Skip to content

Commit 65f9e43

Browse files
authored
Merge pull request #79 from DurianPy-Davao-Python-User-Group/staging
2 parents 2dcc03d + 116c84e commit 65f9e43

37 files changed

Lines changed: 1575 additions & 58 deletions
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
'use client';
2+
3+
import { useState, useEffect, useCallback } from 'react';
4+
5+
interface CountdownTimerProps {
6+
eventDate: string;
7+
}
8+
9+
export default function CountdownTimer({ eventDate }: CountdownTimerProps) {
10+
const formatNumber = (num: number) => (num < 10 ? `0${num}` : `${num}`);
11+
12+
const calculateTimeLeft = useCallback(() => {
13+
const difference = +new Date(eventDate) - +new Date();
14+
if (difference > 0) {
15+
return {
16+
days: formatNumber(Math.floor(difference / (1000 * 60 * 60 * 24))),
17+
hours: formatNumber(Math.floor((difference / (1000 * 60 * 60)) % 24)),
18+
minutes: formatNumber(Math.floor((difference / 1000 / 60) % 60)),
19+
seconds: formatNumber(Math.floor((difference / 1000) % 60)),
20+
};
21+
}
22+
return { days: '00', hours: '00', minutes: '00', seconds: '00' };
23+
}, [eventDate]); // Dependency array ensures the function updates when `eventDate` changes
24+
25+
const [timeLeft, setTimeLeft] = useState(calculateTimeLeft());
26+
const [isClient, setIsClient] = useState(false);
27+
28+
useEffect(() => {
29+
setIsClient(true);
30+
31+
const timer = setInterval(() => {
32+
setTimeLeft(calculateTimeLeft());
33+
}, 1000);
34+
35+
return () => clearInterval(timer);
36+
}, [calculateTimeLeft]); // Dependency array ensures the effect re-runs if `calculateTimeLeft` changes
37+
38+
if (!isClient) return null;
39+
40+
return (
41+
<div className="bg-none p-2 w-full text-[#36FF90] md:w-auto">
42+
<h2 className="text-sm font-bold mb-8 md:mb-6 xl:text-5xl text-center hidden xl:block">
43+
COMING SOON
44+
</h2>
45+
<h2 className="text-[1rem] font-bold mb-2 md:mb-3 lg:text-[40px] md:text-3xl text-center block lg:block xl:hidden">
46+
PYCON COUNTDOWN
47+
</h2>
48+
<div className="flex justify-center gap-4 md:space-x-8 text-center text-2xl lg:text-[75px] md:text-[55px] xl:text-[60px] leading-[100%]">
49+
<div>
50+
<p className="text-center tabular-nums tracking-[-0.05em]">{`${timeLeft.days}`}</p>
51+
<p className="text-sm md:text-xl">DAYS</p>
52+
</div>
53+
<div>
54+
<p className="text-center tabular-nums tracking-[-0.05em]">{`${timeLeft.hours}`}</p>
55+
<p className="text-sm md:text-xl">HRS</p>
56+
</div>
57+
<div>
58+
<p className="text-center tabular-nums tracking-[-0.05em]">{`${timeLeft.minutes}`}</p>
59+
<p className="text-sm md:text-xl">MIN</p>
60+
</div>
61+
<div>
62+
<p className="text-center tabular-nums tracking-[-0.05em]">{`${timeLeft.seconds}`}</p>
63+
<p className="text-sm md:text-xl">SEC</p>
64+
</div>
65+
</div>
66+
</div>
67+
);
68+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { Button } from '@/components/ui/button';
2+
import { cn } from '@/lib/utils';
3+
import CountdownTimer from './CountdownTimer';
4+
import Link from 'next/link';
5+
6+
interface Event {
7+
title: string;
8+
date: string;
9+
location: string;
10+
variant: 'main' | 'regular'; // "main" for the featured event, "regular" for other events
11+
link: string;
12+
}
13+
14+
export default function EventCard({ event }: { event: Event }) {
15+
return (
16+
<div
17+
className={cn(
18+
'rounded-md border py-4 border-midori-green bg-medium-dark-green text-center xl:py-10',
19+
event.variant !== 'main' &&
20+
'transition-transform duration-200 hover:scale-105',
21+
event.variant === 'main' &&
22+
'bg-gradient-ltr-darkgreen-lightgreen py-8 lg:py-14 max-w-[80%] md:max-w-[80%] lg:max-w-[80%] mx-auto xl:text-left md:px-6 xl:px-14 xl:py-7 xl:flex xl:max-w-[100%] xl:justify-between hover:'
23+
)}
24+
>
25+
<div>
26+
<h2
27+
className={cn(
28+
'font-semibold text-sm lg:text-2xl md:text-xl xl:text-[40px] xl:mb-2',
29+
event.variant === 'main' &&
30+
'text-[20px] mb-2 lg:text-5xl lg:mb-3 md:text-3xl xl:text-[45px]'
31+
)}
32+
>
33+
{event.title}
34+
</h2>
35+
<p
36+
className={cn(
37+
'text-[8px] lg:text-[15px] md:text-[11px] xl:text-xl space-y-1',
38+
event.variant === 'main' &&
39+
'text-xs lg:text-xl md:text-[17px] md:leading-tight'
40+
)}
41+
>
42+
{event.date} <br /> {event.location}
43+
</p>
44+
{event.variant === 'main' && (
45+
<Button className="mx-auto mt-5 text-[10px] font-medium text-dark-green px-[10px] py-[6px] bg-primary hover:scale-105 hover:bg-primary transition-transform duration-300 rounded-full md:py-[9px] md:px-5 md:text-[12px] lg:py-[12px] lg:px-6 lg:text-[16px] xl:mx-0 xl:text-2xl">
46+
<Link href="/404">Register Here</Link>
47+
</Button>
48+
)}
49+
</div>
50+
51+
{event.variant === 'main' && (
52+
<div className="hidden xl:block border-4 rounded-full border-midori-green"></div>
53+
)}
54+
55+
{event.variant === 'main' && (
56+
<div className="hidden xl:block mr-8">
57+
<CountdownTimer eventDate={new Date(event.date).toISOString()} />
58+
</div>
59+
)}
60+
</div>
61+
);
62+
}

app/(home)/components/Footer.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import logo from '@/public/assets/logo.svg';
88
import { Button } from '@/components/ui/button';
99
import { Input } from '@/components/ui/input';
1010
import { Checkbox } from '@/components/ui/checkbox';
11-
import { ChevronDown } from 'lucide-react';
12-
import {
13-
Accordion,
14-
AccordionTrigger,
15-
AccordionContent,
16-
AccordionItem,
17-
} from '@/components/ui/accordion';
11+
// import { ChevronDown } from 'lucide-react';
12+
// import {
13+
// Accordion,
14+
// AccordionTrigger,
15+
// AccordionContent,
16+
// AccordionItem,
17+
// } from '@/components/ui/accordion';
1818

1919
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
2020
import {
@@ -174,7 +174,7 @@ export function Footer() {
174174
</Link>
175175
))}
176176

