Improved wiki for mobile + removed old hook

This commit is contained in:
DrMint 2022-07-15 01:51:06 +02:00
parent 0df66815c8
commit c6ee213903
10 changed files with 99 additions and 97 deletions

View File

@ -1,7 +1,7 @@
import { Fragment, useCallback, useState } from "react";
import { Fragment, useCallback } from "react";
import { Ico, Icon } from "components/Ico";
import { cIf, cJoin } from "helpers/className";
import { useToggle } from "hooks/useToggle";
import { useBoolean } from "hooks/useBoolean";
/*
*
@ -26,8 +26,11 @@ export const Select = ({
allowEmpty,
onChange,
}: Props): JSX.Element => {
const [opened, setOpened] = useState(false);
const toggleOpened = useToggle(setOpened);
const {
state: isOpened,
setFalse: setClosed,
toggleState: toggleOpened,
} = useBoolean(false);
const tryToggling = useCallback(() => {
const optionCount = options.length + (value === -1 ? 1 : 0);
@ -38,7 +41,7 @@ export const Select = ({
<div
className={cJoin(
"relative text-center transition-[filter]",
cIf(opened, "z-10 drop-shadow-shade-lg"),
cIf(isOpened, "z-10 drop-shadow-shade-lg"),
className
)}
>
@ -47,7 +50,7 @@ export const Select = ({
`grid cursor-pointer grid-flow-col grid-cols-[1fr_auto_auto] place-items-center
rounded-[1em] bg-light p-1 outline outline-2 outline-offset-[-2px] outline-mid
transition-all hover:bg-mid hover:outline-[transparent]`,
cIf(opened, "rounded-b-none bg-highlight outline-[transparent]")
cIf(isOpened, "rounded-b-none bg-highlight outline-[transparent]")
)}
>
<p onClick={tryToggling} className="w-full">
@ -58,20 +61,20 @@ export const Select = ({
icon={Icon.Close}
className="!text-xs"
onClick={() => {
setClosed();
onChange(-1);
setOpened(false);
}}
/>
)}
<Ico
onClick={tryToggling}
icon={opened ? Icon.ArrowDropUp : Icon.ArrowDropDown}
icon={isOpened ? Icon.ArrowDropUp : Icon.ArrowDropDown}
/>
</div>
<div
className={cJoin(
"left-0 right-0 rounded-b-[1em]",
cIf(opened, "absolute", "hidden")
cIf(isOpened, "absolute", "hidden")
)}
>
{options.map((option, index) => (
@ -80,11 +83,11 @@ export const Select = ({
<div
className={cJoin(
"cursor-pointer p-1 transition-colors last-of-type:rounded-b-[1em] hover:bg-mid",
cIf(opened, "bg-highlight", "bg-light")
cIf(isOpened, "bg-highlight", "bg-light")
)}
id={option}
onClick={() => {
setOpened(false);
setClosed();
onChange(index);
}}
>

View File

@ -1,6 +1,7 @@
import { Fragment, useCallback, useEffect, useMemo, useState } from "react";
import { Chip } from "./Chip";
import { PageSelector } from "./Inputs/PageSelector";
import { Ico, Icon } from "./Ico";
import { AppStaticProps } from "graphql/getAppStaticProps";
import { cJoin } from "helpers/className";
import { isDefined, isDefinedAndNotEmpty, iterateMap } from "helpers/others";
@ -145,43 +146,47 @@ export const SmartList = <T,>({
)}
<div className="mb-8">
{groupedList.size > 0
? iterateMap(
groupedList,
(name, groupItems) =>
groupItems.length > 0 && (
<Fragment key={name}>
{name.length > 0 && (
<h2
className="flex flex-row place-items-center gap-2 pb-2 pt-10 text-2xl
{groupedList.size > 0 ? (
iterateMap(
groupedList,
(name, groupItems) =>
groupItems.length > 0 && (
<Fragment key={name}>
{name.length > 0 && (
<h2
className="flex flex-row place-items-center gap-2 pb-2 pt-10 text-2xl
first-of-type:pt-0"
>
{name}
<Chip
text={`${groupItems.length} ${
groupItems.length <= 1
? langui.result?.toLowerCase() ?? ""
: langui.results?.toLowerCase() ?? ""
}`}
/>
</h2>
)}
<div
className={cJoin(
`grid items-start gap-8 border-b-[3px] border-dotted pb-12
last-of-type:border-0 mobile:gap-4`,
className
)}
>
{groupItems.map((item) => (
<RenderItem item={item} key={getItemId(item)} />
))}
</div>
</Fragment>
),
([a], [b]) => groupSortingFunction(a, b)
)
: isDefined(RenderWhenEmpty) && <RenderWhenEmpty />}
{name}
<Chip
text={`${groupItems.length} ${
groupItems.length <= 1
? langui.result?.toLowerCase() ?? ""
: langui.results?.toLowerCase() ?? ""
}`}
/>
</h2>
)}
<div
className={cJoin(
`grid items-start gap-8 border-b-[3px] border-dotted pb-12
last-of-type:border-0 mobile:gap-4`,
className
)}
>
{groupItems.map((item) => (
<RenderItem item={item} key={getItemId(item)} />
))}
</div>
</Fragment>
),
([a], [b]) => groupSortingFunction(a, b)
)
) : isDefined(RenderWhenEmpty) ? (
<RenderWhenEmpty />
) : (
<DefaultRenderWhenEmpty langui={langui} />
)}
</div>
{pageCount > 1 && paginationSelectorBottom && (
@ -190,3 +195,25 @@ export const SmartList = <T,>({
</>
);
};
/*
*
* PRIVATE COMPONENTS
*/
interface DefaultRenderWhenEmptyProps {
langui: AppStaticProps["langui"];
}
const DefaultRenderWhenEmpty = ({ langui }: DefaultRenderWhenEmptyProps) => (
<div className="grid h-full place-content-center">
<div
className="grid grid-flow-col place-items-center gap-9 rounded-2xl border-2 border-dotted
border-dark p-8 text-dark opacity-40"
>
<Ico icon={Icon.ChevronLeft} className="!text-[300%] mobile:hidden" />
<p className="max-w-xs text-2xl"> {langui.no_results_message} </p>
<Ico icon={Icon.ChevronRight} className="!text-[300%] desktop:hidden" />
</div>
</div>
);

