بلاک‌ها · حساب کاربری

یک کارتِ وسط‌چین با عکس و تغییرِ عکس، چهار فیلدِ اصلی و ذخیره‌ای که تا تغییری نباشد غیرفعال است.

۱. نصب کامپوننت‌ها

این بلاک از ۶ آیتم دیگ استفاده می‌کند: avatarbuttoncontrol-sizepersiantext-fieldtoast

پکیج‌منیجر پیش‌فرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیج‌منیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/text-field.json https://docs.digdesign.ir/r/toast.json
pnpm dlx digdesign@latest add https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/text-field.json https://docs.digdesign.ir/r/toast.json
yarn dlx digdesign@latest add https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/text-field.json https://docs.digdesign.ir/r/toast.json
bunx --bun digdesign@latest add https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/text-field.json https://docs.digdesign.ir/r/toast.json

۲. کد صفحه

کد را در app/<route>/page.tsx بگذارید و متن‌ها، داده و هندلرها را با محصول خودتان عوض کنید.

profile-simple.tsx
"use client"

import * as React from "react"

import { Avatar } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { TextField } from "@/components/ui/text-field"
import { toast } from "@/components/ui/toast"
import { isValidEmail, isValidMobile } from "@/lib/persian"
import { stockImages } from "@/lib/stock-images"

/**
 * پروفایلِ ساده: یک کارتِ وسط‌چین با عکس و «تغییرِ عکس»، چهار فیلدِ اصلی و ذخیره؛ برای
 * اپ‌هایی که پروفایلِ کامل لازم ندارند. ذخیره تا تغییری نباشد غیرفعال است.
 */
export default function ProfileSimpleBlock() {
  const [dirty, setDirty] = React.useState(false)
  const [saving, setSaving] = React.useState(false)

  return (
    <ControlSizeProvider size="xl" asChild>
      <main className="flex min-h-svh items-start justify-center bg-subtle p-4 sm:items-center">
        <form
          onChange={() => setDirty(true)}
          onSubmit={(event) => {
            event.preventDefault()
            setSaving(true)
            window.setTimeout(() => {
              setSaving(false)
              setDirty(false)
              toast.success("پروفایل ذخیره شد.")
            }, 700)
          }}
          className="flex w-full max-w-md flex-col gap-8 rounded-xl border border-border bg-card p-6 sm:p-8"
        >
          <div className="flex flex-col items-center gap-4 text-center">
            <Avatar alt="" src={stockImages.personMan1.src} className="size-24" />
            <div className="flex flex-col gap-1">
              <h1 className="text-xl font-bold">امیر رضایی</h1>
              <Button type="button" variant="ghost" className="self-center">
                تغییرِ عکس
              </Button>
            </div>
          </div>
          <div className="flex flex-col gap-5">
            <TextField label="نام و نام خانوادگی" name="name" defaultValue="امیر رضایی" autoComplete="name" required />
            <TextField label="شماره موبایل" name="mobile" type="tel" dir="ltr" maxLength={11} defaultValue="09127654321" required validate={(value) => (isValidMobile(value) ? undefined : "شماره موبایل باید با ۰۹ شروع شود و ۱۱ رقم باشد.")} />
            <TextField label="ایمیل" name="email" type="email" dir="ltr" defaultValue="amir@avand.example" validate={(value) => (!value || isValidEmail(value) ? undefined : "ایمیل معتبر نیست.")} />
            <TextField label="شهر" name="city" defaultValue="تهران" />
          </div>
          <Button type="submit" fullWidth loading={saving} disabled={!dirty} className="mt-2">
            ذخیرهٔ تغییرات
          </Button>
        </form>
      </main>
    </ControlSizeProvider>
  )
}