"use client"; import { useState, useEffect } from "react"; import Link from "next/link"; import { useParams } from "next/navigation"; import { ArrowLeft, Download, Film } from "lucide-react"; import { api } from "@/lib/api"; import { Navbar } from "@/components/public/Navbar"; import { Footer } from "@/components/public/Footer"; interface MediaItem { id: string; slug: string; type: "image" | "video"; mimeType: string; size: number; originalFilename: string; createdAt: string; url: string; title?: string; description?: string; altText?: string; } function extractUlid(slugParam: string): string { const parts = slugParam.split("-"); return parts[parts.length - 1]; } function formatFileSize(bytes: number): string { if (bytes < 1024) return `${bytes} B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`; return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; } export default function GalleryDetailPage() { const { slug } = useParams<{ slug: string }>(); const [media, setMedia] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { if (!slug) return; const id = extractUlid(slug); api .getMedia(id) .then((data) => setMedia(data)) .catch((err) => setError(err.message)) .finally(() => setLoading(false)); }, [slug]); return ( <>
Back {loading && (
Loading...
)} {error && (
Media not found or failed to load.
)} {!loading && !error && media && (
{media.type === "image" ? ( {media.altText ) : ( )}

{media.title || media.originalFilename}

{media.description && (

{media.description}

)}
{media.type === "video" ? : null} {media.type.charAt(0).toUpperCase() + media.type.slice(1)} {formatFileSize(media.size)} {media.mimeType}
Download
)}