"use client" import { useCallback, useEffect, useMemo, useState } from "react" import Link from "next/link" import { useQueryClient } from "@tanstack/react-query" import { apiClient } from "@/lib/api/client" import { Button } from "@/components/ui/button" import { ArrowLeft, Loader2 } from "lucide-react" import { RichTextDocumentEditor } from "@/components/drive/richtext-document" import { useDriveFileById, useDriveMutations, useDriveShares } from "@/lib/api/hooks/use-drive-queries" import { displayFileBaseName } from "@/lib/drive/display-file-name" import { readDriveEditorReturnTo } from "@/lib/drive/drive-editor-return" import { resolveRenameName } from "@/lib/drive/drive-default-name" import { driveFolderHref } from "@/lib/drive/drive-sidebar-tree" import { resolveDriveEditReturnTo } from "@/lib/drive/drive-url" import { useDriveDocumentTitle } from "@/lib/drive/use-drive-document-title" import { useDriveUIStore } from "@/lib/stores/drive-ui-store" import { colorForGuestId } from "@/lib/drive/guest-editor-identity" import type { RichTextSessionResponse } from "@/lib/drive/richtext-types" import type { DriveFileInfo } from "@/lib/api/types" import { useChromeIdentity } from "@/lib/hooks/use-chrome-identity" function fileNameFromPath(filePath: string): string { return filePath.split("/").filter(Boolean).pop() ?? filePath } function renameTargetPath(filePath: string, newName: string): string { const parent = filePath.replace(/\/[^/]+$/, "") || "/" const base = parent === "/" ? "" : parent return `${base}/${newName}`.replace(/\/+/g, "/") || `/${newName}` } export function RichTextEditor({ fileId }: { fileId: string }) { const queryClient = useQueryClient() const identity = useChromeIdentity() const setSharePath = useDriveUIStore((s) => s.setSharePath) const { data: file, error: fileError, isLoading: fileLoading } = useDriveFileById(fileId) const displayPath = file?.path ?? "" const [session, setSession] = useState(null) const [sessionError, setSessionError] = useState(null) const [renameSignal, setRenameSignal] = useState(0) const fileName = file?.name ?? fileNameFromPath(displayPath) const title = displayFileBaseName(fileName) useDriveDocumentTitle(title) const [backHref, setBackHref] = useState("/drive") useEffect(() => { if (!displayPath) return setBackHref( resolveDriveEditReturnTo( null, displayPath, (folderPath) => driveFolderHref("files", folderPath), readDriveEditorReturnTo() ) ) }, [displayPath]) const { data: sharesData } = useDriveShares(displayPath, Boolean(displayPath)) const { rename } = useDriveMutations() const refreshFile = useCallback(async () => { await queryClient.invalidateQueries({ queryKey: ["drive", "file", fileId] }) }, [fileId, queryClient]) useEffect(() => { if (!displayPath) return let cancelled = false setSession(null) setSessionError(null) void (async () => { try { const res = await apiClient.post("/richtext/session", { path: displayPath, mode: "edit", }) if (!cancelled) setSession(res) } catch (e) { if (!cancelled) { setSessionError(e instanceof Error ? e.message : "Impossible d'ouvrir le document") } } })() return () => { cancelled = true } }, [displayPath]) const handleRename = useCallback( async (input: string) => { if (!displayPath) return const newName = resolveRenameName({ name: fileName, type: "file" }, input) if (displayFileBaseName(fileName) === input.trim()) return await rename.mutateAsync({ path: displayPath, new_name: newName }) await refreshFile() }, [displayPath, fileName, refreshFile, rename] ) const openShare = useCallback(() => { if (displayPath) setSharePath(displayPath) }, [displayPath, setSharePath]) const moveFile = useMemo((): DriveFileInfo | undefined => { if (!file || !displayPath) return undefined return { ...file, path: displayPath, name: fileName, type: "file", } }, [displayPath, file, fileName]) const handleFileMoved = useCallback( async (_newPath: string) => { await refreshFile() }, [refreshFile] ) const collabUserName = identity?.name?.trim() || identity?.email || "Utilisateur" const collabUserColor = colorForGuestId(identity?.email ?? collabUserName) const chrome = useMemo( () => ({ title, onRename: handleRename, renameDisabled: rename.isPending, backHref, backLabel: "Drive", showBack: true, shares: sharesData?.shares ?? [], onShareClick: openShare, showShare: true, showAccount: true, moveFile, onFileMoved: handleFileMoved, file: moveFile, onRenameRequest: () => setRenameSignal((value) => value + 1), renameSignal, }), [ title, handleRename, rename.isPending, backHref, sharesData?.shares, openShare, moveFile, handleFileMoved, renameSignal, ] ) const error = fileError instanceof Error ? fileError.message : sessionError if (fileLoading) { return (
) } if (error || !file) { return (

{error ?? "Document introuvable"}

) } return (
{!session ? (
) : ( )}
) }