178 lines
5.8 KiB
TypeScript
178 lines
5.8 KiB
TypeScript
import { headers as getHeaders } from 'next/headers.js'
|
|
import { getPayload, PaginatedDocs } from 'payload'
|
|
import config from '@/payload.config'
|
|
import React from 'react'
|
|
|
|
import UserFeed from '@/components/Feed/UserFeed'
|
|
import { Book, Checkout, Repository } from '@/payload-types'
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
|
import { TextShimmer } from '@/components/ui/text-shimmer'
|
|
import { LoginForm } from '@/components/login-form'
|
|
import SearchBooks from '@/components/Search/SearchBooks'
|
|
import Manage from '@/components/Manage/Manage'
|
|
|
|
export default async function HomePage() {
|
|
const headers = await getHeaders()
|
|
const payloadConfig = await config
|
|
const payload = await getPayload({ config: payloadConfig })
|
|
const { user } = await payload.auth({ headers })
|
|
|
|
const initBrowseBooks = (await payload.find({
|
|
collection: 'books',
|
|
depth: 10,
|
|
limit: 25,
|
|
overrideAccess: false,
|
|
select: {
|
|
title: true,
|
|
authors: true,
|
|
publication: true,
|
|
lcc: true,
|
|
genre: true,
|
|
isbn: true,
|
|
copies: true,
|
|
},
|
|
})) as PaginatedDocs<Book>
|
|
|
|
let userRepos: PaginatedDocs<Repository> | null = null
|
|
if (user?.id)
|
|
userRepos = (await payload.find({
|
|
collection: 'repositories',
|
|
depth: 3,
|
|
limit: 10,
|
|
select: {
|
|
name: true,
|
|
abbreviation: true,
|
|
image: true,
|
|
description: true,
|
|
dateOpenToPublic: true,
|
|
holdRequests: true,
|
|
},
|
|
where: {
|
|
'owner.id': {
|
|
equals: user.id,
|
|
},
|
|
},
|
|
joins: {
|
|
holdRequests: {
|
|
limit: 100,
|
|
},
|
|
},
|
|
})) as PaginatedDocs<Repository>
|
|
|
|
let userCheckouts: PaginatedDocs<Checkout> | null = null
|
|
if (user?.id)
|
|
userCheckouts = await payload.find({
|
|
collection: 'checkouts',
|
|
depth: 3,
|
|
limit: 10,
|
|
select: {
|
|
id: true,
|
|
copy: true,
|
|
dateDue: true,
|
|
},
|
|
sort: 'dateDue',
|
|
where: {
|
|
and: [
|
|
{
|
|
isReturned: {
|
|
not_equals: true,
|
|
},
|
|
},
|
|
{
|
|
'user.id': {
|
|
equals: user.id,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
})
|
|
|
|
return (
|
|
<div className="home">
|
|
<div className="relative isolate overflow-hidden py-24 sm:py-32 rounded-md">
|
|
<img
|
|
alt=""
|
|
src="/api/media/file/geniza1.jpg"
|
|
className="absolute inset-0 -z-10 size-full object-cover"
|
|
/>
|
|
|
|
<div
|
|
aria-hidden="true"
|
|
className="hidden sm:absolute sm:-top-10 sm:right-1/2 sm:-z-10 sm:mr-10 sm:block sm:transform-gpu sm:blur-3xl"
|
|
>
|
|
<div
|
|
style={{
|
|
clipPath:
|
|
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
|
|
}}
|
|
className="aspect-1097/845 w-[78.5625rem] bg-linear-to-tr from-accent-background to-background opacity-100"
|
|
/>
|
|
</div>
|
|
|
|
<div
|
|
aria-hidden="true"
|
|
className="absolute -top-52 left-1/2 -z-10 -translate-x-1/2 transform-gpu blur-3xl sm:top-[-28rem] sm:ml-16 sm:translate-x-0 sm:transform-gpu"
|
|
>
|
|
<div
|
|
style={{
|
|
clipPath:
|
|
'polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)',
|
|
}}
|
|
className="aspect-1097/845 w-[78.5625rem] bg-linear-to-tr from-background bg-background"
|
|
/>
|
|
</div>
|
|
|
|
<div className="mx-auto max-w-7xl px-6 lg:px-8 ">
|
|
<div className="mx-auto max-w-2xl lg:mx-0">
|
|
<p className="text-base/7 font-semibold text-foreground">Temple Beth-El Beit Midrash</p>
|
|
|
|
<h2 className="mt-2 text-5xl font-semibold tracking-tight text-foreground sm:text-7xl text-shadow-lg">
|
|
<TextShimmer
|
|
duration={2.2}
|
|
className="[--base-color:var(--color-emerald-700)] [--base-gradient-color:var(--color-white)] dark:[--base-color:var(--color-emerald-600)] dark:[--base-gradient-color:var(--color-white)]"
|
|
>
|
|
Welcome
|
|
</TextShimmer>
|
|
<span className="text-shadow-lg text-shadow-background">
|
|
{user ? <small>{user.firstName}</small> : <small>In</small>}
|
|
</span>
|
|
</h2>
|
|
<div className="mt-8 text-lg font-normal text-pretty text-foreground text-shadow-lg text-shadow-background sm:text-xl/8">
|
|
<p className="indent-5 italic">
|
|
Never refuse to lend books to anyone who cannot afford to purchase them, but lend
|
|
books only to those who can be trusted to return them.
|
|
</p>
|
|
|
|
<small className="block text-right">- ibn Tibbon</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{user ? (
|
|
<Tabs defaultValue="feed" className="p-4">
|
|
<TabsList className="grid w-full grid-cols-3">
|
|
<TabsTrigger value="feed">Your Feed</TabsTrigger>
|
|
<TabsTrigger value="search">Search</TabsTrigger>
|
|
<TabsTrigger value="manage">Manage</TabsTrigger>
|
|
</TabsList>
|
|
|
|
<TabsContent value="feed">{user && <UserFeed user={user} />}</TabsContent>
|
|
|
|
<TabsContent value="search">
|
|
<SearchBooks initBrowseBooks={initBrowseBooks} />
|
|
</TabsContent>
|
|
|
|
<TabsContent value="manage">
|
|
<Manage repos={userRepos} checkouts={userCheckouts} />
|
|
</TabsContent>
|
|
</Tabs>
|
|
) : (
|
|
<div className="flex w-full max-w-sm flex-col gap-6 mx-auto my-6">
|
|
<LoginForm />
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|