68 lines
1.8 KiB
TypeScript
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 };
|
|
}
|