'use client' import { useState } from 'react' import { useQuery, useMutation } from '@tanstack/react-query' import { useRouter } from 'next/navigation' import { toast } from 'sonner' import { DashboardLayout } from '@/components/layout/dashboard-layout' import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Badge } from '@/components/ui/badge' import { settingsAPI } from '@/lib/api' import { clearAuth } from '@/lib/auth' import { usePlan } from '@/lib/use-plan' export default function SettingsPage() { const router = useRouter() const [showPasswordForm, setShowPasswordForm] = useState(false) const [showWebhookForm, setShowWebhookForm] = useState(false) const [showSlackForm, setShowSlackForm] = useState(false) const [showDeleteConfirm, setShowDeleteConfirm] = useState(false) const { canUseSlack, canUseWebhook } = usePlan() const [passwordForm, setPasswordForm] = useState({ currentPassword: '', newPassword: '', confirmPassword: '', }) const [webhookUrl, setWebhookUrl] = useState('') const [slackWebhookUrl, setSlackWebhookUrl] = useState('') const [deletePassword, setDeletePassword] = useState('') // Fetch user settings const { data: settings, isLoading, refetch } = useQuery({ queryKey: ['settings'], queryFn: async () => { const response = await settingsAPI.get() setWebhookUrl(response.settings.webhookUrl || '') setSlackWebhookUrl(response.settings.slackWebhookUrl || '') return response.settings }, }) // Change password mutation const changePasswordMutation = useMutation({ mutationFn: async () => { if (passwordForm.newPassword !== passwordForm.confirmPassword) { throw new Error('Passwords do not match') } if (passwordForm.newPassword.length < 8) { throw new Error('Password must be at least 8 characters') } return settingsAPI.changePassword(passwordForm.currentPassword, passwordForm.newPassword) }, onSuccess: () => { toast.success('Password changed successfully') setShowPasswordForm(false) setPasswordForm({ currentPassword: '', newPassword: '', confirmPassword: '' }) }, onError: (error: any) => { toast.error(error.response?.data?.message || error.message || 'Failed to change password') }, }) // Toggle email notifications const toggleEmailMutation = useMutation({ mutationFn: async (enabled: boolean) => { return settingsAPI.updateNotifications({ emailEnabled: enabled }) }, onSuccess: () => { toast.success('Email notifications updated') refetch() }, onError: (error: any) => { toast.error(error.response?.data?.message || 'Failed to update notifications') }, }) // Update webhook const updateWebhookMutation = useMutation({ mutationFn: async () => { return settingsAPI.updateNotifications({ webhookUrl: webhookUrl || null, webhookEnabled: !!webhookUrl, }) }, onSuccess: () => { toast.success('Webhook settings updated') setShowWebhookForm(false) refetch() }, onError: (error: any) => { toast.error(error.response?.data?.message || 'Failed to update webhook') }, }) // Update Slack const updateSlackMutation = useMutation({ mutationFn: async () => { return settingsAPI.updateNotifications({ slackWebhookUrl: slackWebhookUrl || null, slackEnabled: !!slackWebhookUrl, }) }, onSuccess: () => { toast.success('Slack integration updated') setShowSlackForm(false) refetch() }, onError: (error: any) => { toast.error(error.response?.data?.message || 'Failed to update Slack') }, }) // Delete account mutation const deleteAccountMutation = useMutation({ mutationFn: async () => { return settingsAPI.deleteAccount(deletePassword) }, onSuccess: () => { toast.success('Account deleted successfully') clearAuth() router.push('/login') }, onError: (error: any) => { toast.error(error.response?.data?.message || 'Failed to delete account') }, }) if (isLoading) { return (
) } return ( {/* Account Settings */} Account Manage your account settings
{settings?.plan || 'free'} plan
{!showPasswordForm ? ( ) : (
setPasswordForm({ ...passwordForm, currentPassword: e.target.value })} required /> setPasswordForm({ ...passwordForm, newPassword: e.target.value })} hint="At least 8 characters" required /> setPasswordForm({ ...passwordForm, confirmPassword: e.target.value })} required />
)}
{/* Notifications */} Notifications Configure how you receive alerts
{/* Email Notifications */}

Email Notifications

Receive email alerts when changes are detected

{/* Slack Integration */}

Slack Integration

Send alerts to your Slack workspace

{settings?.slackEnabled && (

✓ Configured

)} {!canUseSlack && (
Pro Feature
)}
{showSlackForm && (
setSlackWebhookUrl(e.target.value)} placeholder="https://hooks.slack.com/services/..." hint="Get this from your Slack app settings" />
{settings?.slackEnabled && ( )}
)}
{/* Webhook */}

Webhook

Send JSON payloads to your server

{settings?.webhookEnabled && (

✓ Configured

)} {!canUseWebhook && (
Pro Feature
)}
{showWebhookForm && (
setWebhookUrl(e.target.value)} placeholder="https://your-server.com/webhook" hint="We'll POST JSON data to this URL on changes" />
{settings?.webhookEnabled && ( )}
)}
{/* Plan & Billing */} Plan & Billing Manage your subscription

{settings?.plan || 'Free'} Plan

Current

{settings?.plan === 'free' && '5 monitors, 1hr frequency'} {settings?.plan === 'pro' && '50 monitors, 5min frequency'} {settings?.plan === 'business' && '200 monitors, 1min frequency'} {settings?.plan === 'enterprise' && 'Unlimited monitors, all features'}

{settings?.plan !== 'free' && (

Stripe Customer ID: {settings?.stripeCustomerId || 'N/A'}

)}
{/* Danger Zone */} Danger Zone Irreversible actions {!showDeleteConfirm ? (

Delete Account

Permanently delete your account and all data

) : (

⚠️ This action cannot be undone!

All your monitors, snapshots, and alerts will be permanently deleted.

setDeletePassword(e.target.value)} placeholder="Enter your password" />
)}
) }