Skip to content

Commit 9788bb3

Browse files
authored
Merge pull request #30 from Dunkstormen/main
Feat: Resolved booking mismatch & updated react to CR
2 parents 1bee8d7 + 89f7889 commit 9788bb3

7 files changed

+6267
-6079
lines changed

package-lock.json

+6,180-6,056
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+8-10
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,33 @@
1010
"astro": "astro"
1111
},
1212
"dependencies": {
13-
"@astrojs/check": "^0.5.4",
14-
"@astrojs/react": "^3.0.10",
13+
"@astrojs/check": "^0.9.4",
14+
"@astrojs/react": "^4.1.0",
1515
"@astrojs/tailwind": "^5.1.0",
1616
"@maptiler/sdk": "^2.0.1",
1717
"@nextui-org/react": "^2.2.10",
1818
"@radix-ui/react-navigation-menu": "^1.1.4",
1919
"@radix-ui/react-slot": "^1.1.0",
2020
"@radix-ui/react-tooltip": "^1.1.2",
21-
"@types/react": "^18.2.55",
22-
"@types/react-dom": "^18.2.19",
23-
"astro": "^4.4.0",
21+
"@types/react": "^19.0.1",
22+
"@types/react-dom": "^19.0.2",
23+
"astro": "^5.0.5",
2424
"astro-navbar": "^2.3.1",
2525
"astro-tooltips": "^0.6.2",
2626
"class-variance-authority": "^0.7.0",
2727
"clsx": "^2.1.1",
2828
"framer-motion": "^11.0.8",
29-
"lucide-react": "^0.383.0",
29+
"lucide-react": "^0.468.0",
3030
"moment": "^2.30.1",
31-
"react": "^18.2.0",
32-
"react-dom": "^18.2.0",
33-
"react-simple-maps": "^3.0.0",
31+
"react": "^19.0.0",
32+
"react-dom": "^19.0.0",
3433
"react-snowfall": "^2.2.0",
3534
"tailwind-merge": "^2.3.0",
3635
"tailwindcss": "^3.4.1",
3736
"tailwindcss-animate": "^1.0.7",
3837
"typescript": "^5.3.3"
3938
},
4039
"devDependencies": {
41-
"@types/react-simple-maps": "^3.0.4",
4240
"daisyui": "^4.10.2"
4341
}
4442
}

