"use client" import { useCallback, useEffect, useMemo, useRef, useState } from "react" import { useRouter } from "next/navigation" import Link from "next/link" import { apiClient } from "@/lib/api/client" import { getOnlyOfficeUrl } from "@/lib/runtime-config" import { Button } from "@/components/ui/button" import { ArrowLeft } from "lucide-react" import { OnlyOfficeMount } from "@/components/drive/onlyoffice-mount" import { OfficeEditorChrome } from "@/components/drive/office-editor-chrome" import { useDriveMutations, useDriveShares } from "@/lib/api/hooks/use-drive-queries" import { displayFileBaseName } from "@/lib/drive/display-file-name" import { resolveRenameName } from "@/lib/drive/drive-default-name" import { driveFolderHref } from "@/lib/drive/drive-sidebar-tree" import { buildDriveEditHref, resolveDriveEditReturnTo } from "@/lib/drive/drive-url" import { resolveOnlyOfficeEditorKind } from "@/lib/drive/onlyoffice-formats" import { useDriveDocumentTitle } from "@/lib/drive/use-drive-document-title" import { useDriveUIStore } from "@/lib/stores/drive-ui-store" 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 OfficeEditor({ filePath, returnTo, }: { filePath: string returnTo?: string | null }) { const router = useRouter() const instanceSeq = useRef(0) const setSharePath = useDriveUIStore((s) => s.setSharePath) const [config, setConfig] = useState | null>(null) const [serverUrl, setServerUrl] = useState("") const [editorId, setEditorId] = useState(null) const [error, setError] = useState(null) const [displayPath, setDisplayPath] = useState(filePath) useEffect(() => { setDisplayPath(filePath) }, [filePath]) const fileName = fileNameFromPath(displayPath) const title = displayFileBaseName(fileName) const editorKind = resolveOnlyOfficeEditorKind({ name: fileName }) useDriveDocumentTitle(title, editorKind) const backHref = useMemo( () => resolveDriveEditReturnTo(returnTo, displayPath, (folderPath) => driveFolderHref("files", folderPath) ), [returnTo, displayPath] ) const { data: sharesData } = useDriveShares(displayPath, Boolean(displayPath)) const { rename } = useDriveMutations() const handleEditorError = useCallback((message: string) => { setError(message) }, []) useEffect(() => { let cancelled = false setConfig(null) setServerUrl("") setEditorId(null) setError(null) void (async () => { try { const res = await apiClient.post<{ config: Record serverUrl: string }>("/office/session", { path: displayPath, mode: "edit" }) if (cancelled) return instanceSeq.current += 1 setConfig(res.config) setServerUrl(res.serverUrl || getOnlyOfficeUrl() || "") setEditorId(`ultidrive-editor-${instanceSeq.current}`) } catch { if (!cancelled) setError("Impossible de charger l’éditeur.") } })() return () => { cancelled = true } }, [displayPath]) const handleRename = useCallback( async (input: string) => { const newName = resolveRenameName( { name: fileName, type: "file" }, input ) if (displayFileBaseName(fileName) === input.trim()) return await rename.mutateAsync({ path: displayPath, new_name: newName }) const nextPath = renameTargetPath(displayPath, newName) setDisplayPath(nextPath) router.replace(buildDriveEditHref(nextPath, returnTo ?? undefined)) }, [displayPath, fileName, rename, returnTo, router] ) const openShareDialog = useCallback(() => { setSharePath(displayPath, "file") }, [displayPath, setSharePath]) if (error) { return (

{error}

) } if (!config || !editorId || !serverUrl) { return

Ouverture du document…

} const docServer = serverUrl.replace(/\/$/, "") return (
) }