86 lines
2.4 KiB
Text
86 lines
2.4 KiB
Text
---
|
|
import type { ComponentInstance } from 'astro';
|
|
|
|
import BookTile from '@/atoms/book-tile.astro';
|
|
import MediaTile from '@/atoms/media-tile.astro';
|
|
import PersonTile from '@/atoms/person-tile.astro';
|
|
import SectionCard from '@/atoms/section-card.astro';
|
|
import Typography from '@/atoms/typography.astro';
|
|
import VideoTile from '@/atoms/video-tile.astro';
|
|
import type { Section } from '@/types/data';
|
|
import type { Book, FavoritesSection, Media, Person, Video } from '@/types/favorites-section';
|
|
|
|
export interface Props extends FavoritesSection {}
|
|
|
|
const {
|
|
config: { title },
|
|
books,
|
|
medias,
|
|
people,
|
|
videos,
|
|
} = Astro.props;
|
|
|
|
type Subsection = 'books' | 'medias' | 'people' | 'videos';
|
|
type SubsectionData = Book | Media | Person | Video;
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- required to avoid type casting
|
|
type SubsectionComponent = (_props: { value: any }) => ComponentInstance;
|
|
|
|
interface FavoritesSubsection<T extends SubsectionData> {
|
|
name: Subsection;
|
|
data: T[];
|
|
title: string;
|
|
columnsLayout: string;
|
|
Component: SubsectionComponent;
|
|
}
|
|
|
|
const booksSubsection: FavoritesSubsection<Book> = {
|
|
name: 'books',
|
|
columnsLayout: 'grid-cols-fluid200',
|
|
Component: BookTile,
|
|
...books,
|
|
};
|
|
|
|
const mediasSubsection: FavoritesSubsection<Media> = {
|
|
name: 'medias',
|
|
columnsLayout: 'grid-cols-fluid120',
|
|
Component: MediaTile,
|
|
...medias,
|
|
};
|
|
|
|
const peopleSubsection: FavoritesSubsection<Person> = {
|
|
name: 'people',
|
|
columnsLayout: 'grid-cols-fluid120',
|
|
Component: PersonTile,
|
|
...people,
|
|
};
|
|
|
|
const videosSubsection: FavoritesSubsection<Video> = {
|
|
name: 'videos',
|
|
columnsLayout: 'grid-cols-fluid240',
|
|
Component: VideoTile,
|
|
...videos,
|
|
};
|
|
|
|
const subsections = [booksSubsection, peopleSubsection, videosSubsection, mediasSubsection];
|
|
|
|
const section: Section = 'favorites';
|
|
---
|
|
|
|
<SectionCard section={section} title={title}>
|
|
<div class="flex flex-col gap-16">
|
|
{
|
|
subsections.map(({ Component, data, name, columnsLayout, title: subsectionTitle }) => (
|
|
<div class="flex flex-col gap-6">
|
|
<Typography variant="section-subtitle" id={`${section}-${name}-heading`}>
|
|
{subsectionTitle}
|
|
</Typography>
|
|
<div class:list={['grid gap-8', columnsLayout]}>
|
|
{data.map((value) => (
|
|
<Component value={value} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
))
|
|
}
|
|
</div>
|
|
</SectionCard>
|