"use client" import { useState } from "react" import { Copy, Download, FolderInput, Link2, MoreVertical, Trash2, Undo2, UserPlus, X, } from "lucide-react" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { DriveMoveDialog, type DriveFolderPickerMode } from "@/components/drive/drive-move-dialog" import { canShareDriveItem, DriveFileMenuActions, } from "@/components/drive/drive-file-menu-actions" import { DRIVE_MENU_SURFACE_CLASS } from "@/components/drive/drive-file-context-menu" import { useDriveMutations } from "@/lib/api/hooks/use-drive-queries" import { downloadDriveFile } from "@/lib/api/drive-download" import type { DriveFileInfo } from "@/lib/api/types" import { useDriveUIStore } from "@/lib/stores/drive-ui-store" import { DRIVE_CARD_PAD_X } from "@/lib/drive/drive-chrome-classes" import { DRIVE_ICON_BTN } from "@/lib/drive/drive-chrome-classes" import { cn } from "@/lib/utils" import { driveTrashItemKey } from "@/lib/drive/drive-trash" function BulkIconButton({ label, onClick, disabled, children, className, }: { label: string onClick: () => void disabled?: boolean children: React.ReactNode className?: string }) { return ( ) } export function DriveBulkToolbar({ targets, isTrash, allowShare = true, allowMove = true, allowCopy = true, allowQuickLink = true, allowDelete = true, mutations: mutationsProp, onDownloadBulk, }: { targets: DriveFileInfo[] isTrash?: boolean allowShare?: boolean allowMove?: boolean allowCopy?: boolean allowQuickLink?: boolean allowDelete?: boolean mutations?: ReturnType onDownloadBulk?: (files: DriveFileInfo[]) => Promise }) { const clearSelection = useDriveUIStore((s) => s.clearSelection) const setSharePath = useDriveUIStore((s) => s.setSharePath) const mutationsDefault = useDriveMutations() const mutations = mutationsProp ?? mutationsDefault const [folderPickerMode, setFolderPickerMode] = useState(null) const [moreOpen, setMoreOpen] = useState(false) const n = targets.length if (n === 0) return null const single = n === 1 ? targets[0]! : null const canShare = Boolean( !isTrash && allowShare && single && canShareDriveItem(single) ) const run = async (fn: () => Promise, ok: string, err: string) => { try { await fn() toast.success(ok) clearSelection() } catch { toast.error(err) } } const onShare = () => { if (!canShare || !single) { toast.error("Sélectionnez un seul élément pour partager") return } setSharePath(single.path, single.type) } const onDownload = async () => { const files = targets.filter((t) => t.type === "file") if (files.length === 0) { toast.error("Aucun fichier à télécharger") return } try { if (onDownloadBulk) { await onDownloadBulk(files) } else { for (const file of files) { await downloadDriveFile(file.path, file.name, file.name) } } toast.success( files.length > 1 ? `${files.length} fichiers téléchargés` : "Fichier téléchargé" ) } catch { toast.error("Impossible de télécharger") } } const onQuickLink = async () => { if (!single) { toast.error("Sélectionnez un seul élément pour obtenir un lien") return } try { const share = await mutations.createShare.mutateAsync({ path: single.path, role: "viewer", mode: "public", }) if (share.url) { await navigator.clipboard.writeText(share.url) toast.success("Lien copié") } else { toast.success("Lien de partage créé") } } catch { toast.error("Impossible de créer le lien") } } const onDelete = () => void run( async () => { for (const f of targets) { await mutations.deleteFile.mutateAsync(f.path) } }, n > 1 ? "Éléments supprimés" : "Élément supprimé", "Impossible de supprimer" ) const onPermanentDelete = () => void run( async () => { for (const f of targets) { await mutations.deleteTrash.mutateAsync(driveTrashItemKey(f)) } }, n > 1 ? "Éléments supprimés définitivement" : "Élément supprimé définitivement", "Impossible de supprimer définitivement" ) const onRestore = () => void run( async () => { for (const f of targets) { await mutations.restore.mutateAsync(driveTrashItemKey(f)) } }, n > 1 ? "Éléments restaurés" : "Élément restauré", "Impossible de restaurer" ) const noopOpen = () => {} return ( <> { if (!open) setFolderPickerMode(null) }} mode={folderPickerMode ?? "move"} sources={targets} onMoved={clearSelection} />
{n} sélectionné{n > 1 ? "s" : ""}
{isTrash ? ( <> ) : ( <> {allowShare ? ( ) : null} void onDownload()}> {allowCopy ? ( setFolderPickerMode("copy")} > ) : null} {allowMove ? ( setFolderPickerMode("move")} > ) : null} {allowDelete ? ( ) : null} {allowQuickLink ? ( void onQuickLink()} disabled={!single} > ) : null} e.preventDefault()} > setMoreOpen(false)} setSharePath={setSharePath} mutations={mutations} onRenameRequest={() => setMoreOpen(false)} onMoveRequest={ isTrash || !allowMove ? undefined : () => { setMoreOpen(false) window.setTimeout(() => setFolderPickerMode("move"), 0) } } onCopyRequest={ isTrash || !allowCopy ? undefined : () => { setMoreOpen(false) window.setTimeout(() => setFolderPickerMode("copy"), 0) } } onQuickLinkRequest={ isTrash || !allowQuickLink || !single ? undefined : () => { setMoreOpen(false) window.setTimeout(() => void onQuickLink(), 0) } } /> )}
) }