Skip to content

Commit

Permalink
805-frontend-display-all-events-to-admin (#814)
Browse files Browse the repository at this point in the history
* 805-frontend-display-all-events-to-admin

Initial commit

* Created EventService.ts for fetching all events

* Add all files for Admin All Events view

Needs refactoring...

* Fetch events in WrappedAdminEventView

* Center event items

* Create variant for EventPreview

* Both regular and admin card

  * Regular is a thicker padding

  * Admin is a smaller padding

* Remove unneeded test file

* Document viewButtonText in EventPreview

* Update comment for AdminEventView

* Also remove `relative` from ReusableButtons as already exists

* Reset button changes

* Remove code related to EventDetailed
  • Loading branch information
jeffplays2005 authored Oct 31, 2024
1 parent 30a5a47 commit 13817ab
Show file tree
Hide file tree
Showing 8 changed files with 403 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import type { Meta, StoryObj } from "@storybook/react"
import AdminAllEvents from "./AdminAllEvents"
import { Timestamp } from "firebase/firestore"

const meta: Meta<typeof AdminAllEvents> = {
component: AdminAllEvents
}

export default meta
type Story = StoryObj<typeof meta>

const earlierStartDate = Timestamp.fromDate(new Date(2023, 1, 1))
const startDate = Timestamp.fromDate(new Date(2024, 1, 1))

export const DefaultEventsPage: Story = {
args: {
rawEvents: [
{
id: "1",
title: "UASC New event 1",
location: "UASC",
physical_start_date: earlierStartDate,
sign_up_start_date: earlierStartDate,
sign_up_end_date: earlierStartDate,
google_forms_link: "https://google.com",
description:
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Reprehenderit adipisci repellat perferendis. Quia ipsum laborum est, veniam accusamus voluptas praesentium, odio perspiciatis blanditiis sequi dignissimos unde. Natus delectus nihil cum."
},
{
id: "2",
title: "UASC New event 2",
location: "UASC",
physical_start_date: earlierStartDate,
sign_up_start_date: startDate,
sign_up_end_date: earlierStartDate,
description:
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Reprehenderit adipisci repellat perferendis. Quia ipsum laborum est, veniam accusamus voluptas praesentium, odio perspiciatis blanditiis sequi dignissimos unde. Natus delectus nihil cum."
},
{
id: "3",
title: "UASC New Event 3",
location: "UASC",
physical_start_date: earlierStartDate,
sign_up_start_date: startDate,
sign_up_end_date: earlierStartDate,
description:
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Reprehenderit adipisci repellat perferendis. Quia ipsum laborum est, veniam accusamus voluptas praesentium, odio perspiciatis blanditiis sequi dignissimos unde. Natus delectus nihil cum."
}
]
},
tags: ["autodocs"]
}

export const EmptyEventsPage: Story = {
args: {
rawEvents: []
},
tags: ["autodocs"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import EventsCardPreview, {
IEventsCardPreview
} from "@/components/generic/Event/EventPreview/EventPreview"
import { DateUtils } from "@/components/utils/DateUtils"
import { Event } from "@/models/Events"
import { useCallback, useMemo, useState } from "react"
import {
EventDateComparisons,
EventRenderingUtils
} from "@/components/generic/Event/EventUtils"
import Button from "@/components/generic/FigmaButtons/FigmaButton"
import Loader from "@/components/generic/SuspenseComponent/Loader"

/**
* Interface representing the properties of the Events Page.
*/
interface IAdminAllEvents {
/**
* A list of _all_ {@link Event}s which should either be mocked
* or fetched from the backend. **NO** pre-processing should be
* performed on this list as it will be further mutated in the
* {@link EventsPage} component.
*/
rawEvents?: Event[]

/**
* Indicates whether the events are currently being loaded.
*/
isLoading?: boolean

/**
* Indicates whether there are more events to be fetched.
*/
hasMoreEvents?: boolean

/**
* Function to fetch more events.
*/
fetchMoreEvents?: () => void

/**
* The ID of the preselected event.
*/
preselectedEventId?: string

/**
* Callback function to handle changes to the selected event ID.
* @param id - The new selected event ID.
*/
onSelectedEventIdChange?: (id?: string) => void
}

/**
* Helper type to split the raw events into upcoming and past ones,
* this is important as they need to be sorted differently
*/
interface EventList {
upcomingAndCurrentEvents: Event[]
pastEvents: Event[]
}

/**
* Used to handle all _presentation_ logic conerning the evnts
*
* - **Do not make any network requests in this component, the data should
* be fetched seperately and passed in as {@link rawEvents}**
* - String operations are ideally done in {@link EventMessages}
* - Complex date comparisons should also be abstracted away into {@link EventDateComparisons}
*/
const AdminAllEvents = ({
rawEvents = [],
hasMoreEvents,
isLoading,
fetchMoreEvents,
preselectedEventId,
onSelectedEventIdChange
}: IAdminAllEvents) => {
const [selectedEventId, setSelectedEventId] = useState<string | undefined>(
preselectedEventId
)

const eventSelectionHandler = useCallback(
(id?: string) => {
setSelectedEventId(id)
onSelectedEventIdChange?.(id)
},
[setSelectedEventId, onSelectedEventIdChange]
)

/**
* Partitions of the array that allow us to individually process the ongoing events
*/
const eventList = useMemo(() => {
return rawEvents.reduce(
(buf: EventList, event) => {
const { physical_start_date, physical_end_date } = event
if (
EventDateComparisons.isPastEvent(
new Date(DateUtils.timestampMilliseconds(physical_start_date)),
physical_end_date &&
new Date(DateUtils.timestampMilliseconds(physical_end_date))
)
) {
buf.pastEvents.push(event)
} else {
buf.upcomingAndCurrentEvents.push(event)
}

/**
* Start dates ascending for upcoming and current events
*/
buf.upcomingAndCurrentEvents.sort(
(
{ physical_start_date: startDate1 },
{ physical_start_date: startDate2 }
) =>
DateUtils.timestampMilliseconds(startDate1) -
DateUtils.timestampMilliseconds(startDate2)
)

return buf
},
{ upcomingAndCurrentEvents: [], pastEvents: [] }
)
}, [rawEvents])

/**
* Detailed view of the event
*/
const previewCurrentEvents: IEventsCardPreview[] =
eventList.upcomingAndCurrentEvents?.map((event) => {
return EventRenderingUtils.previewTransformer(
event,
eventSelectionHandler,
"edit event",
"admin"
)
}) || []

const previewPastEvents: IEventsCardPreview[] =
eventList.pastEvents?.map((event) => {
return EventRenderingUtils.previewTransformer(
event,
eventSelectionHandler,
"edit event",
"admin"
)
}) || []

return (
<>
<div className={`flex w-full max-w-[1000px] flex-col gap-2`}>
{selectedEventId ? null : (
<>
{isLoading ? (
<Loader />
) : (
<h5 className="text-dark-blue-100 font-bold uppercase">
{rawEvents.length > 0 ? (
<>Upcoming Events</>
) : (
<>No events found!</>
)}
</h5>
)}
{previewCurrentEvents.map((event) => (
<EventsCardPreview key={event.title} {...event} />
))}

{previewPastEvents.map((event) => (
<EventsCardPreview key={event.title} {...event} />
))}
</>
)}

{hasMoreEvents && !selectedEventId && (
<Button
variant="default"
onClick={fetchMoreEvents}
disabled={isLoading}
>
Load More
</Button>
)}
</div>
</>
)
}

export default AdminAllEvents
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Meta, StoryObj } from "@storybook/react"

import AdminEventView from "./AdminEventView"
import { Timestamp } from "firebase/firestore"

const meta: Meta<typeof AdminEventView> = {
component: AdminEventView
Expand All @@ -9,11 +10,57 @@ const meta: Meta<typeof AdminEventView> = {
export default meta
type Story = StoryObj<typeof meta>

const earlierStartDate = Timestamp.fromDate(new Date(2023, 1, 1))
const startDate = Timestamp.fromDate(new Date(2024, 1, 1))

export const DefaultAdminEventView: Story = {
args: {
handlePostEvent: () => {},
generateImageLink: async () => {
return undefined
}
},
rawEvents: []
}
}

export const AdminEventViewWithEvents: Story = {
args: {
handlePostEvent: () => {},
generateImageLink: async () => {
return undefined
},
rawEvents: [
{
id: "1",
title: "UASC New event 1",
location: "UASC",
physical_start_date: earlierStartDate,
sign_up_start_date: earlierStartDate,
sign_up_end_date: earlierStartDate,
google_forms_link: "https://google.com",
description:
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Reprehenderit adipisci repellat perferendis. Quia ipsum laborum est, veniam accusamus voluptas praesentium, odio perspiciatis blanditiis sequi dignissimos unde. Natus delectus nihil cum."
},
{
id: "2",
title: "UASC New event 2",
location: "UASC",
physical_start_date: earlierStartDate,
sign_up_start_date: startDate,
sign_up_end_date: earlierStartDate,
description:
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Reprehenderit adipisci repellat perferendis. Quia ipsum laborum est, veniam accusamus voluptas praesentium, odio perspiciatis blanditiis sequi dignissimos unde. Natus delectus nihil cum."
},
{
id: "3",
title: "UASC New Event 3",
location: "UASC",
physical_start_date: earlierStartDate,
sign_up_start_date: startDate,
sign_up_end_date: earlierStartDate,
description:
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Reprehenderit adipisci repellat perferendis. Quia ipsum laborum est, veniam accusamus voluptas praesentium, odio perspiciatis blanditiis sequi dignissimos unde. Natus delectus nihil cum."
}
]
}
}
Loading

0 comments on commit 13817ab

Please sign in to comment.