-
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
feat: Add events page #66
Open
ZeroWave022
wants to merge
48
commits into
dev
Choose a base branch
from
events
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 38 commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
7fe9d78
feat: Update Avatar component
ZeroWave022 71ecab2
feat: Add events page
ZeroWave022 f596d8c
feat: Update Avatar component
ZeroWave022 354c13e
feat: Add events page
ZeroWave022 a4623d9
Merge branch 'events' of https://github.com/hackerspace-ntnu/website-…
ZeroWave022 e0d572d
perf: Convert jpg to webp
ZeroWave022 8f40388
feat: Make EventCards into links
ZeroWave022 b55d8e0
refactor: Simpler keys for mock data
ZeroWave022 af75395
feat: Add page for each event
ZeroWave022 84acf43
refactor: Move event details back button to layout
ZeroWave022 b2fa718
feat: Add loading to events page
ZeroWave022 d3cc9a7
fix: Add ARIA label to button
ZeroWave022 0ea7d99
chore: Add page to lighthouse CI
ZeroWave022 f57378e
fix: ARIA label for event cards
ZeroWave022 53772c0
fix: Make event cards grid responsive
ZeroWave022 fc6d96a
Merge branch 'dev' into events
ZeroWave022 e19585e
fix: Use event.id as key instead of useId
ZeroWave022 8d29c29
feat: Add loading page to event details page
ZeroWave022 1ff7d79
feat: Translate event pages
ZeroWave022 6bd2d07
feat: Mark internal events with badge
ZeroWave022 df46e61
Merge branch 'dev' into events
ZeroWave022 e40dffc
refactor: Linting
ZeroWave022 5fbca9c
fix: Ignore label content name mismatch warning
ZeroWave022 1f6f993
refactor: lint
ZeroWave022 cf9c8de
fix: Event card skeletons on mobile show correctly
ZeroWave022 9b6367c
fix: Correct grid cols on events loading
ZeroWave022 338fae4
fix: Use 24-hour clock on event cards, add alt to image
ZeroWave022 7243def
fix: Clean up css for event card skeletons, fix regressions on mobile
ZeroWave022 fb4f949
refactor: Use absolute path for component imports
ZeroWave022 00861fd
fix: Translate events loading
ZeroWave022 54cf2b6
refactor: Use more sensible order of components in events layout
ZeroWave022 52b9084
fix: Translate internal badge
ZeroWave022 c3ccccb
Merge branch 'dev' into events
ZeroWave022 024069b
refactor: Use date-fns for dates
ZeroWave022 7f1e439
fix: Change h3 to h2
ZeroWave022 eab2829
refactor: Add event prop to EventCard
ZeroWave022 4ba5ca7
fix: Correct routing of event page
ZeroWave022 d47dc56
fix: Add translation to image alt
ZeroWave022 0c64648
refactor: Use p instead of span for event card time info
ZeroWave022 0630307
refactor: lint
ZeroWave022 b035055
fix: event card skeleton on smaller screens
ZeroWave022 a528ed5
refactor: Make event cards a client component, fix rings
ZeroWave022 4fe8c16
feat: Add hover effect to event cards
ZeroWave022 05ddfbd
feat: Starts/ends event card text in bold
ZeroWave022 dda95b6
feat: Event headings are clickable
ZeroWave022 0a46cc2
fix: Skeleton for small screens on single event page
ZeroWave022 1242f0e
fix: Adjust height of event card skeletons
ZeroWave022 5cd0bc3
fix: Adjust margins on events page
ZeroWave022 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { Button } from '@/components/ui/Button'; | ||
import { Link } from '@/lib/locale/navigation'; | ||
import { ArrowLeftIcon } from 'lucide-react'; | ||
import { getTranslations } from 'next-intl/server'; | ||
|
||
export default async function EventDetailsLayout({ | ||
children, | ||
}: { children: React.ReactNode }) { | ||
const t = await getTranslations('events'); | ||
return ( | ||
<> | ||
<Button variant='secondary' aria-label='Back to Events' asChild> | ||
<Link href='/events' className='flex gap-2'> | ||
<ArrowLeftIcon aria-hidden='true' /> | ||
{t('backToEvents')} | ||
</Link> | ||
</Button> | ||
{children} | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,27 @@ | ||||||
import { Separator } from '@/components/ui/Separator'; | ||||||
import { Skeleton } from '@/components/ui/Skeleton'; | ||||||
import { CalendarIcon, MapPinIcon } from 'lucide-react'; | ||||||
|
||||||
export default function EventDetailsLoading() { | ||||||
return ( | ||||||
<> | ||||||
<Skeleton className='my-4 h-12 w-3/4 rounded-lg' /> | ||||||
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.
Suggested change
To keep same layout as in the actual page |
||||||
<Skeleton className='h-8 w-1/2 rounded-lg' /> | ||||||
<div className='mt-4 space-y-4'> | ||||||
<div className='flex items-center gap-2'> | ||||||
<CalendarIcon className='h-8 w-8' /> | ||||||
<Skeleton className='h-6 w-64 rounded-lg' /> | ||||||
</div> | ||||||
<div className='flex items-center gap-2'> | ||||||
<MapPinIcon className='h-8 w-8' /> | ||||||
<Skeleton className='h-6 w-32 rounded-lg' /> | ||||||
</div> | ||||||
<Separator /> | ||||||
<div className='flex justify-between'> | ||||||
<Skeleton className='h-36 w-3/5 rounded-lg' /> | ||||||
<Skeleton className='h-48 w-48 rounded-full' /> | ||||||
</div> | ||||||
</div> | ||||||
</> | ||||||
); | ||||||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { getTranslations, setRequestLocale } from 'next-intl/server'; | ||
import { CalendarIcon, MapPinIcon } from 'lucide-react'; | ||
import { notFound } from 'next/navigation'; | ||
import { format, isSameDay } from 'date-fns'; | ||
|
||
import { Avatar, AvatarImage } from '@/components/ui/Avatar'; | ||
import { Badge } from '@/components/ui/Badge'; | ||
import { Separator } from '@/components/ui/Separator'; | ||
// TODO: Must be replaced with actual events | ||
import { events } from '@/mock-data/events'; | ||
|
||
export async function generateMetadata({ | ||
ZeroWave022 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
params, | ||
}: { | ||
params: Promise<{ locale: string; id: string }>; | ||
}) { | ||
const { id } = await params; | ||
const event = events.find((event) => event.id.toString() === id); | ||
|
||
return { | ||
title: `${event?.title}`, | ||
}; | ||
} | ||
|
||
export default async function EventDetailsPage({ | ||
params, | ||
}: { | ||
params: Promise<{ locale: string; id: string }>; | ||
}) { | ||
const { locale, id } = await params; | ||
setRequestLocale(locale); | ||
|
||
const t = await getTranslations('ui'); | ||
const event = events.find((event) => event.id.toString() === id); | ||
|
||
if (!event) return notFound(); | ||
|
||
const startDate = new Date(event.startTime); | ||
const endDate = new Date(event.endTime); | ||
|
||
const formattedRange = isSameDay(startDate, endDate) | ||
? `${format(startDate, 'HH:mm')} - ${format(endDate, 'HH:mm, dd.MM.yyyy')}` | ||
: `${format(startDate, 'HH:mm, dd/MM/yyyy')} - ${format(endDate, 'HH:mm, dd.MM.yyyy')}`; | ||
|
||
return ( | ||
<> | ||
<h1 className='my-4'>{event.title}</h1> | ||
<h2 className='border-b-0 text-2xl'>{event.subheader}</h2> | ||
<div className='mt-4 space-y-4'> | ||
{event.internal && ( | ||
<Badge className='rounded-full'>{t('internal')}</Badge> | ||
)} | ||
<div className='flex items-center gap-2'> | ||
<CalendarIcon className='h-8 w-8' /> | ||
{formattedRange} | ||
</div> | ||
<div className='flex items-center gap-2'> | ||
<MapPinIcon className='h-8 w-8' /> | ||
{event.location} | ||
</div> | ||
<Separator /> | ||
<div className='flex justify-between'> | ||
<div className='max-w-prose'> | ||
<p>{event.description}</p> | ||
</div> | ||
<Avatar className='h-48 w-48'> | ||
<AvatarImage src='/event.webp' alt='' className='object-cover' /> | ||
ZeroWave022 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
</Avatar> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,27 @@ | ||||||
import { EventCardSkeleton } from '@/components/events/EventCardSkeleton'; | ||||||
import { getTranslations } from 'next-intl/server'; | ||||||
|
||||||
export default async function EventsSkeleton() { | ||||||
const t = await getTranslations('events'); | ||||||
return ( | ||||||
<> | ||||||
<h1 className='my-4'>{t('title')}</h1> | ||||||
<h2 className='my-2'>{t('activeEvents')}</h2> | ||||||
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.
Suggested change
Consistent styling with other h2 elements |
||||||
<EventCardSkeleton /> | ||||||
<h2 className='my-4'>{t('upcomingEvents')}</h2> | ||||||
<div className='grid grid-cols-1 gap-2 lg:grid-cols-2'> | ||||||
<EventCardSkeleton /> | ||||||
<EventCardSkeleton /> | ||||||
<EventCardSkeleton /> | ||||||
<EventCardSkeleton /> | ||||||
</div> | ||||||
<h2 className='my-4'>{t('pastEvents')}</h2> | ||||||
<div className='grid grid-cols-1 gap-2 lg:grid-cols-2'> | ||||||
<EventCardSkeleton /> | ||||||
<EventCardSkeleton /> | ||||||
<EventCardSkeleton /> | ||||||
<EventCardSkeleton /> | ||||||
</div> | ||||||
</> | ||||||
); | ||||||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { | ||
Card, | ||
CardContent, | ||
CardDescription, | ||
CardFooter, | ||
CardHeader, | ||
CardTitle, | ||
} from '@/components/ui/Card'; | ||
|
||
import { Avatar, AvatarImage } from '@/components/ui/Avatar'; | ||
import { Badge } from '@/components/ui/Badge'; | ||
import { Link } from '@/lib/locale/navigation'; | ||
import { cx } from '@/lib/utils'; | ||
import type { events } from '@/mock-data/events'; | ||
import { format } from 'date-fns'; | ||
import { getTranslations } from 'next-intl/server'; | ||
|
||
type EventCardProps = { | ||
event: (typeof events)[number]; | ||
wrapperClassName?: string; | ||
cardClassName?: string; | ||
_active?: boolean; | ||
}; | ||
|
||
/** | ||
* A card for an event. | ||
* Only set the _active prop to true if you're testing active events. | ||
*/ | ||
async function EventCard({ | ||
event, | ||
wrapperClassName, | ||
cardClassName, | ||
_active, | ||
}: EventCardProps) { | ||
const t = await getTranslations('events'); | ||
const tUi = await getTranslations('ui'); | ||
|
||
const formattedStartDate = format(event.startTime, 'HH:mm, dd.MM.yyyy'); | ||
const formattedEndDate = format(event.endTime, 'HH:mm, dd.MM.yyyy'); | ||
|
||
const started = event.startTime < new Date() || _active; | ||
const ended = event.endTime < new Date(); | ||
|
||
return ( | ||
<Link | ||
href={{ pathname: '/events/[id]', params: { id: event.id } }} | ||
aria-label={t('detailsAboutEvent', { eventName: event.title })} | ||
className={wrapperClassName} | ||
> | ||
<Card | ||
className={cx('flex flex-col text-center', cardClassName, { | ||
'bg-secondary': started && !ended, | ||
})} | ||
> | ||
<CardHeader> | ||
<CardTitle>{event.title}</CardTitle> | ||
<CardDescription>{event.subheader}</CardDescription> | ||
{event.internal && ( | ||
<Badge className='mx-auto w-fit rounded-full'> | ||
{tUi('internal')} | ||
</Badge> | ||
)} | ||
</CardHeader> | ||
<CardContent className='flex flex-col-reverse items-center gap-2 md:flex-row md:justify-between'> | ||
<p>{event.description}</p> | ||
<Avatar className='h-48 w-48'> | ||
<AvatarImage | ||
src='/event.webp' | ||
alt={tUi('photoOf', { name: event.title })} | ||
className='object-cover' | ||
/> | ||
</Avatar> | ||
</CardContent> | ||
<CardFooter className='mt-auto flex-col gap-2'> | ||
<span> | ||
ZeroWave022 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{started ? <>{t('startedAt')}</> : <>{t('startsAt')}</>}{' '} | ||
{formattedStartDate} | ||
</span> | ||
<span> | ||
{ended ? <>{t('endedAt')}</> : <>{t('endsAt')}</>}{' '} | ||
{formattedEndDate} | ||
</span> | ||
</CardFooter> | ||
</Card> | ||
</Link> | ||
); | ||
} | ||
|
||
export { EventCard }; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Aria-label isn't translated