import { useState, useEffect } from 'react' import { useNavigate, useSearchParams } from 'react-router-dom' import { useAuth } from '@/context/AuthContext' import { Button } from '@/components/ui/button' import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Badge } from '@/components/ui/badge' import { api } from '@/lib/api' import { Mail, User, CreditCard, Shield, Settings as SettingsIcon, ArrowLeft, Plus, Trash2, Check, X, ExternalLink, Loader2, Crown, Star, Brain, Building2, } from 'lucide-react' import type { AIControlSettings, CompanyLabel, CategoryInfo } from '@/types/settings' type TabType = 'profile' | 'accounts' | 'vip' | 'ai-control' | 'subscription' interface EmailAccount { id: string email: string provider: 'gmail' | 'outlook' connected: boolean lastSync?: string } interface VIPSender { email: string name?: string } interface Subscription { status: string plan: string currentPeriodEnd?: string cancelAtPeriodEnd?: boolean } export function Settings() { // #region agent log try { fetch('http://127.0.0.1:7242/ingest/4fa7412d-6f79-4871-8728-29c37c9e5772',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'Settings.tsx:52',message:'Settings component rendering',data:{},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{}); } catch(e) {} // #endregion const { user } = useAuth() const navigate = useNavigate() const [searchParams, setSearchParams] = useSearchParams() const activeTab = (searchParams.get('tab') as TabType) || 'profile' // #region agent log try { fetch('http://127.0.0.1:7242/ingest/4fa7412d-6f79-4871-8728-29c37c9e5772',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'Settings.tsx:60',message:'Settings state initialized',data:{hasUser:!!user,activeTab},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{}); } catch(e) {} // #endregion const [loading, setLoading] = useState(false) const [saving, setSaving] = useState(false) const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null) const [name, setName] = useState(user?.name || '') const [email] = useState(user?.email || '') const [accounts, setAccounts] = useState([]) const [connectingProvider, setConnectingProvider] = useState(null) const [vipSenders, setVipSenders] = useState([]) const [newVipEmail, setNewVipEmail] = useState('') const [subscription, setSubscription] = useState(null) // AI Control state const [aiControlSettings, setAiControlSettings] = useState({ enabledCategories: [], categoryActions: {}, autoDetectCompanies: true, }) const [categories, setCategories] = useState([]) const [companyLabels, setCompanyLabels] = useState([]) const [newCompanyLabel, setNewCompanyLabel] = useState({ name: '', condition: '', category: 'promotions' }) useEffect(() => { loadData() }, [user]) const loadData = async () => { // #region agent log try { fetch('http://127.0.0.1:7242/ingest/4fa7412d-6f79-4871-8728-29c37c9e5772',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'Settings.tsx:84',message:'loadData called',data:{hasUser:!!user,userId:user?.$id},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'E'})}).catch(()=>{}); } catch(e) {} // #endregion if (!user?.$id) return setLoading(true) try { const [accountsRes, subsRes, prefsRes, aiControlRes, companyLabelsRes] = await Promise.all([ api.getEmailAccounts(user.$id), api.getSubscriptionStatus(user.$id), api.getUserPreferences(user.$id), api.getAIControlSettings(user.$id), api.getCompanyLabels(user.$id), ]) if (accountsRes.data) setAccounts(accountsRes.data) if (subsRes.data) setSubscription(subsRes.data) if (prefsRes.data?.vipSenders) setVipSenders(prefsRes.data.vipSenders) if (aiControlRes.data) setAiControlSettings(aiControlRes.data) if (companyLabelsRes.data) setCompanyLabels(companyLabelsRes.data) // Load categories from API or use defaults const categoryList: CategoryInfo[] = [ { key: 'vip', name: 'Important', description: 'Important emails from known contacts', defaultAction: 'star', color: '#ff0000', enabled: true }, { key: 'customers', name: 'Clients', description: 'Emails from clients and projects', defaultAction: 'inbox', color: '#4285f4', enabled: true }, { key: 'invoices', name: 'Invoices', description: 'Invoices, receipts and financial documents', defaultAction: 'inbox', color: '#0f9d58', enabled: true }, { key: 'newsletters', name: 'Newsletter', description: 'Regular newsletters and updates', defaultAction: 'archive_read', color: '#9c27b0', enabled: true }, { key: 'promotions', name: 'Promotions', description: 'Marketing emails and promotions', defaultAction: 'archive_read', color: '#ff9800', enabled: true }, { key: 'social', name: 'Social', description: 'Social media and platform notifications', defaultAction: 'archive_read', color: '#00bcd4', enabled: true }, { key: 'security', name: 'Security', description: 'Security codes and notifications', defaultAction: 'inbox', color: '#f44336', enabled: true }, { key: 'calendar', name: 'Calendar', description: 'Calendar invites and events', defaultAction: 'inbox', color: '#673ab7', enabled: true }, { key: 'review', name: 'Review', description: 'Emails that need manual review', defaultAction: 'inbox', color: '#607d8b', enabled: true }, ] // Update enabled status from settings const enabledCategories = aiControlRes.data?.enabledCategories || categoryList.map(c => c.key) const updatedCategories = categoryList.map(cat => ({ ...cat, enabled: enabledCategories.includes(cat.key), })) setCategories(updatedCategories) // #region agent log try { fetch('http://127.0.0.1:7242/ingest/4fa7412d-6f79-4871-8728-29c37c9e5772',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'Settings.tsx:122',message:'loadData success',data:{accountsCount:accountsRes.data?.length||0,categoriesCount:updatedCategories.length},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'E'})}).catch(()=>{}); } catch(e) {} // #endregion } catch (error) { // #region agent log try { fetch('http://127.0.0.1:7242/ingest/4fa7412d-6f79-4871-8728-29c37c9e5772',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'Settings.tsx:123',message:'loadData error',data:{errorMessage:error instanceof Error?error.message:String(error),errorStack:error instanceof Error?error.stack:undefined},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'E'})}).catch(()=>{}); } catch(e) {} // #endregion console.error('Failed to load settings data:', error) } finally { setLoading(false) } } const setTab = (tab: TabType) => { setSearchParams({ tab }) setMessage(null) } const showMessage = (type: 'success' | 'error', text: string) => { setMessage({ type, text }) setTimeout(() => setMessage(null), 5000) } const handleSaveProfile = async () => { setSaving(true) try { showMessage('success', 'Profile saved!') } catch { showMessage('error', 'Failed to save') } finally { setSaving(false) } } const handleConnectAccount = async (provider: 'gmail' | 'outlook') => { if (!user?.$id) return setConnectingProvider(provider) try { const res = await api.getOAuthUrl(provider, user.$id) if (res.data?.url) { window.location.href = res.data.url } } catch { showMessage('error', `Failed to connect ${provider}`) setConnectingProvider(null) } } const handleDisconnectAccount = async (accountId: string) => { if (!user?.$id) return try { await api.disconnectEmailAccount(accountId, user.$id) setAccounts(accounts.filter(a => a.id !== accountId)) showMessage('success', 'Account disconnected') } catch { showMessage('error', 'Failed to disconnect') } } const handleAddVip = () => { if (!newVipEmail.trim() || !newVipEmail.includes('@')) return if (vipSenders.some(v => v.email === newVipEmail)) { showMessage('error', 'This email is already in the VIP list') return } setVipSenders([...vipSenders, { email: newVipEmail }]) setNewVipEmail('') showMessage('success', 'VIP added') } const handleRemoveVip = (email: string) => { setVipSenders(vipSenders.filter(v => v.email !== email)) } const handleSaveVips = async () => { if (!user?.$id) return setSaving(true) try { await api.saveUserPreferences(user.$id, { vipSenders }) showMessage('success', 'VIP list saved!') } catch { showMessage('error', 'Failed to save') } finally { setSaving(false) } } const handleManageSubscription = async () => { if (!user?.$id) return try { const res = await api.createPortalSession(user.$id) if (res.data?.url) { window.location.href = res.data.url } } catch { showMessage('error', 'Failed to open customer portal') } } const handleUpgrade = async (plan: string) => { if (!user?.$id) return try { const res = await api.createSubscriptionCheckout(plan, user.$id, user.email) if (res.data?.url) { window.location.href = res.data.url } } catch { showMessage('error', 'Failed to start checkout') } } const tabs = [ { id: 'profile' as TabType, label: 'Profile', icon: User }, { id: 'accounts' as TabType, label: 'Email Accounts', icon: Mail }, { id: 'vip' as TabType, label: 'VIP List', icon: Star }, { id: 'ai-control' as TabType, label: 'AI Control', icon: Brain }, { id: 'subscription' as TabType, label: 'Subscription', icon: CreditCard }, ] // #region agent log try { fetch('http://127.0.0.1:7242/ingest/4fa7412d-6f79-4871-8728-29c37c9e5772',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'Settings.tsx:243',message:'Settings render starting',data:{loading,activeTab,hasUser:!!user},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{}); } catch(e) {} // #endregion return (

Settings

{message && (
{message.type === 'success' ? : } {message.text}
)}
{loading ? (
) : ( <> {activeTab === 'profile' && ( Profile Manage your personal information
{name?.charAt(0)?.toUpperCase() || email?.charAt(0)?.toUpperCase() || 'U'}

{name || 'User'}

{email}

setName(e.target.value)} placeholder="Your name" />

Email address cannot be changed

)} {activeTab === 'accounts' && (
Connected Email Accounts Connect your email accounts for automatic sorting {accounts.length > 0 ? ( accounts.map((account) => (

{account.email}

{account.provider}

{account.connected ? 'Connected' : 'Disconnected'}
)) ) : (

No email accounts connected yet

)}
Add Account Connect a new email account
)} {activeTab === 'vip' && ( VIP List Emails from these senders will always be marked as important
setNewVipEmail(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && handleAddVip()} />
{vipSenders.length > 0 ? ( vipSenders.map((vip) => (
{vip.email}
)) ) : (

No VIP senders added yet

)}
{vipSenders.length > 0 && ( )}
)} {activeTab === 'ai-control' && (
{/* Category Toggles */}
Category Control Enable or disable email categories for AI sorting
{categories.map((category) => (

{category.name}

{category.description}

{category.enabled && ( )}
))} {/* Company Labels */}
Company Labels Automatically label emails from specific companies
{/* Auto-Detection Toggle */}

Auto-Detect Known Companies

Automatically detect and label emails from Amazon, Google, Microsoft, etc. Labels are created automatically when emails from these companies are detected.

{/* Custom Company Labels - Optional */} {companyLabels.length > 0 && (

Custom Company Labels (Optional)

{/* Add New Label Form */}
setNewCompanyLabel({ ...newCompanyLabel, name: e.target.value })} />
setNewCompanyLabel({ ...newCompanyLabel, condition: e.target.value })} />

Use "from:domain.com" or "subject:keyword"

{/* Existing Labels */}
{companyLabels.map((label) => (

{label.name}

{label.enabled ? 'Enabled' : 'Disabled'}

{label.condition}

{label.category && (

Category: {label.category}

)}
))}
)} {/* Add Custom Label - Collapsible */}
Add Custom Company Label (Optional)
setNewCompanyLabel({ ...newCompanyLabel, name: e.target.value })} />
setNewCompanyLabel({ ...newCompanyLabel, condition: e.target.value })} />

Use "from:domain.com" or "subject:keyword"

)} {activeTab === 'subscription' && (
Current Subscription Manage your EmailSorter subscription

{subscription?.plan || 'Trial'}

{subscription?.status === 'active' ? 'Active' : 'Trial'}
{subscription?.currentPeriodEnd && (

Next billing: {new Date(subscription.currentPeriodEnd).toLocaleDateString('en-US')}

)}
Available Plans Choose the plan that fits you
{[ { id: 'basic', name: 'Basic', price: '9', features: ['1 email account', '500 emails/day', 'Standard support'] }, { id: 'pro', name: 'Pro', price: '19', features: ['3 email accounts', 'Unlimited emails', 'Historical sorting', 'Priority support'], popular: true }, { id: 'business', name: 'Business', price: '49', features: ['10 email accounts', 'Unlimited emails', 'Team features', 'API access', '24/7 support'] }, ].map((plan) => (
{plan.popular && (
Popular
)}

{plan.name}

${plan.price} /month
    {plan.features.map((feature) => (
  • {feature}
  • ))}
))}
)} )}
) }