Skip to content

Commit 8b3cd3b

Browse files
Fix error handling disabling almost all of the main page (#92)
* Fixed error handling completely disabling the website if there was any error with events or events did not exist * Response to review - removed redundancy due to previous experimentation
1 parent b2caa1a commit 8b3cd3b

File tree

1 file changed

+86
-82
lines changed

1 file changed

+86
-82
lines changed

src/pages/HomePage.tsx

Lines changed: 86 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,51 @@ import {
2626
CardTitle,
2727
} from "@/components/ui/card";
2828

29+
function eventsSection(isLoading: boolean, error: string | null, events: EventProps[]): React.ReactElement {
30+
const today = new Date();
31+
32+
// Conditional rendering for loading, error, and no events
33+
if (isLoading) {
34+
return <div className="text-center py-20">Loading events...</div>;
35+
}
36+
37+
if (error) {
38+
return <div className="text-center py-20 text-red-500">Error: Could not load events.</div>;
39+
}
40+
41+
if (events.length === 0) {
42+
return <div className="text-center py-20 dark:text-gray-300">No scheduled events found.</div>;
43+
}
44+
45+
return <>
46+
{/* Past Events */}
47+
<div className="space-y-4">
48+
<h3 className="text-xl font-semibold dark:text-white text-gray-900 mb-4 flex items-center">
49+
<Users2 className="w-5 h-5 mr-2 dark:text-blue-400 text-blue-500" />
50+
Vergangene Treffen
51+
</h3>
52+
{events
53+
.filter((event) => event.endTimestamp < today.getTime())
54+
.map((event) => (
55+
<Event key={event.title + event.startTimestamp} {...event} />
56+
))}
57+
</div>
58+
59+
{/* Future Events */}
60+
<div className="space-y-4">
61+
<h3 className="text-xl font-semibold dark:text-white text-gray-900 mb-4 flex items-center">
62+
<CalendarIcon className="w-5 h-5 mr-2 text-blue-400" />
63+
Kommende Events
64+
</h3>
65+
{events
66+
.filter((event) => event.endTimestamp >= today.getTime())
67+
.map((event) => (
68+
<Event key={event.title + event.startTimestamp} {...event} />
69+
))}
70+
</div>
71+
</>
72+
}
73+
2974
export default function HomePage() {
3075
// Define the URL for the JSON data
3176
const eventsUrl = "https://raw.githubusercontent.com/TUM-Dev/Website/refs/heads/event-data/scheduled_events.json";
@@ -235,66 +280,49 @@ export default function HomePage() {
235280
tech: ["To", "Be", "Decided"],
236281
},
237282
];
238-
239-
283+
284+
240285
// Use the useEffect hook to fetch data when the component mounts
241286
useEffect(() => {
242287
const fetchEvents = async () => {
243-
try {
244-
// Fetch the JSON data from the URL
245-
const response = await fetch(eventsUrl);
246-
if (!response.ok) {
247-
throw new Error(`HTTP error! status: ${response.status}`);
248-
}
249-
const data = await response.json();
288+
try {
289+
// Fetch the JSON data from the URL
290+
const response = await fetch(eventsUrl);
291+
if (!response.ok) {
292+
throw new Error(`HTTP error! status: ${response.status}`);
293+
}
294+
const data = await response.json();
250295

251-
// Convert timestamps from string to Date objects
252-
const formattedEvents: EventProps[] = data.map((event: any) => ({
253-
...event,
254-
title: event.name,
255-
description: event.description,
256-
location: event.entity_metadata?.location || "Online", // Use optional chaining for safety
257-
startTimestamp: new Date(event.scheduled_start_time).getTime(),
258-
endTimestamp: new Date(event.scheduled_end_time).getTime(),
259-
// Derive the type based on the name
260-
type: event.name.toLowerCase().includes("coding") ? "coding" :
261-
event.name.toLowerCase().includes("meeting") ? "meeting" :
262-
"event"
263-
}));
296+
// Convert timestamps from string to Date objects
297+
const formattedEvents: EventProps[] = data.map((event: any) => ({
298+
...event,
299+
title: event.name,
300+
description: event.description,
301+
location: event.entity_metadata?.location || "Online", // Use optional chaining for safety
302+
startTimestamp: new Date(event.scheduled_start_time).getTime(),
303+
endTimestamp: new Date(event.scheduled_end_time).getTime(),
304+
// Derive the type based on the name
305+
type: event.name.toLowerCase().includes("coding") ? "coding" :
306+
event.name.toLowerCase().includes("meeting") ? "meeting" :
307+
"event"
308+
}));
264309

265-
// Set the events state with the fetched data, sorted by start time
266-
setEvents(formattedEvents.sort((a, b) => a.startTimestamp - b.startTimestamp));
267-
} catch (e) {
268-
// Set the error state if fetching fails
269-
if (e instanceof Error) {
270-
setError(e.message);
310+
// Set the events state with the fetched data, sorted by start time
311+
setEvents(formattedEvents.sort((a, b) => a.startTimestamp - b.startTimestamp));
312+
} catch (e) {
313+
// Set the error state if fetching fails
314+
if (e instanceof Error) {
315+
setError(e.message);
316+
}
317+
} finally {
318+
// Set loading to false once the request is complete
319+
setIsLoading(false);
271320
}
272-
} finally {
273-
// Set loading to false once the request is complete
274-
setIsLoading(false);
275-
}
276321
};
277322

278323
fetchEvents();
279324
}, []); // The empty array ensures this effect runs only once
280325

281-
const today = new Date();
282-
283-
// Conditional rendering for loading, error, and no events
284-
if (isLoading) {
285-
return <div className="text-center py-20">Loading events...</div>;
286-
}
287-
288-
if (error) {
289-
return <div className="text-center py-20 text-red-500">Error: Could not load events.</div>;
290-
}
291-
292-
if (events.length === 0) {
293-
// You might want to handle this case more gracefully
294-
// For example, by showing a "No upcoming events" message
295-
return <div className="text-center py-20 dark:text-gray-300">No scheduled events found.</div>;
296-
}
297-
298326
return (
299327
<div>
300328
<section className="py-20 px-4">
@@ -415,42 +443,18 @@ export default function HomePage() {
415443
id="events"
416444
>
417445
<div className="container mx-auto max-w-6xl">
418-
<div className="text-center mb-12">
419-
<h2 className="text-3xl font-bold dark:text-white text-gray-900 mb-4">
420-
Termine
421-
</h2>
422-
<p className="dark:text-gray-300 text-gray-600">
423-
Verpasse keine unserer Veranstaltungen und Treffen
424-
</p>
425-
</div>
426-
427-
<div className="grid lg:grid-cols-2 gap-8">
428-
{/* Past Events */}
429-
<div className="space-y-4">
430-
<h3 className="text-xl font-semibold dark:text-white text-gray-900 mb-4 flex items-center">
431-
<Users2 className="w-5 h-5 mr-2 dark:text-blue-400 text-blue-500" />
432-
Vergangene Treffen
433-
</h3>
434-
{events
435-
.filter((event) => event.endTimestamp < today.getTime())
436-
.map((event) => (
437-
<Event key={event.title + event.startTimestamp} {...event} />
438-
))}
446+
<div className="text-center mb-12">
447+
<h2 className="text-3xl font-bold dark:text-white text-gray-900 mb-4">
448+
Termine
449+
</h2>
450+
<p className="dark:text-gray-300 text-gray-600">
451+
Verpasse keine unserer Veranstaltungen und Treffen
452+
</p>
439453
</div>
440454

441-
{/* Future Events */}
442-
<div className="space-y-4">
443-
<h3 className="text-xl font-semibold dark:text-white text-gray-900 mb-4 flex items-center">
444-
<CalendarIcon className="w-5 h-5 mr-2 text-blue-400" />
445-
Kommende Events
446-
</h3>
447-
{events
448-
.filter((event) => event.endTimestamp >= today.getTime())
449-
.map((event) => (
450-
<Event key={event.title + event.startTimestamp} {...event} />
451-
))}
455+
<div className="grid lg:grid-cols-2 gap-8">
456+
{ eventsSection(isLoading, error, events) }
452457
</div>
453-
</div>
454458
</div>
455459
</section>
456460

0 commit comments

Comments
 (0)