Added recorders pages
This commit is contained in:
parent
0e148f06cf
commit
91e67a7645
3
TODO.md
3
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
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ const { t } = await getI18n(Astro.locals.currentLocale);
|
|||
parentPages.length === 1 && parentPages[0] ? (
|
||||
<ReturnToButton parentPage={parentPages[0]} />
|
||||
) : (
|
||||
<Tooltip trigger="click">
|
||||
<Tooltip trigger="click" class="when-js">
|
||||
<div id="tooltip-content" slot="tooltip-content">
|
||||
<p>{t("header.nav.parentPages.tooltip")}</p>
|
||||
<div>
|
||||
|
|
|
@ -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);
|
|||
<Metadata
|
||||
icon={icon}
|
||||
title={getLocalizedMatch(translations).name}
|
||||
values={recorders.map(({ username }) => ({ name: username }))}
|
||||
values={recorders.map(({ username, id }) => ({
|
||||
name: username,
|
||||
href: getLocalizedUrl(`/recorders/${id}`),
|
||||
}))}
|
||||
/>
|
||||
))
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 ------------------------------------------- */}
|
||||
|
||||
<AppLayout>
|
||||
<AsideLayout>
|
||||
<Fragment slot="header">
|
||||
<AppLayoutTitle pretitle={`Recorder#${id.substring(0, 5)}`} title={username} />
|
||||
</Fragment>
|
||||
|
||||
{
|
||||
avatar && (
|
||||
<Fragment slot="header-aside">
|
||||
<img src={avatar.url} width={avatar.width} height={avatar.height} />
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
avatar && additionalAttributes.length > 0 && (
|
||||
<Fragment slot="aside">
|
||||
<Attributes attributes={additionalAttributes} />
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
<div id="info">
|
||||
{
|
||||
!avatar && additionalAttributes.length > 0 && (
|
||||
<Attributes attributes={additionalAttributes} />
|
||||
)
|
||||
}
|
||||
{biography && <RichText content={biography} />}
|
||||
</div>
|
||||
</AsideLayout>
|
||||
</AppLayout>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
img {
|
||||
max-width: min(35rem, 100%);
|
||||
max-height: 50vh;
|
||||
width: auto;
|
||||
height: auto;
|
||||
margin-bottom: 2em;
|
||||
|
||||
@media (max-width: 1280.5px) {
|
||||
margin-top: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
#info {
|
||||
margin-top: 2em;
|
||||
}
|
||||
</style>
|
|
@ -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<EndpointWording[]> =>
|
||||
await (await request(payloadApiUrl(Collections.Wordings, `all`))).json(),
|
||||
getRecorders: async (): Promise<EndpointRecorder[]> =>
|
||||
await (await request(payloadApiUrl(Collections.Recorders, `all`))).json(),
|
||||
getPage: async (slug: string): Promise<EndpointPage> =>
|
||||
await (await request(payloadApiUrl(Collections.Pages, `slug/${slug}`))).json(),
|
||||
getCollectible: async (slug: string): Promise<EndpointCollectible> =>
|
||||
|
@ -1888,4 +1911,6 @@ export const payload = {
|
|||
await (await request(payloadApiUrl(Collections.Audios, `id/${id}`))).json(),
|
||||
getVideoByID: async (id: string): Promise<EndpointVideo> =>
|
||||
await (await request(payloadApiUrl(Collections.Videos, `id/${id}`))).json(),
|
||||
getRecorderByID: async (id: string): Promise<EndpointRecorder> =>
|
||||
await (await request(payloadApiUrl(Collections.Recorders, `id/${id}`))).json(),
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue