Skip to content

Commit

Permalink
772 event view for user (#809)
Browse files Browse the repository at this point in the history
* pages made

* page set up

* events card imported

* story structure set up

* mock data

* map function to map the props

* import interface as type

* reimported

* interface created to accept event card props

* name change

* mock data passed into storybook

* removed mocks from actual page

* bg image

* basic fetching done

* basic implementation of events view

* improve documentation

* add documentation to helper methods

* add documentation and enforce consistent naming

* update docs

* pages made

* page set up

* events card imported

* story structure set up

* mock data

* map function to map the props

* import interface as type

* reimported

* interface created to accept event card props

* name change

* mock data passed into storybook

* removed mocks from actual page

* bg image

* basic fetching done

* basic implementation of events view

* improve documentation

* add documentation to helper methods

* add documentation and enforce consistent naming

* update docs

* change event creation to also update description

* sort events properly

* allow pagination

* update styling

* fix date display error

* remove footer from loader

* small fixes

* add search param for easier sharing

* fix query

* change stale time

* handle edge case of no events

* add placeholder for image

* add placehold as image domain

---------

Co-authored-by: zlrkw11 <[email protected]>
  • Loading branch information
choden-dev and zlrkw11 authored Oct 21, 2024
1 parent 969768e commit 30a5a47
Show file tree
Hide file tree
Showing 21 changed files with 956 additions and 148 deletions.
6 changes: 5 additions & 1 deletion client/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ const nextConfig = {
// Need this to allow static site generation to work with firebase hosting
trailingSlash: generateStatic,
images: {
remotePatterns: [{ protocol: "https", hostname: "cdn.sanity.io" }],
remotePatterns: [
{ protocol: "https", hostname: "cdn.sanity.io" },
{ protocol: "https", hostname: "firebasestorage.googleapis.com" },
{ protocol: "https", hostname: "placehold.co" }
],
// TODO: remove this and use an image CDN
unoptimized: generateStatic
}
Expand Down
26 changes: 26 additions & 0 deletions client/src/app/events/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"use client"

import { Footer } from "@/components/generic/Footer/Footer"
import queryClient from "@/services/QueryClient"
import { QueryClientProvider } from "@tanstack/react-query"
import { ReactNode } from "react"

type IBookingLayout = Readonly<{ children: ReactNode }>

const EventsPageLayout = ({ children }: IBookingLayout) => {
return (
<div
className="bg-mountain-background-image relative z-10 flex min-h-screen
w-full flex-col items-center gap-8 bg-cover bg-top bg-no-repeat"
>
<div className="bg-gray-1 pointer-events-none absolute -z-30 h-full w-full opacity-70" />
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>

<span className="mt-auto w-full">
<Footer />
</span>
</div>
)
}

export default EventsPageLayout
76 changes: 65 additions & 11 deletions client/src/app/events/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,70 @@
import WorkInProgressComponent from "@/components/generic/WorkInProgressComponent/WorkInProgressComponent"
import Link from "next/link"
"use client"

import EventsPage from "@/components/composite/EventsView/EventsView"
import { useLatestEventsQuery } from "@/services/Event/EventQueries"
import { useRouter, useSearchParams } from "next/navigation"
import { useEffect, useMemo, useState } from "react"

const EVENT_QUERY_KEY = "id" as const

const Events = () => {
/**
* We need a way to set the param, in case a user pastes in a link
* shared by someone else. This would ideally be a dynamic route,
* however as we are using static export this is the best workaround
*/
const params = useSearchParams()
const router = useRouter()
const [preselectedEventId, setPreselectedEventId] = useState<
string | undefined
>(params.get(EVENT_QUERY_KEY) || undefined)

/**
* Set the search params (i.e `/events?id={id}`) to the required value
*/
useEffect(() => {
const url = new URL(window.location.href)

if (!preselectedEventId) {
url.searchParams.delete(EVENT_QUERY_KEY)
} else {
url.searchParams.set(EVENT_QUERY_KEY, preselectedEventId)
}

router.push(url.toString())
}, [preselectedEventId, router])

const {
data,
isPending,
hasNextPage,
isFetching,
fetchNextPage,
isFetchingNextPage
} = useLatestEventsQuery()
const rawEvents = useMemo(() => {
const flattenedEvents = data?.pages.flatMap((page) => {
return page.data || []
})
return flattenedEvents
}, [data])

return (
<div className="fixed flex h-screen w-full flex-col items-center justify-center gap-4">
<WorkInProgressComponent pageName="Events" />
<Link
href="https://www.facebook.com/UoAsnowsports"
className="text-light-blue-100 hover:underline"
>
Go to our Facebook to sign up for the events!
</Link>
</div>
<>
<h2 className="text-dark-blue-100 mt-8 italic">Events</h2>
<EventsPage
onSelectedEventIdChange={setPreselectedEventId}
preselectedEventId={preselectedEventId}
rawEvents={rawEvents || []}
hasMoreEvents={hasNextPage}
isLoading={isPending}
fetchMoreEvents={() => {
if (!isFetchingNextPage && !isFetching) {
fetchNextPage()
}
}}
/>
</>
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const AdminEventForm = ({
google_forms_link: data.get(
AdminEventFormKeys.GOOGLE_FORMS_LINK
) as string,
description: data.get(AdminEventFormKeys.DESCRIPTION) as string,
sign_up_end_date: sign_up_end_date
? Timestamp.fromDate(new Date(sign_up_end_date as string))
: undefined,
Expand Down
58 changes: 58 additions & 0 deletions client/src/components/composite/EventsView/EventsView.story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import type { Meta, StoryObj } from "@storybook/react"
import EventsPage from "./EventsView"
import { Timestamp } from "firebase/firestore"

const meta: Meta<typeof EventsPage> = {
component: EventsPage
}
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"]
}
Loading

0 comments on commit 30a5a47

Please sign in to comment.