Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions src/app/(protected)/profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ enum Role {
FINANCE = 5,
}

// Mapping from application status to its respective color
const applicationStatusColorMap = new Map<string, string>([
['pending', 'text-purple-400'],
['accepted', 'text-blue-400'],
['rejected', 'text-red-600'],
['waitlisted', 'text-orange-300'],
['confirmed', 'text-green-600'],
['declined', 'text-stone-500']
]);

// Utility to get user role from token
function getUserRole(token: string | undefined): number {
if (!token) return Role.NONE;
Expand Down Expand Up @@ -366,6 +376,13 @@ export default function Profile() {
</p>
</div>
)}
{(!isOrganizer && userData?.registration) && (
<div className="bg-slate-700/50 rounded-lg p-3 mt-4">
<p className={`text-2xl text-slate-200 text-center`}>
Application Status: <span className={`font-bold ${applicationStatusColorMap.get(userData.registration.applicationStatus)}`}>{userData.registration.applicationStatus.toUpperCase()}</span>
</p>
</div>
)}
</CardContent>
</Card>

Expand Down
2 changes: 1 addition & 1 deletion src/app/(protected)/register/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ export default function RegistrationPage() {
major: userInfo.major || "",
phone: userInfo.phone || "",
country: userInfo.country || "",
race: "",
race: userInfo.race || "",
hasDietaryRestrictions: !!(
userInfo.dietaryRestriction || userInfo.allergies
),
Expand Down
67 changes: 58 additions & 9 deletions src/components/FAQ.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,40 @@ const AccordionItem: React.FC<AccordionItemProps> = ({
);
};

function playRobotSound() {
try {
const ctx = new (window.AudioContext || (window as any).webkitAudioContext)();
const playBeep = (frequency: number, startTime: number, duration: number) => {
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.connect(gain);
gain.connect(ctx.destination);
osc.type = "square";
osc.frequency.setValueAtTime(frequency, startTime);
osc.frequency.setValueAtTime(frequency * 0.5, startTime + duration * 0.6);
gain.gain.setValueAtTime(0.12, startTime);
gain.gain.exponentialRampToValueAtTime(0.01, startTime + duration);
osc.start(startTime);
osc.stop(startTime + duration);
};
playBeep(440, 0, 0.08);
playBeep(330, 0.12, 0.1);
playBeep(550, 0.26, 0.12);
} catch {
// ignore if audio not supported or blocked
}
}

const FAQ: React.FC = () => {
const [openItems, setOpenItems] = useState<Set<number>>(new Set());
const [fishClicked, setFishClicked] = useState(false);
const [robotDance, setRobotDance] = useState(false);

const handleRobotClick = () => {
playRobotSound();
setRobotDance(true);
setTimeout(() => setRobotDance(false), 800);
};

const toggleItem = (index: number) => {
setOpenItems((prev) => {
Expand Down Expand Up @@ -228,25 +259,43 @@ const FAQ: React.FC = () => {
{/* Left side - Image on desktop, hidden on mobile */}
<div className="hidden lg:flex lg:w-1/2 items-center justify-center px-[4vw] pb-[8vw]">
<motion.div
className="relative"
className="relative cursor-pointer select-none"
style={{
width: "clamp(200px, 50vw, 800px)",
height: "clamp(200px, 50vw, 800px)",
}}
initial={{ opacity: 1, scale: 1, rotate: 0 }}
animate={{ scale: [0.9, 1, 0.9], opacity: [0.8, 1, 0.8] }}
transition={{
duration: 6,
repeat: Infinity,
ease: "easeInOut",
delay: 0.2,
}}
animate={
robotDance
? {
scale: [1, 1.15, 0.95, 1],
rotate: [0, -12, 12, -8, 8, 0],
transition: {
duration: 0.8,
ease: "easeOut",
},
}
: {
scale: [0.9, 1, 0.9],
opacity: [0.8, 1, 0.8],
rotate: 0,
transition: {
duration: 6,
repeat: Infinity,
ease: "easeInOut",
delay: 0.2,
},
}
}
onClick={handleRobotClick}
title="Click me!"
>
<Image
src="/sp26/robot.png"
alt="FAQ Illustration"
fill
className="object-contain"
className="object-contain pointer-events-none"
draggable={false}
/>
</motion.div>
</div>
Expand Down
95 changes: 88 additions & 7 deletions src/components/Sponsors/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,16 @@ const SponsorTier: React.FC<SponsorTierProps> = ({
const Sponsors: React.FC = () => {
const { data: sponsors, isLoading, error } = useAllSponsors();

// Group sponsors by tier level
// Group sponsors by tier level, filtering out partners
const sponsorsByTier = useMemo(() => {
if (!sponsors) return {};

const grouped: Record<string, SponsorEntity[]> = {};

sponsors.forEach((sponsor) => {
// Skip partners - they'll be displayed separately
if (sponsor.sponsorType === "partner") return;

const level = sponsor.level.toLowerCase();
if (!grouped[level]) {
grouped[level] = [];
Expand All @@ -191,6 +194,14 @@ const Sponsors: React.FC = () => {
return grouped;
}, [sponsors]);

// Get partners separately
const partners = useMemo(() => {
if (!sponsors) return [];
return sponsors
.filter((sponsor) => sponsor.sponsorType === "partner")
.sort((a, b) => a.order - b.order);
}, [sponsors]);

if (isLoading) {
return (
<section
Expand All @@ -217,10 +228,8 @@ const Sponsors: React.FC = () => {
return (
<section
id="sponsors"
className="relative flex flex-col items-center justify-center w-full px-[4vw] py-[8vw]"
className="sponsors-bg relative flex flex-col items-center justify-center w-full px-[4vw] py-[8vw]"
style={{
backgroundImage: "url('/f25/sponsors_bg.png')",
backgroundSize: "cover",
borderTop: "2px solid #ff88e9ff",
borderBottom: "2px solid #ff88e9ff",
boxShadow:
Expand All @@ -237,7 +246,6 @@ const Sponsors: React.FC = () => {
transition={{ duration: 0.8, delay: 0.5 }}
></motion.div>

{/* Glowing Decorative Images - f25/1.png */}
<motion.div
className="absolute z-10"
style={{
Expand Down Expand Up @@ -313,7 +321,7 @@ const Sponsors: React.FC = () => {
></motion.div>

{/* Header */}
<div className="text-center mb-12 z-10 relative">
<div className="text-center mb-12 mt-12 z-10 relative">
<motion.div
initial={{ opacity: 0, y: -30 }}
animate={{ opacity: 1, y: 0 }}
Expand All @@ -335,7 +343,7 @@ const Sponsors: React.FC = () => {
</div>

{/* Main Content */}
<div className="w-full max-w-7xl mx-auto">
<div className="w-full max-w-7xl mx-auto mt-12">
{/* Sponsor Pyramid */}
<div className="space-y-8">
{Object.entries(TIER_CONFIG).map(([tierKey, config], index) => {
Expand All @@ -351,6 +359,79 @@ const Sponsors: React.FC = () => {
})}
</div>

{/* Event Partners Section */}
{partners.length > 0 && (
<motion.div
className="mt-20 pt-12 border-t-2 border-[#ff88e9ff] w-full flex flex-col items-center"
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.5 }}
>
<motion.h2
className="text-2xl md:text-3xl font-bold text-[#2f234bff] text-center mb-8"
style={{
fontFamily: "Orbitron, monospace",
backgroundColor: "#ffffff",
borderRadius: "12px",
padding: "0.5rem 1rem",
}}
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.6 }}
>
Event Partners
</motion.h2>
<div className="flex flex-wrap justify-center gap-8 mt-10">
{partners.map((partner, index) => {
const tierConfig = TIER_CONFIG.partner;
const handleClick = () => {
if (partner.link) {
window.open(partner.link, "_blank", "noopener,noreferrer");
}
};
return (
<motion.div
key={partner.id}
className={`
relative p-6 rounded-2xl border-2 ${tierConfig.borderColor} ${tierConfig.containerBg}
${tierConfig.shadowColor} cursor-pointer transition-all duration-300
hover:shadow-xl hover:scale-105 active:scale-95
`}
onClick={handleClick}
initial={{ opacity: 0, y: 20, scale: 0.9 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
transition={{
duration: 0.6,
delay: index * 0.1,
type: "spring",
stiffness: 100,
}}
whileHover={{
scale: 1.05,
transition: { duration: 0.3 },
}}
whileTap={{ scale: 0.95 }}
>
<div className="flex items-center justify-center h-full">
<div
className={`relative ${tierConfig.logoSize} flex items-center justify-center`}
>
<Image
src={partner.darkLogo || partner.lightLogo || ""}
alt={partner.name}
fill
className="object-contain drop-shadow-lg"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
</div>
</div>
</motion.div>
);
})}
</div>
</motion.div>
)}

{/* Call to Action */}
<motion.div
className="text-center mt-16"
Expand Down
1 change: 1 addition & 0 deletions src/lib/api/sponsor/entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export interface SponsorEntity {
lightLogo?: string;
order: number;
hackathonId?: string;
sponsorType: "sponsor" | "partner";
}
4 changes: 2 additions & 2 deletions src/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,9 @@
}

.sponsors-bg {
background-image: url("/sp26/computer_backgrounds/sponsors_seventh_page_computer2.png");
background-image: url("/sp26/computer_backgrounds/sponsors_seventh_page_computer3.png");
background-size: 100% auto;
background-position: center;
background-position: top center;
}

@media (max-width: 1024px) {
Expand Down
28 changes: 14 additions & 14 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2399,35 +2399,35 @@
dependencies:
cross-spawn "^7.0.6"

"@posthog/core@1.20.2":
version "1.20.2"
resolved "https://registry.yarnpkg.com/@posthog/core/-/core-1.20.2.tgz#1dc2757d1775ca008d596c5629231e75813fb4b9"
integrity sha512-aQhrUzOHYr0z/bkwDsJ5hXahdh6oyeWdx2/CHwR6vFG3eK07J69lbuGOj+HGOOxJP1eAdNnsk8J0fj1vqRA9+A==
"@posthog/core@1.21.0":
version "1.21.0"
resolved "https://registry.yarnpkg.com/@posthog/core/-/core-1.21.0.tgz#f907aa9a6f4d0419585cb11eb5a7c4c27f039abb"
integrity sha512-0a2JUIX1vhduP2El/6/J8s5AeYAurIoufQGFgMiGnJE5ajd63o9LFocu2vFYYBnIOmy75y4ADNeW8zSl1keEQQ==
dependencies:
cross-spawn "^7.0.6"

"@posthog/nextjs-config@^1.0.2":
version "1.8.13"
resolved "https://registry.yarnpkg.com/@posthog/nextjs-config/-/nextjs-config-1.8.13.tgz#40668bfa09adb7c71c3adbacdb0a680c0eec5002"
integrity sha512-u+UVZlom+a4LV0nio23q4xGHcGTbdOjM712d5vr3im12JmytFfMBbDT0QbF8X2HmuhtrlQq9lWN1fXHVUuRn1A==
version "1.8.14"
resolved "https://registry.yarnpkg.com/@posthog/nextjs-config/-/nextjs-config-1.8.14.tgz#c34e07e64c3880e9f23bf124a67d07ffad29c8cc"
integrity sha512-RDaKLYXmJuZAFc7NLHvMowXCESe3xaV3KF0LH+9zUvfJ9I4nl9uNX2WMFnfbZf5doK8mWPYVdIRpiXLwgP6e3Q==
dependencies:
"@posthog/cli" "~0.5.26"
"@posthog/core" "1.20.2"
"@posthog/webpack-plugin" "1.2.19"
"@posthog/core" "1.21.0"
"@posthog/webpack-plugin" "1.2.20"
semver "^7.7.2"

"@posthog/types@1.342.1":
version "1.342.1"
resolved "https://registry.yarnpkg.com/@posthog/types/-/types-1.342.1.tgz#a4d5f7b44539641e910f36818fd4b6aa41022a2f"
integrity sha512-bcyBdO88FWTkd5AVTa4Nu8T7RfY0WJrG7WMCXum/rcvNjYhS3DmOfKf8o/Bt56vA3J3yeU0vbgrmltYVoTAfaA==

"@posthog/webpack-plugin@1.2.19":
version "1.2.19"
resolved "https://registry.yarnpkg.com/@posthog/webpack-plugin/-/webpack-plugin-1.2.19.tgz#8111246ec16b24bebd03a09447ef181b8d2ce1bf"
integrity sha512-0oy+mkuferiL5hO5tOwgoGlFb5zZO5UqUhDd9a1C16+P9MShQuItwgaMdgGJ+7G15Hq+gzLAmErz6Ffp6qJCgQ==
"@posthog/webpack-plugin@1.2.20":
version "1.2.20"
resolved "https://registry.yarnpkg.com/@posthog/webpack-plugin/-/webpack-plugin-1.2.20.tgz#a6355a38a136248b82478d2a9175f7566fca412a"
integrity sha512-rqyCFBzCwMne2YdjbSJEijb0f/wU5QKIX53ObgxdazfQlVroflb+qwevIKkkU1lUg5e4S6zYvVNNwrpe0Zoomw==
dependencies:
"@posthog/cli" "~0.5.26"
"@posthog/core" "1.20.2"
"@posthog/core" "1.21.0"

"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
version "1.1.2"
Expand Down