Skip to content
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

Closed
wants to merge 8 commits into from
Closed
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
47 changes: 47 additions & 0 deletions src/app/student/_components/EventItem.tsx
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>
)
}
20 changes: 20 additions & 0 deletions src/app/student/_components/EventsTimeLine.tsx
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>
)
}
19 changes: 19 additions & 0 deletions src/app/student/events/page.tsx
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"

Copy link
Member

@hampfh hampfh May 3, 2024

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 i

Update: Nvm this is not necessary for /events, only necessary for /events/:id which Valdemar is working on

export default async function StudentEventPage() {
const events = await fetchEvents()

return (
<Page.Background withIndents>
<Page.Boundary>
<Page.Header>Events</Page.Header>
<Suspense>
Copy link
Member

Choose a reason for hiding this comment

The 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>
)
}
4 changes: 2 additions & 2 deletions src/components/shared/NavigationMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ const studentLinks: { title: string; href: string; description: string }[] = [
href: "/student/exhibitors",
description: `Get an in depth look at the companies attending the fair`
},
/* {
{
title: "Events",
href: "/student/events",
description: "See the events leading up to the fair"
}, */
},
{
title: "Recruitment",
href: "/student/recruitment",
Expand Down
47 changes: 47 additions & 0 deletions src/components/shared/hooks/api/useEvents.tsx
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) {
Copy link
Member

Choose a reason for hiding this comment

The 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)
})
}
Loading