diff --git a/README.md b/README.md index 2c8c399..d7739d4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# Deerhack 2025 Website +# DeerHack 2026 Website ## Please use Node Version 20.11.0 diff --git a/frontend/src/app/(pages)/ExpectationsV2.tsx b/frontend/src/app/(pages)/ExpectationsV2.tsx new file mode 100644 index 0000000..c1fecca --- /dev/null +++ b/frontend/src/app/(pages)/ExpectationsV2.tsx @@ -0,0 +1,21 @@ +import { ReactElement } from "react"; +import { cabinetExtraBold } from "../utils/fonts"; +import ExpectationCards from "../sections/ExpectationsV2/ExpectationCards"; +import ExpectationsVine from "../assets/icons/ExpectationsVine"; +import Butterfly from "../assets/icons/Butterfly"; + +export default function ExpectationPageV2(): ReactElement { + return ( +
+ +
+ What Else Can You Expect at

DeerHack? +
+ + + +
+ ); +} diff --git a/frontend/src/app/MainPage.tsx b/frontend/src/app/MainPage.tsx index 8ceffb3..dc035e7 100644 --- a/frontend/src/app/MainPage.tsx +++ b/frontend/src/app/MainPage.tsx @@ -14,6 +14,7 @@ import Judges from "@/app/(pages)/Judges"; import Mentors from "@/app/(pages)/Mentors"; import Navbar from "@/app/components/Navbar/Navbar"; import ExperiencePage from "./(pages)/DeerhackExperiencePage"; +import ExpectationPageV2 from "./(pages)/ExpectationsV2"; export default function Home() { return ( @@ -24,7 +25,8 @@ export default function Home() { - + {/* */} + diff --git a/frontend/src/app/assets/icons/Butterfly.svg b/frontend/src/app/assets/icons/Butterfly.svg new file mode 100644 index 0000000..4ac788f --- /dev/null +++ b/frontend/src/app/assets/icons/Butterfly.svg @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/app/assets/icons/Butterfly.tsx b/frontend/src/app/assets/icons/Butterfly.tsx new file mode 100644 index 0000000..1b47349 --- /dev/null +++ b/frontend/src/app/assets/icons/Butterfly.tsx @@ -0,0 +1,697 @@ +import React from "react"; +interface Props{ + width?:number; + height?:number; + className?:string; +} +const Butterfly = ({width = 154, height = 188, className = ""} : Props) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default Butterfly; diff --git a/frontend/src/app/assets/icons/ExpectatioArrow.svg b/frontend/src/app/assets/icons/ExpectatioArrow.svg new file mode 100644 index 0000000..f5741c1 --- /dev/null +++ b/frontend/src/app/assets/icons/ExpectatioArrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/assets/icons/ExpectationsArrow.tsx b/frontend/src/app/assets/icons/ExpectationsArrow.tsx new file mode 100644 index 0000000..77dffa4 --- /dev/null +++ b/frontend/src/app/assets/icons/ExpectationsArrow.tsx @@ -0,0 +1,27 @@ +import React, { ReactElement } from "react"; + +interface Props { + onClick: () => void; + className?: string; +} + +const ExpectationsArrow = ({ onClick, className = "" }: Props): ReactElement => { + return ( + + + + ); +}; + +export default ExpectationsArrow; \ No newline at end of file diff --git a/frontend/src/app/assets/icons/ExpectationsVine.svg b/frontend/src/app/assets/icons/ExpectationsVine.svg new file mode 100644 index 0000000..269d9d4 --- /dev/null +++ b/frontend/src/app/assets/icons/ExpectationsVine.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/frontend/src/app/assets/icons/ExpectationsVine.tsx b/frontend/src/app/assets/icons/ExpectationsVine.tsx new file mode 100644 index 0000000..9177177 --- /dev/null +++ b/frontend/src/app/assets/icons/ExpectationsVine.tsx @@ -0,0 +1,43 @@ +export default function ExpectationsVine({ + width = 215, + height = 334, + className = "", +}: { + width?: number; + height?: number; + className?: string; +}) { + return ( + + + + + + + + + + + + ); +} diff --git a/frontend/src/app/assets/images/expectations/badminton.jpg b/frontend/src/app/assets/images/expectations/badminton.jpg new file mode 100644 index 0000000..bed60f3 Binary files /dev/null and b/frontend/src/app/assets/images/expectations/badminton.jpg differ diff --git a/frontend/src/app/assets/images/expectations/football.jpg b/frontend/src/app/assets/images/expectations/football.jpg new file mode 100644 index 0000000..8fce904 Binary files /dev/null and b/frontend/src/app/assets/images/expectations/football.jpg differ diff --git a/frontend/src/app/assets/images/expectations/workshop_1.jpg b/frontend/src/app/assets/images/expectations/workshop_1.jpg new file mode 100644 index 0000000..3bd795f Binary files /dev/null and b/frontend/src/app/assets/images/expectations/workshop_1.jpg differ diff --git a/frontend/src/app/assets/images/expectations/workshop_2.jpg b/frontend/src/app/assets/images/expectations/workshop_2.jpg new file mode 100644 index 0000000..5106ec2 Binary files /dev/null and b/frontend/src/app/assets/images/expectations/workshop_2.jpg differ diff --git a/frontend/src/app/assets/images/genderEllipse.tsx b/frontend/src/app/assets/images/genderEllipse.tsx index b76de1f..a7918c7 100644 --- a/frontend/src/app/assets/images/genderEllipse.tsx +++ b/frontend/src/app/assets/images/genderEllipse.tsx @@ -16,6 +16,7 @@ export default function GenderEllipseSVG({ }): ReactElement { const [visible, setVisible] = useState({ male: true, female: true }); const [hasAnimated, setHasAnimated] = useState(false); + const [showChart, setShowChart] = useState(false); const chartRef = useRef>(null); const containerRef = useRef(null); @@ -33,6 +34,13 @@ export default function GenderEllipseSVG({ return () => observer.disconnect(); }, [hasAnimated]); + useEffect(() => { + if (hasAnimated) { + const id = setTimeout(() => setShowChart(true), 50); + return () => clearTimeout(id); + } + }, [hasAnimated]); + const handleToggle = (gender: "male" | "female") => { const chart = chartRef.current; if (!chart) return; @@ -66,41 +74,41 @@ export default function GenderEllipseSVG({ const options: ChartOptions<"doughnut"> = { animation: { - duration: 2000, - }, + duration: 2000, + }, rotation: 90, maintainAspectRatio: false, cutout: "60%", plugins: { legend: { display: false }, tooltip: { - enabled: true, - backgroundColor: "#110C24", - titleColor: "#fff", - bodyColor: "#fff", - borderColor: "#D977F2", - borderWidth: 1, - displayColors: false, - callbacks: { - title: (context) => { - const index = context[0].dataIndex; - if (index === 1 || index === 2) return "Female"; - return "Male"; - }, - label: (context) => { - if (context.dataIndex === 1 || context.dataIndex === 2) { - return "25%"; - } - return `75%`; - }, - }, -}, + enabled: true, + backgroundColor: "#110C24", + titleColor: "#fff", + bodyColor: "#fff", + borderColor: "#D977F2", + borderWidth: 1, + displayColors: false, + callbacks: { + title: (context) => { + const index = context[0].dataIndex; + if (index === 1 || index === 2) return "Female"; + return "Male"; + }, + label: (context) => { + if (context.dataIndex === 1 || context.dataIndex === 2) { + return "25%"; + } + return `75%`; + }, + }, + }, }, }; return (
- {hasAnimated && ( + {showChart && ( )}
diff --git a/frontend/src/app/components/About/AboutCard.tsx b/frontend/src/app/components/About/AboutCard.tsx index 333479e..ee03d75 100644 --- a/frontend/src/app/components/About/AboutCard.tsx +++ b/frontend/src/app/components/About/AboutCard.tsx @@ -65,7 +65,7 @@ export default function AboutCard({ return (
-
+
{buttons.map(({ key, Icon }) => { const isActive = activeTab === key; @@ -78,6 +78,7 @@ export default function AboutCard({ rounded-r-[40px] rounded-l-[6px] about-section-button p-1 md:p-2 flex items-center justify-end shadow-lg h-10 md:h-16 + transition-all duration-300 ease-in-out ${isActive ? "w-[72px] md:w-[140px] brightness-125" : "w-12 md:w-16"} `} aria-label={`Show ${key} info`} @@ -133,11 +134,11 @@ export default function AboutCard({

{description}

); -} +} \ No newline at end of file diff --git a/frontend/src/app/components/ExpectationsV2/ExpectationCard.tsx b/frontend/src/app/components/ExpectationsV2/ExpectationCard.tsx new file mode 100644 index 0000000..faef669 --- /dev/null +++ b/frontend/src/app/components/ExpectationsV2/ExpectationCard.tsx @@ -0,0 +1,38 @@ +"use client"; +import { ReactElement } from "react"; +import { cabinetBold } from "@/app/utils/fonts"; + +export default function ExpectationCard({ + svg, + title, + description, + isActive, +}: { + svg?: ReactElement; + title?: string; + description?: string; + isActive?: boolean; +}): ReactElement { + return ( +
+
+
{svg}
+

+ {title} +

+
+ +
+

+ {description} +

+
+
+ ); +} diff --git a/frontend/src/app/components/ExpectationsV2/ExpectationImage.tsx b/frontend/src/app/components/ExpectationsV2/ExpectationImage.tsx new file mode 100644 index 0000000..676cbd0 --- /dev/null +++ b/frontend/src/app/components/ExpectationsV2/ExpectationImage.tsx @@ -0,0 +1,24 @@ + import Image, { StaticImageData } from "next/image"; + import { ReactElement } from "react"; + + export default function ExpectationImage({ + imageSrc, + className, + }: { + imageSrc: StaticImageData; + className?:string; + }): ReactElement { + return ( +
+
+ Some Fun Games Played at Deerhack 2023 +
+
+ ); + } diff --git a/frontend/src/app/global.d.ts b/frontend/src/app/global.d.ts new file mode 100644 index 0000000..7f70183 --- /dev/null +++ b/frontend/src/app/global.d.ts @@ -0,0 +1 @@ +declare module "*.css"; \ No newline at end of file diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index b815cb4..3188bd3 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -25,17 +25,17 @@ export const metadata = { " why participate in hackathon", ], openGraph: { - title: "Deerhack 2026 - Fawning over Innovation", + title: "DeerHack 2026 - Fawning over Innovation", description: "DeerHack 2026 is the brainchild of a small team to unleash the potential of young innovators through a 36-hour hackathon in which developers, designers, students, entrepreneurs, educators, and mentors collaborate to create solutions that tackle real-world problems. When people from many backgrounds collaborate, they do more than merely do good; they become a force for global change", url: "https://deerhack.deerwalk.edu.np", - siteName: "Deerhack 2026 - Fawning Over Innovation", + siteName: "DeerHack 2026 - Fawning Over Innovation", images: [ { url: "/banner.webp", width: 400, height: 250, - alt: "Deerhack 2026 Banner", + alt: "DeerHack 2026 Banner", }, ], locale: "en_US", @@ -43,7 +43,7 @@ export const metadata = { }, twitter: { card: "summary_large_image", - title: "Deerhack 2026", + title: "DeerHack 2026", description: "DeerHack 2026 is the brainchild of a small team to unleash the potential of young innovators through a 36-hour hackathon in which developers, designers, students, entrepreneurs, educators, and mentors collaborate to create solutions that tackle real-world problems. When people from many backgrounds collaborate, they do more than merely do good; they become a force for global change", images: ["/banner.webp"], diff --git a/frontend/src/app/sections/AboutTheEvent/AboutTheEventCards.tsx b/frontend/src/app/sections/AboutTheEvent/AboutTheEventCards.tsx index b0da563..c78c075 100644 --- a/frontend/src/app/sections/AboutTheEvent/AboutTheEventCards.tsx +++ b/frontend/src/app/sections/AboutTheEvent/AboutTheEventCards.tsx @@ -7,7 +7,7 @@ const AboutTheEventCards = () => { const tabs = { deerhack: { svg: , - title: "Deerhack 2026", + title: "DeerHack 2026", description: "DeerHack 2026 is a 48-hour hackathon where developers, designers, students, entrepreneurs, educators, and mentors work together to build ideas that solve real-world complications. DeerHack provides an opportunity for individuals to sharpen their teamwork, communication, leadership skills, and networking in a risk-free and comfortable environment.", }, diff --git a/frontend/src/app/sections/ExpectationsV2/ExpectationCards.tsx b/frontend/src/app/sections/ExpectationsV2/ExpectationCards.tsx new file mode 100644 index 0000000..7897c12 --- /dev/null +++ b/frontend/src/app/sections/ExpectationsV2/ExpectationCards.tsx @@ -0,0 +1,181 @@ +"use client"; +import ExpectationCard from "@/app/components/ExpectationsV2/ExpectationCard"; +import { ReactElement, useState, useEffect, useRef } from "react"; +import ExpectationImage from "@/app/components/ExpectationsV2/ExpectationImage"; +import ExpectationsArrow from "@/app/assets/icons/ExpectationsArrow"; +import { originalCards } from "./data"; + +export default function ExpectationCards(): ReactElement { + const cards = [...originalCards, ...originalCards, ...originalCards]; + + const [currentIndex, setCurrentIndex] = useState(originalCards.length); + const [isTransitioning, setIsTransitioning] = useState(false); + + const [gap, setGap] = useState(98); + const [cardWidth, setCardWidth] = useState(380); + + useEffect(() => { + const handleResize = () => { + const width = window.innerWidth; + if (width >= 1280) { + setGap(98); + setCardWidth(380); + } else if (width >= 768) { + setGap(50); + setCardWidth(320); + } else { + setGap(28); + setCardWidth(300); + } + }; + + handleResize(); + window.addEventListener("resize", handleResize); + return () => window.removeEventListener("resize", handleResize); + }, []); + + const nextSlide = () => { + if (isTransitioning) return; + setIsTransitioning(true); + setCurrentIndex((prev) => prev + 1); + }; + + const prevSlide = () => { + if (isTransitioning) return; + setIsTransitioning(true); + setCurrentIndex((prev) => prev - 1); + }; + + const handleTransitionEnd = () => { + setIsTransitioning(false); + + if (currentIndex >= originalCards.length * 2) { + setCurrentIndex(currentIndex - originalCards.length); + } else if (currentIndex < originalCards.length) { + setCurrentIndex(currentIndex + originalCards.length); + } + }; + + const touchStartX = useRef(null); + const touchEndX = useRef(null); + const minSwipeDistance = 50; + + const onTouchStart = (e: React.TouchEvent) => { + touchEndX.current = null; + touchStartX.current = e.targetTouches[0].clientX; + }; + + const onTouchMove = (e: React.TouchEvent) => { + touchEndX.current = e.targetTouches[0].clientX; + }; + + const onTouchEnd = () => { + if (!touchStartX.current || !touchEndX.current) return; + + const distance = touchStartX.current - touchEndX.current; + const isLeftSwipe = distance > minSwipeDistance; + const isRightSwipe = distance < -minSwipeDistance; + + if (isLeftSwipe) { + nextSlide(); + } else if (isRightSwipe) { + prevSlide(); + } + }; + + return ( +
+
+ + + +
+
+
+
+ +
+ {cards.map((card, index) => { + const isActive = index === currentIndex; + + return ( +
+
+ + +
+
+ ); + })} +
+ +
+ {originalCards.map((_, dotIndex) => { + const activeDotIndex = currentIndex % originalCards.length; + return ( +
+ ); + })} +
+
+ +
+ +
+
+ ); +} \ No newline at end of file diff --git a/frontend/src/app/sections/ExpectationsV2/data.tsx b/frontend/src/app/sections/ExpectationsV2/data.tsx new file mode 100644 index 0000000..e6a2739 --- /dev/null +++ b/frontend/src/app/sections/ExpectationsV2/data.tsx @@ -0,0 +1,32 @@ +import FunGamesSVG from "@/app/assets/images/funGames"; +import MusicSVG from "@/app/assets/images/music"; +import WorkshopSVG from "@/app/assets/images/workshop"; + +import fun_games_image from "@/app/assets/images/fun_games.webp"; +import live_music_image from "@/app/assets/images/live_music_image.webp"; +import workshop_image from "@/app/assets/images/workshop_image.webp"; + +// import fun_games_image from "@/app/assets/images/expectations/badminton.jpg"; +// import live_music_image from "@/app/assets/images/expectations/football.jpg"; +// import workshop_image from "@/app/assets/images/expectations/workshop_2.jpg"; + +export const originalCards = [ + { + svg: , + title: "Fun Games", + img: fun_games_image, + desc: "Take a break from coding and immerse yourself in the soulful melodies and electrifying beats of live music performances, adding rhythm and energy to your DeerHack experience.", + }, + { + svg: , + title: "Live Music", + img: live_music_image, + desc: "Take a break from coding and immerse yourself in the soulful melodies and electrifying beats of live music performances, adding rhythm and energy to your DeerHack experience.", + }, + { + svg: , + title: "Workshops", + img: workshop_image, + desc: "Dive deep into cutting-edge technologies, sharpen your skills, and gain invaluable insights from industry experts through interactive workshops tailored to enhance your expertise.", + }, +];