Improved wiki for mobile + removed old hook
This commit is contained in:
		
							parent
							
								
									0df66815c8
								
							
						
					
					
						commit
						c6ee213903
					
				| @ -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); | ||||
|                 }} | ||||
|               > | ||||
|  | ||||
| @ -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> | ||||
| ); | ||||
|  | ||||
| @ -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> | ||||
|  | ||||
| @ -1,8 +0,0 @@ | ||||
| import { Dispatch, SetStateAction, useCallback } from "react"; | ||||
| 
 | ||||
| export const useToggle = ( | ||||
|   setState: Dispatch<SetStateAction<boolean>> | ||||
| ): (() => void) => | ||||
|   useCallback(() => { | ||||
|     setState((current) => !current); | ||||
|   }, [setState]); | ||||
| @ -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} | ||||
|  | ||||
| @ -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} | ||||
|  | ||||
| @ -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" /> | ||||
|  | ||||
| @ -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} | ||||
|  | ||||
| @ -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(); | ||||
|  | ||||
| @ -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} | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 DrMint
						DrMint