From 91e67a76451da46766858603cd585b256304073e Mon Sep 17 00:00:00 2001 From: DrMint <29893320+DrMint@users.noreply.github.com> Date: Thu, 16 May 2024 14:15:49 +0200 Subject: [PATCH] Added recorders pages --- TODO.md | 3 +- .../Topbar/components/ParentPagesButton.astro | 2 +- src/components/Credits.astro | 7 +- src/components/Metadata.astro | 4 +- src/pages/[locale]/api/pages/partial.astro | 7 +- .../[locale]/collectibles/[slug]/index.astro | 8 +- src/pages/[locale]/recorders/[id].astro | 91 +++++++++++++++++++ src/shared/payload/payload-sdk.ts | 29 +++++- 8 files changed, 132 insertions(+), 19 deletions(-) create mode 100644 src/pages/[locale]/recorders/[id].astro diff --git a/TODO.md b/TODO.md index 4c2b639..7f797a6 100644 --- a/TODO.md +++ b/TODO.md @@ -3,7 +3,6 @@ ## Short term - Number of audio players seems limited (on Chrome and Firefox) -- Create a tool to upload scans images and apply them to collectible - Automatically generate different sizes of images - Handle relationship in RichText Content @@ -15,7 +14,6 @@ - [Timeline] Error if collectible not published? - [Timeline] display source language - [Timeline] Add details button in footer with credits + last updated / created -- When the tags overflow, the tag group name should be align start (see http://localhost:12499/en/pages/magnitude-negative-chapter-1) - [SDK] create a initPayload() that return a payload sdk (and stop hard wirring to ENV or node-cache) - [Videos] see why no video on Firefox and no poster on Chrome https://v3.accords-library.com/en/videos/661b672825d380e548dbb8c8 - [Videos] Display platform info + channel page @@ -41,6 +39,7 @@ - Convert Rich text to simple text for indexing and open graph purposes - Anonymous comments - [Images] add images group (which could be named or not) +- [Recorders] add list of contributions on recorders' pages ## Bonus diff --git a/src/components/AppLayout/components/Topbar/components/ParentPagesButton.astro b/src/components/AppLayout/components/Topbar/components/ParentPagesButton.astro index 0a8cda5..970c668 100644 --- a/src/components/AppLayout/components/Topbar/components/ParentPagesButton.astro +++ b/src/components/AppLayout/components/Topbar/components/ParentPagesButton.astro @@ -21,7 +21,7 @@ const { t } = await getI18n(Astro.locals.currentLocale); parentPages.length === 1 && parentPages[0] ? ( ) : ( - +

{t("header.nav.parentPages.tooltip")}

