42 lines
3.0 KiB
JavaScript
42 lines
3.0 KiB
JavaScript
import { useCallback, useEffect, useState } from 'react'
|
||
import { ArrowLeft, Download, File, Folder, LoaderCircle } from 'lucide-react'
|
||
import { Button } from '@/components/ui/button'
|
||
import { drive, message, publicFileUrl } from '@/api/client'
|
||
|
||
export default function PublicSharePage({token}) {
|
||
const [parent,setParent] = useState(null)
|
||
const [data,setData] = useState(null)
|
||
const [error,setError] = useState('')
|
||
const [loading,setLoading] = useState(true)
|
||
const load = useCallback(async()=>{
|
||
setLoading(true)
|
||
try {setData(await drive.publicBrowse(token,parent));setError('')}
|
||
catch(e){setError(e?.response?.status===404 ? 'Ce lien est invalide ou n’est plus disponible.' : message(e))}
|
||
finally{setLoading(false)}
|
||
},[token,parent])
|
||
useEffect(()=>{load()},[load])
|
||
const folderBack = () => {
|
||
if(!data?.breadcrumb?.length || data.breadcrumb.length<=1) {setParent(null);return}
|
||
setParent(data.breadcrumb.at(-2).id)
|
||
}
|
||
return <div className="min-h-dvh bg-background px-4 py-10">
|
||
<main className="mx-auto max-w-3xl rounded-2xl border bg-card p-5 shadow-sm sm:p-8">
|
||
<div className="mb-6 flex items-center gap-3"><img src="/icon.png" alt="GoodDrive" className="size-10"/><div><h1 className="text-xl font-bold">GoodDrive</h1><p className="text-sm text-muted-foreground">Fichier partagé publiquement</p></div></div>
|
||
{loading ? <p className="flex items-center gap-2"><LoaderCircle className="size-4 animate-spin"/> Chargement…</p> : error ? <p className="text-destructive" role="alert">{error}</p> : data && <>
|
||
<h2 className="mb-5 break-all text-lg font-semibold">{data.root.name}</h2>
|
||
{data.root.is_folder && <>
|
||
<div className="mb-3 flex items-center gap-2">
|
||
{!!parent && <Button variant="outline" size="sm" onClick={folderBack}><ArrowLeft className="size-4"/> Retour</Button>}
|
||
<span className="truncate text-sm text-muted-foreground">{data.breadcrumb?.map(node=>node.name).join(' / ')}</span>
|
||
</div>
|
||
<div className="divide-y rounded-lg border">{data.items?.length ? data.items.map(item=><div key={item.id} className="flex items-center justify-between gap-3 p-3">
|
||
<div className="flex min-w-0 items-center gap-2">{item.is_folder?<Folder className="size-5 shrink-0"/>:<File className="size-5 shrink-0"/>}<span className="truncate text-sm">{item.name}</span></div>
|
||
{item.is_folder ? <Button size="sm" variant="outline" onClick={()=>setParent(item.id)}>Ouvrir</Button> : <a className="grid size-8 place-items-center rounded-lg border hover:bg-muted" title="Télécharger" href={publicFileUrl(token,item.id)}><Download className="size-4"/></a>}
|
||
</div>) : <p className="p-4 text-sm text-muted-foreground">Ce dossier est vide.</p>}</div>
|
||
</>}
|
||
{!data.root.is_folder && <a className="inline-flex h-9 items-center gap-2 rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground" href={publicFileUrl(token,data.root.id)}><Download className="size-4"/> Télécharger {data.root.name}</a>}
|
||
</>}
|
||
</main>
|
||
</div>
|
||
}
|