diff --git a/app/api/courrier/account/route.ts b/app/api/courrier/account/route.ts index f7f0f9e7..1f7d508f 100644 --- a/app/api/courrier/account/route.ts +++ b/app/api/courrier/account/route.ts @@ -201,44 +201,86 @@ export async function DELETE(request: Request) { export async function PATCH(request: Request) { try { + // Authenticate user const session = await getServerSession(authOptions); if (!session?.user?.id) { - return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); + return NextResponse.json( + { error: 'Unauthorized' }, + { status: 401 } + ); } + + // Parse request body const body = await request.json(); - const { accountId, newPassword } = body; - if (!accountId || !newPassword) { - return NextResponse.json({ error: 'Missing accountId or newPassword' }, { status: 400 }); + const { accountId, newPassword, display_name, color } = body; + + if (!accountId) { + return NextResponse.json( + { error: 'Account ID is required' }, + { status: 400 } + ); } - // Find the account + + // Check if at least one of the fields is provided + if (!newPassword && !display_name && !color) { + return NextResponse.json( + { error: 'At least one field to update is required' }, + { status: 400 } + ); + } + + // Verify the account belongs to the user const account = await prisma.mailCredentials.findFirst({ - where: { id: accountId, userId: session.user.id }, + where: { + id: accountId, + userId: session.user.id + } }); + if (!account) { - return NextResponse.json({ error: 'Account not found' }, { status: 404 }); + return NextResponse.json( + { error: 'Account not found' }, + { status: 404 } + ); } - // Test new credentials - const testResult = await testEmailConnection({ - email: account.email, - password: newPassword, - host: account.host, - port: account.port, - secure: typeof (account as any).secure === 'boolean' ? (account as any).secure : true, - }); - if (!testResult.imap) { - return NextResponse.json({ error: `Connection test failed: ${testResult.error || 'Could not connect to IMAP server'}` }, { status: 400 }); + + // Build update data object + const updateData: any = {}; + + // Add password if provided + if (newPassword) { + updateData.password = newPassword; } - // Update password in database + + // Add display_name if provided + if (display_name !== undefined) { + updateData.display_name = display_name; + } + + // Add color if provided + if (color) { + updateData.color = color; + } + + // Update the account await prisma.mailCredentials.update({ where: { id: accountId }, - data: { password: newPassword }, + data: updateData + }); + + return NextResponse.json({ + success: true, + message: 'Account updated successfully' }); - // Invalidate cache - await invalidateFolderCache(session.user.id, account.email, '*'); - return NextResponse.json({ success: true, message: 'Password updated' }); } catch (error) { - console.error('Error updating account password:', error); - return NextResponse.json({ error: 'Failed to update password', details: error instanceof Error ? error.message : 'Unknown error' }, { status: 500 }); + console.error('Error updating account:', error); + return NextResponse.json( + { + error: 'Failed to update account', + details: error instanceof Error ? error.message : 'Unknown error' + }, + { status: 500 } + ); } } diff --git a/app/courrier/page.tsx b/app/courrier/page.tsx index 1d894323..b943f100 100644 --- a/app/courrier/page.tsx +++ b/app/courrier/page.tsx @@ -9,7 +9,7 @@ import { Inbox, Send, Star, Trash, Plus, ChevronLeft, ChevronRight, Search, ChevronDown, Folder, ChevronUp, Reply, Forward, ReplyAll, MoreHorizontal, FolderOpen, X, Paperclip, MessageSquare, Copy, EyeOff, - AlertOctagon, Archive, RefreshCw, Menu + AlertOctagon, Archive, Menu, Check } from 'lucide-react'; import { Dialog, DialogContent, DialogTitle } from '@/components/ui/dialog'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; @@ -901,37 +901,109 @@ export default function CourrierPage() { {/* Edit Password Modal */} { if (!open) setShowEditModal(false); }}> - - Edit Account Password + + Edit Account Settings
{ e.preventDefault(); if (!accountToEdit) return; setEditLoading(true); try { + const formElement = e.target as HTMLFormElement; + const displayName = (formElement.querySelector('#display-name') as HTMLInputElement).value; + const color = (formElement.querySelector('input[name="color"]:checked') as HTMLInputElement)?.value || accountToEdit.color; + const res = await fetch('/api/courrier/account', { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ accountId: accountToEdit.id, newPassword }), + body: JSON.stringify({ + accountId: accountToEdit.id, + newPassword: newPassword || undefined, + display_name: displayName, + color: color + }), }); const data = await res.json(); - if (!res.ok) throw new Error(data.error || 'Failed to update password'); - toast({ title: 'Password updated', description: 'Password changed successfully.' }); + if (!res.ok) throw new Error(data.error || 'Failed to update account settings'); + toast({ title: 'Account updated', description: 'Account settings updated successfully.' }); setShowEditModal(false); setNewPassword(''); - window.location.reload(); + // Update the local account data + setAccounts(accounts.map(account => + account.id === accountToEdit.id + ? {...account, name: displayName, color: color} + : account + )); } catch (err) { - toast({ title: 'Error', description: err instanceof Error ? err.message : 'Failed to update password', variant: 'destructive' }); + toast({ title: 'Error', description: err instanceof Error ? err.message : 'Failed to update account settings', variant: 'destructive' }); } finally { setEditLoading(false); } }}> -
- - setNewPassword(e.target.value)} required className="mt-1" /> +
+ +
-
- - + +
+ + setNewPassword(e.target.value)} + className="mt-1 bg-white text-gray-800" + placeholder="Leave blank to keep current password" + /> +
+ +
+ +
+ {colorPalette.map((color, index) => ( +
+ + +
+ ))} +
+
+ +
+ +