"use client"; import { useState, useEffect } from "react"; import { motion } from "framer-motion"; import { Plus, Trash2, Edit2, Users, UserPlus, UserMinus } from "lucide-react"; import Button from "../ui/Button"; import Modal from "../ui/Modal"; import UserAvatar from "../ui/UserAvatar"; import { EmptyState } from "../ui/PageHeader"; import toast from "react-hot-toast"; import { formatFileSize } from "@/lib/utils"; interface MemberData { id: string; user: { id: string; name: string | null; username: string | null }; } interface SpaceData { id: string; name: string; quotaBytes: number; usedBytes: number; createdAt: string; _count: { members: number; folders: number }; members: MemberData[]; } interface UserOption { id: string; name: string | null; username: string | null; } const inputClasses = "field h-11 mb-4"; export default function SharedSpaceManagement() { const [spaces, setSpaces] = useState([]); const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [showCreate, setShowCreate] = useState(false); const [editSpace, setEditSpace] = useState(null); const [form, setForm] = useState({ name: "", memberIds: [] as string[] }); const [toDelete, setToDelete] = useState(null); const fetchData = async () => { const [spacesRes, usersRes] = await Promise.all([ fetch("/api/shared-spaces"), fetch("/api/users"), ]); if (spacesRes.ok) setSpaces(await spacesRes.json()); if (usersRes.ok) setUsers(await usersRes.json()); setLoading(false); }; useEffect(() => { fetchData(); }, []); const handleCreate = async () => { const res = await fetch("/api/shared-spaces", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(form), }); if (res.ok) { toast.success("Espace créé"); setShowCreate(false); setForm({ name: "", memberIds: [] }); fetchData(); } else { toast.error("Erreur lors de la création"); } }; const handleDelete = async () => { if (!toDelete) return; const res = await fetch(`/api/shared-spaces/${toDelete.id}`, { method: "DELETE" }); setToDelete(null); if (res.ok) { toast.success("Espace supprimé"); fetchData(); } else toast.error("Erreur"); }; const handleRename = async () => { if (!editSpace) return; const res = await fetch(`/api/shared-spaces/${editSpace.id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: editSpace.name }), }); if (res.ok) { toast.success("Renommé"); setEditSpace(null); fetchData(); } else toast.error("Erreur"); }; const handleAddMember = async (spaceId: string, userId: string) => { const res = await fetch(`/api/shared-spaces/${spaceId}/members`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ userId }), }); if (res.ok) { toast.success("Membre ajouté"); fetchData(); } else toast.error("Déjà membre ou erreur"); }; const handleRemoveMember = async (spaceId: string, userId: string) => { const res = await fetch(`/api/shared-spaces/${spaceId}/members`, { method: "DELETE", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ userId }), }); if (res.ok) { toast.success("Membre retiré"); fetchData(); } else toast.error("Erreur"); }; const toggleMember = (userId: string) => { setForm((f) => ({ ...f, memberIds: f.memberIds.includes(userId) ? f.memberIds.filter((id) => id !== userId) : [...f.memberIds, userId], })); }; if (loading) { return (
{[0, 1].map((i) => (
))}
); } return (

{spaces.length} espace{spaces.length !== 1 ? "s" : ""}

{spaces.length === 0 && ( setShowCreate(true)}> Créer un espace} /> )}
{spaces.map((space) => { const percent = space.quotaBytes > 0 ? Math.min(Math.round((space.usedBytes / space.quotaBytes) * 100), 100) : 0; const memberUserIds = space.members.map((m) => m.user.id); const nonMembers = users.filter((u) => !memberUserIds.includes(u.id)); return ( {/* Header */}

{space.name}

{space._count.members} membre{space._count.members !== 1 ? "s" : ""} · {space._count.folders} dossier{space._count.folders !== 1 ? "s" : ""}

{/* Storage quota */}
Stockage utilisé {formatFileSize(space.usedBytes)} / {formatFileSize(space.quotaBytes)}
90 ? "bg-rose-500" : percent > 70 ? "bg-amber-500" : "bg-accent-gradient"}`} style={{ width: `${Math.max(1, percent)}%` }} />

{percent}% utilisé

{/* Members */}

Membres

{space.members.map((m) => (
{m.user.name || m.user.username}
))} {space.members.length === 0 && (

Aucun membre pour l'instant

)}
{/* Add member */} {nonMembers.length > 0 && (
)}
); })}
{/* Create modal */} { setShowCreate(false); setForm({ name: "", memberIds: [] }); }} title="Nouvel espace partagé"> setForm({ ...form, name: e.target.value })} className={inputClasses} autoFocus /> {users.length > 0 && (

Membres

{users.map((u) => ( ))}
)}

Quota : 500 Go par défaut

setToDelete(null)} title="Supprimer cet espace partagé ?" description={toDelete?.name} footer={<>} >

Les dossiers seront conservés mais retirés de l'espace ; les membres perdront l'accès partagé.

{/* Edit modal */} setEditSpace(null)} title="Modifier l'espace"> {editSpace && ( <> setEditSpace({ ...editSpace, name: e.target.value })} className={inputClasses} autoFocus />
)}
); }