Files
EpicNext-Cms/src/components/admin/use-media-library.ts
T
Simo c6b919c01d
CI / check (push) Successful in 1m32s
CI / deploy (push) Successful in 1m11s
CI / e2e (push) Successful in 21s
refactor(admin): organize user actions and improve content editing UX
2026-09-05 18:56:56 +02:00

68 lines
1.8 KiB
TypeScript

"use client";
import { useCallback, useEffect, useRef, useState } from "react";
import { uploadMediaAndReturn } from "@/actions/admin-media";
type MediaFile = { name: string; url: string };
export function useMediaLibrary(
open: boolean,
setOpen: (open: boolean) => void,
onSelect: (url: string) => void,
) {
const [files, setFiles] = useState<MediaFile[]>([]);
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const [uploading, setUploading] = useState(false);
const fileRef = useRef<HTMLInputElement>(null);
const load = useCallback(async () => {
setLoading(true);
setError("");
try {
const res = await fetch("/api/media");
if (!res.ok) throw Error("Could not load media library");
const data = await res.json();
setFiles(data.files ?? []);
} catch {
setError("Could not load media library. Please retry.");
}
setLoading(false);
}, []);
useEffect(() => {
if (open) load();
}, [open, load]);
async function handleUpload(e: React.ChangeEvent<HTMLInputElement>) {
const chosen = Array.from(e.target.files ?? []);
if (!chosen.length || uploading) return;
setUploading(true);
setError("");
const urls: string[] = [];
try {
for (const file of chosen) {
const fd = new FormData();
fd.set("file", file);
const url = await uploadMediaAndReturn(fd);
if (!url)
throw Error(
`Could not upload ${file.name}. Check file type and size.`,
);
urls.push(url);
}
await load();
onSelect(urls[urls.length - 1]);
setOpen(false);
} catch (err) {
if (urls.length) await load();
setError(
err instanceof Error ? err.message : "Upload failed. Please retry.",
);
} finally {
setUploading(false);
if (fileRef.current) fileRef.current.value = "";
}
}
return { files, loading, uploading, fileRef, error, load, handleUpload };
}