"use client"; import { useRouter } from "next/navigation"; import { useState, useTransition } from "react"; import { Button } from "@/components/ui/button"; import { NotificationChannel } from "@/generated/prisma/enums"; const CHANNEL_ORDER: NotificationChannel[] = [NotificationChannel.EMAIL, NotificationChannel.PUSH]; const CHANNEL_LABEL: Record = { EMAIL: "Email", PUSH: "Push", IN_APP: "In-app" }; export interface PreferenceCellState { channel: NotificationChannel; isEnabled: boolean; } /** * Every other notification a barber gets (new appointment, reschedule, * cancellation, schedule change) is required — always sent, no toggle — * so this form only ever shows the one type that's genuinely optional: * appointment reminders. See NotificationService/types.ts, * PREFERENCE_CONTROLLED_TYPES, and docs/phase-7-summary.md — showing a * toggle for a required type would just be a no-op switch that does * nothing when flipped, which the Phase 7 brief explicitly calls out to * avoid. */ export interface NotificationPreferencesFormProps { initial: PreferenceCellState[]; /** Recipient-specific — see features/staff/actions/profile.ts (staff) and features/notifications/actions/preferences.ts (customer). */ action: (cells: PreferenceCellState[]) => Promise<{ success: boolean; error?: string }>; } export function NotificationPreferencesForm({ initial, action }: NotificationPreferencesFormProps) { const router = useRouter(); const [cells, setCells] = useState(initial); const [saved, setSaved] = useState(false); const [isPending, startTransition] = useTransition(); const isEnabled = (channel: NotificationChannel) => cells.find((c) => c.channel === channel)?.isEnabled ?? true; const toggle = (channel: NotificationChannel) => { setSaved(false); setCells((prev) => prev.map((c) => (c.channel === channel ? { ...c, isEnabled: !c.isEnabled } : c))); }; const handleSave = () => { startTransition(async () => { await action(cells); setSaved(true); router.refresh(); }); }; return (

Booking confirmations, changes, and cancellations always notify you — those aren't optional. Choose how you'd like to hear about upcoming appointment reminders.

{CHANNEL_ORDER.map((channel) => (
Reminders via {CHANNEL_LABEL[channel]}
))}
{saved && (

Saved.

)}
); }