54 lines
1.5 KiB
TypeScript
54 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
type Entry = { name: string; type: string; size?: number | null; rel?: string };
|
|
|
|
export default function FilesPage() {
|
|
const [path, setPath] = useState("");
|
|
const [entries, setEntries] = useState<Entry[]>([]);
|
|
|
|
async function load(p: string) {
|
|
const r = await fetch(`/api/files?path=${encodeURIComponent(p)}`);
|
|
if (!r.ok) return;
|
|
const b = await r.json();
|
|
setPath(b.path ?? "");
|
|
setEntries(b.entries ?? []);
|
|
}
|
|
|
|
useEffect(() => {
|
|
load("");
|
|
}, []);
|
|
|
|
function up() {
|
|
if (!path) return;
|
|
const parts = path.split("/").filter(Boolean);
|
|
parts.pop();
|
|
load(parts.join("/"));
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<h1>Dateien</h1>
|
|
<p className="muted">/{path}</p>
|
|
{path && <button onClick={up} className="btn" style={{ marginBottom: 10 }}>↑ Ebene hoch</button>}
|
|
<ul>
|
|
{entries.map((e) => (
|
|
<li key={e.rel ?? e.name}>
|
|
{e.type === "dir" ? (
|
|
<button onClick={() => load(e.rel ?? e.name)} className="btn">📁 {e.name}</button>
|
|
) : (
|
|
<span>
|
|
🎵 {e.name}{typeof e.size === "number" ? ` (${Math.round(e.size / 1024 / 1024)} MB)` : ""}{" "}
|
|
<a href={`/api/files/download?path=${encodeURIComponent(e.rel ?? e.name)}`} download>
|
|
Herunterladen ↓
|
|
</a>
|
|
</span>
|
|
)}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
);
|
|
}
|