import { useCloudAccounts, useRefreshQuota, useDeleteCloudAccount, useAddGoogleAccount, useSwitchCloudAccount, useAutoSwitchEnabled, useSetAutoSwitchEnabled, useForcePollCloudMonitor, useSyncLocalAccount, startAuthFlow, } from '@/hooks/useCloudAccounts'; import { CloudAccountCard } from '@/components/CloudAccountCard'; import { CloudAccount } from '@/types/cloudAccount'; import { Button } from '@/components/ui/button'; import { Switch } from '@/components/ui/switch'; import { Plus, Loader2, Cloud, Zap, RefreshCcw, Download, CheckSquare, Trash2, X, RefreshCw, } from 'lucide-react'; import { useToast } from '@/components/ui/use-toast'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { getLocalizedErrorMessage } from '@/utils/errorMessages'; // ... (existing code: imports and comments) export function CloudAccountList() { const { t } = useTranslation(); const { data: accounts, isLoading, isError, error } = useCloudAccounts(); const refreshMutation = useRefreshQuota(); const deleteMutation = useDeleteCloudAccount(); const addMutation = useAddGoogleAccount(); const switchMutation = useSwitchCloudAccount(); const syncMutation = useSyncLocalAccount(); const { data: autoSwitchEnabled, isLoading: isSettingsLoading } = useAutoSwitchEnabled(); const setAutoSwitchMutation = useSetAutoSwitchEnabled(); const forcePollMutation = useForcePollCloudMonitor(); const { toast } = useToast(); const [isAddDialogOpen, setIsAddDialogOpen] = useState(false); const [authCode, setAuthCode] = useState(''); const handleAddAccount = (codeVal?: string) => { const codeToUse = codeVal || authCode; if (!codeToUse) { return; } addMutation.mutate( { authCode: codeToUse }, { onSuccess: () => { setIsAddDialogOpen(false); setAuthCode(''); toast({ title: t('cloud.toast.addSuccess') }); }, onError: (err) => { toast({ title: t('cloud.toast.addFailed.title'), description: getLocalizedErrorMessage(err, t), variant: 'destructive', }); }, }, ); }; // Listen for Google Auth Code useEffect(() => { if (window.electron?.onGoogleAuthCode) { console.log('[OAuth] Setting up auth code listener, dialog open:', isAddDialogOpen); const cleanup = window.electron.onGoogleAuthCode((code) => { console.log('[OAuth] Received auth code via IPC:', code?.substring(0, 10) + '...'); setAuthCode(code); // Note: Auto-submit will be triggered by the authCode change effect below }); return cleanup; } }, []); // Auto-submit when authCode is set and dialog is open useEffect(() => { if (authCode && isAddDialogOpen && !addMutation.isPending) { console.log('[OAuth] Auto-submitting auth code'); handleAddAccount(authCode); } }, [authCode, isAddDialogOpen]); // Batch Operations State const [selectedIds, setSelectedIds] = useState>(new Set()); // ... (existing code: handleRefresh, handleSwitch, handleDelete) const handleRefresh = (id: string) => { refreshMutation.mutate( { accountId: id }, { onSuccess: () => toast({ title: t('cloud.toast.quotaRefreshed') }), onError: () => toast({ title: t('cloud.toast.refreshFailed'), variant: 'destructive' }), }, ); }; const handleSwitch = (id: string) => { switchMutation.mutate( { accountId: id }, { onSuccess: () => toast({ title: t('cloud.toast.switched.title'), description: t('cloud.toast.switched.description'), }), onError: (err) => toast({ title: t('cloud.toast.switchFailed'), description: getLocalizedErrorMessage(err, t), variant: 'destructive', }), }, ); }; const handleDelete = (id: string) => { if (confirm(t('cloud.toast.deleteConfirm'))) { deleteMutation.mutate( { accountId: id }, { onSuccess: () => { toast({ title: t('cloud.toast.deleted') }); // Clear from selection if deleted setSelectedIds((prev) => { const next = new Set(prev); next.delete(id); return next; }); }, onError: () => toast({ title: t('cloud.toast.deleteFailed'), variant: 'destructive' }), }, ); } }; const handleToggleAutoSwitch = (checked: boolean) => { setAutoSwitchMutation.mutate( { enabled: checked }, { onSuccess: () => toast({ title: checked ? t('cloud.toast.autoSwitchOn') : t('cloud.toast.autoSwitchOff'), }), onError: () => toast({ title: t('cloud.toast.updateSettingsFailed'), variant: 'destructive' }), }, ); }; const handleForcePoll = () => { forcePollMutation.mutate(undefined, { onSuccess: () => toast({ title: t('cloud.polling') }), }); }; const handleSyncLocal = () => { syncMutation.mutate(undefined, { onSuccess: (acc: CloudAccount | null) => { if (acc) { toast({ title: t('cloud.toast.syncSuccess.title'), description: t('cloud.toast.syncSuccess.description', { email: acc.email }), }); } else { toast({ title: t('cloud.toast.syncFailed.title'), description: t('cloud.toast.syncFailed.description'), variant: 'destructive', }); } }, onError: (err) => { toast({ title: t('cloud.toast.syncFailed.title'), description: getLocalizedErrorMessage(err, t), variant: 'destructive', }); }, }); }; const openAuthUrl = async () => { try { await startAuthFlow(); } catch (e) { toast({ title: t('cloud.toast.startAuthFailed'), // Need to add this key or just use generic error description: String(e), variant: 'destructive', }); } }; // Batch Selection Handlers const toggleSelection = (id: string, selected: boolean) => { setSelectedIds((prev) => { const next = new Set(prev); if (selected) { next.add(id); } else { next.delete(id); } return next; }); }; const toggleSelectAll = () => { if (selectedIds.size === accounts?.length) { setSelectedIds(new Set()); } else { setSelectedIds(new Set(accounts?.map((a) => a.id) || [])); } }; const handleBatchRefresh = () => { selectedIds.forEach((id) => { refreshMutation.mutate({ accountId: id }); }); toast({ title: t('cloud.toast.quotaRefreshed'), description: `triggered for ${selectedIds.size} accounts.`, }); setSelectedIds(new Set()); }; const handleBatchDelete = () => { if (confirm(t('cloud.batch.confirmDelete', { count: selectedIds.size }))) { selectedIds.forEach((id) => { deleteMutation.mutate({ accountId: id }); }); toast({ title: t('cloud.toast.deleted'), description: `${selectedIds.size} accounts deleted.`, }); setSelectedIds(new Set()); } }; if (isLoading) { return (
); } if (isError) { const errorMessage = getLocalizedErrorMessage(error, t); return (
{t('cloud.error.loadFailed')}
{errorMessage}
); } return (

{t('cloud.title')}

{t('cloud.description')}

{t('cloud.authDialog.title')} {t('cloud.authDialog.description')}
) => setAuthCode(e.target.value) } />

{t('cloud.authDialog.instruction')}

{accounts?.map((account) => ( ))} {accounts?.length === 0 && (
{t('cloud.list.noAccounts')}
)}
{/* Batch Action Bar */} {selectedIds.size > 0 && (
{t('cloud.batch.selected', { count: selectedIds.size })}
)}
); }