diff --git a/src/i18n/i18n.ts b/src/i18n/i18n.ts index 3ed5728..9e8cc91 100644 --- a/src/i18n/i18n.ts +++ b/src/i18n/i18n.ts @@ -5,6 +5,8 @@ import { capitalize, formatInlineTitle } from "src/utils/format"; export const defaultLocale = "en"; +export type I18n = Awaited>; + export const getI18n = async (locale: string) => { const formatWithValues = ( templateName: string, diff --git a/src/pages/[locale]/folders/_components/RowView.astro b/src/pages/[locale]/folders/_components/RowView.astro new file mode 100644 index 0000000..a54606d --- /dev/null +++ b/src/pages/[locale]/folders/_components/RowView.astro @@ -0,0 +1,257 @@ +--- +import { Icon } from "astro-icon/components"; +import { getI18n } from "src/i18n/i18n"; +import { + Collections, + type EndpointFolder, + type EndpointImage, +} from "src/shared/payload/payload-sdk"; +import { type Attribute, convertEndpointAttributeToAttribute } from "src/utils/attributes"; +import { formatLocale } from "src/utils/format"; + +interface Props { + files: EndpointFolder["files"]; +} + +const { files } = Astro.props; + +type Row = { + thumbnail?: EndpointImage | undefined; + pretitle?: string | undefined; + title: string; + lang?: string | undefined; + subtitle?: string | undefined; + icon?: string; + iconHoverLabel?: string; + attributes: Attribute[]; +}; + +const i18n = await getI18n(Astro.locals.currentLocale); +const { t, getLocalizedMatch } = i18n; + +const rows = files.map(({ relationTo, value }) => { + switch (relationTo) { + case Collections.Collectibles: { + const { title, pretitle, subtitle, language } = getLocalizedMatch(value.translations); + + const attributes = value.attributes.map((attribute) => + convertEndpointAttributeToAttribute(attribute, i18n) + ); + + const additionalAttributes: Attribute[] = []; + + if (value.languages.length > 0) { + additionalAttributes.push({ + title: t("collectibles.languages"), + icon: "material-symbols:translate", + values: value.languages.map((lang) => ({ name: formatLocale(lang) })), + withBorder: true, + }); + } + + return { + thumbnail: value.thumbnail, + title, + pretitle, + subtitle, + lang: language, + icon: "material-symbols:category", + iconHoverLabel: t("global.previewTypes.collectible"), + attributes: [...attributes, ...additionalAttributes], + }; + } + } + return { title: "Error", attributes: [] }; +}); + +const commomAttributes = [ + ...new Map>( + rows.flatMap(({ attributes }) => attributes.map((attribute) => [attribute.title, attribute])) + ).values(), +]; +--- + + + + + + + { + commomAttributes.map(({ title, icon }) => ( + + )) + } + + + + { + rows.map( + ({ thumbnail, pretitle, title, subtitle, lang, icon, iconHoverLabel, attributes }) => ( + + + + {commomAttributes.map((attributeToFind) => { + const attribute = attributes.find(({ title }) => title === attributeToFind.title); + if (!attribute) return ; + return ( + + ); + })} + + ) + ) + } + +
+
+ +

{title}

+
+
+ {thumbnail ? ( + + ) : ( +
+ +
+ )} +
+

+ {pretitle && ( + + {pretitle} + + )} + {title} + {subtitle && ( + + {subtitle} + + )} +

+
+
+ {attribute.values.map(({ name }) => ( +
+ {name} +
+ ))} +
+
+ + diff --git a/src/utils/attributes.ts b/src/utils/attributes.ts index b7207cc..a2af69e 100644 --- a/src/utils/attributes.ts +++ b/src/utils/attributes.ts @@ -1,3 +1,6 @@ +import type { I18n } from "src/i18n/i18n"; +import { AttributeTypes, type EndpointAttribute } from "src/shared/payload/payload-sdk"; + export type Attribute = { icon: string; title: string; @@ -5,3 +8,34 @@ export type Attribute = { values: { name: string; href?: string | undefined; lang?: string | undefined }[]; withBorder?: boolean | undefined; }; + +export const convertEndpointAttributeToAttribute = ( + endpointAttribute: EndpointAttribute, + { getLocalizedMatch, getLocalizedUrl, formatNumber }: I18n +): Attribute => { + const { icon, translations, value, type } = endpointAttribute; + const { language: lang, name: title } = getLocalizedMatch(translations); + + switch (type) { + case AttributeTypes.Number: + return { icon, title, lang, values: [{ name: formatNumber(value) }] }; + + case AttributeTypes.Text: + return { icon, title, lang, values: [{ name: value }] }; + + case AttributeTypes.Tags: + return { + icon, + title, + lang, + values: value.map(({ translations, page }) => { + const { name, language } = getLocalizedMatch(translations); + return { + name, + lang: language, + ...(page ? { href: getLocalizedUrl(`/pages/${page.slug}`) } : {}), + }; + }), + }; + } +};