diff --git a/src/components/Credits.astro b/src/components/Credits.astro index fbf34d0..be16fab 100644 --- a/src/components/Credits.astro +++ b/src/components/Credits.astro @@ -8,7 +8,7 @@ interface Props { } const { credits } = Astro.props; -const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale); +const { getLocalizedMatch, getLocalizedUrl } = await getI18n(Astro.locals.currentLocale); --- {/* ------------------------------------------- HTML ------------------------------------------- */} @@ -19,7 +19,10 @@ const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale); ({ name: username }))} + values={recorders.map(({ username, id }) => ({ + name: username, + href: getLocalizedUrl(`/recorders/${id}`), + }))} /> )) } diff --git a/src/components/Metadata.astro b/src/components/Metadata.astro index 341308f..300a293 100644 --- a/src/components/Metadata.astro +++ b/src/components/Metadata.astro @@ -1,4 +1,4 @@ ---- + --- import { Icon } from "astro-icon/components"; import type { Attribute } from "src/utils/attributes"; @@ -38,7 +38,6 @@ if (values.length === 0) return; display: grid; grid-template-columns: auto 1fr; gap: 0.5em 1em; - align-items: center; @media (max-width: 35em) { grid-template-columns: 1fr; @@ -46,7 +45,6 @@ if (values.length === 0) return; & > #title { display: flex; - place-items: center; gap: 8px; & > p { diff --git a/src/pages/[locale]/api/pages/partial.astro b/src/pages/[locale]/api/pages/partial.astro index ef2bde3..db33adb 100644 --- a/src/pages/[locale]/api/pages/partial.astro +++ b/src/pages/[locale]/api/pages/partial.astro @@ -10,6 +10,7 @@ import { getI18n } from "src/i18n/i18n"; import AsideLayout from "components/AppLayout/AsideLayout.astro"; import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro"; import Attributes from "components/Attributes.astro"; +import type { Attribute } from "src/utils/attributes"; export const partial = true; @@ -31,18 +32,16 @@ const { getLocalizedMatch } = await getI18n(lang); const { pretitle, title, subtitle, summary, content, credits, toc, language, sourceLanguage } = getLocalizedMatch(translations); -const metaAttributes = [ +const metaAttributes: Attribute[] = [ { title: t("global.media.attributes.createdAt"), icon: "material-symbols:calendar-add-on-outline", values: [{ name: formatDate(new Date(createdAt)) }], - withBorder: false, }, { title: t("global.media.attributes.updatedAt"), icon: "material-symbols:edit-calendar", values: [{ name: formatDate(new Date(updatedAt)) }], - withBorder: false, }, ]; @@ -50,7 +49,7 @@ if (updatedBy) { metaAttributes.push({ title: t("global.media.attributes.updatedBy"), icon: "material-symbols:person-edit-outline", - values: [{ name: updatedBy.username }], + values: [{ name: updatedBy.username, href: getLocalizedUrl(`/recorders/${updatedBy.id}`) }], withBorder: true, }); } diff --git a/src/pages/[locale]/collectibles/[slug]/index.astro b/src/pages/[locale]/collectibles/[slug]/index.astro index 6884c94..8cf7554 100644 --- a/src/pages/[locale]/collectibles/[slug]/index.astro +++ b/src/pages/[locale]/collectibles/[slug]/index.astro @@ -16,6 +16,7 @@ import AsideLayout from "components/AppLayout/AsideLayout.astro"; import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro"; import { convert } from "src/utils/currencies"; import Attributes from "components/Attributes.astro"; +import type { Attribute } from "src/utils/attributes"; const { slug } = Astro.params; const { getLocalizedMatch, getLocalizedUrl, t, formatDate, formatPrice } = await getI18n( @@ -53,18 +54,16 @@ const { const translation = getLocalizedMatch(translations); const { pretitle, title, subtitle, description } = translation; -const metaAttributes = [ +const metaAttributes: Attribute[] = [ { title: t("global.media.attributes.createdAt"), icon: "material-symbols:calendar-add-on-outline", values: [{ name: formatDate(new Date(createdAt)) }], - withBorder: false, }, { title: t("global.media.attributes.updatedAt"), icon: "material-symbols:edit-calendar", values: [{ name: formatDate(new Date(updatedAt)) }], - withBorder: false, }, ]; @@ -72,7 +71,7 @@ if (updatedBy) { metaAttributes.push({ title: t("global.media.attributes.updatedBy"), icon: "material-symbols:person-edit-outline", - values: [{ name: updatedBy.username }], + values: [{ name: updatedBy.username, href: getLocalizedUrl(`/recorders/${updatedBy.id}`) }], withBorder: true, }); } @@ -259,7 +258,6 @@ if (price) { max-height: 80vh; width: auto; height: auto; - border-radius: 16px; box-shadow: 0 5px 20px -10px var(--color-shadow); transition: 100ms scale; diff --git a/src/pages/[locale]/recorders/[id].astro b/src/pages/[locale]/recorders/[id].astro new file mode 100644 index 0000000..4ebafcb --- /dev/null +++ b/src/pages/[locale]/recorders/[id].astro @@ -0,0 +1,91 @@ +--- +import AppLayout from "components/AppLayout/AppLayout.astro"; +import AsideLayout from "components/AppLayout/AsideLayout.astro"; +import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro"; +import Attributes from "components/Attributes.astro"; +import RichText from "components/RichText/RichText.astro"; +import { getI18n } from "src/i18n/i18n"; +import { payload } from "src/shared/payload/payload-sdk"; +import type { Attribute } from "src/utils/attributes"; +import { formatLocale } from "src/utils/format"; +import { fetchOr404 } from "src/utils/responses"; + +const id = Astro.params.id!; +const recorder = await fetchOr404(() => payload.getRecorderByID(id)); +if (recorder instanceof Response) { + return recorder; +} + +const { t, getLocalizedMatch } = await getI18n(Astro.locals.currentLocale); + +const { username, languages, avatar, translations } = recorder; + +const { biography } = + translations.length > 0 ? getLocalizedMatch(translations) : { biography: undefined }; + +const additionalAttributes: Attribute[] = []; + +if (languages.length > 0) { + additionalAttributes.push({ + title: t("collectibles.languages"), + icon: "material-symbols:translate", + values: languages.map((lang) => ({ name: formatLocale(lang) })), + withBorder: true, + }); +} +--- + +{/* ------------------------------------------- HTML ------------------------------------------- */} + + + + + + + + { + avatar && ( + + + + ) + } + + { + avatar && additionalAttributes.length > 0 && ( + + + + ) + } + +
+ { + !avatar && additionalAttributes.length > 0 && ( + + ) + } + {biography && } +
+
+
+ +{/* ------------------------------------------- CSS -------------------------------------------- */} + + diff --git a/src/shared/payload/payload-sdk.ts b/src/shared/payload/payload-sdk.ts index 5e4124c..b8a0677 100644 --- a/src/shared/payload/payload-sdk.ts +++ b/src/shared/payload/payload-sdk.ts @@ -262,6 +262,27 @@ export interface Recorder { username: string; avatar?: string | Image | null; languages?: (string | Language)[] | null; + translations?: + | { + language: string | Language; + biography: { + root: { + type: string; + children: { + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ("ltr" | "rtl") | null; + format: "left" | "start" | "center" | "right" | "end" | "justify" | ""; + indent: number; + version: number; + }; + [k: string]: unknown; + }; + id?: string | null; + }[] + | null; role?: ("Admin" | "Recorder" | "Api")[] | null; anonymize: boolean; email: string; @@ -1471,6 +1492,10 @@ export type EndpointRecorder = { id: string; username: string; avatar?: EndpointImage; + translations: { + language: string; + biography: RichTextContent; + }[]; languages: string[]; }; @@ -1854,8 +1879,6 @@ export const payload = { await (await request(payloadApiUrl(Collections.Currencies, `all`))).json(), getWordings: async (): Promise => await (await request(payloadApiUrl(Collections.Wordings, `all`))).json(), - getRecorders: async (): Promise => - await (await request(payloadApiUrl(Collections.Recorders, `all`))).json(), getPage: async (slug: string): Promise => await (await request(payloadApiUrl(Collections.Pages, `slug/${slug}`))).json(), getCollectible: async (slug: string): Promise => @@ -1888,4 +1911,6 @@ export const payload = { await (await request(payloadApiUrl(Collections.Audios, `id/${id}`))).json(), getVideoByID: async (id: string): Promise => await (await request(payloadApiUrl(Collections.Videos, `id/${id}`))).json(), + getRecorderByID: async (id: string): Promise => + await (await request(payloadApiUrl(Collections.Recorders, `id/${id}`))).json(), };