177-
<div className="col-span-2 flex justify-center md:justify-start ">
177+
{/* <div className="col-span-2 flex justify-center md:justify-start ">
178178
<Accordion
179179
type="single"
180180
collapsible
@@ -194,7 +194,7 @@ export function Footer() {
194194
</AccordionContent>
195195
</AccordionItem>
196196
</Accordion>
197-
</div>
197+
</div> */}
198198
</div>
199199
</div>
200200
</div>

app/(home)/components/Sponsors.tsx

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { Container } from '@/components/ui/container';
2+
import dynamic from 'next/dynamic';
3+
const SponsorsDesktop = dynamic(() => import('./SponsorsDesktop'));
4+
const SponsorsMobile = dynamic(() => import('./SponsorsMobile'));
5+
6+
interface SponsorshipProps {
7+
name: string;
8+
logo: string;
9+
logoMobile: string;
10+
description: string;
11+
url: string;
12+
}
13+
14+
export function Sponsors() {
15+
const sponsors: SponsorshipProps[] = [
16+
{
17+
name: 'Mugna Tech',
18+
logo: '/sponsor-logos/mugna-logo.png',
19+
logoMobile: '/sponsor-logos/mugna-logo.png',
20+
description:
21+
'Mugna Tech specializes in Web, Software, and Mobile Development, UI/UX Design, and more, with 75+ projects for diverse businesses.',
22+
url: 'https://mugna.tech',
23+
},
24+
{
25+
name: 'Codev',
26+
logo: '/sponsor-logos/codev-logo.png',
27+
logoMobile: '/sponsor-logos/codev-logo.png',
28+
description:
29+
'Hire top offshore developers with CoDev—skilled professionals dedicated to your success.',
30+
url: 'https://codev.com',
31+
},
32+
{
33+
name: 'Ingenuity Software',
34+
logo: '/sponsor-logos/ingenuity-logo.png',
35+
logoMobile: '/sponsor-logos/ingenuity-logo-mobile.png',
36+
description:
37+
'Ingenuity Software is a Davao-based software development company that turns ideas into impactful digital solutions. ',
38+
url: 'https://ingenuity.ph',
39+
},
40+
{
41+
name: 'PythonPH',
42+
logo: '/sponsor-logos/pythonph-logo.png',
43+
logoMobile: '/sponsor-logos/pythonph-logo-mobile.png',
44+
description:
45+
'Python Philippines is a volunteer-run non-profit supporting the growth of the Python community in the country.',
46+
url: 'https://python.ph',
47+
},
48+
{
49+
name: 'Stace',
50+
logo: '/sponsor-logos/stace-logo.svg',
51+
logoMobile: '/sponsor-logos/stace-logo.svg',
52+
description:
53+
'Stace is a comprehensive platform designed to enhance and simplify the rental experience for both renters and landlords.',
54+
url: 'https://www.stace.app',
55+
},
56+
];
57+
58+
return (
59+
<section className="bg-[#112018] py-16 font-montserrat lg:mb-[-90px] md:mb-[-70px] sm:mb-0">
60+
<Container>
61+
{/* Desktop View (768px and up) */}
62+
<section className="hidden md:block">
63+
<SponsorsDesktop sponsors={sponsors} />
64+
</section>
65+
66+
{/* Mobile View (Below 768px) */}
67+
<section className="md:hidden">
68+
<SponsorsMobile sponsors={sponsors} />
69+
</section>
70+
</Container>
71+
</section>
72+
);
73+
}

0 commit comments

Comments
 (0)