'use client'; import { useState, useEffect, useCallback } from 'react'; import { Bell, Send, Mail, CheckCircle2, AlertCircle, Loader2, Globe } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Separator } from '@/components/ui/separator'; import { Skeleton } from '@/components/ui/skeleton'; import { Badge } from '@/components/ui/badge'; import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { cn } from '@/lib/utils'; interface NotificationSettings { telegramBotToken: string | null; telegramChatId: string | null; telegramEnabled: boolean; emailEnabled: boolean; onNewVideo: boolean; onNewVersion: boolean; onNewComment: boolean; onNewReply: boolean; onApprovalEvents: boolean; timezone: string; } function ToggleButton({ enabled, onToggle, label, description, }: { enabled: boolean; onToggle: () => void; label: string; description?: string; }) { return ( ); } export default function SettingsPage() { const [settings, setSettings] = useState({ telegramBotToken: null, telegramChatId: null, telegramEnabled: false, emailEnabled: false, onNewVideo: true, onNewVersion: true, onNewComment: true, onNewReply: true, onApprovalEvents: true, timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC', }); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [testing, setTesting] = useState(null); const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null); // Form state for Telegram fields (separate from saved settings for editing) const [telegramToken, setTelegramToken] = useState(''); const [telegramChatId, setTelegramChatId] = useState(''); useEffect(() => { async function fetchSettings() { try { const res = await fetch('/api/settings/notifications'); if (res.ok) { const data = await res.json(); setSettings(data.data); setTelegramToken(data.data.telegramBotToken || ''); setTelegramChatId(data.data.telegramChatId || ''); } } catch { console.error('Failed to fetch notification settings'); } finally { setLoading(false); } } fetchSettings(); }, []); const showMessage = useCallback((type: 'success' | 'error', text: string) => { setMessage({ type, text }); setTimeout(() => setMessage(null), 4000); }, []); const handleSave = useCallback(async () => { setSaving(true); try { const res = await fetch('/api/settings/notifications', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ...settings, telegramBotToken: telegramToken || null, telegramChatId: telegramChatId || null, }), }); if (res.ok) { const data = await res.json(); setSettings(data.data); showMessage('success', 'Settings saved'); } else { const data = await res.json(); showMessage('error', data.error || 'Failed to save'); } } catch { showMessage('error', 'Failed to save settings'); } finally { setSaving(false); } }, [settings, telegramToken, telegramChatId, showMessage]); const handleTest = useCallback( async (channel: 'telegram' | 'email') => { setTesting(channel); try { const res = await fetch('/api/settings/notifications', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ channel, telegramBotToken: telegramToken, telegramChatId, }), }); const data = await res.json(); if (res.ok) { showMessage('success', data.data.message); } else { showMessage('error', data.error || 'Test failed'); } } catch { showMessage('error', 'Test failed'); } finally { setTesting(null); } }, [telegramToken, telegramChatId, showMessage] ); if (loading) { return (
{Array.from({ length: 4 }).map((_, i) => ( {Array.from({ length: 3 }).map((_, j) => (
))}
))}
); } return (

Settings

Manage your notification preferences

{/* Status message */} {message && (
{message.type === 'success' ? ( ) : ( )} {message.text}
)} {/* Event Subscriptions */} Notification Events Choose which events trigger notifications setSettings((s) => ({ ...s, onNewVideo: !s.onNewVideo })) } label="New Video Added" description="When a new video is added to one of your projects" /> setSettings((s) => ({ ...s, onNewVersion: !s.onNewVersion })) } label="New Version Added" description="When a new version is added to an existing video" /> setSettings((s) => ({ ...s, onNewComment: !s.onNewComment })) } label="New Comment" description="When someone leaves a comment on your videos" /> setSettings((s) => ({ ...s, onNewReply: !s.onNewReply })) } label="New Reply" description="When someone replies to a comment thread" /> setSettings((s) => ({ ...s, onApprovalEvents: !s.onApprovalEvents })) } label="Approval Workflow" description="When approval requests are created, responded to, or finalized" /> {/* Telegram */}
Telegram {settings.telegramEnabled ? 'Enabled' : 'Disabled'}
Get instant notifications via a Telegram bot
setTelegramToken(e.target.value)} className="mt-1 font-mono text-sm" />
setTelegramChatId(e.target.value)} className="mt-1 font-mono text-sm" />
setSettings((s) => ({ ...s, telegramEnabled: !s.telegramEnabled })) } label="Enable Telegram notifications" />
{/* Email */}
Email {settings.emailEnabled ? 'Enabled' : 'Disabled'}
Receive notification emails to your account email address
setSettings((s) => ({ ...s, emailEnabled: !s.emailEnabled })) } label="Enable email notifications" />
{/* Timezone */} Timezone Timestamps in notifications will use this timezone {/* Save button */}
); }