"use client" import { useMemo, useState } from "react" import { ChevronRight, Folder } from "lucide-react" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { useDriveList, useDriveMutations } from "@/lib/api/hooks/use-drive-queries" import type { DriveFileInfo } from "@/lib/api/types" import { displayFileName } from "@/lib/drive/display-file-name" import { DRIVE_BTN_GHOST, DRIVE_BTN_PRIMARY, DRIVE_DIALOG_CONTENT, DRIVE_DIALOG_DIVIDER, DRIVE_DIALOG_FOOTER, DRIVE_DIALOG_OVERLAY, DRIVE_TEXT_PRIMARY, DRIVE_TEXT_SECONDARY, DRIVE_TEXT_TITLE, } from "@/lib/drive/drive-dialog-styles" import { copyDriveItemsToFolder, isMoveDestinationBlocked, moveDriveItemsToFolder, } from "@/lib/drive/drive-move-items" import { normalizeDriveFolderPath } from "@/lib/drive/drive-sidebar-tree" import { cn } from "@/lib/utils" export type DriveFolderPickerMode = "move" | "copy" export function DriveMoveDialog({ open, onOpenChange, sources, onMoved, mode = "move", }: { open: boolean onOpenChange: (open: boolean) => void sources: DriveFileInfo[] onMoved?: () => void mode?: DriveFolderPickerMode }) { const [browsePath, setBrowsePath] = useState("/") const mutations = useDriveMutations() const list = useDriveList(browsePath, 1, "", open) const sourcePaths = useMemo(() => new Set(sources.map((s) => s.path)), [sources]) const isCopy = mode === "copy" const folders = useMemo( () => (list.data?.files ?? []).filter( (f) => f.type === "directory" && !sourcePaths.has(f.path) ), [list.data?.files, sourcePaths] ) const crumbs = useMemo(() => { const normalized = normalizeDriveFolderPath(browsePath) if (normalized === "/") return [{ path: "/", label: "Mon Drive" }] const parts = normalized.slice(1).split("/") const out: { path: string; label: string }[] = [{ path: "/", label: "Mon Drive" }] for (let i = 0; i < parts.length; i++) { const path = "/" + parts.slice(0, i + 1).join("/") out.push({ path, label: displayFileName(parts[i]!) }) } return out }, [browsePath]) const blockedDestination = isMoveDestinationBlocked(sources, browsePath) const confirm = async () => { if (blockedDestination) { toast.error( isCopy ? "Impossible de copier un dossier dans lui-même" : "Impossible de déplacer un dossier dans lui-même" ) return } try { if (isCopy) { await copyDriveItemsToFolder(sources, browsePath, (body) => mutations.copy.mutateAsync(body) ) toast.success(sources.length > 1 ? "Éléments copiés" : "Élément copié") } else { await moveDriveItemsToFolder(sources, browsePath, (body) => mutations.move.mutateAsync(body) ) toast.success(sources.length > 1 ? "Éléments déplacés" : "Élément déplacé") } onOpenChange(false) onMoved?.() } catch { toast.error(isCopy ? "Impossible de copier" : "Impossible de déplacer") } } const pending = isCopy ? mutations.copy.isPending : mutations.move.isPending const titleVerb = isCopy ? "Copier" : "Déplacer" const countLabel = sources.length > 1 ? `${sources.length} éléments` : "l'élément" return ( { if (next) setBrowsePath("/") onOpenChange(next) }} > {titleVerb} {countLabel} {isCopy ? `Choisir le dossier de destination pour copier ${countLabel}.` : `Choisir le dossier de destination pour déplacer ${countLabel}.`}
{crumbs.map((crumb, i) => ( {i > 0 ? ( ) : null} ))}
{list.isLoading ? (

Chargement…

) : folders.length === 0 ? (

Aucun sous-dossier

) : ( folders.map((folder) => ( )) )}
) }