remove static site generation and change some styling

also added references
This commit is contained in:
Youwen Wu 2024-02-11 16:52:59 -08:00
parent aa84c011f5
commit 4dc677d945
10 changed files with 257 additions and 91 deletions

View file

@ -1,7 +1,5 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
output: 'export',
basePath: '/eexiv-2',
images: { images: {
unoptimized: true, unoptimized: true,
}, },

View file

@ -1,7 +1,7 @@
import styles from './loading.module.css' import styles from './loading.module.css'
const LoadingBar = () => { const LoadingBar = () => {
return ( return (
<div className='w-full absolute top-0 left-0'> <div className='w-full fixed top-0 left-0'>
<div className='h-1.5 w-full bg-pink-100 overflow-hidden'> <div className='h-1.5 w-full bg-pink-100 overflow-hidden'>
<div <div
className={`${styles.progress} w-full h-full bg-blue-500 ${styles['left-right']}`} className={`${styles.progress} w-full h-full bg-blue-500 ${styles['left-right']}`}

View file

@ -1,26 +1,15 @@
import styles from './container.module.css' import styles from './container.module.css'
/** /**
* Renders a container component with the specified width, containing the provided children. * Renders a container component with the specified width, containing the provided children.
* *
* @param children - The children to be rendered within the container. * @param children - The children to be rendered within the container.
* @param width - The width of the container.
* @param fill - Whether the container should fill the available height
* @return The container component with the specified width and children. * @return The container component with the specified width and children.
*/ */
export default function Container({ export default function Container({
children, children,
width, }: Readonly<{ children: React.ReactNode }>) {
fill,
}: Readonly<{ children: React.ReactNode; width: string; fill?: boolean }>) {
return ( return (
<div <div className={`${styles.container} pb-10 px-5 max-w-[1200px] mx-auto`}>
className={styles.container}
style={{
maxWidth: width,
minHeight: fill ? 'calc(100vh - 450px' : 'auto',
}}
>
{children} {children}
</div> </div>
) )

View file

@ -1,5 +1,3 @@
.container { .container {
margin: 0 auto; min-height: calc(100vh - 400px);
padding: 0 20px;
margin-bottom: 30px;
} }

View file

@ -17,6 +17,12 @@ documents {
file: pdf | docx | pptx | targz | other, named file[rev].[ext] file: pdf | docx | pptx | targz | other, named file[rev].[ext]
(eg. revision 1 = file1.pdf, revision 2 = file2.pdf, etc) (eg. revision 1 = file1.pdf, revision 2 = file2.pdf, etc)
the "latest" should be the latest revision the "latest" should be the latest revision
citation: a string that can be used to cite the document
reviewers: an array of reviewers, following the reviewer format. if you specify a local
profile username, it will link to the author's profile, and take priority over the link
status: draft | under review | reviewed | published no review
note: published no review should be used for documents where peer review
is not appropriate or unnecessary
} }
} }
*/ */
@ -28,6 +34,18 @@ export type DocumentType =
| 'dwm' | 'dwm'
| 'datasheet' | 'datasheet'
| 'other' | 'other'
export type reviewer = {
first: string
last: string
profile?: string
url?: string
}
export type DocumentStatus =
| 'draft'
| 'under review'
| 'reviewed'
| 'published no review'
export interface DocumentDB { export interface DocumentDB {
[key: string]: { [key: string]: {
manifest: { manifest: {
@ -40,9 +58,12 @@ export interface DocumentDB {
type: DocumentType type: DocumentType
latest: number latest: number
keywords?: string[] keywords?: string[]
status: DocumentStatus
reviewers?: reviewer[]
} }
abstract: string abstract: string
file: FileType file: FileType
citation?: string
} }
} }
export const documents: DocumentDB = { export const documents: DocumentDB = {
@ -61,6 +82,7 @@ export const documents: DocumentDB = {
'driven torque', 'driven torque',
'power', 'power',
], ],
status: 'published no review',
}, },
abstract: abstract:
'This guide to mechanical engineering covers gears and gear ratios, gear types, gear diagrams and measurements and sprockets and chains. It also introduces a discussion of power in the context of gears and mechanical engineering specific to FRC robotics.', 'This guide to mechanical engineering covers gears and gear ratios, gear types, gear diagrams and measurements and sprockets and chains. It also introduces a discussion of power in the context of gears and mechanical engineering specific to FRC robotics.',
@ -102,6 +124,7 @@ export const documents: DocumentDB = {
'https://github.com/Team-1280/Jankboard', 'https://github.com/Team-1280/Jankboard',
'https://github.com/Team-1280/identity', 'https://github.com/Team-1280/identity',
], ],
status: 'published no review',
}, },
abstract: abstract:
'This document outlines the first two weeks of prototyping conducted by the EECS subteam for Team 1280. Action items are presented in a doing/working/moving format to keep track of new developments related to EECS projects.', 'This document outlines the first two weeks of prototyping conducted by the EECS subteam for Team 1280. Action items are presented in a doing/working/moving format to keep track of new developments related to EECS projects.',
@ -140,6 +163,8 @@ export const documents: DocumentDB = {
code: ['https://github.com/Team-1280/DeepBozo'], code: ['https://github.com/Team-1280/DeepBozo'],
type: 'report', type: 'report',
latest: 1, latest: 1,
status: 'reviewed',
reviewers: [{ first: 'Youwen', last: 'Wu', profile: 'ywu' }],
}, },
file: 'pdf', file: 'pdf',
abstract: abstract:
@ -178,6 +203,12 @@ export const documents: DocumentDB = {
type: 'report', type: 'report',
topics: ['frc', 'eecs', 'econ'], topics: ['frc', 'eecs', 'econ'],
latest: 1, latest: 1,
status: 'reviewed',
reviewers: [
{ first: 'Youwen', last: 'Wu', profile: 'ywu' },
{ first: 'Youwen', last: 'Wu', profile: 'ywu' },
{ first: 'Youwen', last: 'Wu', profile: 'ywu' },
],
}, },
abstract: abstract:
'The toughbook is a rugged, industrial computer intended for low-performance, scalable, and cheap computational operations. The robotics storage cabinet contained a Lenovo ThinkPad toughbook which was, at the time of its discovery, severely damaged, both internally (software) and externally (hardware). The programming team invested significant time, energy, resources, and capital into the revival of this storied piece of digital infrastructure, thus restoring the ThinkPad and, by extension, the robotics team, to its former glory.', 'The toughbook is a rugged, industrial computer intended for low-performance, scalable, and cheap computational operations. The robotics storage cabinet contained a Lenovo ThinkPad toughbook which was, at the time of its discovery, severely damaged, both internally (software) and externally (hardware). The programming team invested significant time, energy, resources, and capital into the revival of this storied piece of digital infrastructure, thus restoring the ThinkPad and, by extension, the robotics team, to its former glory.',
@ -272,7 +303,7 @@ export const authors: Authors = {
}, },
affiliation: ['Undergraduate@usc-viterbi'], affiliation: ['Undergraduate@usc-viterbi'],
formerAffiliations: ['Lead Mechanical Engineer@1280-mech', 'Student@srvhs'], formerAffiliations: ['Lead Mechanical Engineer@1280-mech', 'Student@srvhs'],
image: '/eexiv-2/img/profiles/shasan.jpg', image: '/img/profiles/shasan.jpg',
nationality: ['pak', 'usa'], nationality: ['pak', 'usa'],
}, },
mbohsali: { mbohsali: {
@ -281,7 +312,7 @@ export const authors: Authors = {
last: 'Bohsali', last: 'Bohsali',
}, },
affiliation: ['Lead Programming Engineer@1280-eecs', 'Student@srvhs'], affiliation: ['Lead Programming Engineer@1280-eecs', 'Student@srvhs'],
image: '/eexiv-2/img/profiles/default.png', image: '/img/profiles/default.png',
nationality: ['lbn', 'usa'], nationality: ['lbn', 'usa'],
}, },
avenkatesh: { avenkatesh: {
@ -291,7 +322,7 @@ export const authors: Authors = {
}, },
affiliation: ['Lead Controls Engineer@1280-eecs'], affiliation: ['Lead Controls Engineer@1280-eecs'],
formerAffiliations: ['Programming Lead@1280-programming'], formerAffiliations: ['Programming Lead@1280-programming'],
image: '/eexiv-2/img/profiles/avenkatesh.png', image: '/img/profiles/avenkatesh.png',
nationality: ['ind', 'eth', 'usa'], nationality: ['ind', 'eth', 'usa'],
bio: 'The king of jank.', bio: 'The king of jank.',
website: 'https://github.com/quantum9Innovation', website: 'https://github.com/quantum9Innovation',
@ -302,7 +333,7 @@ export const authors: Authors = {
last: 'Wu', last: 'Wu',
}, },
affiliation: ['Artificial Intelligence Lead@1280-eecs'], affiliation: ['Artificial Intelligence Lead@1280-eecs'],
image: '/eexiv-2/img/profiles/ywu.webp', image: '/img/profiles/ywu.webp',
nationality: ['chn'], nationality: ['chn'],
bio: 'The kingpin of jank. Never before has so much jank been so distilled in one place.', bio: 'The kingpin of jank. Never before has so much jank been so distilled in one place.',
website: 'https://github.com/couscousdude', website: 'https://github.com/couscousdude',
@ -318,7 +349,7 @@ export const authors: Authors = {
'General Affairs@1280-business', 'General Affairs@1280-business',
'Student@srvhs', 'Student@srvhs',
], ],
image: '/eexiv-2/img/profiles/wlin.jpg', image: '/img/profiles/wlin.jpg',
nationality: ['twn', 'chn', 'usa'], nationality: ['twn', 'chn', 'usa'],
formerAffiliations: ['Intern@raid-zero'], 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.', 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.',
@ -330,7 +361,7 @@ export const authors: Authors = {
last: 'Ostler', last: 'Ostler',
}, },
affiliation: ['Vision Researcher@1280-eecs', 'Student@srvhs'], affiliation: ['Vision Researcher@1280-eecs', 'Student@srvhs'],
image: '/eexiv-2/img/profiles/gostler.jpg', image: '/img/profiles/gostler.jpg',
nationality: ['usa'], nationality: ['usa'],
website: 'https://github.com/gavinostler', website: 'https://github.com/gavinostler',
bio: `I'm Gavin, a high school student from the Bay Area. I am a fullstack developer and love making random things to fill my day. I'm interested in creating useful tools and software in the future.`, bio: `I'm Gavin, a high school student from the Bay Area. I am a fullstack developer and love making random things to fill my day. I'm interested in creating useful tools and software in the future.`,
@ -350,7 +381,7 @@ export const affiliations: Affiliations = {
'1280-mech': { '1280-mech': {
name: "Team 1280, the Ragin' C Biscuits, Mechanical Subteam", name: "Team 1280, the Ragin' C Biscuits, Mechanical Subteam",
short: '1280 Mech', short: '1280 Mech',
image: '/eexiv-2/img/logos/1280-main.png', image: '/img/logos/1280-main.png',
description: `The mechanical subteam is the backbone of Team 1280, focusing on the physical design, construction, and mechanical integrity of their robots. This subteam is where concepts and designs become tangible, transforming ideas into the moving parts and structural components that give the robots their form and function. The Mechanical subteam's work encompasses a broad range of activities, from drafting initial sketches and CAD modeling to machining parts and assembling complex mechanical systems. description: `The mechanical subteam is the backbone of Team 1280, focusing on the physical design, construction, and mechanical integrity of their robots. This subteam is where concepts and designs become tangible, transforming ideas into the moving parts and structural components that give the robots their form and function. The Mechanical subteam's work encompasses a broad range of activities, from drafting initial sketches and CAD modeling to machining parts and assembling complex mechanical systems.
[linebreak] [linebreak]
Members of the Mechanical subteam are adept in applying principles of mechanical engineering to solve practical problems, ensuring that the robot is not only capable of performing the tasks required by the competition but is also robust, efficient, and adaptable to the dynamic environment of a FIRST Robotics match. They work closely with materials, tools, and manufacturing processes, gaining hands-on experience in fabrication techniques such as welding, 3D printing, and CNC machining. Members of the Mechanical subteam are adept in applying principles of mechanical engineering to solve practical problems, ensuring that the robot is not only capable of performing the tasks required by the competition but is also robust, efficient, and adaptable to the dynamic environment of a FIRST Robotics match. They work closely with materials, tools, and manufacturing processes, gaining hands-on experience in fabrication techniques such as welding, 3D printing, and CNC machining.
@ -362,7 +393,7 @@ The Mechanical subteam fosters a culture of creativity, innovation, and excellen
'1280-eecs': { '1280-eecs': {
name: "Team 1280, the Ragin' C Biscuits, Electrical Engineering and Computer Science Subteam", name: "Team 1280, the Ragin' C Biscuits, Electrical Engineering and Computer Science Subteam",
short: '1280 EECS', short: '1280 EECS',
image: '/eexiv-2/img/logos/eecs-wordmark.png', image: '/img/logos/eecs-wordmark.png',
description: `The Team 1280 EECS (Electrical Engineering and Computer Science) subteam is an autonomous organization within Team 1280, specializing in the design, programming, and electrical systems that bring their robots to life. As the nerve center of Team 1280, the EECS subteam combines the disciplines of electrical engineering and computer science to develop sophisticated control systems, autonomous functionalities, and robust electrical infrastructures that enable their robots to perform complex tasks and maneuvers in the competitive arena. description: `The Team 1280 EECS (Electrical Engineering and Computer Science) subteam is an autonomous organization within Team 1280, specializing in the design, programming, and electrical systems that bring their robots to life. As the nerve center of Team 1280, the EECS subteam combines the disciplines of electrical engineering and computer science to develop sophisticated control systems, autonomous functionalities, and robust electrical infrastructures that enable their robots to perform complex tasks and maneuvers in the competitive arena.
[linebreak] [linebreak]
Team 1280 EECS is composed of highly skilled and passionate students who are keen on applying theoretical knowledge to practical challenges. They are responsible for everything from circuit design and sensor integration to software development and debugging, ensuring that the robot can effectively communicate, navigate, and interact with its environment. Team 1280 EECS is composed of highly skilled and passionate students who are keen on applying theoretical knowledge to practical challenges. They are responsible for everything from circuit design and sensor integration to software development and debugging, ensuring that the robot can effectively communicate, navigate, and interact with its environment.
@ -372,13 +403,13 @@ Team 1280 EECS benefits from mentorship by experienced professionals and alumni,
'1280-programming': { '1280-programming': {
name: "Team 1280, the Ragin' C Biscuits, Programming Subteam (now defunct)", name: "Team 1280, the Ragin' C Biscuits, Programming Subteam (now defunct)",
short: '1280 Programming', short: '1280 Programming',
image: '/eexiv-2/img/logos/1280-main.png', image: '/img/logos/1280-main.png',
description: `The former programming subteam of Team 1280, it combined with the Team 1280 electrical subteam in a historic merger to form Team 1280 EECS.`, description: `The former programming subteam of Team 1280, it combined with the Team 1280 electrical subteam in a historic merger to form Team 1280 EECS.`,
}, },
'usc-viterbi': { 'usc-viterbi': {
name: 'University of Southern California, Viterbi School of Engineering', name: 'University of Southern California, Viterbi School of Engineering',
short: 'USC Viterbi', short: 'USC Viterbi',
image: '/eexiv-2/img/logos/usc-viterbi.jpg', image: '/img/logos/usc-viterbi.jpg',
description: `The University of Southern California (USC) Viterbi School of description: `The University of Southern California (USC) Viterbi School of
Engineering is a cornerstone of innovation and excellence in the Engineering is a cornerstone of innovation and excellence in the
engineering field. Established in 1905, it has grown into a leading engineering field. Established in 1905, it has grown into a leading
@ -406,7 +437,7 @@ Team 1280 EECS benefits from mentorship by experienced professionals and alumni,
'1280-business': { '1280-business': {
name: "Team 1280, the Ragin' C Biscuits, Business Subteam", name: "Team 1280, the Ragin' C Biscuits, Business Subteam",
short: '1280 Business', short: '1280 Business',
image: '/eexiv-2/img/logos/1280-main.png', image: '/img/logos/1280-main.png',
description: `The Business subteam of Team 1280 plays a crucial role in ensuring the team's operational success and sustainability. Unlike the engineering-focused subteams, the Business subteam focuses on the financial, organizational, and community aspects of the team's operations. They are responsible for fundraising, sponsorship outreach, budget management, and public relations, ensuring that the team has the necessary resources and support to thrive in their endeavors. description: `The Business subteam of Team 1280 plays a crucial role in ensuring the team's operational success and sustainability. Unlike the engineering-focused subteams, the Business subteam focuses on the financial, organizational, and community aspects of the team's operations. They are responsible for fundraising, sponsorship outreach, budget management, and public relations, ensuring that the team has the necessary resources and support to thrive in their endeavors.
[linebreak] [linebreak]
Members of the Business subteam develop and execute strategies to engage with corporate sponsors, local businesses, and individual donors, crafting compelling sponsorship proposals and maintaining ongoing relationships with stakeholders. They also manage the team's finances, meticulously planning and tracking expenditures to ensure that resources are allocated efficiently and effectively. Members of the Business subteam develop and execute strategies to engage with corporate sponsors, local businesses, and individual donors, crafting compelling sponsorship proposals and maintaining ongoing relationships with stakeholders. They also manage the team's finances, meticulously planning and tracking expenditures to ensure that resources are allocated efficiently and effectively.
@ -420,7 +451,7 @@ By bridging the gap between engineering innovation and business acumen, the Busi
'raid-zero': { 'raid-zero': {
name: 'Team 4253 - Raid Zero', name: 'Team 4253 - Raid Zero',
short: 'Raid 0', short: 'Raid 0',
image: '/eexiv-2/img/logos/raid-zero.png', image: '/img/logos/raid-zero.png',
description: `Team 4253, Raid Zero, hailing from Taipei American School in Taipei, Taipei Special Municipality, Chinese Taipei, has been a formidable presence in the world of robotics since its rookie year in 2012. As a participant in the international FIRST Robotics Competition, Raid Zero exemplifies innovation, teamwork, and the pursuit of excellence in science, technology, engineering, and mathematics (STEM). description: `Team 4253, Raid Zero, hailing from Taipei American School in Taipei, Taipei Special Municipality, Chinese Taipei, has been a formidable presence in the world of robotics since its rookie year in 2012. As a participant in the international FIRST Robotics Competition, Raid Zero exemplifies innovation, teamwork, and the pursuit of excellence in science, technology, engineering, and mathematics (STEM).
[linebreak] [linebreak]
Since its inception, Raid Zero has dedicated itself to designing, building, and programming competitive robots that can perform complex tasks and compete at high levels. The team's journey through the FIRST Robotics Competition has been marked by continuous learning, adaptation, and growth, reflecting their commitment to not only compete but also to embody the ideals of gracious professionalism and cooperation. Since its inception, Raid Zero has dedicated itself to designing, building, and programming competitive robots that can perform complex tasks and compete at high levels. The team's journey through the FIRST Robotics Competition has been marked by continuous learning, adaptation, and growth, reflecting their commitment to not only compete but also to embody the ideals of gracious professionalism and cooperation.
@ -434,7 +465,7 @@ Raid Zero's influence extends beyond the technical achievements in robotics comp
srvhs: { srvhs: {
name: 'San Ramon Valley High School', name: 'San Ramon Valley High School',
short: 'SRVHS', short: 'SRVHS',
image: '/eexiv-2/img/logos/srvhs.jpg', image: '/img/logos/srvhs.jpg',
description: `A relatively average high school located in Danville, California. It has no standout features besides being the base of operations for Team 1280 and Team 1280 EECS.`, description: `A relatively average high school located in Danville, California. It has no standout features besides being the base of operations for Team 1280 and Team 1280 EECS.`,
}, },
} }

View file

@ -1,22 +1,21 @@
'use client'
import { Zilla_Slab } from 'next/font/google' import { Zilla_Slab } from 'next/font/google'
import { import {
DocumentType, DocumentType,
documents, documents,
topics as topicList, topics as topicList,
authors as authorList, authors as authorList,
DocumentStatus,
reviewer,
} from '@/app/db/data' } from '@/app/db/data'
import Link from 'next/link' import Link from 'next/link'
import { notFound } from 'next/navigation' import { notFound } from 'next/navigation'
import { Fragment } from 'react' import { Fragment, useEffect } from 'react'
import { epoch2datestring } from '@/app/utils/epoch2datestring' import { epoch2datestring } from '@/app/utils/epoch2datestring'
import { toast } from 'react-toastify'
const zillaSlab = Zilla_Slab({ subsets: ['latin'], weight: ['500'] }) const zillaSlab = Zilla_Slab({ subsets: ['latin'], weight: ['500'] })
export function generateStaticParams() {
const documentsList = Object.keys(documents)
return documentsList.map((slug) => ({ slug }))
}
export default function Page({ export default function Page({
params, params,
}: Readonly<{ params: { slug: string } }>) { }: Readonly<{ params: { slug: string } }>) {
@ -25,8 +24,27 @@ export default function Page({
notFound() notFound()
} }
const { abstract, file } = doc const { abstract, file } = doc
const { title, authors, topics, dates, references, code, type, latest } = const {
doc.manifest title,
authors,
topics,
dates,
references,
code,
type,
latest,
reviewers,
status,
} = doc.manifest
useEffect(() => {
if (status === 'reviewed' && !reviewers) {
toast.warn(
`This document is marked reviewed, but the author
forgot to add a list of reviewers.`
)
}
}, [])
const Topics = () => { const Topics = () => {
return ( return (
@ -95,39 +113,104 @@ export default function Page({
) )
} }
const Status = ({ statusName }: Readonly<{ statusName: DocumentStatus }>) => {
let text = ''
let itemStyle: string = ''!
switch (statusName) {
case 'draft':
text = 'Draft'
itemStyle += 'badge-draft'
break
case 'published no review':
text = 'Published'
itemStyle += 'badge-published'
break
case 'reviewed':
text = 'Peer Reviewed'
itemStyle += 'badge-reviewed'
break
case 'under review':
text = 'Pending Review'
itemStyle = 'badge-under-review'
break
}
return <span className={itemStyle}>{text}</span>
}
const ItemBadge = ({ itemName }: Readonly<{ itemName: DocumentType }>) => { const ItemBadge = ({ itemName }: Readonly<{ itemName: DocumentType }>) => {
let text = '' let text = ''
let itemStyle: string = let itemStyle: string = ''!
'px-3 py-1.5 rounded inline-block w-fit mr-2 mt-4 text-slate-50 border-2 '
switch (itemName) { switch (itemName) {
case 'report': case 'report':
itemStyle += 'bg-green-500 border-green-500' itemStyle = 'badge-report'
text = 'Report' text = 'Report'
break break
case 'presentation': case 'presentation':
text = 'Presentation' text = 'Presentation'
itemStyle += `bg-blue-500 border-blue-500` itemStyle = 'badge-presentation'
break break
case 'white paper': case 'white paper':
text = 'White Paper' text = 'White Paper'
itemStyle += `bg-fuchsia-700 border-fuchsia-700` itemStyle = 'badge-white-paper'
break break
case 'datasheet': case 'datasheet':
text = 'Datasheet' text = 'Datasheet'
itemStyle += 'bg-amber-600 border-amber-600' itemStyle = 'badge-datasheet'
break break
case 'dwm': case 'dwm':
text = 'DWM' text = 'DWM'
itemStyle += 'bg-rose-950 border-rose-950' itemStyle = 'badge-dwm'
break break
case 'other': case 'other':
text = 'Other' text = 'Other'
itemStyle += `bg-gray-400 border-gray-400` itemStyle = 'badge-other'
break break
} }
return <span className={itemStyle}>{text}</span> return <span className={itemStyle}>{text}</span>
} }
const Reviewers = () => {
if (!reviewers) return null
const ReviewerDisplay = ({ r }: Readonly<{ r: reviewer }>) => {
if (r.profile) {
return (
<>
<Link href={`/author/${r.profile}`} target='_blank'>
{r.first} {r.last}
</Link>
</>
)
}
if (r.url) {
return (
<>
<a href={r.url} target='_blank'>
{r.first} {r.last}
</a>
</>
)
}
return (
<span>
{r.first} {r.last}
</span>
)
}
return (
<>
<span className='font-bold'>Reviewers: </span>
{reviewers.map((r: reviewer, i) => (
<Fragment key={i}>
<ReviewerDisplay r={r} />
{i !== reviewers.length - 1 && reviewers.length > 2 ? ', ' : null}
{i === reviewers.length - 2 ? ' and ' : null}
</Fragment>
))}
</>
)
}
return ( return (
<div> <div>
<div> <div>
@ -150,9 +233,10 @@ export default function Page({
</span> </span>
</p> </p>
<ItemBadge itemName={type as DocumentType} /> <ItemBadge itemName={type as DocumentType} />
<p className='inline-block border-gray-200 border-2 rounded px-2 py-1.5'> <span className='inline-block border-gray-200 border-2 rounded px-2 py-1.5 mr-2'>
Revision {latest} Revision {latest}
</p> </span>
<Status statusName={status} />
<hr className='my-4' /> <hr className='my-4' />
<h4 className='text-2xl mt-5 font-serif font-semibold'>Abstract</h4> <h4 className='text-2xl mt-5 font-serif font-semibold'>Abstract</h4>
<p className='my-4 text-xl text-slate-600 font-serif text-balance'> <p className='my-4 text-xl text-slate-600 font-serif text-balance'>
@ -167,6 +251,9 @@ export default function Page({
<p className='my-2'> <p className='my-2'>
<References /> <References />
</p> </p>
<p className='my-2'>
<Reviewers />
</p>
<Link <Link
href={`/download/${params.slug}/file${latest}.${file}`} href={`/download/${params.slug}/file${latest}.${file}`}
download={`${params.slug}-rev-${latest}.pdf`} download={`${params.slug}-rev-${latest}.pdf`}

View file

@ -23,3 +23,47 @@ a:hover {
.button-default { .button-default {
@apply bg-blue-600 text-slate-100 hover:bg-blue-400 font-semibold rounded py-2 px-4 my-2; @apply bg-blue-600 text-slate-100 hover:bg-blue-400 font-semibold rounded py-2 px-4 my-2;
} }
.badge-base {
@apply px-3 py-1.5 rounded inline-block w-fit mr-2 mt-4 text-slate-50 border-2;
}
.badge-draft {
@apply badge-base bg-slate-500 border-slate-500;
}
.badge-published {
@apply badge-base bg-sky-500 border-sky-500;
}
.badge-reviewed {
@apply badge-base bg-green-700 border-green-700;
}
.badge-under-review {
@apply badge-base bg-yellow-500 border-yellow-500;
}
.badge-report {
@apply badge-base bg-green-500 border-green-500;
}
.badge-presentation {
@apply badge-base bg-blue-500 border-blue-500;
}
.badge-white-paper {
@apply badge-base bg-fuchsia-700 border-fuchsia-700;
}
.badge-datasheet {
@apply badge-base bg-amber-600 border-amber-600;
}
.badge-dwm {
@apply badge-base bg-rose-950 border-rose-950;
}
.badge-other {
@apply badge-base bg-gray-400 border-gray-400;
}

View file

@ -7,8 +7,6 @@ import SearchBar from './searchBar/SearchBar'
import Container from './container/Container' import Container from './container/Container'
import { ToastContainer } from 'react-toastify' import { ToastContainer } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.css' import 'react-toastify/dist/ReactToastify.css'
import { Suspense } from 'react'
import LoadingBar from './components/Loading'
/* The default font is Inter. If you want to use Zilla Slab (or any other Google Font, /* The default font is Inter. If you want to use Zilla Slab (or any other Google Font,
which are pre-provided by Next.js in the 'next/font/google' module), you need to which are pre-provided by Next.js in the 'next/font/google' module), you need to
@ -38,7 +36,7 @@ export default function RootLayout({
<Link href='/affiliation/1280-eecs'> <Link href='/affiliation/1280-eecs'>
<img <img
className='h-[100px] mt-4' className='h-[100px] mt-4'
src='/eexiv-2/img/logos/eecs-wordmark.png' src='/img/logos/eecs-wordmark.png'
alt='EECS' alt='EECS'
/> />
</Link> </Link>
@ -67,46 +65,40 @@ export default function RootLayout({
</div> </div>
</div> </div>
</div> </div>
<Suspense fallback={<LoadingBar />}> <Container>{children}</Container>
<Container width='1200px' fill>
{children}
</Container>
</Suspense>
<footer> <footer>
<div className={styles.footerContent}> <div className={styles.footerContent}>
<Container width='1200px'> <ul>
<ul> <li key='about'>
<li key='about'> <Link href='/about'>About</Link>
<Link href='/about'>About</Link> </li>
</li> <li key='help'>
<li key='help'> <Link href='/help'>Help</Link>
<Link href='/help'>Help</Link> </li>
</li> <li key='contact'>
<li key='contact'> <Link href='/contact'>Contact</Link>
<Link href='/contact'>Contact</Link> </li>
</li> <li key='subscribe'>
<li key='subscribe'> <Link href='/subscribe'>Subscribe</Link>
<Link href='/subscribe'>Subscribe</Link> </li>
</li> <li key='copyright'>
<li key='copyright'> <Link href='/legal/copyright'>Copyright</Link>
<Link href='/legal/copyright'>Copyright</Link> </li>
</li> <li key='privacy'>
<li key='privacy'> <Link href='/legal/privacy'>Privacy Policy</Link>
<Link href='/legal/privacy'>Privacy Policy</Link> </li>
</li> <li key='accessibility'>
<li key='accessibility'> <Link href='/help/accessibility'>Accessibility</Link>
<Link href='/help/accessibility'>Accessibility</Link> </li>
</li> <li key='status'>
<li key='status'> <Link href='/status'>eeXiv status</Link>
<Link href='/status'>eeXiv status</Link> </li>
</li> <li key='notifications'>
<li key='notifications'> <Link href='/status/notifications'>
<Link href='/status/notifications'> Get status notifications
Get status notifications </Link>
</Link> </li>
</li> </ul>
</ul>
</Container>
</div> </div>
</footer> </footer>
</body> </body>

10
src/app/loading.tsx Normal file
View file

@ -0,0 +1,10 @@
import LoadingBar from './components/LoadingBar'
/* this special file is used to tell next.js to wrap our layout in a
React Suspense and display the specified loading screen while we wait for loading
In this case, we just show a loading bar fixed at the top of the screen as well as
as fill 100% of the page height to prevent the page from jumping
*/
export default function Loading() {
return <LoadingBar />
}

17
src/app/not-found.tsx Normal file
View file

@ -0,0 +1,17 @@
import Link from 'next/link'
export default function NotFound() {
return (
<div
className={`flex flex-col sm:flex-row justify-center p-5 m-2 items-center`}
>
<h1 className='text-5xl md:text-8xl font-bold m-2'>404</h1>
<div className='border-2 border-black h-20 rounded-md m-2 hidden sm:inline text-center sm:text-left' />
<hr className='border-2 border-black w-40 rounded-md sm:hidden' />
<div className='grid grid-cols-1 m-2 text-center sm:text-left'>
<p>Could not find requested resource</p>
<Link href='/'>Return Home</Link>
</div>
</div>
)
}