Improve flight view appearance
This commit is contained in:
parent
887f83119f
commit
04813bfd76
@ -1,8 +1,17 @@
|
|||||||
|
import { LogItem, VerticalLogItem } from "@/ui/display/log-item";
|
||||||
import ErrorDisplay from "@/ui/error-display";
|
import ErrorDisplay from "@/ui/error-display";
|
||||||
import { client } from "@/util/api";
|
import { client } from "@/util/api";
|
||||||
import { Center, Container, List, Loader, Stack, Text } from "@mantine/core";
|
import {
|
||||||
|
Center,
|
||||||
|
Container,
|
||||||
|
Divider,
|
||||||
|
Grid,
|
||||||
|
Loader,
|
||||||
|
ScrollAreaAutosize,
|
||||||
|
Stack,
|
||||||
|
Title,
|
||||||
|
} from "@mantine/core";
|
||||||
import { useParams } from "@remix-run/react";
|
import { useParams } from "@remix-run/react";
|
||||||
import { IconAlertTriangle } from "@tabler/icons-react";
|
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
export default function Flight() {
|
export default function Flight() {
|
||||||
@ -14,30 +23,239 @@ export default function Flight() {
|
|||||||
await client.get(`/flights/${params.id}`).then((res) => res.data),
|
await client.get(`/flights/${params.id}`).then((res) => res.data),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const log = flight.data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Stack h="calc(100vh - 95px)">
|
<Stack>
|
||||||
{flight.isError ? (
|
{flight.isError ? (
|
||||||
<ErrorDisplay error="Error Fetching Flight" />
|
<Center h="calc(100vh - 95px)">
|
||||||
|
<ErrorDisplay error="Error Fetching Flight" />
|
||||||
|
</Center>
|
||||||
) : flight.isPending ? (
|
) : flight.isPending ? (
|
||||||
<Center h="100%">
|
<Center h="calc(100vh - 95px)">
|
||||||
<Loader />
|
<Loader />
|
||||||
</Center>
|
</Center>
|
||||||
|
) : flight.data ? (
|
||||||
|
<>
|
||||||
|
<Title order={3} py="lg" style={{ textAlign: "center" }}>
|
||||||
|
Flight Log
|
||||||
|
</Title>
|
||||||
|
<ScrollAreaAutosize mah="calc(100vh - 95px - 110px)" m="0" p="0">
|
||||||
|
<Container h="100%">
|
||||||
|
<Grid justify="center">
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem label="Date" content={log.date} date />
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem label="Aircraft" content={log.aircraft} />
|
||||||
|
</Grid.Col>
|
||||||
|
{log.waypoint_from || log.waypoint_to ? (
|
||||||
|
<>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Waypoint From"
|
||||||
|
content={log.waypoint_from}
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Waypoint To"
|
||||||
|
content={log.waypoint_to}
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
{log.route ? (
|
||||||
|
<>
|
||||||
|
<Grid.Col span={12}>
|
||||||
|
<VerticalLogItem label="Route" content={log.route} />
|
||||||
|
</Grid.Col>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
{log.hobbs_start || log.hobbs_end ? (
|
||||||
|
<>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Hobbs Start"
|
||||||
|
content={log.hobbs_start}
|
||||||
|
hours
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Hobbs End"
|
||||||
|
content={log.hobbs_end}
|
||||||
|
hours
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
{log.tach_start || log.tach_end ? (
|
||||||
|
<>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Tach Start"
|
||||||
|
content={log.tach_start}
|
||||||
|
hours
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Tach End"
|
||||||
|
content={log.tach_end}
|
||||||
|
hours
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
{log.time_start || log.time_off ? (
|
||||||
|
<>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Time Start"
|
||||||
|
content={log.time_start}
|
||||||
|
time
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Time Off"
|
||||||
|
content={log.time_off}
|
||||||
|
time
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
{log.time_down || log.time_stop ? (
|
||||||
|
<>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Time Down"
|
||||||
|
content={log.time_down}
|
||||||
|
time
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Time Stop"
|
||||||
|
content={log.time_stop}
|
||||||
|
time
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
<Grid.Col span={4}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Total Time"
|
||||||
|
content={log.time_total}
|
||||||
|
hours
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={4}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Time Solo"
|
||||||
|
content={log.time_solo}
|
||||||
|
hours
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={4}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Time Night"
|
||||||
|
content={log.time_night}
|
||||||
|
hours
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Time PIC"
|
||||||
|
content={log.time_pic}
|
||||||
|
hours
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Time SIC"
|
||||||
|
content={log.time_sic}
|
||||||
|
hours
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
{log.time_xc && log.dist_xc ? (
|
||||||
|
<>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Time Cross-Country"
|
||||||
|
content={log.time_xc}
|
||||||
|
hours
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Cross-Country Distance"
|
||||||
|
content={log.dist_xc}
|
||||||
|
decimal={2}
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Takeoffs (Day)"
|
||||||
|
content={log.takeoffs_day}
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Landings (Day)"
|
||||||
|
content={log.landings_day}
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Takeoffs (Night)"
|
||||||
|
content={log.takeoffs_night}
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Landings (Night)"
|
||||||
|
content={log.landings_night}
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
{log.time_instrument ||
|
||||||
|
log.time_sim_instrument ||
|
||||||
|
log.holds_instrument ? (
|
||||||
|
<>
|
||||||
|
<Grid.Col span={4}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Instrument Time"
|
||||||
|
content={log.time_instrument}
|
||||||
|
hours
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={4}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Simulated Instrument Time"
|
||||||
|
content={log.time_sim_instrument}
|
||||||
|
hours
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={4}>
|
||||||
|
<VerticalLogItem
|
||||||
|
label="Instrument Holds"
|
||||||
|
content={log.holds_instrument}
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</Grid>
|
||||||
|
</Container>
|
||||||
|
</ScrollAreaAutosize>
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<List>
|
<Center h="calc(100vh - 95px)">
|
||||||
{Object.entries(flight.data).map(([key, value]) =>
|
<ErrorDisplay error="Unknown Error" />
|
||||||
value && value.length !== 0 ? (
|
</Center>
|
||||||
<List.Item key={key}>
|
|
||||||
<Text span>
|
|
||||||
<Text span fw={700}>
|
|
||||||
{key}
|
|
||||||
</Text>
|
|
||||||
: <Text span>{value}</Text>
|
|
||||||
</Text>
|
|
||||||
</List.Item>
|
|
||||||
) : null
|
|
||||||
)}
|
|
||||||
</List>
|
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -111,7 +111,7 @@ export default function NewFlight() {
|
|||||||
<Title order={2}>New Flight</Title>
|
<Title order={2}>New Flight</Title>
|
||||||
|
|
||||||
<form onSubmit={form.onSubmit((values) => createFlight.mutate(values))}>
|
<form onSubmit={form.onSubmit((values) => createFlight.mutate(values))}>
|
||||||
<ScrollAreaAutosize mah="calc(100vh - 95px - 110px">
|
<ScrollAreaAutosize mah="calc(100vh - 95px - 110px)">
|
||||||
<Container>
|
<Container>
|
||||||
{/* Date and Aircraft */}
|
{/* Date and Aircraft */}
|
||||||
|
|
||||||
|
53
web/app/ui/display/log-item.tsx
Normal file
53
web/app/ui/display/log-item.tsx
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { Card, Group, Stack, Text } from "@mantine/core";
|
||||||
|
|
||||||
|
export function LogItem({
|
||||||
|
label,
|
||||||
|
content,
|
||||||
|
}: {
|
||||||
|
label: string;
|
||||||
|
content: string | null;
|
||||||
|
}) {
|
||||||
|
if (content === null) content = "";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Group justify="space-between" px="sm">
|
||||||
|
<Text>{label}</Text>
|
||||||
|
<Text>{content}</Text>
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VerticalLogItem({
|
||||||
|
label,
|
||||||
|
content,
|
||||||
|
decimal = 0,
|
||||||
|
hours = false,
|
||||||
|
time = false,
|
||||||
|
date = false,
|
||||||
|
}: {
|
||||||
|
label: string;
|
||||||
|
content: string | null;
|
||||||
|
decimal?: number;
|
||||||
|
hours?: boolean;
|
||||||
|
time?: boolean;
|
||||||
|
date?: boolean;
|
||||||
|
}) {
|
||||||
|
if (content === null) content = "";
|
||||||
|
if (decimal > 0) content = Number(content).toFixed(decimal);
|
||||||
|
if (hours) content = Number(content).toFixed(1);
|
||||||
|
if (time) content = content.split("T")[1];
|
||||||
|
if (date) content = content.split("T")[0];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<Stack gap="xs" align="center">
|
||||||
|
<Text c="dimmed" style={{ textalign: "center" }}>
|
||||||
|
{label}
|
||||||
|
</Text>
|
||||||
|
<Text size="lg" style={{ textalign: "center" }}>
|
||||||
|
{content}
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
@ -14,11 +14,6 @@ type FlightBaseSchema = {
|
|||||||
tach_start: number | null;
|
tach_start: number | null;
|
||||||
tach_end: number | null;
|
tach_end: number | null;
|
||||||
|
|
||||||
time_start: number | null;
|
|
||||||
time_off: number | null;
|
|
||||||
time_down: number | null;
|
|
||||||
time_stop: number | null;
|
|
||||||
|
|
||||||
time_total: number;
|
time_total: number;
|
||||||
time_pic: number;
|
time_pic: number;
|
||||||
time_sic: number;
|
time_sic: number;
|
||||||
@ -52,16 +47,31 @@ type FlightBaseSchema = {
|
|||||||
|
|
||||||
type FlightFormSchema = FlightBaseSchema & {
|
type FlightFormSchema = FlightBaseSchema & {
|
||||||
date: dayjs.Dayjs;
|
date: dayjs.Dayjs;
|
||||||
|
|
||||||
|
time_start: number | null;
|
||||||
|
time_off: number | null;
|
||||||
|
time_down: number | null;
|
||||||
|
time_stop: number | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type FlightCreateSchema = FlightBaseSchema & {
|
type FlightCreateSchema = FlightBaseSchema & {
|
||||||
date: string;
|
date: string;
|
||||||
|
|
||||||
|
time_start: dayjs.Dayjs;
|
||||||
|
time_off: dayjs.Dayjs;
|
||||||
|
time_down: dayjs.Dayjs;
|
||||||
|
time_stop: dayjs.Dayjs;
|
||||||
};
|
};
|
||||||
|
|
||||||
type FlightDisplaySchema = FlightBaseSchema & {
|
type FlightDisplaySchema = FlightBaseSchema & {
|
||||||
id: string;
|
id: string;
|
||||||
user: string;
|
user: string;
|
||||||
date: dayjs.Dayjs;
|
date: dayjs.Dayjs;
|
||||||
|
|
||||||
|
time_start: number | null;
|
||||||
|
time_off: number | null;
|
||||||
|
time_down: number | null;
|
||||||
|
time_stop: number | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type FlightConciseSchema = {
|
type FlightConciseSchema = {
|
||||||
@ -86,6 +96,22 @@ const flightCreateHelper = (values: FlightFormSchema): FlightCreateSchema => {
|
|||||||
hobbs_end: Number(values.hobbs_end),
|
hobbs_end: Number(values.hobbs_end),
|
||||||
tach_start: Number(values.tach_start),
|
tach_start: Number(values.tach_start),
|
||||||
tach_end: Number(values.tach_end),
|
tach_end: Number(values.tach_end),
|
||||||
|
time_start: values.date
|
||||||
|
.utc()
|
||||||
|
.hour(values.time_start ?? 0 / 100)
|
||||||
|
.minute(values.time_start ?? 0 % 100),
|
||||||
|
time_off: values.date
|
||||||
|
.utc()
|
||||||
|
.hour(values.time_off ?? 0 / 100)
|
||||||
|
.minute(values.time_off ?? 0 % 100),
|
||||||
|
time_down: values.date
|
||||||
|
.utc()
|
||||||
|
.hour(values.time_down ?? 0 / 100)
|
||||||
|
.minute(values.time_down ?? 0 % 100),
|
||||||
|
time_stop: values.date
|
||||||
|
.utc()
|
||||||
|
.hour(values.time_stop ?? 0 / 100)
|
||||||
|
.minute(values.time_stop ?? 0 % 100),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user