import { useState, useEffect } from "react"; import { Bell, Mail, Smartphone } from "lucide-react"; import { useConversation, useMessages } from "./Communication.api.js"; import type { Message as ApiMessage } from "./Communication.api.js"; interface NotificationCategory { email: boolean; sms: boolean; push: boolean; } interface NotificationPreferences { appointmentReminders: NotificationCategory; vaccinationAlerts: NotificationCategory; promotional: NotificationCategory; reportCards: NotificationCategory; invoiceReceipts: NotificationCategory; } interface Props { sessionId: string | null; readOnly: boolean; } export function Communication({ sessionId, readOnly }: Props) { const [tab, setTab] = useState<"messages" | "notifications">("messages"); return (
{tab === "messages" && } {tab === "notifications" && }
); } interface MessageThreadProps { sessionId: string | null; readOnly: boolean; } function MessageThread({ sessionId, readOnly: _readOnly }: MessageThreadProps) { const [businessName, setBusinessName] = useState("Business"); const { conversation, loading: convLoading, error: convError } = useConversation(sessionId); const { messages, loading: msgLoading, error: msgError, loadMore, hasMore } = useMessages(sessionId); useEffect(() => { async function fetchBranding() { try { const response = await fetch("/api/branding"); if (response.ok) { const data = await response.json(); setBusinessName(data.businessName || data.name || "Business"); } } catch { setBusinessName("Business"); } } fetchBranding(); }, []); const loading = convLoading || msgLoading; const error = convError || msgError; if (loading) { return (
Loading messages...
); } if (error) { return (

{businessName}

{error}

); } if (!conversation) { return (

{businessName}

Usually replies within a few hours

No conversation yet

Messages with {businessName} will appear here once you start texting.

Reply from your phone
); } return (

{businessName}

Usually replies within a few hours

{messages.length === 0 ? (

No messages yet

) : ( messages.map((msg: ApiMessage) => { const sender = msg.direction === "inbound" ? "customer" : "business"; return (
{msg.body &&

{msg.body}

}
{new Date(msg.createdAt).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" })}
); }) )} {hasMore && (
)}
Reply from your phone
); } function NotificationPreferences({ readOnly }: { readOnly: boolean }) { const [prefs, setPrefs] = useState({ appointmentReminders: { email: true, sms: true, push: true }, vaccinationAlerts: { email: true, sms: false, push: true }, promotional: { email: false, sms: false, push: false }, reportCards: { email: true, sms: false, push: true }, invoiceReceipts: { email: true, sms: false, push: false }, }); type PrefKey = keyof NotificationPreferences; type ChannelKey = "email" | "sms" | "push"; const toggle = (category: PrefKey, channel: ChannelKey) => { if (readOnly) return; setPrefs(prev => ({ ...prev, [category]: { ...prev[category], [channel]: !prev[category][channel], }, })); }; const categories: { key: PrefKey; label: string; desc: string; icon: typeof Bell }[] = [ { key: "appointmentReminders", label: "Appointment Reminders", desc: "Upcoming appointment notifications", icon: Bell }, { key: "vaccinationAlerts", label: "Vaccination Alerts", desc: "Expiration and renewal reminders", icon: Mail }, { key: "promotional", label: "Promotions & Offers", desc: "Deals and seasonal specials", icon: Smartphone }, { key: "reportCards", label: "Report Cards", desc: "Grooming report card delivery", icon: Mail }, { key: "invoiceReceipts", label: "Invoice & Receipts", desc: "Payment confirmations", icon: Bell }, ]; const channels: { key: ChannelKey; label: string; icon: typeof Mail }[] = [ { key: "email", label: "Email", icon: Mail }, { key: "sms", label: "SMS", icon: Smartphone }, { key: "push", label: "Push", icon: Bell }, ]; return (
{channels.map(ch => ( ))} {categories.map(cat => ( {channels.map(ch => ( ))} ))}
Category
{ch.label}

{cat.label}

{cat.desc}

); } export default Communication;