diff --git a/public/static/event/btb/2025/group.jpg b/public/static/event/btb/2025/group.jpg
new file mode 100644
index 0000000..d6fba01
Binary files /dev/null and b/public/static/event/btb/2025/group.jpg differ
diff --git a/public/static/event/btb/2025/otherteamfocus.jpeg b/public/static/event/btb/2025/otherteamfocus.jpeg
new file mode 100644
index 0000000..8b52eeb
Binary files /dev/null and b/public/static/event/btb/2025/otherteamfocus.jpeg differ
diff --git a/public/static/event/btb/2025/singleteamfocus.jpeg b/public/static/event/btb/2025/singleteamfocus.jpeg
new file mode 100644
index 0000000..f7a8a33
Binary files /dev/null and b/public/static/event/btb/2025/singleteamfocus.jpeg differ
diff --git a/public/static/event/btb/2025/whole.jpg b/public/static/event/btb/2025/whole.jpg
new file mode 100644
index 0000000..daabdae
Binary files /dev/null and b/public/static/event/btb/2025/whole.jpg differ
diff --git a/public/static/event/btb/2025/wholea2.jpeg b/public/static/event/btb/2025/wholea2.jpeg
new file mode 100644
index 0000000..6f2517d
Binary files /dev/null and b/public/static/event/btb/2025/wholea2.jpeg differ
diff --git a/public/static/event/codesprint/2025/groupphoto.png b/public/static/event/codesprint/2025/groupphoto.png
new file mode 100644
index 0000000..e9f487e
Binary files /dev/null and b/public/static/event/codesprint/2025/groupphoto.png differ
diff --git a/public/static/event/codesprint/2025/j.png b/public/static/event/codesprint/2025/j.png
new file mode 100644
index 0000000..ed78dd9
Binary files /dev/null and b/public/static/event/codesprint/2025/j.png differ
diff --git a/public/static/event/estimathon/2025/group.JPG b/public/static/event/estimathon/2025/group.JPG
new file mode 100644
index 0000000..88ec85c
Binary files /dev/null and b/public/static/event/estimathon/2025/group.JPG differ
diff --git a/public/static/icon/btb.png b/public/static/icon/btb.png
new file mode 100644
index 0000000..4b042be
Binary files /dev/null and b/public/static/icon/btb.png differ
diff --git a/public/static/icon/eventicon.png b/public/static/icon/eventicon.png
new file mode 100644
index 0000000..a7fc872
Binary files /dev/null and b/public/static/icon/eventicon.png differ
diff --git a/public/static/icon/eventicon.svg b/public/static/icon/eventicon.svg
new file mode 100644
index 0000000..5cad9d9
--- /dev/null
+++ b/public/static/icon/eventicon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/static/icon/eventiconl.png b/public/static/icon/eventiconl.png
new file mode 100644
index 0000000..daf9619
Binary files /dev/null and b/public/static/icon/eventiconl.png differ
diff --git a/public/static/icon/icpccomplogo.svg b/public/static/icon/icpccomplogo.svg
new file mode 100644
index 0000000..a7a3b0d
--- /dev/null
+++ b/public/static/icon/icpccomplogo.svg
@@ -0,0 +1,57 @@
+
+
+
+
diff --git a/public/static/icon/interviewtrackicon.png b/public/static/icon/interviewtrackicon.png
new file mode 100644
index 0000000..d0798ec
Binary files /dev/null and b/public/static/icon/interviewtrackicon.png differ
diff --git a/public/static/icon/trainingicon.png b/public/static/icon/trainingicon.png
new file mode 100644
index 0000000..bdb352d
Binary files /dev/null and b/public/static/icon/trainingicon.png differ
diff --git a/public/static/icon/workshopicon.png b/public/static/icon/workshopicon.png
new file mode 100644
index 0000000..31b2822
Binary files /dev/null and b/public/static/icon/workshopicon.png differ
diff --git a/src/app.js b/src/app.js
index 4b66fd7..c17023c 100644
--- a/src/app.js
+++ b/src/app.js
@@ -48,6 +48,7 @@ const { createHash } = require('crypto');
const HomeContainer = lazy(() => import('pages/home'));
+const WorkshopsContainer = lazy(() => import('pages/workshops'))
const EventsContainer = lazy(() => import('pages/events'));
const RegionalsContainer = lazy(() => import('pages/regionals'));
const TeamContainer = lazy(() => import('pages/team'));
@@ -72,9 +73,9 @@ const Navbar = (props) => {
const MenuContent = () => {
return (
- ({color: isActive ? '#ff5479' : 'inherit'})}>
+ ({color: isActive ? '#ff5479' : 'inherit'})}>
({color: isActive ? '#ff5479' : 'inherit'})}>
@@ -92,12 +93,6 @@ const Navbar = (props) => {
team
-
-
-
-
)};
@@ -282,6 +277,7 @@ const App = () => {
} />
+ } />
} />
} />
} />
diff --git a/src/main.scss b/src/main.scss
index a06e2ed..64eb5f4 100644
--- a/src/main.scss
+++ b/src/main.scss
@@ -57,4 +57,4 @@ label {
max-width: 600px;
width: 80%;
// flex-grow: 1;
-}
\ No newline at end of file
+}
diff --git a/src/pages/events.js b/src/pages/events.js
index 814f993..125fe6f 100644
--- a/src/pages/events.js
+++ b/src/pages/events.js
@@ -1,145 +1,278 @@
-import React, { useEffect, useState } from 'react';
-import { Helmet } from 'react-helmet';
+import React, { useRef, useState, useEffect, useCallback } from "react";
import {
- Heading,
- Image,
- Stack,
- Flex,
- Text,
- Badge,
- SimpleGrid,
Box,
+ Flex,
+ Heading,
Link,
-} from '@chakra-ui/react';
-import {
- FaFacebook,
- FaDiscord,
-} from 'react-icons/fa';
-import Container from 'components/container';
-import { EventCard, EventDescriptionCard } from 'components/eventcard';
-// import * as AWS from "aws-sdk";
-import { allEvents, pastEvents } from 'data';
+ Text,
+ Image,
+ VStack,
+ Button,
+ Circle,
+} from "@chakra-ui/react";
+import Carousel from 'components/competitionCarousel';
-// const docClient = new AWS.DynamoDB.DocumentClient();
+// TODO Put this in data js
+// TODO Make this more intuitive to work with
+// --- 1. Enhanced Data Structure (Adjusted Colors for Lighter Theme) ---
+const featuredEvents = [
+ {
+ title: "Codesprint",
+ description:
+ "Our flagship coding contest, Codesprint LA, is one of the largest college-run competitions of its kind. With over 700 participants last year and a total prize pool of over a $2000, it’s an event you won’t want to miss.",
+ cta: "Visit the Website",
+ isLink: true,
+ link: "https://codesprintla.uclaacm.com",
+ carouselCards: [
+ "/static/event/codesprint/2025/groupphoto.png",
+ "/static/event/codesprint/2025/j.png"
+ ],
+ theme: {
+ // Lighter, more vibrant tones
+ mainBg: "white", // White background for the slide itself
+ textColor: "gray.800", // Darker text for contrast on light background
+ blob1: "purple.200", // Lighter purple
+ blob2: "pink.200", // Lighter pink
+ gradient: "linear(to-r, pink.300, purple.400)", // Lighter button gradient
+ hoverGradient: "linear(to-r, pink.400, purple.500)", // Slightly darker on hover
+ buttonTextColor: "white", // White text on button
+ paginationActive: "purple.400", // Active pagination dot
+ paginationInactive: "gray.300", // Inactive pagination dot
+ },
+ },
+ {
+ title: "Break the Binary",
+ description:
+ "An annual themed puzzle hunt hosted with ACM-W. Teams of 3–4 take on 10–15 puzzles combining creativity, logic, and teamwork, with a focus on broadening participation in STEM.",
+ cta: "See the Puzzles",
+ isLink: true,
+ link: "https://break-the-binary.github.io/website25/",
+ carouselCards: [
+ "/static/event/btb/2025/group.jpg",
+ "/static/event/btb/2025/singleteamfocus.jpeg",
+ "/static/event/btb/2025/otherteamfocus.jpeg",
+ "/static/event/btb/2025/whole.jpg",
+ "/static/event/btb/2025/wholea2.jpeg"
+ ],
+ theme: {
+ mainBg: "white",
+ textColor: "gray.800",
+ blob1: "teal.200",
+ blob2: "blue.200",
+ gradient: "linear(to-r, teal.300, blue.400)",
+ hoverGradient: "linear(to-r, teal.400, blue.500)",
+ buttonTextColor: "white",
+ paginationActive: "blue.400",
+ paginationInactive: "gray.300",
+ },
+ },
+ {
+ title: "Estimathon",
+ description:
+ "Test your estimation skills in our fast-paced, brain-teasing challenge! Teams of 1–3 will tackle a series of Fermi estimation questions, putting your intuition and reasoning to the test.",
+ cta: "",
+ isLink: false,
+ link: "#",
+ carouselCards: [
+ "/static/event/estimathon/2025/group.JPG",
+ ],
+ theme: {
+ mainBg: "white",
+ textColor: "gray.800",
+ blob1: "orange.200",
+ blob2: "red.200",
+ gradient: "linear(to-r, orange.300, red.400)",
+ hoverGradient: "linear(to-r, orange.400, red.500)",
+ buttonTextColor: "white",
+ paginationActive: "red.400",
+ paginationInactive: "gray.300",
+ },
+ },
+];
-const UpcomingEvents = () => {
- const [eventsData, setEventsData] = useState([]);
-
- useEffect(()=>{
- (async ()=>{
- let res = await fetch('https://clammy-waiting-dragon.glitch.me/events');
- let data = await res.json();
- console.log(data);
- data = data.map(event => ({
- ...event,
- start_time: new Date(event.start_time),
- end_time: new Date(event.end_time)
- }));
- data.sort((a,b) => {return a.start_time - b.start_time});
- const firstUpcomingEvent = data.findIndex(event => event.end_time > (new Date()));
- if (firstUpcomingEvent !== -1) {
- setEventsData(data.splice(firstUpcomingEvent, firstUpcomingEvent+4));
- }
- // setEventsData(eventsData.splice(0, 4));
- })()
+const EventsContainer = () => {
+ const [activeIndex, setActiveIndex] = useState(0);
+ const scrollRef = useRef(null);
+
+ useEffect(() => {
+ const node = scrollRef.current;
+ if (!node) return;
+ const handleScroll = () => {
+ const width = node.clientWidth || node.offsetWidth;
+ const scrollLeft = node.scrollLeft;
+ setActiveIndex(Math.round(scrollLeft / width));
+ };
+ node.addEventListener("scroll", handleScroll, { passive: true });
+ handleScroll();
+ return () => node.removeEventListener("scroll", handleScroll);
}, []);
- function hourToString(hour){
- return ((hour%12) === 0 ? '12' : (hour % 12)) + ((hour < 12) ? ' AM' : ' PM');
- }
+ useEffect(() => {
+ const onResize = () => {
+ const node = scrollRef.current;
+ if (!node) return;
+ node.scrollTo({ left: activeIndex * node.clientWidth, behavior: "auto" });
+ };
+ window.addEventListener("resize", onResize);
+ return () => window.removeEventListener("resize", onResize);
+ }, [activeIndex]);
- if (eventsData.length === 0)
- return (Loading...);
- return (
-
- {eventsData.map((event, index) => (
-
- ))}
-
- );
-};
+ const goToIndex = useCallback((idx) => {
+ const node = scrollRef.current;
+ if (!node) return;
+ const width = node.clientWidth || node.offsetWidth;
+ node.scrollTo({ left: idx * width, behavior: "smooth" });
+ setActiveIndex(idx);
+ }, []);
-const AllEvents = () => {
- const eventsData = allEvents;
- return (
-
- {eventsData.map((event, index) => (
-
- ))}
-
- );
- return (
-
- {eventsData.map((event, index) => (
-
-
-
- {typeof event.quarter !== "undefined" &&
- event.quarter.split('/').map((qtr, index) => (
- {qtr}
- ))}
-
- {event.name}
- {event.description}
-
- ))}
-
- );
-};
+ useEffect(() => {
+ const handleKey = (e) => {
+ if (e.key === "ArrowRight") {
+ goToIndex(Math.min(activeIndex + 1, featuredEvents.length - 1));
+ } else if (e.key === "ArrowLeft") {
+ goToIndex(Math.max(activeIndex - 1, 0));
+ }
+ };
+ window.addEventListener("keydown", handleKey);
+ return () => window.removeEventListener("keydown", handleKey);
+ }, [activeIndex, goToIndex]);
+
+ // Get the current event's theme for dynamic styling
+ const currentTheme = featuredEvents[activeIndex].theme;
-const PastEvents = () => {
- const eventsData = pastEvents;
return (
-
- {eventsData.map((event, index) => (
-
-
-
- {typeof event.quarter !== "undefined" &&
- event.quarter.split('/').map((qtr, index) => (
- {qtr}
- ))}
-
- {event.name}
- {event.description}
-
- ))}
-
+
+
+ {featuredEvents.map((event, index) => (
+
+ {/* Background Blobs */}
+
+
+
+
+ {/* Left Column: Text & CTA */}
+
+
+ {event.title}
+
+
+ {event.description}
+
+
+
+
+
+
+
+ {/* Right Column: Carousel */}
+
+
+
+
+
+
+
+ ))}
+
+
+ {/* Pagination dots (using currentTheme for colors) */}
+
+ {featuredEvents.map((_, idx) => (
+ goToIndex(idx)}
+ />
+ ))}
+
+
);
};
-const EventsContainer = (props) => (
-
-
- Events | ACM ICPC at UCLA
-
-
-
-
-
-
-
-
-
-
- Events
-
-
- Upcoming
-
-
-
- All Events and Workshops
-
-
- {/*
- Past Events and Workshops
-
- */}
-
-
-
-);
-
-export { UpcomingEvents };
export default EventsContainer;
diff --git a/src/pages/home.js b/src/pages/home.js
index 52a852d..6d468fc 100644
--- a/src/pages/home.js
+++ b/src/pages/home.js
@@ -14,7 +14,6 @@ import {
} from '@chakra-ui/react';
import Container from 'components/container';
import Sponsor from "components/sponsor";
-import { UpcomingEvents } from 'pages/events';
import { useMediaQuery } from 'hooks';
@@ -58,7 +57,7 @@ const HomeContainer = () => {
- who are we?
+ Who Are We?algorithmic thinking, problem solving
We are a group of problem solvers at heart! ACM ICPC at UCLA is a student-led organization whose mission is to promote algorithmic thinking and help build proficient problem solvers.
@@ -68,33 +67,108 @@ const HomeContainer = () => {
programming contests, everything we do revolves around the central theme of critical algorithmic thinking.
- Click below to find out more about us:
+ We have the following:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Upcoming Events
-
-
+
+ {/* Workshops Column */}
+
+ Workshops
+
+
+ Explore our regularly held workshops to practice for interviews, competitive projects, and more.
+
+
+
+ {/* Events Column */}
+
+ Events
+
+
+ Checkout out the events we will be hosting throughout the year.
+
+
+
+ {/* Competitions Column */}
+
+ Competitions
+
+
+ Try out for our competitiion team to participate in the International Collegiate Programming Contest.
+
+
+
diff --git a/src/pages/workshops.js b/src/pages/workshops.js
new file mode 100644
index 0000000..2a91710
--- /dev/null
+++ b/src/pages/workshops.js
@@ -0,0 +1,118 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import {
+ Flex,
+ Heading,
+ Image,
+ VStack,
+ Text,
+ Box,
+ Divider,
+} from '@chakra-ui/react';
+import Container from 'components/container';
+
+// A reusable card component for each track
+const TrackCard = ({ title, text, imageUrl, imageOnLeft = false }) => {
+ return (
+
+
+ {/* Left/Right Side: Text Content */}
+
+
+ {title}
+
+
+ {text}
+
+
+
+ {/* Right/Left Side: Image */}
+
+
+
+
+
+ );
+};
+
+const WorkshopsContainer = () => {
+ const loremIpsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum"
+
+ const tracks = [
+ {
+ title: "Interview Track",
+ text: "Get ready for interviews with focused sessions designed to help you succeed. We’ll cover algorithms and techniques that often come up in technical interviews, explore behavioral strategies to help you tell your story, and run mock interviews so you can practice in a supportive setting.",
+ imageUrl: "/static/icon/interviewtrackicon.png",
+ imageOnLeft: false,
+ },
+ {
+ title: "Small Group Training",
+ text: "Join us for focused small group training sessions where you’ll learn algorithms and competitive coding alongside peers at a similar skill level. The smaller group sizes ensure you’ll get more personal feedback and support as you grow your skills.",
+ imageUrl: "/static/icon/trainingicon.png",
+ imageOnLeft: true,
+ },
+ {
+ title: "Project Track",
+ text: loremIpsum,
+ imageUrl: "https://picsum.photos/1600/900",
+ imageOnLeft: false,
+ }
+ ];
+
+ return (
+
+
+ Workshops
+
+
+ {/* Using your custom Container for consistent page width and padding */}
+
+
+
+ {/* Main Title Section */}
+
+ Workshops
+
+
+ {/* Map over the tracks array to render a card for each one */}
+ {tracks.map((track) => (
+
+ ))}
+
+
+
+
+
+