React/TypeScript/Vite/Tailwind prototype from the design session (login, dashboard, photos, backups, settings views with mocked API layer). Infra work (Rust services, Ansible, OpenTofu) follows in subsequent commits. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
45 lines
1.2 KiB
TypeScript
45 lines
1.2 KiB
TypeScript
import { useEffect, useMemo, useState } from 'react';
|
|
import { getFiles } from '../api/files';
|
|
import type { FileFilter, FileItem } from '../types';
|
|
|
|
const FILTERS: FileFilter[] = ['Tous', 'Dossiers', 'Documents', 'Médias'];
|
|
|
|
function matchesFilter(file: FileItem, filter: FileFilter): boolean {
|
|
switch (filter) {
|
|
case 'Tous':
|
|
return true;
|
|
case 'Dossiers':
|
|
return file.kind === 'folder';
|
|
case 'Documents':
|
|
return file.kind === 'document';
|
|
case 'Médias':
|
|
return file.kind === 'video' || file.kind === 'image';
|
|
}
|
|
}
|
|
|
|
export function useRecentFiles() {
|
|
const [files, setFiles] = useState<FileItem[]>([]);
|
|
const [filter, setFilter] = useState<FileFilter>('Tous');
|
|
const [sortDesc, setSortDesc] = useState(true);
|
|
const [gridView, setGridView] = useState(true);
|
|
|
|
useEffect(() => {
|
|
void getFiles().then(setFiles);
|
|
}, []);
|
|
|
|
const visibleFiles = useMemo(() => {
|
|
const filtered = files.filter((f) => matchesFilter(f, filter));
|
|
return sortDesc ? filtered : filtered.slice().reverse();
|
|
}, [files, filter, sortDesc]);
|
|
|
|
return {
|
|
files: visibleFiles,
|
|
filters: FILTERS,
|
|
filter,
|
|
setFilter,
|
|
sortDesc,
|
|
toggleSort: () => setSortDesc((v) => !v),
|
|
gridView,
|
|
setGridView,
|
|
};
|
|
}
|