diff --git a/package-lock.json b/package-lock.json index 73ca762..a62a4cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,11 @@ "name": "pse-website", "version": "0.1.0", "dependencies": { + "@radix-ui/react-slot": "^1.2.4", "@tanstack/react-query": "5.69.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "embla-carousel-react": "^8.6.0", "lucide-react": "^0.484.0", "motion": "^12.23.24", "next": "^15.5.6", @@ -1073,6 +1075,24 @@ } } }, + "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-arrow": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", @@ -1226,6 +1246,24 @@ } } }, + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", @@ -1316,6 +1354,24 @@ } } }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-direction": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", @@ -1557,6 +1613,24 @@ } } }, + "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-menubar": { "version": "1.1.16", "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.16.tgz", @@ -1721,6 +1795,24 @@ } } }, + "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", @@ -1820,6 +1912,24 @@ } } }, + "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-progress": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.7.tgz", @@ -1976,6 +2086,24 @@ } } }, + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-separator": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", @@ -2031,9 +2159,10 @@ } }, "node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", + "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, @@ -2250,6 +2379,24 @@ } } }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", @@ -3703,6 +3850,34 @@ "node": ">= 0.4" } }, + "node_modules/embla-carousel": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz", + "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==", + "license": "MIT" + }, + "node_modules/embla-carousel-react": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.6.0.tgz", + "integrity": "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==", + "license": "MIT", + "dependencies": { + "embla-carousel": "8.6.0", + "embla-carousel-reactive-utils": "8.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/embla-carousel-reactive-utils": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.6.0.tgz", + "integrity": "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==", + "license": "MIT", + "peerDependencies": { + "embla-carousel": "8.6.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.18.3", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", @@ -6172,6 +6347,24 @@ } } }, + "node_modules/radix-ui/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react": { "version": "19.2.0", "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", diff --git a/package.json b/package.json index dc76a3f..3de1f6a 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,11 @@ "prepare": "husky" }, "dependencies": { + "@radix-ui/react-slot": "^1.2.4", "@tanstack/react-query": "5.69.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "embla-carousel-react": "^8.6.0", "lucide-react": "^0.484.0", "motion": "^12.23.24", "next": "^15.5.6", diff --git a/public/overview/FDH1.webp b/public/overview/FDH1.webp new file mode 100644 index 0000000..aaddf2e Binary files /dev/null and b/public/overview/FDH1.webp differ diff --git a/public/overview/FDH2.webp b/public/overview/FDH2.webp new file mode 100644 index 0000000..5f5927d Binary files /dev/null and b/public/overview/FDH2.webp differ diff --git a/public/overview/FDH3.webp b/public/overview/FDH3.webp new file mode 100644 index 0000000..6804072 Binary files /dev/null and b/public/overview/FDH3.webp differ diff --git a/public/overview/FDH4.webp b/public/overview/FDH4.webp new file mode 100644 index 0000000..4b98fb1 Binary files /dev/null and b/public/overview/FDH4.webp differ diff --git a/public/overview/FDH5.webp b/public/overview/FDH5.webp new file mode 100644 index 0000000..46e9aa6 Binary files /dev/null and b/public/overview/FDH5.webp differ diff --git a/public/overview/FDH6.webp b/public/overview/FDH6.webp new file mode 100644 index 0000000..eade29e Binary files /dev/null and b/public/overview/FDH6.webp differ diff --git a/public/overview/FDH7.webp b/public/overview/FDH7.webp new file mode 100644 index 0000000..84fe52a Binary files /dev/null and b/public/overview/FDH7.webp differ diff --git a/public/overview/FDH8.webp b/public/overview/FDH8.webp new file mode 100644 index 0000000..2616756 Binary files /dev/null and b/public/overview/FDH8.webp differ diff --git a/public/overview/FDH9.webp b/public/overview/FDH9.webp new file mode 100644 index 0000000..d25af93 Binary files /dev/null and b/public/overview/FDH9.webp differ diff --git a/public/overview/PSEInsightEvent.webp b/public/overview/PSEInsightEvent.webp new file mode 100644 index 0000000..86bbc67 Binary files /dev/null and b/public/overview/PSEInsightEvent.webp differ diff --git a/public/overview/SHARP1.webp b/public/overview/SHARP1.webp new file mode 100644 index 0000000..44c339d Binary files /dev/null and b/public/overview/SHARP1.webp differ diff --git a/public/overview/SHARP2.webp b/public/overview/SHARP2.webp new file mode 100644 index 0000000..aa8f58e Binary files /dev/null and b/public/overview/SHARP2.webp differ diff --git a/public/overview/SHARP3.webp b/public/overview/SHARP3.webp new file mode 100644 index 0000000..e49a625 Binary files /dev/null and b/public/overview/SHARP3.webp differ diff --git a/public/overview/SHARP4.webp b/public/overview/SHARP4.webp new file mode 100644 index 0000000..c3007f4 Binary files /dev/null and b/public/overview/SHARP4.webp differ diff --git a/public/overview/SHARP5.webp b/public/overview/SHARP5.webp new file mode 100644 index 0000000..000ae94 Binary files /dev/null and b/public/overview/SHARP5.webp differ diff --git a/public/overview/Spring1.webp b/public/overview/Spring1.webp new file mode 100644 index 0000000..5f9daa8 Binary files /dev/null and b/public/overview/Spring1.webp differ diff --git a/public/overview/Spring10.webp b/public/overview/Spring10.webp new file mode 100644 index 0000000..3a11151 Binary files /dev/null and b/public/overview/Spring10.webp differ diff --git a/public/overview/Spring2.webp b/public/overview/Spring2.webp new file mode 100644 index 0000000..c82ac99 Binary files /dev/null and b/public/overview/Spring2.webp differ diff --git a/public/overview/Spring3.webp b/public/overview/Spring3.webp new file mode 100644 index 0000000..14258f7 Binary files /dev/null and b/public/overview/Spring3.webp differ diff --git a/public/overview/Spring4.webp b/public/overview/Spring4.webp new file mode 100644 index 0000000..f981848 Binary files /dev/null and b/public/overview/Spring4.webp differ diff --git a/public/overview/Spring5.webp b/public/overview/Spring5.webp new file mode 100644 index 0000000..4dadd3f Binary files /dev/null and b/public/overview/Spring5.webp differ diff --git a/public/overview/Spring6.webp b/public/overview/Spring6.webp new file mode 100644 index 0000000..b8ef92e Binary files /dev/null and b/public/overview/Spring6.webp differ diff --git a/public/overview/Spring7.webp b/public/overview/Spring7.webp new file mode 100644 index 0000000..aa14edd Binary files /dev/null and b/public/overview/Spring7.webp differ diff --git a/public/overview/Spring8.webp b/public/overview/Spring8.webp new file mode 100644 index 0000000..85986a9 Binary files /dev/null and b/public/overview/Spring8.webp differ diff --git a/public/overview/Spring9.webp b/public/overview/Spring9.webp new file mode 100644 index 0000000..b31e5d6 Binary files /dev/null and b/public/overview/Spring9.webp differ diff --git a/public/overview/UCLAXUCR1.webp b/public/overview/UCLAXUCR1.webp new file mode 100644 index 0000000..6a1544a Binary files /dev/null and b/public/overview/UCLAXUCR1.webp differ diff --git a/public/overview/UCLAXUCR2.webp b/public/overview/UCLAXUCR2.webp new file mode 100644 index 0000000..17894fd Binary files /dev/null and b/public/overview/UCLAXUCR2.webp differ diff --git a/public/overview/UCLAXUCR3.webp b/public/overview/UCLAXUCR3.webp new file mode 100644 index 0000000..2c912a0 Binary files /dev/null and b/public/overview/UCLAXUCR3.webp differ diff --git a/public/overview/UCLAXUCR4.webp b/public/overview/UCLAXUCR4.webp new file mode 100644 index 0000000..86104e1 Binary files /dev/null and b/public/overview/UCLAXUCR4.webp differ diff --git a/public/overview/UCLAXUCR5.webp b/public/overview/UCLAXUCR5.webp new file mode 100644 index 0000000..009ca52 Binary files /dev/null and b/public/overview/UCLAXUCR5.webp differ diff --git a/src/app/board/page.tsx b/src/app/board/page.tsx index b304876..7268192 100644 --- a/src/app/board/page.tsx +++ b/src/app/board/page.tsx @@ -1,10 +1,12 @@ import BoardGrid from "@/components/board/BoardGrid"; +import TitleComp from "@/components/TitleComp"; const ExecutiveBoardPage = () => { return ( -
+ <> + -
+ ); }; export default ExecutiveBoardPage; diff --git a/src/app/join/page.tsx b/src/app/join/page.tsx index 89962bc..909c694 100644 --- a/src/app/join/page.tsx +++ b/src/app/join/page.tsx @@ -1,11 +1,11 @@ -import Testimonials from "@/components/join/testimonials"; +import Testimonials from "@/components/joinus/testimonials"; import InterestSection from "@/components/landing/InterestSection"; import TitleComp from "@/components/TitleComp"; const JoinUs = () => { return ( <> - + diff --git a/src/app/overviews/page.tsx b/src/app/overviews/page.tsx new file mode 100644 index 0000000..4513644 --- /dev/null +++ b/src/app/overviews/page.tsx @@ -0,0 +1,12 @@ +import TitleComp from "@/components/TitleComp"; +import { EventSections } from "@/components/overviews/EventSections"; + +const EventOverviews = () => { + return ( + <> + + + + ); +}; +export default EventOverviews; diff --git a/src/app/page.tsx b/src/app/page.tsx index e21ddeb..69e0c25 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -3,6 +3,7 @@ import PSEBanner from "@/components/landing/PSEBanner"; import Principles from "@/components/landing/Principles"; import OurMission from "@/components/landing/ourmission"; +import PhotoGallery from "@/components/landing/PhotoGallery"; const Home = () => { return ( @@ -10,6 +11,7 @@ const Home = () => { + ); }; diff --git a/src/components/Carousel.tsx b/src/components/Carousel.tsx new file mode 100644 index 0000000..43b2ce6 --- /dev/null +++ b/src/components/Carousel.tsx @@ -0,0 +1,37 @@ +import * as React from "react"; + +import { Card, CardContent } from "@/components/ui/card"; +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "@/components/ui/carousel"; + +export function CarouselSize() { + return ( + + + {Array.from({ length: 5 }).map((_, index) => ( + +
+ + + {index + 1} + + +
+
+ ))} +
+ + +
+ ); +} diff --git a/src/components/TitleComp.tsx b/src/components/TitleComp.tsx index 1eb6bbe..49e6c4b 100644 --- a/src/components/TitleComp.tsx +++ b/src/components/TitleComp.tsx @@ -7,14 +7,14 @@ interface TitleProp { const TitleComp = (props: TitleProp) => { return ( -
+
TitleComp -

+

{props.title}

diff --git a/src/components/joinus/testimonialcard.tsx b/src/components/joinus/testimonialcard.tsx new file mode 100644 index 0000000..59222ef --- /dev/null +++ b/src/components/joinus/testimonialcard.tsx @@ -0,0 +1,47 @@ +import Image, { StaticImageData } from "next/image"; + +interface TestimonialProps { + name: string; + classInfo: string; + quote: string; + image: StaticImageData; + reverse?: boolean; +} + +const TestimonialCard = ({ + name, + classInfo, + quote, + image, + reverse = false, +}: TestimonialProps) => { + return ( +
+
+ {`${name} +
+ +
+

+ {name}, {classInfo} +

+ +

+ {quote} +

+
+
+ ); +}; + +export default TestimonialCard; diff --git a/src/components/join/testimonials.tsx b/src/components/joinus/testimonials.tsx similarity index 100% rename from src/components/join/testimonials.tsx rename to src/components/joinus/testimonials.tsx diff --git a/src/components/landing/PhotoGallery.tsx b/src/components/landing/PhotoGallery.tsx new file mode 100644 index 0000000..6193396 --- /dev/null +++ b/src/components/landing/PhotoGallery.tsx @@ -0,0 +1,67 @@ +import { EventCarousel } from "@/components/overviews/EventCarousel"; +import Group1 from "@/public/gallery/group1.webp"; +import Group2 from "@/public/gallery/group2.webp"; +import Group3 from "@/public/gallery/group3.webp"; +import Group4 from "@/public/gallery/group4.webp"; +import Group5 from "@/public/gallery/group5.webp"; +import Group6 from "@/public/gallery/group6.webp"; +import Group7 from "@/public/gallery/group7.webp"; +import Group8 from "@/public/gallery/group8.webp"; +import Group9 from "@/public/gallery/group9.webp"; +import Group10 from "@/public/gallery/group10.webp"; +import Group11 from "@/public/gallery/group11.webp"; +import Group12 from "@/public/gallery/group12.webp"; +import Group13 from "@/public/gallery/group13.webp"; +import Group14 from "@/public/gallery/group14.webp"; +import Group15 from "@/public/gallery/group15.webp"; +import Group16 from "@/public/gallery/group16.webp"; +import Group17 from "@/public/gallery/group17.webp"; +import Group18 from "@/public/gallery/group18.webp"; +import Group19 from "@/public/gallery/group19.webp"; +import Group20 from "@/public/gallery/group20.webp"; +import Group21 from "@/public/gallery/group21.webp"; +import Group22 from "@/public/gallery/group22.webp"; +import Group23 from "@/public/gallery/group23.webp"; +import Group24 from "@/public/gallery/group24.webp"; +import Group25 from "@/public/gallery/group25.webp"; + +const images = [ + Group1, + Group2, + Group3, + Group4, + Group5, + Group6, + Group7, + Group8, + Group9, + Group10, + Group11, + Group12, + Group13, + Group14, + Group15, + Group16, + Group17, + Group18, + Group19, + Group20, + Group21, + Group22, + Group23, + Group24, + Group25, +]; + +const PhotoGallery = () => { + return ( +
+

+ Photo Gallery +

+ +
+ ); +}; + +export default PhotoGallery; diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index c967c42..8f07591 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -5,7 +5,7 @@ import Image from "next/image"; import Link from "next/link"; import { usePathname } from "next/navigation"; import pseLogo from "@/../public/PSE-Gradient-Logo-3.webp"; -import { tags } from "@/components/data/navBar"; +import { tags } from "@/data/navBar"; const Navbar = () => { const pathname = usePathname(); diff --git a/src/components/overviews/EventCarousel.tsx b/src/components/overviews/EventCarousel.tsx new file mode 100644 index 0000000..cb40adb --- /dev/null +++ b/src/components/overviews/EventCarousel.tsx @@ -0,0 +1,56 @@ +"use client"; + +import { Card, CardContent } from "@/components/ui/card"; +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "@/components/ui/carousel"; +import Image, { StaticImageData } from "next/image"; + +type EventCarouselProps = { + images: StaticImageData[]; +}; + +export function EventCarousel({ images }: EventCarouselProps) { + const items = + images.length === 1 + ? [...images, ...images, ...images, ...images, ...images] + : images; + + return ( + + + {items.map((img, idx) => ( + +
+ + +
+ {`Event +
+
+
+
+
+ ))} +
+ + + +
+ ); +} diff --git a/src/components/overviews/EventSection.tsx b/src/components/overviews/EventSection.tsx new file mode 100644 index 0000000..3f43b8d --- /dev/null +++ b/src/components/overviews/EventSection.tsx @@ -0,0 +1,30 @@ +import { EventItem } from "@/data/events"; +import { EventCarousel } from "./EventCarousel"; + +type EventSectionProps = EventItem; + +export function EventSection({ + title, + date, + description, + images, +}: EventSectionProps) { + return ( +
+
+
+

+ {title} +

+

+ {date} +

+
+
+

+ {description} +

+ +
+ ); +} diff --git a/src/components/overviews/EventSections.tsx b/src/components/overviews/EventSections.tsx new file mode 100644 index 0000000..fd82a90 --- /dev/null +++ b/src/components/overviews/EventSections.tsx @@ -0,0 +1,12 @@ +import { events } from "@/data/events"; +import { EventSection } from "./EventSection"; + +export function EventSections() { + return ( +
+ {events.map((event, index) => ( + + ))} +
+ ); +} diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx new file mode 100644 index 0000000..1dd187c --- /dev/null +++ b/src/components/ui/button.tsx @@ -0,0 +1,60 @@ +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "@/lib/utils"; + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: + "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: + "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2 has-[>svg]:px-3", + sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", + lg: "h-10 rounded-md px-6 has-[>svg]:px-4", + icon: "size-9", + "icon-sm": "size-8", + "icon-lg": "size-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, +); + +function Button({ + className, + variant, + size, + asChild = false, + ...props +}: React.ComponentProps<"button"> & + VariantProps & { + asChild?: boolean; + }) { + const Comp = asChild ? Slot : "button"; + + return ( + + ); +} + +export { Button, buttonVariants }; diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx new file mode 100644 index 0000000..19bb13c --- /dev/null +++ b/src/components/ui/card.tsx @@ -0,0 +1,92 @@ +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +function Card({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function CardHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function CardTitle({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function CardDescription({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function CardAction({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function CardContent({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function CardFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +export { + Card, + CardHeader, + CardFooter, + CardTitle, + CardAction, + CardDescription, + CardContent, +}; diff --git a/src/components/ui/carousel.tsx b/src/components/ui/carousel.tsx new file mode 100644 index 0000000..f069328 --- /dev/null +++ b/src/components/ui/carousel.tsx @@ -0,0 +1,241 @@ +"use client"; + +import * as React from "react"; +import useEmblaCarousel, { + type UseEmblaCarouselType, +} from "embla-carousel-react"; +import { ArrowLeft, ArrowRight } from "lucide-react"; + +import { cn } from "@/lib/utils"; +import { Button } from "@/components/ui/button"; + +type CarouselApi = UseEmblaCarouselType[1]; +type UseCarouselParameters = Parameters; +type CarouselOptions = UseCarouselParameters[0]; +type CarouselPlugin = UseCarouselParameters[1]; + +type CarouselProps = { + opts?: CarouselOptions; + plugins?: CarouselPlugin; + orientation?: "horizontal" | "vertical"; + setApi?: (api: CarouselApi) => void; +}; + +type CarouselContextProps = { + carouselRef: ReturnType[0]; + api: ReturnType[1]; + scrollPrev: () => void; + scrollNext: () => void; + canScrollPrev: boolean; + canScrollNext: boolean; +} & CarouselProps; + +const CarouselContext = React.createContext(null); + +function useCarousel() { + const context = React.useContext(CarouselContext); + + if (!context) { + throw new Error("useCarousel must be used within a "); + } + + return context; +} + +function Carousel({ + orientation = "horizontal", + opts, + setApi, + plugins, + className, + children, + ...props +}: React.ComponentProps<"div"> & CarouselProps) { + const [carouselRef, api] = useEmblaCarousel( + { + ...opts, + axis: orientation === "horizontal" ? "x" : "y", + }, + plugins, + ); + const [canScrollPrev, setCanScrollPrev] = React.useState(false); + const [canScrollNext, setCanScrollNext] = React.useState(false); + + const onSelect = React.useCallback((api: CarouselApi) => { + if (!api) return; + setCanScrollPrev(api.canScrollPrev()); + setCanScrollNext(api.canScrollNext()); + }, []); + + const scrollPrev = React.useCallback(() => { + api?.scrollPrev(); + }, [api]); + + const scrollNext = React.useCallback(() => { + api?.scrollNext(); + }, [api]); + + const handleKeyDown = React.useCallback( + (event: React.KeyboardEvent) => { + if (event.key === "ArrowLeft") { + event.preventDefault(); + scrollPrev(); + } else if (event.key === "ArrowRight") { + event.preventDefault(); + scrollNext(); + } + }, + [scrollPrev, scrollNext], + ); + + React.useEffect(() => { + if (!api || !setApi) return; + setApi(api); + }, [api, setApi]); + + React.useEffect(() => { + if (!api) return; + onSelect(api); + api.on("reInit", onSelect); + api.on("select", onSelect); + + return () => { + api?.off("select", onSelect); + }; + }, [api, onSelect]); + + return ( + +
+ {children} +
+
+ ); +} + +function CarouselContent({ className, ...props }: React.ComponentProps<"div">) { + const { carouselRef, orientation } = useCarousel(); + + return ( +
+
+
+ ); +} + +function CarouselItem({ className, ...props }: React.ComponentProps<"div">) { + const { orientation } = useCarousel(); + + return ( +
+ ); +} + +function CarouselPrevious({ + className, + variant = "outline", + size = "icon", + ...props +}: React.ComponentProps) { + const { orientation, scrollPrev, canScrollPrev } = useCarousel(); + + return ( + + ); +} + +function CarouselNext({ + className, + variant = "outline", + size = "icon", + ...props +}: React.ComponentProps) { + const { orientation, scrollNext, canScrollNext } = useCarousel(); + + return ( + + ); +} + +export { + type CarouselApi, + Carousel, + CarouselContent, + CarouselItem, + CarouselPrevious, + CarouselNext, +}; diff --git a/src/data/events.ts b/src/data/events.ts new file mode 100644 index 0000000..1ec0bd2 --- /dev/null +++ b/src/data/events.ts @@ -0,0 +1,87 @@ +import { StaticImageData } from "next/image"; +import FDH1 from "@/public/overview/FDH1.webp"; +import FDH2 from "@/public/overview/FDH2.webp"; +import FDH3 from "@/public/overview/FDH3.webp"; +import FDH4 from "@/public/overview/FDH4.webp"; +import FDH5 from "@/public/overview/FDH5.webp"; +import FDH6 from "@/public/overview/FDH6.webp"; +import FDH7 from "@/public/overview/FDH7.webp"; +import FDH8 from "@/public/overview/FDH8.webp"; +import FDH9 from "@/public/overview/FDH9.webp"; +import PSEInsightEvent from "@/public/overview/PSEInsightEvent.webp"; +import SHARP1 from "@/public/overview/SHARP1.webp"; +import SHARP2 from "@/public/overview/SHARP2.webp"; +import SHARP3 from "@/public/overview/SHARP3.webp"; +import SHARP4 from "@/public/overview/SHARP4.webp"; +import SHARP5 from "@/public/overview/SHARP5.webp"; +import Spring1 from "@/public/overview/Spring1.webp"; +import Spring2 from "@/public/overview/Spring2.webp"; +import Spring3 from "@/public/overview/Spring3.webp"; +import Spring4 from "@/public/overview/Spring4.webp"; +import Spring5 from "@/public/overview/Spring5.webp"; +import Spring6 from "@/public/overview/Spring6.webp"; +import Spring7 from "@/public/overview/Spring7.webp"; +import Spring8 from "@/public/overview/Spring8.webp"; +import Spring9 from "@/public/overview/Spring9.webp"; +import Spring10 from "@/public/overview/Spring10.webp"; +import UCLAXUCR1 from "@/public/overview/UCLAXUCR1.webp"; +import UCLAXUCR2 from "@/public/overview/UCLAXUCR2.webp"; +import UCLAXUCR3 from "@/public/overview/UCLAXUCR3.webp"; +import UCLAXUCR4 from "@/public/overview/UCLAXUCR4.webp"; +import UCLAXUCR5 from "@/public/overview/UCLAXUCR5.webp"; + +export interface EventItem { + title: string; + date: string; + description: string; + images: StaticImageData[]; +} + +export const events: EventItem[] = [ + { + title: "Spring Recruitment 2025", + date: "April 7-9, 2025", + description: + "PSE holds recruitment every fall and spring quarter of the academic year. In the span of three days, PSE hosts three professional and social events for potential new members to meet the active members. Potential new members then submit an application to be invited to an interview to join PSE. Info Night allows potential new members to learn about PSE’s principles and what we’re all about. Speed Networking/Game Night encourages potential new members to step out of their comfort zone by growing their personal and professional connections with active members. Game Night lets potential new members put their sales and creativity skills to the test, who knows…you might win! BBQ with the Bros lets potential new members and active members mingle over food and games! Recruitment is a fun outlet to step out of your comfort zone and get to know the people of PSE!", + images: [ + Spring1, + Spring2, + Spring3, + Spring4, + Spring5, + Spring6, + Spring7, + Spring8, + Spring9, + Spring10, + ], + }, + { + title: "Meta Guest Speakers", + date: "November 22, 2024", + description: + "At this particular speaker event, we were joined by employees from Meta, Amazon Web Services, EPIC, and MindgruveMacarta who came and shared their experience with their current positions and insight into how they made it there. PSE members got the opportunity to talk with them afterwards and gain valuable insight into their respective fields as well as set up opportunities to connect with them outside of the event.", + images: [PSEInsightEvent], + }, + { + title: "UCR x UCLA PSE Collab", + date: "May 9, 2025", + description: + "UCR PSE and UCLA PSE came together for a collaborative event at Dockweiler State Beach centered around connection, community, and fun. What started as a simple meetup turned into a meaningful opportunity to network, build friendships, and expand the reach of our organization. By bringing together two unique chapters, we were able to celebrate diversity, strengthen our presence, and show the power of cross-campus unity.", + images: [UCLAXUCR1, UCLAXUCR2, UCLAXUCR3, UCLAXUCR4, UCLAXUCR5], + }, + { + title: "FDH Guest Speaker and Resume Workshop Event", + date: "October 7, 2025", + description: + "As one of our Fall recruitment events open to all UCR students, we hosted guest speakers from FDH, a global supply-chain company. Their team provided an insightful overview of the company and shared valuable career advice for students exploring different professional paths. Following the speaker session, we led a resume workshop where we highlighted the key components of an effective resume and reviewed sample examples with participants.", + images: [FDH1, FDH2, FDH3, FDH4, FDH5, FDH6, FDH7, FDH8, FDH9], + }, + { + title: "SHARP Collab", + date: "October 30, 2025", + description: + "As part of our fraternity’s philanthropy efforts, we collaborated with SHARP UCR and several other organizations to create peanut butter and jelly sandwiches for individuals in need. This event allowed us to give back to the community while also creating a space to connect and socialize with members of PSE and our partner organizations.", + images: [SHARP1, SHARP2, SHARP3, SHARP4, SHARP5], + }, +]; diff --git a/src/components/data/navBar.ts b/src/data/navBar.ts similarity index 57% rename from src/components/data/navBar.ts rename to src/data/navBar.ts index a8c1f6a..94b6738 100644 --- a/src/components/data/navBar.ts +++ b/src/data/navBar.ts @@ -9,12 +9,13 @@ export const tags = [ }, { name: "Events", - dropdown: [ - { name: "Calendar", link: "/calendar" }, - { name: "Overviews", link: "/events" }, - ], + link: "/overviews", + // dropdown: [ + // { name: "Calendar", link: "/calendar" }, no calendar? + // { name: "Overviews", link: "/overviews" }, + // ], }, { name: "Gallery", link: "/gallery" }, - { name: "Newsletter", link: "/newsletter" }, + // { name: "Newsletter", link: "/newsletter" }, no newsletter? { name: "Join Us", link: "/join" }, ];