Skip to content

Commit 8d29b2b

Browse files
committed
feat: Add @tanstack/react-table dependency and implement table filtering/sorting
- Add @tanstack/react-table v8.21.3 to both ARO and MCC frontends - Implement TanStack React Table in all major table components: - ARO requests table with status filtering and column sorting - MCC ARO requests view with coordinate formatting and status colors - MCC telemetry data table with real-time updates and multi-column filtering - MCC system logs with search filtering and timestamp sorting - MCC mission commands with output filtering - Add shared TypeScript types aligned with database schema - Implement proper enum types for AROCommandStatus and other statuses - Add responsive table design with sorting indicators - Include error handling and loading states - Update API integration for real data fetching Resolves #346
1 parent a0d78fb commit 8d29b2b

File tree

18 files changed

+1162
-154
lines changed

18 files changed

+1162
-154
lines changed

gs/frontend/aro/package-lock.json

Lines changed: 35 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gs/frontend/aro/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"dependencies": {
1313
"@tailwindcss/vite": "^4.1.13",
1414
"@tanstack/react-query": "^5.87.4",
15+
"@tanstack/react-table": "^8.21.3",
1516
"@types/react-router-dom": "^5.3.3",
1617
"react": "^19.1.1",
1718
"react-dom": "^19.1.1",
@@ -30,6 +31,6 @@
3031
"globals": "^16.3.0",
3132
"typescript": "~5.8.3",
3233
"typescript-eslint": "^8.39.1",
33-
"vite": "^7.1.2"
34+
"vite": "^7.1.5"
3435
}
3536
}

gs/frontend/aro/src/new-request/new-request-form.tsx

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import "./new-request-form.css";
22
import { type ChangeEvent, useState } from "react";
3+
import React from "react";
34

45
const NewRequestForm = () => {
56
const [latitude, setLatitude] = useState(0);
@@ -11,16 +12,42 @@ const NewRequestForm = () => {
1112
// TODO: Show a map centered at latitude / longitude.
1213
});
1314

