diff --git a/package-lock.json b/package-lock.json
index 062eb52..4c7280c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -28,6 +28,7 @@
"patch-package": "^7.0.0",
"rc-slider": "^10.1.1",
"react": "^18.2.0",
+ "react-collapsible": "^2.10.0",
"react-dom": "18.2.0",
"react-hotkeys-hook": "^3.4.7",
"react-swipeable": "^7.0.0",
@@ -9214,6 +9215,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-collapsible": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/react-collapsible/-/react-collapsible-2.10.0.tgz",
+ "integrity": "sha512-kEVsmlFfXBMTCnU5gwIv19MdmPAhbIPzz5Er37TiJSzRKS0IHrqAKQyQeHEmtoGIQMTcVI46FzE4z3NlVTx77A==",
+ "peerDependencies": {
+ "react": "~15 || ~16 || ~17 || ~18",
+ "react-dom": "~15 || ~16 || ~17 || ~18"
+ }
+ },
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
@@ -17699,6 +17709,12 @@
"loose-envify": "^1.1.0"
}
},
+ "react-collapsible": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/react-collapsible/-/react-collapsible-2.10.0.tgz",
+ "integrity": "sha512-kEVsmlFfXBMTCnU5gwIv19MdmPAhbIPzz5Er37TiJSzRKS0IHrqAKQyQeHEmtoGIQMTcVI46FzE4z3NlVTx77A==",
+ "requires": {}
+ },
"react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
diff --git a/package.json b/package.json
index 44c3894..298a851 100644
--- a/package.json
+++ b/package.json
@@ -41,6 +41,7 @@
"patch-package": "^7.0.0",
"rc-slider": "^10.1.1",
"react": "^18.2.0",
+ "react-collapsible": "^2.10.0",
"react-dom": "18.2.0",
"react-hotkeys-hook": "^3.4.7",
"react-swipeable": "^7.0.0",
diff --git a/src/components/Chronicles/ChroniclesList.tsx b/src/components/Chronicles/ChroniclesList.tsx
index 5105ed4..3485127 100644
--- a/src/components/Chronicles/ChroniclesList.tsx
+++ b/src/components/Chronicles/ChroniclesList.tsx
@@ -1,15 +1,15 @@
import { useCallback } from "react";
-import { useBoolean } from "usehooks-ts";
+import Collapsible from "react-collapsible";
import { TranslatedChroniclePreview } from "./ChroniclePreview";
import { GetChroniclesChaptersQuery } from "graphql/generated";
import { filterHasAttributes } from "helpers/asserts";
import { prettyInlineTitle, prettySlug, sJoin } from "helpers/formatters";
-import { Ico } from "components/Ico";
import { compareDate } from "helpers/date";
import { TranslatedProps } from "types/TranslatedProps";
import { useSmartLanguage } from "hooks/useSmartLanguage";
import { useAtomSetter } from "helpers/atoms";
import { atoms } from "contexts/atoms";
+import { Button } from "components/Inputs/Button";
/*
* ╭─────────────╮
@@ -24,27 +24,41 @@ interface Props {
>["data"];
currentSlug?: string;
title: string;
+ open?: boolean;
+ onTriggerClosing?: () => void;
+ onOpening?: () => void;
}
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
-const ChroniclesList = ({ chronicles, currentSlug, title }: Props): JSX.Element => {
+const ChroniclesList = ({
+ chronicles,
+ currentSlug,
+ title,
+ open,
+ onTriggerClosing,
+ onOpening,
+}: Props): JSX.Element => {
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
- const { value: isOpen, toggle: toggleOpen } = useBoolean(
- chronicles.some((chronicle) => chronicle.attributes?.slug === currentSlug)
- );
return (
-
-
+
+ {title}
+
+
+ }>
{filterHasAttributes(chronicles, ["attributes.contents", "attributes.translations"])
.sort((a, b) => compareDate(a.attributes.date_start, b.attributes.date_start))
.map((chronicle) => (
@@ -104,7 +118,7 @@ const ChroniclesList = ({ chronicles, currentSlug, title }: Props): JSX.Element
)}
))}
-
+
);
};
diff --git a/src/components/Chronicles/ChroniclesLists.tsx b/src/components/Chronicles/ChroniclesLists.tsx
new file mode 100644
index 0000000..e469c1d
--- /dev/null
+++ b/src/components/Chronicles/ChroniclesLists.tsx
@@ -0,0 +1,53 @@
+import { useState } from "react";
+import { GetChroniclesChaptersQuery } from "graphql/generated";
+import { filterHasAttributes } from "helpers/asserts";
+import { TranslatedChroniclesList } from "components/Chronicles/ChroniclesList";
+import { prettySlug } from "helpers/formatters";
+
+/*
+ * ╭─────────────╮
+ * ───────────────────────────────────────╯ COMPONENT ╰───────────────────────────────────────────
+ */
+
+interface Props {
+ chapters: NonNullable["data"];
+ currentChronicleSlug?: string;
+}
+
+// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
+
+export const ChroniclesLists = ({ chapters, currentChronicleSlug }: Props): JSX.Element => {
+ const [openedIndex, setOpenedIndex] = useState(
+ currentChronicleSlug
+ ? chapters.findIndex((chapter) =>
+ chapter.attributes?.chronicles?.data.some(
+ (chronicle) => chronicle.attributes?.slug === currentChronicleSlug
+ )
+ )
+ : -1
+ );
+
+ return (
+
+ {filterHasAttributes(chapters, ["attributes.chronicles", "id"]).map(
+ (chapter, chapterIndex) => (
+ setOpenedIndex(chapterIndex)}
+ onTriggerClosing={() => setOpenedIndex(-1)}
+ key={chapter.id}
+ chronicles={chapter.attributes.chronicles.data}
+ translations={filterHasAttributes(chapter.attributes.titles, [
+ "language.data.attributes.code",
+ ]).map((translation) => ({
+ title: translation.title,
+ language: translation.language.data.attributes.code,
+ }))}
+ fallback={{ title: prettySlug(chapter.attributes.slug) }}
+ />
+ )
+ )}
+
+ );
+};
diff --git a/src/pages/chronicles/[slug]/index.tsx b/src/pages/chronicles/[slug]/index.tsx
index c433972..7bee657 100644
--- a/src/pages/chronicles/[slug]/index.tsx
+++ b/src/pages/chronicles/[slug]/index.tsx
@@ -22,6 +22,7 @@ import { Ids } from "types/ids";
import { useFormat } from "hooks/useFormat";
import { getFormat } from "helpers/i18n";
import { ElementsSeparator } from "helpers/component";
+import { ChroniclesLists } from "components/Chronicles/ChroniclesLists";
/*
* ╭────────╮
@@ -65,6 +66,18 @@ const Chronicle = ({ chronicle, chapters, ...otherProps }: Props): JSX.Element =
),
});
+ const subPanel = (
+
+
+
+
+
+ );
+
const contentPanel = (
);
- const subPanel = (
-
-
-
-
-
-
- {filterHasAttributes(chapters, ["attributes.chronicles", "id"]).map((chapter) => (
- ({
- title: translation.title,
- language: translation.language.data.attributes.code,
- }))}
- fallback={{ title: prettySlug(chapter.attributes.slug) }}
- currentSlug={chronicle.slug}
- />
- ))}
-
-
- );
-
return (
{
const { format } = useFormat();
+
const subPanel = (
{
title={format("chronicles")}
description={format("chronicles_description")}
/>
-
-
-
- {filterHasAttributes(chapters, ["attributes.chronicles", "id"]).map((chapter) => (
- ({
- title: translation.title,
- language: translation.language.data.attributes.code,
- }))}
- fallback={{ title: prettySlug(chapter.attributes.slug) }}
- />
- ))}
-
+
);