Simplified layouts
This commit is contained in:
parent
030f0a1f34
commit
3347fb6b7c
1
TODO.md
1
TODO.md
|
@ -7,7 +7,6 @@
|
|||
- Create a tool to upload scans images and apply them to collectible
|
||||
- Automatically generate different sizes of images
|
||||
- Handle relationship in RichText Content
|
||||
- On most pages (collectibles + pages), there is a gap in the breakpoints where no thumbnail is displayed.
|
||||
- Add proper localization for formatFilesize, formatInches, formatMillimeters, formatPounds, and formatGrams
|
||||
|
||||
## Mid term
|
||||
|
|
|
@ -2,18 +2,25 @@
|
|||
import Html from "./components/Html.astro";
|
||||
import Topbar from "./components/Topbar/Topbar.astro";
|
||||
import Footer from "./components/Footer.astro";
|
||||
import type { EndpointSource, PayloadImage } from "src/shared/payload/payload-sdk";
|
||||
import type { EndpointSource } from "src/shared/payload/payload-sdk";
|
||||
import AppLayoutBackgroundImg from "./components/AppLayoutBackgroundImg.astro";
|
||||
import type { ComponentProps } from "astro/types";
|
||||
|
||||
interface Props {
|
||||
openGraph?: ComponentProps<typeof Html>["openGraph"];
|
||||
parentPages?: EndpointSource[];
|
||||
backgroundImage?: ComponentProps<typeof AppLayoutBackgroundImg>["img"] | undefined;
|
||||
hideFooterLinks?: boolean;
|
||||
backgroundImage?: PayloadImage | undefined;
|
||||
hideHomeButton?: boolean;
|
||||
}
|
||||
|
||||
const { openGraph, hideFooterLinks = false, parentPages, backgroundImage } = Astro.props;
|
||||
const {
|
||||
openGraph,
|
||||
parentPages,
|
||||
backgroundImage,
|
||||
hideFooterLinks = false,
|
||||
hideHomeButton = false,
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
@ -21,7 +28,7 @@ const { openGraph, hideFooterLinks = false, parentPages, backgroundImage } = Ast
|
|||
<Html openGraph={openGraph}>
|
||||
<header>
|
||||
{backgroundImage && <AppLayoutBackgroundImg img={backgroundImage} />}
|
||||
<Topbar parentPages={parentPages} />
|
||||
<Topbar parentPages={parentPages} hideHomeButton={hideHomeButton} />
|
||||
</header>
|
||||
<main><slot /></main>
|
||||
<Footer withLinks={!hideFooterLinks} />
|
||||
|
@ -37,7 +44,7 @@ const { openGraph, hideFooterLinks = false, parentPages, backgroundImage } = Ast
|
|||
}
|
||||
|
||||
main {
|
||||
padding-top: 1em;
|
||||
padding-top: 1.5em;
|
||||
padding-bottom: 8em;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
---
|
||||
import Html from "./components/Html.astro";
|
||||
import AppLayoutBackgroundImg from "./components/AppLayoutBackgroundImg.astro";
|
||||
import Topbar from "./components/Topbar/Topbar.astro";
|
||||
import Footer from "./components/Footer.astro";
|
||||
import AppLayoutTitle from "./components/AppLayoutTitle.astro";
|
||||
import type { ComponentProps } from "astro/types";
|
||||
|
||||
interface Props {
|
||||
openGraph?: ComponentProps<typeof Html>["openGraph"];
|
||||
parentPages?: ComponentProps<typeof Topbar>["parentPages"];
|
||||
pretitle?: string | undefined;
|
||||
title?: string;
|
||||
subtitle?: string | undefined;
|
||||
description?: string | undefined;
|
||||
illustration?: string;
|
||||
illustrationSize?: string;
|
||||
illustrationPosition?: string;
|
||||
backgroundImage?: ComponentProps<typeof AppLayoutBackgroundImg>["img"] | undefined;
|
||||
hideFooterLinks?: boolean;
|
||||
hideHomeButton?: boolean;
|
||||
}
|
||||
|
||||
const {
|
||||
openGraph,
|
||||
title,
|
||||
subtitle,
|
||||
pretitle,
|
||||
description,
|
||||
illustration,
|
||||
backgroundImage,
|
||||
parentPages,
|
||||
illustrationSize = "contain",
|
||||
illustrationPosition = "center",
|
||||
hideFooterLinks = false,
|
||||
hideHomeButton = false,
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<Html openGraph={openGraph}>
|
||||
<header>
|
||||
{backgroundImage && <AppLayoutBackgroundImg img={backgroundImage} />}
|
||||
|
||||
<Topbar parentPages={parentPages} hideHomeButton={hideHomeButton} />
|
||||
{
|
||||
(
|
||||
<div id="header-content">
|
||||
<div id="header-left">
|
||||
<slot name="header-title">
|
||||
{title && <AppLayoutTitle pretitle={pretitle} title={title} subtitle={subtitle} />}
|
||||
</slot>
|
||||
|
||||
<div class="prose">
|
||||
<slot name="header-description">
|
||||
<p>{description}</p>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
{illustration && <div id="image-container" />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</header>
|
||||
<main><slot /></main>
|
||||
<Footer withLinks={!hideFooterLinks} />
|
||||
</Html>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
{/* TODO: Not use CSS image if possible */}
|
||||
<style
|
||||
define:vars={{
|
||||
illustration: illustration ? `url(${illustration})` : "unset",
|
||||
illustrationSize,
|
||||
illustrationPosition,
|
||||
}}
|
||||
>
|
||||
header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5em;
|
||||
|
||||
& > #header-content {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
|
||||
& > #header-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2em;
|
||||
place-items: flex-start;
|
||||
}
|
||||
|
||||
& > #image-container {
|
||||
background-image: var(--illustration);
|
||||
background-size: var(--illustrationSize);
|
||||
background-repeat: no-repeat;
|
||||
background-position: right var(--illustrationPosition);
|
||||
mask-image: linear-gradient(to left, rgba(0, 0, 0, 1) 50%, transparent 80%);
|
||||
|
||||
@media (max-width: 60rem) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
padding-top: 6em;
|
||||
padding-bottom: 8em;
|
||||
flex-grow: 1;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,65 @@
|
|||
---
|
||||
/*
|
||||
|
||||
On larger screens (>= 1280)
|
||||
|
||||
header header-aside
|
||||
meta aside
|
||||
default slot
|
||||
|
||||
|
||||
On smaller screens (<= 1280)
|
||||
|
||||
header
|
||||
header-aside
|
||||
meta
|
||||
aside
|
||||
default slot
|
||||
|
||||
*/
|
||||
---
|
||||
|
||||
<div id="layout">
|
||||
<div id="left">
|
||||
<slot name="header" />
|
||||
<div class="when-not-large">
|
||||
<slot name="header-aside" />
|
||||
<slot name="meta" />
|
||||
<slot name="aside" />
|
||||
</div>
|
||||
<div class="when-large">
|
||||
<slot name="meta" />
|
||||
</div>
|
||||
<slot />
|
||||
</div>
|
||||
<div id="right" class="when-large">
|
||||
<slot name="header-aside" />
|
||||
<slot name="aside" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
#layout {
|
||||
container-type: inline-size;
|
||||
|
||||
@media (min-width: 1280.5px) {
|
||||
display: grid;
|
||||
justify-content: space-between;
|
||||
grid-template-columns: 35rem 35rem;
|
||||
}
|
||||
}
|
||||
|
||||
.when-large {
|
||||
@media (max-width: 1280.5px) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.when-not-large {
|
||||
@media (min-width: 1280.5px) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
import RichText from "components/RichText/RichText.astro";
|
||||
import type { RichTextContent } from "src/shared/payload/payload-sdk";
|
||||
|
||||
interface Props {
|
||||
description: RichTextContent | string;
|
||||
}
|
||||
|
||||
const { description } = Astro.props;
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<div class="high-contrast-text">
|
||||
{
|
||||
typeof description === "string" ? (
|
||||
<p class="prose" set:html={description} />
|
||||
) : (
|
||||
<RichText content={description} />
|
||||
)
|
||||
}
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
div {
|
||||
backdrop-filter: blur(5px);
|
||||
padding: 1.5em;
|
||||
margin: -1.5em;
|
||||
margin-block: 0.5em;
|
||||
border-radius: 3em;
|
||||
width: fit-content;
|
||||
}
|
||||
</style>
|
|
@ -24,7 +24,7 @@ const { t, getLocalizedUrl } = await getI18n(Astro.locals.currentLocale);
|
|||
{
|
||||
(!hideHomeButton || parentPages.length > 0) && (
|
||||
<div id="left" class="hide-scrollbar high-contrast-text">
|
||||
<a href="/" class="pressable-label">
|
||||
<a href={getLocalizedUrl("/")} class="pressable-label">
|
||||
<Icon name="material-symbols:home" width={16} height={16} />
|
||||
<p>{t("home.title")}</p>
|
||||
</a>
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
---
|
||||
import AppLayout from "components/AppLayout/AppLayout.astro";
|
||||
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
|
||||
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<AppLayout title="Oh nyo..." />
|
||||
<AppEmptyLayout>
|
||||
<AppLayoutTitle title="Oh nyo..." />
|
||||
</AppEmptyLayout>
|
||||
|
|
|
@ -8,6 +8,8 @@ import TableOfContent from "components/TableOfContent/TableOfContent.astro";
|
|||
import LanguageOverride from "components/LanguageOverride.astro";
|
||||
import Credits from "components/Credits.astro";
|
||||
import { getI18n } from "src/i18n/i18n";
|
||||
import AsideLayout from "components/AppLayout/AsideLayout.astro";
|
||||
import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro";
|
||||
|
||||
export const partial = true;
|
||||
|
||||
|
@ -31,20 +33,21 @@ const translation = getLocalizedMatch(page.translations);
|
|||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<MasoTarget>
|
||||
<div id="layout">
|
||||
<div id="left">
|
||||
<AsideLayout>
|
||||
<Fragment slot="header">
|
||||
<AppLayoutTitle
|
||||
title={translation.title}
|
||||
pretitle={translation.pretitle}
|
||||
subtitle={translation.subtitle}
|
||||
/>
|
||||
</Fragment>
|
||||
|
||||
<Fragment slot="header-aside">
|
||||
{
|
||||
page.thumbnail && (
|
||||
<a href={getLocalizedUrl(`/images/${page.thumbnail.id}`)}>
|
||||
<img
|
||||
id="thumbnail"
|
||||
class="when-not-large"
|
||||
src={page.thumbnail.url}
|
||||
width={page.thumbnail.width}
|
||||
height={page.thumbnail.height}
|
||||
|
@ -52,147 +55,66 @@ const translation = getLocalizedMatch(page.translations);
|
|||
</a>
|
||||
)
|
||||
}
|
||||
</Fragment>
|
||||
|
||||
{
|
||||
translation.summary && (
|
||||
<div id="summary" class="high-contrast-text">
|
||||
<RichText content={translation.summary} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<Fragment slot="meta">
|
||||
{translation.summary && <AppLayoutDescription description={translation.summary} />}
|
||||
{page.tagGroups.length > 0 && <TagGroups tagGroups={page.tagGroups} />}
|
||||
</Fragment>
|
||||
|
||||
<div class="when-not-large meta-container">
|
||||
{
|
||||
page.translations.length > 1 && (
|
||||
<LanguageOverride
|
||||
currentLang={lang}
|
||||
availableLanguages={page.translations.map(({ language }) => language)}
|
||||
getPartialUrl={(lang) =>
|
||||
getLocalizedUrl(`/api/pages/partial?lang=${lang}&slug=${slug}`)
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{translation.credits.length > 0 && <Credits credits={translation.credits} />}
|
||||
</div>
|
||||
|
||||
<Fragment slot="aside">
|
||||
{
|
||||
translation.toc.length > 0 && (
|
||||
<div class="when-not-large meta-container">
|
||||
<TableOfContent toc={translation.toc} />
|
||||
</div>
|
||||
page.translations.length > 1 && (
|
||||
<LanguageOverride
|
||||
currentLang={lang}
|
||||
availableLanguages={page.translations.map(({ language }) => language)}
|
||||
getPartialUrl={(lang) =>
|
||||
getLocalizedUrl(`/api/pages/partial?lang=${lang}&slug=${slug}`)
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
<hr />
|
||||
<div id="text">
|
||||
<RichText content={translation.content} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="right" class="when-large">
|
||||
{
|
||||
page.thumbnail && (
|
||||
<a href={getLocalizedUrl(`/images/${page.thumbnail.id}`)}>
|
||||
<img
|
||||
id="thumbnail"
|
||||
src={page.thumbnail.url}
|
||||
width={page.thumbnail.width}
|
||||
height={page.thumbnail.height}
|
||||
/>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
<div class="meta-container">
|
||||
{
|
||||
page.translations.length > 1 && (
|
||||
<LanguageOverride
|
||||
currentLang={lang}
|
||||
availableLanguages={page.translations.map(({ language }) => language)}
|
||||
getPartialUrl={(lang) =>
|
||||
getLocalizedUrl(`/api/pages/partial?lang=${lang}&slug=${slug}`)
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{translation.credits.length > 0 && <Credits credits={translation.credits} />}
|
||||
</div>
|
||||
{translation.credits.length > 0 && <Credits credits={translation.credits} />}
|
||||
|
||||
{translation.toc.length > 0 && <TableOfContent toc={translation.toc} />}
|
||||
</Fragment>
|
||||
|
||||
<hr />
|
||||
<div id="text">
|
||||
<RichText content={translation.content} />
|
||||
</div>
|
||||
</div>
|
||||
</AsideLayout>
|
||||
</MasoTarget>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
#layout {
|
||||
display: grid;
|
||||
justify-content: space-between;
|
||||
container-type: inline-size;
|
||||
|
||||
@media (min-width: 80rem) {
|
||||
grid-template-columns: 35rem 35rem;
|
||||
}
|
||||
|
||||
& > #left {
|
||||
& > a > #thumbnail {
|
||||
max-width: 35rem;
|
||||
margin-block: 2em;
|
||||
}
|
||||
|
||||
& > #summary {
|
||||
backdrop-filter: blur(5px);
|
||||
padding: 1.5em;
|
||||
margin: -1.5em;
|
||||
margin-block: 1em;
|
||||
border-radius: 3em;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 3px dotted var(--color-base-500);
|
||||
margin-block: 3em;
|
||||
}
|
||||
}
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 3px dotted var(--color-base-500);
|
||||
margin-block: 3em;
|
||||
}
|
||||
|
||||
#thumbnail {
|
||||
max-width: 35rem;
|
||||
max-height: 60vh;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 5px 20px -10px var(--color-shadow);
|
||||
transition: 100ms scale;
|
||||
|
||||
@media (max-width: 1280.5px) {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
@media (min-width: 1280.5px) {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
scale: 102%;
|
||||
}
|
||||
}
|
||||
|
||||
.meta-container {
|
||||
@media (max-width: 35rem) {
|
||||
margin-block: 5em;
|
||||
gap: 2em;
|
||||
}
|
||||
|
||||
margin-block: 2em;
|
||||
display: grid;
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
.when-large {
|
||||
@media (max-width: 80rem) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.when-not-large {
|
||||
@media (min-width: 80rem) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
|
||||
import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro";
|
||||
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
||||
import RichText from "components/RichText/RichText.astro";
|
||||
import { getI18n } from "src/i18n/i18n";
|
||||
import { payload } from "src/shared/payload/payload-sdk";
|
||||
import { formatInlineTitle, formatRichTextToString } from "src/utils/format";
|
||||
|
@ -34,13 +34,7 @@ const translation = getLocalizedMatch(translations);
|
|||
subtitle={translation.subtitle}
|
||||
/>
|
||||
|
||||
{
|
||||
translation.description && (
|
||||
<div id="summary" class="high-contrast-text">
|
||||
<RichText content={translation.description} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{translation.description && <AppLayoutDescription description={translation.description} />}
|
||||
|
||||
<div>
|
||||
{
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
---
|
||||
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
|
||||
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
||||
import RichText from "components/RichText/RichText.astro";
|
||||
import TagGroups from "components/TagGroups.astro";
|
||||
import { getI18n } from "src/i18n/i18n";
|
||||
import { payload } from "src/shared/payload/payload-sdk";
|
||||
|
@ -16,6 +15,8 @@ import WeightInfo from "./_components/WeightInfo.astro";
|
|||
import SubitemSection from "./_components/SubitemSection.astro";
|
||||
import ContentsSection from "./_components/ContentsSection/ContentsSection.astro";
|
||||
import { formatInlineTitle, formatRichTextToString } from "src/utils/format";
|
||||
import AsideLayout from "components/AppLayout/AsideLayout.astro";
|
||||
import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro";
|
||||
|
||||
const { slug } = Astro.params;
|
||||
const { getLocalizedMatch, getLocalizedUrl, t } = await getI18n(Astro.locals.currentLocale);
|
||||
|
@ -56,82 +57,30 @@ const translation = getLocalizedMatch(translations);
|
|||
}}
|
||||
parentPages={parentPages}
|
||||
backgroundImage={backgroundImage ?? thumbnail}>
|
||||
<div id="layout">
|
||||
<div id="left">
|
||||
<AsideLayout>
|
||||
<Fragment slot="header">
|
||||
<AppLayoutTitle
|
||||
title={translation.title}
|
||||
pretitle={translation.pretitle}
|
||||
subtitle={translation.subtitle}
|
||||
/>
|
||||
</Fragment>
|
||||
|
||||
<div id="images" class="when-not-large">
|
||||
{
|
||||
thumbnail && (
|
||||
<a href={getLocalizedUrl(`/images/${thumbnail.id}`)}>
|
||||
<img
|
||||
id="thumbnail"
|
||||
src={thumbnail.url}
|
||||
width={thumbnail.width}
|
||||
height={thumbnail.height}
|
||||
/>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
<div id="gallery-scans" class="when-no-print">
|
||||
{
|
||||
gallery && (
|
||||
<ImageTile
|
||||
image={gallery.thumbnail.url}
|
||||
title={t("collectibles.gallery.title")}
|
||||
subtitle={t("collectibles.gallery.subtitle", { count: gallery.count })}
|
||||
href={getLocalizedUrl(`/collectibles/${slug}/gallery`)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
scans && (
|
||||
<ImageTile
|
||||
image={scans.thumbnail.url}
|
||||
title={t("collectibles.scans.title")}
|
||||
subtitle={t("collectibles.scans.subtitle", { count: scans.count })}
|
||||
href={getLocalizedUrl(`/collectibles/${slug}/scans`)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{
|
||||
translation.description && (
|
||||
<div id="summary" class="high-contrast-text">
|
||||
<RichText content={translation.description} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<TagGroups tagGroups={tagGroups}>
|
||||
{releaseDate && <ReleaseDateInfo releaseDate={releaseDate} />}
|
||||
|
||||
{price && <PriceInfo price={price} />}
|
||||
|
||||
<AvailabilityInfo urls={urls} price={price !== undefined} releaseDate={releaseDate} />
|
||||
|
||||
{size && <SizeInfo size={size} />}
|
||||
|
||||
{weight && <WeightInfo weight={weight} />}
|
||||
|
||||
{pageInfo && <PageInfo pageInfo={pageInfo} />}
|
||||
</TagGroups>
|
||||
|
||||
{subitems.length > 0 && <SubitemSection subitems={subitems} />}
|
||||
|
||||
{contents.length > 0 && <ContentsSection contents={contents} />}
|
||||
</div>
|
||||
|
||||
<div id="right" class="when-large">
|
||||
<Fragment slot="header-aside">
|
||||
<div id="images">
|
||||
{
|
||||
thumbnail && (
|
||||
<a href={getLocalizedUrl(`/images/${thumbnail.id}`)}>
|
||||
<img
|
||||
id="thumbnail"
|
||||
src={thumbnail.url}
|
||||
width={thumbnail.width}
|
||||
height={thumbnail.height}
|
||||
/>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
<div id="gallery-scans" class="when-no-print">
|
||||
{
|
||||
gallery && (
|
||||
|
@ -155,129 +104,95 @@ const translation = getLocalizedMatch(translations);
|
|||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
{
|
||||
thumbnail && (
|
||||
<a href={getLocalizedUrl(`/images/${thumbnail.id}`)}>
|
||||
<img
|
||||
id="thumbnail"
|
||||
src={thumbnail.url}
|
||||
width={thumbnail.width}
|
||||
height={thumbnail.height}
|
||||
/>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
|
||||
{translation.description && <AppLayoutDescription description={translation.description} />}
|
||||
|
||||
<TagGroups tagGroups={tagGroups}>
|
||||
{releaseDate && <ReleaseDateInfo releaseDate={releaseDate} />}
|
||||
|
||||
{price && <PriceInfo price={price} />}
|
||||
|
||||
<AvailabilityInfo urls={urls} price={price !== undefined} releaseDate={releaseDate} />
|
||||
|
||||
{size && <SizeInfo size={size} />}
|
||||
|
||||
{weight && <WeightInfo weight={weight} />}
|
||||
|
||||
{pageInfo && <PageInfo pageInfo={pageInfo} />}
|
||||
</TagGroups>
|
||||
|
||||
{subitems.length > 0 && <SubitemSection subitems={subitems} />}
|
||||
|
||||
{contents.length > 0 && <ContentsSection contents={contents} />}
|
||||
</AsideLayout>
|
||||
</AppEmptyLayout>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
#layout {
|
||||
#images {
|
||||
display: grid;
|
||||
justify-content: space-between;
|
||||
container-type: inline-size;
|
||||
place-content: start;
|
||||
place-items: start;
|
||||
margin-block: 2em;
|
||||
gap: clamp(1em, 0.5em + 3vw, 2em);
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
@media (min-width: 80rem) {
|
||||
grid-template-columns: 35rem 35rem;
|
||||
@media (max-width: 23rem) {
|
||||
gap: 2.5em;
|
||||
}
|
||||
|
||||
& > #left {
|
||||
& > #images {
|
||||
display: grid;
|
||||
place-content: start;
|
||||
place-items: start;
|
||||
margin-block: 2em;
|
||||
gap: clamp(1em, 0.5em + 3vw, 2em);
|
||||
grid-template-columns: 1fr;
|
||||
@media (min-width: 52rem) {
|
||||
grid-template-columns: 35rem 10rem;
|
||||
}
|
||||
|
||||
@media (max-width: 23rem) {
|
||||
gap: 2.5em;
|
||||
@media (min-width: 1280.5px) {
|
||||
grid-template-columns: 10rem 1fr;
|
||||
margin-block: initial;
|
||||
|
||||
& > #gallery-scans {
|
||||
order: -1;
|
||||
}
|
||||
}
|
||||
|
||||
& a > #thumbnail {
|
||||
max-width: 35rem;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
box-shadow: 0 5px 20px -10px var(--color-shadow);
|
||||
transition: 100ms scale;
|
||||
|
||||
&:hover {
|
||||
scale: 102%;
|
||||
}
|
||||
}
|
||||
|
||||
& > #gallery-scans {
|
||||
display: flex;
|
||||
max-width: 35rem;
|
||||
flex-direction: column;
|
||||
gap: 2.5em;
|
||||
width: 100%;
|
||||
|
||||
> :global(a) {
|
||||
aspect-ratio: 2 / 1;
|
||||
}
|
||||
|
||||
@media (min-width: 23rem) {
|
||||
gap: clamp(1em, 0.5em + 3vw, 2em);
|
||||
flex-direction: row;
|
||||
|
||||
> :global(a) {
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
@media (min-width: 52rem) {
|
||||
grid-template-columns: 35rem 10rem;
|
||||
}
|
||||
|
||||
& > #thumbnail {
|
||||
max-width: 35rem;
|
||||
}
|
||||
|
||||
& > #gallery-scans {
|
||||
display: flex;
|
||||
max-width: 35rem;
|
||||
max-width: 15rem;
|
||||
flex-direction: column;
|
||||
gap: 2.5em;
|
||||
width: 100%;
|
||||
|
||||
> :global(div) {
|
||||
aspect-ratio: 2 / 1;
|
||||
}
|
||||
|
||||
@media (min-width: 23rem) {
|
||||
gap: clamp(1em, 0.5em + 3vw, 2em);
|
||||
flex-direction: row;
|
||||
|
||||
> :global(div) {
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
@media (min-width: 52rem) {
|
||||
max-width: 15rem;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > #summary {
|
||||
backdrop-filter: blur(5px);
|
||||
padding: 1.5em;
|
||||
margin: -1.5em;
|
||||
margin-block: 1em;
|
||||
border-radius: 3em;
|
||||
width: fit-content;
|
||||
}
|
||||
}
|
||||
|
||||
& > #right {
|
||||
& > #images {
|
||||
display: grid;
|
||||
grid-template-columns: 10rem 1fr;
|
||||
gap: 1em;
|
||||
|
||||
& > #gallery-scans {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#thumbnail {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
box-shadow: 0 5px 20px -10px var(--color-shadow);
|
||||
transition: 100ms scale;
|
||||
|
||||
&:hover {
|
||||
scale: 102%;
|
||||
}
|
||||
}
|
||||
|
||||
.when-large {
|
||||
@media (max-width: 80rem) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.when-not-large {
|
||||
@media (min-width: 80rem) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
|
||||
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
||||
import Credits from "components/Credits.astro";
|
||||
import RichText from "components/RichText/RichText.astro";
|
||||
import { getI18n } from "src/i18n/i18n";
|
||||
import { payload } from "src/shared/payload/payload-sdk";
|
||||
import { fetchOr404 } from "src/utils/responses";
|
||||
import ScanPreview from "./_components/ScanPreview.astro";
|
||||
import { formatInlineTitle, formatRichTextToString } from "src/utils/format";
|
||||
import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro";
|
||||
|
||||
const slug = Astro.params.slug!;
|
||||
const { getLocalizedMatch, t } = await getI18n(Astro.locals.currentLocale);
|
||||
|
@ -52,13 +52,7 @@ const hasOutsideObi = obi ? Object.keys(obi).some((value) => !value.includes("in
|
|||
subtitle={translation.subtitle}
|
||||
/>
|
||||
|
||||
{
|
||||
translation.description && (
|
||||
<div id="summary" class="high-contrast-text">
|
||||
<RichText content={translation.description} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{translation.description && <AppLayoutDescription description={translation.description} />}
|
||||
|
||||
{credits.length > 0 && <Credits credits={credits} />}
|
||||
|
||||
|
@ -195,10 +189,6 @@ const hasOutsideObi = obi ? Object.keys(obi).some((value) => !value.includes("in
|
|||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
#summary {
|
||||
margin-block: 2.5em;
|
||||
}
|
||||
|
||||
section {
|
||||
margin-block: 6em;
|
||||
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
---
|
||||
import AppLayout from "components/AppLayout/AppLayout.astro";
|
||||
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
|
||||
import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro";
|
||||
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<AppLayout
|
||||
pretitle="Guide to"
|
||||
title="Rich Text Editor"
|
||||
description="Having troubles using the Rich Text Editor? Looking for tips and advanced techniques? You've come to the right place!">
|
||||
<AppEmptyLayout>
|
||||
<AppLayoutTitle pretitle="Guide to" title="Rich Text Editor" />
|
||||
<AppLayoutDescription
|
||||
description="Having troubles using the Rich Text Editor? Looking for tips and advanced techniques? You've come to the right place!"
|
||||
/>
|
||||
|
||||
<div class="prose">
|
||||
<h2>Add indentation / spaces between words</h2>
|
||||
|
||||
|
@ -28,4 +32,12 @@ import AppLayout from "components/AppLayout/AppLayout.astro";
|
|||
</kbd> to create a linebreak.
|
||||
</p>
|
||||
</div>
|
||||
</AppLayout>
|
||||
</AppEmptyLayout>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
.prose {
|
||||
margin-top: 4.5em;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
---
|
||||
import AppLayout from "components/AppLayout/AppLayout.astro";
|
||||
import { Collections, payload } from "src/shared/payload/payload-sdk";
|
||||
import RichText from "components/RichText/RichText.astro";
|
||||
import FoldersSection from "./_components/FoldersSection.astro";
|
||||
import { fetchOr404 } from "src/utils/responses";
|
||||
import ErrorMessage from "components/ErrorMessage.astro";
|
||||
|
@ -12,6 +10,9 @@ import { formatRichTextToString } from "src/utils/format";
|
|||
import ImagePreview from "components/Previews/ImagePreview.astro";
|
||||
import AudioPreview from "components/Previews/AudioPreview.astro";
|
||||
import VideoPreview from "components/Previews/VideoPreview.astro";
|
||||
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
|
||||
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
||||
import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro";
|
||||
|
||||
const { slug } = Astro.params;
|
||||
|
||||
|
@ -26,38 +27,36 @@ const meta = getLocalizedMatch(folder.translations);
|
|||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<AppLayout
|
||||
title={meta.name}
|
||||
<AppEmptyLayout
|
||||
openGraph={{
|
||||
title: meta.name,
|
||||
description: meta.description && formatRichTextToString(meta.description),
|
||||
}}
|
||||
parentPages={folder.parentPages}>
|
||||
{
|
||||
meta.description && (
|
||||
<div slot="header-description">
|
||||
<RichText content={meta.description} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<AppLayoutTitle title={meta.name} />
|
||||
{meta.description && <AppLayoutDescription description={meta.description} />}
|
||||
|
||||
<div id="main">
|
||||
{
|
||||
folder.sections.type === "single" ? (
|
||||
folder.sections.type === "single" && folder.sections.subfolders.length > 0 ? (
|
||||
<FoldersSection folders={folder.sections.subfolders} />
|
||||
) : (
|
||||
<div id="sections">
|
||||
{folder.sections.sections.map(({ subfolders, translations }) => (
|
||||
<FoldersSection
|
||||
folders={subfolders}
|
||||
title={
|
||||
getLocalizedMatch<{
|
||||
language: string;
|
||||
name: string | undefined;
|
||||
}>(translations).name
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
folder.sections.type === "multiple" &&
|
||||
folder.sections.sections.length > 0 && (
|
||||
<div id="sections">
|
||||
{folder.sections.sections.map(({ subfolders, translations }) => (
|
||||
<FoldersSection
|
||||
folders={subfolders}
|
||||
title={
|
||||
getLocalizedMatch<{
|
||||
language: string;
|
||||
name: string | undefined;
|
||||
}>(translations).name
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -92,12 +91,13 @@ const meta = getLocalizedMatch(folder.translations);
|
|||
}
|
||||
</div>
|
||||
</div>
|
||||
</AppLayout>
|
||||
</AppEmptyLayout>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
#main {
|
||||
margin-top: 4.5em;
|
||||
display: grid;
|
||||
gap: 4em;
|
||||
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
---
|
||||
import { Icon } from "astro-icon/components";
|
||||
import AppLayout from "components/AppLayout/AppLayout.astro";
|
||||
import Button from "components/Button.astro";
|
||||
import LibraryGrid from "./_components/LibraryGrid.astro";
|
||||
import ChronicleCard from "./_components/ChronicleCard.astro";
|
||||
import LinkCard from "./_components/LinkCard.astro";
|
||||
import { getI18n } from "src/i18n/i18n";
|
||||
import { cache } from "src/utils/cachedPayload";
|
||||
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
|
||||
import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro";
|
||||
|
||||
const { t, getLocalizedUrl } = await getI18n(Astro.locals.currentLocale);
|
||||
---
|
||||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<AppLayout
|
||||
<AppEmptyLayout
|
||||
openGraph={{ title: t("home.title") }}
|
||||
backgroundImage={{
|
||||
url: "/img/background-image.webp",
|
||||
|
@ -22,19 +23,19 @@ const { t, getLocalizedUrl } = await getI18n(Astro.locals.currentLocale);
|
|||
}}
|
||||
hideFooterLinks
|
||||
hideHomeButton>
|
||||
<div id="title" slot="header-title">
|
||||
<div id="title">
|
||||
<Icon name="accords" />
|
||||
<div>
|
||||
<h1 class="font-serif">{t("global.siteName")}</h1>
|
||||
<p>{t("global.siteSubtitle")}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="description" slot="header-description">
|
||||
<p set:html={t("home.description")} class="high-contrast-text" />
|
||||
<a href={getLocalizedUrl("/about")} class="DEV_TODO">
|
||||
<Button title={t("home.aboutUsButton")} icon="material-symbols:left-click" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<AppLayoutDescription description={t("home.description")} />
|
||||
|
||||
<a href={getLocalizedUrl("/about")}>
|
||||
<Button title={t("home.aboutUsButton")} icon="material-symbols:left-click" />
|
||||
</a>
|
||||
|
||||
<div id="main">
|
||||
<section id="library" class="high-contrast-text">
|
||||
|
@ -178,37 +179,11 @@ const { t, getLocalizedUrl } = await getI18n(Astro.locals.currentLocale);
|
|||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</AppLayout>
|
||||
</AppEmptyLayout>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
#description {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
align-items: flex-start;
|
||||
|
||||
margin-bottom: 128px;
|
||||
|
||||
> p {
|
||||
backdrop-filter: blur(5px);
|
||||
padding: 1em;
|
||||
margin: -1em;
|
||||
width: fit-content;
|
||||
|
||||
border-radius: 5em;
|
||||
}
|
||||
|
||||
@media (max-width: 35rem) {
|
||||
align-items: center;
|
||||
|
||||
@media (max-width: 25rem) {
|
||||
align-items: stretch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#title {
|
||||
display: flex;
|
||||
place-items: center;
|
||||
|
@ -267,9 +242,9 @@ const { t, getLocalizedUrl } = await getI18n(Astro.locals.currentLocale);
|
|||
}
|
||||
|
||||
#main {
|
||||
margin-top: 96px;
|
||||
display: grid;
|
||||
gap: 64px;
|
||||
margin-top: -96px;
|
||||
|
||||
& > section {
|
||||
& > h2 {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
import AppLayout from "components/AppLayout/AppLayout.astro";
|
||||
import AppEmptyLayout from "components/AppLayout/AppEmptyLayout.astro";
|
||||
import AppLayoutTitle from "components/AppLayout/components/AppLayoutTitle.astro";
|
||||
import { getI18n } from "src/i18n/i18n";
|
||||
import { cache } from "src/utils/cachedPayload";
|
||||
import { formatCurrency } from "src/utils/currencies";
|
||||
|
@ -11,7 +12,9 @@ const { t } = await getI18n(currentLocale);
|
|||
|
||||
{/* ------------------------------------------- HTML ------------------------------------------- */}
|
||||
|
||||
<AppLayout openGraph={{ title: t("settings.title") }} title={t("settings.title")}>
|
||||
<AppEmptyLayout openGraph={{ title: t("settings.title") }}>
|
||||
<AppLayoutTitle title={t("settings.title")} />
|
||||
|
||||
<div id="main">
|
||||
<div class="section">
|
||||
<h2>{t("settings.language.title")}</h2>
|
||||
|
@ -66,7 +69,7 @@ const { t } = await getI18n(currentLocale);
|
|||
}
|
||||
</div>
|
||||
</div>
|
||||
</AppLayout>
|
||||
</AppEmptyLayout>
|
||||
|
||||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
|
@ -87,5 +90,6 @@ const { t } = await getI18n(currentLocale);
|
|||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 5em;
|
||||
margin-top: 4.5em;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -9,6 +9,7 @@ import { getI18n } from "src/i18n/i18n";
|
|||
import AppLayoutBackgroundImg from "components/AppLayout/components/AppLayoutBackgroundImg.astro";
|
||||
import { cache } from "src/utils/cachedPayload";
|
||||
import type { WordingKey } from "src/i18n/wordings-keys";
|
||||
import AppLayoutDescription from "components/AppLayout/components/AppLayoutDescription.astro";
|
||||
|
||||
const events = await payload.getChronologyEvents();
|
||||
const groupedEvents = groupBy(events, (event) => event.date.year);
|
||||
|
@ -26,12 +27,7 @@ const { getLocalizedUrl, t, formatTimelineDate } = await getI18n(Astro.locals.cu
|
|||
}}
|
||||
/>
|
||||
<AppLayoutTitle title={t("timeline.title")} />
|
||||
|
||||
<div id="summary" class="prose">
|
||||
<p>
|
||||
{t("timeline.description")}
|
||||
</p>
|
||||
</div>
|
||||
<AppLayoutDescription description={t("timeline.description")} />
|
||||
|
||||
<div class="card-container">
|
||||
<Card>
|
||||
|
@ -85,15 +81,6 @@ const { getLocalizedUrl, t, formatTimelineDate } = await getI18n(Astro.locals.cu
|
|||
{/* ------------------------------------------- CSS -------------------------------------------- */}
|
||||
|
||||
<style>
|
||||
#summary {
|
||||
backdrop-filter: blur(5px);
|
||||
padding: 1.5em;
|
||||
margin: -1.5em;
|
||||
margin-block: 1em;
|
||||
border-radius: 3em;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: clamp(1em, 4vw, 3em);
|
||||
max-width: 35rem;
|
||||
|
|
Loading…
Reference in New Issue