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

تنظیمِ اعلان‌ها

پیش‌نمایش تمام‌صفحه

تنظیمِ اعلان‌ها به شکلِ جدولِ رویداد × کانال (ایمیل، پیامک، اپ) با چک‌باکس، گروه‌بندیِ رویدادها و «همه را خاموش کن».

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

این بلاک از ۵ آیتم دیگ استفاده می‌کند: buttoncheckboxcontrol-sizetabletoast

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

۲. کد صفحه

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

settings-notifications.tsx
"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { toast } from "@/components/ui/toast"

const CHANNELS = ["ایمیل", "پیامک", "اپ"] as const
const EVENTS = [
  { group: "سفارش‌ها", items: ["سفارشِ تازه", "تغییرِ وضعیتِ ارسال", "مرجوعی"] },
  { group: "مالی", items: ["پرداختِ موفق", "سررسیدِ فاکتور"] },
  { group: "تیم", items: ["دعوتِ عضوِ تازه", "نام‌بردن از من"] },
]

/**
 * تنظیمِ اعلان‌ها به شکلِ جدولِ رویداد × کانال: هر ردیف یک رویداد، هر ستون یک کانال (ایمیل،
 * پیامک، اپ) با چک‌باکس؛ تیترِ هر گروه جدا و «همه را خاموش کن» برای وقتِ مرخصی.
 */
export default function SettingsNotificationsBlock() {
  const [on, setOn] = React.useState<Record<string, boolean>>(() =>
    Object.fromEntries(EVENTS.flatMap((group) => group.items.flatMap((item) => CHANNELS.map((channel) => [`${item}:${channel}`, channel !== "پیامک" || item.includes("پرداخت")]))))
  )
  const toggle = (key: string) => setOn((state) => ({ ...state, [key]: !state[key] }))

  return (
    <ControlSizeProvider size="xl" asChild>
      <main className="mx-auto flex w-full max-w-3xl flex-col gap-8 p-4 sm:p-6">
        <header className="flex flex-wrap items-end justify-between gap-x-4 gap-y-6">
          <div className="flex flex-col gap-1">
            <h1 className="text-2xl font-bold">اعلان‌ها</h1>
            <p className="text-muted-foreground">برای هر رویداد انتخاب کن از کجا خبردار شوی.</p>
          </div>
          <Button variant="outline" onClick={() => setOn((state) => Object.fromEntries(Object.keys(state).map((key) => [key, false])))}>
            همه را خاموش کن
          </Button>
        </header>
        <div className="rounded-xl border border-border bg-card">
          <Table stackOnMobile className="min-w-[30rem]">
            <TableHeader className="bg-subtle">
              <TableRow className="hover:bg-subtle">
                <TableHead>رویداد</TableHead>
                {CHANNELS.map((channel) => (
                  <TableHead key={channel} className="w-24 text-center">
                    {channel}
                  </TableHead>
                ))}
              </TableRow>
            </TableHeader>
            <TableBody>
              {EVENTS.map((group) => (
                <React.Fragment key={group.group}>
                  <TableRow className="hover:bg-card">
                    <TableCell colSpan={CHANNELS.length + 1} className="pt-5 pb-2 font-bold">
                      {group.group}
                    </TableCell>
                  </TableRow>
                  {group.items.map((item) => (
                    <TableRow key={item}>
                      <TableCell>{item}</TableCell>
                      {CHANNELS.map((channel) => {
                        const key = `${item}:${channel}`
                        return (
                          <TableCell key={channel} className="text-center">
                            <Checkbox checked={on[key]} onCheckedChange={() => toggle(key)} aria-label={`${item} از ${channel}`} />
                          </TableCell>
                        )
                      })}
                    </TableRow>
                  ))}
                </React.Fragment>
              ))}
            </TableBody>
          </Table>
        </div>
        <div className="flex justify-end border-t border-border pt-8">
          <Button onClick={() => toast.success("تنظیمِ اعلان‌ها ذخیره شد.")}>ذخیره</Button>
        </div>
      </main>
    </ControlSizeProvider>
  )
}