Formatted all TS files + fixed ugly code in _app
This commit is contained in:
		
							parent
							
								
									40046955fb
								
							
						
					
					
						commit
						7076b2d71e
					
				| @ -11,7 +11,7 @@ export type ChronologyItemComponentProps = { | ||||
| 
 | ||||
| export default function ChronologyItemComponent( | ||||
|   props: ChronologyItemComponentProps | ||||
| ) { | ||||
| ): JSX.Element { | ||||
|   function generateAnchor( | ||||
|     year: number, | ||||
|     month: number, | ||||
| @ -87,30 +87,28 @@ export default function ChronologyItemComponent( | ||||
|       <div className={styles.events}> | ||||
|         {props.item.attributes.events.map((event: ChronologyItemsEvent) => ( | ||||
|           <div className={styles.event} key={event.id}> | ||||
|             {event.translations.map( | ||||
|               (translation) => ( | ||||
|                 <> | ||||
|                   {translation.title ? <h3>{translation.title}</h3> : ""} | ||||
|             {event.translations.map((translation) => ( | ||||
|               <> | ||||
|                 {translation.title ? <h3>{translation.title}</h3> : ""} | ||||
| 
 | ||||
|                   {translation.description ? ( | ||||
|                     <p | ||||
|                       className={ | ||||
|                         event.translations.length > 1 ? styles.bulletItem : "" | ||||
|                       } | ||||
|                     > | ||||
|                       {translation.description} | ||||
|                     </p> | ||||
|                   ) : ( | ||||
|                     "" | ||||
|                   )} | ||||
|                   {translation.note ? ( | ||||
|                     <em>{"Notes: " + translation.note}</em> | ||||
|                   ) : ( | ||||
|                     "" | ||||
|                   )} | ||||
|                 </> | ||||
|               ) | ||||
|             )} | ||||
|                 {translation.description ? ( | ||||
|                   <p | ||||
|                     className={ | ||||
|                       event.translations.length > 1 ? styles.bulletItem : "" | ||||
|                     } | ||||
|                   > | ||||
|                     {translation.description} | ||||
|                   </p> | ||||
|                 ) : ( | ||||
|                   "" | ||||
|                 )} | ||||
|                 {translation.note ? ( | ||||
|                   <em>{"Notes: " + translation.note}</em> | ||||
|                 ) : ( | ||||
|                   "" | ||||
|                 )} | ||||
|               </> | ||||
|             ))} | ||||
| 
 | ||||
|             <p className={styles.source}> | ||||
|               {event.source.data | ||||
|  | ||||
| @ -8,7 +8,7 @@ type ChronologyYearComponentProps = { | ||||
| 
 | ||||
| export default function ChronologyYearComponent( | ||||
|   props: ChronologyYearComponentProps | ||||
| ) { | ||||
| ): JSX.Element { | ||||
|   return ( | ||||
|     <div | ||||
|       className={styles.chronologyYear} | ||||
|  | ||||
							
								
								
									
										58
									
								
								src/components/Library/LibraryItemComponent.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/components/Library/LibraryItemComponent.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| import styles from "styles/Library/LibraryItemComponent.module.css"; | ||||
| import { LibraryItem } from "queries/library"; | ||||
| import Link from "next/link"; | ||||
| import Image from "next/image"; | ||||
| import { BasicDate, getAssetURL } from "queries/helpers"; | ||||
| 
 | ||||
| export type LibraryItemComponentProps = { | ||||
|   item: LibraryItem; | ||||
| }; | ||||
| 
 | ||||
| export default function LibraryItemComponent( | ||||
|   props: LibraryItemComponentProps | ||||
| ): JSX.Element { | ||||
|   function prettyTitleSubtitle(title: string, subtitle: string): string { | ||||
|     let result = title; | ||||
|     if (subtitle !== null) result += " - " + subtitle; | ||||
|     return result; | ||||
|   } | ||||
| 
 | ||||
|   function prettyDate(date: BasicDate): string { | ||||
|     return ( | ||||
|       date.year + | ||||
|       "/" + | ||||
|       date.month.toString().padStart(2, "0") + | ||||
|       "/" + | ||||
|       date.day.toString().padStart(2, "0") | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   return ( | ||||
|     <Link href={"/library/" + props.item.attributes.slug} passHref> | ||||
|       <div className={styles.libraryItem}> | ||||
|         <h2> | ||||
|           {prettyTitleSubtitle( | ||||
|             props.item.attributes.title, | ||||
|             props.item.attributes.subtitle | ||||
|           )} | ||||
|         </h2> | ||||
|         <p>{prettyDate(props.item.attributes.release_date)}</p> | ||||
| 
 | ||||
|         {props.item.attributes.thumbnail.data ? ( | ||||
|           <Image | ||||
|             src={getAssetURL( | ||||
|               props.item.attributes.thumbnail.data.attributes.url | ||||
|             )} | ||||
|             alt={ | ||||
|               props.item.attributes.thumbnail.data.attributes.alternativeText | ||||
|             } | ||||
|             width={props.item.attributes.thumbnail.data.attributes.width} | ||||
|             height={props.item.attributes.thumbnail.data.attributes.height} | ||||
|           /> | ||||
|         ) : ( | ||||
|           "" | ||||
|         )} | ||||
|       </div> | ||||
|     </Link> | ||||
|   ); | ||||
| } | ||||
| @ -1,12 +1,14 @@ | ||||
| import styles from 'styles/Panels/ContentPanel.module.css' | ||||
| import panelStyles from 'styles/Panels/Panels.module.css' | ||||
| import styles from "styles/Panels/ContentPanel.module.css"; | ||||
| import panelStyles from "styles/Panels/Panels.module.css"; | ||||
| 
 | ||||
| export default function ContentPanel({children}) { | ||||
| type ContentPanelProps = { | ||||
|   children: React.ReactNode; | ||||
| }; | ||||
| 
 | ||||
| export default function ContentPanel(props: ContentPanelProps): JSX.Element { | ||||
|   return ( | ||||
|     <div className={[panelStyles.panel, styles.panel].join(' ')}> | ||||
|       <main className={styles.panelInside}> | ||||
|         {children} | ||||
|       </main> | ||||
|     <div className={[panelStyles.panel, styles.panel].join(" ")}> | ||||
|       <main className={styles.panelInside}>{props.children}</main> | ||||
|     </div> | ||||
|   ) | ||||
| } | ||||
|   ); | ||||
| } | ||||
|  | ||||
| @ -1,40 +1,37 @@ | ||||
| import Link from 'next/link' | ||||
| import styles from 'styles/Panels/MainPanel.module.css' | ||||
| import panelStyles from 'styles/Panels/Panels.module.css' | ||||
| import NavOption from 'components/Panels/NavOption' | ||||
| 
 | ||||
| export default function MainPanel() { | ||||
| import Link from "next/link"; | ||||
| import styles from "styles/Panels/MainPanel.module.css"; | ||||
| import panelStyles from "styles/Panels/Panels.module.css"; | ||||
| import NavOption from "components/Panels/NavOption"; | ||||
| 
 | ||||
| export default function MainPanel(): JSX.Element { | ||||
|   return ( | ||||
| 
 | ||||
|     <div className={[panelStyles.panel, styles.panel].join(' ')}> | ||||
| 
 | ||||
|     <div className={[panelStyles.panel, styles.panel].join(" ")}> | ||||
|       <Link href="/" passHref> | ||||
|         <div className={styles.topLogo}> | ||||
|           <img src="/icons/accords.svg" alt="" /> | ||||
|           <h2>Accord's Library</h2> | ||||
|         </div> | ||||
|       </Link> | ||||
|        | ||||
| 
 | ||||
|       <button>Change language</button> | ||||
| 
 | ||||
|       <hr /> | ||||
| 
 | ||||
|       <NavOption  | ||||
|         url="/library"  | ||||
|         icon="/icons/book-solid.svg"  | ||||
|         title="Library"  | ||||
|       <NavOption | ||||
|         url="/library" | ||||
|         icon="/icons/book-solid.svg" | ||||
|         title="Library" | ||||
|         subtitle="Browse all physical and digital media" | ||||
|       /> | ||||
|        | ||||
|       <NavOption  | ||||
|         url="/hubs"  | ||||
|         icon="/icons/hubs.svg"  | ||||
|         title="Hubs"  | ||||
| 
 | ||||
|       <NavOption | ||||
|         url="/hubs" | ||||
|         icon="/icons/hubs.svg" | ||||
|         title="Hubs" | ||||
|         subtitle="Explore all content of a specific game/series" | ||||
|       /> | ||||
|        | ||||
|       <NavOption  | ||||
| 
 | ||||
|       <NavOption | ||||
|         url="/chronology" | ||||
|         icon="/icons/timeline-solid.svg" | ||||
|         title="Chronology" | ||||
| @ -49,11 +46,7 @@ export default function MainPanel() { | ||||
|         title="Archive" | ||||
|       /> | ||||
| 
 | ||||
|       <NavOption | ||||
|         url="/news" | ||||
|         icon="/icons/newspaper-solid.svg" | ||||
|         title="News" | ||||
|       /> | ||||
|       <NavOption url="/news" icon="/icons/newspaper-solid.svg" title="News" /> | ||||
| 
 | ||||
|       <NavOption | ||||
|         url="/gallery" | ||||
| @ -70,7 +63,11 @@ export default function MainPanel() { | ||||
|       <hr /> | ||||
| 
 | ||||
|       <div className={styles.menuFooter}> | ||||
|         <p>This website’s content is made available under <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA</a> unless otherwise noted.</p> | ||||
|         <p> | ||||
|           This website’s content is made available under{" "} | ||||
|           <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA</a>{" "} | ||||
|           unless otherwise noted. | ||||
|         </p> | ||||
|         <a href="https://creativecommons.org/licenses/by-sa/4.0/"> | ||||
|           <div className={styles.menuFooterCC}> | ||||
|             <img src="/icons/creative-commons-brands.svg" alt="" /> | ||||
| @ -78,12 +75,20 @@ export default function MainPanel() { | ||||
|             <img src="/icons/creative-commons-sa-brands.svg" alt="" /> | ||||
|           </div> | ||||
|         </a> | ||||
|         <p>Accord’s Library is not affiliated with or endorsed by SQUARE ENIX CO. LTD. All game assets and promotional materials belongs to © SQUARE ENIX CO. LTD.</p> | ||||
|         <p> | ||||
|           Accord’s Library is not affiliated with or endorsed by SQUARE | ||||
|           ENIX CO. LTD. All game assets and promotional materials belongs to © | ||||
|           SQUARE ENIX CO. LTD. | ||||
|         </p> | ||||
|         <div className={styles.menuFooterSocials}> | ||||
|           <a href="https://github.com/Accords-Library"><img src="/icons/github-brands.svg" alt="" /></a> | ||||
|           <a href="https://accords-library.com/discord"><img src="/icons/discord-brands.svg" alt="" /></a> | ||||
|           <a href="https://github.com/Accords-Library"> | ||||
|             <img src="/icons/github-brands.svg" alt="" /> | ||||
|           </a> | ||||
|           <a href="https://accords-library.com/discord"> | ||||
|             <img src="/icons/discord-brands.svg" alt="" /> | ||||
|           </a> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   ) | ||||
| } | ||||
|   ); | ||||
| } | ||||
|  | ||||
| @ -1,28 +1,28 @@ | ||||
| import { useRouter } from 'next/router' | ||||
| import styles from 'styles/Panels/NavOption.module.css' | ||||
| import Link from 'next/link' | ||||
| import { useRouter } from "next/router"; | ||||
| import styles from "styles/Panels/NavOption.module.css"; | ||||
| import Link from "next/link"; | ||||
| 
 | ||||
| type NavOptionProps = { | ||||
|   url: string,  | ||||
|   icon?: string,  | ||||
|   title: string,  | ||||
|   subtitle?: string | ||||
|   border?: boolean | ||||
| } | ||||
|   url: string; | ||||
|   icon?: string; | ||||
|   title: string; | ||||
|   subtitle?: string; | ||||
|   border?: boolean; | ||||
| }; | ||||
| 
 | ||||
| export default function NavOption(pageProps: NavOptionProps) { | ||||
| export default function NavOption(pageProps: NavOptionProps): JSX.Element { | ||||
|   const router = useRouter(); | ||||
|   let classNames = [styles.menuOption] | ||||
|   if (router.asPath.startsWith(pageProps.url)) classNames.push(styles.active) | ||||
|   if (pageProps.icon) classNames.push(styles.icon) | ||||
|   if (pageProps.border === true) classNames.push(styles.border) | ||||
|   let classNames = [styles.menuOption]; | ||||
|   if (router.asPath.startsWith(pageProps.url)) classNames.push(styles.active); | ||||
|   if (pageProps.icon) classNames.push(styles.icon); | ||||
|   if (pageProps.border === true) classNames.push(styles.border); | ||||
|   return ( | ||||
|     <Link href={pageProps.url} passHref> | ||||
|         <div className={classNames.join(' ')}> | ||||
|           {pageProps.icon && <img src={pageProps.icon} alt="" />} | ||||
|           <h3>{pageProps.title}</h3> | ||||
|           {pageProps.subtitle && <p>{pageProps.subtitle}</p>} | ||||
|         </div> | ||||
|       <div className={classNames.join(" ")}> | ||||
|         {pageProps.icon && <img src={pageProps.icon} alt="" />} | ||||
|         <h3>{pageProps.title}</h3> | ||||
|         {pageProps.subtitle && <p>{pageProps.subtitle}</p>} | ||||
|       </div> | ||||
|     </Link> | ||||
|   ) | ||||
| } | ||||
|   ); | ||||
| } | ||||
|  | ||||
| @ -1,17 +1,15 @@ | ||||
| import styles from 'styles/Panels/ReturnButton.module.css' | ||||
| import Link from 'next/link' | ||||
| import styles from "styles/Panels/ReturnButton.module.css"; | ||||
| import Link from "next/link"; | ||||
| 
 | ||||
| type ReturnButtonProps = { | ||||
|   url: string, | ||||
|   title: string | ||||
| } | ||||
|   url: string; | ||||
|   title: string; | ||||
| }; | ||||
| 
 | ||||
| export default function ReturnButton(pageProps: ReturnButtonProps) { | ||||
| export default function ReturnButton(props: ReturnButtonProps): JSX.Element { | ||||
|   return ( | ||||
|     <Link href={pageProps.url} passHref> | ||||
|         <button> | ||||
|             ❮ Return to {pageProps.title} | ||||
|         </button> | ||||
|     <Link href={props.url} passHref> | ||||
|       <button>❮ Return to {props.title}</button> | ||||
|     </Link> | ||||
|   ) | ||||
| } | ||||
|   ); | ||||
| } | ||||
|  | ||||
| @ -1,10 +1,14 @@ | ||||
| import styles from 'styles/Panels/SubPanel.module.css' | ||||
| import panelStyles from 'styles/Panels/Panels.module.css' | ||||
| import styles from "styles/Panels/SubPanel.module.css"; | ||||
| import panelStyles from "styles/Panels/Panels.module.css"; | ||||
| 
 | ||||
| export default function SubPanel({children}) { | ||||
| type SubPanelProps = { | ||||
|   children: React.ReactNode; | ||||
| }; | ||||
| 
 | ||||
| export default function SubPanel(props: SubPanelProps): JSX.Element { | ||||
|   return ( | ||||
|     <div className={[panelStyles.panel, styles.panel].join(' ')}> | ||||
|       {children} | ||||
|     <div className={[panelStyles.panel, styles.panel].join(" ")}> | ||||
|       {props.children} | ||||
|     </div> | ||||
|   ) | ||||
| } | ||||
|   ); | ||||
| } | ||||
|  | ||||
| @ -1,7 +1,13 @@ | ||||
| import Link from "next/link"; | ||||
| import ContentPanel from "components/Panels/ContentPanel"; | ||||
| import { applyCustomAppProps } from "./_app"; | ||||
| 
 | ||||
| export default function FourOhFour() { | ||||
| applyCustomAppProps(FourOhFour, { | ||||
|   useSubPanel: false, | ||||
|   useContentPanel: true, | ||||
| }); | ||||
| 
 | ||||
| export default function FourOhFour(): JSX.Element { | ||||
|   return ( | ||||
|     <ContentPanel> | ||||
|       <h1>404 - Page Not Found</h1> | ||||
|  | ||||
| @ -3,46 +3,24 @@ import Head from "next/head"; | ||||
| import MainPanel from "components/Panels/MainPanel"; | ||||
| import "styles/globals.css"; | ||||
| 
 | ||||
| function AccordsLibraryApp({ Component, pageProps }: AppProps) { | ||||
|   /* [BIG HACK] | ||||
|       Yes this is probably terrible, I'm trying to apply a different style to my appContainer div | ||||
|       depending on if the page uses a subpanel or contentpanel, or both, or neither. This is because | ||||
|       I want the first column to be always 20rem, the second one to be 20rem when it's the subbar, but | ||||
|       1fr if it's the content... | ||||
|        | ||||
|       Anyway, there is probably a much better way to do this, it it might backfire in my face in the future | ||||
|       Much love, | ||||
| export type CustomAppProps = { | ||||
|   useSubPanel: boolean; | ||||
|   useContentPanel: boolean; | ||||
| }; | ||||
| 
 | ||||
|       Mint   | ||||
|   */ | ||||
| 
 | ||||
|   const componentProcessed = Component(pageProps); | ||||
|   let useSubPanel = false; | ||||
|   let useContentPanel = false; | ||||
| 
 | ||||
|   const children = componentProcessed.props.children; | ||||
| 
 | ||||
|   if (Array.isArray(children)) { | ||||
|     children.forEach((child) => { | ||||
|       if (child.type.name === "SubPanel") { | ||||
|         useSubPanel = true; | ||||
|       } else if (child.type.name === "ContentPanel") { | ||||
|         useContentPanel = true; | ||||
|       } | ||||
|     }); | ||||
|   } else { | ||||
|     if (children.type.name === "SubPanel") { | ||||
|       useSubPanel = true; | ||||
|     } else if (children.type.name === "ContentPanel") { | ||||
|       useContentPanel = true; | ||||
|     } | ||||
|   } | ||||
| export function applyCustomAppProps( | ||||
|   page: Function, | ||||
|   customAppProps: CustomAppProps | ||||
| ) { | ||||
|   page.customAppProps = customAppProps; | ||||
| } | ||||
| 
 | ||||
| export default function AccordsLibraryApp(appProps: AppProps) { | ||||
|   let additionalClasses = ""; | ||||
|   if (useSubPanel) additionalClasses += " withSubPanel"; | ||||
|   if (useContentPanel) additionalClasses += " withContentPanel"; | ||||
| 
 | ||||
|   /* [End of BIG HACK] */ | ||||
|   if (appProps.Component.customAppProps.useSubPanel) | ||||
|     additionalClasses += " withSubPanel"; | ||||
|   if (appProps.Component.customAppProps.useContentPanel) | ||||
|     additionalClasses += " withContentPanel"; | ||||
| 
 | ||||
|   const siteTitle = | ||||
|     "Accord's Library - Discover • Analyse • Translate • Archive"; | ||||
| @ -71,9 +49,7 @@ function AccordsLibraryApp({ Component, pageProps }: AppProps) { | ||||
| 
 | ||||
|       <MainPanel /> | ||||
| 
 | ||||
|       {componentProcessed} | ||||
|       <appProps.Component {...appProps.pageProps} /> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export default AccordsLibraryApp; | ||||
|  | ||||
| @ -1,8 +1,13 @@ | ||||
| import type { NextPage } from "next"; | ||||
| import SubPanel from "components/Panels/SubPanel"; | ||||
| import NavOption from "components/Panels/NavOption"; | ||||
| import { applyCustomAppProps } from "pages/_app"; | ||||
| 
 | ||||
| const Chronology: NextPage = () => { | ||||
| applyCustomAppProps(Chronology, { | ||||
|   useSubPanel: true, | ||||
|   useContentPanel: false, | ||||
| }); | ||||
| 
 | ||||
| export default function Chronology(): JSX.Element { | ||||
|   return ( | ||||
|     <> | ||||
|       <SubPanel> | ||||
| @ -37,5 +42,4 @@ const Chronology: NextPage = () => { | ||||
|       </SubPanel> | ||||
|     </> | ||||
|   ); | ||||
| }; | ||||
| export default Chronology; | ||||
| } | ||||
|  | ||||
| @ -11,14 +11,19 @@ import { | ||||
|   ChronologyEra, | ||||
|   ChronologyItemsEvent, | ||||
| } from "queries/chronology/overview"; | ||||
| import { applyCustomAppProps } from "pages/_app"; | ||||
| 
 | ||||
| type Props = { | ||||
|   chronologyItems: ChronologyItem[]; | ||||
|   chronologyEras: ChronologyEra[]; | ||||
| }; | ||||
| 
 | ||||
| export default function ChronologyOverview(props: Props): JSX.Element { | ||||
| applyCustomAppProps(ChronologyOverview, { | ||||
|   useSubPanel: true, | ||||
|   useContentPanel: true, | ||||
| }); | ||||
| 
 | ||||
| export default function ChronologyOverview(props: Props): JSX.Element { | ||||
|   // Group by year the Chronology items
 | ||||
|   let chronologyItemYearGroups: ChronologyItem[][] = []; | ||||
|   props.chronologyItems.map((item: ChronologyItem) => { | ||||
| @ -27,7 +32,7 @@ export default function ChronologyOverview(props: Props): JSX.Element { | ||||
|     } else { | ||||
|       chronologyItemYearGroups[item.attributes.year].push(item); | ||||
|     } | ||||
|   });   | ||||
|   }); | ||||
| 
 | ||||
|   return ( | ||||
|     <> | ||||
| @ -80,15 +85,11 @@ export default function ChronologyOverview(props: Props): JSX.Element { | ||||
|           }); | ||||
|         })} | ||||
| 
 | ||||
|         {chronologyItemYearGroups.map((items: ChronologyItem[], index: number) => { | ||||
|           return ( | ||||
|             <ChronologyYearComponent | ||||
|               key={index} | ||||
|               items={items} | ||||
|             /> | ||||
|           ) | ||||
| 
 | ||||
|         })} | ||||
|         {chronologyItemYearGroups.map( | ||||
|           (items: ChronologyItem[], index: number) => { | ||||
|             return <ChronologyYearComponent key={index} items={items} />; | ||||
|           } | ||||
|         )} | ||||
|       </ContentPanel> | ||||
|     </> | ||||
|   ); | ||||
|  | ||||
| @ -1,7 +1,12 @@ | ||||
| import type { NextPage } from "next"; | ||||
| import ContentPanel from "components/Panels/ContentPanel"; | ||||
| import { applyCustomAppProps } from "./_app"; | ||||
| 
 | ||||
| const Home: NextPage = () => { | ||||
| applyCustomAppProps(Home, { | ||||
|   useSubPanel: false, | ||||
|   useContentPanel: true, | ||||
| }); | ||||
| 
 | ||||
| export default function Home(): JSX.Element { | ||||
|   return ( | ||||
|     <> | ||||
|       <ContentPanel> | ||||
| @ -129,6 +134,4 @@ const Home: NextPage = () => { | ||||
|       </ContentPanel> | ||||
|     </> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default Home; | ||||
| } | ||||
|  | ||||
| @ -6,16 +6,22 @@ import { | ||||
|   getBreadcrumbs, | ||||
|   getLibraryItemsSkeleton, | ||||
|   LibraryItem, | ||||
|   LibrarySubItem | ||||
|   LibrarySubItem, | ||||
| } from "queries/library/[...slug]"; | ||||
| import Image from "next/image"; | ||||
| import Link from "next/link"; | ||||
| import { GetStaticProps } from "next"; | ||||
| import { applyCustomAppProps } from "pages/_app"; | ||||
| 
 | ||||
| type Props = { | ||||
|   libraryItem: LibraryItem; | ||||
| }; | ||||
| 
 | ||||
| applyCustomAppProps(Library, { | ||||
|   useSubPanel: false, | ||||
|   useContentPanel: true, | ||||
| }); | ||||
| 
 | ||||
| export default function Library(props: Props): JSX.Element { | ||||
|   const router = useRouter(); | ||||
|   return ( | ||||
| @ -35,28 +41,33 @@ export default function Library(props: Props): JSX.Element { | ||||
|           height={props.libraryItem.attributes.thumbnail.data.attributes.height} | ||||
|         /> | ||||
| 
 | ||||
|         {props.libraryItem.attributes.subitems.data.map((subitem: LibrarySubItem) => ( | ||||
|           <Link | ||||
|             href={router.asPath + "/" + subitem.attributes.slug} | ||||
|             key={subitem.id} | ||||
|             passHref | ||||
|           > | ||||
|             <div> | ||||
|               {subitem.attributes.thumbnail.data ? ( | ||||
|                 <Image | ||||
|                   src={getAssetURL(subitem.attributes.thumbnail.data.attributes.url)} | ||||
|                   alt={subitem.attributes.thumbnail.data.attributes.alternativeText} | ||||
|                   width={subitem.attributes.thumbnail.data.attributes.width} | ||||
|                   height={subitem.attributes.thumbnail.data.attributes.height} | ||||
|                 /> | ||||
|               ) : ( | ||||
|                 "" | ||||
|               )} | ||||
|             </div> | ||||
|           </Link> | ||||
|         ))} | ||||
| 
 | ||||
|          | ||||
|         {props.libraryItem.attributes.subitems.data.map( | ||||
|           (subitem: LibrarySubItem) => ( | ||||
|             <Link | ||||
|               href={router.asPath + "/" + subitem.attributes.slug} | ||||
|               key={subitem.id} | ||||
|               passHref | ||||
|             > | ||||
|               <div> | ||||
|                 {subitem.attributes.thumbnail.data ? ( | ||||
|                   <Image | ||||
|                     src={getAssetURL( | ||||
|                       subitem.attributes.thumbnail.data.attributes.url | ||||
|                     )} | ||||
|                     alt={ | ||||
|                       subitem.attributes.thumbnail.data.attributes | ||||
|                         .alternativeText | ||||
|                     } | ||||
|                     width={subitem.attributes.thumbnail.data.attributes.width} | ||||
|                     height={subitem.attributes.thumbnail.data.attributes.height} | ||||
|                   /> | ||||
|                 ) : ( | ||||
|                   "" | ||||
|                 )} | ||||
|               </div> | ||||
|             </Link> | ||||
|           ) | ||||
|         )} | ||||
|       </ContentPanel> | ||||
|     </> | ||||
|   ); | ||||
| @ -66,15 +77,15 @@ export const getStaticProps: GetStaticProps = async (context) => { | ||||
|   if (context.params && Array.isArray(context.params.slug) && context.locale) { | ||||
|     return { | ||||
|       props: { | ||||
|         libraryItem: (await getLibraryItem(context.params.slug, context.locale)), | ||||
|         libraryItem: await getLibraryItem(context.params.slug, context.locale), | ||||
|       }, | ||||
|     }; | ||||
|   } | ||||
|   return {props: {}}; | ||||
| } | ||||
|   return { props: {} }; | ||||
| }; | ||||
| 
 | ||||
| export async function getStaticPaths() { | ||||
|   const paths = (await getAllSlugs()); | ||||
|   const paths = await getAllSlugs(); | ||||
|   return { | ||||
|     paths, | ||||
|     fallback: false, | ||||
| @ -85,16 +96,16 @@ async function getAllSlugs() { | ||||
|   type Path = { | ||||
|     params: { | ||||
|       slug: string[]; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   const data = (await getLibraryItemsSkeleton()); | ||||
|   const paths:Path[] = []; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   const data = await getLibraryItemsSkeleton(); | ||||
|   const paths: Path[] = []; | ||||
|   data.map((item) => { | ||||
|     const breadcrumbs = getBreadcrumbs([], item); | ||||
|     breadcrumbs.map((breadcrumb) => { | ||||
|       paths.push({params: {slug: breadcrumb}}) | ||||
|     }) | ||||
|   }) | ||||
|  return paths; | ||||
|       paths.push({ params: { slug: breadcrumb } }); | ||||
|     }); | ||||
|   }); | ||||
|   return paths; | ||||
| } | ||||
|  | ||||
| @ -2,14 +2,18 @@ import { GetStaticProps } from "next"; | ||||
| import SubPanel from "components/Panels/SubPanel"; | ||||
| import ContentPanel from "components/Panels/ContentPanel"; | ||||
| import { LibraryItem, getLibraryItems } from "queries/library/index"; | ||||
| import { BasicDate, getAssetURL } from "queries/helpers"; | ||||
| import Image from "next/image"; | ||||
| import Link from "next/link"; | ||||
| import LibraryItemComponent from "components/Library/LibraryItemComponent"; | ||||
| import { applyCustomAppProps } from "pages/_app"; | ||||
| 
 | ||||
| type Props = { | ||||
|   libraryItems: LibraryItem[]; | ||||
| }; | ||||
| 
 | ||||
| applyCustomAppProps(Library, { | ||||
|   useSubPanel: true, | ||||
|   useContentPanel: true, | ||||
| }); | ||||
| 
 | ||||
| export default function Library(props: Props): JSX.Element { | ||||
|   return ( | ||||
|     <> | ||||
| @ -26,25 +30,7 @@ export default function Library(props: Props): JSX.Element { | ||||
| 
 | ||||
|       <ContentPanel> | ||||
|         {props.libraryItems.map((item: LibraryItem) => ( | ||||
|           <Link href={"/library/" + item.attributes.slug} key={item.id} passHref> | ||||
|             <div> | ||||
|               <p> | ||||
|                 {prettyTitleSubtitle(item.attributes.title, item.attributes.subtitle)} | ||||
|               </p> | ||||
|               <p>{prettyDate(item.attributes.release_date)}</p> | ||||
| 
 | ||||
|               {item.attributes.thumbnail.data ? ( | ||||
|                 <Image | ||||
|                   src={getAssetURL(item.attributes.thumbnail.data.attributes.url)} | ||||
|                   alt={item.attributes.thumbnail.data.attributes.alternativeText} | ||||
|                   width={item.attributes.thumbnail.data.attributes.width} | ||||
|                   height={item.attributes.thumbnail.data.attributes.height} | ||||
|                 /> | ||||
|               ) : ( | ||||
|                 "" | ||||
|               )} | ||||
|             </div> | ||||
|           </Link> | ||||
|           <LibraryItemComponent key={item.id} item={item} /> | ||||
|         ))} | ||||
|       </ContentPanel> | ||||
|     </> | ||||
| @ -58,13 +44,3 @@ export const getStaticProps: GetStaticProps = async (context) => { | ||||
|     }, | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| function prettyTitleSubtitle(title: string, subtitle: string): string { | ||||
|   let result = title; | ||||
|   if (subtitle !== null) result += " - " + subtitle; | ||||
|   return result; | ||||
| } | ||||
| 
 | ||||
| function prettyDate(date: BasicDate): string { | ||||
|   return date.year + "/" + date.month + "/" + date.day; | ||||
| } | ||||
| @ -1,9 +1,15 @@ | ||||
| import { BasicDate, BasicPrice, BasicSize, queryGraphQL, UploadImage } from "queries/helpers"; | ||||
| import { | ||||
|   BasicDate, | ||||
|   BasicPrice, | ||||
|   BasicSize, | ||||
|   queryGraphQL, | ||||
|   UploadImage, | ||||
| } from "queries/helpers"; | ||||
| 
 | ||||
| export type LibraryItemSkeleton = { | ||||
|   attributes: { | ||||
|     slug: string; | ||||
|     subitems: {  | ||||
|     subitems: { | ||||
|       data: LibraryItemSkeleton[]; | ||||
|     }; | ||||
|   }; | ||||
| @ -63,7 +69,6 @@ export function getBreadcrumbs( | ||||
|   return result; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| export type LibraryItem = { | ||||
|   id: string; | ||||
|   attributes: { | ||||
| @ -90,14 +95,13 @@ export type LibrarySubItem = { | ||||
|     subtitle: string; | ||||
|     slug: string; | ||||
|     thumbnail: UploadImage; | ||||
|   } | ||||
| } | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export async function getLibraryItem( | ||||
|   slug: string[], | ||||
|   language_code: string | undefined | ||||
| ): Promise<LibraryItem> { | ||||
|   | ||||
|   return ( | ||||
|     await queryGraphQL( | ||||
|       ` | ||||
|  | ||||
| @ -1,4 +1,10 @@ | ||||
| import { UploadImage, queryGraphQL, BasicPrice, BasicDate, BasicSize } from "queries/helpers"; | ||||
| import { | ||||
|   UploadImage, | ||||
|   queryGraphQL, | ||||
|   BasicPrice, | ||||
|   BasicDate, | ||||
|   BasicSize, | ||||
| } from "queries/helpers"; | ||||
| 
 | ||||
| export type LibraryItem = { | ||||
|   id: string; | ||||
|  | ||||
							
								
								
									
										3
									
								
								src/styles/Library/LibraryItemComponent.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/styles/Library/LibraryItemComponent.module.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| .libraryItem { | ||||
|     cursor: pointer; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 DrMint
						DrMint