Frontend: CSS modules, Zustand + URL sync

This commit is contained in:
Adrian Rumpold
2025-04-25 08:17:46 +02:00
parent e8a9a42ef4
commit ad335ad4d3
26 changed files with 1457 additions and 294 deletions

View File

@@ -1,97 +1,64 @@
import { useQueries } from "@tanstack/react-query";
import { useNavigate } from "react-router-dom";
import { getArticleIds, getToc } from "./lib/api";
import { Language } from "./lib/types";
import ArticleSelector from "./components/ArticleSelector";
import Panel from "./components/Panel";
import TOC from "./components/TOC";
import ArticleSelector from "./components/ArticleSelector/ArticleSelector";
import Panel from "./components/Panel/Panel";
import TOC from "./components/TOC/TOC";
import useNavState from "./store/navStore";
import useUIStore from "./store/uiStore";
import "./App.css";
import styles from "./App.module.css";
import CelexSelector from "./components/CelexSelector/CelexSelector";
type Props = {
celexId: string;
articleId: number;
};
function App({ celexId, articleId }: Props) {
const navigate = useNavigate();
function App() {
const { numPanels, addPanel } = useUIStore();
const { celexId, articleId } = useNavState();
const results = useQueries({
queries: [
{
queryKey: ["articleIds", celexId],
queryFn: () => getArticleIds(celexId),
queryFn: () => getArticleIds(celexId!),
enabled: !!celexId,
},
{
queryKey: ["toc", celexId],
queryFn: () => getToc(celexId, Language.ENG),
queryFn: () => getToc(celexId!, Language.ENG),
enabled: !!celexId,
},
],
});
const isPending = results.some((result) => result.isPending);
const error = results.find((result) => result.isError);
if (isPending) {
return <div className="panel">Loading...</div>;
return <div>Loading...</div>;
}
if (error) {
return <div className="panel">Error: {error.error?.message}</div>;
return <div>Error: {error.error?.message}</div>;
}
const examples = [
{ name: "GDPR", id: "32016R0679" },
{ name: "AI Act", id: "32024R1689" },
{ name: "Cyber Resilience Act", id: "32024R2847" },
];
return (
<div className="App">
<div className="controls">
<div>
<label htmlFor="examples">Select example:</label>
<select
id="examples"
value={celexId}
onChange={(e) => {
navigate(`/${e.target.value}`);
}}
>
{examples.map((example) => (
<option key={example.id} value={example.id}>
{example.name}
</option>
))}
</select>
</div>
{/* <CelexSelector defaultId={celexId} onSelected={setCelexId} /> */}
<ArticleSelector
articleIds={results[0].data!}
selectedId={articleId}
onSelected={(id) => navigate(`/${celexId}/articles/${id}`)}
/>
<div className={styles.App}>
<div className={styles.controls}>
<CelexSelector />
<ArticleSelector articleIds={results[0].data!} />
<button onClick={addPanel}>Add Panel</button>
</div>
<div className="panel-container">
<TOC
toc={results[1].data!}
selectedArticleId={articleId}
onArticleSelected={(id) => navigate(`/${celexId}/articles/${id}`)}
/>
<div className={styles.panelContainer}>
<TOC toc={results[1].data!} />
{Array.from({ length: numPanels }, (_, index) => (
<Panel
key={index}
celexId={celexId}
celexId={celexId!}
language={
Object.values(Language)[index % Object.values(Language).length]
}
articleId={articleId}
articleId={articleId!}
/>
))}
</div>