// // Copyright (c) 2025 rustmailer.com (https://rustmailer.com) // // This file is part of the Bichon Email Archiving Project // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . import { useState } from 'react' import useDialogState from '@/hooks/use-dialog-state' import { Button } from '@/components/ui/button' import { Main } from '@/components/layout/main' import { AccountActionDialog } from './components/action-dialog' import { useColumns } from './components/columns' import { AccountDeleteDialog } from './components/delete-dialog' import { AccountTable } from './components/table' import AccountProvider, { type AccountDialogType, } from './context' import { MoreVertical, Plus } from 'lucide-react' import Logo from '@/assets/logo.svg' import { AccountModel } from './data/schema' import { AccountDetailDrawer } from './components/account-detail' import { list_accounts } from '@/api/account/api' import { TableSkeleton } from '@/components/table-skeleton' import { useQuery } from '@tanstack/react-query' import { OAuth2TokensDialog } from './components/oauth2-tokens' import { RunningStateDialog } from './components/running-state-dialog' import { FixedHeader } from '@/components/layout/fixed-header' import { SyncFoldersDialog } from './components/sync-folders' import { NoSyncAccountDialog } from './components/nosync-dialog' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu' import { useTranslation } from 'react-i18next' export default function Accounts() { const { t } = useTranslation() const columns = useColumns() // Dialog states const [currentRow, setCurrentRow] = useState(null) const [open, setOpen] = useDialogState(null) const { data: accountList, isLoading } = useQuery({ queryKey: ['account-list'], queryFn: list_accounts, }) const hasAccounts = accountList != null && accountList.items.length > 0; return (
{/* Header Section */}

{t('accounts.title')}

{t('accounts.description')}

setOpen("add-nosync")}> {t('accounts.addNoSync')}
{/* Table / Empty State Section */}
{isLoading ? ( ) : hasAccounts ? ( ) : (
Bichon Logo

{t('accounts.noAccountConfigurations')}

{t('accounts.noAccountConfigurationsDesc')}

)}
setOpen('add-imap')} /> setOpen('add-nosync')} /> {currentRow && ( <> { setOpen('edit-imap') setTimeout(() => { setCurrentRow(null) }, 500) }} currentRow={currentRow} /> { setOpen('edit-nosync') setTimeout(() => { setCurrentRow(null) }, 500) }} currentRow={currentRow} /> { setOpen('running-state') setTimeout(() => { setCurrentRow(null) }, 500) }} currentRow={currentRow} /> { setOpen('delete') setTimeout(() => { setCurrentRow(null) }, 500) }} currentRow={currentRow} /> { setOpen('sync-folders') setTimeout(() => { setCurrentRow(null) }, 500) }} currentRow={currentRow} /> setOpen('detail')} currentRow={currentRow} /> setOpen('oauth2')} currentRow={currentRow} /> )}
) }