"use client" import { useEffect, useMemo, useRef } from "react" import { useRouter } from "next/navigation" import { Upload, FolderPlus } from "lucide-react" import { toast } from "sonner" import { FileBrowser } from "@/components/drive/file-browser" import { DriveFilterBar } from "@/components/drive/drive-filter-bar" import { DriveViewModeToggle } from "@/components/drive/drive-view-mode-toggle" import { DriveSortMenu } from "@/components/drive/drive-sort-menu" import { DriveBulkToolbar } from "@/components/drive/drive-bulk-toolbar" import { DriveMarqueeSurface } from "@/components/drive/drive-marquee-surface" import { DriveScrollEndSpacer } from "@/components/drive/drive-scroll-end-spacer" import { Button } from "@/components/ui/button" import { usePublicShareMenuMutations, usePublicShareMutations } from "@/lib/api/hooks/use-public-share-mutations" import type { DriveFileInfo } from "@/lib/api/types" import { useDriveSettingsStore } from "@/lib/stores/drive-settings-store" import { useDriveFilteredItems } from "@/lib/hooks/use-drive-filtered-items" import { useDriveFiltersStore } from "@/lib/stores/drive-filters-store" import { sharePermCanCreate, sharePermCanDelete, sharePermCanEdit, sharePermCanUpdate, } from "@/lib/drive/drive-share-permissions" import { openPublicShareItem, downloadPublicShareFile } from "@/lib/drive/open-public-share-item" import { useDriveUIStore } from "@/lib/stores/drive-ui-store" import { DRIVE_BROWSER_CARD_CLASS, DRIVE_CARD_PAD_X, DRIVE_CARD_SCROLL_PT, DRIVE_FILTER_CONTENT_GAP, } from "@/lib/drive/drive-chrome-classes" import { cn } from "@/lib/utils" import { nextUntitledName } from "@/lib/drive/drive-default-name" export function PublicShareFolderView({ token, folderPath, files, permissions, password, folderTitle, }: { token: string folderPath: string files: DriveFileInfo[] permissions: number password?: string folderTitle: string }) { const router = useRouter() const openPreview = useDriveUIStore((s) => s.openPreview) const selectedPaths = useDriveUIStore((s) => s.selectedPaths) const clearSelection = useDriveUIStore((s) => s.clearSelection) const sortField = useDriveSettingsStore((s) => s.sortField) const sortDir = useDriveSettingsStore((s) => s.sortDir) const folderPlacement = useDriveSettingsStore((s) => s.folderPlacement) const filters = useDriveFiltersStore() const uploadInputRef = useRef(null) const canEdit = sharePermCanEdit(permissions) const canCreate = sharePermCanCreate(permissions) const canUpdate = sharePermCanUpdate(permissions) const canDelete = sharePermCanDelete(permissions) const writable = canUpdate || canDelete const mutations = usePublicShareMenuMutations(token, password) const { uploadFile, createFolder } = usePublicShareMutations(token, password) const filtersSnapshot = useMemo( () => ({ types: filters.types, sources: filters.sources, contactEmail: filters.contactEmail, contactName: filters.contactName, datePreset: filters.datePreset, dateFrom: filters.dateFrom, dateTo: filters.dateTo, }), [ filters.types, filters.sources, filters.contactEmail, filters.contactName, filters.datePreset, filters.dateFrom, filters.dateTo, ] ) const { filteredItems: filteredFiles } = useDriveFilteredItems( files, filtersSnapshot, { sortField, sortDir, folderPlacement }, { scopePath: folderPath } ) const selectedTargets = useMemo( () => filteredFiles.filter((f) => selectedPaths.has(f.path)), [filteredFiles, selectedPaths] ) const showBulk = selectedTargets.length > 0 useEffect(() => { clearSelection() }, [folderPath, clearSelection]) const openItem = (file: DriveFileInfo) => { openPublicShareItem(file, { token, password, canEdit: sharePermCanEdit(permissions), router, openPreview, contextItems: filteredFiles, }) } const handleUpload = async (fileList: FileList | null) => { if (!fileList?.length || !canCreate) return const base = folderPath === "/" ? "" : folderPath try { for (const file of Array.from(fileList)) { await uploadFile(`${base}/${file.name}`.replace(/\/+/g, "/"), file) } toast.success("Fichier(s) importé(s)") } catch { toast.error("Impossible d’importer le fichier") } } const handleNewFolder = async () => { if (!canCreate) return const name = nextUntitledName( filteredFiles.filter((f) => f.type === "directory").map((f) => f.name), "Dossier" ) const base = folderPath === "/" ? "" : folderPath const path = `${base}/${name}`.replace(/\/+/g, "/") try { await createFolder.mutateAsync(path) toast.success("Dossier créé") } catch { toast.error("Impossible de créer le dossier") } } const downloadBulk = async (targets: DriveFileInfo[]) => { for (const file of targets) { await downloadPublicShareFile(token, file, password) } } return (

{folderTitle} {" · "} {filteredFiles.length} élément{filteredFiles.length > 1 ? "s" : ""} {canEdit ? " · Éditeur" : " · Lecture seule"}

{canCreate ? ( <> void handleUpload(e.target.files)} /> ) : null}
{showBulk ? ( ) : ( )}
0} className="min-h-full" > {files.length === 0 ? (

Ce dossier est vide. {canCreate ? " Importez un fichier ou créez un dossier." : ""}

) : filteredFiles.length === 0 ? (

Aucun élément ne correspond aux filtres.

) : ( void downloadPublicShareFile(token, file, password).catch(() => toast.error("Téléchargement impossible") ) } /> )}
) }