Added easy access to search input on mobile pages
This commit is contained in:
parent
d560008cff
commit
22e1bf4842
|
@ -5,7 +5,7 @@ import { atoms } from "contexts/atoms";
|
||||||
import { isUndefined } from "helpers/asserts";
|
import { isUndefined } from "helpers/asserts";
|
||||||
import { useAtomGetter } from "helpers/atoms";
|
import { useAtomGetter } from "helpers/atoms";
|
||||||
import { useFormat } from "hooks/useFormat";
|
import { useFormat } from "hooks/useFormat";
|
||||||
import { useScrollTopOnChange } from "hooks/useScrollTopOnChange";
|
import { useScrollTopOnChange } from "hooks/useScrollOnChange";
|
||||||
import { Ids } from "types/ids";
|
import { Ids } from "types/ids";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { useRef } from "react";
|
||||||
|
import { Button, TranslatedButton } from "components/Inputs/Button";
|
||||||
|
import { atoms } from "contexts/atoms";
|
||||||
|
import { ParentFolderPreviewFragment } from "graphql/generated";
|
||||||
|
import { useAtomSetter } from "helpers/atoms";
|
||||||
|
import { useScrollRightOnChange } from "hooks/useScrollOnChange";
|
||||||
|
import { Ids } from "types/ids";
|
||||||
|
import { filterHasAttributes } from "helpers/asserts";
|
||||||
|
import { prettySlug } from "helpers/formatters";
|
||||||
|
import { Ico } from "components/Ico";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
path: ParentFolderPreviewFragment[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FolderPath = ({ path }: Props): JSX.Element => {
|
||||||
|
useScrollRightOnChange(Ids.ContentsFolderPath, [path]);
|
||||||
|
const setMenuGesturesEnabled = useAtomSetter(atoms.layout.menuGesturesEnabled);
|
||||||
|
const gestureReenableTimeout = useRef<NodeJS.Timeout>();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="grid">
|
||||||
|
<div
|
||||||
|
id={Ids.ContentsFolderPath}
|
||||||
|
onPointerEnter={() => {
|
||||||
|
if (gestureReenableTimeout.current) clearTimeout(gestureReenableTimeout.current);
|
||||||
|
setMenuGesturesEnabled(false);
|
||||||
|
}}
|
||||||
|
onPointerLeave={() => {
|
||||||
|
gestureReenableTimeout.current = setTimeout(() => setMenuGesturesEnabled(true), 500);
|
||||||
|
}}
|
||||||
|
className={`-mx-4 flex place-items-center justify-start gap-x-1 gap-y-4
|
||||||
|
overflow-x-auto px-4 pb-10 scrollbar-none`}>
|
||||||
|
{path.map((pathFolder, index) => (
|
||||||
|
<>
|
||||||
|
{pathFolder.slug === "root" ? (
|
||||||
|
<Button href="/contents" icon="home" active={index === path.length - 1} />
|
||||||
|
) : (
|
||||||
|
<TranslatedButton
|
||||||
|
className="w-max"
|
||||||
|
href={`/contents/folder/${pathFolder.slug}`}
|
||||||
|
translations={filterHasAttributes(pathFolder.titles, [
|
||||||
|
"language.data.attributes.code",
|
||||||
|
]).map((title) => ({
|
||||||
|
language: title.language.data.attributes.code,
|
||||||
|
text: title.title,
|
||||||
|
}))}
|
||||||
|
fallback={{
|
||||||
|
text: prettySlug(pathFolder.slug),
|
||||||
|
}}
|
||||||
|
active={index === path.length - 1}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{index < path.length - 1 && <Ico icon="chevron_right" />}
|
||||||
|
</>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -2,10 +2,8 @@ import { useCallback } from "react";
|
||||||
import { Button } from "components/Inputs/Button";
|
import { Button } from "components/Inputs/Button";
|
||||||
import { TranslatedProps } from "types/TranslatedProps";
|
import { TranslatedProps } from "types/TranslatedProps";
|
||||||
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||||
import { isUndefined } from "helpers/asserts";
|
|
||||||
import { atoms } from "contexts/atoms";
|
|
||||||
import { useAtomGetter } from "helpers/atoms";
|
|
||||||
import { useFormat } from "hooks/useFormat";
|
import { useFormat } from "hooks/useFormat";
|
||||||
|
import { cJoin } from "helpers/className";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -15,27 +13,18 @@ import { useFormat } from "hooks/useFormat";
|
||||||
interface Props {
|
interface Props {
|
||||||
href: string;
|
href: string;
|
||||||
title: string | null | undefined;
|
title: string | null | undefined;
|
||||||
|
|
||||||
displayOnlyOn?: "1ColumnLayout" | "3ColumnsLayout";
|
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||||
|
|
||||||
export const ReturnButton = ({ href, title, displayOnlyOn, className }: Props): JSX.Element => {
|
export const ReturnButton = ({ href, title, className }: Props): JSX.Element => {
|
||||||
const { format } = useFormat();
|
const { format } = useFormat();
|
||||||
const is3ColumnsLayout = useAtomGetter(atoms.containerQueries.is3ColumnsLayout);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className={cJoin("mx-auto w-full max-w-lg place-self-center", className)}>
|
||||||
{((is3ColumnsLayout && displayOnlyOn === "3ColumnsLayout") ||
|
|
||||||
(!is3ColumnsLayout && displayOnlyOn === "1ColumnLayout") ||
|
|
||||||
isUndefined(displayOnlyOn)) && (
|
|
||||||
<div className={className}>
|
|
||||||
<Button href={href} text={format("return_to_x", { x: title })} icon="navigate_before" />
|
<Button href={href} text={format("return_to_x", { x: title })} icon="navigate_before" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Fragment, useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
import { AppLayout, AppLayoutRequired } from "./AppLayout";
|
import { AppLayout, AppLayoutRequired } from "./AppLayout";
|
||||||
import { getTocFromMarkdawn, Markdawn, TableOfContents } from "./Markdown/Markdawn";
|
import { getTocFromMarkdawn, Markdawn, TableOfContents } from "./Markdown/Markdawn";
|
||||||
import { ReturnButton } from "./PanelComponents/ReturnButton";
|
import { ReturnButton } from "./PanelComponents/ReturnButton";
|
||||||
|
@ -91,13 +91,8 @@ export const PostPage = ({
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
{returnHref && returnTitle && (
|
{is1ColumnLayout && returnHref && returnTitle && (
|
||||||
<ReturnButton
|
<ReturnButton href={returnHref} title={returnTitle} className="mb-10" />
|
||||||
href={returnHref}
|
|
||||||
title={returnTitle}
|
|
||||||
displayOnlyOn={"1ColumnLayout"}
|
|
||||||
className="mb-10"
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{displayThumbnailHeader ? (
|
{displayThumbnailHeader ? (
|
||||||
|
@ -109,6 +104,7 @@ export const PostPage = ({
|
||||||
categories={filterHasAttributes(post.categories?.data, ["attributes"]).map((category) =>
|
categories={filterHasAttributes(post.categories?.data, ["attributes"]).map((category) =>
|
||||||
formatCategory(category.attributes.slug)
|
formatCategory(category.attributes.slug)
|
||||||
)}
|
)}
|
||||||
|
releaseDate={post.date}
|
||||||
languageSwitcher={
|
languageSwitcher={
|
||||||
languageSwitcherProps.locales.size > 1 ? (
|
languageSwitcherProps.locales.size > 1 ? (
|
||||||
<LanguageSwitcher {...languageSwitcherProps} />
|
<LanguageSwitcher {...languageSwitcherProps} />
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Chip } from "components/Chip";
|
||||||
import { Img } from "components/Img";
|
import { Img } from "components/Img";
|
||||||
import { InsetBox } from "components/Containers/InsetBox";
|
import { InsetBox } from "components/Containers/InsetBox";
|
||||||
import { Markdawn } from "components/Markdown/Markdawn";
|
import { Markdawn } from "components/Markdown/Markdawn";
|
||||||
import { UploadImageFragment } from "graphql/generated";
|
import { DatePickerFragment, UploadImageFragment } from "graphql/generated";
|
||||||
import { prettyInlineTitle, slugify } from "helpers/formatters";
|
import { prettyInlineTitle, slugify } from "helpers/formatters";
|
||||||
import { ImageQuality } from "helpers/img";
|
import { ImageQuality } from "helpers/img";
|
||||||
import { useAtomGetter } from "helpers/atoms";
|
import { useAtomGetter } from "helpers/atoms";
|
||||||
|
@ -21,6 +21,7 @@ interface Props {
|
||||||
description?: string | null | undefined;
|
description?: string | null | undefined;
|
||||||
type?: string;
|
type?: string;
|
||||||
categories?: string[];
|
categories?: string[];
|
||||||
|
releaseDate?: DatePickerFragment;
|
||||||
thumbnail?: UploadImageFragment | null | undefined;
|
thumbnail?: UploadImageFragment | null | undefined;
|
||||||
className?: string;
|
className?: string;
|
||||||
languageSwitcher?: JSX.Element;
|
languageSwitcher?: JSX.Element;
|
||||||
|
@ -37,9 +38,10 @@ export const ThumbnailHeader = ({
|
||||||
categories,
|
categories,
|
||||||
description,
|
description,
|
||||||
languageSwitcher,
|
languageSwitcher,
|
||||||
|
releaseDate,
|
||||||
className,
|
className,
|
||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
const { format } = useFormat();
|
const { format, formatDate } = useFormat();
|
||||||
const { showLightBox } = useAtomGetter(atoms.lightBox);
|
const { showLightBox } = useAtomGetter(atoms.lightBox);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -76,6 +78,15 @@ export const ThumbnailHeader = ({
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{releaseDate && (
|
||||||
|
<div className="flex flex-col place-items-center gap-2">
|
||||||
|
<h3 className="text-xl">{format("release_date")}</h3>
|
||||||
|
<div className="flex flex-row flex-wrap">
|
||||||
|
<Chip text={formatDate(releaseDate)} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{categories && categories.length > 0 && (
|
{categories && categories.length > 0 && (
|
||||||
<div className="flex flex-col place-items-center gap-2">
|
<div className="flex flex-col place-items-center gap-2">
|
||||||
<h3 className="text-xl">{format("category", { count: categories.length })}</h3>
|
<h3 className="text-xl">{format("category", { count: categories.length })}</h3>
|
||||||
|
|
|
@ -14,3 +14,15 @@ export const useScrollTopOnChange = (id: Ids, deps: DependencyList, enabled = tr
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [id, ...deps, enabled]);
|
}, [id, ...deps, enabled]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Scroll to top of element "id" when "deps" update.
|
||||||
|
export const useScrollRightOnChange = (id: Ids, deps: DependencyList, enabled = true): void => {
|
||||||
|
useEffect(() => {
|
||||||
|
if (enabled) {
|
||||||
|
logger.log("Change detected. Scrolling to right");
|
||||||
|
const elem = document.querySelector(`#${CSS.escape(id)}`);
|
||||||
|
elem?.scrollTo({ left: elem.scrollWidth, behavior: "smooth" });
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [id, ...deps, enabled]);
|
||||||
|
};
|
|
@ -27,6 +27,8 @@ import { getReadySdk } from "graphql/sdk";
|
||||||
import { Paginator } from "components/Containers/Paginator";
|
import { Paginator } from "components/Containers/Paginator";
|
||||||
import { useFormat } from "hooks/useFormat";
|
import { useFormat } from "hooks/useFormat";
|
||||||
import { getFormat } from "helpers/i18n";
|
import { getFormat } from "helpers/i18n";
|
||||||
|
import { useAtomGetter } from "helpers/atoms";
|
||||||
|
import { atoms } from "contexts/atoms";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -63,6 +65,7 @@ const Channel = ({ channel, ...otherProps }: Props): JSX.Element => {
|
||||||
const { format } = useFormat();
|
const { format } = useFormat();
|
||||||
const hoverable = useDeviceSupportsHover();
|
const hoverable = useDeviceSupportsHover();
|
||||||
const router = useTypedRouter(queryParamSchema);
|
const router = useTypedRouter(queryParamSchema);
|
||||||
|
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||||
|
|
||||||
const sortingMethods = useMemo(
|
const sortingMethods = useMemo(
|
||||||
() => [
|
() => [
|
||||||
|
@ -147,14 +150,27 @@ const Channel = ({ channel, ...otherProps }: Props): JSX.Element => {
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [router.isReady]);
|
}, [router.isReady]);
|
||||||
|
|
||||||
|
const searchInput = (
|
||||||
|
<TextInput
|
||||||
|
placeholder={format("search_placeholder")}
|
||||||
|
value={query}
|
||||||
|
onChange={(newQuery) => {
|
||||||
|
setPage(1);
|
||||||
|
setQuery(newQuery);
|
||||||
|
if (isDefinedAndNotEmpty(newQuery)) {
|
||||||
|
sendAnalytics("Videos/Channel", "Change search term");
|
||||||
|
} else {
|
||||||
|
sendAnalytics("Videos/Channel", "Clear search term");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
const subPanel = (
|
const subPanel = (
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton
|
{!is1ColumnLayout && (
|
||||||
href="/archives/videos"
|
<ReturnButton href="/archives/videos" title={format("videos")} className="mb-10" />
|
||||||
title={format("videos")}
|
)}
|
||||||
displayOnlyOn={"3ColumnsLayout"}
|
|
||||||
className="mb-10"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<PanelHeader
|
<PanelHeader
|
||||||
icon="movie"
|
icon="movie"
|
||||||
|
@ -166,20 +182,7 @@ const Channel = ({ channel, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
<HorizontalLine />
|
<HorizontalLine />
|
||||||
|
|
||||||
<TextInput
|
{!is1ColumnLayout && <div className="mb-6">{searchInput}</div>}
|
||||||
className="mb-6 w-full"
|
|
||||||
placeholder={format("search_placeholder")}
|
|
||||||
value={query}
|
|
||||||
onChange={(newQuery) => {
|
|
||||||
setPage(1);
|
|
||||||
setQuery(newQuery);
|
|
||||||
if (isDefinedAndNotEmpty(newQuery)) {
|
|
||||||
sendAnalytics("Videos", "Change search term");
|
|
||||||
} else {
|
|
||||||
sendAnalytics("Videos", "Clear search term");
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<WithLabel label={format("order_by")}>
|
<WithLabel label={format("order_by")}>
|
||||||
<Select
|
<Select
|
||||||
|
@ -190,7 +193,7 @@ const Channel = ({ channel, ...otherProps }: Props): JSX.Element => {
|
||||||
setPage(1);
|
setPage(1);
|
||||||
setSortingMethod(newSort);
|
setSortingMethod(newSort);
|
||||||
sendAnalytics(
|
sendAnalytics(
|
||||||
"Videos",
|
"Videos/Channel",
|
||||||
`Change sorting method (${
|
`Change sorting method (${
|
||||||
sortingMethods.map((item) => item.meiliAttribute)[newSort]
|
sortingMethods.map((item) => item.meiliAttribute)[newSort]
|
||||||
})`
|
})`
|
||||||
|
@ -224,7 +227,7 @@ const Channel = ({ channel, ...otherProps }: Props): JSX.Element => {
|
||||||
setQuery(DEFAULT_FILTERS_STATE.searchName);
|
setQuery(DEFAULT_FILTERS_STATE.searchName);
|
||||||
setSortingMethod(DEFAULT_FILTERS_STATE.sortingMethod);
|
setSortingMethod(DEFAULT_FILTERS_STATE.sortingMethod);
|
||||||
setKeepInfoVisible(DEFAULT_FILTERS_STATE.keepInfoVisible);
|
setKeepInfoVisible(DEFAULT_FILTERS_STATE.keepInfoVisible);
|
||||||
sendAnalytics("Videos", "Reset all filters");
|
sendAnalytics("Videos/Channel", "Reset all filters");
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
|
@ -232,6 +235,7 @@ const Channel = ({ channel, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
|
{is1ColumnLayout && <div className="mx-auto mb-12 max-w-lg">{searchInput}</div>}
|
||||||
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={videos?.totalPages}>
|
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={videos?.totalPages}>
|
||||||
<div
|
<div
|
||||||
className="grid grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-start
|
className="grid grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-start
|
||||||
|
|
|
@ -25,6 +25,8 @@ import { Button } from "components/Inputs/Button";
|
||||||
import { Paginator } from "components/Containers/Paginator";
|
import { Paginator } from "components/Containers/Paginator";
|
||||||
import { useFormat } from "hooks/useFormat";
|
import { useFormat } from "hooks/useFormat";
|
||||||
import { getFormat } from "helpers/i18n";
|
import { getFormat } from "helpers/i18n";
|
||||||
|
import { useAtomGetter } from "helpers/atoms";
|
||||||
|
import { atoms } from "contexts/atoms";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -57,6 +59,7 @@ const Videos = ({ ...otherProps }: Props): JSX.Element => {
|
||||||
const { format } = useFormat();
|
const { format } = useFormat();
|
||||||
const hoverable = useDeviceSupportsHover();
|
const hoverable = useDeviceSupportsHover();
|
||||||
const router = useTypedRouter(queryParamSchema);
|
const router = useTypedRouter(queryParamSchema);
|
||||||
|
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||||
|
|
||||||
const sortingMethods = useMemo(
|
const sortingMethods = useMemo(
|
||||||
() => [
|
() => [
|
||||||
|
@ -141,25 +144,8 @@ const Videos = ({ ...otherProps }: Props): JSX.Element => {
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [router.isReady]);
|
}, [router.isReady]);
|
||||||
|
|
||||||
const subPanel = (
|
const searchInput = (
|
||||||
<SubPanel>
|
|
||||||
<ReturnButton
|
|
||||||
href="/archives/"
|
|
||||||
title={"Archives"}
|
|
||||||
displayOnlyOn={"3ColumnsLayout"}
|
|
||||||
className="mb-10"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<PanelHeader
|
|
||||||
icon="movie"
|
|
||||||
title={format("videos")}
|
|
||||||
description={format("archives_description")}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<HorizontalLine />
|
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
className="mb-6 w-full"
|
|
||||||
placeholder={format("search_placeholder")}
|
placeholder={format("search_placeholder")}
|
||||||
value={query}
|
value={query}
|
||||||
onChange={(newQuery) => {
|
onChange={(newQuery) => {
|
||||||
|
@ -172,6 +158,21 @@ const Videos = ({ ...otherProps }: Props): JSX.Element => {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const subPanel = (
|
||||||
|
<SubPanel>
|
||||||
|
{!is1ColumnLayout && <ReturnButton href="/archives/" title={"Archives"} className="mb-10" />}
|
||||||
|
|
||||||
|
<PanelHeader
|
||||||
|
icon="movie"
|
||||||
|
title={format("videos")}
|
||||||
|
description={format("archives_description")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<HorizontalLine />
|
||||||
|
|
||||||
|
{!is1ColumnLayout && <div className="mb-6">{searchInput}</div>}
|
||||||
|
|
||||||
<WithLabel label={format("order_by")}>
|
<WithLabel label={format("order_by")}>
|
||||||
<Select
|
<Select
|
||||||
|
@ -226,6 +227,7 @@ const Videos = ({ ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
|
{is1ColumnLayout && <div className="mx-auto mb-12 max-w-lg">{searchInput}</div>}
|
||||||
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={videos?.totalPages}>
|
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={videos?.totalPages}>
|
||||||
<div
|
<div
|
||||||
className="grid grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-start
|
className="grid grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-start
|
||||||
|
|
|
@ -34,19 +34,19 @@ interface Props extends AppLayoutRequired {
|
||||||
|
|
||||||
const Video = ({ video, ...otherProps }: Props): JSX.Element => {
|
const Video = ({ video, ...otherProps }: Props): JSX.Element => {
|
||||||
const isContentPanelAtLeast4xl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeast4xl);
|
const isContentPanelAtLeast4xl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeast4xl);
|
||||||
|
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||||
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
||||||
const closeSubPanel = useCallback(() => setSubPanelOpened(false), [setSubPanelOpened]);
|
const closeSubPanel = useCallback(() => setSubPanelOpened(false), [setSubPanelOpened]);
|
||||||
const { format, formatDate } = useFormat();
|
const { format, formatDate } = useFormat();
|
||||||
|
|
||||||
const subPanel = (
|
const subPanel = (
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton
|
{!is1ColumnLayout && (
|
||||||
href="/archives/videos/"
|
<>
|
||||||
title={format("videos")}
|
<ReturnButton href="/archives/videos/" title={format("videos")} />
|
||||||
displayOnlyOn={"3ColumnsLayout"}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<HorizontalLine />
|
<HorizontalLine />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
<NavOption title={format("video")} url="#video" border onClick={closeSubPanel} />
|
<NavOption title={format("video")} url="#video" border onClick={closeSubPanel} />
|
||||||
<NavOption title={format("channel")} url="#channel" border onClick={closeSubPanel} />
|
<NavOption title={format("channel")} url="#channel" border onClick={closeSubPanel} />
|
||||||
|
@ -56,12 +56,9 @@ const Video = ({ video, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<ReturnButton
|
{is1ColumnLayout && (
|
||||||
href="/library/"
|
<ReturnButton href="/library/" title={format("library")} className="mb-10" />
|
||||||
title={format("library")}
|
)}
|
||||||
displayOnlyOn={"1ColumnLayout"}
|
|
||||||
className="mb-10"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="grid place-items-center gap-12">
|
<div className="grid place-items-center gap-12">
|
||||||
<div id="video" className="w-full overflow-hidden rounded-xl shadow-xl shadow-shade/80">
|
<div id="video" className="w-full overflow-hidden rounded-xl shadow-xl shadow-shade/80">
|
||||||
|
|
|
@ -16,12 +16,14 @@ import { ReturnButton } from "components/PanelComponents/ReturnButton";
|
||||||
import { getOpenGraph } from "helpers/openGraph";
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales";
|
import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales";
|
||||||
import { getDescription } from "helpers/description";
|
import { getDescription } from "helpers/description";
|
||||||
import { useScrollTopOnChange } from "hooks/useScrollTopOnChange";
|
import { useScrollTopOnChange } from "hooks/useScrollOnChange";
|
||||||
import { Ids } from "types/ids";
|
import { Ids } from "types/ids";
|
||||||
import { useFormat } from "hooks/useFormat";
|
import { useFormat } from "hooks/useFormat";
|
||||||
import { getFormat } from "helpers/i18n";
|
import { getFormat } from "helpers/i18n";
|
||||||
import { ElementsSeparator } from "helpers/component";
|
import { ElementsSeparator } from "helpers/component";
|
||||||
import { ChroniclesLists } from "components/Chronicles/ChroniclesLists";
|
import { ChroniclesLists } from "components/Chronicles/ChroniclesLists";
|
||||||
|
import { useAtomGetter } from "helpers/atoms";
|
||||||
|
import { atoms } from "contexts/atoms";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
|
@ -35,6 +37,7 @@ interface Props extends AppLayoutRequired {
|
||||||
|
|
||||||
const Chronicle = ({ chronicle, chapters, ...otherProps }: Props): JSX.Element => {
|
const Chronicle = ({ chronicle, chapters, ...otherProps }: Props): JSX.Element => {
|
||||||
const { format, formatContentType, formatCategory } = useFormat();
|
const { format, formatContentType, formatCategory } = useFormat();
|
||||||
|
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||||
useScrollTopOnChange(Ids.ContentPanel, [chronicle.slug]);
|
useScrollTopOnChange(Ids.ContentPanel, [chronicle.slug]);
|
||||||
|
|
||||||
const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({
|
const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({
|
||||||
|
@ -67,24 +70,22 @@ const Chronicle = ({ chronicle, chapters, ...otherProps }: Props): JSX.Element =
|
||||||
|
|
||||||
const subPanel = (
|
const subPanel = (
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton
|
{!is1ColumnLayout && (
|
||||||
displayOnlyOn={"3ColumnsLayout"}
|
<>
|
||||||
href="/chronicles"
|
<ReturnButton href="/chronicles" title={format("chronicles")} />
|
||||||
title={format("chronicles")}
|
|
||||||
/>
|
|
||||||
<HorizontalLine />
|
<HorizontalLine />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
<ChroniclesLists chapters={chapters} currentChronicleSlug={chronicle.slug} />
|
<ChroniclesLists chapters={chapters} currentChronicleSlug={chronicle.slug} />
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
<ReturnButton
|
{is1ColumnLayout && (
|
||||||
displayOnlyOn={"1ColumnLayout"}
|
<ReturnButton href="/chronicles" title={format("chronicles")} className="mb-10" />
|
||||||
href="/chronicles"
|
)}
|
||||||
title={format("chronicles")}
|
|
||||||
className="mb-10"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{isDefined(selectedTranslation) ? (
|
{isDefined(selectedTranslation) ? (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { prettyInlineTitle, prettySlug } from "helpers/formatters";
|
||||||
import { isUntangibleGroupItem } from "helpers/libraryItem";
|
import { isUntangibleGroupItem } from "helpers/libraryItem";
|
||||||
import { filterHasAttributes, isDefined, isDefinedAndNotEmpty } from "helpers/asserts";
|
import { filterHasAttributes, isDefined, isDefinedAndNotEmpty } from "helpers/asserts";
|
||||||
import { ContentWithTranslations } from "types/types";
|
import { ContentWithTranslations } from "types/types";
|
||||||
import { useScrollTopOnChange } from "hooks/useScrollTopOnChange";
|
import { useScrollTopOnChange } from "hooks/useScrollOnChange";
|
||||||
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||||
import { getOpenGraph } from "helpers/openGraph";
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales";
|
import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales";
|
||||||
|
@ -226,11 +226,7 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<TranslatedReturnButton
|
{is1ColumnLayout && <TranslatedReturnButton {...returnButtonProps} className="mb-10" />}
|
||||||
{...returnButtonProps}
|
|
||||||
displayOnlyOn="1ColumnLayout"
|
|
||||||
className="mb-10"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="grid place-items-center">
|
<div className="grid place-items-center">
|
||||||
<ElementsSeparator
|
<ElementsSeparator
|
||||||
|
|
|
@ -64,6 +64,7 @@ const Contents = (props: Props): JSX.Element => {
|
||||||
const { format, formatCategory, formatContentType, formatLanguage } = useFormat();
|
const { format, formatCategory, formatContentType, formatLanguage } = useFormat();
|
||||||
const router = useTypedRouter(queryParamSchema);
|
const router = useTypedRouter(queryParamSchema);
|
||||||
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
||||||
|
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||||
|
|
||||||
const sortingMethods = useMemo(
|
const sortingMethods = useMemo(
|
||||||
() => [
|
() => [
|
||||||
|
@ -152,6 +153,22 @@ const Contents = (props: Props): JSX.Element => {
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [router.isReady]);
|
}, [router.isReady]);
|
||||||
|
|
||||||
|
const searchInput = (
|
||||||
|
<TextInput
|
||||||
|
placeholder={format("search_placeholder")}
|
||||||
|
value={query}
|
||||||
|
onChange={(name) => {
|
||||||
|
setPage(1);
|
||||||
|
setQuery(name);
|
||||||
|
if (isDefinedAndNotEmpty(name)) {
|
||||||
|
sendAnalytics("Contents/All", "Change search term");
|
||||||
|
} else {
|
||||||
|
sendAnalytics("Contents/All", "Clear search term");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
const subPanel = (
|
const subPanel = (
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<PanelHeader
|
<PanelHeader
|
||||||
|
@ -171,20 +188,8 @@ const Contents = (props: Props): JSX.Element => {
|
||||||
|
|
||||||
<HorizontalLine />
|
<HorizontalLine />
|
||||||
|
|
||||||
<TextInput
|
{!is1ColumnLayout && <div className="mb-6">{searchInput}</div>}
|
||||||
className="mb-6 w-full"
|
|
||||||
placeholder={format("search_placeholder")}
|
|
||||||
value={query}
|
|
||||||
onChange={(name) => {
|
|
||||||
setPage(1);
|
|
||||||
setQuery(name);
|
|
||||||
if (isDefinedAndNotEmpty(name)) {
|
|
||||||
sendAnalytics("Contents/All", "Change search term");
|
|
||||||
} else {
|
|
||||||
sendAnalytics("Contents/All", "Clear search term");
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<WithLabel label={format("order_by")}>
|
<WithLabel label={format("order_by")}>
|
||||||
<Select
|
<Select
|
||||||
|
@ -252,6 +257,7 @@ const Contents = (props: Props): JSX.Element => {
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
|
{is1ColumnLayout && <div className="mx-auto mb-12 max-w-lg">{searchInput}</div>}
|
||||||
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={contents?.totalPages}>
|
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={contents?.totalPages}>
|
||||||
<div
|
<div
|
||||||
className="grid grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-start
|
className="grid grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-start
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { useMemo } from "react";
|
|
||||||
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
|
import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
|
||||||
import { getOpenGraph } from "helpers/openGraph";
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
@ -8,8 +7,7 @@ import { filterHasAttributes } from "helpers/asserts";
|
||||||
import { GetContentsFolderQuery, ParentFolderPreviewFragment } from "graphql/generated";
|
import { GetContentsFolderQuery, ParentFolderPreviewFragment } from "graphql/generated";
|
||||||
import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales";
|
import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales";
|
||||||
import { prettySlug } from "helpers/formatters";
|
import { prettySlug } from "helpers/formatters";
|
||||||
import { Ico } from "components/Ico";
|
import { Button } from "components/Inputs/Button";
|
||||||
import { Button, TranslatedButton } from "components/Inputs/Button";
|
|
||||||
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
||||||
import { SubPanel } from "components/Containers/SubPanel";
|
import { SubPanel } from "components/Containers/SubPanel";
|
||||||
import { TranslatedPreviewCard } from "components/PreviewCard";
|
import { TranslatedPreviewCard } from "components/PreviewCard";
|
||||||
|
@ -21,6 +19,7 @@ import { TranslatedPreviewFolder } from "components/Contents/PreviewFolder";
|
||||||
import { useFormat } from "hooks/useFormat";
|
import { useFormat } from "hooks/useFormat";
|
||||||
import { getFormat } from "helpers/i18n";
|
import { getFormat } from "helpers/i18n";
|
||||||
import { Chip } from "components/Chip";
|
import { Chip } from "components/Chip";
|
||||||
|
import { FolderPath } from "components/Contents/FolderPath";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
|
@ -39,14 +38,6 @@ const ContentsFolder = ({ openGraph, folder, path, ...otherProps }: Props): JSX.
|
||||||
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
||||||
const isContentPanelAtLeast4xl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeast4xl);
|
const isContentPanelAtLeast4xl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeast4xl);
|
||||||
|
|
||||||
const filteredPath = useMemo(
|
|
||||||
() =>
|
|
||||||
path.filter(
|
|
||||||
(_, index) => isContentPanelAtLeast4xl || index === 0 || index === path.length - 1
|
|
||||||
),
|
|
||||||
[path, isContentPanelAtLeast4xl]
|
|
||||||
);
|
|
||||||
|
|
||||||
const subPanel = (
|
const subPanel = (
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<PanelHeader
|
<PanelHeader
|
||||||
|
@ -68,30 +59,7 @@ const ContentsFolder = ({ openGraph, folder, path, ...otherProps }: Props): JSX.
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<div className="mb-10 flex flex-wrap place-items-center justify-start gap-x-1 gap-y-4">
|
<FolderPath path={path} />
|
||||||
{filteredPath.map((pathFolder, index) => (
|
|
||||||
<>
|
|
||||||
{pathFolder.slug === "root" ? (
|
|
||||||
<Button href="/contents" icon="home" active={index === filteredPath.length - 1} />
|
|
||||||
) : (
|
|
||||||
<TranslatedButton
|
|
||||||
href={`/contents/folder/${pathFolder.slug}`}
|
|
||||||
translations={filterHasAttributes(pathFolder.titles, [
|
|
||||||
"language.data.attributes.code",
|
|
||||||
]).map((title) => ({
|
|
||||||
language: title.language.data.attributes.code,
|
|
||||||
text: title.title,
|
|
||||||
}))}
|
|
||||||
fallback={{
|
|
||||||
text: prettySlug(pathFolder.slug),
|
|
||||||
}}
|
|
||||||
active={index === filteredPath.length - 1}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{index < filteredPath.length - 1 && <Ico icon="chevron_right" />}
|
|
||||||
</>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{folder.subfolders?.data && folder.subfolders.data.length > 0 && (
|
{folder.subfolders?.data && folder.subfolders.data.length > 0 && (
|
||||||
<div className="mb-8">
|
<div className="mb-8">
|
||||||
|
@ -101,7 +69,7 @@ const ContentsFolder = ({ openGraph, folder, path, ...otherProps }: Props): JSX.
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={cJoin(
|
className={cJoin(
|
||||||
"grid items-start gap-8 pb-12",
|
"grid items-start pb-12",
|
||||||
cIf(
|
cIf(
|
||||||
isContentPanelAtLeast4xl,
|
isContentPanelAtLeast4xl,
|
||||||
"grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] gap-x-6 gap-y-8",
|
"grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] gap-x-6 gap-y-8",
|
||||||
|
@ -133,7 +101,7 @@ const ContentsFolder = ({ openGraph, folder, path, ...otherProps }: Props): JSX.
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={cJoin(
|
className={cJoin(
|
||||||
"grid items-start gap-8 pb-12",
|
"grid items-start pb-12",
|
||||||
cIf(
|
cIf(
|
||||||
isContentPanelAtLeast4xl,
|
isContentPanelAtLeast4xl,
|
||||||
"grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] gap-x-6 gap-y-8",
|
"grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] gap-x-6 gap-y-8",
|
||||||
|
|
|
@ -29,7 +29,7 @@ import {
|
||||||
isDefined,
|
isDefined,
|
||||||
isDefinedAndNotEmpty,
|
isDefinedAndNotEmpty,
|
||||||
} from "helpers/asserts";
|
} from "helpers/asserts";
|
||||||
import { useScrollTopOnChange } from "hooks/useScrollTopOnChange";
|
import { useScrollTopOnChange } from "hooks/useScrollOnChange";
|
||||||
import { getScanArchiveURL, getTrackURL, isUntangibleGroupItem } from "helpers/libraryItem";
|
import { getScanArchiveURL, getTrackURL, isUntangibleGroupItem } from "helpers/libraryItem";
|
||||||
import { useDeviceSupportsHover } from "hooks/useMediaQuery";
|
import { useDeviceSupportsHover } from "hooks/useMediaQuery";
|
||||||
import { WithLabel } from "components/Inputs/WithLabel";
|
import { WithLabel } from "components/Inputs/WithLabel";
|
||||||
|
@ -95,7 +95,7 @@ const LibrarySlug = ({
|
||||||
|
|
||||||
const isContentPanelAtLeast3xl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeast3xl);
|
const isContentPanelAtLeast3xl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeast3xl);
|
||||||
const isContentPanelAtLeastSm = useAtomGetter(atoms.containerQueries.isContentPanelAtLeastSm);
|
const isContentPanelAtLeastSm = useAtomGetter(atoms.containerQueries.isContentPanelAtLeastSm);
|
||||||
const is3ColumnsLayout = useAtomGetter(atoms.containerQueries.is3ColumnsLayout);
|
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||||
|
|
||||||
const hoverable = useDeviceSupportsHover();
|
const hoverable = useDeviceSupportsHover();
|
||||||
const { value: keepInfoVisible, toggle: toggleKeepInfoVisible } = useBoolean(false);
|
const { value: keepInfoVisible, toggle: toggleKeepInfoVisible } = useBoolean(false);
|
||||||
|
@ -111,13 +111,8 @@ const LibrarySlug = ({
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ElementsSeparator>
|
<ElementsSeparator>
|
||||||
{[
|
{[
|
||||||
is3ColumnsLayout && (
|
!is1ColumnLayout && (
|
||||||
<ReturnButton
|
<ReturnButton key="ReturnButton" href="/library/" title={format("library")} />
|
||||||
key="ReturnButton"
|
|
||||||
href="/library/"
|
|
||||||
title={format("library")}
|
|
||||||
displayOnlyOn="3ColumnsLayout"
|
|
||||||
/>
|
|
||||||
),
|
),
|
||||||
<div className="grid gap-4" key="NavOption">
|
<div className="grid gap-4" key="NavOption">
|
||||||
<NavOption
|
<NavOption
|
||||||
|
@ -177,12 +172,10 @@ const LibrarySlug = ({
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<ReturnButton
|
{is1ColumnLayout && (
|
||||||
href="/library/"
|
<ReturnButton href="/library/" title={format("library")} className="mb-10" />
|
||||||
title={format("library")}
|
)}
|
||||||
displayOnlyOn="1ColumnLayout"
|
|
||||||
className="mb-10"
|
|
||||||
/>
|
|
||||||
<div className="grid place-items-center gap-12">
|
<div className="grid place-items-center gap-12">
|
||||||
<div
|
<div
|
||||||
className={cJoin(
|
className={cJoin(
|
||||||
|
|
|
@ -33,6 +33,8 @@ import { useLibraryItemUserStatus } from "hooks/useLibraryItemUserStatus";
|
||||||
import { Paginator } from "components/Containers/Paginator";
|
import { Paginator } from "components/Containers/Paginator";
|
||||||
import { useFormat } from "hooks/useFormat";
|
import { useFormat } from "hooks/useFormat";
|
||||||
import { getFormat } from "helpers/i18n";
|
import { getFormat } from "helpers/i18n";
|
||||||
|
import { useAtomGetter } from "helpers/atoms";
|
||||||
|
import { atoms } from "contexts/atoms";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -71,6 +73,7 @@ const Library = (props: Props): JSX.Element => {
|
||||||
const hoverable = useDeviceSupportsHover();
|
const hoverable = useDeviceSupportsHover();
|
||||||
const { format, formatCategory, formatLibraryItemSubType } = useFormat();
|
const { format, formatCategory, formatLibraryItemSubType } = useFormat();
|
||||||
const { libraryItemUserStatus } = useLibraryItemUserStatus();
|
const { libraryItemUserStatus } = useLibraryItemUserStatus();
|
||||||
|
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||||
|
|
||||||
const sortingMethods = useMemo(
|
const sortingMethods = useMemo(
|
||||||
() => [
|
() => [
|
||||||
|
@ -234,18 +237,8 @@ const Library = (props: Props): JSX.Element => {
|
||||||
if (isDefined(totalPages) && totalPages < page && totalPages >= 1) setPage(totalPages);
|
if (isDefined(totalPages) && totalPages < page && totalPages >= 1) setPage(totalPages);
|
||||||
}, [libraryItems?.totalPages, page]);
|
}, [libraryItems?.totalPages, page]);
|
||||||
|
|
||||||
const subPanel = (
|
const searchInput = (
|
||||||
<SubPanel>
|
|
||||||
<PanelHeader
|
|
||||||
icon="auto_stories"
|
|
||||||
title={format("library")}
|
|
||||||
description={format("library_description")}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<HorizontalLine />
|
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
className="mb-6 w-full"
|
|
||||||
placeholder={format("search_placeholder")}
|
placeholder={format("search_placeholder")}
|
||||||
value={query}
|
value={query}
|
||||||
onChange={(name) => {
|
onChange={(name) => {
|
||||||
|
@ -258,6 +251,19 @@ const Library = (props: Props): JSX.Element => {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const subPanel = (
|
||||||
|
<SubPanel>
|
||||||
|
<PanelHeader
|
||||||
|
icon="auto_stories"
|
||||||
|
title={format("library")}
|
||||||
|
description={format("library_description")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<HorizontalLine />
|
||||||
|
|
||||||
|
{!is1ColumnLayout && <div className="mb-6">{searchInput}</div>}
|
||||||
|
|
||||||
<WithLabel label={format("order_by")}>
|
<WithLabel label={format("order_by")}>
|
||||||
<Select
|
<Select
|
||||||
|
@ -388,6 +394,7 @@ const Library = (props: Props): JSX.Element => {
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
|
{is1ColumnLayout && <div className="mx-auto mb-12 max-w-lg">{searchInput}</div>}
|
||||||
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={libraryItems?.totalPages}>
|
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={libraryItems?.totalPages}>
|
||||||
<div
|
<div
|
||||||
className="grid grid-cols-[repeat(auto-fill,_minmax(12rem,1fr))] items-end
|
className="grid grid-cols-[repeat(auto-fill,_minmax(12rem,1fr))] items-end
|
||||||
|
|
|
@ -63,6 +63,7 @@ const News = ({ ...otherProps }: Props): JSX.Element => {
|
||||||
const hoverable = useDeviceSupportsHover();
|
const hoverable = useDeviceSupportsHover();
|
||||||
const router = useTypedRouter(queryParamSchema);
|
const router = useTypedRouter(queryParamSchema);
|
||||||
const isTerminalMode = useAtomGetter(atoms.layout.terminalMode);
|
const isTerminalMode = useAtomGetter(atoms.layout.terminalMode);
|
||||||
|
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||||
|
|
||||||
const [query, setQuery] = useState(router.query.query ?? DEFAULT_FILTERS_STATE.query);
|
const [query, setQuery] = useState(router.query.query ?? DEFAULT_FILTERS_STATE.query);
|
||||||
|
|
||||||
|
@ -136,18 +137,8 @@ const News = ({ ...otherProps }: Props): JSX.Element => {
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [router.isReady]);
|
}, [router.isReady]);
|
||||||
|
|
||||||
const subPanel = (
|
const searchInput = (
|
||||||
<SubPanel>
|
|
||||||
<PanelHeader
|
|
||||||
icon="newspaper"
|
|
||||||
title={format("news")}
|
|
||||||
description={format("news_description")}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<HorizontalLine />
|
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
className="mb-6 w-full"
|
|
||||||
placeholder={format("search_placeholder")}
|
placeholder={format("search_placeholder")}
|
||||||
value={query}
|
value={query}
|
||||||
onChange={(name) => {
|
onChange={(name) => {
|
||||||
|
@ -160,6 +151,19 @@ const News = ({ ...otherProps }: Props): JSX.Element => {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const subPanel = (
|
||||||
|
<SubPanel>
|
||||||
|
<PanelHeader
|
||||||
|
icon="newspaper"
|
||||||
|
title={format("news")}
|
||||||
|
description={format("news_description")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<HorizontalLine />
|
||||||
|
|
||||||
|
{!is1ColumnLayout && <div className="mb-6">{searchInput}</div>}
|
||||||
|
|
||||||
<WithLabel label={format("language", { count: Infinity })}>
|
<WithLabel label={format("language", { count: Infinity })}>
|
||||||
<Select
|
<Select
|
||||||
|
@ -208,6 +212,7 @@ const News = ({ ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
|
{is1ColumnLayout && <div className="mx-auto mb-12 max-w-lg">{searchInput}</div>}
|
||||||
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={posts?.totalPages}>
|
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={posts?.totalPages}>
|
||||||
<div
|
<div
|
||||||
className="grid grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-start
|
className="grid grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-start
|
||||||
|
|
|
@ -39,6 +39,7 @@ interface Props extends AppLayoutRequired {
|
||||||
|
|
||||||
const WikiPage = ({ page, ...otherProps }: Props): JSX.Element => {
|
const WikiPage = ({ page, ...otherProps }: Props): JSX.Element => {
|
||||||
const { format, formatCategory, formatWikiTag } = useFormat();
|
const { format, formatCategory, formatWikiTag } = useFormat();
|
||||||
|
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const isTerminalMode = useAtomGetter(atoms.layout.terminalMode);
|
const isTerminalMode = useAtomGetter(atoms.layout.terminalMode);
|
||||||
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
||||||
|
@ -51,20 +52,15 @@ const WikiPage = ({ page, ...otherProps }: Props): JSX.Element => {
|
||||||
[]
|
[]
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
const is3ColumnsLayout = useAtomGetter(atoms.containerQueries.is3ColumnsLayout);
|
|
||||||
|
|
||||||
const toc = getTocFromMarkdawn(selectedTranslation?.body?.body, selectedTranslation?.title);
|
const toc = getTocFromMarkdawn(selectedTranslation?.body?.body, selectedTranslation?.title);
|
||||||
|
|
||||||
const subPanel = is3ColumnsLayout ? (
|
const subPanel =
|
||||||
|
toc || !is1ColumnLayout ? (
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ElementsSeparator>
|
<ElementsSeparator>
|
||||||
{[
|
{[
|
||||||
<ReturnButton
|
!is1ColumnLayout && <ReturnButton key="return" href={`/wiki`} title={format("wiki")} />,
|
||||||
key="return"
|
|
||||||
href={`/wiki`}
|
|
||||||
title={format("wiki")}
|
|
||||||
displayOnlyOn={"3ColumnsLayout"}
|
|
||||||
/>,
|
|
||||||
toc && (
|
toc && (
|
||||||
<TableOfContents
|
<TableOfContents
|
||||||
key="toc"
|
key="toc"
|
||||||
|
@ -79,13 +75,7 @@ const WikiPage = ({ page, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Large}>
|
<ContentPanel width={ContentPanelWidthSizes.Large}>
|
||||||
<ReturnButton
|
{is1ColumnLayout && <ReturnButton href={`/wiki`} title={format("wiki")} className="mb-10" />}
|
||||||
href={`/wiki`}
|
|
||||||
title={format("wiki")}
|
|
||||||
displayOnlyOn={"1ColumnLayout"}
|
|
||||||
className="mb-10"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="flex flex-wrap place-content-center gap-3">
|
<div className="flex flex-wrap place-content-center gap-3">
|
||||||
<h1 className="text-center text-3xl">{selectedTranslation?.title}</h1>
|
<h1 className="text-center text-3xl">{selectedTranslation?.title}</h1>
|
||||||
{selectedTranslation?.aliases && selectedTranslation.aliases.length > 0 && (
|
{selectedTranslation?.aliases && selectedTranslation.aliases.length > 0 && (
|
||||||
|
@ -103,7 +93,7 @@ const WikiPage = ({ page, ...otherProps }: Props): JSX.Element => {
|
||||||
<div
|
<div
|
||||||
className={cJoin(
|
className={cJoin(
|
||||||
"mb-8 overflow-hidden rounded-lg bg-mid text-center",
|
"mb-8 overflow-hidden rounded-lg bg-mid text-center",
|
||||||
cIf(is3ColumnsLayout, "float-right ml-8 w-96")
|
cIf(!is1ColumnLayout, "float-right ml-8 w-96")
|
||||||
)}>
|
)}>
|
||||||
{page.thumbnail?.data?.attributes && (
|
{page.thumbnail?.data?.attributes && (
|
||||||
<Img
|
<Img
|
||||||
|
|
|
@ -27,7 +27,7 @@ import { useIntersectionList } from "hooks/useIntersectionList";
|
||||||
import { HorizontalLine } from "components/HorizontalLine";
|
import { HorizontalLine } from "components/HorizontalLine";
|
||||||
import { useFormat } from "hooks/useFormat";
|
import { useFormat } from "hooks/useFormat";
|
||||||
import { getFormat } from "helpers/i18n";
|
import { getFormat } from "helpers/i18n";
|
||||||
import { useAtomSetter } from "helpers/atoms";
|
import { useAtomGetter, useAtomSetter } from "helpers/atoms";
|
||||||
import { atoms } from "contexts/atoms";
|
import { atoms } from "contexts/atoms";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -43,6 +43,7 @@ interface Props extends AppLayoutRequired {
|
||||||
const Chronology = ({ chronologyItems, chronologyEras, ...otherProps }: Props): JSX.Element => {
|
const Chronology = ({ chronologyItems, chronologyEras, ...otherProps }: Props): JSX.Element => {
|
||||||
const { format } = useFormat();
|
const { format } = useFormat();
|
||||||
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
||||||
|
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||||
const closeSubPanel = useCallback(() => setSubPanelOpened(false), [setSubPanelOpened]);
|
const closeSubPanel = useCallback(() => setSubPanelOpened(false), [setSubPanelOpened]);
|
||||||
const ids = useMemo(
|
const ids = useMemo(
|
||||||
() => filterHasAttributes(chronologyEras, ["attributes"]).map((era) => era.attributes.slug),
|
() => filterHasAttributes(chronologyEras, ["attributes"]).map((era) => era.attributes.slug),
|
||||||
|
@ -53,7 +54,7 @@ const Chronology = ({ chronologyItems, chronologyEras, ...otherProps }: Props):
|
||||||
|
|
||||||
const subPanel = (
|
const subPanel = (
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton href="/wiki" title={format("wiki")} displayOnlyOn="3ColumnsLayout" />
|
{!is1ColumnLayout && <ReturnButton href="/wiki" title={format("wiki")} />}
|
||||||
|
|
||||||
<HorizontalLine />
|
<HorizontalLine />
|
||||||
|
|
||||||
|
@ -83,12 +84,7 @@ const Chronology = ({ chronologyItems, chronologyEras, ...otherProps }: Props):
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
<ReturnButton
|
{is1ColumnLayout && <ReturnButton href="/wiki" title={format("wiki")} className="mb-10" />}
|
||||||
href="/wiki"
|
|
||||||
title={format("wiki")}
|
|
||||||
displayOnlyOn="1ColumnLayout"
|
|
||||||
className="mb-10"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{filterHasAttributes(chronologyEras, ["attributes"]).map((era) => (
|
{filterHasAttributes(chronologyEras, ["attributes"]).map((era) => (
|
||||||
<TranslatedChronologyEra
|
<TranslatedChronologyEra
|
||||||
|
|
|
@ -29,7 +29,7 @@ import {
|
||||||
import { Paginator } from "components/Containers/Paginator";
|
import { Paginator } from "components/Containers/Paginator";
|
||||||
import { useFormat } from "hooks/useFormat";
|
import { useFormat } from "hooks/useFormat";
|
||||||
import { getFormat } from "helpers/i18n";
|
import { getFormat } from "helpers/i18n";
|
||||||
import { useAtomSetter } from "helpers/atoms";
|
import { useAtomGetter, useAtomSetter } from "helpers/atoms";
|
||||||
import { atoms } from "contexts/atoms";
|
import { atoms } from "contexts/atoms";
|
||||||
import { Select } from "components/Inputs/Select";
|
import { Select } from "components/Inputs/Select";
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ const Wiki = (props: Props): JSX.Element => {
|
||||||
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
|
||||||
const closeSubPanel = useCallback(() => setSubPanelOpened(false), [setSubPanelOpened]);
|
const closeSubPanel = useCallback(() => setSubPanelOpened(false), [setSubPanelOpened]);
|
||||||
const router = useTypedRouter(queryParamSchema);
|
const router = useTypedRouter(queryParamSchema);
|
||||||
|
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||||
|
|
||||||
const languageOptions = useMemo(() => {
|
const languageOptions = useMemo(() => {
|
||||||
const memo =
|
const memo =
|
||||||
|
@ -137,18 +138,8 @@ const Wiki = (props: Props): JSX.Element => {
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [router.isReady]);
|
}, [router.isReady]);
|
||||||
|
|
||||||
const subPanel = (
|
const searchInput = (
|
||||||
<SubPanel>
|
|
||||||
<PanelHeader
|
|
||||||
icon="travel_explore"
|
|
||||||
title={format("wiki")}
|
|
||||||
description={format("wiki_description")}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<HorizontalLine />
|
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
className="mb-6 w-full"
|
|
||||||
placeholder={format("search_placeholder")}
|
placeholder={format("search_placeholder")}
|
||||||
value={query}
|
value={query}
|
||||||
onChange={(name) => {
|
onChange={(name) => {
|
||||||
|
@ -161,6 +152,19 @@ const Wiki = (props: Props): JSX.Element => {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const subPanel = (
|
||||||
|
<SubPanel>
|
||||||
|
<PanelHeader
|
||||||
|
icon="travel_explore"
|
||||||
|
title={format("wiki")}
|
||||||
|
description={format("wiki_description")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<HorizontalLine />
|
||||||
|
|
||||||
|
{!is1ColumnLayout && <div className="mb-6">{searchInput}</div>}
|
||||||
|
|
||||||
<WithLabel label={format("language", { count: Infinity })}>
|
<WithLabel label={format("language", { count: Infinity })}>
|
||||||
<Select
|
<Select
|
||||||
|
@ -226,6 +230,7 @@ const Wiki = (props: Props): JSX.Element => {
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
|
{is1ColumnLayout && <div className="mx-auto mb-12 max-w-lg">{searchInput}</div>}
|
||||||
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={wikiPages?.totalPages}>
|
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={wikiPages?.totalPages}>
|
||||||
<div
|
<div
|
||||||
className="grid grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-start
|
className="grid grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-start
|
||||||
|
|
|
@ -73,17 +73,19 @@ const WeaponPage = ({ weapon, primaryName, aliases, ...otherProps }: Props): JSX
|
||||||
const currentIntersection = useIntersectionList(intersectionIds);
|
const currentIntersection = useIntersectionList(intersectionIds);
|
||||||
const is3ColumnsLayout = useAtomGetter(atoms.containerQueries.is3ColumnsLayout);
|
const is3ColumnsLayout = useAtomGetter(atoms.containerQueries.is3ColumnsLayout);
|
||||||
|
|
||||||
const subPanel = (
|
const searchInput = (
|
||||||
<SubPanel>
|
|
||||||
<ElementsSeparator>
|
|
||||||
{[
|
|
||||||
is3ColumnsLayout && (
|
|
||||||
<ReturnButton
|
<ReturnButton
|
||||||
key="return-button"
|
key="return-button"
|
||||||
href="/wiki/weapons"
|
href="/wiki/weapons"
|
||||||
title={format("weapon", { count: Infinity })}
|
title={format("weapon", { count: Infinity })}
|
||||||
/>
|
/>
|
||||||
),
|
);
|
||||||
|
|
||||||
|
const subPanel = (
|
||||||
|
<SubPanel>
|
||||||
|
<ElementsSeparator>
|
||||||
|
{[
|
||||||
|
is3ColumnsLayout && searchInput,
|
||||||
|
|
||||||
<Fragment key="nav-options">
|
<Fragment key="nav-options">
|
||||||
{intersectionIds.map((id, index) => (
|
{intersectionIds.map((id, index) => (
|
||||||
|
@ -126,12 +128,8 @@ const WeaponPage = ({ weapon, primaryName, aliases, ...otherProps }: Props): JSX
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
<ReturnButton
|
{!is3ColumnsLayout && <div className="mb-10">{searchInput}</div>}
|
||||||
href="/wiki/weapons"
|
|
||||||
title={format("weapon", { count: Infinity })}
|
|
||||||
displayOnlyOn="1ColumnLayout"
|
|
||||||
className="mb-10"
|
|
||||||
/>
|
|
||||||
<ThumbnailHeader
|
<ThumbnailHeader
|
||||||
title={primaryName}
|
title={primaryName}
|
||||||
subtitle={aliases.join("・")}
|
subtitle={aliases.join("・")}
|
||||||
|
|
|
@ -30,6 +30,8 @@ import { WithLabel } from "components/Inputs/WithLabel";
|
||||||
import { Switch } from "components/Inputs/Switch";
|
import { Switch } from "components/Inputs/Switch";
|
||||||
import { ReturnButton } from "components/PanelComponents/ReturnButton";
|
import { ReturnButton } from "components/PanelComponents/ReturnButton";
|
||||||
import { Select } from "components/Inputs/Select";
|
import { Select } from "components/Inputs/Select";
|
||||||
|
import { useAtomGetter } from "helpers/atoms";
|
||||||
|
import { atoms } from "contexts/atoms";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -60,6 +62,7 @@ const Weapons = (props: Props): JSX.Element => {
|
||||||
const { format, formatCategory, formatWeaponType, formatLanguage } = useFormat();
|
const { format, formatCategory, formatWeaponType, formatLanguage } = useFormat();
|
||||||
const hoverable = useDeviceSupportsHover();
|
const hoverable = useDeviceSupportsHover();
|
||||||
const router = useTypedRouter(queryParamSchema);
|
const router = useTypedRouter(queryParamSchema);
|
||||||
|
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
|
||||||
|
|
||||||
const languageOptions = useMemo(() => {
|
const languageOptions = useMemo(() => {
|
||||||
const memo =
|
const memo =
|
||||||
|
@ -132,24 +135,8 @@ const Weapons = (props: Props): JSX.Element => {
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [router.isReady]);
|
}, [router.isReady]);
|
||||||
|
|
||||||
const subPanel = (
|
const searchInput = (
|
||||||
<SubPanel>
|
|
||||||
<ReturnButton
|
|
||||||
href="/wiki"
|
|
||||||
title={format("wiki")}
|
|
||||||
displayOnlyOn="3ColumnsLayout"
|
|
||||||
className="mb-10"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<PanelHeader
|
|
||||||
icon="shield"
|
|
||||||
title={format("weapon", { count: Infinity })}
|
|
||||||
description={format("weapons_description")}
|
|
||||||
/>
|
|
||||||
<HorizontalLine />
|
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
className="mb-6 w-full"
|
|
||||||
placeholder={format("search_placeholder")}
|
placeholder={format("search_placeholder")}
|
||||||
value={query}
|
value={query}
|
||||||
onChange={(name) => {
|
onChange={(name) => {
|
||||||
|
@ -162,6 +149,21 @@ const Weapons = (props: Props): JSX.Element => {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const subPanel = (
|
||||||
|
<SubPanel>
|
||||||
|
{!is1ColumnLayout && <ReturnButton href="/wiki" title={format("wiki")} className="mb-10" />}
|
||||||
|
|
||||||
|
<PanelHeader
|
||||||
|
icon="shield"
|
||||||
|
title={format("weapon", { count: Infinity })}
|
||||||
|
description={format("weapons_description")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<HorizontalLine />
|
||||||
|
|
||||||
|
{!is1ColumnLayout && <div className="mb-6">{searchInput}</div>}
|
||||||
|
|
||||||
<WithLabel label={format("language", { count: Infinity })}>
|
<WithLabel label={format("language", { count: Infinity })}>
|
||||||
<Select
|
<Select
|
||||||
|
@ -210,12 +212,12 @@ const Weapons = (props: Props): JSX.Element => {
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<ReturnButton
|
{is1ColumnLayout && (
|
||||||
href="/wiki"
|
<>
|
||||||
title={format("wiki")}
|
<ReturnButton href="/wiki" title={format("wiki")} className="mb-6" />
|
||||||
displayOnlyOn="1ColumnLayout"
|
<div className="mx-auto mb-12 max-w-lg">{searchInput}</div>
|
||||||
className="mb-10"
|
</>
|
||||||
/>
|
)}
|
||||||
|
|
||||||
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={weapons?.totalPages}>
|
<Paginator page={page} onPageChange={setPage} totalNumberOfPages={weapons?.totalPages}>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -3,4 +3,5 @@ export enum Ids {
|
||||||
ContentPanel = "contentPanel495922447721572",
|
ContentPanel = "contentPanel495922447721572",
|
||||||
SubPanel = "subPanelz9e8rs2d3f18zer98ze",
|
SubPanel = "subPanelz9e8rs2d3f18zer98ze",
|
||||||
LightBox = "lightBoxqsd564az89e732s1",
|
LightBox = "lightBoxqsd564az89e732s1",
|
||||||
|
ContentsFolderPath = "contentsfolderpath8zer6az4",
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue