ultisuite-client/components/gmail/move-to-menu-items.tsx
R3D347HR4Y 9266aa34cd huhu
2026-05-19 22:20:43 +02:00

151 lines
4.3 KiB
TypeScript

"use client"
import { useMemo, type ReactNode } from "react"
import {
Clock,
Inbox,
Send,
FileEdit,
ShieldAlert,
Trash2,
} from "lucide-react"
import {
DropdownMenuItem,
DropdownMenuSeparator,
} from "@/components/ui/dropdown-menu"
import type { FolderTreeNode } from "@/lib/sidebar-nav-data"
export type MailMoveTargets = {
recents: MoveTarget[]
system: MoveTarget[]
folders: MoveTarget[]
}
export type MoveTarget = {
id: string
label: string
icon?: ReactNode
depth: number
isFolder?: boolean
isRecent?: boolean
color?: string
}
const SYSTEM_DESTINATIONS: MoveTarget[] = [
{ id: "inbox", label: "Boîte de réception", icon: <Inbox className="size-4 shrink-0 text-[#5f6368]" strokeWidth={1.5} />, depth: 0 },
{ id: "sent", label: "Messages envoyés", icon: <Send className="size-4 shrink-0 text-[#5f6368]" strokeWidth={1.5} />, depth: 0 },
{ id: "drafts", label: "Brouillons", icon: <FileEdit className="size-4 shrink-0 text-[#5f6368]" strokeWidth={1.5} />, depth: 0 },
{ id: "spam", label: "Spam", icon: <ShieldAlert className="size-4 shrink-0 text-[#5f6368]" strokeWidth={1.5} />, depth: 0 },
{ id: "trash", label: "Corbeille", icon: <Trash2 className="size-4 shrink-0 text-[#5f6368]" strokeWidth={1.5} />, depth: 0 },
]
function flattenFolderTree(
nodes: FolderTreeNode[],
depth: number = 0
): MoveTarget[] {
const out: MoveTarget[] = []
for (const n of nodes) {
out.push({
id: n.id,
label: n.label,
icon: (
<span
className={`inline-block size-3 shrink-0 rounded-sm ${n.color ?? "bg-slate-400"}`}
/>
),
depth,
isFolder: true,
color: n.color,
})
if (n.children?.length) {
out.push(...flattenFolderTree(n.children, depth + 1))
}
}
return out
}
export function useMoveTargets({
folderTree,
recentMoveTargets,
currentFolderId,
}: {
folderTree: FolderTreeNode[]
recentMoveTargets: string[]
currentFolderId: string
}): { recents: MoveTarget[]; system: MoveTarget[]; folders: MoveTarget[] } {
return useMemo(() => {
const allSystem = SYSTEM_DESTINATIONS.filter((d) => d.id !== currentFolderId)
const allFolders = flattenFolderTree(folderTree).filter(
(f) => f.id !== currentFolderId
)
const allById = new Map<string, MoveTarget>()
for (const t of allSystem) allById.set(t.id, t)
for (const t of allFolders) allById.set(t.id, t)
const recents: MoveTarget[] = []
for (const rid of recentMoveTargets) {
if (rid === currentFolderId) continue
const target = allById.get(rid)
if (target) recents.push({ ...target, isRecent: true, depth: 0 })
}
return { recents, system: allSystem, folders: allFolders }
}, [folderTree, recentMoveTargets, currentFolderId])
}
export function MoveToDropdownItems({
targets,
onMoveTo,
}: {
targets: MailMoveTargets
onMoveTo: (targetId: string) => void
}) {
return (
<>
{targets.recents.length > 0 && (
<>
<div className="px-3 py-1.5 text-[11px] font-medium uppercase tracking-wide text-[#5f6368]">
Récents
</div>
{targets.recents.map((t) => (
<DropdownMenuItem key={`recent-${t.id}`} onSelect={() => onMoveTo(t.id)}>
<span className="flex items-center gap-2">
{t.icon}
<Clock className="size-3 shrink-0 text-[#9aa0a6]" strokeWidth={1.5} />
</span>
{t.label}
</DropdownMenuItem>
))}
<DropdownMenuSeparator />
</>
)}
{targets.system.map((t) => (
<DropdownMenuItem key={t.id} onSelect={() => onMoveTo(t.id)}>
{t.icon}
{t.label}
</DropdownMenuItem>
))}
{targets.folders.length > 0 && (
<>
<DropdownMenuSeparator />
<div className="px-3 py-1.5 text-[11px] font-medium uppercase tracking-wide text-[#5f6368]">
Dossiers
</div>
{targets.folders.map((t) => (
<DropdownMenuItem
key={t.id}
onSelect={() => onMoveTo(t.id)}
style={{ paddingLeft: `${12 + t.depth * 16}px` }}
>
{t.icon}
{t.label}
</DropdownMenuItem>
))}
</>
)}
</>
)
}
export { SYSTEM_DESTINATIONS, flattenFolderTree }