50ed8abe95
- Full file browser page at /files with lazy-load, breadcrumbs, drag&drop - FileBrowserModal component for path selection from Samba/NFS forms - PathField component replaces bare inputs in share/export forms - Backend: /api/files/* routes with List, Mkdir, Rename, Delete, Chmod, Chown, Upload, Download, Preview, Search - Reuses NASCTL_ALLOWED_ROOTS for path validation - NASCTL_UPLOAD_MAX_BYTES (100MB) and NASCTL_PREVIEW_MAX_BYTES (256KB) env vars - Capabilities endpoint returns chmod/chown availability (requires root) - Version bump: 0.3.2 -> 0.4.0
67 lines
2.2 KiB
TypeScript
67 lines
2.2 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { Navigate, Route, Routes } from "react-router-dom";
|
|
import { api } from "./api";
|
|
import { DirtyProvider } from "./DirtyContext";
|
|
import Layout from "./components/Layout";
|
|
import Login from "./pages/Login";
|
|
import Dashboard from "./pages/Dashboard";
|
|
import Users from "./pages/Users";
|
|
import Samba from "./pages/Samba";
|
|
import Nfs from "./pages/Nfs";
|
|
import Log from "./pages/Log";
|
|
import Settings from "./pages/Settings";
|
|
import Files from "./pages/Files";
|
|
|
|
type AuthState = { loading: boolean; authenticated: boolean; username: string };
|
|
|
|
export default function App() {
|
|
const [auth, setAuth] = useState<AuthState>({ loading: true, authenticated: false, username: "" });
|
|
|
|
useEffect(() => {
|
|
api
|
|
.status()
|
|
.then((res) => setAuth({ loading: false, authenticated: res.authenticated, username: res.username }))
|
|
.catch(() => setAuth({ loading: false, authenticated: false, username: "" }));
|
|
}, []);
|
|
|
|
if (auth.loading) {
|
|
return <div className="flex min-h-screen items-center justify-center text-slate-400">Cargando...</div>;
|
|
}
|
|
|
|
if (!auth.authenticated) {
|
|
return (
|
|
<Routes>
|
|
<Route
|
|
path="/login"
|
|
element={<Login onLoggedIn={(username) => setAuth({ loading: false, authenticated: true, username })} />}
|
|
/>
|
|
<Route path="*" element={<Navigate to="/login" replace />} />
|
|
</Routes>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<DirtyProvider>
|
|
<Routes>
|
|
<Route
|
|
element={
|
|
<Layout
|
|
username={auth.username}
|
|
onLogout={() => setAuth({ loading: false, authenticated: false, username: "" })}
|
|
/>
|
|
}
|
|
>
|
|
<Route path="/" element={<Dashboard />} />
|
|
<Route path="/users" element={<Users />} />
|
|
<Route path="/files" element={<Files />} />
|
|
<Route path="/samba" element={<Samba />} />
|
|
<Route path="/nfs" element={<Nfs />} />
|
|
<Route path="/log" element={<Log />} />
|
|
<Route path="/settings" element={<Settings />} />
|
|
<Route path="*" element={<Navigate to="/" replace />} />
|
|
</Route>
|
|
</Routes>
|
|
</DirtyProvider>
|
|
);
|
|
}
|