Skip to content

Commit 06b0f60

Browse files
feat: events page (#70)
1 parent d6ec37d commit 06b0f60

File tree

31 files changed

+971
-58
lines changed

31 files changed

+971
-58
lines changed

bun.lockb

7.6 KB
Binary file not shown.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414
"@formatjs/intl-localematcher": "^0.5.7",
1515
"@headlessui/react": "^2.2.0",
1616
"@types/negotiator": "^0.6.3",
17+
"axios": "^1.7.9",
1718
"markdown-to-jsx": "^7.7.4",
1819
"motion": "^11.11.15",
1920
"negotiator": "^1.0.0",
2021
"next": "14.2.16",
2122
"react": "^18",
2223
"react-dom": "^18",
2324
"react-intersection-observer": "^9.13.1",
25+
"react-swipeable": "^7.0.2",
2426
"swiper": "^11.2.1"
2527
},
2628
"devDependencies": {

src/app/[lang]/about/become-a-collaborator/layout.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import {
22
getDictionary,
33
type Locale,
44
} from "@/internationalization/dictionaries";
5+
import { fullLocale } from "@/lib/locale";
56
import { type Metadata } from "next";
67

78
export function generateMetadata({
89
params: { lang },
910
}: {
1011
params: { lang: Locale };
1112
}): Metadata {
12-
const dict = getDictionary(lang);
13+
const dict = getDictionary(fullLocale(lang));
1314

1415
return {
1516
title: dict.seo.become_a_collaborator.title,
@@ -42,8 +43,8 @@ export function generateMetadata({
4243
alternates: {
4344
canonical: "https://cesium.di.uminho.pt/about/become-a-collaborator",
4445
languages: {
45-
en: "https://cesium.di.uminho.pt/en_US/about/become-a-collaborator",
46-
pt: "https://cesium.di.uminho.pt/pt_PT/about/team",
46+
en: "https://cesium.di.uminho.pt/en/about/become-a-collaborator",
47+
pt: "https://cesium.di.uminho.pt/pt/about/team",
4748
},
4849
},
4950
};

src/app/[lang]/about/become-a-member/layout.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import {
22
getDictionary,
33
type Locale,
44
} from "@/internationalization/dictionaries";
5+
import { fullLocale } from "@/lib/locale";
56
import { type Metadata } from "next";
67

78
export function generateMetadata({
89
params: { lang },
910
}: {
1011
params: { lang: Locale };
1112
}): Metadata {
12-
const dict = getDictionary(lang);
13+
const dict = getDictionary(fullLocale(lang));
1314

1415
return {
1516
title: dict.seo.become_a_member.title,
@@ -42,8 +43,8 @@ export function generateMetadata({
4243
alternates: {
4344
canonical: "https://cesium.di.uminho.pt/about/become-a-member",
4445
languages: {
45-
en: "https://cesium.di.uminho.pt/en_US/about/become-a-member",
46-
pt: "https://cesium.di.uminho.pt/pt_PT/about/become-a-member",
46+
en: "https://cesium.di.uminho.pt/en/about/become-a-member",
47+
pt: "https://cesium.di.uminho.pt/pt/about/become-a-member",
4748
},
4849
},
4950
};

src/app/[lang]/about/departments/layout.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import {
22
getDictionary,
33
type Locale,
44
} from "@/internationalization/dictionaries";
5+
import { fullLocale } from "@/lib/locale";
56
import { type Metadata } from "next";
67

78
export function generateMetadata({
89
params: { lang },
910
}: {
1011
params: { lang: Locale };
1112
}): Metadata {
12-
const dict = getDictionary(lang);
13+
const dict = getDictionary(fullLocale(lang));
1314

1415
return {
1516
title: dict.seo.departments.title,
@@ -42,8 +43,8 @@ export function generateMetadata({
4243
alternates: {
4344
canonical: "https://cesium.di.uminho.pt/about/departments",
4445
languages: {
45-
en: "https://cesium.di.uminho.pt/en_US/about/departments",
46-
pt: "https://cesium.di.uminho.pt/pt_PT/about/departments",
46+
en: "https://cesium.di.uminho.pt/en/about/departments",
47+
pt: "https://cesium.di.uminho.pt/pt/about/departments",
4748
},
4849
},
4950
};

src/app/[lang]/about/layout.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import {
22
getDictionary,
33
type Locale,
44
} from "@/internationalization/dictionaries";
5+
import { fullLocale } from "@/lib/locale";
56
import { type Metadata } from "next";
67

78
export function generateMetadata({
89
params: { lang },
910
}: {
1011
params: { lang: Locale };
1112
}): Metadata {
12-
const dict = getDictionary(lang);
13+
const dict = getDictionary(fullLocale(lang));
1314

1415
return {
1516
title: dict.seo.about.title,
@@ -42,8 +43,8 @@ export function generateMetadata({
4243
alternates: {
4344
canonical: "https://cesium.di.uminho.pt/about",
4445
languages: {
45-
en: "https://cesium.di.uminho.pt/en_US/about",
46-
pt: "https://cesium.di.uminho.pt/pt_PT/about",
46+
en: "https://cesium.di.uminho.pt/en/about",
47+
pt: "https://cesium.di.uminho.pt/pt/about",
4748
},
4849
},
4950
};

src/app/[lang]/about/team/layout.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import {
22
getDictionary,
33
type Locale,
44
} from "@/internationalization/dictionaries";
5+
import { fullLocale } from "@/lib/locale";
56
import { type Metadata } from "next";
67

78
export function generateMetadata({
89
params: { lang },
910
}: {
1011
params: { lang: Locale };
1112
}): Metadata {
12-
const dict = getDictionary(lang);
13+
const dict = getDictionary(fullLocale(lang));
1314

1415
return {
1516
title: dict.seo.team.title,
@@ -42,8 +43,8 @@ export function generateMetadata({
4243
alternates: {
4344
canonical: "https://cesium.di.uminho.pt/about/team",
4445
languages: {
45-
en: "https://cesium.di.uminho.pt/en_US/about/team",
46-
pt: "https://cesium.di.uminho.pt/pt_PT/about/team",
46+
en: "https://cesium.di.uminho.pt/en/about/team",
47+
pt: "https://cesium.di.uminho.pt/pt/about/team",
4748
},
4849
},
4950
};

src/app/[lang]/events/layout.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import {
22
getDictionary,
33
type Locale,
44
} from "@/internationalization/dictionaries";
5+
import { fullLocale } from "@/lib/locale";
56
import { type Metadata } from "next";
67

78
export function generateMetadata({
89
params: { lang },
910
}: {
1011
params: { lang: Locale };
1112
}): Metadata {
12-
const dict = getDictionary(lang);
13+
const dict = getDictionary(fullLocale(lang));
1314

1415
return {
1516
title: dict.seo.events.title,
@@ -42,8 +43,8 @@ export function generateMetadata({
4243
alternates: {
4344
canonical: "https://cesium.di.uminho.pt/events",
4445
languages: {
45-
en: "https://cesium.di.uminho.pt/en_US/events",
46-
pt: "https://cesium.di.uminho.pt/pt_PT/events",
46+
en: "https://cesium.di.uminho.pt/en/events",
47+
pt: "https://cesium.di.uminho.pt/pt/events",
4748
},
4849
},
4950
};

src/app/[lang]/events/page.tsx

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,115 @@
1-
export default function Events() {
2-
return <main>Events</main>;
3-
}
1+
"use client";
2+
3+
import { Calendar } from "@/components/calendar";
4+
import { EventList } from "@/components/event-list";
5+
import PromotionalCard from "@/components/promotional-card";
6+
import { useDictionary } from "@/contexts/dictionary-provider";
7+
import getEvents from "@/lib/api/getEvents";
8+
import { type Event, CardType } from "@/lib/types";
9+
import { useEffect, useState } from "react";
10+
import { isSameDay } from "@/lib/utils";
11+
import { horizontalPadding, verticalPadding } from "@/lib/styling";
12+
import AppLink from "@/components/link";
13+
import Markdown from "markdown-to-jsx";
14+
15+
export default function EventsPage() {
16+
const dict = useDictionary();
17+
const [events, setEvents] = useState<Event[]>([]);
18+
const [isLoading, setIsLoading] = useState(true);
19+
const [selectedDate, setSelectedDate] = useState<Date | null>(null);
20+
21+
useEffect(() => {
22+
async function fetchEvents() {
23+
try {
24+
setIsLoading(true);
25+
const eventsData = await getEvents();
26+
setEvents(eventsData);
27+
} catch (error) {
28+
console.error("Failed to fetch events:", error);
29+
} finally {
30+
setIsLoading(false);
31+
}
32+
}
33+
34+
void fetchEvents();
35+
}, []);
36+
37+
const handleDateSelect = (date: Date | null) => {
38+
setSelectedDate((prevDate) =>
39+
prevDate && date && isSameDay(prevDate, date) ? null : date,
40+
);
41+
};
42+
43+
const handleClearDate = () => {
44+
setSelectedDate(null);
45+
};
46+
47+
return (
48+
<main
49+
className={`flex flex-col gap-10 lg:gap-14 ${horizontalPadding} ${verticalPadding}`}
50+
>
51+
<div className="flex items-center justify-between">
52+
<h1 className="font-title text-3xl font-medium">{dict.events.title}</h1>
53+
<div className="hidden items-center gap-4 lg:flex">
54+
<AppLink
55+
href="https://calendario.cesium.di.uminho.pt/"
56+
arrow="outward"
57+
title="Calendarium"
58+
/>
59+
<AppLink
60+
href="https://instagram.com/cesiuminho"
61+
arrow="outward"
62+
title="Instagram"
63+
/>
64+
</div>
65+
</div>
66+
67+
<div className="md:flex md:gap-12">
68+
<div className="mb-8 flex w-full flex-col gap-14 md:mb-0 md:w-2/5">
69+
<Calendar
70+
events={events}
71+
onDateSelect={handleDateSelect}
72+
selectedDate={selectedDate}
73+
className="your-calendar-class"
74+
/>
75+
<div className="hidden md:block">
76+
<PromotionalCard mobileOnlyLayout type={CardType.Membership} />
77+
</div>
78+
</div>
79+
<div className="flex flex-1 flex-col gap-6">
80+
<EventList
81+
events={events}
82+
isLoading={isLoading}
83+
selectedDate={selectedDate}
84+
onClearDate={handleClearDate}
85+
/>
86+
<div className="text-sm">
87+
<h2 className="mb-4 font-title text-2xl font-medium">
88+
{dict.events.warningTitle}
89+
</h2>
90+
<div className="text-black/50">
91+
<Markdown
92+
options={{
93+
overrides: {
94+
a: {
95+
props: {
96+
className: "font-bold text-primary hover:underline",
97+
target: "_blank",
98+
rel: "noopener noreferrer",
99+
},
100+
},
101+
},
102+
}}
103+
>
104+
{dict.events.warning}
105+
</Markdown>
106+
</div>
107+
</div>
108+
<div className="md:hidden">
109+
<PromotionalCard type={CardType.Membership} />
110+
</div>
111+
</div>
112+
</div>
113+
</main>
114+
);
115+
}

src/app/[lang]/layout.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
import { DictionaryProvider } from "@/contexts/dictionary-provider";
99
import Navbar from "@/components/navbar";
1010
import Footer from "@/components/footer";
11+
import { fullLocale } from "@/lib/locale";
1112

1213
const inter = Inter({
1314
subsets: ["latin"],
@@ -25,15 +26,15 @@ export function generateMetadata({
2526
}: {
2627
params: { lang: Locale };
2728
}): Metadata {
28-
const dict = getDictionary(lang);
29+
const dict = getDictionary(fullLocale(lang));
2930

3031
return {
3132
metadataBase: new URL("https://cesium.di.uminho.pt"),
3233
openGraph: {
3334
siteName: dict.seo.title,
3435
type: "website",
35-
locale: "pt_PT",
36-
alternateLocale: "en_US",
36+
locale: "pt",
37+
alternateLocale: "en",
3738
},
3839
robots: {
3940
index: true,
@@ -82,14 +83,14 @@ export default function RootLayout({
8283
params: { lang },
8384
}: Readonly<{ children: React.ReactNode; params: { lang: Locale } }>) {
8485
return (
85-
<html lang={lang}>
86+
<html lang={fullLocale(lang)}>
8687
<head>
8788
<meta name="apple-mobile-web-app-title" content="CeSIUM" />
8889
</head>
8990
<body
9091
className={`${inter.variable} ${orbitron.variable} overflow-x-hidden bg-white font-sans text-black antialiased`}
9192
>
92-
<DictionaryProvider lang={lang}>
93+
<DictionaryProvider lang={fullLocale(lang)}>
9394
<Navbar />
9495
<div className="h-full">{children}</div>
9596
<Footer />

0 commit comments

Comments
 (0)