From 654393bab887f509fc0757d565307f6fefd3758a Mon Sep 17 00:00:00 2001 From: april Date: Fri, 5 Jan 2024 14:54:44 -0600 Subject: [PATCH] Implement flight deletion --- web/app/root.tsx | 15 +- web/app/routes/logbook.flights.$id/route.tsx | 501 +++++++++++-------- web/app/routes/logbook.flights.new/route.tsx | 29 +- web/app/ui/form/list-input.tsx | 2 +- web/app/util/types.ts | 83 +-- web/package-lock.json | 1 + 6 files changed, 356 insertions(+), 275 deletions(-) diff --git a/web/app/root.tsx b/web/app/root.tsx index 0ac04d6..b129019 100644 --- a/web/app/root.tsx +++ b/web/app/root.tsx @@ -37,6 +37,7 @@ import { Stack, Title, } from "@mantine/core"; +import { ModalsProvider } from "@mantine/modals"; import { IconRocket } from "@tabler/icons-react"; import { AuthProvider } from "./util/auth"; @@ -159,12 +160,14 @@ export default function App() { - - - - - - + + + + + + + + diff --git a/web/app/routes/logbook.flights.$id/route.tsx b/web/app/routes/logbook.flights.$id/route.tsx index a84d5f7..539fe76 100644 --- a/web/app/routes/logbook.flights.$id/route.tsx +++ b/web/app/routes/logbook.flights.$id/route.tsx @@ -2,21 +2,31 @@ import { VerticalLogItem } from "@/ui/display/log-item"; import ErrorDisplay from "@/ui/error-display"; import { useApi } from "@/util/api"; import { + ActionIcon, Center, Container, Grid, + Group, Loader, ScrollArea, Stack, Title, + Tooltip, + Text, + Modal, + Button, } from "@mantine/core"; -import { useParams } from "@remix-run/react"; -import { useQuery } from "@tanstack/react-query"; +import { useDisclosure } from "@mantine/hooks"; +import { modals } from "@mantine/modals"; +import { useNavigate, useParams } from "@remix-run/react"; +import { IconPencil, IconTrash } from "@tabler/icons-react"; +import { useMutation, useQuery } from "@tanstack/react-query"; export default function Flight() { const params = useParams(); const client = useApi(); + const navigate = useNavigate(); const flight = useQuery({ queryKey: [params.id], @@ -24,241 +34,302 @@ export default function Flight() { await client.get(`/flights/${params.id}`).then((res) => res.data), }); + const [deleteOpened, { open: openDelete, close: closeDelete }] = + useDisclosure(false); + + const deleteFlight = useMutation({ + mutationFn: async () => + await client.delete(`/flights/${params.id}`).then((res) => res.data), + onSuccess: () => { + navigate("/logbook/flights"); + }, + }); + const log = flight.data; return ( - // - - {flight.isError ? ( -
- -
- ) : flight.isPending ? ( -
- -
- ) : flight.data ? ( - <> - - Flight Log - - - - - - - - - - - {log.waypoint_from || log.waypoint_to ? ( - <> + <> + + + + Are you sure you want to delete this flight? This action cannot be + undone. + + {deleteFlight.isError ? ( + + {deleteFlight.error.message} + + ) : null} + + + + + + + + + {flight.isError ? ( +
+ +
+ ) : flight.isPending ? ( +
+ +
+ ) : flight.data ? ( + <> + + + Flight Log + + + + + + + + + + + + + + + + + - + - - ) : null} - {log.route ? ( - <> - - - - - ) : null} - {log.hobbs_start || log.hobbs_end ? ( - <> - - - - - - - - ) : null} - {log.tach_start || log.tach_end ? ( - <> - - - - - - - - ) : null} - {log.time_start || log.time_off ? ( - <> - - - - - - - - ) : null} - {log.time_down || log.time_stop ? ( - <> - - - - - - - - ) : null} - - - - - - - - - - - - - - - - {log.time_xc && log.dist_xc ? ( - <> - - - - - - - - ) : null} - - - - - - - - - - - - - {log.time_instrument || - log.time_sim_instrument || - log.holds_instrument ? ( - <> + {log.waypoint_from || log.waypoint_to ? ( + <> + + + + + + + + ) : null} + {log.route ? ( + <> + + + + + ) : null} + {log.hobbs_start || log.hobbs_end ? ( + <> + + + + + + + + ) : null} + {log.tach_start || log.tach_end ? ( + <> + + + + + + + + ) : null} + {log.time_start || log.time_off ? ( + <> + + + + + + + + ) : null} + {log.time_down || log.time_stop ? ( + <> + + + + + + + + ) : null} - - ) : null} - - - - - ) : ( -
- -
- )} -
- //
+ + + + + + + {log.time_xc && log.dist_xc ? ( + <> + + + + + + + + ) : null} + + + + + + + + + + + + + {log.time_instrument || + log.time_sim_instrument || + log.holds_instrument ? ( + <> + + + + + + + + + + + ) : null} +
+
+
+ + ) : ( +
+ +
+ )} +
+
+ ); } diff --git a/web/app/routes/logbook.flights.new/route.tsx b/web/app/routes/logbook.flights.new/route.tsx index a6a3106..452c829 100644 --- a/web/app/routes/logbook.flights.new/route.tsx +++ b/web/app/routes/logbook.flights.new/route.tsx @@ -5,8 +5,9 @@ import { Fieldset, Group, NumberInput, - ScrollAreaAutosize, + ScrollArea, Stack, + Text, TextInput, Textarea, Title, @@ -23,7 +24,6 @@ import ListInput from "@/ui/form/list-input"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { useApi } from "@/util/api"; import { useNavigate } from "@remix-run/react"; -import { useAuth } from "@/util/auth"; import { AxiosError } from "axios"; export default function NewFlight() { @@ -82,24 +82,18 @@ export default function NewFlight() { const client = useApi(); - const { clearUser } = useAuth(); - const createFlight = useMutation({ mutationFn: async (values: FlightFormSchema) => { const newFlight = flightCreateHelper(values); - const res = await client.post("/flights", newFlight); - return res.data; + if (newFlight) { + const res = await client.post("/flights", newFlight); + return res.data; + } + throw new Error("Flight creation failed"); }, retry: (failureCount, error: AxiosError) => { return !error || error.response?.status !== 401; }, - onError: (error: AxiosError) => { - console.log(error); - if (error.response?.status === 401) { - clearUser(); - navigate("/login"); - } - }, onSuccess: async (data: { id: string }) => { await queryClient.invalidateQueries({ queryKey: ["flights-list"] }); navigate(`/logbook/flights/${data.id}`); @@ -112,7 +106,7 @@ export default function NewFlight() { New Flight
createFlight.mutate(values))}> - + {/* Date and Aircraft */} @@ -347,9 +341,14 @@ export default function NewFlight() { /> - + + {createFlight.isError ? ( + + {createFlight.error.message} + + ) : null} diff --git a/web/app/ui/form/list-input.tsx b/web/app/ui/form/list-input.tsx index b1cc753..fd85264 100644 --- a/web/app/ui/form/list-input.tsx +++ b/web/app/ui/form/list-input.tsx @@ -37,7 +37,7 @@ export default function ListInput({ }; return ( - + {(form.getTransformedValues()[field_key] as string[]).map( (item: string) => ( diff --git a/web/app/util/types.ts b/web/app/util/types.ts index 0ac358e..91cc973 100644 --- a/web/app/util/types.ts +++ b/web/app/util/types.ts @@ -88,44 +88,51 @@ type FlightConciseSchema = { comments: string; }; -const flightCreateHelper = (values: FlightFormSchema): FlightCreateSchema => { - console.log(values.date.utc().startOf("date").toISOString()); - return { - ...values, - date: values.date.utc().startOf("day").toISOString(), - hobbs_start: Number(values.hobbs_start), - hobbs_end: Number(values.hobbs_end), - tach_start: Number(values.tach_start), - tach_end: Number(values.tach_end), - time_start: values.date - .utc() - .hour(Math.floor((values.time_start ?? 0) / 100)) - .minute(Math.floor((values.time_start ?? 0) % 100)) - .second(0) - .millisecond(0) - .toISOString(), - time_off: values.date - .utc() - .hour(Math.floor((values.time_off ?? 0) / 100)) - .minute(Math.floor((values.time_off ?? 0) % 100)) - .second(0) - .millisecond(0) - .toISOString(), - time_down: values.date - .utc() - .hour(Math.floor((values.time_down ?? 0) / 100)) - .minute(Math.floor((values.time_down ?? 0) % 100)) - .second(0) - .millisecond(0) - .toISOString(), - time_stop: values.date - .utc() - .hour(Math.floor((values.time_stop ?? 0) / 100)) - .minute(Math.floor((values.time_stop ?? 0) % 100)) - .second(0) - .millisecond(0) - .toISOString(), - }; +const flightCreateHelper = ( + values: FlightFormSchema +): FlightCreateSchema | void => { + const date = dayjs(values.date); + try { + const newFlight = { + ...values, + date: date.utc().startOf("day").toISOString(), + hobbs_start: values.hobbs_start ? Number(values.hobbs_start) : null, + hobbs_end: values.hobbs_end ? Number(values.hobbs_end) : null, + tach_start: values.tach_start ? Number(values.tach_start) : null, + tach_end: values.tach_end ? Number(values.tach_end) : null, + time_start: date + .utc() + .hour(Math.floor((values.time_start ?? 0) / 100)) + .minute(Math.floor((values.time_start ?? 0) % 100)) + .second(0) + .millisecond(0) + .toISOString(), + time_off: date + .utc() + .hour(Math.floor((values.time_off ?? 0) / 100)) + .minute(Math.floor((values.time_off ?? 0) % 100)) + .second(0) + .millisecond(0) + .toISOString(), + time_down: date + .utc() + .hour(Math.floor((values.time_down ?? 0) / 100)) + .minute(Math.floor((values.time_down ?? 0) % 100)) + .second(0) + .millisecond(0) + .toISOString(), + time_stop: date + .utc() + .hour(Math.floor((values.time_stop ?? 0) / 100)) + .minute(Math.floor((values.time_stop ?? 0) % 100)) + .second(0) + .millisecond(0) + .toISOString(), + }; + return newFlight; + } catch (err) { + console.log(err); + } }; export { diff --git a/web/package-lock.json b/web/package-lock.json index 275ad33..4d993d1 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -4,6 +4,7 @@ "requires": true, "packages": { "": { + "name": "tailfin-web", "dependencies": { "@mantine/core": "^7.4.0", "@mantine/dates": "^7.4.0",