View File

@ -88,7 +88,7 @@ const DefinitionCard = ({
{source?.url && source.name && (
<Link href={source.url}>
<div className="mt-3 flex place-items-center gap-2">
<div className="mt-3 flex place-items-center gap-2 mobile:flex-col mobile:text-center">
<p>{langui.source}: </p>
<Button size="small" text={source.name} />
</div>

View File

@ -1,8 +0,0 @@
import { Dispatch, SetStateAction, useCallback } from "react";
export const useToggle = (
setState: Dispatch<SetStateAction<boolean>>
): (() => void) =>
useCallback(() => {
setState((current) => !current);
}, [setState]);

View File

@ -6,7 +6,6 @@ import { Icon } from "components/Ico";
import { Switch } from "components/Inputs/Switch";
import { TextInput } from "components/Inputs/TextInput";
import { WithLabel } from "components/Inputs/WithLabel";
import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholder";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
import {
ReturnButton,
@ -120,12 +119,6 @@ const Videos = ({ langui, videos, ...otherProps }: Props): JSX.Element => {
/>
</>
)}
renderWhenEmpty={() => (
<ContentPlaceholder
message={langui.no_results_message ?? "No results"}
icon={Icon.ChevronLeft}
/>
)}
className="desktop:grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] mobile:grid-cols-2
thin:grid-cols-1"
paginationItemPerPage={20}

View File

@ -20,7 +20,6 @@ import { Icon } from "components/Ico";
import { filterDefined, filterHasAttributes } from "helpers/others";
import { GetContentsQuery } from "graphql/generated";
import { SmartList } from "components/SmartList";
import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholder";
import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable";
import { useBoolean } from "hooks/useBoolean";
import { TranslatedPreviewCard } from "components/Translated";
@ -259,12 +258,6 @@ const Contents = ({
keepInfoVisible={keepInfoVisible}
/>
)}
renderWhenEmpty={() => (
<ContentPlaceholder
message={langui.no_results_message ?? "No results"}
icon={Icon.ChevronLeft}
/>
)}
className="grid-cols-2 items-end desktop:grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))]"
groupingFunction={groupingFunction}
filteringFunction={filteringFunction}

View File

@ -1,4 +1,4 @@
import { Fragment, useCallback, useMemo, useState } from "react";
import { Fragment, useCallback, useMemo } from "react";
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
import { AppLayout } from "components/AppLayout";
import { Chip } from "components/Chip";
@ -49,7 +49,6 @@ import { AnchorIds, useScrollTopOnChange } from "hooks/useScrollTopOnChange";
import { isUntangibleGroupItem } from "helpers/libraryItem";
import { useMediaHoverable } from "hooks/useMediaQuery";
import { WithLabel } from "components/Inputs/WithLabel";
import { useToggle } from "hooks/useToggle";
import { Ico, Icon } from "components/Ico";
import { cJoin, cIf } from "helpers/className";
import { useSmartLanguage } from "hooks/useSmartLanguage";
@ -682,8 +681,7 @@ const ContentLine = ({
slug,
parentSlug,
}: ContentLineProps): JSX.Element => {
const [opened, setOpened] = useState(false);
const toggleOpened = useToggle(setOpened);
const { state: isOpened, toggleState: toggleOpened } = useBoolean(false);
const [selectedTranslation] = useSmartLanguage({
items: content?.translations ?? [],
@ -700,7 +698,7 @@ const ContentLine = ({
<div
className={cJoin(
"grid gap-2 rounded-lg px-4",
cIf(opened, "my-2 h-auto bg-mid py-3 shadow-inner-sm shadow-shade")
cIf(isOpened, "my-2 h-auto bg-mid py-3 shadow-inner-sm shadow-shade")
)}
>
<div
@ -733,7 +731,7 @@ const ContentLine = ({
</div>
<div
className={`grid-flow-col place-content-start place-items-center gap-2 ${
opened ? "grid" : "hidden"
isOpened ? "grid" : "hidden"
}`}
>
<Ico icon={Icon.SubdirectoryArrowRight} className="text-dark" />

View File

@ -28,7 +28,6 @@ import { PreviewCard } from "components/PreviewCard";
import { useMediaHoverable } from "hooks/useMediaQuery";
import { ButtonGroup } from "components/Inputs/ButtonGroup";
import { filterHasAttributes, isDefined, isUndefined } from "helpers/others";
import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholder";
import { useAppLayout } from "contexts/AppLayoutContext";
import { convertPrice } from "helpers/numbers";
import { SmartList } from "components/SmartList";
@ -445,12 +444,6 @@ const Library = ({
}
/>
)}
renderWhenEmpty={() => (
<ContentPlaceholder
message={langui.no_results_message ?? "No results"}
icon={Icon.ChevronLeft}
/>
)}
className="grid-cols-2 items-end desktop:grid-cols-[repeat(auto-fill,_minmax(13rem,1fr))]"
searchingTerm={searchName}
sortingFunction={sortingFunction}

View File

@ -27,6 +27,11 @@ import { prettySlug } from "helpers/formatters";
import { useLightBox } from "hooks/useLightBox";
import { getAssetURL, ImageQuality } from "helpers/img";
/*
*
* PAGE
*/
interface Props extends AppStaticProps {
page: WikiPageWithTranslations;
}
@ -78,7 +83,7 @@ const WikiPage = ({
className="mb-10"
/>
<div className="flex place-content-center gap-3">
<div className="flex flex-wrap place-content-center gap-3">
<h1 className="text-center text-3xl">{selectedTranslation?.title}</h1>
{selectedTranslation?.aliases &&
selectedTranslation.aliases.length > 0 && (
@ -96,8 +101,8 @@ const WikiPage = ({
{selectedTranslation && (
<div className="text-justify">
<div
className="float-right ml-8 mb-8 w-[25rem] overflow-hidden rounded-lg bg-mid
text-center"
className="mb-8 overflow-hidden rounded-lg bg-mid text-center desktop:float-right
desktop:ml-8 desktop:w-[25rem]"
>
{page.thumbnail?.data?.attributes && (
<Img
@ -160,7 +165,7 @@ const WikiPage = ({
</div>
{isDefinedAndNotEmpty(selectedTranslation.summary) && (
<div className="mb-6">
<div className="mb-12">
<p className="font-headers text-lg font-bold">
{langui.summary}
</p>
@ -171,9 +176,8 @@ const WikiPage = ({
{filterHasAttributes(page.definitions, [
"translations",
] as const).map((definition, index) => (
<>
<div key={index} className="mb-12">
<DefinitionCard
key={index}
source={{
name: definition.source?.data?.attributes?.name,
url: definition.source?.data?.attributes?.content?.data
@ -193,8 +197,7 @@ const WikiPage = ({
"attributes",
] as const).map((category) => category.attributes.short)}
/>
<br />
</>
</div>
))}
</div>
)}
@ -225,6 +228,11 @@ const WikiPage = ({
};
export default WikiPage;
/*
*
* NEXT DATA FETCHING
*/
export const getStaticProps: GetStaticProps = async (context) => {
const sdk = getReadySdk();
const slug =
@ -246,6 +254,8 @@ export const getStaticProps: GetStaticProps = async (context) => {
};
};
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
export const getStaticPaths: GetStaticPaths = async (context) => {
const sdk = getReadySdk();
const contents = await sdk.getWikiPagesSlugs();

View File

@ -19,7 +19,6 @@ import { TextInput } from "components/Inputs/TextInput";
import { WithLabel } from "components/Inputs/WithLabel";
import { useMediaHoverable } from "hooks/useMediaQuery";
import { filterDefined, filterHasAttributes } from "helpers/others";
import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholder";
import { SmartList } from "components/SmartList";
import { Select } from "components/Inputs/Select";
import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable";
@ -204,12 +203,6 @@ const Wiki = ({
).map((category) => category.attributes.short)}
/>
)}
renderWhenEmpty={() => (
<ContentPlaceholder
message={langui.no_results_message ?? "No results"}
icon={Icon.ChevronLeft}
/>
)}
langui={langui}
className="grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(20rem,1fr))]"
searchingTerm={searchName}