import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; import { Link } from "react-router-dom"; import { Button, EmptyState, Spinner, inputClass } from "@/components/ui"; import { api, errorMessage } from "@/lib/api"; import { cn } from "@/lib/cn"; import { formatBytes } from "@/lib/format"; import type { MediaItem, Paginated, StorageInfo } from "@/lib/types"; function parseJIds(text: string): string[] { return text .split(/[\s,]+/) .map((value) => value.trim().toUpperCase()) .filter((value) => /^J-\d+$/.test(value)); } export default function DeletePage() { const queryClient = useQueryClient(); const [jIdsInput, setJIdsInput] = useState(""); const [loadedIds, setLoadedIds] = useState([]); const [selected, setSelected] = useState([]); const [status, setStatus] = useState(null); const storageQuery = useQuery({ queryKey: ["storage"], queryFn: () => api("/api/storage/"), }); const filesQuery = useQuery({ queryKey: ["delete-files", loadedIds], queryFn: () => api>(`/api/files/?j_ids=${loadedIds.join(",")}`), enabled: loadedIds.length > 0, }); const deleteMutation = useMutation({ mutationFn: (jIds: string[]) => api<{ deleted: string[]; errors: { j_id?: string; error: string }[] }>( "/api/delete/", { method: "POST", json: { j_ids: jIds } }, ), onSuccess: (result) => { setSelected([]); setLoadedIds([]); setStatus( `Deleted ${result.deleted.length} item(s)${ result.errors.length > 0 ? ` · ${result.errors.length} failed` : "" }.`, ); void queryClient.invalidateQueries({ queryKey: ["storage"] }); void queryClient.invalidateQueries({ queryKey: ["files"] }); void queryClient.invalidateQueries({ queryKey: ["duplicates-md5"] }); }, onError: (error) => setStatus(errorMessage(error)), }); const tempMutation = useMutation({ mutationFn: () => api<{ removed: number }>("/api/temp/clear/", { method: "POST" }), onSuccess: (result) => { setStatus(`Removed ${result.removed} temp file(s).`); void queryClient.invalidateQueries({ queryKey: ["storage"] }); }, onError: (error) => setStatus(errorMessage(error)), }); function toggleSelected(jId: string) { setSelected((current) => current.includes(jId) ? current.filter((value) => value !== jId) : [...current, jId], ); } const storage = storageQuery.data; return (

Delete & storage

Inspect disk usage and remove files from the library.

{status ? (

{status}

) : null}
{storageQuery.isPending ? ( ) : storage ? ( <>

Library size

{formatBytes(storage.watched_folder.library_size)}

{storage.watched_folder.path}

{storage.library_items} items

Disk

{formatBytes(storage.watched_folder.used)} /{" "} {formatBytes(storage.watched_folder.total)}

= 95 ? "bg-ctp-red" : storage.watched_folder.percent_used >= 80 ? "bg-ctp-peach" : "bg-ctp-blue", )} style={{ width: `${storage.watched_folder.percent_used}%` }} />

{storage.watched_folder.percent_used}% used ·{" "} {formatBytes(storage.watched_folder.free)} free

Media folder

{formatBytes(storage.media.size)}

{storage.media.path}

Temp uploads

{formatBytes(storage.temp.size)} · {storage.temp.files} file(s)

) : ( )}

Delete files by J-ID