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
81 changes: 43 additions & 38 deletions apps/next/src/app/events/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@ import CalendarView from "@/components/ui/calendar-view";
import EventCard, { type EventInfo } from "@/components/ui/card/event-card";
import EventCardSkeleton from "@/components/ui/skeleton/event-card-skeleton";
import { useMediaQuery } from "@/hooks/useMediaQuery";
import { getEventType } from "@/utils/funcs";
import {
classifyEvent,
EVENT_CATEGORIES,
type EventCategory,
} from "@/utils/classifyEvent";
import { HallEnum } from "@/utils/types";

const Events = () => {
const [selectedDiningHall, setSelectedDiningHall] = useState<
"both" | "anteatery" | "brandywine"
>("both");
const [selectedEventType, setSelectedEventType] = useState<
"both" | "special" | "celebration"
"both" | EventCategory
>("both");
const [viewMode, setViewMode] = useState<"grid" | "calendar">("grid");
const [selectedEventData, setSelectedEventData] = useState<EventInfo | null>(
Expand All @@ -39,24 +43,28 @@ const Events = () => {
before: endOfMonth(currentDate),
});

const sortedEvents =
(events?.length ?? 0) > 0
? [...(events ?? [])].sort(
(a: any, b: any) =>
new Date(a.start).getTime() - new Date(b.start).getTime(),
)
: [];
const sortedEvents = (events ?? []).sort(
(a: any, b: any) =>
new Date(a.start).getTime() - new Date(b.start).getTime(),
);

const eventsWithType = sortedEvents.map((event: any) => ({
...event,
eventType: classifyEvent(
event.title,
`${event.shortDescription ?? ""} ${event.longDescription ?? ""}`,
),
}));

const filteredEvents = sortedEvents.filter((event: any) => {
const filteredEvents = eventsWithType.filter((event: any) => {
const matchesDiningHall =
selectedDiningHall === "both" ||
(selectedDiningHall === "anteatery" &&
event.restaurantId === "anteatery") ||
(selectedDiningHall === "brandywine" &&
event.restaurantId === "brandywine");
const matchesEventType =
selectedEventType === "both" ||
getEventType(event.title) === selectedEventType;
selectedEventType === "both" || event.eventType === selectedEventType;
return matchesDiningHall && matchesEventType;
});

Expand Down Expand Up @@ -85,6 +93,7 @@ const Events = () => {
? HallEnum.ANTEATERY
: HallEnum.BRANDYWINE,
isOngoing: resource.start <= now && resource.end >= now,
eventType: resource.eventType,
});
};

Expand Down Expand Up @@ -156,7 +165,7 @@ const Events = () => {
<span className="text-sm font-medium text-slate-900 dark:text-white">
Event Type
</span>
<div className="flex gap-3">
<div className="flex flex-wrap gap-3">
<Button
variant="outlined"
size="small"
Expand All @@ -169,37 +178,32 @@ const Events = () => {
>
All Events
</Button>
<Button
variant="outlined"
size="small"
onClick={() => setSelectedEventType("special")}
className={`!px-4 !py-1 flex items-center justify-center !normal-case !text-sm !font-thin ${
selectedEventType === "special"
? "!bg-sky-700 !text-white !border-sky-700 hover:!bg-sky-800 dark:!bg-blue-300 dark:!text-gray-900 dark:!border-blue-300 dark:hover:!bg-blue-400"
: "!bg-white !border-sky-700 !text-slate-900 hover:!bg-sky-50 dark:!bg-transparent dark:!border-blue-300 dark:!text-white dark:hover:!bg-zinc-700"
}`}
>
Special Meals
</Button>
<Button
variant="outlined"
size="small"
onClick={() => setSelectedEventType("celebration")}
className={`!px-4 !py-1 flex items-center justify-center !normal-case !text-sm !font-thin ${
selectedEventType === "celebration"
? "!bg-sky-700 !text-white !border-sky-700 hover:!bg-sky-800 dark:!bg-blue-300 dark:!text-gray-900 dark:!border-blue-300 dark:hover:!bg-blue-400"
: "!bg-white !border-sky-700 !text-slate-900 hover:!bg-sky-50 dark:!bg-transparent dark:!border-blue-300 dark:!text-white dark:hover:!bg-zinc-700"
}`}
>
Celebration
</Button>
{EVENT_CATEGORIES.map((category) => {
const isSelected = selectedEventType === category;

return (
<Button
key={category}
variant="outlined"
size="small"
onClick={() => setSelectedEventType(category)}
className={`!px-4 !py-1 flex items-center justify-center !normal-case !text-sm !font-thin ${
isSelected
? "!bg-sky-700 dark:!bg-sky-400 !text-white !border-sky-700 dark:!border-sky-400 hover:!bg-sky-800 dark:hover:!bg-sky-500"
: "!bg-white dark:!bg-zinc-800 !border-sky-700 dark:!border-sky-400 !text-slate-900 dark:!text-zinc-100 hover:!bg-sky-50 dark:hover:!bg-zinc-700"
}`}
>
{category}
</Button>
);
})}
</div>
</div>
<div className="flex flex-col gap-3">
<span className="text-sm font-medium text-slate-900 dark:text-white">
Location
</span>
<div className="flex gap-3">
<div className="flex flex-wrap gap-3">
<Button
variant="outlined"
size="small"
Expand Down Expand Up @@ -279,6 +283,7 @@ const Events = () => {
shortDesc={event.shortDescription}
longDesc={event.longDescription}
isOngoing={event.start <= now && event.end >= now}
eventType={event.eventType}
/>
))}
</div>
Expand Down
5 changes: 4 additions & 1 deletion apps/next/src/components/ui/card/event-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Image from "next/image";
import React from "react";
import EventTypeBadge from "@/components/ui/event-type-badge";
import { useMediaQuery } from "@/hooks/useMediaQuery";
import type { EventCategory } from "@/utils/classifyEvent";
import { dateToString, timeToString, toTitleCase } from "@/utils/funcs";
import { HallEnum } from "@/utils/types";
import EventDialogContent from "../event-dialog-content";
Expand Down Expand Up @@ -35,6 +36,8 @@ export interface EventInfo {
location: HallEnum;
/** If true, indicates the event is currently ongoing and displays a badge. */
isOngoing: boolean;
/** The category of the event, determined by its description. */
eventType: EventCategory;
}

/**
Expand Down Expand Up @@ -77,7 +80,7 @@ const EventCardContent = React.forwardRef<
height={300}
className="w-full object-contain"
/>
<EventTypeBadge title={props.name} />
<EventTypeBadge type={props.eventType} />
</div>
<CardContent className="flex flex-col gap-2 p-4">
<div className="flex flex-row gap-2 items-center">
Expand Down
30 changes: 17 additions & 13 deletions apps/next/src/components/ui/card/upcoming-event-card.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { AccessTime, CalendarMonth, LocationOn } from "@mui/icons-material";
import { Box, Card, Dialog, Typography } from "@mui/material";
import { useState } from "react";
import { classifyEvent } from "@/utils/classifyEvent";
import { timeToString, toTitleCase } from "@/utils/funcs";
import { HallEnum, numToMonth } from "@/utils/types";
import EventDialogContent from "../event-dialog-content";
import EventTypeBadge from "../event-type-badge";
import type { EventInfo } from "./event-card";

/** A compact card for an upcoming event in the horizontal scroll row */
Expand All @@ -25,7 +27,10 @@ export default function UpcomingEventCard({
const [open, setOpen] = useState(false);
const startDate = event.start ? new Date(event.start) : null;
const endDate = event.end ? new Date(event.end) : null;

const eventType = classifyEvent(
event.title,
`${event.shortDescription ?? ""} ${event.longDescription ?? ""}`,
);
/*

Seems to be an error where HallEnum is not properly getting the info
Expand All @@ -49,6 +54,7 @@ export default function UpcomingEventCard({
isOngoing: startDate
? startDate <= new Date() && (endDate ? endDate >= new Date() : false)
: false,
eventType,
};

// alternative sizing depending on mobile/desktop
Expand All @@ -60,22 +66,20 @@ export default function UpcomingEventCard({
return (
<>
<Card
className="w-full rounded-xl p-5 shadow-sm hover:shadow-md transition cursor-pointer text-left bg-transparent"
sx={{ border: 1, borderColor: "divider" }}
className="relative w-full rounded-xl border border-neutral-200 dark:border-neutral-700 p-5 shadow-sm hover:shadow-md transition cursor-pointer text-left bg-transparent"
onClick={() => setOpen(true)}
>
<div className="mb-3 flex items-start gap-2 min-w-0">
<Typography
className={`${titleSize} font-bold leading-tight pr-2 line-clamp-2 min-w-0 flex-1 whitespace-normal break-normal`}
color="primary"
<div className="absolute top-2 right-0 h-14 w-48 scale-75 origin-top-right">
<div className="hidden md:block [&>span]:!bg-sky-100 [&>span]:!text-sky-700 [&>span]:!shadow-sm">
<EventTypeBadge type={eventType} />
</div>
</div>
<div className="mb-3 flex items-start gap-2 min-w-0 pr-28">
<h3
className={`${titleSize} whitespace-normal break-normal min-w-0 flex-1 whitespace-normal break-normal font-bold leading-tight text-sky-700`}
>
{event.title}
</Typography>
<span
className={`flex-shrink-0 ${tagSize} font-semibold tracking-wider bg-sky-100 text-sky-700 dark:bg-transparent dark:border dark:border-blue-300 dark:text-blue-300 px-2 py-0.5 rounded-full`}
>
Celebration
</span>
</h3>
</div>
<div className={spacing}>
{startDate && (
Expand Down
2 changes: 1 addition & 1 deletion apps/next/src/components/ui/event-dialog-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default function EventDialogContent(
height={600}
className="w-full object-contain"
/>
<EventTypeBadge title={props.name} />
<EventTypeBadge type={props.eventType} />
</div>
<DialogContent
sx={{ padding: "20px 24px 24px !important" }}
Expand Down
2 changes: 1 addition & 1 deletion apps/next/src/components/ui/event-drawer-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default function EventDrawerContent(
height={600}
className="w-full object-contain"
/>
<EventTypeBadge title={props.name} />
<EventTypeBadge title={props.name} desc={props.longDesc} />
</div>
<Box sx={{ padding: "20px 24px 24px" }} className="flex flex-col gap-2">
<Typography
Expand Down
10 changes: 4 additions & 6 deletions apps/next/src/components/ui/event-type-badge.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { getEventType } from "@/utils/funcs";
import type { EventCategory } from "@/utils/classifyEvent";

export default function EventTypeBadge({ title }: { title: string }) {
const type = getEventType(title);
if (type !== "celebration" && type !== "special") return null;
export default function EventTypeBadge({ type }: { type: EventCategory }) {
return (
<span className="absolute bottom-3 right-3 bg-white text-black dark:bg-[#303035] dark:text-white text-sm font-medium px-4 py-1.5 rounded-full shadow-md">
{type === "celebration" ? "Celebration" : "Special Meal"}
<span className="absolute bottom-3 right-3 bg-white/80 text-black text-sm font-medium px-4 py-1.5 rounded-full shadow-md">
{type}
</span>
);
}
Loading
Loading