Use zustand for state management
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
import { useState } from "react";
|
||||
import Panel from "./components/Panel";
|
||||
|
||||
import { useQueries } from "@tanstack/react-query";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import "./App.css";
|
||||
import ArticleSelector from "./components/ArticleSelector";
|
||||
import TOC from "./components/TOC";
|
||||
|
||||
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 useUIStore from "./store/uiStore";
|
||||
|
||||
import "./App.css";
|
||||
|
||||
type Props = {
|
||||
celexId: string;
|
||||
articleId: number;
|
||||
@@ -16,10 +19,7 @@ type Props = {
|
||||
|
||||
function App({ celexId, articleId }: Props) {
|
||||
const navigate = useNavigate();
|
||||
const [numPanels, setNumPanels] = useState(1);
|
||||
const [selectedParagraphId, setSelectedParagraphId] = useState<string | null>(
|
||||
null
|
||||
);
|
||||
const { numPanels, addPanel } = useUIStore();
|
||||
|
||||
const results = useQueries({
|
||||
queries: [
|
||||
@@ -76,9 +76,7 @@ function App({ celexId, articleId }: Props) {
|
||||
selectedId={articleId}
|
||||
onSelected={(id) => navigate(`/${celexId}/articles/${id}`)}
|
||||
/>
|
||||
<button onClick={() => setNumPanels((prev) => prev + 1)}>
|
||||
Add Panel
|
||||
</button>
|
||||
<button onClick={addPanel}>Add Panel</button>
|
||||
</div>
|
||||
<div className="panel-container">
|
||||
<TOC
|
||||
@@ -94,8 +92,6 @@ function App({ celexId, articleId }: Props) {
|
||||
Object.values(Language)[index % Object.values(Language).length]
|
||||
}
|
||||
articleId={articleId}
|
||||
selectedParagraphId={selectedParagraphId || undefined}
|
||||
onParagraphSelected={setSelectedParagraphId}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useQuery } from "@tanstack/react-query";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { getArticle } from "../lib/api";
|
||||
import { Language } from "../lib/types";
|
||||
import useUIStore from "../store/uiStore";
|
||||
import LanguageSwitcher from "./LanguageSwitcher";
|
||||
import "./Panel.css";
|
||||
|
||||
@@ -9,17 +10,11 @@ type PanelProps = {
|
||||
celexId: string;
|
||||
language?: Language;
|
||||
articleId: number;
|
||||
selectedParagraphId?: string;
|
||||
onParagraphSelected(paragraphId: string): void;
|
||||
};
|
||||
|
||||
function Panel({
|
||||
celexId,
|
||||
language,
|
||||
articleId,
|
||||
onParagraphSelected,
|
||||
selectedParagraphId,
|
||||
}: PanelProps) {
|
||||
function Panel({ celexId, language, articleId }: PanelProps) {
|
||||
const { selectedParagraphId, setSelectedParagraphId } = useUIStore();
|
||||
|
||||
const [lang, setLang] = useState(language || Language.ENG);
|
||||
const articleRef = useRef<HTMLDivElement>(null);
|
||||
const { data, isPending, error } = useQuery({
|
||||
@@ -39,11 +34,11 @@ function Panel({
|
||||
p.classList.remove("highlight");
|
||||
});
|
||||
if (selectedParagraphId) {
|
||||
const selectedParagraph = Array.from(paragraphs).find(
|
||||
const el = Array.from(paragraphs).find(
|
||||
(p) => p.getAttribute("data-paragraph-id") === selectedParagraphId
|
||||
);
|
||||
if (selectedParagraph) {
|
||||
selectedParagraph.classList.add("highlight");
|
||||
if (el) {
|
||||
el.classList.add("highlight");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +53,7 @@ function Panel({
|
||||
return;
|
||||
}
|
||||
target.classList.add("highlight");
|
||||
onParagraphSelected(paragraphId);
|
||||
setSelectedParagraphId(paragraphId);
|
||||
};
|
||||
|
||||
paragraphs.forEach((element) => {
|
||||
@@ -72,7 +67,7 @@ function Panel({
|
||||
element.removeEventListener("click", handleClick(element));
|
||||
});
|
||||
};
|
||||
}, [articleRef, data, selectedParagraphId, onParagraphSelected]);
|
||||
}, [articleRef, data, selectedParagraphId, setSelectedParagraphId]);
|
||||
|
||||
if (isPending) return "Loading...";
|
||||
if (error) return "An error has occurred: " + error.message;
|
||||
|
||||
21
frontend/src/store/uiStore.ts
Normal file
21
frontend/src/store/uiStore.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { create } from "zustand";
|
||||
|
||||
interface UIState {
|
||||
numPanels: number;
|
||||
addPanel: () => void;
|
||||
removePanel: () => void;
|
||||
|
||||
selectedParagraphId: string | null;
|
||||
setSelectedParagraphId: (selectedParagraphId: string | null) => void;
|
||||
}
|
||||
const useUIStore = create<UIState>((set) => ({
|
||||
numPanels: 1,
|
||||
selectedParagraphId: null,
|
||||
addPanel: () => set((state) => ({ numPanels: state.numPanels + 1 })),
|
||||
removePanel: () =>
|
||||
set((state) => ({ numPanels: Math.max(state.numPanels - 1, 1) })),
|
||||
setSelectedParagraphId: (selectedParagraphId: string | null) =>
|
||||
set({ selectedParagraphId }),
|
||||
}));
|
||||
|
||||
export default useUIStore;
|
||||
Reference in New Issue
Block a user