mirror of
https://github.com/jorgev259/soc_site-astro.git
synced 2025-06-29 07:57:41 +00:00
Compare commits
5 commits
427f271375
...
af3cede125
| Author | SHA1 | Date | |
|---|---|---|---|
| af3cede125 | |||
| f4aec30b8f | |||
| 9541b0745a | |||
| 5ed7cbf23e | |||
| 686758e754 |
18 changed files with 356 additions and 32 deletions
|
|
@ -49,11 +49,8 @@ export default defineConfig({
|
|||
adapter: node({ mode: 'standalone' }),
|
||||
redirects: {
|
||||
'/en/[...params]': '/[...params]',
|
||||
'/platform/[id]': { status: 307, destination: '/maintenance' },
|
||||
'/profile': { status: 307, destination: '/maintenance' },
|
||||
'/profile/[username]': { status: 307, destination: '/maintenance' },
|
||||
'/series/[slug]': { status: 307, destination: '/maintenance' },
|
||||
'/studio/[slug]': { status: 307, destination: '/maintenance' },
|
||||
'/request': { status: 307, destination: '/maintenance' }
|
||||
},
|
||||
security: {
|
||||
|
|
|
|||
|
|
@ -84,5 +84,8 @@
|
|||
"holy12_5": "Silksong is hidden behind one of these",
|
||||
"latestGameReleases": "Latest game releases",
|
||||
"latestAnimReleases": " Latest animation releases",
|
||||
"latestReleases": "Latest releases"
|
||||
"latestReleases": "Latest releases",
|
||||
"firstRelease": "First Release",
|
||||
"newestRelease": "Newest Release",
|
||||
"variousGames": "Various Games"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ const { title, href, image, loading = false, class: className } = props
|
|||
<a
|
||||
href={href}
|
||||
class:list={[
|
||||
'block w-full mt-2.5 rounded-xl bg-dark/85 ',
|
||||
loading ? 'cursor-default' : 'hover:bg-dark group',
|
||||
'block w-full mt-2.5 rounded-xl bg-btn-dark ',
|
||||
loading ? 'cursor-default' : 'hover:bg-gray/85 group',
|
||||
className
|
||||
]}
|
||||
>
|
||||
|
|
|
|||
9
src/components/ReleaseDate.astro
Normal file
9
src/components/ReleaseDate.astro
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
interface Props {
|
||||
date: Date
|
||||
}
|
||||
const { props, currentLocale: locale } = Astro
|
||||
const { date } = props
|
||||
---
|
||||
|
||||
{new Intl.DateTimeFormat(locale, { dateStyle: 'medium' }).format(date)}
|
||||
23
src/components/letterList/PlatformGameList.astro
Normal file
23
src/components/letterList/PlatformGameList.astro
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
import { AlbumStatus } from '@prisma/client'
|
||||
import prismaClient from 'utils/prisma-client'
|
||||
|
||||
interface Props {
|
||||
letter: string
|
||||
platformId: number
|
||||
}
|
||||
|
||||
const { letter, platformId } = Astro.props
|
||||
const albums = await prismaClient.game.findMany({
|
||||
where: { name: { startsWith: letter }, platforms: { some: { platformId } } },
|
||||
select: { slug: true, name: true }
|
||||
})
|
||||
---
|
||||
|
||||
{
|
||||
albums.map((a) => (
|
||||
<a class='text-left hover:bg-btn-gray/30 rounded-md p-2' href={`/game/${a.slug}`}>
|
||||
{a.name}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
|
|
@ -44,7 +44,10 @@ const [count, search] = await Promise.all([
|
|||
<div>
|
||||
Albums ({count}) {
|
||||
count > take ? (
|
||||
<span> / Showing {page === 1 ? `first ${take}` : `${(page - 1) * take}-${Math.min(page * take, count)}`} results</span>
|
||||
<span>
|
||||
{' '}
|
||||
/ Showing {page === 1 ? `first ${take}` : `${(page - 1) * take}-${Math.min(page * take, count)}`} results
|
||||
</span>
|
||||
) : null
|
||||
}
|
||||
</div>
|
||||
|
|
@ -56,7 +59,7 @@ const [count, search] = await Promise.all([
|
|||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class='grid sm:grid-cols-1 md:grid-cols-3 mt-1.5 gap-4'>
|
||||
<div class='grid grid-cols-1 md:grid-cols-3 mt-1.5 gap-4'>
|
||||
{
|
||||
search.map((album) => (
|
||||
<a class='flex bg-gray h-40 group hover:no-underline' href={`/album/${album.id}`}>
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ import BaseLayout from 'layouts/base.astro'
|
|||
import TrackList from 'components/albumPage/TrackList'
|
||||
import DownloadBtn from 'components/albumPage/DownloadBtn.astro'
|
||||
import AlbumBox from 'components/AlbumBox.astro'
|
||||
import releaseDate from 'utils/releaseDate'
|
||||
|
||||
import kofi from 'img/socials/ko-fi-donate-button.png'
|
||||
import discord from 'img/socials/discord.png'
|
||||
import vgmdbLogo from 'img/assets/vgmdb-logo.png'
|
||||
import flyIcon from 'img/assets/fly-icon.png'
|
||||
import ouoIcon from 'img/assets/ouo-icon.png'
|
||||
import ReleaseDate from 'components/ReleaseDate.astro'
|
||||
|
||||
const { id } = Astro.params
|
||||
const { permissions } = Astro.locals
|
||||
|
|
@ -131,7 +131,7 @@ const coverImage = await getImage({
|
|||
<tr>
|
||||
<th class='width-row'>{m.releaseDate()}</th>
|
||||
<td>
|
||||
{releaseDate(album?.releaseDate)}
|
||||
<ReleaseDate date={album?.releaseDate} />
|
||||
</td>
|
||||
</tr>
|
||||
) : null
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Image } from 'astro:assets'
|
|||
|
||||
import BaseLayout from 'layouts/base.astro'
|
||||
import AlbumBox from 'components/AlbumBox.astro'
|
||||
import releaseDate from 'utils/releaseDate'
|
||||
import ReleaseDate from 'components/ReleaseDate.astro'
|
||||
|
||||
const { id } = Astro.params
|
||||
|
||||
|
|
@ -87,7 +87,9 @@ const { currentLocale } = Astro
|
|||
anim.releaseDate ? (
|
||||
<div class='table-row'>
|
||||
<div class='table-cell text-md font-medium'>{m.releaseDate()}</div>
|
||||
<div class='table-cell text-md'>{releaseDate(anim.releaseDate)}</div>
|
||||
<div class='table-cell text-md'>
|
||||
<ReleaseDate date={anim.releaseDate} />
|
||||
</div>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ const letters: { letter: string; count: BigInt }[] = await prismaClient.$queryRa
|
|||
letters.map((l) => (
|
||||
<div id={l.letter}>
|
||||
<div class='flex uppercase border-y-2 text-4xl justify-center border-white py-1.5'>{l.letter}</div>
|
||||
<div class='py-4 grid sm:grid-cols-1 md:grid-cols-6 gap-1 justify-items-center'>
|
||||
<div class='py-4 grid grid-cols-1 md:grid-cols-6 gap-1 justify-items-center'>
|
||||
<AnimList letter={l.letter} server:defer>
|
||||
<Fragment slot='fallback'>
|
||||
{Array.from({ length: Number(l.count) }).map(() => (
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { SEO } from 'astro-seo'
|
|||
import BaseLayout from 'layouts/base.astro'
|
||||
|
||||
import AlbumBox from 'components/AlbumBox.astro'
|
||||
import releaseDate from 'utils/releaseDate'
|
||||
import ReleaseDate from 'components/ReleaseDate.astro'
|
||||
|
||||
const { slug } = Astro.params
|
||||
if (!slug) return Astro.redirect('/404')
|
||||
|
|
@ -62,29 +62,31 @@ const coverImage = await getImage({
|
|||
|
||||
<BaseLayout>
|
||||
<div class='flex flex-col flex-1 max-w-[1440px] mx-auto p-3'>
|
||||
<div class='flex flex-wrap md:flex-nowrap gap-x-3'>
|
||||
<div class='flex flex-col md:flex-row flex-wrap md:flex-nowrap gap-x-3 gap-y-2'>
|
||||
<div class='flex-1 flex-wrap md:flex-5/12'>
|
||||
<div class='size-full relative cursor-pointer'>
|
||||
<!-- <Image
|
||||
<div class='size-full relative cursor-pointer bg-dark rounded-xl p-4'>
|
||||
<Image
|
||||
src={`https://cdn.sittingonclouds.net/game/${slug}.png`}
|
||||
alt={`${game.name} logo`}
|
||||
class='rounded-sm size-full object-contain h-fit mb-2 md:min-h-96 px-10'
|
||||
class='rounded-sm'
|
||||
quality='mid'
|
||||
width={500}
|
||||
height={500}
|
||||
/> -->
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class='flex-1 flex-wrap md:flex-7/12'>
|
||||
<div class='bg-dark rounded-xl py-4 px-6'>
|
||||
<div class='font-medium text-4xl text-center'>{game.name}</div>
|
||||
<table class='mt-4 border-spacing-y-4 border-separate w-full'>
|
||||
<table class='border-spacing-y-4 border-separate w-full'>
|
||||
<tbody>
|
||||
{
|
||||
game.releaseDate ? (
|
||||
<tr>
|
||||
<th class='width-row'>{m.releaseDate()}:</th>
|
||||
<td>{releaseDate(game.releaseDate)}</td>
|
||||
<td>
|
||||
<ReleaseDate date={game.releaseDate} />
|
||||
</td>
|
||||
</tr>
|
||||
) : null
|
||||
}
|
||||
|
|
@ -134,7 +136,7 @@ const coverImage = await getImage({
|
|||
</div>
|
||||
<hr />
|
||||
<div class='flex flex-wrap md:flex-nowrap gap-x-3'>
|
||||
<div class='grid grid-cols-5 gap-x-2'>
|
||||
<div class='grid grid-cols-2 md:grid-cols-5 gap-x-2'>
|
||||
{
|
||||
game.albums.map((a) => (
|
||||
<AlbumBox href={`/album/${a.album.id}`} image={`/album/${a.album.id}.png`} title={a.album.title} />
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ const letters: { letter: string; count: BigInt }[] = await prismaClient.$queryRa
|
|||
letters.map((l) => (
|
||||
<div id={l.letter}>
|
||||
<div class='flex uppercase border-y-2 text-4xl justify-center border-white py-1.5'>{l.letter}</div>
|
||||
<div class='py-4 grid sm:grid-cols-1 md:grid-cols-3 gap-1'>
|
||||
<div class='py-4 grid grid-cols-1 md:grid-cols-3 gap-1'>
|
||||
<GameList letter={l.letter} server:defer>
|
||||
<Fragment slot='fallback'>
|
||||
{Array.from({ length: Number(l.count) }).map(() => (
|
||||
|
|
|
|||
45
src/pages/platform/[id].astro
Normal file
45
src/pages/platform/[id].astro
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
---
|
||||
import prismaClient from 'utils/prisma-client'
|
||||
|
||||
import LetterList from 'layouts/LetterList.astro'
|
||||
import PlatformGameList from 'components/letterList/PlatformGameList.astro'
|
||||
import { AlbumStatus } from '@prisma/client'
|
||||
|
||||
const { id } = Astro.params
|
||||
|
||||
if (!id) return Astro.redirect('/404')
|
||||
const platformId = parseInt(id)
|
||||
if (!platformId) return Astro.redirect('/404')
|
||||
|
||||
const platform = await prismaClient.platform.findUnique({ where: { id: platformId }, select: { name: true } })
|
||||
if (!platform) return Astro.redirect('/404')
|
||||
|
||||
const letters: { letter: string; count: BigInt }[] = await prismaClient.$queryRaw`
|
||||
SELECT DISTINCT UPPER(LEFT(game.name, 1)) AS letter, COUNT(*) AS count
|
||||
FROM game, platform, Game_Platform
|
||||
WHERE game.slug = Game_Platform.gameSlug
|
||||
AND platform.id = Game_Platform.platformId
|
||||
AND platform.id = ${platformId}
|
||||
GROUP BY letter
|
||||
ORDER BY letter;
|
||||
`
|
||||
---
|
||||
|
||||
<LetterList letters={letters}>
|
||||
{
|
||||
letters.map((l) => (
|
||||
<div id={l.letter}>
|
||||
<div class='flex uppercase border-y-2 text-4xl justify-center border-white py-1.5'>{l.letter}</div>
|
||||
<div class='flex flex-col gap-2 py-4'>
|
||||
<PlatformGameList platformId={platformId} letter={l.letter} server:defer>
|
||||
<Fragment slot='fallback'>
|
||||
{Array.from({ length: Number(l.count) }).map(() => (
|
||||
<div class='animate-pulse h-8 w-full bg-gray/85' />
|
||||
))}
|
||||
</Fragment>
|
||||
</PlatformGameList>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</LetterList>
|
||||
|
|
@ -21,7 +21,7 @@ const letters: { letter: string; count: BigInt }[] = await prismaClient.$queryRa
|
|||
letters.map((l) => (
|
||||
<div id={l.letter}>
|
||||
<div class='flex uppercase border-y-2 text-4xl justify-center border-white py-1.5'>{l.letter}</div>
|
||||
<div class='py-4 grid sm:grid-cols-1 md:grid-cols-4 gap-1'>
|
||||
<div class='py-4 grid grid-cols-1 md:grid-cols-4 gap-1'>
|
||||
<PlatformList letter={l.letter} server:defer>
|
||||
<Fragment slot='fallback'>
|
||||
{Array.from({ length: Number(l.count) }).map(() => (
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ const letters: { letter: string; count: BigInt }[] = await prismaClient.$queryRa
|
|||
letters.map((l) => (
|
||||
<div id={l.letter}>
|
||||
<div class='flex uppercase border-y-2 text-4xl justify-center border-white py-1.5'>{l.letter}</div>
|
||||
<div class='py-4 grid sm:grid-cols-1 md:grid-cols-4 gap-1'>
|
||||
<div class='py-4 grid grid-cols-1 md:grid-cols-4 gap-1'>
|
||||
<PublisherList letter={l.letter} server:defer>
|
||||
<Fragment slot='fallback'>
|
||||
{Array.from({ length: Number(l.count) }).map(() => (
|
||||
|
|
|
|||
188
src/pages/series/[slug].astro
Normal file
188
src/pages/series/[slug].astro
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
---
|
||||
import prismaClient from 'utils/prisma-client'
|
||||
import * as m from 'paraglide/messages'
|
||||
import { getImage, Image } from 'astro:assets'
|
||||
import { SEO } from 'astro-seo'
|
||||
|
||||
import BaseLayout from 'layouts/base.astro'
|
||||
import AlbumBox from 'components/AlbumBox.astro'
|
||||
import ReleaseDate from 'components/ReleaseDate.astro'
|
||||
|
||||
const { slug } = Astro.params
|
||||
if (!slug) return Astro.redirect('/404')
|
||||
|
||||
const series = await prismaClient.series.findUnique({
|
||||
where: { slug },
|
||||
select: {
|
||||
name: true,
|
||||
headerColor: true,
|
||||
games: {
|
||||
select: {
|
||||
game: {
|
||||
select: {
|
||||
slug: true,
|
||||
releaseDate: true,
|
||||
name: true,
|
||||
albums: {
|
||||
select: {
|
||||
album: { select: { id: true, title: true, games: { select: { gameSlug: true, game: true } } } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
orderBy: { game: { releaseDate: 'asc' } }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (!series) return Astro.redirect('/404')
|
||||
|
||||
const variousAlbums: { id: number; title: string | null }[] = []
|
||||
const singleAlbumsObj: {
|
||||
[key: string]: {
|
||||
albums: { id: number; title: string | null }[]
|
||||
game: {
|
||||
slug: string
|
||||
name: string | null
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
placeholder: string | null
|
||||
headerColor: string | null
|
||||
releaseDate: Date | null
|
||||
}
|
||||
}
|
||||
} = {}
|
||||
const checkedAlbums = new Set<number>()
|
||||
|
||||
series.games.forEach((g) => {
|
||||
g.game.albums.forEach(({ album }) => {
|
||||
if (checkedAlbums.has(album.id)) return
|
||||
else checkedAlbums.add(album.id)
|
||||
|
||||
if (album.games.length > 1) {
|
||||
variousAlbums.push(album)
|
||||
} else {
|
||||
const game = album.games[0]
|
||||
if (!singleAlbumsObj[game.gameSlug]) {
|
||||
singleAlbumsObj[game.gameSlug] = { albums: [], game: game.game }
|
||||
}
|
||||
singleAlbumsObj[game.gameSlug].albums.push(album)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const singleAlbums = Object.values(singleAlbumsObj).sort((a, b) => {
|
||||
if (!a.game.releaseDate || !b.game.releaseDate) return 0
|
||||
return b.game.releaseDate.getTime() - a.game.releaseDate.getTime()
|
||||
})
|
||||
const firstGame = series.games[0]?.game
|
||||
const lastGame = series.games[series.games.length - 1]?.game
|
||||
const coverImage = await getImage({
|
||||
src: `https://cdn.sittingonclouds.net/game/${slug}.png`,
|
||||
height: 150,
|
||||
width: 150
|
||||
})
|
||||
---
|
||||
|
||||
<SEO
|
||||
slot='head'
|
||||
titleDefault='Sitting on Clouds'
|
||||
title={series.name ?? undefined}
|
||||
description='Largest Video Game & Animation Soundtrack サウンドトラック Archive'
|
||||
openGraph={{
|
||||
basic: {
|
||||
title: series.name ?? '',
|
||||
type: 'website',
|
||||
image: `https://www.sittingonclouds.net${coverImage.src}`,
|
||||
url: Astro.url.pathname
|
||||
},
|
||||
optional: {
|
||||
siteName: 'Sitting on Clouds'
|
||||
}
|
||||
}}
|
||||
extend={{
|
||||
meta: [{ name: 'theme-color', content: series.headerColor ?? '#121212' }]
|
||||
}}
|
||||
/>
|
||||
|
||||
<BaseLayout>
|
||||
<div class='flex flex-col flex-1 max-w-[1440px] mx-auto p-3'>
|
||||
<div class='flex flex-col md:flex-row flex-wrap md:flex-nowrap gap-x-3 gap-y-2'>
|
||||
<div class='flex-1 flex-wrap md:flex-5/12'>
|
||||
<div class='size-full relative cursor-pointer bg-dark rounded-xl p-2'>
|
||||
<Image
|
||||
src={`https://cdn.sittingonclouds.net/series/${slug}.png`}
|
||||
alt={`${series.name} logo`}
|
||||
class='rounded-sm'
|
||||
quality='mid'
|
||||
width={500}
|
||||
height={500}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class='flex-1 flex-wrap md:flex-7/12'>
|
||||
<div class='bg-dark rounded-xl py-4 px-6'>
|
||||
<div class='font-medium text-4xl text-center'>{series.name}</div>
|
||||
<table class='border-spacing-y-4 border-separate w-full'>
|
||||
<tbody>
|
||||
{
|
||||
firstGame.releaseDate ? (
|
||||
<tr>
|
||||
<th class='width-row'>{m.firstRelease()}:</th>
|
||||
<td>
|
||||
<ReleaseDate date={firstGame.releaseDate} /> -{' '}
|
||||
<a href={`/game/${firstGame.slug}`}>{firstGame.name}</a>
|
||||
</td>
|
||||
</tr>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
lastGame.releaseDate ? (
|
||||
<tr>
|
||||
<th class='width-row'>{m.newestRelease()}:</th>
|
||||
<td>
|
||||
<ReleaseDate date={lastGame.releaseDate} />
|
||||
<span> - </span>
|
||||
<a href={`/game/${lastGame.slug}`}>{lastGame.name}</a>
|
||||
</td>
|
||||
</tr>
|
||||
) : null
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div class='flex flex-col gap-y-3'>
|
||||
<div class='w-full'>
|
||||
<div class='w-full bg-dark text-2xl px-4 py-2 rounded-t-md'>{m.variousGames()}</div>
|
||||
<div class='grid grid-cols-3 md:grid-cols-5 gap-x-2 bg-gray px-4 pb-2 rounded-b-md'>
|
||||
{
|
||||
variousAlbums.map((album) => (
|
||||
<AlbumBox title={album.title ?? ''} href={`/album/${album.id}`} image={`/album/${album.id}.png`} />
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class='w-full flex flex-col gap-y-3'>
|
||||
{
|
||||
singleAlbums.map((s) => (
|
||||
<div class='w-full'>
|
||||
<div class='w-full bg-dark text-2xl px-4 py-2 rounded-t-md flex gap-x-9'>
|
||||
<span>{s.game.releaseDate?.getFullYear()}</span>
|
||||
<span>{s.game.name}</span>
|
||||
</div>
|
||||
<div class='grid grid-cols-3 md:grid-cols-5 gap-x-2 bg-gray px-4 pb-2 rounded-b-md'>
|
||||
{s.albums.map((album) => (
|
||||
<AlbumBox title={album.title ?? ''} href={`/album/${album.id}`} image={`/album/${album.id}.png`} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseLayout>
|
||||
58
src/pages/studio/[slug].astro
Normal file
58
src/pages/studio/[slug].astro
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
import prismaClient from 'utils/prisma-client'
|
||||
|
||||
import DefaultSEO from 'components/DefaultSEO.astro'
|
||||
import BaseLayout from 'layouts/base.astro'
|
||||
import Sidebar from 'components/Sidebar.astro'
|
||||
import AlbumBox from 'components/AlbumBox.astro'
|
||||
|
||||
const { slug } = Astro.params
|
||||
if (!slug) return Astro.redirect('/404')
|
||||
|
||||
const studio = await prismaClient.studio.findUnique({
|
||||
where: { slug },
|
||||
select: {
|
||||
name: true,
|
||||
animations: {
|
||||
select: {
|
||||
animation: {
|
||||
select: {
|
||||
albums: {
|
||||
select: { albumId: true, album: { select: { title: true, publishedAt: true } } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (!studio) return Astro.redirect('/404')
|
||||
|
||||
const albumsMap = new Map<number, { title: string | null; publishedAt: Date }>()
|
||||
studio.animations.forEach((a) => {
|
||||
a.animation.albums.forEach(({ albumId, album }) => {
|
||||
albumsMap.set(albumId, album)
|
||||
})
|
||||
})
|
||||
|
||||
const albums = Array.from(albumsMap.entries())
|
||||
.map(([id, data]) => ({ id, ...data }))
|
||||
.sort((a, b) => a.publishedAt.getTime() - b.publishedAt.getTime())
|
||||
.reverse()
|
||||
---
|
||||
|
||||
<DefaultSEO />
|
||||
<BaseLayout>
|
||||
<div class='flex flex-col md:flex-row flex-1 max-w-[2000px]'>
|
||||
<div class='flex-1 px-5 bg-dark'>
|
||||
<div class='p-2 text-center text-3xl text-white border-white border-b-1 border-t-1'>
|
||||
{studio.name}
|
||||
</div>
|
||||
<div class='grid grid-cols-2 md:grid-cols-4 gap-x-2.5'>
|
||||
{albums.map((a) => <AlbumBox href={`/album/${a.id}`} image={`/album/${a.id}.png`} title={a.title} />)}
|
||||
</div>
|
||||
</div>
|
||||
<Sidebar />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
|
|
@ -20,7 +20,7 @@ const letters: { letter: string; count: BigInt }[] = await prismaClient.$queryRa
|
|||
letters.map((l) => (
|
||||
<div id={l.letter}>
|
||||
<div class='flex uppercase border-y-2 text-4xl justify-center border-white py-1.5'>{l.letter}</div>
|
||||
<div class='py-4 grid sm:grid-cols-1 md:grid-cols-4 gap-1'>
|
||||
<div class='py-4 grid grid-cols-1 md:grid-cols-4 gap-1'>
|
||||
<PublisherList letter={l.letter} server:defer>
|
||||
<Fragment slot='fallback'>
|
||||
{Array.from({ length: Number(l.count) }).map(() => (
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
const locale =
|
||||
navigator && navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.language
|
||||
|
||||
const releaseDate = (date: Date) => new Intl.DateTimeFormat(locale, { dateStyle: 'medium' }).format(date)
|
||||
|
||||
export default releaseDate
|
||||
Loading…
Add table
Add a link
Reference in a new issue