Now using attributes instead of tag groups
This commit is contained in:
parent
600a2374e1
commit
0e148f06cf
|
@ -0,0 +1,87 @@
|
||||||
|
---
|
||||||
|
import { AttributeTypes, type EndpointAttribute } from "src/shared/payload/payload-sdk";
|
||||||
|
import Metadata from "./Metadata.astro";
|
||||||
|
import { getI18n } from "src/i18n/i18n";
|
||||||
|
import ErrorMessage from "./ErrorMessage.astro";
|
||||||
|
import type { Attribute } from "src/utils/attributes";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
attributes: (EndpointAttribute | Attribute)[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const { attributes } = Astro.props;
|
||||||
|
const { getLocalizedMatch, getLocalizedUrl, formatNumber } = await getI18n(
|
||||||
|
Astro.locals.currentLocale
|
||||||
|
);
|
||||||
|
---
|
||||||
|
|
||||||
|
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
attributes.map((attribute) => {
|
||||||
|
if ("title" in attribute) {
|
||||||
|
return <Metadata {...attribute} />;
|
||||||
|
}
|
||||||
|
const { icon, translations, value, type } = attribute;
|
||||||
|
const translation = getLocalizedMatch(translations);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case AttributeTypes.Number:
|
||||||
|
return (
|
||||||
|
<Metadata
|
||||||
|
icon={icon}
|
||||||
|
title={translation.name}
|
||||||
|
values={[{ name: formatNumber(value) }]}
|
||||||
|
withBorder={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case AttributeTypes.Text:
|
||||||
|
return (
|
||||||
|
<Metadata
|
||||||
|
icon={icon}
|
||||||
|
title={translation.name}
|
||||||
|
values={[{ name: value }]}
|
||||||
|
withBorder={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case AttributeTypes.Tags:
|
||||||
|
return (
|
||||||
|
<Metadata
|
||||||
|
icon={icon}
|
||||||
|
title={translation.name}
|
||||||
|
values={value.map(({ translations, page }) => ({
|
||||||
|
name: getLocalizedMatch(translations).name,
|
||||||
|
...(page ? { href: getLocalizedUrl(`/pages/${page.slug}`) } : {}),
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (
|
||||||
|
<ErrorMessage
|
||||||
|
title={`Unknown attribute type: ${type}`}
|
||||||
|
description="Please contact website technical administrator."
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2em;
|
||||||
|
|
||||||
|
@media (max-width: 35rem) {
|
||||||
|
gap: 3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,83 @@
|
||||||
|
---
|
||||||
|
import { AttributeTypes, type EndpointAttribute } from "src/shared/payload/payload-sdk";
|
||||||
|
import InlineMetadata from "./InlineMetadata.astro";
|
||||||
|
import { getI18n } from "src/i18n/i18n";
|
||||||
|
import ErrorMessage from "./ErrorMessage.astro";
|
||||||
|
import type { Attribute } from "src/utils/attributes";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
attributes: (EndpointAttribute | Attribute)[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const { attributes } = Astro.props;
|
||||||
|
const { getLocalizedMatch, getLocalizedUrl, formatNumber } = await getI18n(
|
||||||
|
Astro.locals.currentLocale
|
||||||
|
);
|
||||||
|
---
|
||||||
|
|
||||||
|
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
{
|
||||||
|
attributes.map((attribute) => {
|
||||||
|
if ("title" in attribute) {
|
||||||
|
return <InlineMetadata {...attribute} />;
|
||||||
|
}
|
||||||
|
const { icon, translations, value, type } = attribute;
|
||||||
|
const translation = getLocalizedMatch(translations);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case AttributeTypes.Number:
|
||||||
|
return (
|
||||||
|
<InlineMetadata
|
||||||
|
icon={icon}
|
||||||
|
title={translation.name}
|
||||||
|
values={[{ name: formatNumber(value) }]}
|
||||||
|
withBorder={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case AttributeTypes.Text:
|
||||||
|
return (
|
||||||
|
<InlineMetadata
|
||||||
|
icon={icon}
|
||||||
|
title={translation.name}
|
||||||
|
values={[{ name: value }]}
|
||||||
|
withBorder={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
case AttributeTypes.Tags:
|
||||||
|
return (
|
||||||
|
<InlineMetadata
|
||||||
|
icon={icon}
|
||||||
|
title={translation.name}
|
||||||
|
values={value.map(({ translations, page }) => ({
|
||||||
|
name: getLocalizedMatch(translations).name,
|
||||||
|
...(page ? { href: getLocalizedUrl(`/pages/${page.slug}`) } : {}),
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (
|
||||||
|
<ErrorMessage
|
||||||
|
title={`Unknown attribute type: ${type}`}
|
||||||
|
description="Please contact website technical administrator."
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#container {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5em 1.5em;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
import type { EndpointCredit } from "src/shared/payload/payload-sdk";
|
import type { EndpointCredit } from "src/shared/payload/payload-sdk";
|
||||||
import { getI18n } from "src/i18n/i18n";
|
import { getI18n } from "src/i18n/i18n";
|
||||||
|
import InlineMetadata from "./InlineMetadata.astro";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
credits: EndpointCredit[];
|
credits: EndpointCredit[];
|
||||||
|
@ -12,13 +13,14 @@ const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale);
|
||||||
|
|
||||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||||
|
|
||||||
<div id="credits">
|
<div>
|
||||||
{
|
{
|
||||||
credits.map(({ recorders, role: { translations } }) => (
|
credits.map(({ recorders, role: { icon, translations } }) => (
|
||||||
<div>
|
<InlineMetadata
|
||||||
<p>{getLocalizedMatch(translations).name}</p>
|
icon={icon}
|
||||||
{recorders.map(({ username }) => username).join(", ")}
|
title={getLocalizedMatch(translations).name}
|
||||||
</div>
|
values={recorders.map(({ username }) => ({ name: username }))}
|
||||||
|
/>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,21 +28,12 @@ const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale);
|
||||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#credits {
|
div {
|
||||||
margin-top: 0.5em;
|
display: grid;
|
||||||
display: flex;
|
gap: 2em;
|
||||||
flex-direction: column;
|
|
||||||
gap: 0.5em 1.5em;
|
|
||||||
|
|
||||||
& > div {
|
@media (max-width: 35rem) {
|
||||||
font-weight: 400;
|
gap: 3em;
|
||||||
font-size: 80%;
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5em;
|
|
||||||
|
|
||||||
& > p {
|
|
||||||
color: var(--color-base-750);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
import { Icon } from "astro-icon/components";
|
||||||
|
import type { Attribute } from "src/utils/attributes";
|
||||||
|
|
||||||
|
interface Props extends Attribute {}
|
||||||
|
|
||||||
|
const { icon, title, values } = Astro.props;
|
||||||
|
|
||||||
|
if (values.length === 0) return;
|
||||||
|
---
|
||||||
|
|
||||||
|
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
<Icon name={icon} />
|
||||||
|
<p>{title}</p>
|
||||||
|
<div>{values.map(({ name }) => name).join(", ")}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#container {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 80%;
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5em;
|
||||||
|
|
||||||
|
& > p {
|
||||||
|
color: var(--color-base-750);
|
||||||
|
}
|
||||||
|
|
||||||
|
& > svg {
|
||||||
|
color: var(--color-base-750);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,64 +0,0 @@
|
||||||
---
|
|
||||||
import { Icon } from "astro-icon/components";
|
|
||||||
import { getI18n } from "src/i18n/i18n";
|
|
||||||
import type { EndpointTagsGroup } from "src/shared/payload/payload-sdk";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
tagGroups: (EndpointTagsGroup | { title: string; icon: string; values: string[] })[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const { tagGroups } = Astro.props;
|
|
||||||
const { getLocalizedMatch } = await getI18n(Astro.locals.currentLocale);
|
|
||||||
|
|
||||||
const groups = tagGroups.map((group) => {
|
|
||||||
if ("title" in group) {
|
|
||||||
return group;
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
title: getLocalizedMatch(group.translations).name,
|
|
||||||
icon: group.icon,
|
|
||||||
values: group.tags.map(({ translations }) => getLocalizedMatch(translations).name),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
---
|
|
||||||
|
|
||||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
|
||||||
|
|
||||||
<div id="tags">
|
|
||||||
{
|
|
||||||
groups.map(({ icon, title, values }) => (
|
|
||||||
<div>
|
|
||||||
<Icon name={icon} />
|
|
||||||
<p>{title}</p>
|
|
||||||
<div>{values.join(", ")}</div>
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
|
||||||
|
|
||||||
<style>
|
|
||||||
#tags {
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5em 1.5em;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
|
|
||||||
& > div {
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 80%;
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5em;
|
|
||||||
|
|
||||||
& > p {
|
|
||||||
color: var(--color-base-750);
|
|
||||||
}
|
|
||||||
|
|
||||||
& > svg {
|
|
||||||
color: var(--color-base-750);
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -5,12 +5,12 @@ import {
|
||||||
type PayloadImage,
|
type PayloadImage,
|
||||||
type RichTextContent,
|
type RichTextContent,
|
||||||
} from "src/shared/payload/payload-sdk";
|
} from "src/shared/payload/payload-sdk";
|
||||||
import TagGroups from "./TagGroups.astro";
|
|
||||||
import Credits from "./Credits.astro";
|
import Credits from "./Credits.astro";
|
||||||
import DownloadButton from "./DownloadButton.astro";
|
import DownloadButton from "./DownloadButton.astro";
|
||||||
import AppLayoutTitle from "./AppLayout/components/AppLayoutTitle.astro";
|
import AppLayoutTitle from "./AppLayout/components/AppLayoutTitle.astro";
|
||||||
import type { ComponentProps } from "astro/types";
|
import type { ComponentProps } from "astro/types";
|
||||||
import AppLayoutDescription from "./AppLayout/components/AppLayoutDescription.astro";
|
import AppLayoutDescription from "./AppLayout/components/AppLayoutDescription.astro";
|
||||||
|
import Attributes from "./Attributes.astro";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
previousImageHref?: string | undefined;
|
previousImageHref?: string | undefined;
|
||||||
|
@ -20,7 +20,8 @@ interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
subtitle?: string | undefined;
|
subtitle?: string | undefined;
|
||||||
description?: RichTextContent | undefined;
|
description?: RichTextContent | undefined;
|
||||||
tagGroups?: ComponentProps<typeof TagGroups>["tagGroups"] | undefined;
|
attributes?: ComponentProps<typeof Attributes>["attributes"] | undefined;
|
||||||
|
metaAttributes?: ComponentProps<typeof Attributes>["attributes"] | undefined;
|
||||||
credits?: EndpointCredit[] | undefined;
|
credits?: EndpointCredit[] | undefined;
|
||||||
filename?: string | undefined;
|
filename?: string | undefined;
|
||||||
}
|
}
|
||||||
|
@ -29,8 +30,9 @@ const {
|
||||||
nextImageHref,
|
nextImageHref,
|
||||||
previousImageHref,
|
previousImageHref,
|
||||||
image: { url, width, height },
|
image: { url, width, height },
|
||||||
tagGroups = [],
|
attributes = [],
|
||||||
credits,
|
metaAttributes = [],
|
||||||
|
credits = [],
|
||||||
description,
|
description,
|
||||||
pretitle,
|
pretitle,
|
||||||
title,
|
title,
|
||||||
|
@ -63,7 +65,7 @@ const smallTitle = !subtitle && !pretitle;
|
||||||
id="info"
|
id="info"
|
||||||
class:list={{
|
class:list={{
|
||||||
complex:
|
complex:
|
||||||
(tagGroups && tagGroups.length > 0) || (credits && credits.length > 0) || description,
|
attributes.length > 0 || metaAttributes.length > 0 || credits.length > 0 || description,
|
||||||
}}>
|
}}>
|
||||||
<div>
|
<div>
|
||||||
{
|
{
|
||||||
|
@ -75,8 +77,9 @@ const smallTitle = !subtitle && !pretitle;
|
||||||
}
|
}
|
||||||
{description && <AppLayoutDescription description={description} />}
|
{description && <AppLayoutDescription description={description} />}
|
||||||
</div>
|
</div>
|
||||||
{tagGroups && tagGroups.length > 0 && <TagGroups tagGroups={tagGroups} />}
|
{attributes.length > 0 && <Attributes attributes={attributes} />}
|
||||||
{credits && credits.length > 0 && <Credits credits={credits} />}
|
{credits.length > 0 && <Credits credits={credits} />}
|
||||||
|
{metaAttributes.length > 0 && <Attributes attributes={metaAttributes} />}
|
||||||
{filename && <DownloadButton href={url} filename={filename} />}
|
{filename && <DownloadButton href={url} filename={filename} />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
---
|
---
|
||||||
import { Icon } from "astro-icon/components";
|
import { Icon } from "astro-icon/components";
|
||||||
|
import type { Attribute } from "src/utils/attributes";
|
||||||
|
|
||||||
interface Props {
|
interface Props extends Attribute {}
|
||||||
icon: string;
|
|
||||||
title: string;
|
|
||||||
values: { name: string; href?: string }[];
|
|
||||||
withBorder?: boolean | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { icon, title, values, withBorder = true } = Astro.props;
|
const { icon, title, values, withBorder = true } = Astro.props;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ const { getLocalizedMatch, getLocalizedUrl, t, formatDuration } = await getI18n(
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
audio: { id, translations, tagGroups, filename, thumbnail, duration },
|
audio: { id, translations, attributes, filename, thumbnail, duration },
|
||||||
} = Astro.props;
|
} = Astro.props;
|
||||||
|
|
||||||
const { pretitle, title, subtitle } =
|
const { pretitle, title, subtitle } =
|
||||||
|
@ -20,12 +20,12 @@ const { pretitle, title, subtitle } =
|
||||||
? getLocalizedMatch(translations)
|
? getLocalizedMatch(translations)
|
||||||
: { pretitle: undefined, title: filename, subtitle: undefined };
|
: { pretitle: undefined, title: filename, subtitle: undefined };
|
||||||
|
|
||||||
const tagsAndAttributes = [
|
const attributesWithMeta = [
|
||||||
...tagGroups,
|
...attributes,
|
||||||
{
|
{
|
||||||
title: t("global.media.attributes.duration"),
|
title: t("global.media.attributes.duration"),
|
||||||
icon: "material-symbols:hourglass-empty",
|
icon: "material-symbols:hourglass-empty",
|
||||||
values: [formatDuration(duration)],
|
values: [{ name: formatDuration(duration) }],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
---
|
---
|
||||||
|
@ -38,7 +38,7 @@ const tagsAndAttributes = [
|
||||||
subtitle={subtitle}
|
subtitle={subtitle}
|
||||||
thumbnail={thumbnail}
|
thumbnail={thumbnail}
|
||||||
href={getLocalizedUrl(`/audios/${id}`)}
|
href={getLocalizedUrl(`/audios/${id}`)}
|
||||||
tagGroups={tagsAndAttributes}
|
attributes={attributesWithMeta}
|
||||||
icon="material-symbols:music-note"
|
icon="material-symbols:music-note"
|
||||||
iconHoverLabel={t("global.previewTypes.audio")}
|
iconHoverLabel={t("global.previewTypes.audio")}
|
||||||
smallTitle={title === filename}
|
smallTitle={title === filename}
|
||||||
|
|
|
@ -10,7 +10,7 @@ interface Props {
|
||||||
const { getLocalizedMatch, getLocalizedUrl, t } = await getI18n(Astro.locals.currentLocale);
|
const { getLocalizedMatch, getLocalizedUrl, t } = await getI18n(Astro.locals.currentLocale);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
collectible: { slug, translations, thumbnail, tagGroups },
|
collectible: { slug, translations, thumbnail, attributes },
|
||||||
} = Astro.props;
|
} = Astro.props;
|
||||||
|
|
||||||
const { title, pretitle, subtitle } = getLocalizedMatch(translations);
|
const { title, pretitle, subtitle } = getLocalizedMatch(translations);
|
||||||
|
@ -24,7 +24,7 @@ const { title, pretitle, subtitle } = getLocalizedMatch(translations);
|
||||||
subtitle={subtitle}
|
subtitle={subtitle}
|
||||||
thumbnail={thumbnail}
|
thumbnail={thumbnail}
|
||||||
href={getLocalizedUrl(`/collectibles/${slug}`)}
|
href={getLocalizedUrl(`/collectibles/${slug}`)}
|
||||||
tagGroups={tagGroups}
|
attributes={attributes}
|
||||||
icon="material-symbols:category"
|
icon="material-symbols:category"
|
||||||
iconHoverLabel={t("global.previewTypes.collectible")}
|
iconHoverLabel={t("global.previewTypes.collectible")}
|
||||||
disableRoundedTop
|
disableRoundedTop
|
||||||
|
|
|
@ -4,7 +4,7 @@ import Card from "components/Card.astro";
|
||||||
import { Icon } from "astro-icon/components";
|
import { Icon } from "astro-icon/components";
|
||||||
import type { ComponentProps } from "astro/types";
|
import type { ComponentProps } from "astro/types";
|
||||||
import { getI18n } from "src/i18n/i18n";
|
import { getI18n } from "src/i18n/i18n";
|
||||||
import InlineTagGroups from "components/InlineTagGroups.astro";
|
import InlineAttributes from "components/InlineAttributes.astro";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
thumbnail?: PayloadImage | undefined;
|
thumbnail?: PayloadImage | undefined;
|
||||||
|
@ -12,7 +12,7 @@ interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
subtitle?: string | undefined;
|
subtitle?: string | undefined;
|
||||||
href?: string | undefined;
|
href?: string | undefined;
|
||||||
tagGroups?: ComponentProps<typeof InlineTagGroups>["tagGroups"];
|
attributes?: ComponentProps<typeof InlineAttributes>["attributes"];
|
||||||
disableRoundedTop?: boolean;
|
disableRoundedTop?: boolean;
|
||||||
smallTitle?: boolean;
|
smallTitle?: boolean;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
|
@ -27,7 +27,7 @@ const {
|
||||||
pretitle,
|
pretitle,
|
||||||
subtitle,
|
subtitle,
|
||||||
href,
|
href,
|
||||||
tagGroups = [],
|
attributes = [],
|
||||||
smallTitle = false,
|
smallTitle = false,
|
||||||
disableRoundedTop = false,
|
disableRoundedTop = false,
|
||||||
icon = "material-symbols:unknown-document",
|
icon = "material-symbols:unknown-document",
|
||||||
|
@ -63,11 +63,11 @@ const {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
tagGroups.length > 0 && (
|
attributes.length > 0 && (
|
||||||
<>
|
<>
|
||||||
{subtitle && <hr />}
|
{subtitle && <hr />}
|
||||||
<div id="tags">
|
<div id="tags">
|
||||||
<InlineTagGroups tagGroups={tagGroups} />
|
<InlineAttributes attributes={attributes} />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,7 @@ const { getLocalizedMatch, getLocalizedUrl, t } = await getI18n(Astro.locals.cur
|
||||||
|
|
||||||
const {
|
const {
|
||||||
image: thumbnail,
|
image: thumbnail,
|
||||||
image: { id, translations, tagGroups, filename },
|
image: { id, translations, attributes, filename },
|
||||||
} = Astro.props;
|
} = Astro.props;
|
||||||
|
|
||||||
const { pretitle, title, subtitle } =
|
const { pretitle, title, subtitle } =
|
||||||
|
@ -28,7 +28,7 @@ const { pretitle, title, subtitle } =
|
||||||
subtitle={subtitle}
|
subtitle={subtitle}
|
||||||
thumbnail={thumbnail}
|
thumbnail={thumbnail}
|
||||||
href={getLocalizedUrl(`/images/${id}`)}
|
href={getLocalizedUrl(`/images/${id}`)}
|
||||||
tagGroups={tagGroups}
|
attributes={attributes}
|
||||||
icon="material-symbols:imagesmode"
|
icon="material-symbols:imagesmode"
|
||||||
iconHoverLabel={t("global.previewTypes.image")}
|
iconHoverLabel={t("global.previewTypes.image")}
|
||||||
smallTitle={title === filename}
|
smallTitle={title === filename}
|
||||||
|
|
|
@ -10,7 +10,7 @@ interface Props {
|
||||||
const { getLocalizedMatch, getLocalizedUrl, t } = await getI18n(Astro.locals.currentLocale);
|
const { getLocalizedMatch, getLocalizedUrl, t } = await getI18n(Astro.locals.currentLocale);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
page: { slug, translations, thumbnail, tagGroups },
|
page: { slug, translations, thumbnail, attributes },
|
||||||
} = Astro.props;
|
} = Astro.props;
|
||||||
|
|
||||||
const { title, pretitle, subtitle } = getLocalizedMatch(translations);
|
const { title, pretitle, subtitle } = getLocalizedMatch(translations);
|
||||||
|
@ -24,7 +24,7 @@ const { title, pretitle, subtitle } = getLocalizedMatch(translations);
|
||||||
subtitle={subtitle}
|
subtitle={subtitle}
|
||||||
thumbnail={thumbnail}
|
thumbnail={thumbnail}
|
||||||
href={getLocalizedUrl(`/pages/${slug}`)}
|
href={getLocalizedUrl(`/pages/${slug}`)}
|
||||||
tagGroups={tagGroups}
|
attributes={attributes}
|
||||||
icon="material-symbols:docs"
|
icon="material-symbols:docs"
|
||||||
iconHoverLabel={t("global.previewTypes.page")}
|
iconHoverLabel={t("global.previewTypes.page")}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -12,7 +12,7 @@ const { getLocalizedMatch, getLocalizedUrl, t, formatDuration } = await getI18n(
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
video: { id, translations, tagGroups, filename, thumbnail, duration },
|
video: { id, translations, attributes, filename, thumbnail, duration },
|
||||||
} = Astro.props;
|
} = Astro.props;
|
||||||
|
|
||||||
const { pretitle, title, subtitle } =
|
const { pretitle, title, subtitle } =
|
||||||
|
@ -20,12 +20,12 @@ const { pretitle, title, subtitle } =
|
||||||
? getLocalizedMatch(translations)
|
? getLocalizedMatch(translations)
|
||||||
: { pretitle: undefined, title: filename, subtitle: undefined };
|
: { pretitle: undefined, title: filename, subtitle: undefined };
|
||||||
|
|
||||||
const tagsAndAttributes = [
|
const attributesWithMeta = [
|
||||||
...tagGroups,
|
...attributes,
|
||||||
{
|
{
|
||||||
title: t("global.media.attributes.duration"),
|
title: t("global.media.attributes.duration"),
|
||||||
icon: "material-symbols:hourglass-empty",
|
icon: "material-symbols:hourglass-empty",
|
||||||
values: [formatDuration(duration)],
|
values: [{ name: formatDuration(duration) }],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
---
|
---
|
||||||
|
@ -38,7 +38,7 @@ const tagsAndAttributes = [
|
||||||
subtitle={subtitle}
|
subtitle={subtitle}
|
||||||
thumbnail={thumbnail}
|
thumbnail={thumbnail}
|
||||||
href={getLocalizedUrl(`/videos/${id}`)}
|
href={getLocalizedUrl(`/videos/${id}`)}
|
||||||
tagGroups={tagsAndAttributes}
|
attributes={attributesWithMeta}
|
||||||
icon="material-symbols:smart-display"
|
icon="material-symbols:smart-display"
|
||||||
iconHoverLabel={t("global.previewTypes.video")}
|
iconHoverLabel={t("global.previewTypes.video")}
|
||||||
smallTitle={title === filename}
|
smallTitle={title === filename}
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
---
|
|
||||||
import type { EndpointTagsGroup } from "src/shared/payload/payload-sdk";
|
|
||||||
import { getI18n } from "src/i18n/i18n";
|
|
||||||
import Metadata from "./Metadata.astro";
|
|
||||||
import type { ComponentProps } from "astro/types";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
tagGroups: (EndpointTagsGroup | ComponentProps<typeof Metadata>)[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const { tagGroups } = Astro.props;
|
|
||||||
const { getLocalizedMatch, getLocalizedUrl } = await getI18n(Astro.locals.currentLocale);
|
|
||||||
|
|
||||||
const groups = tagGroups.map((group) => {
|
|
||||||
if ("title" in group) {
|
|
||||||
return group;
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
title: getLocalizedMatch(group.translations).name,
|
|
||||||
icon: group.icon,
|
|
||||||
values: group.tags.map(({ translations, page }) => ({
|
|
||||||
name: getLocalizedMatch(translations).name,
|
|
||||||
...(page ? { href: getLocalizedUrl(`/pages/${page.slug}`) } : {}),
|
|
||||||
})),
|
|
||||||
withBorder: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
---
|
|
||||||
|
|
||||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
|
||||||
|
|
||||||
<div>
|
|
||||||
{groups.map((group) => <Metadata {...group} />)}
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
|
||||||
|
|
||||||
<style>
|
|
||||||
div {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 2em;
|
|
||||||
|
|
||||||
@media (max-width: 35rem) {
|
|
||||||
gap: 3em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -3,13 +3,13 @@ import RichText from "components/RichText/RichText.astro";
|
||||||
import { payload, type EndpointPage } from "src/shared/payload/payload-sdk";
|
import { payload, type EndpointPage } from "src/shared/payload/payload-sdk";
|
||||||
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
||||||
import MasoTarget from "components/Maso/MasoTarget.astro";
|
import MasoTarget from "components/Maso/MasoTarget.astro";
|
||||||
import TagGroups from "components/TagGroups.astro";
|
|
||||||
import TableOfContent from "components/TableOfContent/TableOfContent.astro";
|
import TableOfContent from "components/TableOfContent/TableOfContent.astro";
|
||||||
import LanguageOverride from "components/LanguageOverride.astro";
|
import LanguageOverride from "components/LanguageOverride.astro";
|
||||||
import Credits from "components/Credits.astro";
|
import Credits from "components/Credits.astro";
|
||||||
import { getI18n } from "src/i18n/i18n";
|
import { getI18n } from "src/i18n/i18n";
|
||||||
import AsideLayout from "components/AppLayout/AsideLayout.astro";
|
import AsideLayout from "components/AppLayout/AsideLayout.astro";
|
||||||
import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro";
|
import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro";
|
||||||
|
import Attributes from "components/Attributes.astro";
|
||||||
|
|
||||||
export const partial = true;
|
export const partial = true;
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ interface Props {
|
||||||
const reqUrl = new URL(Astro.request.url);
|
const reqUrl = new URL(Astro.request.url);
|
||||||
const lang = Astro.props.lang ?? reqUrl.searchParams.get("lang")!;
|
const lang = Astro.props.lang ?? reqUrl.searchParams.get("lang")!;
|
||||||
const slug = Astro.props.slug ?? reqUrl.searchParams.get("slug")!;
|
const slug = Astro.props.slug ?? reqUrl.searchParams.get("slug")!;
|
||||||
const { translations, thumbnail, tagGroups, createdAt, updatedAt, updatedBy } =
|
const { translations, thumbnail, createdAt, updatedAt, updatedBy, attributes } =
|
||||||
Astro.props.page ?? (await payload.getPage(slug));
|
Astro.props.page ?? (await payload.getPage(slug));
|
||||||
|
|
||||||
const { getLocalizedUrl, t, formatDate } = await getI18n(Astro.locals.currentLocale);
|
const { getLocalizedUrl, t, formatDate } = await getI18n(Astro.locals.currentLocale);
|
||||||
|
@ -31,7 +31,7 @@ const { getLocalizedMatch } = await getI18n(lang);
|
||||||
const { pretitle, title, subtitle, summary, content, credits, toc, language, sourceLanguage } =
|
const { pretitle, title, subtitle, summary, content, credits, toc, language, sourceLanguage } =
|
||||||
getLocalizedMatch(translations);
|
getLocalizedMatch(translations);
|
||||||
|
|
||||||
const attributes = [
|
const metaAttributes = [
|
||||||
{
|
{
|
||||||
title: t("global.media.attributes.createdAt"),
|
title: t("global.media.attributes.createdAt"),
|
||||||
icon: "material-symbols:calendar-add-on-outline",
|
icon: "material-symbols:calendar-add-on-outline",
|
||||||
|
@ -47,7 +47,7 @@ const attributes = [
|
||||||
];
|
];
|
||||||
|
|
||||||
if (updatedBy) {
|
if (updatedBy) {
|
||||||
attributes.push({
|
metaAttributes.push({
|
||||||
title: t("global.media.attributes.updatedBy"),
|
title: t("global.media.attributes.updatedBy"),
|
||||||
icon: "material-symbols:person-edit-outline",
|
icon: "material-symbols:person-edit-outline",
|
||||||
values: [{ name: updatedBy.username }],
|
values: [{ name: updatedBy.username }],
|
||||||
|
@ -82,9 +82,9 @@ if (updatedBy) {
|
||||||
<Fragment slot="meta">
|
<Fragment slot="meta">
|
||||||
{summary && <AppLayoutDescription description={summary} />}
|
{summary && <AppLayoutDescription description={summary} />}
|
||||||
{
|
{
|
||||||
tagGroups.length > 0 && (
|
attributes.length > 0 && (
|
||||||
<div id="tags">
|
<div id="tags">
|
||||||
<TagGroups tagGroups={tagGroups} />
|
<Attributes attributes={attributes} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ if (updatedBy) {
|
||||||
{credits.length > 0 && <Credits credits={credits} />}
|
{credits.length > 0 && <Credits credits={credits} />}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{attributes.length > 0 && <TagGroups tagGroups={attributes} />}
|
{metaAttributes.length > 0 && <Attributes attributes={metaAttributes} />}
|
||||||
|
|
||||||
{toc.length > 0 && <TableOfContent toc={toc} />}
|
{toc.length > 0 && <TableOfContent toc={toc} />}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
---
|
---
|
||||||
import AppLayout from "components/AppLayout/AppLayout.astro";
|
import AppLayout from "components/AppLayout/AppLayout.astro";
|
||||||
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
||||||
|
import Attributes from "components/Attributes.astro";
|
||||||
import AudioPlayer from "components/AudioPlayer.astro";
|
import AudioPlayer from "components/AudioPlayer.astro";
|
||||||
import Credits from "components/Credits.astro";
|
import Credits from "components/Credits.astro";
|
||||||
import DownloadButton from "components/DownloadButton.astro";
|
import DownloadButton from "components/DownloadButton.astro";
|
||||||
import RichText from "components/RichText/RichText.astro";
|
import RichText from "components/RichText/RichText.astro";
|
||||||
import TagGroups from "components/TagGroups.astro";
|
|
||||||
import { getI18n } from "src/i18n/i18n";
|
import { getI18n } from "src/i18n/i18n";
|
||||||
import { payload } from "src/shared/payload/payload-sdk";
|
import { payload } from "src/shared/payload/payload-sdk";
|
||||||
import { formatInlineTitle, formatRichTextToString } from "src/utils/format";
|
import { formatInlineTitle, formatRichTextToString } from "src/utils/format";
|
||||||
|
@ -22,7 +22,7 @@ const { getLocalizedMatch, t, formatFilesize, formatDate } = await getI18n(
|
||||||
);
|
);
|
||||||
const {
|
const {
|
||||||
translations,
|
translations,
|
||||||
tagGroups,
|
attributes,
|
||||||
filename,
|
filename,
|
||||||
url,
|
url,
|
||||||
credits,
|
credits,
|
||||||
|
@ -36,7 +36,7 @@ const { pretitle, title, subtitle, description } = getLocalizedMatch(translation
|
||||||
|
|
||||||
const smallTitle = !subtitle && !pretitle;
|
const smallTitle = !subtitle && !pretitle;
|
||||||
|
|
||||||
const attributes = [
|
const metaAttributes = [
|
||||||
...(filename && title !== filename
|
...(filename && title !== filename
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
|
@ -89,9 +89,9 @@ const attributes = [
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
{description && <RichText content={description} />}
|
{description && <RichText content={description} />}
|
||||||
{tagGroups.length > 0 && <TagGroups tagGroups={tagGroups} />}
|
{attributes.length > 0 && <Attributes attributes={attributes} />}
|
||||||
{credits.length > 0 && <Credits credits={credits} />}
|
{credits.length > 0 && <Credits credits={credits} />}
|
||||||
{attributes.length > 0 && <TagGroups tagGroups={attributes} />}
|
{metaAttributes.length > 0 && <Attributes attributes={metaAttributes} />}
|
||||||
<DownloadButton href={url} filename={filename} />
|
<DownloadButton href={url} filename={filename} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,10 +4,10 @@ import RichText from "components/RichText/RichText.astro";
|
||||||
import { getI18n } from "src/i18n/i18n";
|
import { getI18n } from "src/i18n/i18n";
|
||||||
import { Collections, type EndpointCollectible } from "src/shared/payload/payload-sdk";
|
import { Collections, type EndpointCollectible } from "src/shared/payload/payload-sdk";
|
||||||
import { formatInlineTitle } from "src/utils/format";
|
import { formatInlineTitle } from "src/utils/format";
|
||||||
import InlineTagGroups from "../../../../../../components/InlineTagGroups.astro";
|
|
||||||
import Card from "components/Card.astro";
|
import Card from "components/Card.astro";
|
||||||
import AudioPlayer from "components/AudioPlayer.astro";
|
import AudioPlayer from "components/AudioPlayer.astro";
|
||||||
import VideoPlayer from "components/VideoPlayer.astro";
|
import VideoPlayer from "components/VideoPlayer.astro";
|
||||||
|
import InlineAttributes from "components/InlineAttributes.astro";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
content: EndpointCollectible["contents"][number];
|
content: EndpointCollectible["contents"][number];
|
||||||
|
@ -99,9 +99,9 @@ const href = (() => {
|
||||||
(content.relationTo === Collections.Pages ||
|
(content.relationTo === Collections.Pages ||
|
||||||
content.relationTo === Collections.Audios ||
|
content.relationTo === Collections.Audios ||
|
||||||
content.relationTo === Collections.Videos) &&
|
content.relationTo === Collections.Videos) &&
|
||||||
content.value.tagGroups.length > 0 && (
|
content.value.attributes.length > 0 && (
|
||||||
<div id="tags">
|
<div id="tags">
|
||||||
<InlineTagGroups tagGroups={content.value.tagGroups} />
|
<InlineAttributes attributes={content.value.attributes} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,15 +18,14 @@ if (galleryImage instanceof Response) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const { parentPages, previousIndex, nextIndex, image } = galleryImage;
|
const { parentPages, previousIndex, nextIndex, image } = galleryImage;
|
||||||
const { filename, translations, createdAt, updatedAt, credits, tagGroups } = image;
|
const { filename, translations, createdAt, updatedAt, credits, attributes } = image;
|
||||||
|
|
||||||
const { pretitle, title, subtitle, description } =
|
const { pretitle, title, subtitle, description } =
|
||||||
translations.length > 0
|
translations.length > 0
|
||||||
? getLocalizedMatch(translations)
|
? getLocalizedMatch(translations)
|
||||||
: { pretitle: undefined, title: filename, subtitle: undefined, description: undefined };
|
: { pretitle: undefined, title: filename, subtitle: undefined, description: undefined };
|
||||||
|
|
||||||
const tagsAndAttributes = [
|
const metaAttributes = [
|
||||||
...tagGroups,
|
|
||||||
...(filename && title !== filename
|
...(filename && title !== filename
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
|
@ -74,7 +73,8 @@ const tagsAndAttributes = [
|
||||||
: undefined}
|
: undefined}
|
||||||
description={description}
|
description={description}
|
||||||
filename={filename}
|
filename={filename}
|
||||||
tagGroups={tagsAndAttributes}
|
attributes={attributes}
|
||||||
|
metaAttributes={metaAttributes}
|
||||||
credits={credits}
|
credits={credits}
|
||||||
/>
|
/>
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
import AppLayout from "components/AppLayout/AppLayout.astro";
|
import AppLayout from "components/AppLayout/AppLayout.astro";
|
||||||
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
||||||
import TagGroups from "components/TagGroups.astro";
|
|
||||||
import { getI18n } from "src/i18n/i18n";
|
import { getI18n } from "src/i18n/i18n";
|
||||||
import { CollectibleNature, payload } from "src/shared/payload/payload-sdk";
|
import { CollectibleNature, payload } from "src/shared/payload/payload-sdk";
|
||||||
import { fetchOr404 } from "src/utils/responses";
|
import { fetchOr404 } from "src/utils/responses";
|
||||||
|
@ -16,6 +15,7 @@ import { formatInlineTitle, formatLocale, formatRichTextToString } from "src/uti
|
||||||
import AsideLayout from "components/AppLayout/AsideLayout.astro";
|
import AsideLayout from "components/AppLayout/AsideLayout.astro";
|
||||||
import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro";
|
import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro";
|
||||||
import { convert } from "src/utils/currencies";
|
import { convert } from "src/utils/currencies";
|
||||||
|
import Attributes from "components/Attributes.astro";
|
||||||
|
|
||||||
const { slug } = Astro.params;
|
const { slug } = Astro.params;
|
||||||
const { getLocalizedMatch, getLocalizedUrl, t, formatDate, formatPrice } = await getI18n(
|
const { getLocalizedMatch, getLocalizedUrl, t, formatDate, formatPrice } = await getI18n(
|
||||||
|
@ -41,7 +41,7 @@ const {
|
||||||
scans,
|
scans,
|
||||||
subitems,
|
subitems,
|
||||||
parentPages,
|
parentPages,
|
||||||
tagGroups,
|
attributes,
|
||||||
contents,
|
contents,
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
|
@ -53,7 +53,7 @@ const {
|
||||||
const translation = getLocalizedMatch(translations);
|
const translation = getLocalizedMatch(translations);
|
||||||
const { pretitle, title, subtitle, description } = translation;
|
const { pretitle, title, subtitle, description } = translation;
|
||||||
|
|
||||||
const attributes = [
|
const metaAttributes = [
|
||||||
{
|
{
|
||||||
title: t("global.media.attributes.createdAt"),
|
title: t("global.media.attributes.createdAt"),
|
||||||
icon: "material-symbols:calendar-add-on-outline",
|
icon: "material-symbols:calendar-add-on-outline",
|
||||||
|
@ -69,7 +69,7 @@ const attributes = [
|
||||||
];
|
];
|
||||||
|
|
||||||
if (updatedBy) {
|
if (updatedBy) {
|
||||||
attributes.push({
|
metaAttributes.push({
|
||||||
title: t("global.media.attributes.updatedBy"),
|
title: t("global.media.attributes.updatedBy"),
|
||||||
icon: "material-symbols:person-edit-outline",
|
icon: "material-symbols:person-edit-outline",
|
||||||
values: [{ name: updatedBy.username }],
|
values: [{ name: updatedBy.username }],
|
||||||
|
@ -77,8 +77,7 @@ if (updatedBy) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const tagGroupWithAttributes = [
|
const additionalAttributes = [
|
||||||
...tagGroups,
|
|
||||||
{
|
{
|
||||||
title: t("collectibles.nature"),
|
title: t("collectibles.nature"),
|
||||||
icon: "material-symbols:leaf-spark-outline",
|
icon: "material-symbols:leaf-spark-outline",
|
||||||
|
@ -96,7 +95,7 @@ const tagGroupWithAttributes = [
|
||||||
];
|
];
|
||||||
|
|
||||||
if (releaseDate) {
|
if (releaseDate) {
|
||||||
tagGroupWithAttributes.push({
|
additionalAttributes.push({
|
||||||
title: t("collectibles.releaseDate"),
|
title: t("collectibles.releaseDate"),
|
||||||
icon: "material-symbols:calendar-month-outline",
|
icon: "material-symbols:calendar-month-outline",
|
||||||
values: [{ name: formatDate(new Date(releaseDate)) }],
|
values: [{ name: formatDate(new Date(releaseDate)) }],
|
||||||
|
@ -105,7 +104,7 @@ if (releaseDate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (languages.length > 0) {
|
if (languages.length > 0) {
|
||||||
tagGroupWithAttributes.push({
|
additionalAttributes.push({
|
||||||
title: t("collectibles.languages"),
|
title: t("collectibles.languages"),
|
||||||
icon: "material-symbols:translate",
|
icon: "material-symbols:translate",
|
||||||
values: languages.map((lang) => ({ name: formatLocale(lang) })),
|
values: languages.map((lang) => ({ name: formatLocale(lang) })),
|
||||||
|
@ -127,7 +126,7 @@ if (price) {
|
||||||
priceText += ` (${formatPrice(convertedPrice)})`;
|
priceText += ` (${formatPrice(convertedPrice)})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
tagGroupWithAttributes.push({
|
additionalAttributes.push({
|
||||||
title: t("collectibles.price"),
|
title: t("collectibles.price"),
|
||||||
icon: "material-symbols:sell-outline",
|
icon: "material-symbols:sell-outline",
|
||||||
values: [{ name: priceText }],
|
values: [{ name: priceText }],
|
||||||
|
@ -194,9 +193,9 @@ if (price) {
|
||||||
|
|
||||||
<Fragment slot="aside">
|
<Fragment slot="aside">
|
||||||
{
|
{
|
||||||
attributes.length > 0 && (
|
metaAttributes.length > 0 && (
|
||||||
<div id="attributes">
|
<div id="attributes">
|
||||||
<TagGroups tagGroups={attributes} />
|
<Attributes attributes={metaAttributes} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -206,7 +205,7 @@ if (price) {
|
||||||
{description && <AppLayoutDescription description={description} />}
|
{description && <AppLayoutDescription description={description} />}
|
||||||
|
|
||||||
<div id="tags">
|
<div id="tags">
|
||||||
<TagGroups tagGroups={tagGroupWithAttributes}>
|
<Attributes attributes={[...attributes, ...additionalAttributes]}>
|
||||||
<AvailabilityInfo urls={urls} price={price !== undefined} releaseDate={releaseDate} />
|
<AvailabilityInfo urls={urls} price={price !== undefined} releaseDate={releaseDate} />
|
||||||
|
|
||||||
{size && <SizeInfo size={size} />}
|
{size && <SizeInfo size={size} />}
|
||||||
|
@ -214,7 +213,7 @@ if (price) {
|
||||||
{weight && <WeightInfo weight={weight} />}
|
{weight && <WeightInfo weight={weight} />}
|
||||||
|
|
||||||
{pageInfo && <PageInfo pageInfo={pageInfo} />}
|
{pageInfo && <PageInfo pageInfo={pageInfo} />}
|
||||||
</TagGroups>
|
</Attributes>
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|
||||||
|
|
|
@ -13,15 +13,14 @@ if (image instanceof Response) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const { getLocalizedMatch, formatDate, t } = await getI18n(Astro.locals.currentLocale);
|
const { getLocalizedMatch, formatDate, t } = await getI18n(Astro.locals.currentLocale);
|
||||||
const { filename, translations, tagGroups, credits, createdAt, updatedAt } = image;
|
const { filename, translations, attributes, credits, createdAt, updatedAt } = image;
|
||||||
|
|
||||||
const { pretitle, title, subtitle, description } =
|
const { pretitle, title, subtitle, description } =
|
||||||
translations.length > 0
|
translations.length > 0
|
||||||
? getLocalizedMatch(translations)
|
? getLocalizedMatch(translations)
|
||||||
: { pretitle: undefined, title: filename, subtitle: undefined, description: undefined };
|
: { pretitle: undefined, title: filename, subtitle: undefined, description: undefined };
|
||||||
|
|
||||||
const tagsAndAttributes = [
|
const metaAttributes = [
|
||||||
...tagGroups,
|
|
||||||
...(filename && title !== filename
|
...(filename && title !== filename
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
|
@ -62,7 +61,8 @@ const tagsAndAttributes = [
|
||||||
subtitle={subtitle}
|
subtitle={subtitle}
|
||||||
description={description}
|
description={description}
|
||||||
filename={filename}
|
filename={filename}
|
||||||
tagGroups={tagsAndAttributes}
|
attributes={attributes}
|
||||||
|
metaAttributes={metaAttributes}
|
||||||
credits={credits}
|
credits={credits}
|
||||||
/>
|
/>
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
---
|
---
|
||||||
import AppLayout from "components/AppLayout/AppLayout.astro";
|
import AppLayout from "components/AppLayout/AppLayout.astro";
|
||||||
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
||||||
|
import Attributes from "components/Attributes.astro";
|
||||||
import Credits from "components/Credits.astro";
|
import Credits from "components/Credits.astro";
|
||||||
import DownloadButton from "components/DownloadButton.astro";
|
import DownloadButton from "components/DownloadButton.astro";
|
||||||
import RichText from "components/RichText/RichText.astro";
|
import RichText from "components/RichText/RichText.astro";
|
||||||
import TagGroups from "components/TagGroups.astro";
|
|
||||||
import VideoPlayer from "components/VideoPlayer.astro";
|
import VideoPlayer from "components/VideoPlayer.astro";
|
||||||
import { getI18n } from "src/i18n/i18n";
|
import { getI18n } from "src/i18n/i18n";
|
||||||
import { payload } from "src/shared/payload/payload-sdk";
|
import { payload } from "src/shared/payload/payload-sdk";
|
||||||
|
@ -22,7 +22,7 @@ const { getLocalizedMatch, t, formatFilesize, formatDate } = await getI18n(
|
||||||
);
|
);
|
||||||
const {
|
const {
|
||||||
translations,
|
translations,
|
||||||
tagGroups,
|
attributes,
|
||||||
filename,
|
filename,
|
||||||
url,
|
url,
|
||||||
credits,
|
credits,
|
||||||
|
@ -35,7 +35,7 @@ const {
|
||||||
const { pretitle, title, subtitle, description } = getLocalizedMatch(translations);
|
const { pretitle, title, subtitle, description } = getLocalizedMatch(translations);
|
||||||
const smallTitle = !subtitle && !pretitle;
|
const smallTitle = !subtitle && !pretitle;
|
||||||
|
|
||||||
const attributes = [
|
const metaAttributes = [
|
||||||
...(filename && title !== filename
|
...(filename && title !== filename
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
|
@ -88,9 +88,9 @@ const attributes = [
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
{description && <RichText content={description} />}
|
{description && <RichText content={description} />}
|
||||||
{tagGroups.length > 0 && <TagGroups tagGroups={tagGroups} />}
|
{attributes.length > 0 && <Attributes attributes={attributes} />}
|
||||||
{credits.length > 0 && <Credits credits={credits} />}
|
{credits.length > 0 && <Credits credits={credits} />}
|
||||||
{attributes.length > 0 && <TagGroups tagGroups={attributes} />}
|
{metaAttributes.length > 0 && <Attributes attributes={metaAttributes} />}
|
||||||
<DownloadButton href={url} filename={filename} />
|
<DownloadButton href={url} filename={filename} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -32,7 +32,6 @@ export interface Config {
|
||||||
"videos-channels": VideosChannel;
|
"videos-channels": VideosChannel;
|
||||||
scans: Scan;
|
scans: Scan;
|
||||||
tags: Tag;
|
tags: Tag;
|
||||||
"tags-groups": TagsGroup;
|
|
||||||
attributes: Attribute;
|
attributes: Attribute;
|
||||||
"credits-roles": CreditsRole;
|
"credits-roles": CreditsRole;
|
||||||
recorders: Recorder;
|
recorders: Recorder;
|
||||||
|
@ -56,8 +55,8 @@ export interface Page {
|
||||||
slug: string;
|
slug: string;
|
||||||
thumbnail?: string | Image | null;
|
thumbnail?: string | Image | null;
|
||||||
backgroundImage?: string | Image | null;
|
backgroundImage?: string | Image | null;
|
||||||
attributes?: (TagsBlock | NumberBlock | TextBlock)[] | null;
|
|
||||||
tags?: (string | Tag)[] | null;
|
tags?: (string | Tag)[] | null;
|
||||||
|
attributes?: (TagsBlock | NumberBlock | TextBlock)[] | null;
|
||||||
translations: {
|
translations: {
|
||||||
language: string | Language;
|
language: string | Language;
|
||||||
sourceLanguage: string | Language;
|
sourceLanguage: string | Language;
|
||||||
|
@ -135,6 +134,7 @@ export interface Image {
|
||||||
}[]
|
}[]
|
||||||
| null;
|
| null;
|
||||||
tags?: (string | Tag)[] | null;
|
tags?: (string | Tag)[] | null;
|
||||||
|
attributes?: (TagsBlock | NumberBlock | TextBlock)[] | null;
|
||||||
credits?: Credits;
|
credits?: Credits;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
|
@ -177,26 +177,8 @@ export interface Language {
|
||||||
*/
|
*/
|
||||||
export interface Tag {
|
export interface Tag {
|
||||||
id: string;
|
id: string;
|
||||||
name?: string | null;
|
|
||||||
slug: string;
|
slug: string;
|
||||||
translations: {
|
|
||||||
language: string | Language;
|
|
||||||
name: string;
|
|
||||||
id?: string | null;
|
|
||||||
}[];
|
|
||||||
group: string | TagsGroup;
|
|
||||||
page?: (string | null) | Page;
|
page?: (string | null) | Page;
|
||||||
updatedAt: string;
|
|
||||||
createdAt: string;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
|
||||||
* via the `definition` "tags-groups".
|
|
||||||
*/
|
|
||||||
export interface TagsGroup {
|
|
||||||
id: string;
|
|
||||||
slug: string;
|
|
||||||
icon?: string | null;
|
|
||||||
translations: {
|
translations: {
|
||||||
language: string | Language;
|
language: string | Language;
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -205,42 +187,6 @@ export interface TagsGroup {
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
|
||||||
* via the `definition` "credits-roles".
|
|
||||||
*/
|
|
||||||
export interface CreditsRole {
|
|
||||||
id: string;
|
|
||||||
slug: string;
|
|
||||||
icon?: string | null;
|
|
||||||
translations: {
|
|
||||||
language: string | Language;
|
|
||||||
name: string;
|
|
||||||
id?: string | null;
|
|
||||||
}[];
|
|
||||||
updatedAt: string;
|
|
||||||
createdAt: string;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
|
||||||
* via the `definition` "recorders".
|
|
||||||
*/
|
|
||||||
export interface Recorder {
|
|
||||||
id: string;
|
|
||||||
username: string;
|
|
||||||
avatar?: string | Image | null;
|
|
||||||
languages?: (string | Language)[] | null;
|
|
||||||
role?: ("Admin" | "Recorder" | "Api")[] | null;
|
|
||||||
anonymize: boolean;
|
|
||||||
email: string;
|
|
||||||
resetPasswordToken?: string | null;
|
|
||||||
resetPasswordExpiration?: string | null;
|
|
||||||
salt?: string | null;
|
|
||||||
hash?: string | null;
|
|
||||||
loginAttempts?: number | null;
|
|
||||||
lockUntil?: string | null;
|
|
||||||
password?: string | null;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "TagsBlock".
|
* via the `definition` "TagsBlock".
|
||||||
|
@ -291,6 +237,42 @@ export interface TextBlock {
|
||||||
blockName?: string | null;
|
blockName?: string | null;
|
||||||
blockType: "textBlock";
|
blockType: "textBlock";
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "credits-roles".
|
||||||
|
*/
|
||||||
|
export interface CreditsRole {
|
||||||
|
id: string;
|
||||||
|
slug: string;
|
||||||
|
icon?: string | null;
|
||||||
|
translations: {
|
||||||
|
language: string | Language;
|
||||||
|
name: string;
|
||||||
|
id?: string | null;
|
||||||
|
}[];
|
||||||
|
updatedAt: string;
|
||||||
|
createdAt: string;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "recorders".
|
||||||
|
*/
|
||||||
|
export interface Recorder {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
avatar?: string | Image | null;
|
||||||
|
languages?: (string | Language)[] | null;
|
||||||
|
role?: ("Admin" | "Recorder" | "Api")[] | null;
|
||||||
|
anonymize: boolean;
|
||||||
|
email: string;
|
||||||
|
resetPasswordToken?: string | null;
|
||||||
|
resetPasswordExpiration?: string | null;
|
||||||
|
salt?: string | null;
|
||||||
|
hash?: string | null;
|
||||||
|
loginAttempts?: number | null;
|
||||||
|
lockUntil?: string | null;
|
||||||
|
password?: string | null;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "folders".
|
* via the `definition` "folders".
|
||||||
|
@ -371,6 +353,7 @@ export interface Collectible {
|
||||||
nature: "Physical" | "Digital";
|
nature: "Physical" | "Digital";
|
||||||
languages?: (string | Language)[] | null;
|
languages?: (string | Language)[] | null;
|
||||||
tags?: (string | Tag)[] | null;
|
tags?: (string | Tag)[] | null;
|
||||||
|
attributes?: (TagsBlock | NumberBlock | TextBlock)[] | null;
|
||||||
translations: {
|
translations: {
|
||||||
language: string | Language;
|
language: string | Language;
|
||||||
pretitle?: string | null;
|
pretitle?: string | null;
|
||||||
|
@ -635,6 +618,7 @@ export interface Audio {
|
||||||
id?: string | null;
|
id?: string | null;
|
||||||
}[];
|
}[];
|
||||||
tags?: (string | Tag)[] | null;
|
tags?: (string | Tag)[] | null;
|
||||||
|
attributes?: (TagsBlock | NumberBlock | TextBlock)[] | null;
|
||||||
credits?: Credits;
|
credits?: Credits;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
|
@ -710,6 +694,7 @@ export interface Video {
|
||||||
id?: string | null;
|
id?: string | null;
|
||||||
}[];
|
}[];
|
||||||
tags?: (string | Tag)[] | null;
|
tags?: (string | Tag)[] | null;
|
||||||
|
attributes?: (TagsBlock | NumberBlock | TextBlock)[] | null;
|
||||||
credits?: Credits;
|
credits?: Credits;
|
||||||
platformEnabled?: boolean | null;
|
platformEnabled?: boolean | null;
|
||||||
platform?: {
|
platform?: {
|
||||||
|
@ -1042,27 +1027,26 @@ export interface SectionBlock {
|
||||||
|
|
||||||
|
|
||||||
export enum Collections {
|
export enum Collections {
|
||||||
|
Attributes = "attributes",
|
||||||
Audios = "audios",
|
Audios = "audios",
|
||||||
ChronologyEvents = "chronology-events",
|
ChronologyEvents = "chronology-events",
|
||||||
|
Collectibles = "collectibles",
|
||||||
|
CreditsRole = "credits-roles",
|
||||||
Currencies = "currencies",
|
Currencies = "currencies",
|
||||||
|
Folders = "folders",
|
||||||
|
GenericContents = "generic-contents",
|
||||||
|
Images = "images",
|
||||||
Languages = "languages",
|
Languages = "languages",
|
||||||
|
MediaThumbnails = "media-thumbnails",
|
||||||
Pages = "pages",
|
Pages = "pages",
|
||||||
Recorders = "recorders",
|
Recorders = "recorders",
|
||||||
Folders = "folders",
|
|
||||||
Tags = "tags",
|
|
||||||
TagsGroups = "tags-groups",
|
|
||||||
Images = "images",
|
|
||||||
Wordings = "wordings",
|
|
||||||
Collectibles = "collectibles",
|
|
||||||
GenericContents = "generic-contents",
|
|
||||||
WebsiteConfig = "website-config",
|
|
||||||
Videos = "videos",
|
|
||||||
VideosSubtitles = "videos-subtitles",
|
|
||||||
VideosChannels = "videos-channels",
|
|
||||||
MediaThumbnails = "media-thumbnails",
|
|
||||||
Scans = "scans",
|
Scans = "scans",
|
||||||
CreditsRole = "credits-roles",
|
Tags = "tags",
|
||||||
Attributes = "attributes",
|
Videos = "videos",
|
||||||
|
VideosChannels = "videos-channels",
|
||||||
|
VideosSubtitles = "videos-subtitles",
|
||||||
|
Wordings = "wordings",
|
||||||
|
WebsiteConfig = "website-config",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum CollectionGroups {
|
export enum CollectionGroups {
|
||||||
|
@ -1507,16 +1491,6 @@ export type EndpointTag = {
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EndpointTagsGroup = {
|
|
||||||
slug: string;
|
|
||||||
icon: string;
|
|
||||||
translations: {
|
|
||||||
language: string;
|
|
||||||
name: string;
|
|
||||||
}[];
|
|
||||||
tags: EndpointTag[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type EndpointGenericAttribute = {
|
export type EndpointGenericAttribute = {
|
||||||
slug: string;
|
slug: string;
|
||||||
icon: string;
|
icon: string;
|
||||||
|
@ -1562,7 +1536,6 @@ export type EndpointCredit = {
|
||||||
export type EndpointPage = {
|
export type EndpointPage = {
|
||||||
slug: string;
|
slug: string;
|
||||||
thumbnail?: EndpointImage;
|
thumbnail?: EndpointImage;
|
||||||
tagGroups: EndpointTagsGroup[];
|
|
||||||
attributes: EndpointAttribute[];
|
attributes: EndpointAttribute[];
|
||||||
backgroundImage?: EndpointImage;
|
backgroundImage?: EndpointImage;
|
||||||
translations: {
|
translations: {
|
||||||
|
@ -1592,7 +1565,7 @@ export type EndpointCollectible = {
|
||||||
subtitle?: string;
|
subtitle?: string;
|
||||||
description?: RichTextContent;
|
description?: RichTextContent;
|
||||||
}[];
|
}[];
|
||||||
tagGroups: EndpointTagsGroup[];
|
attributes: EndpointAttribute[];
|
||||||
releaseDate?: string;
|
releaseDate?: string;
|
||||||
languages: string[];
|
languages: string[];
|
||||||
backgroundImage?: EndpointImage;
|
backgroundImage?: EndpointImage;
|
||||||
|
@ -1816,7 +1789,7 @@ export type EndpointMedia = {
|
||||||
filesize: number;
|
filesize: number;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
tagGroups: EndpointTagsGroup[];
|
attributes: EndpointAttribute[];
|
||||||
translations: {
|
translations: {
|
||||||
language: string;
|
language: string;
|
||||||
pretitle?: string;
|
pretitle?: string;
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
export type Attribute = {
|
||||||
|
icon: string;
|
||||||
|
title: string;
|
||||||
|
values: { name: string; href?: string }[];
|
||||||
|
withBorder?: boolean | undefined;
|
||||||
|
};
|
Loading…
Reference in New Issue