14-
const handleSubmit = () => {
15-
// TODO: Use the proper type for this
16-
const submission = {
17-
latitude,
18-
longitude,
19-
};
20-
// TODO: Submit form to backend
21-
console.log(submission);
15+
const handleSubmit = async (event: React.FormEvent) => {
16+
event.preventDefault();
17+
18+
try {
19+
const submission = {
20+
latitude,
21+
longitude,
2222

23-
alert("Thanks for submitting!");
23+
};
24+
25+
const response = await fetch('http://localhost:5000/aro-request', {
26+
method: 'POST',
27+
headers: {
28+
'Content-Type': 'application/json',
29+
// NOTE TO REVIEWERS:
30+
// Add authentication headers when implemented
31+
// 'Authorization': `Bearer ${token}`
32+
},
33+
body: JSON.stringify(submission),
34+
});
35+
36+
if (!response.ok) {
37+
throw new Error(`HTTP error! status: ${response.status}`);
38+
}
39+
40+
const result = await response.json();
41+
console.log('Request submitted successfully:', result);
42+
43+
alert("Request submitted successfully! You can view it in your requests list.");
44+
45+
46+
47+
} catch (error) {
48+
console.error('Error submitting request:', error);
49+
alert("Error submitting request. Please try again.");
50+
}
2451
};
2552

2653
const handleLatitudeChange = (event: ChangeEvent<HTMLInputElement>) => {

gs/frontend/aro/src/profile/profile-api.ts

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,49 @@ import type { ProfileData } from "./profile-data.ts";
44
* @brief Gets the profile info of the current user
55
*/
66
export const getProfile = async (): Promise<ProfileData> => {
7-
// This is a mock implementation of an API call
8-
return {
9-
name: "John Doe",
10-
email: "john.doe@gmail.com",
11-
call_sign: "VAYPO",
12-
phone: "1234567890",
13-
};
7+
try {
8+
const response = await fetch('http://localhost:5000/user/profile', {
9+
method: 'GET',
10+
headers: {
11+
'Content-Type': 'application/json',
12+
// Add authentication headers here when implemented
13+
// 'Authorization': `Bearer ${token}`
14+
},
15+
});
16+
17+
if (!response.ok) {
18+
throw new Error(`HTTP error! status: ${response.status}`);
19+
}
20+
21+
const data = await response.json();
22+
return data;
23+
} catch (error) {
24+
console.error('Error fetching profile:', error);
25+
throw error;
26+
}
1427
};
1528

1629
/**
1730
* @brief Updates the profile info of the current user
1831
* @param data The new profile data
1932
*/
2033
export const updateProfile = async (data: ProfileData): Promise<void> => {
21-
// This is a mock implementation of an API call
22-
console.log(data);
34+
try {
35+
const response = await fetch('http://localhost:5000/user/profile', {
36+
method: 'PUT',
37+
headers: {
38+
'Content-Type': 'application/json',
39+
// Add authentication headers here when implemented
40+
// 'Authorization': `Bearer ${token}`
41+
},
42+
body: JSON.stringify(data),
43+
});
44+
45+
if (!response.ok) {
46+
throw new Error(`HTTP error! status: ${response.status}`);
47+
}
48+
} catch (error) {
49+
console.error('Error updating profile:', error);
50+
throw error;
51+
}
2352
};
Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
1+
2+
export type AROCommandStatus =
3+
| 'pending'
4+
| 'scheduled'
5+
| 'taken'
6+
| 'cancelled'
7+
| 'failed'
8+
| 'completed';
9+
110
export interface RequestItemData {
211
id: number;
3-
latitude: number;
4-
longitude: number;
5-
status: string;
12+
aro_id?: number;
13+
latitude: number;
14+
longitude: number;
15+
status: AROCommandStatus;
616
created_on: Date;
717
request_sent_to_obc_on: Date | null;
818
pic_taken_on: Date | null;
919
pic_transmitted_on: Date | null;
10-
cancellable_after: Date;
20+
packet_id?: number | null;
21+
cancellable_after: Date;
1122
// Add more properties as needed
1223
}
Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
import type { RequestItemData } from "./request-item-data.ts";
22

33
export const getRequestItems = async (): Promise<RequestItemData[]> => {
4-
return [
5-
{
6-
id: 1,
7-
status: "Pending",
8-
longitude: 100,
9-
latitude: 80,
10-
created_on: new Date(2024, 10),
11-
cancellable_after: new Date(2025, 12),
12-
request_sent_to_obc_on: null,
13-
pic_transmitted_on: null,
14-
pic_taken_on: null,
15-
},
16-
{
17-
id: 2,
18-
status: "Pending",
19-
longitude: 120,
20-
latitude: 80,
21-
created_on: new Date(2024, 10),
22-
cancellable_after: new Date(2025, 12),
23-
request_sent_to_obc_on: null,
24-
pic_transmitted_on: null,
25-
pic_taken_on: null,
26-
},
27-
];
4+
try {
5+
const response = await fetch('http://localhost:5000/aro-request');
6+
7+
if (!response.ok) {
8+
throw new Error(`HTTP error! status: ${response.status}`);
9+
}
10+
11+
const data = await response.json();
12+
13+
// Transform API response to match our interface if needed
14+
return data.map((item: any) => ({
15+
...item,
16+
status: item.status.toLowerCase(), // Ensure status matches our enum
17+
created_on: new Date(item.created_on),
18+
request_sent_to_obc_on: item.request_sent_to_obc_on ? new Date(item.request_sent_to_obc_on) : null,
19+
pic_taken_on: item.pic_taken_on ? new Date(item.pic_taken_on) : null,
20+
pic_transmitted_on: item.pic_transmitted_on ? new Date(item.pic_transmitted_on) : null,
21+
cancellable_after: item.cancellable_after ? new Date(item.cancellable_after) : new Date(), // Calculate or get from API
22+
}));
23+
} catch (error) {
24+
console.error('Error fetching ARO requests:', error);
25+
throw error;
26+
}
2827
};

0 commit comments

Comments
 (0)