mirror of
https://github.com/jorgev259/soc_site-astro.git
synced 2025-06-29 07:57:41 +00:00
Compare commits
5 commits
a4b8cf5aab
...
491d72bd3c
| Author | SHA1 | Date | |
|---|---|---|---|
| 491d72bd3c | |||
| 91a91cb6a3 | |||
| 5c8f8be791 | |||
| d618e30110 | |||
| f675e177b7 |
13 changed files with 211 additions and 74 deletions
|
|
@ -48,10 +48,8 @@ export default defineConfig({
|
||||||
output: 'server',
|
output: 'server',
|
||||||
adapter: node({ mode: 'standalone' }),
|
adapter: node({ mode: 'standalone' }),
|
||||||
redirects: {
|
redirects: {
|
||||||
'/anim': { status: 307, destination: '/maintenance' },
|
|
||||||
'/anim/[id]': { status: 307, destination: '/maintenance' },
|
'/anim/[id]': { status: 307, destination: '/maintenance' },
|
||||||
'/anim/list': { status: 307, destination: '/maintenance' },
|
'/anim/list': { status: 307, destination: '/maintenance' },
|
||||||
'/game': { status: 307, destination: '/maintenance' },
|
|
||||||
'/game/[slug]': { status: 307, destination: '/maintenance' },
|
'/game/[slug]': { status: 307, destination: '/maintenance' },
|
||||||
'/game/list': { status: 307, destination: '/maintenance' },
|
'/game/list': { status: 307, destination: '/maintenance' },
|
||||||
'/platform/list': { status: 307, destination: '/maintenance' },
|
'/platform/list': { status: 307, destination: '/maintenance' },
|
||||||
|
|
@ -62,7 +60,6 @@ export default defineConfig({
|
||||||
'/series/list': { status: 307, destination: '/maintenance' },
|
'/series/list': { status: 307, destination: '/maintenance' },
|
||||||
'/studio/[slug]': { status: 307, destination: '/maintenance' },
|
'/studio/[slug]': { status: 307, destination: '/maintenance' },
|
||||||
'/studio/list': { status: 307, destination: '/maintenance' },
|
'/studio/list': { status: 307, destination: '/maintenance' },
|
||||||
'/holy12': { status: 307, destination: '/maintenance' },
|
|
||||||
'/request': { status: 307, destination: '/maintenance' }
|
'/request': { status: 307, destination: '/maintenance' }
|
||||||
},
|
},
|
||||||
security: {
|
security: {
|
||||||
|
|
|
||||||
|
|
@ -75,5 +75,14 @@
|
||||||
"discordRoleNeeded": "You need the Donator Discord role to access this page",
|
"discordRoleNeeded": "You need the Donator Discord role to access this page",
|
||||||
"addedDonator": "Added donator benefits to your account!",
|
"addedDonator": "Added donator benefits to your account!",
|
||||||
"errorDonatorCheck": "Something went wrong when checking your Discord donator status. Please try again later. {error}",
|
"errorDonatorCheck": "Something went wrong when checking your Discord donator status. Please try again later. {error}",
|
||||||
"discordRateLimit": "{message} Retry after {retry_after} seconds."
|
"discordRateLimit": "{message} Retry after {retry_after} seconds.",
|
||||||
|
"holy12_0": "Cloud's secret mixtape",
|
||||||
|
"holy12_1": "Best romantic dinner BGM",
|
||||||
|
"holy12_2": "12 clicks till midnight",
|
||||||
|
"holy12_3": "We let our technicians pick these",
|
||||||
|
"holy12_4": "It's noisy outside, take one of these",
|
||||||
|
"holy12_5": "Silksong is hidden behind one of these",
|
||||||
|
"latestGameReleases": "Latest game releases",
|
||||||
|
"latestAnimReleases": " Latest animation releases",
|
||||||
|
"latestReleases": "Latest releases"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
import { Image, Picture } from 'astro:assets'
|
import { Image, Picture } from 'astro:assets'
|
||||||
import * as m from '../paraglide/messages.js'
|
import * as m from '../paraglide/messages.js'
|
||||||
|
import prismaClient from 'utils/prisma-client.js'
|
||||||
|
|
||||||
import logo from 'img/logos/winter.png'
|
import logo from 'img/logos/winter.png'
|
||||||
import logoEs from 'img/logos/default_es.png'
|
import logoEs from 'img/logos/default_es.png'
|
||||||
|
|
@ -10,12 +11,16 @@ import DropdownItem from './header/DropdownItem.astro'
|
||||||
import Toggler from './header/Toggler.astro'
|
import Toggler from './header/Toggler.astro'
|
||||||
import NavButton from './header/NavButton.astro'
|
import NavButton from './header/NavButton.astro'
|
||||||
import LoginNav from './header/LoginNav.astro'
|
import LoginNav from './header/LoginNav.astro'
|
||||||
import prismaClient from 'utils/prisma-client.js'
|
|
||||||
import { Icon } from 'astro-icon/components'
|
|
||||||
import SearchBar from './search/SearchBar.astro'
|
import SearchBar from './search/SearchBar.astro'
|
||||||
|
|
||||||
const { value: bannerId } = (await prismaClient.config.findUnique({ where: { name: 'banner' } })) ?? {}
|
const [bannerConfig, bannerPositionConfig] = await Promise.all([
|
||||||
const { value: bannerPosition } = (await prismaClient.config.findUnique({ where: { name: 'banner-position' } })) ?? {}
|
prismaClient.config.findUnique({ where: { name: 'banner' }, select: { value: true } }),
|
||||||
|
prismaClient.config.findUnique({ where: { name: 'banner-position' }, select: { value: true } })
|
||||||
|
])
|
||||||
|
|
||||||
|
const bannerId = bannerConfig?.value || ''
|
||||||
|
const bannerPosition = bannerPositionConfig?.value || 'top'
|
||||||
|
|
||||||
const { session } = Astro.locals
|
const { session } = Astro.locals
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -53,18 +58,18 @@ const { session } = Astro.locals
|
||||||
<Dropdown>
|
<Dropdown>
|
||||||
{m.games()}
|
{m.games()}
|
||||||
<Fragment slot='items'>
|
<Fragment slot='items'>
|
||||||
<DropdownItem href='/game'>{m.albums()}</DropdownItem>
|
<DropdownItem href='/game/latest'>{m.latestReleases()}</DropdownItem>
|
||||||
|
<DropdownItem href='/game/list'>{m.gamelist()}</DropdownItem>
|
||||||
<DropdownItem href='/series'>{m.series()}</DropdownItem>
|
<DropdownItem href='/series'>{m.series()}</DropdownItem>
|
||||||
<DropdownItem href='/publisher/list'>{m.publishers()}</DropdownItem>
|
<DropdownItem href='/publisher/list'>{m.publishers()}</DropdownItem>
|
||||||
<DropdownItem href='/platforms/list'>{m.platforms()}</DropdownItem>
|
<DropdownItem href='/platforms/list'>{m.platforms()}</DropdownItem>
|
||||||
<DropdownItem href='/game/list'>{m.gamelist()}</DropdownItem>
|
|
||||||
</Fragment>
|
</Fragment>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
|
||||||
<Dropdown>
|
<Dropdown>
|
||||||
{m.animation()}
|
{m.animation()}
|
||||||
<Fragment slot='items'>
|
<Fragment slot='items'>
|
||||||
<DropdownItem href='/anim'>{m.albums()}</DropdownItem>
|
<DropdownItem href='/anim/latest'>{m.latestReleases()}</DropdownItem>
|
||||||
<DropdownItem href='/anim/list'>{m.animationlist()}</DropdownItem>
|
<DropdownItem href='/anim/list'>{m.animationlist()}</DropdownItem>
|
||||||
<DropdownItem href='/studio/list'>{m.studios()}</DropdownItem>
|
<DropdownItem href='/studio/list'>{m.studios()}</DropdownItem>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,17 @@ import AlbumBox from './AlbumBox.astro'
|
||||||
import AlbumCount from './sidebar/AlbumCount.astro'
|
import AlbumCount from './sidebar/AlbumCount.astro'
|
||||||
import CommentCarousel from './sidebar/CommentCarousel.astro'
|
import CommentCarousel from './sidebar/CommentCarousel.astro'
|
||||||
import SidebarAd from './sidebar/SidebarAd.astro'
|
import SidebarAd from './sidebar/SidebarAd.astro'
|
||||||
|
import GetLuckyAlbum from './sidebar/GetLuckyAlbum.astro'
|
||||||
|
|
||||||
const listClass =
|
const listClass =
|
||||||
'uppercase text-3xl font-semibold w-full text-center py-3 hover:bg-dark-hover hover:text-cyan-400 hover:underline'
|
'uppercase text-3xl font-semibold w-full text-center py-3 hover:bg-dark-hover hover:text-cyan-400 hover:underline'
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class='md:w-3/12 md:max-w-[300px] h-full bg-dark flex flex-col'>
|
<div class='md:w-3/12 md:max-w-[300px] h-full bg-dark flex flex-col'>
|
||||||
<a href='#' class={listClass}>{m.getLucky()}</a>
|
<GetLuckyAlbum server:defer class={listClass}>
|
||||||
<a href='#' class={listClass}>{m.randomPull()}</a>
|
<div slot='fallback' class:list={[listClass, 'animate-pulse w-full h-14 bg-gray/90']}></div>
|
||||||
|
</GetLuckyAlbum>
|
||||||
|
<a href='/holy12' class={listClass}>{m.randomPull()}</a>
|
||||||
<div class='px-6 flex flex-col gap-y-3'>
|
<div class='px-6 flex flex-col gap-y-3'>
|
||||||
<SidebarSection class='flex flex-col gap-y-3'>
|
<SidebarSection class='flex flex-col gap-y-3'>
|
||||||
<div class='flex gap-x-2 justify-center'>
|
<div class='flex gap-x-2 justify-center'>
|
||||||
|
|
|
||||||
|
|
@ -11,31 +11,20 @@ interface Props {
|
||||||
|
|
||||||
const take = 20
|
const take = 20
|
||||||
const { query } = Astro.props
|
const { query } = Astro.props
|
||||||
|
|
||||||
|
const queryString = query
|
||||||
|
.toLowerCase()
|
||||||
|
.split('_')
|
||||||
|
.map((w) => `+${w}`)
|
||||||
|
.join(' ')
|
||||||
const findQuery: Prisma.albumsFindManyArgs = {
|
const findQuery: Prisma.albumsFindManyArgs = {
|
||||||
select: { title: true, releaseDate: true, id: true },
|
select: { title: true, releaseDate: true, id: true },
|
||||||
where: {
|
where: {
|
||||||
OR: [
|
OR: [{ title: { search: queryString } }, { subTitle: { search: queryString } }]
|
||||||
{
|
|
||||||
title: {
|
|
||||||
search: query
|
|
||||||
.toLowerCase()
|
|
||||||
.split('_')
|
|
||||||
.map((w) => `+${w}`)
|
|
||||||
.join(' ')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subTitle: {
|
|
||||||
search: query
|
|
||||||
.toLowerCase()
|
|
||||||
.split('_')
|
|
||||||
.map((w) => `+${w}`)
|
|
||||||
.join(' ')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
orderBy: { publishedAt: 'desc' }
|
orderBy: {
|
||||||
|
_relevance: { fields: ['title', 'subTitle'], sort: 'desc', search: query.toLowerCase() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const countQuery: Prisma.albumsCountArgs<DefaultArgs> = {
|
const countQuery: Prisma.albumsCountArgs<DefaultArgs> = {
|
||||||
where: findQuery.where
|
where: findQuery.where
|
||||||
|
|
|
||||||
14
src/components/sidebar/GetLuckyAlbum.astro
Normal file
14
src/components/sidebar/GetLuckyAlbum.astro
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
class: string
|
||||||
|
}
|
||||||
|
|
||||||
|
import * as m from '../../paraglide/messages.js'
|
||||||
|
|
||||||
|
import { getRandomAlbum } from 'utils/queries'
|
||||||
|
|
||||||
|
const album = await getRandomAlbum()
|
||||||
|
const { class: className } = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<a href={`/album/${album.id}`} class={className}>{m.getLucky()}</a>
|
||||||
42
src/layouts/PaginatedAlbumList.astro
Normal file
42
src/layouts/PaginatedAlbumList.astro
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
albums: { title: string | null; id: number }[]
|
||||||
|
limitXS: number
|
||||||
|
limitMD: number
|
||||||
|
fullPageList: number[]
|
||||||
|
page: number
|
||||||
|
}
|
||||||
|
|
||||||
|
import Base from './base.astro'
|
||||||
|
import AlbumBox from 'components/AlbumBox.astro'
|
||||||
|
import FooterNav from 'components/lastAdded/FooterNav.astro'
|
||||||
|
|
||||||
|
const { albums, limitMD, limitXS, ...listProps } = Astro.props
|
||||||
|
|
||||||
|
if (albums.length === 0) {
|
||||||
|
Astro.redirect('/404')
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<Base>
|
||||||
|
<div class='flex flex-col w-full'>
|
||||||
|
<div class='w-full min-h-100vh mx-auto max-w-[1140px]'>
|
||||||
|
<div class='px-2 mb-2'>
|
||||||
|
<h1 class='uppercase font-medium tracking-wide text-5xl drop-shadow-2xl mt-5 mb-2 text-center'>
|
||||||
|
<slot />
|
||||||
|
</h1>
|
||||||
|
<div class='grid grid-cols-2 md:grid-cols-4 gap-x-1.5'>
|
||||||
|
{
|
||||||
|
albums.map((album) => (
|
||||||
|
<AlbumBox title={album.title} href={`/album/${album.id}`} image={`/album/${album.id}.png`} />
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<nav class='bg-dark p-2'>
|
||||||
|
<FooterNav class='flex md:hidden' pageLimit={limitXS} {...listProps} />
|
||||||
|
<FooterNav class='hidden md:flex' pageLimit={limitMD} {...listProps} />
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</Base>
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
---
|
---
|
||||||
import prismaClient from 'utils/prisma-client'
|
import prismaClient from 'utils/prisma-client'
|
||||||
import * as m from 'paraglide/messages'
|
|
||||||
import { AlbumStatus } from '@prisma/client'
|
|
||||||
|
|
||||||
import Sidebar from 'components/Sidebar.astro'
|
|
||||||
import BaseLayout from 'layouts/base.astro'
|
import BaseLayout from 'layouts/base.astro'
|
||||||
import AlbumBox from 'components/AlbumBox.astro'
|
import Sidebar from 'components/Sidebar.astro'
|
||||||
import LetterSection from 'components/albumList/letterSection.astro'
|
import LetterSection from 'components/albumList/letterSection.astro'
|
||||||
|
|
||||||
const letters: { letter: string; count: BigInt }[] = await prismaClient.$queryRaw`
|
const letters: { letter: string; count: BigInt }[] = await prismaClient.$queryRaw`
|
||||||
|
|
@ -40,7 +37,15 @@ const letters: { letter: string; count: BigInt }[] = await prismaClient.$queryRa
|
||||||
<div id={l.letter}>
|
<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 uppercase border-y-2 text-4xl justify-center border-white py-1.5'>{l.letter}</div>
|
||||||
<div class='my-4'>
|
<div class='my-4'>
|
||||||
<LetterSection letter={l.letter} />
|
<LetterSection letter={l.letter} server:defer>
|
||||||
|
<Fragment slot="fallback">
|
||||||
|
<div class='flex flex-col gap-y-2'>
|
||||||
|
{Array.from({ length: Number(l.count) }).map(() => (
|
||||||
|
<div class='animate-pulse h-3.5 w-lg bg-gray/85' />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Fragment>
|
||||||
|
</LetterSection>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
|
|
|
||||||
28
src/pages/anim/latest/[...page].astro
Normal file
28
src/pages/anim/latest/[...page].astro
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
import prismaClient from 'utils/prisma-client'
|
||||||
|
import * as m from 'paraglide/messages'
|
||||||
|
import { AlbumStatus } from '@prisma/client'
|
||||||
|
|
||||||
|
import PaginatedAlbumList from 'layouts/PaginatedAlbumList.astro'
|
||||||
|
|
||||||
|
const page = Math.min(1, parseInt(Astro.params.page ?? '1'))
|
||||||
|
const take = 40
|
||||||
|
const limitMD = 12
|
||||||
|
const limitXS = 5
|
||||||
|
|
||||||
|
const albums = await prismaClient.albums.findMany({
|
||||||
|
where: { status: AlbumStatus.SHOW, categories: { some: { categoryName: 'Animation' } } },
|
||||||
|
select: { id: true, title: true },
|
||||||
|
take,
|
||||||
|
skip: take * (page - 1),
|
||||||
|
orderBy: [{ releaseDate: 'desc' }, { publishedAt: 'desc' }, { createdAt: 'desc' }]
|
||||||
|
})
|
||||||
|
const count = await prismaClient.albums.count({ where: { status: AlbumStatus.SHOW } })
|
||||||
|
|
||||||
|
const fullPageList = [...Array(Math.ceil(count / take))].map((v, i) => i + 1)
|
||||||
|
const listProps = { fullPageList, page, albums, limitMD, limitXS }
|
||||||
|
---
|
||||||
|
|
||||||
|
<PaginatedAlbumList {...listProps}>
|
||||||
|
{m.latestAnimReleases()}
|
||||||
|
</PaginatedAlbumList>
|
||||||
28
src/pages/game/latest/[...page].astro
Normal file
28
src/pages/game/latest/[...page].astro
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
import prismaClient from 'utils/prisma-client'
|
||||||
|
import * as m from 'paraglide/messages'
|
||||||
|
import { AlbumStatus } from '@prisma/client'
|
||||||
|
|
||||||
|
import PaginatedAlbumList from 'layouts/PaginatedAlbumList.astro'
|
||||||
|
|
||||||
|
const page = Math.min(1, parseInt(Astro.params.page ?? '1'))
|
||||||
|
const take = 40
|
||||||
|
const limitMD = 12
|
||||||
|
const limitXS = 5
|
||||||
|
|
||||||
|
const albums = await prismaClient.albums.findMany({
|
||||||
|
where: { status: AlbumStatus.SHOW, categories: { some: { categoryName: 'Game' } } },
|
||||||
|
select: { id: true, title: true },
|
||||||
|
take,
|
||||||
|
skip: take * (page - 1),
|
||||||
|
orderBy: [{ releaseDate: 'desc' }, { publishedAt: 'desc' }, { createdAt: 'desc' }]
|
||||||
|
})
|
||||||
|
const count = await prismaClient.albums.count({ where: { status: AlbumStatus.SHOW } })
|
||||||
|
|
||||||
|
const fullPageList = [...Array(Math.ceil(count / take))].map((v, i) => i + 1)
|
||||||
|
const listProps = { fullPageList, page, albums, limitMD, limitXS }
|
||||||
|
---
|
||||||
|
|
||||||
|
<PaginatedAlbumList {...listProps}>
|
||||||
|
{m.latestGameReleases()}
|
||||||
|
</PaginatedAlbumList>
|
||||||
26
src/pages/holy12.astro
Normal file
26
src/pages/holy12.astro
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
import * as m from 'paraglide/messages'
|
||||||
|
|
||||||
|
import { getRandom } from 'utils/form'
|
||||||
|
import { getRandomAlbum } from 'utils/queries'
|
||||||
|
|
||||||
|
import Base from 'layouts/base.astro'
|
||||||
|
import AlbumBox from 'components/AlbumBox.astro'
|
||||||
|
|
||||||
|
const titles = [m.holy12_0(), m.holy12_1(), m.holy12_2(), m.holy12_3(), m.holy12_4(), m.holy12_5()]
|
||||||
|
const title = getRandom(titles)
|
||||||
|
const albums: { id: number; title: string }[] = await Promise.all(Array.from({ length: 12 }, getRandomAlbum))
|
||||||
|
---
|
||||||
|
|
||||||
|
<Base>
|
||||||
|
<div class='flex flex-col px-28'>
|
||||||
|
<h1 class='w-full uppercase font-medium tracking-wide text-4xl drop-shadow-2xl mt-5 mb-2 text-center'>{title}</h1>
|
||||||
|
<div class='grid grid-cols-2 md:grid-cols-4 gap-x-1.5 mb-4'>
|
||||||
|
{
|
||||||
|
albums.map((album) => (
|
||||||
|
<AlbumBox title={album.title} href={`/album/${album.id}`} image={`/album/${album.id}.png`} />
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Base>
|
||||||
|
|
@ -3,53 +3,26 @@ import prismaClient from 'utils/prisma-client'
|
||||||
import * as m from 'paraglide/messages'
|
import * as m from 'paraglide/messages'
|
||||||
import { AlbumStatus } from '@prisma/client'
|
import { AlbumStatus } from '@prisma/client'
|
||||||
|
|
||||||
import BaseLayout from 'layouts/base.astro'
|
import PaginatedAlbumList from 'layouts/PaginatedAlbumList.astro'
|
||||||
import AlbumBox from 'components/AlbumBox.astro'
|
|
||||||
import FooterNav from 'components/lastAdded/FooterNav.astro'
|
|
||||||
|
|
||||||
const page = parseInt(Astro.params.page ?? '1')
|
const page = Math.min(1, parseInt(Astro.params.page ?? '1'))
|
||||||
const take = 40
|
const take = 40
|
||||||
const limitMD = 12
|
const limitMD = 12
|
||||||
const limitXS = 5
|
const limitXS = 5
|
||||||
|
|
||||||
if (page < 1) {
|
const albums = await prismaClient.albums.findMany({
|
||||||
Astro.redirect('/last-added')
|
|
||||||
}
|
|
||||||
|
|
||||||
const lastAlbums = await prismaClient.albums.findMany({
|
|
||||||
where: { status: AlbumStatus.SHOW },
|
where: { status: AlbumStatus.SHOW },
|
||||||
select: { id: true, title: true },
|
select: { id: true, title: true },
|
||||||
take,
|
take,
|
||||||
skip: take * (page - 1),
|
skip: take * (page - 1),
|
||||||
orderBy: { createdAt: 'desc' }
|
orderBy: { publishedAt: 'desc' }
|
||||||
})
|
})
|
||||||
const count = await prismaClient.albums.count({ where: { status: AlbumStatus.SHOW } })
|
const count = await prismaClient.albums.count({ where: { status: AlbumStatus.SHOW } })
|
||||||
|
|
||||||
if (lastAlbums.length === 0) {
|
|
||||||
Astro.redirect('/404')
|
|
||||||
}
|
|
||||||
|
|
||||||
const fullPageList = [...Array(Math.ceil(count / take))].map((v, i) => i + 1)
|
const fullPageList = [...Array(Math.ceil(count / take))].map((v, i) => i + 1)
|
||||||
const listProps = { fullPageList, page }
|
const listProps = { fullPageList, page, albums, limitMD, limitXS }
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout>
|
<PaginatedAlbumList {...listProps}>
|
||||||
<div class='w-full min-h-100vh mx-auto max-w-[1440px]'>
|
{m.lastAdded()}
|
||||||
<div class='px-2 mb-2'>
|
</PaginatedAlbumList>
|
||||||
<h1 class='uppercase font-medium tracking-wide text-5xl drop-shadow-2xl mt-5 mb-2 text-center'>
|
|
||||||
{m.lastAdded()}
|
|
||||||
</h1>
|
|
||||||
<div class='grid grid-cols-2 md:grid-cols-4 gap-x-1.5'>
|
|
||||||
{
|
|
||||||
lastAlbums.map((album) => (
|
|
||||||
<AlbumBox title={album.title} href={`/album/${album.id}`} image={`/album/${album.id}.png`} />
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<nav class='bg-dark p-2'>
|
|
||||||
<FooterNav class='flex md:hidden' pageLimit={limitXS} {...listProps} />
|
|
||||||
<FooterNav class='hidden md:flex' pageLimit={limitMD} {...listProps} />
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</BaseLayout>
|
|
||||||
|
|
|
||||||
18
src/utils/queries.ts
Normal file
18
src/utils/queries.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
import prismaClient from './prisma-client'
|
||||||
|
|
||||||
|
export async function getRandomAlbum(): Promise<{ id: number; title: string }> {
|
||||||
|
const res: { id: number; title: string }[] = await prismaClient.$queryRawUnsafe(`
|
||||||
|
SELECT r1.id as id, r1.title as title
|
||||||
|
FROM albums AS r1 JOIN (
|
||||||
|
SELECT (
|
||||||
|
RAND() * (
|
||||||
|
SELECT MAX(id) FROM albums
|
||||||
|
)
|
||||||
|
) AS id
|
||||||
|
) AS r2
|
||||||
|
WHERE r1.id >= r2.id
|
||||||
|
ORDER BY r1.id ASC
|
||||||
|
LIMIT 1;`)
|
||||||
|
|
||||||
|
return res[0]
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue