feat: add author list page
- Added a new function `generateStaticParams()` to generate static parameters for each author. - Created a new component `AuthorCard` to display information about an author. - Updated the `Page` component to render a grid of `AuthorCard` components for each author. - Added styling for the author cards using CSS modules.
This commit is contained in:
parent
37128f52c0
commit
354d5b2b91
1 changed files with 83 additions and 0 deletions
83
src/app/author/page.tsx
Normal file
83
src/app/author/page.tsx
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
import { authors, affiliations } from '@/app/db/data'
|
||||||
|
import { notFound } from 'next/navigation'
|
||||||
|
import { Zilla_Slab } from 'next/font/google'
|
||||||
|
import { Fragment } from 'react'
|
||||||
|
import Image from 'next/image'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import cardEffects from '@/app/styles/cardEffects.module.css'
|
||||||
|
|
||||||
|
const zillaSlab = Zilla_Slab({ subsets: ['latin'], weight: ['500'] })
|
||||||
|
|
||||||
|
export function generateStaticParams() {
|
||||||
|
const authorsList = Object.keys(authors)
|
||||||
|
return authorsList.map((shortName) => ({ shortName }))
|
||||||
|
}
|
||||||
|
|
||||||
|
const AuthorCard = ({
|
||||||
|
params,
|
||||||
|
}: Readonly<{ params: { shortName: string } }>) => {
|
||||||
|
const { shortName } = params
|
||||||
|
const { name, image, affiliation } = authors[shortName]
|
||||||
|
if (!name) {
|
||||||
|
notFound()
|
||||||
|
}
|
||||||
|
|
||||||
|
const mainAffiliationShort = affiliation[0].split('@')[1]
|
||||||
|
const mainPosition = affiliation[0].split('@')[0]
|
||||||
|
const mainAffiliation = affiliations[mainAffiliationShort]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
className={`${cardEffects['card-large']} border-4 rounded-lg border-gray-300 hover:border-blue-500 p-5 my-4 w-full cursor-pointer shadow-slate-300 shadow-md text-left m-4 no-link-style pb-8`}
|
||||||
|
href={`/author/${shortName}`}
|
||||||
|
>
|
||||||
|
<div className='grid grid-cols-1 max-w-3xl mx-auto'>
|
||||||
|
<div className='mx-auto mb-4 max-w-3xl md:w-auto md:h-[40vw] lg:h-[20vw] rounded-lg'>
|
||||||
|
<Image
|
||||||
|
alt='profile'
|
||||||
|
width={1000}
|
||||||
|
height={1000}
|
||||||
|
className='rounded-lg mx-auto p-8 object-contain w-full h-full'
|
||||||
|
src={image}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<span
|
||||||
|
className={`${zillaSlab.className} font-bold text-4xl text-center`}
|
||||||
|
>
|
||||||
|
{name.first} {name.last}
|
||||||
|
</span>
|
||||||
|
<div className='text-slate-600 text-lg mt-4 text-center'>
|
||||||
|
{mainPosition} at{' '}
|
||||||
|
<Link href={`/affiliation/${mainAffiliationShort}`}>
|
||||||
|
{mainAffiliation.name}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const Page = () => {
|
||||||
|
return (
|
||||||
|
<div className='p-6'>
|
||||||
|
<h1 className={`${zillaSlab.className} text-6xl text-center mb-10`}>
|
||||||
|
Affiliations
|
||||||
|
</h1>
|
||||||
|
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4'>
|
||||||
|
{Object.keys(authors).map((authorShortName) => {
|
||||||
|
return (
|
||||||
|
<Fragment key={authorShortName}>
|
||||||
|
<AuthorCard
|
||||||
|
key={authorShortName}
|
||||||
|
params={{ shortName: authorShortName }}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Page
|
Loading…
Reference in a new issue