diff --git a/app/archive/[slug]/page.tsx b/app/archive/[slug]/page.tsx new file mode 100644 index 0000000..22358b6 --- /dev/null +++ b/app/archive/[slug]/page.tsx @@ -0,0 +1,18 @@ +"use client" +import '@/src/styles/reset.scss'; + +import NavigationBar from '@/src/components/navbar'; +import ProjectDetail from '@/src/sections/ProjectDetail'; +import Footer from '@/src/components/footer'; + +const ProjectPage = ({ params }: { params: { slug: string } }) => { + return ( +
+ + +
+ ); +}; + +export default ProjectPage; diff --git a/app/layout.tsx b/app/layout.tsx index a120171..cf01f3a 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -2,7 +2,7 @@ import "./globals.css"; import type { Metadata } from "next"; import { DM_Sans } from "next/font/google"; -const dm_sans = DM_Sans({ subsets: ["latin"], weight: "400" }); +const dm_sans = DM_Sans({ subsets: ["latin"], weight: ["200", "400", "500", "600", "700", "800"] }); export const metadata: Metadata = { title: "ACM at UC San Diego Projects Website", diff --git a/public/assets/chevron-down.svg b/public/assets/chevron-down.svg new file mode 100644 index 0000000..5af78b8 --- /dev/null +++ b/public/assets/chevron-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/embeds/figma-icon.svg b/public/assets/embeds/figma-icon.svg new file mode 100644 index 0000000..cd15c45 --- /dev/null +++ b/public/assets/embeds/figma-icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/assets/embeds/github-icon.svg b/public/assets/embeds/github-icon.svg new file mode 100644 index 0000000..c097de2 --- /dev/null +++ b/public/assets/embeds/github-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/robo.svg b/public/assets/robo.svg new file mode 100644 index 0000000..ace28cc --- /dev/null +++ b/public/assets/robo.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/components/project-card/highlighted.json b/src/components/project-card/highlighted.json new file mode 100644 index 0000000..7db038f --- /dev/null +++ b/src/components/project-card/highlighted.json @@ -0,0 +1,5 @@ +[ + "sp23-hack-1", + "wi23-design-1", + "fa22-ai-1" +] diff --git a/src/components/project-card/index.tsx b/src/components/project-card/index.tsx index 541c8af..7daa089 100644 --- a/src/components/project-card/index.tsx +++ b/src/components/project-card/index.tsx @@ -1,148 +1,156 @@ +'use client' +import { useEffect, useLayoutEffect, useRef } from "react"; import s from "./style.module.scss"; +import projects_data from "./projects.json"; +import highlighted_ids from "./highlighted.json"; -// Images for embed links and other logos - -const default_pic = "/assets/proj_logo.png"; -const figma = "/assets/embeds/figma.png"; -const github = "/assets/embeds/github.png"; -const slides = "/assets/embeds/slides.png"; -const other_links = "/assets/embeds/other_links.png"; -const hack_logo = "/assets/hack.svg"; -const design_logo = "/assets/design.svg"; -const ai_logo = "/assets/ai.svg"; - -const projects_data = [ - {"quarter": "Spring 2023", - "subgroup": "Hack", - "project_title": "Word Nerd", - "team_name": "Team 1", - "logo": "/assets/project_logos/word_nerd.png", - "description": "We created a clone of the game CodeNames, except that users have the option to upload their own words so they can follow a theme or use it as a unique way to study vocab concepts with friends.", - "mentor": "Sujal", - "members": ["Greg Weber (Front-end)", "Julie Nguyen (Front-end)", "Josh Chen (Front-end)", "Tim Liu (Back-end)", "Gonzalo Allen-Perez (Back-end)", "Annie Ping (Back-end)"], - "slides": "https://docs.google.com/presentation/d/1xPRnYbfmZHW8l7_jo7gmTAxowV3PmLO39MvzfHht_Dk/edit?usp=sharing", - "project_link": "https://github.com/acmucsd-projects/sp23-hack-team-1", - "other_links": "https://codenames-acm.netlify.app/" +const SUBGROUP_CONFIG: Record = { + Design: { + logo: "/assets/design.svg", + border: s.borderDesign, + color: s.colorDesign, + repoIcon: "/assets/embeds/figma-icon.svg", + repoLabel: "Figma", }, - {"quarter": "Spring 2023", - "subgroup": "Hack", - "project_title": "GAMED", - "team_name": "Team 2", - "logo": "/assets/project_logos/gamed.png", - "description": "We created a website where UCSD students can find other players to play video games with. They can do this by creating an account, creating cards, and sending cards to people!.", - "mentor": "Shreya Nagunuri and Kevin Wu", - "members": ["Calvin Nguyen (Front-end)", "Kane Li (Full-stack)"], - "slides": "https://docs.google.com/presentation/d/1W-3JfpnNEghKXsuuCe1638ZBUkyCkntRNy6yUnFhr_4/edit?usp=sharing", - "project_link": "https://github.com/acmucsd-projects/sp23-hack-team-2", - "other_links": "https://ucsdgamed.onrender.com/" + Hack: { + logo: "/assets/hack.svg", + border: s.borderHack, + color: s.colorHack, + repoIcon: "/assets/embeds/github-icon.svg", + repoLabel: "GitHub File", }, - {"quarter": "Spring 2023", - "subgroup": "Hack", - "project_title": "Eventify", - "team_name": "Team 3", - "logo": "/assets/project_logos/eventify.png", - "description": "We created a website that can track on-campus UCSD events.", - "mentor": "Angela Hu and Charvi Shukla", - "members": ["Gavyn Ezell", "Cho Jung (Angela) Tsai", "Qijun (Mary) Hu", "Jae Whan Lee", "Rachel Chau", "Willey Zhou"], - "slides": "https://docs.google.com/presentation/d/1U93WsdyVuFDbvgWZ931oakEpL7zgzbZz8vNolmMZtFI/edit?usp=sharing", - "project_link": "https://github.com/acmucsd-projects/sp23-hack-team-3", - "other_links": "https://www.figma.com/file/KqvP7N6lLUu8NnT2ZnYK3o/Eventify?type=design&node-id=0%3A1&mode=design&t=hnFUTSx4agxe4CNT-1" + AI: { + logo: "/assets/ai.svg", + border: s.borderAI, + color: s.colorAI, + repoIcon: "/assets/embeds/github-icon.svg", + repoLabel: "GitHub File", }, - {"quarter": "Winter 2023", - "subgroup": "Hack", - "project_title": "IGFood", - "team_name": "Team 1", - "logo": "/assets/project_logos/ig_food.svg", - "description": "Yelp and Google Reviews are written by strangers that you cannot necessarily trust. Our solution is to create an application which creates a more personalized food-rating experience! The application connects you to your friends and allows you to see what/where your friends are eating via posts on a feed.", - "mentor": "Nikhil Dange", - "members": ["Angela Hu (Project Lead/Front-end)", "Nicholas Cheah (Front-end)", "Kinan Alatasi (Front-end)", "Alexis Vergnet (Back-end)", "Charvi Shukla (Back-end)", "Jason Wong (Back-end)"], - "slides": "https://docs.google.com/presentation/d/1g0pEKT7Rx_hoZDnC27zxxPs2UqipDLffgUC0Z0v5xUE/edit?usp=sharing", - "project_link": "https://github.com/acmucsd-projects/wi23-hack-team-1", - "other_links": "https://www.figma.com/file/lX9VzkvBHesJT4e2zK6LOr/IGFood-Web-App-Design?type=design&node-id=0%3A1&mode=design&t=Z6gg0vyLGspHj7r5-1" + Robotics: { + logo: "/assets/robotics.svg", + border: s.borderRobotics, + color: s.colorRobotics, + repoIcon: "/assets/embeds/github-icon.svg", + repoLabel: "GitHub File", }, - {"quarter": "Winter 2023", - "subgroup": "Design", - "project_title": "Triton2Go Redesign", - "team_name": "Team 1", - "description": "Recognizing the indispensable role of food ordering apps in the UCSD students’ daily lives, our team aimed to focus on the official food ordering mobile app Triton2Go (Mobile Order) by redesigning both the visual layouts and content layouts to optimize the user interface, streamline the ordering process, incorporate engaging gamification elements in rewards store to encourage user loyalty and satisfaction. We hope to help our target users and make the end process intelligent, enjoyable, and productive.", - "mentor": "Anmol", - "members": ["Cindy Peng (Project Lead)", "Thomas Wang", "Dianne Natanauan", "Amy To"], - "slides": "https://docs.google.com/presentation/d/1eCxEr19T1yPc1zffcvXHE9n0KPUSUy6G87tE_Ub_9Fk/edit?usp=sharing", - "project_link": "https://www.figma.com/file/0r2ncVSKHqBY9pOQCGrHvq/Mobile-Order-Prototypes?type=design&node-id=0%3A1&t=33a883iMHphAA1U1-1" - }, - {"quarter": "Fall 2022", - "subgroup": "AI", - "project_title": "Supreme Court Predictor", - "team_name": "Team 1", - "description": "Using machine learning, predict the outcomes of Supreme Court Cases (whether they are conservative, liberal, or unspecifiable).", - "mentor": "Stephanie", - "members": ["Jenny Mar", "Nitya Pillai", "Ada He", "Han Hoang", "Rushil Chandrupatla", "Serena Chen"], - "slides": "https://docs.google.com/presentation/d/1qANpLZvhv5F0lOkbUxtlJU5UF4KqsDzuy0Dy6E2BG-0/edit?usp=sharing", - "project_link": "https://github.com/acmucsd-projects/fa22-ai-team-1", - "other_links": "https://deepnote.com/join-team?token=02d34e715c9e4f6" - }, - {"quarter": "Fall 2022", - "subgroup": "AI", - "project_title": "GAIN: Gamers for Artificial Intelligence and NLP", - "team_name": "Team 2", - "description": "Using NLP and Machine Learning, created a Political Sentiment Classifier that can address blocks of texts and determine whether they are politically charged and classify them as Liberal or Democratic. ", - "mentor": "Weiji Chen", - "members": ["Samvrit Srinath", "Calvin Nguyen", "Peter Gao", "Benjamin Johnson", "Skyler Goh", "Joon Kim"], - "slides": "https://docs.google.com/presentation/d/1s7W3E9Wv5RXAzmgQYjCN166xycIJuxyFnCbs_IpVBlw/edit?usp=sharing", - "project_link": "https://github.com/acmucsd-projects/fa22-ai-team-2", - "other_links": "https://colab.research.google.com/drive/1zfL2UtCyJnwAMzqeAAvfTigUU6rVxCca?usp=sharing" - }, - {"quarter": "Fall 2022", - "subgroup": "Design", - "project_title": "UCSD App Redesign", - "team_name": "Team 1", - "description": "We redesigned the UCSD mobile app to increase its functionality and aesthetic appeal, helping students navigate it with more ease, efficiency, and less confusion.", - "mentor": "Anthony Manrique", - "members": ["Tammy Ding","Khoi Nguyen", "Caitlyn Cielo", "Sashwat Nayak"], - "slides": "https://docs.google.com/presentation/d/1NBU4o8cFqalW_I9UUo_t_h7XsHVtjGcQ7hVZUzqO0qg/edit?usp=sharing", - "project_link": "https://www.figma.com/file/8kuHJXTZcIGVjm88OCYi1W/Final-Draft?type=design&node-id=1%3A2&t=K7vUmdAhPcQpWj6O-1" - }, -]; +}; + +const DEFAULT_CONFIG = { + logo: "/assets/proj_logo.png", + border: "", + color: "", + repoIcon: "/assets/embeds/github-icon.svg", + repoLabel: "GitHub File", +}; interface ProjectProps { quarter: string; + highlighted?: boolean; + subgroup?: string | null; } -const ProjectCards: React.FC = ({quarter}) => { - const filteredProjects = quarter === "All" ? projects_data : projects_data.filter((project) => - project.quarter === quarter - ); +const ProjectCards: React.FC = ({ quarter, highlighted, subgroup }) => { + let projects = quarter === "All" + ? projects_data + : projects_data.filter((project) => project.quarter === quarter); + + if (subgroup) { + projects = projects.filter((project) => project.subgroup === subgroup); + } + + if (highlighted !== undefined) { + projects = projects.filter((project) => + highlighted ? highlighted_ids.includes(project.id) : !highlighted_ids.includes(project.id) + ); + } + + projects = [...projects].sort((a, b) => a.team_name.localeCompare(b.team_name)); + + const descWrapperRefs = useRef<(HTMLDivElement | null)[]>([]); + + const updateClamps = () => { + const wrappers = descWrapperRefs.current; + if (!wrappers) return; + for (const wrapper of wrappers) { + if (!wrapper) continue; + const p = wrapper.querySelector("p") as HTMLParagraphElement | null; + if (!p) continue; + p.style.webkitLineClamp = "unset"; + const availableHeight = wrapper.clientHeight; + const lineHeight = parseFloat(getComputedStyle(p).lineHeight); + const lines = Math.max(1, Math.floor(availableHeight / lineHeight)); + p.style.webkitLineClamp = String(lines); + } + }; + + useLayoutEffect(() => { updateClamps(); }, [projects.length]); + + useEffect(() => { + window.addEventListener("resize", updateClamps); + return () => window.removeEventListener("resize", updateClamps); + }, []); + return (
- {filteredProjects && filteredProjects.map((project, index) => ( -
-
-
- Community Logo -

{project.quarter} {project.subgroup} {project.team_name}

+ {projects.map((project, index) => { + const config = SUBGROUP_CONFIG[project.subgroup] ?? DEFAULT_CONFIG; + return ( +
+
+ {`${project.subgroup} +
+ {project.quarter} + {project.subgroup} {project.team_name} +
+
+ +
+ {project.project_title} +
+ +

{project.project_title}

+ +
+

Created by: {project.members.join(", ")}

+

Mentored by: {project.mentors.join(", ")}

+ {project.technology && ( +

Technology: {project.technology}

+ )} +
+ +
{ descWrapperRefs.current[index] = el; }} + > +

{project.description}

+
+ +
+ + Explore Project + + {project.project_link && ( + + {config.repoLabel} + {config.repoLabel} + + )}
-

{project.project_title}

-
- Project Logo -
-

Project Description: {project.description}

-

Members: {project.members.join(", ")}

-

Mentor: {project.mentor}

-
-
- - Slides Logo - - Project Repo Logo - {project.other_links && ( - Other Links Logo - )}
-
- ))} + ); + })}
- ) -} + ); +}; -export default ProjectCards; \ No newline at end of file +export default ProjectCards; diff --git a/src/components/project-card/projects.json b/src/components/project-card/projects.json new file mode 100644 index 0000000..7f461c0 --- /dev/null +++ b/src/components/project-card/projects.json @@ -0,0 +1,116 @@ +[ + { + "id": "sp23-hack-1", + "quarter": "Spring 2023", + "subgroup": "Hack", + "project_title": "Word Nerd", + "team_name": "Team 1", + "logo": "/assets/project_logos/word_nerd.png", + "description": "We created a clone of the game CodeNames, except that users have the option to upload their own words so they can follow a theme or use it as a unique way to study vocab concepts with friends.", + "mentors": ["Sujal"], + "members": ["Greg Weber", "Julie Nguyen", "Josh Chen", "Tim Liu", "Gonzalo Allen-Perez", "Annie Ping"], + "slides": "https://docs.google.com/presentation/d/1xPRnYbfmZHW8l7_jo7gmTAxowV3PmLO39MvzfHht_Dk/edit?usp=sharing", + "project_link": "https://github.com/acmucsd-projects/sp23-hack-team-1", + "other_links": "https://codenames-acm.netlify.app/", + "technology": null + }, + { + "id": "sp23-hack-2", + "quarter": "Spring 2023", + "subgroup": "Hack", + "project_title": "GAMED", + "team_name": "Team 2", + "logo": "/assets/project_logos/gamed.png", + "description": "We created a website where UCSD students can find other players to play video games with. They can do this by creating an account, creating cards, and sending cards to people!", + "mentors": ["Shreya Nagunuri", "Kevin Wu"], + "members": ["Calvin Nguyen", "Kane Li"], + "slides": "https://docs.google.com/presentation/d/1W-3JfpnNEghKXsuuCe1638ZBUkyCkntRNy6yUnFhr_4/edit?usp=sharing", + "project_link": "https://github.com/acmucsd-projects/sp23-hack-team-2", + "other_links": "https://ucsdgamed.onrender.com/", + "technology": null + }, + { + "id": "sp23-hack-3", + "quarter": "Spring 2023", + "subgroup": "Hack", + "project_title": "Eventify", + "team_name": "Team 3", + "logo": "/assets/project_logos/eventify.png", + "description": "We created a website that can track on-campus UCSD events.", + "mentors": ["Angela Hu", "Charvi Shukla"], + "members": ["Gavyn Ezell", "Cho Jung (Angela) Tsai", "Qijun (Mary) Hu", "Jae Whan Lee", "Rachel Chau", "Willey Zhou"], + "slides": "https://docs.google.com/presentation/d/1U93WsdyVuFDbvgWZ931oakEpL7zgzbZz8vNolmMZtFI/edit?usp=sharing", + "project_link": "https://github.com/acmucsd-projects/sp23-hack-team-3", + "other_links": "https://www.figma.com/file/KqvP7N6lLUu8NnT2ZnYK3o/Eventify?type=design&node-id=0%3A1&mode=design&t=hnFUTSx4agxe4CNT-1", + "technology": null + }, + { + "id": "wi23-hack-1", + "quarter": "Winter 2023", + "subgroup": "Hack", + "project_title": "IGFood", + "team_name": "Team 1", + "logo": "/assets/project_logos/ig_food.svg", + "description": "Yelp and Google Reviews are written by strangers that you cannot necessarily trust. Our solution is to create an application which creates a more personalized food-rating experience! The application connects you to your friends and allows you to see what/where your friends are eating via posts on a feed.", + "mentors": ["Nikhil Dange"], + "members": ["Angela Hu", "Nicholas Cheah", "Kinan Alatasi", "Alexis Vergnet", "Charvi Shukla", "Jason Wong"], + "slides": "https://docs.google.com/presentation/d/1g0pEKT7Rx_hoZDnC27zxxPs2UqipDLffgUC0Z0v5xUE/edit?usp=sharing", + "project_link": "https://github.com/acmucsd-projects/wi23-hack-team-1", + "other_links": "https://www.figma.com/file/lX9VzkvBHesJT4e2zK6LOr/IGFood-Web-App-Design?type=design&node-id=0%3A1&mode=design&t=Z6gg0vyLGspHj7r5-1", + "technology": null + }, + { + "id": "wi23-design-1", + "quarter": "Winter 2023", + "subgroup": "Design", + "project_title": "Triton2Go Redesign", + "team_name": "Team 1", + "description": "Recognizing the indispensable role of food ordering apps in the UCSD students' daily lives, our team aimed to focus on the official food ordering mobile app Triton2Go (Mobile Order) by redesigning both the visual layouts and content layouts to optimize the user interface, streamline the ordering process, incorporate engaging gamification elements in rewards store to encourage user loyalty and satisfaction. We hope to help our target users and make the end process intelligent, enjoyable, and productive.", + "mentors": ["Anmol"], + "members": ["Cindy Peng", "Thomas Wang", "Dianne Natanauan", "Amy To"], + "slides": "https://docs.google.com/presentation/d/1eCxEr19T1yPc1zffcvXHE9n0KPUSUy6G87tE_Ub_9Fk/edit?usp=sharing", + "project_link": "https://www.figma.com/file/0r2ncVSKHqBY9pOQCGrHvq/Mobile-Order-Prototypes?type=design&node-id=0%3A1&t=33a883iMHphAA1U1-1", + "technology": null + }, + { + "id": "fa22-ai-1", + "quarter": "Fall 2022", + "subgroup": "AI", + "project_title": "Supreme Court Predictor", + "team_name": "Team 1", + "description": "Using machine learning, predict the outcomes of Supreme Court Cases (whether they are conservative, liberal, or unspecifiable).", + "mentors": ["Stephanie"], + "members": ["Jenny Mar", "Nitya Pillai", "Ada He", "Han Hoang", "Rushil Chandrupatla", "Serena Chen"], + "slides": "https://docs.google.com/presentation/d/1qANpLZvhv5F0lOkbUxtlJU5UF4KqsDzuy0Dy6E2BG-0/edit?usp=sharing", + "project_link": "https://github.com/acmucsd-projects/fa22-ai-team-1", + "other_links": "https://deepnote.com/join-team?token=02d34e715c9e4f6", + "technology": null + }, + { + "id": "fa22-ai-2", + "quarter": "Fall 2022", + "subgroup": "AI", + "project_title": "GAIN: Gamers for Artificial Intelligence and NLP", + "team_name": "Team 2", + "description": "Using NLP and Machine Learning, created a Political Sentiment Classifier that can address blocks of texts and determine whether they are politically charged and classify them as Liberal or Democratic. ", + "mentors": ["Weiji Chen"], + "members": ["Samvrit Srinath", "Calvin Nguyen", "Peter Gao", "Benjamin Johnson", "Skyler Goh", "Joon Kim"], + "slides": "https://docs.google.com/presentation/d/1s7W3E9Wv5RXAzmgQYjCN166xycIJuxyFnCbs_IpVBlw/edit?usp=sharing", + "project_link": "https://github.com/acmucsd-projects/fa22-ai-team-2", + "other_links": "https://colab.research.google.com/drive/1zfL2UtCyJnwAMzqeAAvfTigUU6rVxCca?usp=sharing", + "technology": null + }, + { + "id": "fa22-design-1", + "quarter": "Fall 2022", + "subgroup": "Design", + "project_title": "UCSD App Redesign", + "team_name": "Team 1", + "description": "We redesigned the UCSD mobile app to increase its functionality and aesthetic appeal, helping students navigate it with more ease, efficiency, and less confusion.", + "mentors": ["Anthony Manrique"], + "members": ["Tammy Ding", "Khoi Nguyen", "Caitlyn Cielo", "Sashwat Nayak"], + "slides": "https://docs.google.com/presentation/d/1NBU4o8cFqalW_I9UUo_t_h7XsHVtjGcQ7hVZUzqO0qg/edit?usp=sharing", + "project_link": "https://www.figma.com/file/8kuHJXTZcIGVjm88OCYi1W/Final-Draft?type=design&node-id=1%3A2&t=K7vUmdAhPcQpWj6O-1", + "technology": null + } +] diff --git a/src/components/project-card/style.module.scss b/src/components/project-card/style.module.scss index 9efd54b..567917f 100644 --- a/src/components/project-card/style.module.scss +++ b/src/components/project-card/style.module.scss @@ -1,70 +1,215 @@ -@use "../../styles/vars.scss" as vars; // allows you to use pre-defined colors +@use "../../styles/vars.scss" as vars; .container { display: grid; - max-width: 95%; - margin: 0 auto; - grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); - margin-top: 2rem; - margin-bottom: 2rem; - row-gap: 2rem; - column-gap: 2rem; - - .projectItem { - background-color: vars.$darker-white; - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - text-decoration: none; - border-radius: 0.5rem; - padding: 1.5rem; - box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); + width: 100%; + grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr)); + gap: 2rem; +} + +.card { + display: flex; + flex-direction: column; + border: 2px solid; + border-radius: 0.5rem; + padding: 1.5rem; + background-color: vars.$white; + height: 42rem; +} + +.borderDesign { + border-color: vars.$pink; +} + +.borderHack { + border-color: vars.$orange; +} + +.borderAI { + border-color: vars.$red; +} + +.borderRobotics { + border-color: vars.$robotics-green; +} + +.cardHeader { + display: flex; + align-items: center; + gap: 0.75rem; + margin-bottom: 1.5rem; +} + +.teamLogo { + width: 4rem; + height: 4rem; + margin: -0.75rem 0 -0.75rem -0.5rem; +} + +.cardHeaderText { + display: flex; + flex-direction: column; + line-height: 1.2; +} + +.cardQuarter { + font-size: 0.875rem; + font-weight: 400; + color: vars.$black; +} + +.cardTeam { + font-size: 1.125rem; + font-weight: 700; + color: vars.$black; +} + +.projectImageWrapper { + width: 100%; + height: 14rem; + min-height: 14rem; + max-height: 14rem; + display: flex; + align-items: center; + justify-content: center; + border-radius: 0.5rem; + margin-bottom: 1rem; + overflow: hidden; + background-color: vars.$darker-white; + pointer-events: none; +} + +.projectImage { + width: 100%; + height: 100%; + object-fit: contain; + padding: 1rem; + margin: 0; +} + +.projectImageDefault { + width: 7rem; + height: 7rem; + object-fit: contain; + margin: 0; +} + +.projectTitle { + font-size: 1.5rem; + font-weight: 700; + margin: 0 0 0.75rem; +} + +.colorDesign { + color: vars.$pink; +} + +.colorHack { + color: vars.$orange; +} + +.colorAI { + color: vars.$red; +} + +.colorRobotics { + color: vars.$robotics-green; +} + +.projectDetails { + margin-bottom: 0.75rem; + + p { + margin: 0 0 0.25rem; + font-size: 0.875rem; + color: vars.$black; } - .header { - text-align: center; - .AI { - color: vars.$red; - font-size: 1.4rem; - } - .Hack { - color: vars.$orange; - font-size: 1.4rem; - } - .Design { - color: vars.$pink; - font-size: 1.4rem; - } - .team { - display: flex; - flex-direction: row; - align-items: center; - justify-content: center; - } - .community_logo { - width: 80px; - height: 80px; - padding-right: 1rem; - } +} + +.descriptionWrapper { + flex-grow: 1; + min-height: 0; + margin-bottom: 1.25rem; + overflow: clip; +} + +.projectDescription { + font-size: 0.875rem; + line-height: 1.5; + color: vars.$black; + margin: 0; + display: -webkit-box; + -webkit-box-orient: vertical; + overflow: hidden; + pointer-events: none; +} + +.cardActions { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; + align-items: center; +} + +.exploreButton { + display: inline-flex; + align-items: center; + padding: 0.4rem 1rem; + border-radius: 0.5rem; + font-size: 0.8rem; + font-weight: 600; + white-space: nowrap; + text-decoration: none; + color: vars.$white; + transition: opacity 0.2s; + + &.colorDesign { + background-color: vars.$pink; } - .logo { - object-fit: contain; - width: 100%; - height: 200px; - border-top-left-radius: 0.5rem; - border-top-right-radius: 0.5rem; + + &.colorHack { + background-color: vars.$orange; } - .description { - flex-grow: 1; + + &.colorAI { + background-color: vars.$red; + } + + &.colorRobotics { + background-color: vars.$robotics-green; } - .project_links { - display: flex; - flex-direction: row; - gap: 1rem; + + &:hover { + opacity: 0.85; } - .links { - object-fit: contain; - width: 100%; - height: 4rem; +} + +.repoButton { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.4rem; + padding: 0.4rem 1rem; + border-radius: 0.5rem; + box-shadow: inset 0 0 0 1.5px vars.$black; + font-size: 0.8rem; + font-weight: 600; + white-space: nowrap; + text-decoration: none; + color: vars.$black; + background-color: vars.$white; + transition: background-color 0.2s; + + &:hover { + background-color: vars.$darker-white; } -} \ No newline at end of file +} + +.repoIcon { + width: 1rem; + height: 1rem; + object-fit: contain; + display: block; + flex-shrink: 0; + margin: 0; +} diff --git a/src/sections/Archive/index.tsx b/src/sections/Archive/index.tsx index 52ce9ef..95be5de 100644 --- a/src/sections/Archive/index.tsx +++ b/src/sections/Archive/index.tsx @@ -3,23 +3,49 @@ import { useState } from 'react'; import s from './style.module.scss'; import ProjectCards from '../../components/project-card'; +const FILTERS = [ + { label: 'Design', className: s.filterDesign }, + { label: 'Hack', className: s.filterHack }, + { label: 'AI', className: s.filterAI }, + { label: 'Robotics', className: s.filterRobotics }, +]; + const Archive: React.FC = () => { const [quarter, setQuarter] = useState('All'); + const [activeFilter, setActiveFilter] = useState(null); return (
-

Past Project Archives

-
- +
+

Past Projects Archive

+ +
+
+ {FILTERS.map(({ label, className }) => ( + + ))} +
+
+

Highlighted Projects

+
+ +
+

Other Projects

- +
) } diff --git a/src/sections/Archive/style.module.scss b/src/sections/Archive/style.module.scss index 42e62de..44777ef 100644 --- a/src/sections/Archive/style.module.scss +++ b/src/sections/Archive/style.module.scss @@ -1,9 +1,140 @@ -@use "../../styles/vars.scss" as vars; // allows you to use pre-defined colors +@use "../../styles/vars.scss" as vars; .container { display: flex; flex-direction: column; align-items: center; margin-top: 2rem; - padding-top: 3rem; -} \ No newline at end of file + padding: 3rem vars.calc-relative-size(531px, 3.1875rem, 834px, 7.5rem); +} + +.headerRow { + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + gap: 1.25rem; + width: 100%; + margin-bottom: 2rem; +} + +.header { + font-size: 2.25rem; + font-weight: 800; + margin: 0; +} + +.project_selector { + appearance: none; + background: vars.$white url("/assets/chevron-down.svg") no-repeat right 0.75rem center; + border: 1.5px solid #5777C0; + border-radius: 0.75rem; + padding: 0.625rem 2rem 0.625rem 1.25rem; + font-size: 1rem; + color: vars.$black; + cursor: pointer; + outline: none; +} + +.filters { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; + align-self: flex-start; + margin-bottom: 2rem; +} + +.filterButton { + background: transparent; + border: 2px solid; + border-radius: 2rem; + padding: 0.5rem 2rem; + font-size: 1rem; + cursor: pointer; + font-weight: 500; + transition: background-color 0.2s; + white-space: nowrap; +} + +.filterDesign { + border-color: vars.$pink; + color: vars.$black; +} + +.filterHack { + border-color: vars.$orange; + color: vars.$black; +} + +.filterAI { + border-color: vars.$red; + color: vars.$black; +} + +.filterRobotics { + border-color: vars.$robotics-green; + color: vars.$black; +} + +.filterActive { + &.filterDesign { + background-color: rgba(vars.$pink, 0.15); + } + &.filterHack { + background-color: rgba(vars.$orange, 0.15); + } + &.filterAI { + background-color: rgba(vars.$red, 0.15); + } + &.filterRobotics { + background-color: rgba(vars.$robotics-green, 0.15); + } +} + +.subheadingRow { + display: flex; + align-items: baseline; + gap: 1rem; + align-self: flex-start; + margin-top: 2rem; + margin-bottom: 1.5rem; +} + +.subheading { + font-size: 1.5rem; + font-weight: 700; + margin: 0; + color: vars.$black; +} + +.dateLabel { + font-size: 1rem; + color: vars.$dark-gray; +} + +@media only screen and (max-width: 530px) { + .headerRow { + flex-direction: column; + align-items: center; + gap: 1.25rem; + } + + .header { + text-align: center; + font-size: 1.75rem; + white-space: nowrap; + } + + .filters { + flex-direction: column; + align-items: center; + align-self: center; + width: 100%; + } + + .filterButton { + width: 55%; + text-align: center; + } +} + diff --git a/src/sections/ProjectDetail/index.tsx b/src/sections/ProjectDetail/index.tsx new file mode 100644 index 0000000..7f5dfd4 --- /dev/null +++ b/src/sections/ProjectDetail/index.tsx @@ -0,0 +1,126 @@ +'use client' +import Link from 'next/link'; +import s from './style.module.scss'; +import projects_data from '../../components/project-card/projects.json'; + +const SUBGROUP_CONFIG: Record = { + Design: { + logo: "/assets/design.svg", + border: s.borderDesign, + color: s.colorDesign, + repoIcon: "/assets/embeds/figma-icon.svg", + repoLabel: "Figma File", + }, + Hack: { + logo: "/assets/hack.svg", + border: s.borderHack, + color: s.colorHack, + repoIcon: "/assets/embeds/github-icon.svg", + repoLabel: "GitHub File", + }, + AI: { + logo: "/assets/ai.svg", + border: s.borderAI, + color: s.colorAI, + repoIcon: "/assets/embeds/github-icon.svg", + repoLabel: "GitHub File", + }, + Robotics: { + logo: "/assets/robotics.svg", + border: s.borderRobotics, + color: s.colorRobotics, + repoIcon: "/assets/embeds/github-icon.svg", + repoLabel: "GitHub File", + }, +}; + +const DEFAULT_CONFIG = { + logo: "/assets/proj_logo.png", + border: "", + color: "", + repoIcon: "/assets/embeds/github-icon.svg", + repoLabel: "GitHub File", +}; + +interface ProjectDetailProps { + slug: string; +} + +const ProjectDetail: React.FC = ({ slug }) => { + const project = projects_data.find( + (p) => p.project_title.toLowerCase().replace(/\s+/g, "-") === slug + ); + + if (!project) { + return ( +
+ Back to Archive +

Project not found

+
+ ); + } + + const config = SUBGROUP_CONFIG[project.subgroup] ?? DEFAULT_CONFIG; + + return ( +
+ Back to Archive + +
+
+ {`${project.subgroup} +
+ {project.quarter} + {project.subgroup} {project.team_name} +
+
+ +
+ {project.project_title} +
+ +

{project.project_title}

+ +
+

Created by: {project.members.join(", ")}

+

Mentored by: {project.mentors.join(", ")}

+ {project.technology && ( +

Technology: {project.technology}

+ )} +
+ +

{project.description}

+ +
+ + {config.repoLabel} + {config.repoLabel} + + {project.slides && ( + + Slides + Slides + + )} + {project.other_links && ( + + Additional Link + + )} +
+
+
+ ); +}; + +export default ProjectDetail; diff --git a/src/sections/ProjectDetail/style.module.scss b/src/sections/ProjectDetail/style.module.scss new file mode 100644 index 0000000..d905d26 --- /dev/null +++ b/src/sections/ProjectDetail/style.module.scss @@ -0,0 +1,219 @@ +@use "../../styles/vars.scss" as vars; + +$stmw: 834px; +$mmw: 530px; + +.container { + display: flex; + flex-direction: column; + align-items: center; + padding: 3rem 7.5rem; + min-height: 60vh; +} + +@media only screen and (max-width: $stmw) { + .container { + padding: + 3rem + vars.calc-relative-size($mmw + 1px, 3.1875rem, $stmw, 7.5rem); + } +} + +@media only screen and (max-width: $mmw) { + .container { + padding: 3rem 3.1875rem; + } +} + +.backLink { + align-self: flex-start; + font-size: 1rem; + font-weight: 600; + color: vars.$proj-blue; + text-decoration: none; + margin-bottom: 2rem; + + &:hover { + text-decoration: underline; + } +} + +.notFound { + font-size: 1.5rem; + color: vars.$black; +} + +.detail { + display: flex; + flex-direction: column; + width: 100%; + max-width: 48rem; + border: 2px solid; + border-radius: 0.75rem; + padding: 2.5rem; + background-color: vars.$white; +} + +.borderDesign { + border-color: vars.$pink; +} + +.borderHack { + border-color: vars.$orange; +} + +.borderAI { + border-color: vars.$red; +} + +.borderRobotics { + border-color: vars.$robotics-green; +} + +.header { + display: flex; + align-items: center; + gap: 0.75rem; + margin-bottom: 1.5rem; +} + +.subgroupLogo { + width: 4rem; + height: 4rem; + margin: -0.75rem 0 -0.75rem -0.5rem; +} + +.headerText { + display: flex; + flex-direction: column; + line-height: 1.2; +} + +.quarter { + font-size: 0.875rem; + font-weight: 400; + color: vars.$black; +} + +.teamName { + font-size: 1.25rem; + font-weight: 700; + color: vars.$black; +} + +.imageWrapper { + width: 100%; + height: 20rem; + display: flex; + align-items: center; + justify-content: center; + border-radius: 0.5rem; + margin-bottom: 1.5rem; + overflow: hidden; + background-color: #f5f5f5; + pointer-events: none; +} + +.projectImage { + width: 100%; + height: 100%; + object-fit: contain; + padding: 1rem; + margin: 0; +} + +.projectImageDefault { + width: 8rem; + height: 8rem; + object-fit: contain; + margin: 0; +} + +.title { + font-size: 2rem; + font-weight: 700; + margin: 0 0 1rem; +} + +.colorDesign { + color: vars.$pink; +} + +.colorHack { + color: vars.$orange; +} + +.colorAI { + color: vars.$red; +} + +.colorRobotics { + color: vars.$robotics-green; +} + +.meta { + margin-bottom: 1.25rem; + + p { + margin: 0 0 0.375rem; + font-size: 1rem; + color: vars.$black; + } +} + +.description { + font-size: 1rem; + line-height: 1.6; + color: vars.$black; + margin: 0 0 2rem; +} + +.links { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; +} + +.repoButton { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.4rem; + padding: 0.5rem 1.25rem; + border-radius: 0.5rem; + box-shadow: inset 0 0 0 1.5px vars.$black; + font-size: 0.875rem; + font-weight: 600; + white-space: nowrap; + text-decoration: none; + color: vars.$black; + background-color: vars.$white; + transition: background-color 0.2s; + + &:hover { + background-color: vars.$darker-white; + } +} + +.repoIcon { + width: 1rem; + height: 1rem; + object-fit: contain; + display: block; + flex-shrink: 0; + margin: 0; +} + +@media only screen and (max-width: $mmw) { + .detail { + padding: 1.5rem; + } + + .imageWrapper { + height: 14rem; + } + + .title { + font-size: 1.5rem; + } +} diff --git a/src/styles/vars.scss b/src/styles/vars.scss index d401e69..ce34db3 100644 --- a/src/styles/vars.scss +++ b/src/styles/vars.scss @@ -13,6 +13,7 @@ $dark-gray: #8d8d8d; $hover-blue: #7cbdff; $turquoise: #51c0c0; $purple: #816dff; +$robotics-green: #9EC284; $black: #333333; $acm-blue-30: #a8d3ff; $acm-blue: #62b0ff; diff --git a/tsconfig.json b/tsconfig.json index b09cc80..7ec35fb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,7 +15,7 @@ "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "react-jsx", + "jsx": "preserve", "incremental": true, "plugins": [ {