import { useCallback, useEffect, useRef, useState } from 'react'
import { ArrowLeft, Download, File, Folder, FolderOpen, LoaderCircle, Eye, X, Image, FileText, ShieldCheck, Maximize2, Minimize2 } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { drive, message, publicFileUrl } from '@/api/client'
import { fmtSize } from '@/lib/drive-format'
function typeOf(item) {
const n = (item.name || '').toLowerCase(), m=(item.mime_type || '').toLowerCase()
if(m.startsWith('image/') && m!=='image/svg+xml' || /\.(png|jpe?g|gif|webp|bmp|avif)$/.test(n)) return 'image'
if(n.endsWith('.docx'))return 'word'
if(m==='application/pdf' || n.endsWith('.pdf'))return 'pdf'
if(m.startsWith('video/') || /\.(mp4|webm|mov|m4v|ogv)$/.test(n))return 'video'
if(m.startsWith('audio/') || /\.(mp3|ogg|wav|m4a|flac|aac)$/.test(n))return 'audio'
if(m.startsWith('text/') || /\.(txt|md|json|csv|xml|log|py|js|css)$/.test(n))return 'text'
return null
}
function Viewer({item,token,fullscreen}) {
const kind=typeOf(item)
const src=publicFileUrl(token,item.id,true)
const mediaHeight=fullscreen?'max-h-[calc(100dvh-5rem)]':'max-h-[72vh]'
const frameHeight=fullscreen?'h-[calc(100dvh-5rem)]':'h-[70vh]'
if(kind==='image')return
if(kind==='word')return
if(kind==='pdf')return
if(kind==='video')return
if(kind==='audio')return
if(kind==='text')return
return
Aperçu indisponible pour ce format.
}
export default function PublicSharePage({token}) {
const [parent,setParent]=useState(null)
const [data,setData]=useState(null)
const [selected,setSelected]=useState(null)
const [error,setError]=useState('')
const [loading,setLoading]=useState(true)
const viewerRef=useRef(null)
const [fullscreen,setFullscreen]=useState(false)
const [fullscreenSupported,setFullscreenSupported]=useState(false)
useEffect(()=>{
setFullscreenSupported(Boolean(document.fullscreenEnabled))
const update=()=>setFullscreen(document.fullscreenElement===viewerRef.current)
document.addEventListener('fullscreenchange', update)
return ()=>document.removeEventListener('fullscreenchange', update)
},[])
const closeViewer=()=>{
if(document.fullscreenElement===viewerRef.current) document.exitFullscreen?.().catch(()=>{})
setSelected(null)
}
const toggleFullscreen=async()=>{
try {
if(document.fullscreenElement===viewerRef.current) await document.exitFullscreen()
else await viewerRef.current?.requestFullscreen()
} catch {
// Browsers may deny fullscreen; leave the normal viewer usable.
}
}
const load=useCallback(async()=>{
setLoading(true)
try { setData(await drive.publicBrowse(token,parent));setError('') }
catch(e){setError(e?.response?.status===404?'Ce lien a expiré ou n’est plus disponible.':message(e))}
finally{setLoading(false)}
},[token,parent])
useEffect(()=>{load()},[load])
// A public file link first shows its details; preview starts only on "Ouvrir".
useEffect(()=>{setSelected(null)},[token])
const previous=()=>setParent(data?.breadcrumb?.length>1?data.breadcrumb.at(-2).id:null)
const items=data?.items || []
return
{loading ? Chargement…
: error ? {error}
: data && <>
Partage public en lecture seule
{data.root.name}
{data.root.is_folder ?
{parent ? data.breadcrumb?.map(i=>i.name).join(' / ') : `${items.length} élément${items.length>1?'s':''}`}
:
{fmtSize(data.root.size)}
}
{data.root.is_folder &&
{parent &&
}
{items.length ? items.map(item=>
{item.is_folder?:typeOf(item)==='image'?:typeOf(item)==='pdf'?:}
{!item.is_folder &&
}
):
Ce dossier est vide.
}
}
{!data.root.is_folder &&
Télécharger
}
>}
{selected &&
{selected.name}
{fullscreenSupported && !['video', 'audio'].includes(typeOf(selected)) &&
}
Télécharger
}
}