diff --git a/components/icon.jsx b/components/icon.jsx index 921fa81..82a3cff 100644 --- a/components/icon.jsx +++ b/components/icon.jsx @@ -15,6 +15,8 @@ import { IoCalendarOutline } from "react-icons/io5"; import { createElement } from "react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faGoogleDrive } from "@fortawesome/free-brands-svg-icons"; const iconMap = { envelope: IoMail, @@ -31,13 +33,20 @@ const iconMap = { slack: IoLogoSlack, copy: IoCopyOutline, calendar: IoCalendarOutline, - + googleSlides: faGoogleDrive, }; -export default function Icon(props) { - if (!(props.name in iconMap)) { - console.error("Could not find name " + props.name); +export default function Icon({ name, ...props }) { + const IconComponent = iconMap[name]; + + if (!IconComponent) { + console.error(`Could not find icon with name "${name}"`); return null; } - return createElement(iconMap[props.name], props); -} + + if (name === 'googleSlides') { + return ; + } + + return createElement(IconComponent, props); +} \ No newline at end of file diff --git a/config/sponsors.json b/config/sponsors.json index f0bce14..df64309 100644 --- a/config/sponsors.json +++ b/config/sponsors.json @@ -26,6 +26,11 @@ "name": "Michigan Institute for Data Science", "link": "https://midas.umich.edu/", "image": "midas.png" + }, + { + "name": "University of Michigan School of Information", + "link": "https://www.si.umich.edu/", + "image": "umsi.png" } ] } diff --git a/package-lock.json b/package-lock.json index ae6f7d8..30d84e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,10 @@ "name": "mdst-website", "version": "0.1.0", "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.5.2", + "@fortawesome/free-brands-svg-icons": "^6.5.2", + "@fortawesome/free-solid-svg-icons": "^6.5.2", + "@fortawesome/react-fontawesome": "^0.2.2", "@fullcalendar/core": "^6.1.10", "@fullcalendar/google-calendar": "^6.1.10", "@fullcalendar/list": "^6.1.10", @@ -88,6 +92,63 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz", + "integrity": "sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz", + "integrity": "sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-brands-svg-icons": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.2.tgz", + "integrity": "sha512-zi5FNYdmKLnEc0jc0uuHH17kz/hfYTg4Uei0wMGzcoCL/4d3WM3u1VMc0iGGa31HuhV5i7ZK8ZlTCQrHqRHSGQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.2.tgz", + "integrity": "sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", + "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, "node_modules/@fullcalendar/core": { "version": "6.1.10", "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.10.tgz", diff --git a/package.json b/package.json index 17cce60..063124e 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,10 @@ "export": "next export -o out" }, "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.5.2", + "@fortawesome/free-brands-svg-icons": "^6.5.2", + "@fortawesome/free-solid-svg-icons": "^6.5.2", + "@fortawesome/react-fontawesome": "^0.2.2", "@fullcalendar/core": "^6.1.10", "@fullcalendar/google-calendar": "^6.1.10", "@fullcalendar/list": "^6.1.10", diff --git a/pages/projects/index.jsx b/pages/projects/index.jsx index a9359fc..5e6dcd8 100644 --- a/pages/projects/index.jsx +++ b/pages/projects/index.jsx @@ -1,41 +1,95 @@ +import HeadContent from "@/components/headContent"; +import Hero from "@/components/hero"; import Layout from "@/components/layout"; -import Link from "next/link"; import fs from "fs"; import path from "path"; -import Hero from "@/components/hero"; -import HeadContent from "@/components/headContent"; +import Link from "next/link"; +import Image from "next/image"; +import { useRouter } from "next/router"; +import Icon from "@/components/icon"; + + export default function Projects({ groupedLinks }) { + const router = useRouter(); + const basePath = router.basePath; + return ( - - - -
- {Object.entries(groupedLinks).map(([subdirectory, links]) => ( -
-

{subdirectory}

-
    - {links.map((link, index) => ( -
  • - { - link.type != "none" ? - {link.label} - : link.label - } - -
  • - ))} -
-
+ + + {Object.entries(groupedLinks).map(([subdirectory, links], index) => ( + + ))} + + ); +} + +function ProjectSection({ subdirectory, links, basePath }) { + return ( +
+
+

{subdirectory}

+
+
+ {links.map((link, index) => ( + ))}
- +
); } +function ProjectCard({ project, basePath }) { + return ( +
+ {project.label} +
+

{project.label}

+
    + {project.type === "link" && ( +
  • + + + +
  • + )} + {project.type === "md" && ( +
  • + + + +
  • + )} + {project.type === "pdf" && ( +
  • + + + +
  • + )} + {project.type === "googleSlides" && ( +
  • + + + +
  • + )} +
+
+
+ ); +} export async function getStaticProps() { const projectsDirectory = path.join(process.cwd(), "public", "projects"); @@ -46,10 +100,10 @@ export async function getStaticProps() { name: dirent.name, })) .sort((a, b) => { - const order = ['Fall_', 'Winter_']; + const order = ["Fall_", "Winter_"]; const getOrderIndex = (dirName) => { - const prefix = order.find(prefix => dirName.startsWith(prefix)); + const prefix = order.find((prefix) => dirName.startsWith(prefix)); return prefix ? 0 : 1; }; @@ -58,17 +112,15 @@ export async function getStaticProps() { if (orderComparison !== 0) { return orderComparison; } else if (getOrderIndex(a.name) === 0) { - const aNumber = parseInt(a.name.split('_')[1]); - const bNumber = parseInt(b.name.split('_')[1]); + const aNumber = parseInt(a.name.split("_")[1]); + const bNumber = parseInt(b.name.split("_")[1]); return bNumber - aNumber; } else { - return a.name.localeCompare(b.name) + return a.name.localeCompare(b.name); } - - });; + }); const groupedLinks = {}; - const paths = [] subdirectories.forEach((subdirectory) => { const subdirectoryPath = path.join(projectsDirectory, subdirectory.name); const innerDirectories = fs @@ -80,38 +132,38 @@ export async function getStaticProps() { innerDirectories.forEach((innerDir) => { const innerDirPath = path.join(subdirectoryPath, innerDir); - const writeupMdPath = path.join(innerDirPath, "writeup.md"); const writeupPdfPath = path.join(innerDirPath, "writeup.pdf"); const linkTxtPath = path.join(innerDirPath, "link.txt"); - const label = innerDir.split("_") - .join(" "); - let type, href + const label = innerDir.split("_").join(" "); + let type, href; if (fs.existsSync(linkTxtPath)) { - const link = fs.readFileSync(linkTxtPath, 'utf-8').trim(); - href = link - type = "link" + const link = fs.readFileSync(linkTxtPath, "utf-8").trim(); + if (link.toLowerCase().includes('docs.google.com/presentation')) { + href = link; + type = "googleSlides"; + } else { + href = link; + type = "link"; + } } else if (fs.existsSync(writeupMdPath)) { - href = `/projects/${subdirectory.name}/${innerDir}` - type = "md" - } - else if (fs.existsSync(writeupPdfPath)) { - href = `/projects/${subdirectory.name}/${innerDir}/writeup.pdf` - type = "pdf" + href = `/projects/${subdirectory.name}/${innerDir}`; + type = "md"; + } else if (fs.existsSync(writeupPdfPath)) { + href = `/projects/${subdirectory.name}/${innerDir}/writeup.pdf`; + type = "pdf"; } else { - href = "" - type = "none" + href = ""; + type = "none"; } - links.push({ label, href, type }) - + links.push({ label, href, type }); }); if (links.length > 0) { groupedLinks[subdirectory.name.split("_").join(" ")] = links; } - }); return { @@ -120,4 +172,3 @@ export async function getStaticProps() { }, }; } - diff --git a/public/images/sponsors/umsi.png b/public/images/sponsors/umsi.png new file mode 100644 index 0000000..26e2b2e Binary files /dev/null and b/public/images/sponsors/umsi.png differ