Skip to content

Commit df16b52

Browse files
authored
Merge branch 'main' into scroll-ui
2 parents 6c78ffc + f4c48df commit df16b52

File tree

13 files changed

+572
-385
lines changed

13 files changed

+572
-385
lines changed

.env

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
VITE_API_URL=https://hytechracing.duckdns.org
2-
1+
VITE_API_URL=api-url:port

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,8 @@ dist-ssr
2323
*.ntvs*
2424
*.njsproj
2525
*.sln
26-
*.sw?
26+
*.sw?
27+
28+
.env
29+
.env.local
30+
.env.*

package-lock.json

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

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"@mantine/hooks": "^7.13.1",
2222
"@tabler/icons-react": "3.17.0",
2323
"dayjs": "^1.11.13",
24+
"nuqs": "^2.2.1",
2425
"react": "^18.3.1",
2526
"react-dom": "^18.3.1",
2627
"react-router-dom": "^6.27.0",
@@ -54,7 +55,7 @@
5455
"storybook": "^8.3.4",
5556
"typescript": "^5.5.3",
5657
"typescript-eslint": "^8.0.1",
57-
"vite": "^5.4.10"
58+
"vite": "^5.4.11"
5859
},
5960
"lint-staged": {
6061
"*.{ts,tsx,js,jsx}": [

src/components/DataTable.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export default function DataTable({
8080
/>
8181
</Input.Wrapper>
8282
</Table.Td>
83+
8384
</Table.Tr>
8485
))
8586
);

src/components/FileUpload.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const FileUpload: React.FC<FileUploadProps> = ({ uploadUrl }) => {
1111
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
1212
const [error, setError] = useState<string | null>(null);
1313
const [success, setSuccess] = useState<string | null>(null);
14+
const [loading, setLoading] = useState(false);
15+
1416

1517
const handleFileChange = (files: File[]) => {
1618
if (files.length > 0) {
@@ -19,6 +21,7 @@ const FileUpload: React.FC<FileUploadProps> = ({ uploadUrl }) => {
1921
};
2022

2123
const handleUpload = async () => {
24+
setLoading(true);
2225
setError(null);
2326
setSuccess(null)
2427
if (selectedFiles.length > 0) {
@@ -79,6 +82,7 @@ const FileUpload: React.FC<FileUploadProps> = ({ uploadUrl }) => {
7982
setError("Please select files to upload.");
8083
}
8184
}
85+
setLoading(false);
8286
};
8387

8488
const toggleModal = () => {
@@ -123,12 +127,9 @@ const FileUpload: React.FC<FileUploadProps> = ({ uploadUrl }) => {
123127
</div>
124128
)}
125129
</div>
126-
127-
<Button onClick={handleUpload} style={{ marginTop: 10 }}>
128-
Upload
129-
</Button>
130-
131-
<Button onClick={handleUpload} style={{ marginTop: 10 }}>Upload</Button>
130+
131+
<Button loading={loading} loaderProps={{ type: 'dots' }} onClick={handleUpload} style={{ marginTop: 10 }} disabled={loading}>Upload</Button>
132+
132133
{success && (
133134
<Notification color="green" onClose={() => setSuccess(null)} style={{ marginTop: 10 }}>
134135
{success}

src/components/PreviewCard.tsx

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
Table,
99
ScrollArea,
1010
TextInput,
11+
Notification,
1112
} from "@mantine/core";
1213
import {
1314
IconDownload,
@@ -23,6 +24,39 @@ interface PreviewCardProps {
2324
}
2425

2526
function PreviewCard({ selectedData }: PreviewCardProps) {
27+
const [loading, setLoading] = useState(false);
28+
const [error, setError] = useState<string | null>(null);
29+
const [success, setSuccess] = useState<string | null>(null);
30+
31+
const handleDelete = async () => {
32+
setLoading(true)
33+
setError(null);
34+
setSuccess(null)
35+
try {
36+
const response = await fetch(`${import.meta.env.VITE_API_URL}/mcaps/${selectedData?.id}`, {
37+
method: 'DELETE',
38+
});
39+
40+
if (!response.ok) {
41+
if (response.status === 503) {
42+
const errorMsg = await response.text();
43+
setError(`Failed to delete: ${errorMsg} \nTry again in a few minutes!`);
44+
} else {
45+
const errorMsg = await response.text();
46+
setError(`Failed to delete: ${errorMsg}`);
47+
}
48+
} else {
49+
const result = await response.json();
50+
setSuccess('File deleted successfully!');
51+
console.log('Delete successful:', result);
52+
}
53+
} catch (error) {
54+
console.error('Error sending Delete request:', error);
55+
setError('An error occurred during file deletion.');
56+
}
57+
setLoading(false)
58+
}
59+
2660
const formatDate = (dateString: string) => {
2761
const date = new Date(dateString);
2862
return date.toLocaleDateString("en-US", {
@@ -158,20 +192,37 @@ function PreviewCard({ selectedData }: PreviewCardProps) {
158192
bottom: 0,
159193
left: 0,
160194
padding: 20,
161-
gap: "10px",
195+
gap: "8px",
162196
}}
163197
>
164-
<DownloadButton
165-
buttonText="MCAP"
166-
//One file for now -- can make it dynamically read several files at a time
167-
fileName={selectedData.mcap_files[0].file_name}
168-
signedUrl={selectedData.mcap_files[0].signed_url ?? null}
169-
/>
170-
<DownloadButton
171-
buttonText="MAT"
172-
fileName={selectedData.mat_files[0].file_name}
173-
signedUrl={selectedData.mat_files[0].signed_url}
174-
/>
198+
<div>
199+
{selectedData.mcap_files.map((item) => (
200+
<DownloadButton
201+
buttonText="MCAP"
202+
fileName={item.file_name}
203+
signedUrl={item.signed_url ?? null}
204+
/>
205+
))}
206+
{selectedData.mat_files.map((item) => (
207+
<DownloadButton
208+
buttonText="MAT"
209+
fileName={item.file_name}
210+
signedUrl={item.signed_url}
211+
/>
212+
))}
213+
<Button loading={loading} loaderProps={{ type: 'dots' }} size="compact-md" color="red" onClick={handleDelete}>Delete</Button>
214+
{success && (
215+
<Notification color="green" onClose={() => setSuccess(null)} style={{ marginTop: 10 }}>
216+
{success}
217+
</Notification>
218+
)}
219+
{error && (
220+
<Notification color="red" onClose={() => setError(null)} style={{ marginTop: 10 }}>
221+
{error}
222+
</Notification>
223+
)}
224+
</div>
225+
175226
</div>
176227
</>
177228
) : (

src/components/SchemaSearch.tsx

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,24 @@
1-
import React, { useState, useEffect } from "react";
1+
import React from "react";
22
import { MultiSelect } from "@mantine/core";
33
import "@/css/SchemaSearch.css";
4+
import { parseAsArrayOf, parseAsString, useQueryState } from "nuqs";
45

56
interface SchemaSearch {
67
schemas: string[];
7-
clear: boolean;
88
}
99

10-
const SchemaSearch: React.FC<SchemaSearch> = ({ schemas, clear }) => {
11-
const [value, setValue] = useState<string>("");
12-
const [selectedSchemas, setSelectedSchemas] = useState<string[]>([]);
13-
14-
const filteredSchemas = schemas.filter((schema) =>
15-
schema.toLowerCase().includes(value.toLowerCase()),
10+
const SchemaSearch: React.FC<SchemaSearch> = ({ schemas }) => {
11+
const [selectedSchemas, setSelectedSchemas] = useQueryState<string[]>(
12+
"schemas",
13+
parseAsArrayOf(parseAsString).withDefault([]),
1614
);
17-
18-
19-
const clearSchema = () => {
20-
setValue("");
21-
setSelectedSchemas([])
22-
};
23-
24-
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
25-
if (event.key === "Enter" && filteredSchemas.length > 0) {
26-
setValue(filteredSchemas[0]);
27-
setValue("")
28-
}
29-
};
30-
31-
useEffect(() => {
32-
clearSchema();
33-
}, [clear]);
3415

3516
return (
3617
<div className="schemasearchbutton">
3718
<MultiSelect
3819
label="Schema"
3920
placeholder="Schema name"
40-
data={filteredSchemas}
41-
onKeyDown={handleKeyDown}
21+
data={schemas}
4222
value={selectedSchemas}
4323
onChange={setSelectedSchemas}
4424
searchable

0 commit comments

Comments
 (0)