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
52 changes: 45 additions & 7 deletions src/components/Events.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,62 @@
import { useState, useMemo } from "react";
import { useCollection } from "@/hooks/useCollection";
import {Carousel, Card} from "./ui/apple-cards-carousel";
import collections from "@/firebase/collections";
import Event from "@/features/events/interfaces/Event";
import BouncingText from "./ui/BouncingText";

export default function Events() {
const [showUpcoming, setShowUpcoming] = useState(true);
const { documents: events } = useCollection<Event>(collections.eventsCollection,null, ["date", "asc"],false, true);
const cards = (events ?? []).map((event) => (
<Card key={event.id} card={event} />

const filteredEvents = useMemo(() => {
if (!events) return [];
const now = new Date();
return events.filter(event => {
const eventDate = event.date.toDate();
return showUpcoming ? eventDate >= now : eventDate < now;
});
}, [events, showUpcoming]);

const cards = filteredEvents.map((event) => (
<Card key={event.id} card={event} upcoming={showUpcoming} />
));

return (
<section id="events" className="relative">
<div className="min-h-screen flex flex-col items-start justify-center text-gray-800 dark:text-gray-200 p-6 rounded-[70px]">
<h1 className="md:ms-12 text-3xl md:text-5xl font-bold mb-6 text-purple-300">
<BouncingText text="Join us at our Events!" />
</h1>
<div className="md:ms-12 w-full max-w-7xl">
<h1 className="text-3xl md:text-5xl font-bold mb-6 text-purple-300">
<BouncingText text="Join us at our Events!" />
</h1>

<div className="flex items-center gap-3 mb-6">
<span className={`text-sm font-medium ${!showUpcoming ? 'text-purple-300' : 'text-gray-400'}`}>
Past Events
</span>
<button
onClick={() => setShowUpcoming(!showUpcoming)}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-purple-400 focus:ring-offset-2 ${
showUpcoming ? 'bg-purple-500' : 'bg-gray-600'
}`}
role="switch"
aria-checked={showUpcoming}
>
<span
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
showUpcoming ? 'translate-x-6' : 'translate-x-1'
}`}
/>
</button>
<span className={`text-sm font-medium ${showUpcoming ? 'text-purple-300' : 'text-gray-400'}`}>
Upcoming Events
</span>
</div>
</div>

{(cards.length === 0) && (
<div className="text-red-500 mb-6 text-lg">
Something went wrong, please reload.
<div className="text-red-500 mb-6 text-lg md:ms-12">
{events ? `No ${showUpcoming ? 'upcoming' : 'past'} events found.` : 'Something went wrong, please reload.'}
</div>
)}
<Carousel items={cards} />
Expand Down
35 changes: 18 additions & 17 deletions src/components/ui/apple-cards-carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { cn } from "@/lib/utils";
import { AnimatePresence, motion } from "motion/react";

import { useOutsideClick } from "@/hooks/useOutsideClick";
import { EventCategoryEnum } from "@/features/events/enums/EventCategoryEnum";
import Event from "@/features/events/interfaces/Event";

interface CarouselProps {
Expand Down Expand Up @@ -95,9 +94,11 @@ export const Carousel = ({ items }: CarouselProps) => {
export const Card = ({
card,
layout = false,
upcoming = true,
}: {
card: Event;
layout?: boolean;
upcoming?: boolean;
}) => {
const [open, setOpen] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
Expand All @@ -121,8 +122,8 @@ export const Card = ({

useOutsideClick(containerRef, () => handleClose());

const handleOpen = (category: string) => {
if (category !== EventCategoryEnum.Past) {
const handleOpen = () => {
if (upcoming) {
setOpen(true);
}
};
Expand Down Expand Up @@ -156,18 +157,18 @@ export const Card = ({
>
<IconX className="h-6 w-6 text-neutral-100 dark:text-neutral-900" />
</button>
<motion.p
layoutId={layout ? `category-${card.title}` : undefined}
className="text-base font-medium text-black dark:text-white"
>
{card.category}
</motion.p>
<motion.p
layoutId={layout ? `title-${card.title}` : undefined}
className="mt-4 text-2xl font-semibold text-neutral-700 md:text-5xl dark:text-white"
>
{card.title}
</motion.p>
{card.special && <motion.div
layoutId={layout ? `category-${card.special}` : undefined}
className="inline-block mt-2 px-3 py-1 bg-gradient-to-r from-purple-500 to-indigo-500 rounded-full text-sm font-semibold text-white shadow-lg md:text-base"
>
{card.special}
</motion.div>}
{card.location && <motion.p
layoutId={layout ? `location-${card.location}` : undefined}
className="mt-2 text-base font-medium text-neutral-600 md:text-xl dark:text-neutral-300"
Expand Down Expand Up @@ -230,23 +231,23 @@ export const Card = ({
</AnimatePresence>
<motion.button
layoutId={layout ? `card-${card.title}` : undefined}
onClick={() => handleOpen(card.category)}
onClick={() => handleOpen()}
className="relative z-10 flex h-[60vh] w-[70vw] flex-col items-start justify-start overflow-hidden rounded-3xl bg-gray-100 md:h-[40rem] md:w-96 dark:bg-neutral-900 hover:cursor-pointer"
>
<div className="pointer-events-none absolute inset-x-0 top-0 z-30 h-full bg-gradient-to-b from-black/50 via-transparent to-transparent" />
<div className="relative z-40 p-8">
<motion.p
layoutId={layout ? `category-${card.category}` : undefined}
className="text-left text-sm font-medium text-white md:text-base"
>
{card.category}
</motion.p>
<motion.p
layoutId={layout ? `title-${card.title}` : undefined}
className="mt-4 max-w-xs text-left text-xl font-semibold [text-wrap:balance] text-white md:text-3xl"
>
{card.title}
</motion.p>
{card.special && <motion.div
layoutId={layout ? `category-${card.special}` : undefined}
className="inline-block mt-2 px-3 py-1 bg-gradient-to-r from-purple-500 to-indigo-500 rounded-full text-sm font-semibold text-white shadow-lg md:text-base"
>
{card.special}
</motion.div>}
<motion.p
layoutId={layout ? `date-${card.date}` : undefined}
className="mt-1 text-left text-sm font-medium text-white md:text-lg"
Expand All @@ -262,7 +263,7 @@ export const Card = ({
src={card.src}
alt={card.title}
fill="true"
className={`absolute inset-0 z-10 object-cover ${card.category === "Past Event" ? "brightness-50" : ""}`}
className={`absolute inset-0 z-10 object-cover ${!upcoming? "brightness-50" : ""}`}
/>
</motion.button>
</>
Expand Down
1 change: 1 addition & 0 deletions src/features/events/interfaces/Event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export default interface Event {
description?: string;
link?: Link;
additionalLinks?: Link[];
special?: string;
}