Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
a1e2838
feat: initialize durianpy testimonials
wenyngcar Mar 29, 2025
e11776d
feat: add testimonal card
wenyngcar Mar 29, 2025
cbb984b
feat: add yellow & white star icon
wenyngcar Mar 29, 2025
a3156b9
feat: custom star rating component
wenyngcar Mar 29, 2025
dd935d4
feat: add testimonial card
wenyngcar Mar 29, 2025
eb8194f
build: add shadcn avatar
wenyngcar Mar 29, 2025
2b24593
refactor: make height static for card
wenyngcar Mar 30, 2025
9039218
feat: add username, userprofile, & date
wenyngcar Mar 30, 2025
616d9c7
feat: add dummy data
wenyngcar Mar 30, 2025
8ec7a7b
refactor: adjust height, width, and position of elements
wenyngcar Mar 31, 2025
8fa0de2
feat: add next & prev arrow icon
wenyngcar Apr 2, 2025
11fcfe1
refactor: adjust height & width for responsiveness
wenyngcar Apr 2, 2025
c656729
fix: responsiveness at md, lg, xl
wenyngcar Apr 2, 2025
6825d40
feat: add autoplay & stop on interact
wenyngcar Apr 16, 2025
bef41cf
format: npm run format
wenyngcar Apr 16, 2025
b6b9a7a
added rating + button to testimonials sec
AkihiroJun Apr 29, 2025
96093ea
testimonials ratings and button
AkihiroJun Apr 30, 2025
9481f4d
fix: add deleted codes
wenyngcar May 1, 2025
6f151ba
refactor: adjust alignment
wenyngcar May 1, 2025
18a6c5b
format: npm run format
wenyngcar May 1, 2025
2bb1fd8
fix: resolve rebase conflict
wenyngcar May 1, 2025
d34a74c
build: npm install
wenyngcar May 1, 2025
a8a8c63
fix: logo, ratings, write a review bttn allignment & size
wenyngcar May 9, 2025
4d4a397
removed footer
Apr 22, 2025
706431d
feat: add sponsor section
Maakkkuu Apr 8, 2025
2b54734
chore: reimport icons and images
wenyngcar Jun 8, 2025
f0aaca3
fix: mobile view
wenyngcar Jun 9, 2025
9182a0e
fix: tablet view
wenyngcar Jun 9, 2025
3bb1226
refactor: redirect read more to /404
wenyngcar Jun 9, 2025
f1b38b7
feat: add text overflow handling in testimonials
Jun 20, 2025
619d61a
feat: updated hidden component and set pycon davao 2025 date
devRaxx Aug 17, 2025
e7d1491
fix: changed event titles
devRaxx Aug 17, 2025
192343b
fix: capitalized C on every events
devRaxx Aug 18, 2025
14ea963
feat: removed upcoming events link and disabled registration button
seangaaab Aug 19, 2025
3aa6927
feat: removed testimonials
seangaaab Aug 19, 2025
0d7c9ed
feat: removed testimonials
seangaaab Aug 19, 2025
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
11 changes: 9 additions & 2 deletions app/(home)/components/EventCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,15 @@ export default function EventCard({ event }: { event: Event }) {
{event.date} <br /> {event.location}
</p>
{event.variant === 'main' && (
<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">
<Link href="/404">Register Here</Link>
<Button
disabled={!event.link}
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"
>
{event.link ? (
<Link href={event.link}>Register Here</Link>
) : (
<Link href={'/#'}>Registration coming soon</Link>
)}
</Button>
)}
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/(home)/components/Sponsors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function Sponsors() {

return (
<section className="bg-[#112018] py-16 font-montserrat lg:mb-[-90px] md:mb-[-70px] sm:mb-0">
<Container>
<Container className="overflow-x-clip">
{/* Desktop View (768px and up) */}
<section className="hidden md:block">
<SponsorsDesktop sponsors={sponsors} />
Expand Down
2 changes: 1 addition & 1 deletion app/(home)/components/SponsorsDesktop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ const SponsorsDesktop = ({ sponsors }: { sponsors: SponsorshipProps[] }) => {
<p className="lg:text-xl mt-4 text-[12px] max-md:m-5 pr-3 pl-3">
{featuredSponsor.description}
<br></br>
<br></br> {featuredSponsor.name}
<br></br>- {featuredSponsor.name}
</p>
</Link>
</div>
Expand Down
291 changes: 291 additions & 0 deletions app/(home)/components/Testimonials.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
'use client';

import { Button } from '@/components/ui/button';
import Image from 'next/image';
import { Container } from '@/components/ui/container';
import Link from 'next/link';
import { CarouselDots, type CarouselApi } from '@/components/ui/carousel';
import { useState, useRef, useEffect } from 'react';
import YellowStar from '@/public/assets/testimonials/yellow-star.svg';
import WhiteStar from '@/public/assets/testimonials/white-star.svg';
import ChatBubble from '@/public/assets/testimonials/chat-bubble.svg';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from '@/components/ui/carousel';

type TestimonialProps = {
text: string;
rate: number;
active: boolean;
};

export function Testimonials() {
const dummyData = [
{
name: 'AlexByte_97',
date: '2 days ago',
comment:
"I've been following similar content for a while, but this one really stands out. The attention to detail and the way everything is explained so clearly make it incredibly easy to understand. Honestly, I wish more people put this level of effort into their posts. Keep it up! Looking forward to more amazing content like this! ????",
rate: 5,
profilePic: 'https://github.com/shadcn.png',
},
{
name: 'GamerXtreme',
date: '3 weeks ago',
comment: 'Not bad, but I expected a bit more tbh. ??',
rate: 3,
profilePic: 'https://github.com/shadcn.png',
},
{
name: 'TechieTasha',
date: '5 days ago',
comment: 'Super useful, definitely sharing this! ??',
rate: 4,
profilePic: 'https://github.com/shadcn.png',
},
{
name: 'MemeLord420',
date: '1 month ago',
comment: "Bro, this ain't it... ??",
rate: 2,
profilePic: 'https://github.com/shadcn.png',
},
{
name: 'NeonC0der',
date: '10 hours ago',
comment:
'I appreciate the effort that went into this, but I feel like some parts could have been elaborated on a bit more. Certain sections were great, but others felt a little rushed. That being said, I still learned a lot and really enjoyed the overall message. Keep refining your style because you definitely have potential! Excited to see how your content evolves over time. ??',
rate: 4,
profilePic: 'https://github.com/shadcn.png',
},
];

const [api, setApi] = useState<CarouselApi>();
const [current, setCurrent] = useState(0);
const [isInteracting, setIsInteracting] = useState(false);

useEffect(() => {
if (!api) {
return;
}
setCurrent(api.selectedScrollSnap());

api.on('select', () => {
setCurrent(api.selectedScrollSnap());
});
}, [api]);

return (
<section className="relative z-10 text-white py-12 sm:py-16 -ms-4 lg:-ms-0 ">
<Container className="space-y-6 xl:space-x-0 mx-auto lg:space-y-3">
{/* Combined container: Ratings + Button */}
<div className="flex flex-col space-y-5 xl:flex-row xl:justify-between px-[1%] 2xl:px-0 sm:pb-4 lg:flex-row lg:px-14">
{/* Logo & Ratings */}
<div className="flex flex-col items-center xl:items-start xl:text-left w-full lg:items-start">
<div className="-space-y-4">
<div className="flex items-center gap-x-2">
<Image
src="/assets/logo.svg"
height={64}
width={64}
className="h-16 sm:h-24 w-auto"
alt="Durianpy Logo"
priority
/>
<h2 className="text-2xl mt-2 sm:text-3xl sm:mt-3 font-normal">
Ratings
</h2>
</div>

{/* Star Ratings */}
<div className="flex text-xs sm:text-base sm:flex-row self items-center space-x-1 sm:space-x-4 -mt-5 ms-2">
<span className="font-semibold mt-1">4.8</span>
<div className="flex -space-x-3 sm:-space-x-1">
{[...Array(4)].map((_, i) => (
<Image
src={YellowStar}
alt="yellow star"
key={i}
className="p-2 sm:p-[6px]"
/>
))}
<Image
src={WhiteStar}
alt="yellow star"
className="p-2 sm:p-[6px]"
/>
</div>
<span className="font-light mt-1">5 reviews</span>
</div>
</div>
</div>

{/* Button */}
<div className="mx-auto">
<Link href="https://www.meetup.com/durianpy/" target="_blank">
<Button
variant="footer"
className="py-1 px-4 text-xs sm:py-1.5 sm:px-6 text-black sm:text-lg sm:font-normal lg:mt-3"
>
Write a Review
</Button>
</Link>
</div>
</div>

{/* CAROUSEL */}
<div>
<Carousel
setApi={setApi}
opts={{ loop: true }}
autoplay={!isInteracting}
autoplayInterval={5000}
onClick={() => setIsInteracting(true)}
onMouseLeave={() => setIsInteracting(false)}
className="max-w-96 sm:w-96 lg:max-w-full lg:w-full lg:px-5 mx-auto"
>
<CarouselContent className="flex mx-auto sm:-ms-4 lg:-ms-0 lg:py-8">
{dummyData.map((data, index) => (
<CarouselItem
className="flex-col justify-center lg:basis-1/3 lg:px-11"
key={index}
>
<TestimonialCard
text={data.comment}
rate={data.rate}
active={current === index ? true : false}
/>
<div
className={
current === index
? 'flex justify-center items-center space-x-3 mt-4 sm:mt-2 sm:-ms-16 lg:-ms-5 lg:scale-125 lg:mt-12 transition-all duration-300 ease-in-out'
: 'flex justify-center items-center space-x-3 mt-4 sm:mt-2 sm:-ms-16 lg:-ms-0 lg:mb-12 transition-all duration-300 ease-in-out'
}
>
<Avatar className="h-16 w-16">
<AvatarImage src={data.profilePic} />
<AvatarFallback className="text-2xl text-[#B3B3B3]">
{data.name
.split(' ')
.map((word) => word[0])
.join('')
.toUpperCase()}
</AvatarFallback>
</Avatar>
<div className="flex-col">
<div>{data.name}</div>
<div className="text-sm text-[#B3B3B3]">{data.date}</div>
</div>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious
className="hidden sm:block absolute -left-24 h-20 w-20 -mt-[5%] lg:-left-6 lg:h-20 lg:w-20"
onClick={() => api?.scrollTo(current - 1)}
/>
<CarouselNext
className="hidden sm:block absolute -right-24 h-20 w-20 -mt-[5%] lg:-right-6 lg:h-20 lg:w-20"
onClick={() => api?.scrollTo(current + 1)}
/>
<CarouselDots className="pt-5" />
</Carousel>
</div>
</Container>
</section>
);
}

export function TestimonialCard({ text, rate, active }: TestimonialProps) {
const starRate = [];
const textRef = useRef<HTMLDivElement>(null);
const [isTextOverflowing, setIsTextOverflowing] = useState(false);

// Check if text is overflowing
useEffect(() => {
const checkOverflow = () => {
if (textRef.current) {
const element = textRef.current;
const isOverflowing =
element.scrollHeight > element.clientHeight ||
element.scrollWidth > element.clientWidth;
setIsTextOverflowing(isOverflowing);
}
};

checkOverflow();
// Re-check on window resize
window.addEventListener('resize', checkOverflow);
return () => window.removeEventListener('resize', checkOverflow);
}, [text]);

// Append stars
for (let i = 0; i < 5; i++) {
// If index is greater than the rating, append white star, else yellow star.
if (i >= rate) {
starRate.push(
<Image src={WhiteStar} alt="yellow star" key={i} className="lg:p-1" />
);
} else {
starRate.push(
<Image src={YellowStar} alt="yellow star" key={i} className="lg:p-1" />
);
}
}

return (
<>
{/* Mobile View Display */}
<div className="relative sm:hidden h-24 p-5 bg-medium-dark-green border border-[#36FF90] rounded-xl w-full text-clip overflow-hidden">
<div className="text-xs sm:text-base">{text}</div>
{isTextOverflowing && (
<div className="absolute bottom-0 pb-2 pt-14 bg-gradient-to-t from-medium-dark-green from-20% inset-x-5">
<Link
href="/404"
target="_blank"
className="text-xs sm:text-base text-yellow-400 underline"
>
Read more
</Link>
</div>
)}
</div>

{/* Tablet & Laptop View Display */}
<div
className={
active === true
? 'hidden sm:block relative transition-all duration-300 ease-in-out lg:scale-125'
: 'hidden sm:block relative transition-all duration-300 ease-in-out'
}
>
<Image src={ChatBubble} alt="chat-bubble" />
<div className="flex absolute top-5 inset-x-0 justify-center space-x-2.5 lg:space-x-0.5">
{starRate}
</div>
<div
ref={textRef}
className="absolute top-16 mt-1 h-44 px-9 text-lg text-clip overflow-hidden lg:text-base lg:px-7 lg:h-1/3 xl:h-1/2"
>
{text}
</div>
{isTextOverflowing && (
<div className="absolute bottom-14 pb-2 pt-28 bg-gradient-to-t from-medium-dark-green from-25% inset-x-9 lg:inset-x-7 lg:bottom-10">
<Link
href="/404"
target="_blank"
className="text-[#B3B3B3] underline lg:text-xs"
>
Read more
</Link>
</div>
)}
</div>
</>
);
}
38 changes: 12 additions & 26 deletions app/(home)/components/UpcomingEvents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { Container } from '@/components/ui/container';
import React from 'react';
import EventCard from './EventCard';
import CountdownTimer from './CountdownTimer';
import { Button } from '@/components/ui/button';
import Link from 'next/link';
// import { Button } from '@/components/ui/button';
// import Link from 'next/link';

interface Event {
title: string;
Expand All @@ -15,32 +15,18 @@ interface Event {

const EVENTS: Event[] = [
{
title: 'Pycon Mini Davao',
date: 'June 20, 2025',
location: 'Mugna Tech, Davao City',
title: 'PyCon Davao 2025',
date: 'October 25, 2025',
location: 'Ateneo de Davao University',
variant: 'main',
link: '/404',
link: '', // TODO: Update Link
},
{
title: 'RAGs & DAGs',
date: 'June 20, 2025',
location: 'Mugna Tech, Davao City',
title: 'PyCon Davao Sprint Day',
date: 'October 26, 2025',
location: 'TBA',
variant: 'regular',
link: '/404',
},
{
title: 'RAGs & DAGs',
date: 'June 20, 2025',
location: 'Mugna Tech, Davao City',
variant: 'regular',
link: '/404',
},
{
title: 'RAGs & DAGs',
date: 'June 20, 2025',
location: 'Mugna Tech, Davao City',
variant: 'regular',
link: '/404',
link: '', // TODO: Update Link
},
];

Expand Down Expand Up @@ -68,9 +54,9 @@ const UpcomingEvents = () => {
</div>

{/* See more Events Button */}
<Button className="bg-primary hover:bg-primary mx-auto max-w-[80%] lg:max-w-[80%] md:max-w-[80%] w-full md:py-2 xl:py-4 md:font-medium text-dark-green lg:py-4 lg:text-[15px] py-[4px] font-semibold text-[11px] xl:text-2xl xl:max-w-full">
{/* <Button className="bg-primary hover:bg-primary mx-auto max-w-[80%] lg:max-w-[80%] md:max-w-[80%] w-full md:py-2 xl:py-4 md:font-medium text-dark-green lg:py-4 lg:text-[15px] py-[4px] font-semibold text-[11px] xl:text-2xl xl:max-w-full">
<Link href="/404">See More Events</Link>
</Button>
</Button> */}
</Container>
);
};
Expand Down
Loading