Finish flight information display

This commit is contained in:
april 2024-01-08 12:50:20 -06:00
parent 352172487a
commit 8bc3639d89
3 changed files with 267 additions and 187 deletions

View File

@ -1,3 +1,4 @@
import CollapsibleFieldset from "@/ui/display/collapsible-fieldset";
import { VerticalLogItem } from "@/ui/display/log-item"; import { VerticalLogItem } from "@/ui/display/log-item";
import ErrorDisplay from "@/ui/error-display"; import ErrorDisplay from "@/ui/error-display";
import { useApi } from "@/util/api"; import { useApi } from "@/util/api";
@ -15,10 +16,18 @@ import {
Text, Text,
Modal, Modal,
Button, Button,
Badge,
Fieldset,
Collapse,
} from "@mantine/core"; } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks"; import { useDisclosure } from "@mantine/hooks";
import { useNavigate, useParams } from "@remix-run/react"; import { useNavigate, useParams } from "@remix-run/react";
import { IconPencil, IconTrash } from "@tabler/icons-react"; import {
IconPencil,
IconPlaneTilt,
IconPlus,
IconTrash,
} from "@tabler/icons-react";
import { useMutation, useQuery } from "@tanstack/react-query"; import { useMutation, useQuery } from "@tanstack/react-query";
export default function Flight() { export default function Flight() {
@ -87,9 +96,11 @@ export default function Flight() {
) : flight.data ? ( ) : flight.data ? (
<> <>
<Group justify="space-between" px="xl"> <Group justify="space-between" px="xl">
<Title order={2} py="lg" style={{ textAlign: "center" }}> <Group>
Flight Log <Title order={2} py="lg" style={{ textAlign: "center" }}>
</Title> Flight Log
</Title>
</Group>
<Group> <Group>
<Tooltip <Tooltip
label="Edit Flight" label="Edit Flight"
@ -116,212 +127,233 @@ export default function Flight() {
<ScrollArea h="calc(100vh - 95px - 110px)" m="0" p="0"> <ScrollArea h="calc(100vh - 95px - 110px)" m="0" p="0">
<Container h="100%"> <Container h="100%">
<Grid justify="center"> <Grid justify="center">
<Grid.Col span={6}> <CollapsibleFieldset legend="About" mt="sm" w="100%">
<VerticalLogItem label="Date" content={log.date} date /> <Group grow>
</Grid.Col> <VerticalLogItem label="Date" content={log.date} date />
<Grid.Col span={6}> <VerticalLogItem
<VerticalLogItem label="Aircraft"
label="Aircraft" content={log.aircraft}
content={log.aircraft} />
/> </Group>
</Grid.Col> {(log.pax || log.crew) &&
{log.waypoint_from || log.waypoint_to ? ( (log.pax.length > 0 || log.crew.length > 0) ? (
<> <Group grow mt="sm">
<Grid.Col span={6}> <VerticalLogItem label="Pax" content={log.pax} list />
<VerticalLogItem <VerticalLogItem
label="Waypoint From" label="Crew"
content={log.waypoint_from} content={log.crew}
list
/> />
</Grid.Col> </Group>
<Grid.Col span={6}> ) : null}
{log.tags && log.tags.length > 0 ? (
<Group grow mt="sm">
<VerticalLogItem <VerticalLogItem
label="Waypoint To" label="Tags"
content={log.waypoint_to} content={log.tags}
list
/> />
</Grid.Col> </Group>
</> ) : null}
{log.comments?.length > 0 ? (
<Group grow mt="sm">
<VerticalLogItem
label="Comments"
content={log.comments}
/>
</Group>
) : null}
</CollapsibleFieldset>
{log.waypoint_from || log.waypoint_to || log.route ? (
<CollapsibleFieldset legend="Route" w="100%" mt="sm">
{log.waypoint_from || log.waypoint_to ? (
<Group grow>
<VerticalLogItem
label="Waypoint From"
content={log.waypoint_from}
/>
<VerticalLogItem
label="Waypoint To"
content={log.waypoint_to}
/>
</Group>
) : null}
{log.route ? (
<Group grow>
<VerticalLogItem
label="Route"
content={log.route}
/>
</Group>
) : null}
</CollapsibleFieldset>
) : null} ) : null}
{log.route ? ( {log.hobbs_start ||
<> log.hobbs_end ||
<Grid.Col span={12}> log.tach_start ||
<VerticalLogItem label="Route" content={log.route} /> log.tach_end ? (
</Grid.Col> <CollapsibleFieldset legend="Times" w="100%" mt="sm">
</> {log.hobbs_start || log.hobbs_end ? (
<Group grow>
<VerticalLogItem
label="Hobbs Start"
content={log.hobbs_start}
hours
/>
<VerticalLogItem
label="Hobbs End"
content={log.hobbs_end}
hours
/>
</Group>
) : null}
{log.tach_start || log.tach_end ? (
<Group grow mt="sm">
<VerticalLogItem
label="Tach Start"
content={log.tach_start}
hours
/>
<VerticalLogItem
label="Tach End"
content={log.tach_end}
hours
/>
</Group>
) : null}
</CollapsibleFieldset>
) : null} ) : null}
{log.hobbs_start || log.hobbs_end ? ( {log.time_start ||
<> log.time_off ||
<Grid.Col span={6}> log.time_down ||
<VerticalLogItem log.time_stop ? (
label="Hobbs Start" <CollapsibleFieldset legend="Start/Stop" w="100%" mt="sm">
content={log.hobbs_start} {log.time_start || log.time_off ? (
hours <Group grow>
/> <VerticalLogItem
</Grid.Col> label="Time Start"
<Grid.Col span={6}> content={log.time_start}
<VerticalLogItem time
label="Hobbs End" />
content={log.hobbs_end} <VerticalLogItem
hours label="Time Off"
/> content={log.time_off}
</Grid.Col> time
</> />
</Group>
) : null}
{log.time_down || log.time_stop ? (
<Group grow mt="sm">
<VerticalLogItem
label="Time Down"
content={log.time_down}
time
/>
<VerticalLogItem
label="Time Stop"
content={log.time_stop}
time
/>
</Group>
) : null}
</CollapsibleFieldset>
) : null} ) : null}
{log.tach_start || log.tach_end ? ( <CollapsibleFieldset legend="Hours" w="100%" mt="sm">
<> <Group grow>
<Grid.Col span={6}> <VerticalLogItem
<VerticalLogItem label="Total Time"
label="Tach Start" content={log.time_total}
content={log.tach_start} hours
hours />
/> <VerticalLogItem
</Grid.Col> label="Time Solo"
<Grid.Col span={6}> content={log.time_solo}
<VerticalLogItem hours
label="Tach End" />
content={log.tach_end} <VerticalLogItem
hours label="Time Night"
/> content={log.time_night}
</Grid.Col> hours
</> />
) : null} </Group>
{log.time_start || log.time_off ? ( <Group grow mt="sm">
<> <VerticalLogItem
<Grid.Col span={6}> label="Time PIC"
<VerticalLogItem content={log.time_pic}
label="Time Start" hours
content={log.time_start} />
time <VerticalLogItem
/> label="Time SIC"
</Grid.Col> content={log.time_sic}
<Grid.Col span={6}> hours
<VerticalLogItem />
label="Time Off" </Group>
content={log.time_off} </CollapsibleFieldset>
time {log.time_xc || log.dist_xc ? (
/> <CollapsibleFieldset
</Grid.Col> legend="Cross-Country"
</> w="100%"
) : null} mt="sm"
{log.time_down || log.time_stop ? ( >
<> <Group grow>
<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 <VerticalLogItem
label="Time Cross-Country" label="Time Cross-Country"
content={log.time_xc} content={log.time_xc}
hours hours
/> />
</Grid.Col>
<Grid.Col span={6}>
<VerticalLogItem <VerticalLogItem
label="Cross-Country Distance" label="Cross-Country Distance"
content={log.dist_xc} content={log.dist_xc}
decimal={2} decimal={2}
/> />
</Grid.Col> </Group>
</> </CollapsibleFieldset>
) : null} ) : null}
<Grid.Col span={6}> <CollapsibleFieldset
<VerticalLogItem legend="Takeoffs/Landings"
label="Takeoffs (Day)" w="100%"
content={log.takeoffs_day} mt="sm"
/> >
</Grid.Col> <Group grow>
<Grid.Col span={6}> <VerticalLogItem
<VerticalLogItem label="Takeoffs (Day)"
label="Landings (Day)" content={log.takeoffs_day}
content={log.landings_day} />
/> <VerticalLogItem
</Grid.Col> label="Landings (Day)"
<Grid.Col span={6}> content={log.landings_day}
<VerticalLogItem />
label="Takeoffs (Night)" <VerticalLogItem
content={log.takeoffs_night} label="Takeoffs (Night)"
/> content={log.takeoffs_night}
</Grid.Col> />
<Grid.Col span={6}> <VerticalLogItem
<VerticalLogItem label="Landings (Night)"
label="Landings (Night)" content={log.landings_night}
content={log.landings_night} />
/> </Group>
</Grid.Col> </CollapsibleFieldset>
{log.time_instrument || {log.time_instrument ||
log.time_sim_instrument || log.time_sim_instrument ||
log.holds_instrument ? ( log.holds_instrument ? (
<> <CollapsibleFieldset legend="Instrument" mt="sm" w="100%">
<Grid.Col span={4}> <Group grow>
<VerticalLogItem <VerticalLogItem
label="Instrument Time" label="Instrument Time"
content={log.time_instrument} content={log.time_instrument}
hours hours
/> />
</Grid.Col>
<Grid.Col span={4}>
<VerticalLogItem <VerticalLogItem
label="Simulated Instrument Time" label="Simulated Instrument Time"
content={log.time_sim_instrument} content={log.time_sim_instrument}
hours hours
/> />
</Grid.Col>
<Grid.Col span={4}>
<VerticalLogItem <VerticalLogItem
label="Instrument Holds" label="Instrument Holds"
content={log.holds_instrument} content={log.holds_instrument}
/> />
</Grid.Col> </Group>
</> </CollapsibleFieldset>
) : null} ) : null}
</Grid> </Grid>
</Container> </Container>

View File

@ -0,0 +1,35 @@
import { ActionIcon, Collapse, Fieldset, Group, Text } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { IconMinus, IconPlus } from "@tabler/icons-react";
import { ReactNode } from "react";
export default function CollapsibleFieldset({
children,
legend,
w = "",
mt = "",
}: {
children: ReactNode;
legend?: string;
w?: string;
mt?: string;
}) {
const [open, { toggle }] = useDisclosure(true);
return (
<Fieldset
legend={
<Group gap="xs">
{legend ? <Text>{legend}</Text> : null}
<ActionIcon variant="transparent" onClick={toggle} color="gray">
{open ? <IconMinus /> : <IconPlus />}
</ActionIcon>
</Group>
}
w={w}
mt={mt}
>
<Collapse in={open}>{children}</Collapse>
</Fieldset>
);
}

View File

@ -1,4 +1,5 @@
import { Card, Group, Stack, Text } from "@mantine/core"; import { Badge, Card, Group, Stack, Text } from "@mantine/core";
import { randomId } from "@mantine/hooks";
import { IconX } from "@tabler/icons-react"; import { IconX } from "@tabler/icons-react";
export function LogItem({ export function LogItem({
@ -25,36 +26,48 @@ export function VerticalLogItem({
hours = false, hours = false,
time = false, time = false,
date = false, date = false,
list = false,
}: { }: {
label: string; label: string;
content: string | null; content: string | string[] | null;
decimal?: number; decimal?: number;
hours?: boolean; hours?: boolean;
time?: boolean; time?: boolean;
date?: boolean; date?: boolean;
list?: boolean;
}) { }) {
if (content === null) content = ""; if (content === null) content = "";
if (decimal > 0) content = Number(content).toFixed(decimal); if (decimal > 0) content = Number(content).toFixed(decimal);
if (hours) content = Number(content).toFixed(1); if (hours) content = Number(content).toFixed(1);
if (time) { if (time) {
const time = content.split("T")[1].split(":"); const time = (content as string).split("T")[1].split(":");
content = `${time[0]}:${time[1]}`; content = `${time[0]}:${time[1]}`;
} }
if (date) content = content.split("T")[0]; if (date) content = (content as string).split("T")[0];
return ( return (
<Card> <Card shadow="sm" withBorder>
<Stack gap="xs" align="center" h="100%"> <Stack gap="xs" align="center" h="100%">
<Text c="dimmed" style={{ textalign: "center" }}> <Text c="dimmed" style={{ textalign: "center" }}>
{label} {label}
</Text> </Text>
<Text {list ? (
size="lg" <Group>
style={{ textalign: "center" }} {(content as string[]).map((item) => (
c={content === "" ? "dimmed" : ""} <Badge key={randomId()} size="lg">
> {item}
{content === "" ? <IconX /> : content} </Badge>
</Text> ))}
</Group>
) : (
<Text
size="lg"
style={{ textalign: "center" }}
c={content === "" ? "dimmed" : ""}
>
{content === "" ? <IconX /> : content}
</Text>
)}
</Stack> </Stack>
</Card> </Card>
); );