Merge branch 'main' into better-documents
This commit is contained in:
commit
5bfcf96987
9 changed files with 122 additions and 49 deletions
|
@ -5,6 +5,7 @@ import { Zilla_Slab } from 'next/font/google'
|
|||
import { notFound } from 'next/navigation'
|
||||
import DocumentCard from '@/app/components/DocumentCard'
|
||||
import findDocumentsByAuthor from './findDocumentsByAuthor'
|
||||
import cardEffects from '@/app/styles/cardEffects.module.css'
|
||||
|
||||
const zillaSlab = Zilla_Slab({ subsets: ['latin'], weight: ['500'] })
|
||||
|
||||
|
@ -41,11 +42,15 @@ export default function AuthorDisplay({
|
|||
) : null}
|
||||
<div className='my-4 max-h-12 flex flex-wrap gap-2'>
|
||||
{affiliation.map((a: string) => (
|
||||
<Link key={a} href={`/affiliation/${a.split('@')[1]}`}>
|
||||
<Link
|
||||
key={a}
|
||||
href={`/affiliation/${a.split('@')[1]}`}
|
||||
className={cardEffects['card-small']}
|
||||
>
|
||||
<img
|
||||
src={affiliations[a.split('@')[1]].image}
|
||||
alt={affiliations[a.split('@')[1]].name}
|
||||
className='h-12 shadow-sm shadow-slate-400 rounded-md'
|
||||
className='h-12 rounded-md'
|
||||
/>
|
||||
</Link>
|
||||
))}
|
||||
|
|
|
@ -14,7 +14,7 @@ const DocumentCard = ({ doc, href }: { doc: Document; href: string }) => {
|
|||
return (
|
||||
<Link href={href} className='no-link-style'>
|
||||
<div
|
||||
className={`${cardEffects.card} border-4 rounded-lg border-gray-300 hover:border-blue-500 p-5 my-4 w-full cursor-pointer shadow-slate-300 shadow-md`}
|
||||
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`}
|
||||
role='button' // this is a critical DEI concern as we have marked this element as a button with ARIA role, yet we have not supported button accessiblity features
|
||||
>
|
||||
<h2 className={`${zillaSlab.className} text-3xl`}>{title}</h2>
|
||||
|
|
|
@ -31,19 +31,21 @@ export default function MobileMenu() {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className='w-20'>
|
||||
<button
|
||||
className='p-2 rounded-xl hover:bg-blue-400'
|
||||
onClick={handleClick}
|
||||
>
|
||||
<RxHamburgerMenu size={40} />
|
||||
</button>
|
||||
<>
|
||||
<div className='w-20'>
|
||||
<button
|
||||
className='p-2 rounded-xl hover:bg-blue-400'
|
||||
onClick={handleClick}
|
||||
>
|
||||
<RxHamburgerMenu size={40} />
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className={`${isOpen ? '' : styles['menu-hidden']} ${styles.menu} shadow-md shadow-slate-300`}
|
||||
>
|
||||
<span className={styles['search-bar']}>
|
||||
<div className={styles['search-bar']}>
|
||||
<SearchBar onSubmit={handleSubmit} />
|
||||
</span>
|
||||
</div>
|
||||
<p className='text-slate-600 mx-4 my-4'>
|
||||
We gratefully acknowledge support from our volunteer peer reviewers,
|
||||
member institutions, and all{' '}
|
||||
|
@ -56,6 +58,6 @@ export default function MobileMenu() {
|
|||
.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -25,10 +25,10 @@ export default function SearchBar({
|
|||
}
|
||||
|
||||
return (
|
||||
<div className='w-full flex flex-nowrap'>
|
||||
<div className='mx-2 flex flex-nowrap gap-2'>
|
||||
<input
|
||||
type='text'
|
||||
className='py-3 px-5 rounded-xl text-slate-800 flex-grow'
|
||||
className='py-3 px-5 rounded-xl text-slate-800 flex-grow flex-shrink min-w-0'
|
||||
name='q'
|
||||
placeholder='Search...'
|
||||
onChange={handleInputChange}
|
||||
|
@ -37,7 +37,7 @@ export default function SearchBar({
|
|||
/>
|
||||
<button
|
||||
type='submit'
|
||||
className='p-2.5 mx-4 border-2 rounded-xl hover:bg-blue-300 flex-shrink'
|
||||
className='p-2.5 border-2 rounded-xl hover:bg-blue-300 flex-shrink'
|
||||
onClick={handleClick}
|
||||
>
|
||||
Search
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
.menu {
|
||||
@apply overflow-hidden left-[0] top-[235px] z-10 absolute bg-slate-200;
|
||||
@apply duration-300;
|
||||
height: fit-content;
|
||||
padding-bottom: 10px;
|
||||
@apply overflow-hidden top-[235px] z-10 absolute bg-slate-200;
|
||||
height: 180px;
|
||||
transition: height 0.2s ease-in-out;
|
||||
width: 100vw;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
@apply w-full flex justify-center z-10 px-4 py-2 bg-slate-300;
|
||||
@apply z-10 mt-2 mx-[2px] sm:m-2;
|
||||
}
|
||||
|
||||
.search-bar button {
|
||||
|
@ -18,5 +16,4 @@
|
|||
|
||||
.menu-hidden {
|
||||
height: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
|
|
@ -415,7 +415,7 @@ export const authors: Readonly<{ [key: string]: Author }> = {
|
|||
'Student@srvhs',
|
||||
],
|
||||
image: '/img/profiles/wlin.jpg',
|
||||
nationality: ['twn', 'chn', 'usa'],
|
||||
nationality: ['twn', 'chn', 'jpn', 'usa'],
|
||||
formerAffiliations: ['Intern@raid-zero'],
|
||||
bio: 'Hi, I am Kaito or Warren. I am a Self-taught programmer and engineer. I go around doing dumb things such as my projects. I have a dream of building a community. I am currently part of many projects.',
|
||||
website: 'https://kaitotlex.carrd.co/',
|
||||
|
@ -442,7 +442,7 @@ export const authors: Readonly<{ [key: string]: Author }> = {
|
|||
'Mentor@team-1280',
|
||||
],
|
||||
formerAffiliations: ['Captain@team-1280', 'Student@srvhs'],
|
||||
nationality: ['usa'],
|
||||
nationality: ['irl', 'usa'],
|
||||
image: '/img/profiles/edanko.jpg',
|
||||
},
|
||||
arvenkatesh: {
|
||||
|
@ -742,6 +742,11 @@ export const nationalities: Readonly<{ [key: string]: Nationality }> = {
|
|||
demonym: 'Filipino',
|
||||
flag: 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/99/Flag_of_the_Philippines.svg/2880px-Flag_of_the_Philippines.svg.png',
|
||||
},
|
||||
irl: {
|
||||
name: 'Republic of Ireland',
|
||||
demonym: 'Irish',
|
||||
flag: 'https://upload.wikimedia.org/wikipedia/commons/4/45/Flag_of_Ireland.svg',
|
||||
},
|
||||
unknown: {
|
||||
name: 'Undetermined',
|
||||
demonym: 'Undetermined',
|
||||
|
|
|
@ -1,28 +1,65 @@
|
|||
import Link from 'next/link'
|
||||
import { documents, authors, affiliations } from './db/data'
|
||||
import { documents, authors, affiliations, Author } from './db/data'
|
||||
import News from './components/News'
|
||||
import RandomDocs from './components/RandomDocs'
|
||||
import RecentDocuments from './components/RecentDocuments'
|
||||
|
||||
function sortAuthorsByDocumentsPublished(authors: {
|
||||
[key: string]: Author
|
||||
}): { id: string; author: Author }[] {
|
||||
// Initialize a map to count documents for each author
|
||||
const authorDocumentCount: { [key: string]: number } = {}
|
||||
|
||||
// Iterate over documents to count the number for each author
|
||||
Object.values(documents).forEach((document) => {
|
||||
document.manifest.authors.forEach((authorId) => {
|
||||
if (authorDocumentCount[authorId]) {
|
||||
authorDocumentCount[authorId] += 1
|
||||
} else {
|
||||
authorDocumentCount[authorId] = 1
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// Convert the authors object into an array of objects including the author ID
|
||||
const authorsWithId = Object.keys(authors).map((id) => ({
|
||||
id,
|
||||
author: authors[id],
|
||||
count: authorDocumentCount[id] || 0, // Include the count for sorting
|
||||
}))
|
||||
|
||||
// Sort authors by their document count in descending order
|
||||
authorsWithId.sort((a, b) => b.count - a.count)
|
||||
|
||||
// Return the sorted array, excluding the count property
|
||||
return authorsWithId.map(({ id, author }) => ({ id, author }))
|
||||
}
|
||||
|
||||
export default function Home() {
|
||||
const AuthorDisplay = () => {
|
||||
return Object.entries(authors).map(([author, data], index) => {
|
||||
let affiliationSlug = data.affiliation[0].split('@')[1]
|
||||
let affiliation = affiliations[affiliationSlug]
|
||||
return (
|
||||
<div key={author}>
|
||||
<Link href={`/author/${author}`}>
|
||||
{data.name.first}
|
||||
{data.name.nickname ? ` "${data.name.nickname}" ` : ' '}
|
||||
{data.name.last}
|
||||
</Link>{' '}
|
||||
of{' '}
|
||||
<Link href={`/affiliation/${affiliationSlug}`}>
|
||||
{affiliation.short}
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
return (
|
||||
<ol className='list-decimal pl-4 space-y-2'>
|
||||
{sortAuthorsByDocumentsPublished(authors).map(({ id, author }) => {
|
||||
let data = author
|
||||
|
||||
let affiliationSlug = data.affiliation[0].split('@')[1]
|
||||
let affiliation = affiliations[affiliationSlug]
|
||||
return (
|
||||
<li key={id}>
|
||||
<Link href={`/author/${id}`}>
|
||||
{data.name.first}
|
||||
{data.name.nickname ? ` "${data.name.nickname}" ` : ' '}
|
||||
{data.name.last}
|
||||
</Link>{' '}
|
||||
of{' '}
|
||||
<Link href={`/affiliation/${affiliationSlug}`}>
|
||||
{affiliation.short}
|
||||
</Link>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ol>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -58,7 +95,7 @@ export default function Home() {
|
|||
<hr className='mx-auto w-full h-1 border-0 bg-slate-200 my-2 rounded-md' />
|
||||
<br />
|
||||
<div className='font-serif text-xl'>
|
||||
Our esteemed faculty and alumni
|
||||
Our esteemed faculty and alumni (ranked by research output)
|
||||
</div>
|
||||
<AuthorDisplay />
|
||||
</div>
|
||||
|
|
|
@ -42,7 +42,7 @@ const SearchResult = ({
|
|||
|
||||
return (
|
||||
<div
|
||||
className={`${cardEffects.card} border-4 rounded-lg border-gray-300 hover:border-blue-500 p-5 my-4 w-full cursor-pointer`}
|
||||
className={`${cardEffects['card-large']} border-4 rounded-lg border-gray-300 hover:border-blue-500 p-5 my-4 w-full cursor-pointer`}
|
||||
onClick={handleClick}
|
||||
role='button' // this is a critical DEI concern as we have marked this element as a button with ARIA role, yet we have not supported button accessiblity features
|
||||
>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/* creates a 3D card effect using a pseudo element for performance reasons */
|
||||
|
||||
.card {
|
||||
.card-large {
|
||||
@apply shadow-sm shadow-slate-300;
|
||||
/* box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); */
|
||||
transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
|
||||
position: relative;
|
||||
}
|
||||
.card::after {
|
||||
.card-large::after {
|
||||
@apply shadow-lg shadow-slate-500;
|
||||
content: '';
|
||||
z-index: -1;
|
||||
|
@ -19,10 +19,37 @@
|
|||
left: 0;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
.card-large:hover {
|
||||
transform: scale(1.02, 1.02);
|
||||
}
|
||||
|
||||
.card:hover::after {
|
||||
.card-large:hover::after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.card-small {
|
||||
@apply shadow-sm shadow-slate-300;
|
||||
/* box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); */
|
||||
transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
|
||||
position: relative;
|
||||
}
|
||||
.card-small::after {
|
||||
@apply shadow-md shadow-slate-500;
|
||||
content: '';
|
||||
z-index: -1;
|
||||
transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.card-small:hover {
|
||||
transform: scale(1.08, 1.08);
|
||||
}
|
||||
|
||||
.card-small:hover::after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue