Skip to content

Commit ba07e22

Browse files
committed
Future events
1 parent 1b6ad3c commit ba07e22

File tree

4 files changed

+142
-9
lines changed

4 files changed

+142
-9
lines changed

futureEvents.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[
2+
{"id": 1, "date": "11/05/25", "location": "Marina di Campo, Italy", "name": "Maratona dell'Isola d'Elba", "link": "https://www.maratonadellisoladelba.it/"},
3+
{"id": 2, "date": "31/05/25", "location": "Stockholm, Sweden", "name": "adidas Stockholm Marathon", "link": "https://www.stockholmmarathon.se/eng/"},
4+
{"id": 3, "date": "05/07/25", "location": "Zermatt, Switzerland", "name": "Zermatt Marathon", "link": "https://www.zermattmarathon.ch/en/index.html"},
5+
{"id": 4, "date": "15/08/25", "location": "Turku, Finland", "name": "Paavo Nurmi Marathon", "link": "https://paavonurmimarathon.fi/en/info"},
6+
{"id": 6, "date": "27/09/25", "location": "Verbania, Italy", "name": "Ultra Trail Lake Maggiore", "link": "https://utlm.it/en/"},
7+
{"id": 5, "date": "06/09/25", "location": "Interlaken, Switzerland", "name": "Jungfrau-Marathon", "link": "https://www.jungfrau-marathon.ch/en/marathon.html"},
8+
{"id": 7, "date": "26/10/25", "location": "Venice, Italy", "name": "Wizz Air Venicemarathon", "link": "https://www.venicemarathon.it/en"},
9+
{"id": 8, "date": "09/11/25", "location": "Nice, France", "name": "French Riviera Marathon Nice-Cannes", "link": "https://www.marathon06.com/2025/AN/"},
10+
{"id": 9, "date": "30/11/25", "location": "Firenze, Italy", "name": "Florence Marathon", "link": "https://www.firenzemarathon.it/en/marathon/"},
11+
{"id": 11, "date": "14/12/25", "location": "Málaga, Spain", "name": "GENERALI Málaga Marathon", "link": "https://www.generalimaratonmalaga.com/marathon-malaga-en/"},
12+
{"id": 12, "date": "May", "location": "Genève, Switzerland", "name": "Generali Geneva Marathon", "link": "https://www.generaligenevemarathon.com/en"},
13+
{"id": 13, "date": "May", "location": "Centra rajons, Latvia", "name": "Rimi Riga Marathon", "link": "https://rimirigamarathon.com/en/"},
14+
{"id": 14, "date": "June", "location": "Barruera, Spain", "name": "GARMIN Mountain Festival - Vall de Boi", "link": "https://garminmountainfestival.com/en/races-garmin-epic-trail/garmin-epic-trail-maraton-42k/"},
15+
{"id": 15, "date": "August", "location": "Mojstrana, Slovenia", "name": "Triglav Trail Run", "link": "https://www.triglavtrailrun.com/"},
16+
{"id": 10, "date": "September", "location": "Valais, Switzerland", "name": "SwissPeaks Marathon", "link": "https://swisspeaks.ch/marathon/?lang=en"},
17+
{"id": 16, "date": "September", "location": "Chișinău, Moldova", "name": "Chisinau International Marathon", "link": "https://marathon.md/en/"}
18+
]

