-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Xi duosi/event overview page #40
Changes from all commits
b14baaa
7ee6e4c
21a0882
640dfc7
1960d5e
e2274f2
c3474f9
db6af1a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { DateTime } from "luxon" | ||
|
||
export function EventItem({ | ||
id, | ||
title, | ||
event_start, | ||
registration_end, | ||
image_url | ||
}: { | ||
id: string | ||
title: string | ||
event_start: number | ||
registration_end: number | ||
image_url?: string | ||
}) { | ||
return ( | ||
<div className="mb-6 ml-6 w-5/6 rounded-lg border-2 border-solid border-emerald-900 bg-gradient-to-br from-emerald-950 to-liqorice-700 hover:brightness-95 md:w-3/5"> | ||
<a | ||
href="#" | ||
className="flex flex-auto flex-col items-center md:h-48 md:max-w-xl md:flex-row"> | ||
<div className="absolute -start-1.5 mt-3.5 h-3 w-3 rounded-full border border-white bg-melon-700"></div> | ||
{image_url && ( | ||
<img | ||
className="h-full w-full rounded-t-lg object-contain md:h-48 md:w-48 md:rounded-l-lg md:rounded-tr-none " | ||
src={image_url} | ||
alt="" | ||
/> | ||
)} | ||
<div className="flex flex-col justify-between md:pl-5"> | ||
<h5 className="mb-4 mt-5 font-bold text-gray-900 dark:text-white md:mb-12 md:text-2xl"> | ||
{title} | ||
</h5> | ||
<p className="mb-1 text-xs text-gray-700 dark:text-gray-400"> | ||
Registration end:{" "} | ||
{DateTime.fromMillis(registration_end * 1000).toFormat( | ||
"yyyy MMM dd" | ||
)} | ||
</p> | ||
<p className="mb-4 text-xs text-gray-700 dark:text-gray-400"> | ||
Event start:{" "} | ||
{DateTime.fromMillis(event_start * 1000).toFormat("yyyy MMM dd")} | ||
</p> | ||
</div> | ||
</a> | ||
</div> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { EventItem } from "@/app/student/_components/EventItem" | ||
import { Event } from "@/components/shared/hooks/api/useEvents" | ||
|
||
export async function EventsTimeline({ events }: { events: Event[] }) { | ||
const renderEvent = events.map(event => ( | ||
<EventItem | ||
key={event.id} | ||
id={event.id.toString()} | ||
title={event.name} | ||
event_start={event.event_start} | ||
registration_end={event.registration_end} | ||
image_url={event.image_url}></EventItem> | ||
)) | ||
|
||
return ( | ||
<div className="relative mt-10 border-s border-melon-700"> | ||
{renderEvent} | ||
</div> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { EventsTimeline } from "@/app/student/_components/EventsTimeLine" | ||
import { Page } from "@/components/shared/Page" | ||
import { fetchEvents } from "@/components/shared/hooks/api/useEvents" | ||
import { Suspense } from "react" | ||
|
||
export default async function StudentEventPage() { | ||
const events = await fetchEvents() | ||
|
||
return ( | ||
<Page.Background withIndents> | ||
<Page.Boundary> | ||
<Page.Header>Events</Page.Header> | ||
<Suspense> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I'm not mistaken suspense won't have any effect here since all the data is passed as props, if there would have been a query within this component suspense would make sense |
||
<EventsTimeline events={events} /> | ||
</Suspense> | ||
</Page.Boundary> | ||
</Page.Background> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { env } from "@/env" | ||
import { useQuery } from "@tanstack/react-query" | ||
|
||
export interface Event { | ||
id: number | ||
name: string | ||
description: string | ||
location: string | ||
food: string | ||
event_start: number | ||
event_end: number | ||
event_start_string: string | ||
registration_end: number | ||
image_url: string | ||
fee: number | ||
registration_required: boolean | ||
external_event_link: string | ||
signup_questions: SignupQuestion[] | ||
signup_link: string | ||
can_create_teams: boolean | ||
can_join_teams: boolean | ||
open_for_signup: boolean | ||
} | ||
|
||
export interface SignupQuestion { | ||
id: number | ||
type: string | ||
question: string | ||
required: boolean | ||
options: string[] | ||
} | ||
|
||
export async function fetchEvents(options?: RequestInit) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
const res = await fetch( | ||
`${env.NEXT_PUBLIC_API_URL}/api/events`, | ||
options ?? {} | ||
) | ||
const result = await res.json() | ||
return result as Event[] | ||
} | ||
|
||
export function useEvents(options?: RequestInit) { | ||
return useQuery({ | ||
queryKey: ["events"], | ||
queryFn: () => fetchEvents(options) | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to make this page statically generated we need to implement generateStaticParams, this will help next to load all the events during build time, I think a good revalidation time here is quite short, maybe rebuild once every hour, to fix the revalidation I think you need to pass the following to the settings iUpdate: Nvm this is not necessary for /events, only necessary for /events/:id which Valdemar is working on