diff --git a/next.config.js b/next.config.js index b38fa01..3748040 100644 --- a/next.config.js +++ b/next.config.js @@ -2,7 +2,7 @@ module.exports = { reactStrictMode: true, i18n: { - locales: ['en', 'fr', 'ja', 'pt-br', 'pt-pt'], + locales: ['en', 'fr', 'ja', 'es'], defaultLocale: 'en', }, images: { diff --git a/src/components/Chronology/ChronologyItem.tsx b/src/components/Chronology/ChronologyItem.tsx deleted file mode 100644 index 68f234c..0000000 --- a/src/components/Chronology/ChronologyItem.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import styles from "styles/Chronology/ChronologyItemDisplay.module.css"; -import { - ChronologyItem, - ChronologyItemsEvent, - } from "queries/chronology/overview"; - - -export default function ChronologyItemDisplay(pageProps: ChronologyItem) { - - function generateAnchor(year: number, month: number, day:number, event?: number): string { - let result: string = ""; - result += year; - if (month) result += '-' + month; - if (day) result += '-' + day; - return result; - } - - function generateDate(displayed_date: string, year: number, month: number, day:number) { - let result: string = ""; - if (displayed_date) { - result += displayed_date; - } else { - result += year; - } - if (month) result += '/' + month; - if (day) result += '/' + day; - return result; - } - - return ( -
-

{generateDate(item.attributes.displayed_date, item.attributes.year, item.attributes.month, item.attributes.day)}

- {item.attributes.events.map((event: ChronologyItemsEvent) => ( -
-

- {event.translations.length ? event.translations[0].title : ""} -

-

- {event.translations.length - ? event.translations[0].description - : ""} - {event.translations.length ? event.translations[0].note : ""} -

-

- {event.source.data ? event.source.data.attributes.name : ""} -

-
- ))} -
- ); -} diff --git a/src/components/Chronology/ChronologyItemComponent.tsx b/src/components/Chronology/ChronologyItemComponent.tsx index 58b73ab..be6c337 100644 --- a/src/components/Chronology/ChronologyItemComponent.tsx +++ b/src/components/Chronology/ChronologyItemComponent.tsx @@ -2,7 +2,6 @@ import styles from "styles/Chronology/ChronologyItemComponent.module.css"; import { ChronologyItem, ChronologyItemsEvent, - ChronologyItemsEventTranslation, } from "queries/chronology/overview"; export type ChronologyItemComponentProps = { @@ -54,7 +53,7 @@ export default function ChronologyItemComponent( if (month) { result += lut[month - 1]; if (day) { - result += " " + day.toString().padStart(2, "0"); + result += " " + day; } } @@ -89,7 +88,7 @@ export default function ChronologyItemComponent( {props.item.attributes.events.map((event: ChronologyItemsEvent) => (
{event.translations.map( - (translation: ChronologyItemsEventTranslation) => ( + (translation) => ( <> {translation.title ?

{translation.title}

: ""} @@ -100,12 +99,15 @@ export default function ChronologyItemComponent( } > {translation.description} -

) : ( "" )} - {translation.note ? {"Notes: " + translation.note} : ""} + {translation.note ? ( + {"Notes: " + translation.note} + ) : ( + "" + )} ) )} @@ -113,7 +115,7 @@ export default function ChronologyItemComponent(

{event.source.data ? "(" + event.source.data.attributes.name + ")" - : ""} + : "(WARNING: NO SOURCE!)"}

))} diff --git a/src/components/Chronology/ChronologyYearComponent.tsx b/src/components/Chronology/ChronologyYearComponent.tsx index 6dc6b39..165b30c 100644 --- a/src/components/Chronology/ChronologyYearComponent.tsx +++ b/src/components/Chronology/ChronologyYearComponent.tsx @@ -1,21 +1,28 @@ import styles from "styles/Chronology/ChronologyYearComponent.module.css"; -import { - ChronologyItem -} from "queries/chronology/overview"; +import { ChronologyItem } from "queries/chronology/overview"; import ChronologyItemComponent from "components/Chronology/ChronologyItemComponent"; type ChronologyYearComponentProps = { - items: ChronologyItem[]; -} + items: ChronologyItem[]; +}; -export default function ChronologyYearComponent(props: ChronologyYearComponentProps) { +export default function ChronologyYearComponent( + props: ChronologyYearComponentProps +) { return ( -
1 ? props.items[0].attributes.year.toString() : undefined}> +
1 + ? props.items[0].attributes.year.toString() + : undefined + } + > {props.items.map((item: ChronologyItem, index: number) => ( ))}
diff --git a/src/pages/chronology/overview.tsx b/src/pages/chronology/overview.tsx index f161e55..3d1377a 100644 --- a/src/pages/chronology/overview.tsx +++ b/src/pages/chronology/overview.tsx @@ -3,7 +3,6 @@ import ContentPanel from "components/Panels/ContentPanel"; import SubPanel from "components/Panels/SubPanel"; import ReturnButton from "components/Panels/ReturnButton"; import NavOption from "components/Panels/NavOption"; -import ChronologyItemComponent from "components/Chronology/ChronologyItemComponent"; import ChronologyYearComponent from "components/Chronology/ChronologyYearComponent"; import { getChronologyItems, @@ -20,12 +19,8 @@ type Props = { export default function ChronologyOverview(props: Props): JSX.Element { - let previousYear = -1; - - let chronologyItemYearGroups: ChronologyItem[][] = []; - - // Group by year the Chronology items + let chronologyItemYearGroups: ChronologyItem[][] = []; props.chronologyItems.map((item: ChronologyItem) => { if (!chronologyItemYearGroups.hasOwnProperty(item.attributes.year)) { chronologyItemYearGroups[item.attributes.year] = [item]; diff --git a/src/pages/library/[...slug].tsx b/src/pages/library/[...slug].tsx index 78c369a..a2735ea 100644 --- a/src/pages/library/[...slug].tsx +++ b/src/pages/library/[...slug].tsx @@ -1,15 +1,16 @@ import { useRouter } from "next/router"; -import SubPanel from "components/Panels/SubPanel"; import ContentPanel from "components/Panels/ContentPanel"; import { getAssetURL } from "queries/helpers"; import { getLibraryItem, - getRecursiveSlugs, + getBreadcrumbs, + getLibraryItemsSkeleton, LibraryItem, - Subitem, + LibrarySubItem } from "queries/library/[...slug]"; import Image from "next/image"; import Link from "next/link"; +import { GetStaticProps } from "next"; type Props = { libraryItem: LibraryItem; @@ -20,28 +21,33 @@ export default function Library(props: Props): JSX.Element { return ( <> -

{props.libraryItem.title}

-

{props.libraryItem.subtitle}

+

{props.libraryItem.attributes.title}

+

{props.libraryItem.attributes.subtitle}

{props.libraryItem.thumbnail.title} - {props.libraryItem.subitems.map((subitem: Subitem) => ( + {props.libraryItem.attributes.subitems.data.map((subitem: LibrarySubItem) => (
- {subitem.subitem_id.thumbnail ? ( + {subitem.attributes.thumbnail.data ? ( {subitem.subitem_id.thumbnail.title} ) : ( "" @@ -49,27 +55,31 @@ export default function Library(props: Props): JSX.Element {
))} + +
); } -export async function getStaticProps({ params }) { - return { - props: { - libraryItem: await getLibraryItem(params.slug), - }, - }; +export const getStaticProps: GetStaticProps = async (context) => { + console.log(context.params); + if (context.params && Array.isArray(context.params.slug) && context.locale) { + return { + props: { + libraryItem: (await getLibraryItem(context.params.slug, context.locale)), + }, + }; + } + return {props: {}}; } export async function getStaticPaths() { - const paths = await getAllSlugs(); + const paths = (await getAllSlugs()); - /* paths.map((item) => { console.log(item.params.slug); }); - */ return { paths, @@ -78,11 +88,19 @@ export async function getStaticPaths() { } async function getAllSlugs() { - return (await getRecursiveSlugs()).map((item) => { - return { - params: { - slug: item, - }, - }; - }); + type Path = { + params: { + slug: string[]; + } + } + + const data = (await getLibraryItemsSkeleton()); + const paths:Path[] = []; + data.map((item) => { + const breadcrumbs = getBreadcrumbs([], item); + breadcrumbs.map((breadcrumb) => { + paths.push({params: {slug: breadcrumb}}) + }) + }) + return paths; } diff --git a/src/pages/library/index.tsx b/src/pages/library/index.tsx index f48c642..308a16d 100644 --- a/src/pages/library/index.tsx +++ b/src/pages/library/index.tsx @@ -2,7 +2,7 @@ import { GetStaticProps } from "next"; import SubPanel from "components/Panels/SubPanel"; import ContentPanel from "components/Panels/ContentPanel"; import { LibraryItem, getLibraryItems } from "queries/library/index"; -import { getAssetURL } from "queries/helpers"; +import { BasicDate, getAssetURL } from "queries/helpers"; import Image from "next/image"; import Link from "next/link"; @@ -26,25 +26,19 @@ export default function Library(props: Props): JSX.Element { {props.libraryItems.map((item: LibraryItem) => ( - +

- {item.subitem_of.length > 0 - ? prettyTitleSubtitle( - item.subitem_of[0].item_id.title, - item.subitem_of[0].item_id.subtitle - ) + " • " - : ""} - {prettyTitleSubtitle(item.title, item.subtitle)} + {prettyTitleSubtitle(item.attributes.title, item.attributes.subtitle)}

-

{item.release_date}

+

{prettyDate(item.attributes.release_date)}

- {item.thumbnail ? ( + {item.attributes.thumbnail.data ? ( {item.thumbnail.title} ) : ( "" @@ -60,7 +54,7 @@ export default function Library(props: Props): JSX.Element { export const getStaticProps: GetStaticProps = async (context) => { return { props: { - libraryItems: await getLibraryItems(), + libraryItems: await getLibraryItems(context.locale), }, }; }; @@ -70,3 +64,7 @@ function prettyTitleSubtitle(title: string, subtitle: string): string { if (subtitle !== null) result += " - " + subtitle; return result; } + +function prettyDate(date: BasicDate): string { + return date.year + "/" + date.month + "/" + date.day; +} \ No newline at end of file diff --git a/src/queries/chronology/overview.ts b/src/queries/chronology/overview.ts index 978ef83..5915ca8 100644 --- a/src/queries/chronology/overview.ts +++ b/src/queries/chronology/overview.ts @@ -1,41 +1,30 @@ import { queryGraphQL } from "queries/helpers"; +import { Source } from "queries/helpers"; export type ChronologyItem = { id: string; - attributes: ChronologyItemAttributes; + attributes: { + year: number; + month: number; + day: number; + displayed_date: string; + events: ChronologyItemsEvent[]; + }; }; -export type ChronologyItemAttributes = { - year: number; - month: number; - day: number; - displayed_date: string; - events: ChronologyItemsEvent[]; -} - export type ChronologyItemsEvent = { id: string; - source: Source - translations: ChronologyItemsEventTranslation[]; + source: Source; + translations: { + title: string; + description: string; + note: string; + status: string; + }[]; }; -export type ChronologyItemsEventTranslation = { - title: string; - description: string; - note: string; - status: string; -} - -export type Source = { - data: { - attributes: { - name: string; - } - } -} - export async function getChronologyItems( - language_code: String | undefined + language_code: string | undefined ): Promise { return ( await queryGraphQL( @@ -58,7 +47,7 @@ export async function getChronologyItems( } } } - translations(filters: { language: { code: { eq: "` + language_code + `" } } }) { + translations(filters: { language: { code: { eq: "${language_code}" } } }) { title description note @@ -84,14 +73,14 @@ export type ChronologyEraAttributes = { starting_year: number; ending_year: number; title: ChronologyEraTranslation[]; -} +}; export type ChronologyEraTranslation = { title: string; }; export async function getChronologyEras( - language_code: String | undefined + language_code: string | undefined ): Promise { return ( await queryGraphQL( @@ -104,7 +93,7 @@ export async function getChronologyEras( slug starting_year ending_year - title (filters: {language: {code: {eq: "` + language_code + `"}}}){ + title (filters: {language: {code: {eq: "${language_code}"}}}){ title } } diff --git a/src/queries/helpers.ts b/src/queries/helpers.ts index e79ecbf..cb528ef 100644 --- a/src/queries/helpers.ts +++ b/src/queries/helpers.ts @@ -1,16 +1,3 @@ -/* -export const queryGraphQL = async (query: string) => { - const res = await fetch( - process.env.URL_GRAPHQL + - "?access_token=" + - process.env.ACCESS_TOKEN + - "&query=" + - query - ); - return (await res.json()).data; -}; -*/ - export const queryGraphQL = async (query: String) => { const res = await fetch(process.env.URL_GRAPHQL, { method: "POST", @@ -25,7 +12,6 @@ export const queryGraphQL = async (query: String) => { return (await res.json()).data; }; - export const queryGraphQLSystem = async (query: string) => { const res = await fetch( process.env.URL_GRAPHQL_SYSTEM + @@ -37,13 +23,53 @@ export const queryGraphQLSystem = async (query: string) => { return (await res.json()).data; }; -export type AssetImage = { - id: string; - title: string; - width: number; - height: number; +export function getAssetURL(url: string): string { + return process.env.NEXT_PUBLIC_URL_CMS + url; +} + +export type Source = { + data: { + attributes: { + name: string; + }; + }; }; -export function getAssetURL(id: string): string { - return "https://cms.accords-library.com/assets/" + id; -} \ No newline at end of file +export type UploadImage = { + data: { + attributes: { + name: string; + alternativeText: string; + caption: string; + width: number; + height: number; + url: string; + }; + }; +}; + +export type BasicPrice = { + amount: number; + currency: BasicCurrency; +}; + +export type BasicCurrency = { + data: { + attributes: { + symbol: string; + code: string; + }; + }; +}; + +export type BasicSize = { + width: number; + height: number; + thickness: number; +}; + +export type BasicDate = { + year: number; + month: number; + day: number; +}; diff --git a/src/queries/library/[...slug].ts b/src/queries/library/[...slug].ts index 6502910..5a328b7 100644 --- a/src/queries/library/[...slug].ts +++ b/src/queries/library/[...slug].ts @@ -1,51 +1,45 @@ -import { queryGraphQL, AssetImage } from "queries/helpers"; +import { BasicDate, BasicPrice, BasicSize, queryGraphQL, UploadImage } from "queries/helpers"; -export type LibraryItem = { - title: string; - subtitle: string; - slug: string; - thumbnail: AssetImage; - subitems: Subitem[]; +export type LibraryItemSkeleton = { + attributes: { + slug: string; + subitems: { + data: LibraryItemSkeleton[]; + }; + }; }; -export type Subitem = { - subitem_id: LibrarySubitem; -}; - -export type LibrarySubitem = { - id: string; - title: string; - subtitle: string; - slug: string; - thumbnail: AssetImage; -}; - -export async function getLibraryItem(slug: string[]) { +export async function getLibraryItemsSkeleton(): Promise< + LibraryItemSkeleton[] +> { return ( await queryGraphQL( ` { - compendium_items(filter: {_and: [` + getFilterForItem(slug) + `]}) { - title - subtitle - slug - thumbnail { - id - title - width - height - } - subitems { - subitem_id { - id - title - subtitle + libraryItems(filters: { root_item: { eq: true } }) { + data { + attributes { slug - thumbnail { - id - title - width - height + subitems { + data { + attributes { + slug + subitems { + data { + attributes { + slug + subitems { + data { + attributes { + slug + } + } + } + } + } + } + } + } } } } @@ -53,118 +47,133 @@ export async function getLibraryItem(slug: string[]) { } ` ) - ).compendium_items[0]; + ).libraryItems.data; } -export async function getRecursiveSlugs() { - const yetToExploreSlugs = level0Filtering( - ( - await queryGraphQL( - ` - { - compendium_items( - filter: { _and: [{ not_sold_separately: { _eq: false } }] } - ) { - subitem_of { - item_id { - virtual_set - } - } - slug - } - } - ` - ) - ).compendium_items - ); - +export function getBreadcrumbs( + parentBreadcrumb: string[], + data: LibraryItemSkeleton +) { const result: string[][] = []; - while (yetToExploreSlugs.length > 0) { - const slug = yetToExploreSlugs.pop(); - if (slug !== undefined) { - const subitems = levelnFiltering((await queryGraphQL( - ` - { - compendium_items(filter: {_and: [` + getFilterForSubitemsOf(slug) + `]}) { + const itemBreadcrumb = [...parentBreadcrumb, data.attributes.slug]; + result.push(itemBreadcrumb); + data.attributes.subitems.data.map((subitem) => { + result.push(...getBreadcrumbs(itemBreadcrumb, subitem)); + }); + return result; +} + + +export type LibraryItem = { + id: string; + attributes: { + title: string; + subtitle: string; + slug: string; + thumbnail: UploadImage; + release_date: BasicDate; + price: BasicPrice; + size: BasicSize; + description: { + description: string; + }; + subitems: { + data: LibrarySubItem[]; + }; + }; +}; + +export type LibrarySubItem = { + id: string; + attributes: { + title: string; + subtitle: string; + slug: string; + thumbnail: UploadImage; + } +} + +export async function getLibraryItem( + slug: string[], + language_code: string | undefined +): Promise { + + return ( + await queryGraphQL( + ` + { + libraryItems( + filters: {slug: {eq: "${slug.pop()}"}} + ) { + data { + id + attributes { + title + subtitle slug + thumbnail { + data { + attributes { + name + alternativeText + caption + width + height + url + } + } + } + release_date { + year + month + day + } + price { + amount + currency { + data { + attributes { + symbol + code + } + } + } + } + size { + width + height + thickness + } + descriptions(filters: { language: { code: { eq: "${language_code}" } } }) { + description + } + subitems { + data { + id + attributes { + slug + title + subtitle + thumbnail { + data { + attributes { + name + alternativeText + caption + width + height + url + } + } + } + } + } + } } } - ` - ) - ).compendium_items - ); - result.push(slug); - subitems.map((subitemSlug) => { - const newSlug = [...slug]; - newSlug.push(subitemSlug); - yetToExploreSlugs.push(newSlug); - }); - } - } - return result; -} - -export function getFilterForSubitemsOf(slug: string[]) { - let filter = ""; - slug.map((segment, index) => { - const depth = slug.length - index; - filter += "{ subitem_of: { item_id: ".repeat(depth); - filter += '{ slug: { _eq: "' + segment + '" } } '; - filter += "} } ".repeat(depth); - filter += ","; - }); - return filter; -} - -export function getFilterForItem(slug: string[]) { - let filter = ""; - slug.map((segment, index) => { - const depth = slug.length - index - 1; - filter += "{ subitem_of: { item_id: ".repeat(depth); - filter += '{ slug: { _eq: "' + segment + '" } } '; - filter += "} } ".repeat(depth); - filter += ","; - }); - return filter; -} - - -function level0Filtering(data: SlugLvl0[]): string[][] { - // Remove element if their parent item is a virtual_set - let result: string[][] = []; - data.map((item: SlugLvl0) => { - if (item.subitem_of.length > 0) { - if (item.subitem_of[0].item_id.virtual_set === false) { - result.push([item.slug]); + } } - } else { - result.push([item.slug]); - } - }); - return result; + ` + ) + ).libraryItems.data[0]; } - -function levelnFiltering(data: SlugLvln[]): string[] { - let result: string[] = []; - data.map((item: SlugLvln) => { - result.push(item.slug); - }); - return result; -} - -type SlugLvl0 = { - subitem_of: SlugLvl0Subitem_of[]; - slug: string; -}; - -type SlugLvl0Subitem_of = { - item_id: SlugLvl0Subitem; -}; - -type SlugLvl0Subitem = { - virtual_set: boolean; -}; - -type SlugLvln = { - slug: string; -}; diff --git a/src/queries/library/index.ts b/src/queries/library/index.ts index 2915040..0a61b5a 100644 --- a/src/queries/library/index.ts +++ b/src/queries/library/index.ts @@ -1,72 +1,80 @@ -import { queryGraphQL, AssetImage } from "queries/helpers"; +import { UploadImage, queryGraphQL, BasicPrice, BasicDate, BasicSize } from "queries/helpers"; export type LibraryItem = { id: string; - subitem_of: Subitem_of[]; - title: string; - subtitle: string; - slug: string; - thumbnail: AssetImage; - release_date: string; - type: "Text" | "Video" | "Games" | "Soundtrack" | "Audiobooks" | "Other"; + attributes: { + title: string; + subtitle: string; + slug: string; + thumbnail: UploadImage; + release_date: BasicDate; + price: BasicPrice; + size: BasicSize; + description: { + description: string; + }; + }; }; -export type Subitem_of = { - item_id: LibrarySubitem; -}; - -export type LibrarySubitem = { - title: string; - subtitle: string; - virtual_set: boolean; -}; - -export async function getLibraryItems() { - return filterGetLibraryItems((await queryGraphQL( +export async function getLibraryItems( + language_code: string | undefined +): Promise { + return ( + await queryGraphQL( ` { - compendium_items( - filter: { _and: [{ not_sold_separately: { _eq: false } }] } - sort: "title" + libraryItems( + filters: { root_item: { eq: true } } + pagination: { limit: -1 } + sort: ["slug:asc"] ) { - id - subitem_of { - item_id { + data { + id + attributes { title subtitle - virtual_set + slug + thumbnail { + data { + attributes { + name + alternativeText + caption + width + height + url + } + } + } + release_date { + year + month + day + } + price { + amount + currency { + data { + attributes { + symbol + code + } + } + } + } + size { + width + height + thickness + } + descriptions(filters: { language: { code: { eq: "${language_code}" } } }) { + description + } } } - title - subtitle - slug - thumbnail { - id - title - width - height - } - release_date - type } } ` ) - ).compendium_items); + ).libraryItems.data; } - -function filterGetLibraryItems(data: LibraryItem[]): LibraryItem[] { - - // Remove element if their parent item is a virtual_set - let result: LibraryItem[] = []; - data.map((item: LibraryItem) => { - if (item.subitem_of.length > 0) { - if (item.subitem_of[0].item_id.virtual_set === false) { - result.push(item); - } - } else { - result.push(item); - } - }); - return result; -} \ No newline at end of file