src/components/futureEvents.tsx

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { useEffect, useState } from "react";
2+
import {
3+
Dialog,
4+
DialogTitle,
5+
DialogContent,
6+
DialogActions,
7+
Button,
8+
Table,
9+
Box,
10+
TableHead,
11+
TableRow,
12+
TableCell,
13+
TableBody,
14+
Link,
15+
} from "@mui/material";
16+
import { FutureEvents } from "../types/futureEvents";
17+
import rawFutureEvents from "../../futureEvents.json";
18+
19+
interface Props {
20+
open: boolean;
21+
onClose: () => void;
22+
}
23+
24+
const FutureEventsDialog = ({ open, onClose }: Props) => {
25+
const [futureEvents, setFutureEvents] = useState<FutureEvents[]>([]);
26+
27+
useEffect(() => {
28+
setFutureEvents(rawFutureEvents);
29+
}, []);
30+
31+
return (
32+
<Dialog
33+
open={open}
34+
onClose={onClose}
35+
slotProps={{
36+
paper: {
37+
sx: {
38+
width: "90vw",
39+
height: "90vh",
40+
maxWidth: "1500px",
41+
maxHeight: "90vh",
42+
},
43+
},
44+
}}
45+
>
46+
<DialogTitle
47+
sx={{
48+
fontSize: "2.2rem",
49+
fontWeight: "bold",
50+
textAlign: "center",
51+
}}
52+
>
53+
Future Events
54+
</DialogTitle>
55+
<DialogContent sx={{ p: 2 }}>
56+
<Box sx={{ width: "100%", overflowX: "auto" }}>
57+
<Table>
58+
<TableHead>
59+
<TableRow>
60+
<TableCell>
61+
<strong>Date</strong>
62+
</TableCell>
63+
<TableCell>
64+
<strong>Location</strong>
65+
</TableCell>
66+
<TableCell>
67+
<strong>Name</strong>
68+
</TableCell>
69+
<TableCell>
70+
<strong>Link</strong>
71+
</TableCell>
72+
</TableRow>
73+
</TableHead>
74+
<TableBody>
75+
{futureEvents.map((event) => (
76+
<TableRow key={event.id}>
77+
<TableCell>{event.date}</TableCell>
78+
<TableCell>{event.location}</TableCell>
79+
<TableCell>{event.name}</TableCell>
80+
<TableCell>
81+
<Link href={event.link} target="_blank" rel="noopener">
82+
Website
83+
</Link>
84+
</TableCell>
85+
</TableRow>
86+
))}
87+
</TableBody>
88+
</Table>
89+
</Box>
90+
</DialogContent>
91+
<DialogActions sx={{ justifyContent: "center", p: 2 }}>
92+
<Button onClick={onClose} variant="outlined">
93+
Close
94+
</Button>
95+
</DialogActions>
96+
</Dialog>
97+
);
98+
};
99+
100+
export default FutureEventsDialog;

src/components/leftSidebar.tsx

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import { Box, IconButton } from "@mui/material";
22
import SettingsIcon from "@mui/icons-material/Settings";
33
import LeaderboardIcon from "@mui/icons-material/Leaderboard";
44
import EmojiEventsIcon from "@mui/icons-material/EmojiEvents";
5+
import EventIcon from "@mui/icons-material/Event";
56
import ZoomOutMapIcon from "@mui/icons-material/ZoomOutMap";
67
import { RefObject, useEffect, useState } from "react";
78
import SummaryDialog from "./summary";
89
import ChallengeDialog from "./challenge";
910
import SettingsDialog from "./settings";
1011
import { TileLayerOption } from "../types/tiles";
1112
import { Event } from "../types/event";
13+
import FutureEventsDialog from "./futureEvents";
1214

1315
interface Props {
1416
filteredEvents: Event[];
@@ -28,6 +30,7 @@ const LeftSidebar = ({
2830
const [openSummary, setOpenSummary] = useState(false);
2931
const [openSettings, setOpenSettings] = useState(false);
3032
const [openChallenges, setOpenChallenges] = useState(false);
33+
const [openEvents, setOpenEvents] = useState(false);
3134

3235
useEffect(() => {
3336
const handleKeyDown = (event: KeyboardEvent) => {
@@ -55,18 +58,12 @@ const LeftSidebar = ({
5558

5659
return (
5760
<Box className="left-sidebar" sx={{ pt: 3 }}>
58-
<IconButton
59-
color="inherit"
60-
size="small"
61-
title="Reset View"
62-
onClick={handleResetView}
63-
>
61+
<IconButton color="inherit" title="Reset View" onClick={handleResetView}>
6462
<ZoomOutMapIcon fontSize="large" />
6563
</IconButton>
6664

6765
<IconButton
6866
color="inherit"
69-
size="small"
7067
title="Summary (s)"
7168
onClick={() => setOpenSummary(true)}
7269
>
@@ -75,7 +72,6 @@ const LeftSidebar = ({
7572

7673
<IconButton
7774
color="inherit"
78-
size="small"
7975
title="Challenges"
8076
onClick={() => setOpenChallenges(true)}
8177
>
@@ -84,7 +80,14 @@ const LeftSidebar = ({
8480

8581
<IconButton
8682
color="inherit"
87-
size="small"
83+
title="Future Events"
84+
onClick={() => setOpenEvents(true)}
85+
>
86+
<EventIcon fontSize="large" />
87+
</IconButton>
88+
89+
<IconButton
90+
color="inherit"
8891
title="Settings"
8992
onClick={() => setOpenSettings(true)}
9093
sx={{
@@ -108,6 +111,11 @@ const LeftSidebar = ({
108111
onClose={() => setOpenChallenges(false)}
109112
/>
110113

114+
<FutureEventsDialog
115+
open={openEvents}
116+
onClose={() => setOpenEvents(false)}
117+
/>
118+
111119
<SettingsDialog
112120
open={openSettings}
113121
selectedTile={selectedTile}

src/types/futureEvents.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface FutureEvents {
2+
id: number;
3+
date: string;
4+
location: string;
5+
name: string;
6+
link: string;
7+
}

0 commit comments

Comments
 (0)