src/components/Announcements.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import React, { useState, useEffect } from 'react';
2-
31
async function PullForumData(URL: string) {
42
try {
53
const response = await fetch(URL);

src/components/BookingComponent.jsx

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React, { useEffect, useState } from "react";
2+
3+
4+
const BookingComponent = () => {
5+
const [ControlCenterBookings, setControlCenterBookings] = useState([]);
6+
const [ControlCenterPositions, setControlCenterPositions] = useState([]);
7+
const [VatsimNetworkSessions, setVatsimNetworkSessions] = useState([]);
8+
const [loading, setLoading] = useState(true);
9+
10+
/**
11+
* Fetch data
12+
*/
13+
const fetchComponentData = async () => {
14+
try {
15+
let [ControlCenterBookingsData, ControlCenterPositionsData, VatsimNetworkSessionsData] = await Promise.all([
16+
fetch('https://cc.vatsim-scandinavia.org/api/bookings'),
17+
fetch('https://cc.vatsim-scandinavia.org/api/positions'),
18+
fetch('https://data.vatsim.net/v3/vatsim-data.json'),
19+
]);
20+
21+
ControlCenterBookingsData = await ControlCenterBookingsData.json();
22+
ControlCenterPositionsData = await ControlCenterPositionsData.json();
23+
VatsimNetworkSessionsData = await VatsimNetworkSessionsData.json();
24+
25+
setControlCenterBookings(ControlCenterBookingsData);
26+
setControlCenterPositions(ControlCenterPositionsData);
27+
setVatsimNetworkSessions(VatsimNetworkSessionsData);
28+
} catch (error) {
29+
console.log('Error while fetching data:', error);
30+
}
31+
}
32+
33+
useEffect(() => {
34+
const fetchData = async () => {
35+
await Promise.all([
36+
fetchComponentData(),
37+
]);
38+
setLoading(false);
39+
}
40+
41+
fetchData();
42+
43+
const interval = setInterval(fetchData, 60000);
44+
45+
return () => clearInterval(interval);
46+
}, []);
47+
48+
return (
49+
<table>
50+
<tbody>
51+
<tr></tr>
52+
</tbody>
53+
</table>
54+
);
55+
};
56+
57+
export default BookingComponent;

src/components/BookingComponentv3.jsx

+18-7
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ const BookingComponent = () => {
5959
return correctedCallsign;
6060
}
6161

62+
function parseDateUTC(dateString) {
63+
if (!dateString) return new Date(0); // Default to epoch for missing dates
64+
// Replace space with 'T' and ensure 'Z' at the end for UTC
65+
const formattedDate = dateString.replace(" ", "T");
66+
return new Date(formattedDate.endsWith("Z") ? formattedDate : `${formattedDate}Z`);
67+
}
68+
6269
ControlCenterBookings.data.forEach(booking => {
6370
const bookingDate = new Date(booking.time_start).toISOString().split('T')[0];
6471
const dateIndex = dateArray.findIndex(dateObj => dateObj.date === bookingDate);
@@ -69,12 +76,15 @@ const BookingComponent = () => {
6976

7077
VATSIMNetworkData.controllers.forEach(session => {
7178
if (acceptedFIRsRegex.test(session.callsign) && !mentorRegex.test(session.callsign)) {
72-
const correctedCallsign = getBookableCallsign(session.callsign, session.frequency);
79+
const normalizeCallsign = (callsign) => callsign.replace(/_+/g, "_");
80+
const correctedCallsign = getBookableCallsign(normalizeCallsign(session.callsign), session.frequency);
7381
session.callsign = correctedCallsign;
7482
const existingBooking = dateArray[0].data.find(booking => booking.callsign === session.callsign);
7583
// Merge if existing booking exists and now is after the booking start time.
76-
if (existingBooking && existingBooking.time_start > new Date()) {
84+
85+
if (existingBooking && parseDateUTC(existingBooking.time_start).getTime() < new Date().getTime()) {
7786
existingBooking.name = session.name;
87+
existingBooking.logon_time = session.logon_time;
7888
} else {
7989
dateArray[0].data.push({
8090
...session,
@@ -86,8 +96,9 @@ const BookingComponent = () => {
8696

8797
// Sort the first date (in most cases today) by time, so ad-hoc sessions also are sorted correctly.
8898
dateArray[0].data.sort((a, b) => {
89-
const aTime = a.time_start || a.logon_time;
90-
const bTime = b.time_start || b.logon_time;
99+
const aTime = parseDateUTC(a.time_start || a.logon_time).getTime();
100+
const bTime = parseDateUTC(b.time_start || b.logon_time).getTime();
101+
91102
return new Date(aTime) - new Date(bTime);
92103
});
93104

@@ -124,9 +135,9 @@ const BookingComponent = () => {
124135
</tr>
125136
{date.data.map((booking) => (
126137
<tr key={booking.id} className="h-6 even:bg-gray-50 odd:bg-white dark:even:bg-tertiary dark:odd:bg-black">
127-
{booking.name ? <td className="pl-[4px] text-[#447b68] font-bold"><img class="circle" src="img/icons/circle-solid.svg" alt=""/> {booking.callsign}</td> : <td className="pl-[4px]"><img class="circle" src="img/icons/circle-regular.svg" alt=""/> {booking.callsign}</td>}
128-
<td className="pl-[4px]">{bookingType(booking)}</td>
129-
<td className="pl-[4px]">{booking.time_start ? convertZulu(booking.time_start) : ""}{booking.logon_time ? convertZulu(fixNetworkTime(booking.logon_time)) : ""}</td>
138+
{booking.name ? <td className="pl-[4px] text-[#447b68] font-bold"><img className="circle" src="img/icons/circle-solid.svg" alt=""/> {booking.callsign}</td> : <td className="pl-[4px]"><img className="circle" src="img/icons/circle-regular.svg" alt=""/> {booking.callsign}</td>}
139+
<td className="px-[15px]">{bookingType(booking)}</td>
140+
<td className="pl-[4px]">{booking.time_start && !booking.logon_time ? convertZulu(booking.time_start) : ""}{booking.logon_time ? convertZulu(fixNetworkTime(booking.logon_time)) : ""}</td>
130141
<td className="pl-[4px]">{convertZulu(booking.time_end)}</td>
131142
</tr>
132143
))}

src/components/Events.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect, useState, useRef } from 'react';
1+
import { useEffect, useState, useRef } from 'react';
22

33
const Events = () => {
44
const [events, setEvents] = useState([]);

src/utils/bookingType.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
function bookingType(booking: any) {
22
if (booking.training === 1) {
3-
return <span className="bg-[#1a475f] text-xs text-white px-2 py-[2px] rounded-md flex items-center justify-center w-fit">Training</span>
3+
return <span className="bg-[#1a475f] text-xs text-white px-2 py-[2px] rounded-md flex items-center justify-center">Training</span>
44
} else if (booking.event === 1) {
5-
return <span className="bg-[#41826e] text-xs text-white px-2 py-[2px] rounded-md flex items-center justify-center w-fit">Event</span>
5+
return <span className="bg-[#41826e] text-xs text-white px-2 py-[2px] rounded-md flex items-center justify-center">Event</span>
66
} else if (booking.exam === 1) {
7-
return <span className="bg-[#b63f3f] text-xs text-white px-2 py-[2px] rounded-md flex items-center justify-center w-fit">Exam</span>
7+
return <span className="bg-[#b63f3f] text-xs text-white px-2 py-[2px] rounded-md flex items-center justify-center">Exam</span>
88
} else {
99
return ""
1010
}

0 commit comments

Comments
 (0)