diff --git a/public/download/day-5-principles-1/file.pdf b/public/download/day-5-principles/file1.pdf similarity index 100% rename from public/download/day-5-principles-1/file.pdf rename to public/download/day-5-principles/file1.pdf diff --git a/src/app/db/data.ts b/src/app/db/data.ts new file mode 100644 index 0000000..696631d --- /dev/null +++ b/src/app/db/data.ts @@ -0,0 +1,153 @@ +/* +documents db schema +documents { + slug: { + manifest: { + title: string + authors: string[] + date: unix epoch integer[] + type: presentation | report | white paper | other + latest: integer >= 1 + keywords: string[] + topics: string[] + references: string[], + code: url[] + }, + abstract: string, + file: pdf | docx | pptx | targz | other, named file[rev].[ext] + (eg. revision 1 = file1.pdf, revision 2 = file2.pdf, etc) + the "latest" should be the latest revision + } +} +*/ +export type FileType = 'pdf' | 'docx' | 'pptx' | 'targz' | 'other' +export type DocumentType = 'presentation' | 'report' | 'white paper' | 'other' +export interface DocumentDB { + [key: string]: { + manifest: { + title: string + authors: string[] + topics: string[] + dates: number[] + references?: string[] + code?: string[] + type: DocumentType + latest: number + } + abstract: string + file: FileType + } +} +export const documents: DocumentDB = { + 'day-5-principles': { + manifest: { + title: 'Day 5 Principles', + authors: ['shasan'], + topics: ['frc', 'mech'], + dates: [1707281608], + type: 'presentation', + latest: 1, + }, + 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.', + file: 'pdf', + }, +} + +export interface Topics { + [key: string]: { + name: string + description: string + wiki: string + } +} +export const topics: Topics = { + frc: { + name: 'FIRST Robotics Competition', + description: + 'FRC is an international robotics competition that was founded by FIRST in 1983 and is currently one of the largest professional robotics competitions in the world.', + wiki: 'https://en.wikipedia.org/wiki/FIRST_Robotics_Competition', + }, + mech: { + name: 'Mechanical Engineering', + description: + 'Mechanical engineering is a branch of engineering that involves the design, development, and use of machines, mechanisms, and other devices.', + wiki: 'https://en.wikipedia.org/wiki/Mechanical_engineering', + }, + eecs: { + name: 'Electrical Engineering and Computer Science', + description: + 'Electrical engineering and computer science are fields that combine engineering, science, and computing. The acronym EECS is derived from ther world-renowned electrical engineering and computer science program at the University of California, Berkeley.', + wiki: 'https://en.wikipedia.org/wiki/Computer_science_and_engineering', + }, + ai: { + name: 'Artificial Intelligence', + description: + 'Artificial intelligence (AI) refers to the simulation of human intelligence in machines that are programmed to think like humans and mimic their actions.', + wiki: 'https://en.wikipedia.org/wiki/Artificial_intelligence', + }, + econ: { + name: 'Economics', + description: + 'Economics is the study of the production, distribution, consumption, and trade of goods and services.', + wiki: 'https://en.wikipedia.org/wiki/Economics', + }, +} + +export interface Authors { + [key: string]: { + name: { + first: string + last: string + } + affiliation: string[] + image: string + nationality: string[] + } +} + +export const authors: Authors = { + shasan: { + name: { + first: 'Saim', + last: 'Hasan', + }, + affiliation: [ + 'Lead Mechanical Engineer @1280-mech', + 'Undergraduate @usc-viterbi', + ], + image: 'https://team-1280.vercel.app/assets/img/gallery6.jpg', + nationality: ['pak'], + }, + mbohsali: { + name: { + first: 'Majd', + last: 'Bohsali', + }, + affiliation: ['Lead Programming Engineer @1280-eecs'], + image: 'https://cdn-icons-png.freepik.com/512/3177/3177440.png', + nationality: ['lbn'], + }, + avenkatesh: { + name: { + first: 'Ananth', + last: 'Venkatesh', + }, + affiliation: [ + 'Programming Lead @1280-programming', + 'Lead Controls Engineer @1280-eecs', + ], + image: 'https://cdn-icons-png.freepik.com/512/3177/3177440.png', + nationality: ['ind', 'eth'], + }, + ywu: { + name: { + first: 'Youwen', + last: 'Wu', + }, + affiliation: ['Artificial Intelligence Lead @1280-eecs'], + image: + 'https://static.wikia.nocookie.net/discoelysium_gamepedia_en/images/9/95/Portrait_evrart.png/revision/latest?cb=20191028100247', + nationality: ['chn'], + }, +} diff --git a/src/app/document/view/[docName]/documentViewer.module.css b/src/app/document/view/[docName]/documentViewer.module.css deleted file mode 100644 index 3d9e24b..0000000 --- a/src/app/document/view/[docName]/documentViewer.module.css +++ /dev/null @@ -1,61 +0,0 @@ -.itemTitle { - margin: 0; - font-size: 2em; -} - -.itemAuthors { - margin-bottom: 0; -} - -.itemDates { - margin-top: 0; -} - -.itemType { - display: inline-block; - width: fit-content; - padding-left: 10px; - padding-right: 10px; - padding-top: 5px; - padding-bottom: 5px; - margin-right: 10px; - border-radius: 5px; - margin-top: 10px; -} - -.typeReport { - background-color: #28a745; -} - -.itemRevision { - display: inline-block; -} - -.itemAbstractHeader { - margin-top: 20px; - margin-bottom: 10px; - color: 33; - font-size: 1.5em; -} - -.itemAbstract { - margin-top: 10px; - color: #666; - font-size: 1.2em; -} - -.typePresentation { - background-color: #007bff; -} - -.typeOther { - background-color: #6c757d; -} - -.resultAbstract { - color: #333; -} - -.downloadButton { - padding: 10px; -} diff --git a/src/app/document/view/[docName]/page.tsx b/src/app/document/view/[docName]/page.tsx deleted file mode 100644 index 23158c1..0000000 --- a/src/app/document/view/[docName]/page.tsx +++ /dev/null @@ -1,92 +0,0 @@ -'use client' -import styles from './documentViewer.module.css' -import { Zilla_Slab } from 'next/font/google' -import { saveAs } from 'file-saver' - -const zillaSlab = Zilla_Slab({ subsets: ['latin'], weight: ['500'] }) - -export default function Page({ - params, -}: Readonly<{ params: { docName: string } }>) { - const handleDownload = () => { - saveAs(`/download/${params.docName}/file.pdf`, `${params.docName}.pdf`) - } - - type ItemType = 'report' | 'presentation' | 'other' - const generateItemBadge = (itemName: ItemType) => { - let itemStyle: string - switch (itemName) { - case 'report': - itemStyle = `${styles.itemType} bg-green-400` - break - case 'presentation': - itemStyle = `${styles.itemType} bg-blue-400` - break - case 'other': - itemStyle = `${styles.itemType} bg-amber-400` - } - return ( -

- {itemName.charAt(0).toUpperCase()} - {itemName.slice(1)} -

- ) - } - - return ( -
-
-

- 2024 Controls/Programming DWM -

-

- Majd Bohsali and{' '} - Ananth Venkatesh -

-

Published Jan 22, 2024

- {generateItemBadge('report')} -

Revision 1

-

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. -

-

- Topics:{' '} - FIRST Robotics Competition,{' '} - - Electrical Engineering and Computer Science - -

-

- Code:{' '} - - https://github.com/Team-1280/Swerve - - ,{' '} - - https://github.com/Team-1280/Jankboard - - ,{' '} - - https://github.com/Team-1280/identity - -

- -
-
- ) -} diff --git a/src/app/document/view/[slug]/actions.ts b/src/app/document/view/[slug]/actions.ts new file mode 100644 index 0000000..badbcda --- /dev/null +++ b/src/app/document/view/[slug]/actions.ts @@ -0,0 +1,7 @@ +'use server' + +import { redirect } from 'next/navigation' + +export async function navigate(url: string) { + redirect(url) +} diff --git a/src/app/document/view/[slug]/documentViewer.module.css b/src/app/document/view/[slug]/documentViewer.module.css new file mode 100644 index 0000000..1ae3e1c --- /dev/null +++ b/src/app/document/view/[slug]/documentViewer.module.css @@ -0,0 +1,27 @@ +.itemTitle { + margin: 0; + font-size: 2em; +} + +.itemAbstractHeader { + margin-top: 20px; + margin-bottom: 10px; + color: 33; + font-size: 1.5em; +} + +.typePresentation { + background-color: #007bff; +} + +.typeOther { + background-color: #6c757d; +} + +.resultAbstract { + color: #333; +} + +.downloadButton { + padding: 10px; +} diff --git a/src/app/document/view/[slug]/page.d.ts b/src/app/document/view/[slug]/page.d.ts new file mode 100644 index 0000000..4cc74f3 --- /dev/null +++ b/src/app/document/view/[slug]/page.d.ts @@ -0,0 +1 @@ +declare module 'unix-timestamp' diff --git a/src/app/document/view/[slug]/page.tsx b/src/app/document/view/[slug]/page.tsx new file mode 100644 index 0000000..78ac6de --- /dev/null +++ b/src/app/document/view/[slug]/page.tsx @@ -0,0 +1,158 @@ +'use client' +import styles from './documentViewer.module.css' +import { Zilla_Slab } from 'next/font/google' +import { saveAs } from 'file-saver' +import { + DocumentType, + documents, + topics as topicList, + authors as authorList, +} from '../../../db/data' +import { navigate } from './actions' +import Link from 'next/link' + +const zillaSlab = Zilla_Slab({ subsets: ['latin'], weight: ['500'] }) + +function epoch2datestring(epoch: number): string { + // Create a new Date object from the epoch + const date = new Date(epoch * 1000) + + // Format the date to the specified format + const formattedDate = date.toLocaleDateString('en-US', { + month: 'short', // abbreviated month name + day: '2-digit', // day as two digits + year: 'numeric', // four digit year + }) + + return formattedDate +} + +export default function Page({ + params, +}: Readonly<{ params: { slug: string } }>) { + const doc = documents[params.slug] + if (!doc) { + navigate('/404') + return + } + const { abstract, file } = doc + const { title, authors, topics, dates, references, code, type, latest } = + doc.manifest + + const handleDownloadLatest = () => { + saveAs( + `/download/${params.slug}/file${latest}.pdf`, + `${params.slug}-rev-${latest}.pdf` + ) + } + + const generateTopics = () => { + return ( + <> + Topics: + {topics.map((t: string, i) => ( + <> + + {topicList[t].name} + + {i !== topics.length - 1 ? ', ' : null} + + ))} + + ) + } + + const generateCode = () => { + if (code) { + return ( + <> + Code: + {code.map((c: string, i) => ( + <> + + {c} + + {i !== code.length - 1 ? ', ' : null} + + ))} + + ) + } + } + + const generateAuthors = () => { + return ( + <> + {authors.map((a: string, i) => ( + <> + + {authorList[a].name.first} {authorList[a].name.last} + + {i !== authors.length - 1 && authors.length > 2 ? ', ' : null} + {i === authors.length - 2 ? ' and ' : null} + + ))} + + ) + } + + const generateItemBadge = (itemName: DocumentType) => { + let itemStyle: string = 'px-3 py-1 rounded inline-block w-fit mr-2 mt-4 ' + switch (itemName) { + case 'report': + itemStyle += 'bg-green-400 text-slate-50' + break + case 'presentation': + itemStyle += `bg-blue-400 text-slate-50` + break + case 'white paper': + itemStyle += `bg-fuchsia-700 text-slate-50` + break + case 'other': + itemStyle += `bg-gray-400 text-slate-50` + break + } + return ( +

+ {itemName.charAt(0).toUpperCase()} + {itemName.slice(1)} +

+ ) + } + + return ( +
+
+

+ {title} +

+

{generateAuthors()}

+

+ Latest revision published{' '} + + {epoch2datestring(dates[dates.length - 1])} + +

+ {generateItemBadge('report')} +

Revision {latest}

+
+

Abstract

+

{abstract}

+

{generateTopics()}

+

{generateCode()}

+ +
+
+ ) +}