ultisuite-client/components/gmail/contacts-page/trash-view.tsx
R3D347HR4Y c87670e90f
Some checks failed
E2E / Playwright e2e (push) Has been cancelled
feat(api): offline-first mail sync w/ TanStack Query
Move mail, compose, contacts, and accounts off mocks onto REST + WS.
Add client, auth store, IDB-backed query cache, offline queue, and
sync bar; hybrid Zustand for UI-only state. Settings still local until
backend has preferences API.
2026-05-23 00:04:28 +02:00

133 lines
4.8 KiB
TypeScript

"use client"
import { MoreVertical, RotateCcw, Trash2 } from "lucide-react"
import { Button } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { useContactsStore } from "@/lib/contacts/contacts-store"
import { useDeleteContact } from "@/lib/api/hooks/use-contact-mutations"
import { fullContactDisplayName } from "@/lib/contacts/types"
import { avatarColor, senderInitial } from "@/lib/sender-display"
import {
CONTACTS_HEADING_TEXT,
CONTACTS_MUTED_TEXT,
CONTACTS_PAGE_BANNER_CLASS,
CONTACTS_PAGE_LINK_BTN_CLASS,
CONTACTS_PAGE_TITLE_CLASS,
CONTACTS_TABLE_HEADER_CLASS,
CONTACTS_TABLE_ROW_CLASS,
CONTACTS_ICON_BTN_CLASS,
} from "@/lib/contacts-chrome-classes"
import { cn } from "@/lib/utils"
export function TrashView() {
const { deletedContacts, restoreContact, emptyTrash } = useContactsStore()
const deleteContactMutation = useDeleteContact()
function formatDate(ts: number): string {
return new Date(ts).toLocaleDateString("fr-FR", {
day: "numeric",
month: "short",
})
}
return (
<div className="px-6 py-4 text-foreground">
{deletedContacts.length > 0 && (
<div className={CONTACTS_PAGE_BANNER_CLASS}>
<p className="text-sm text-foreground">
Les contacts qui sont dans la corbeille depuis plus de 30 jours seront supprimés définitivement
</p>
<button type="button" onClick={emptyTrash} className={cn("shrink-0", CONTACTS_PAGE_LINK_BTN_CLASS)}>
Vider la corbeille
</button>
</div>
)}
<h1 className={cn("mb-4", CONTACTS_PAGE_TITLE_CLASS)}>
Corbeille ({deletedContacts.length})
</h1>
{deletedContacts.length === 0 && (
<p className={cn("py-12 text-center text-sm", CONTACTS_MUTED_TEXT)}>
La corbeille est vide
</p>
)}
{deletedContacts.length > 0 && (
<>
<div
className={cn(
"grid grid-cols-[minmax(0,2fr)_minmax(0,2fr)_minmax(0,1fr)_40px] gap-2",
CONTACTS_TABLE_HEADER_CLASS,
)}
>
<span>Nom</span>
<span>Raison du placement dans la corbeille</span>
<span>Date de suppression</span>
<span />
</div>
{deletedContacts.map((entry) => {
const { contact, deletedAt, reason } = entry
const displayName = fullContactDisplayName(contact)
const name = displayName || contact.emails[0]?.value || "?"
const color = avatarColor(name)
const initial = senderInitial(name)
return (
<div
key={contact.id}
className={cn(
"grid grid-cols-[minmax(0,2fr)_minmax(0,2fr)_minmax(0,1fr)_40px] items-center gap-2 py-3 text-sm",
CONTACTS_TABLE_ROW_CLASS,
)}
>
<span className="flex items-center gap-3">
{contact.avatarUrl ? (
<img src={contact.avatarUrl} alt={name} className="h-8 w-8 rounded-full object-cover" />
) : (
<span
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-xs font-medium text-white"
style={{ backgroundColor: color }}
>
{initial}
</span>
)}
<span className={cn("truncate", CONTACTS_HEADING_TEXT)}>{name}</span>
</span>
<span className={cn("truncate", CONTACTS_MUTED_TEXT)}>{reason}</span>
<span className={CONTACTS_MUTED_TEXT}>{formatDate(deletedAt)}</span>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon" className={cn("h-8 w-8 rounded-full", CONTACTS_ICON_BTN_CLASS)}>
<MoreVertical className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => restoreContact(contact.id)}>
<RotateCcw className="mr-2 h-4 w-4" />
Restaurer
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => deleteContactMutation.mutate({ path: contact.id })}
className="text-red-600 focus:text-red-600"
>
<Trash2 className="mr-2 h-4 w-4" />
Supprimer définitivement
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
)
})}
</>
)}
</div>
)
}