Implement filtering flights by aircraft

This commit is contained in:
april 2024-01-11 13:21:55 -06:00
parent b50d333677
commit 38d62770f6
4 changed files with 121 additions and 36 deletions

View File

@ -5,13 +5,13 @@ import { IconFeather } from "@tabler/icons-react";
export default function Flights() { export default function Flights() {
return ( return (
<> <>
<Container visibleFrom="md" h="calc(100vh - 95px)"> <Container visibleFrom="lg" h="calc(100vh - 95px)">
<Stack align="center" justify="center" h="100%"> <Stack align="center" justify="center" h="100%">
<IconFeather size="3rem" /> <IconFeather size="3rem" />
<Center>Select a flight</Center> <Center>Select a flight</Center>
</Stack> </Stack>
</Container> </Container>
<Container hiddenFrom="md"> <Container hiddenFrom="lg">
<MobileFlightsList /> <MobileFlightsList />
</Container> </Container>
</> </>

View File

@ -1,6 +1,7 @@
import ErrorDisplay from "@/ui/error-display"; import ErrorDisplay from "@/ui/error-display";
import { useApi } from "@/util/api"; import { useApi } from "@/util/api";
import { FlightConciseSchema } from "@/util/types"; import { useAircraft, useFlights } from "@/util/hooks";
import { AircraftSchema, FlightConciseSchema } from "@/util/types";
import { import {
NavLink, NavLink,
Text, Text,
@ -12,8 +13,10 @@ import {
Badge, Badge,
Group, Group,
Divider, Divider,
Modal,
Select,
} from "@mantine/core"; } from "@mantine/core";
import { randomId } from "@mantine/hooks"; import { randomId, useDisclosure } from "@mantine/hooks";
import { Link, useLocation, useNavigate } from "@remix-run/react"; import { Link, useLocation, useNavigate } from "@remix-run/react";
import { import {
IconArrowRightTail, IconArrowRightTail,
@ -21,19 +24,12 @@ import {
IconPlus, IconPlus,
IconX, IconX,
} from "@tabler/icons-react"; } from "@tabler/icons-react";
import { UseQueryResult, useQuery } from "@tanstack/react-query"; import {
UseQueryResult,
function useFlights() { useQuery,
const client = useApi(); useQueryClient,
} from "@tanstack/react-query";
const flights = useQuery({ import { useState } from "react";
queryKey: ["flights-list"],
queryFn: async () =>
await client.get(`/flights/by-date?order=1`).then((res) => res.data),
});
return flights;
}
function FlightsListDisplay({ function FlightsListDisplay({
flights, flights,
@ -202,24 +198,76 @@ function FlightsListDisplay({
); );
} }
function AircraftFilter({
aircraft,
setAircraft,
query = "flights-list",
}: {
aircraft: string;
setAircraft: (aircraft: string) => void;
query?: string;
}) {
const getAircraft = useAircraft();
const queryClient = useQueryClient();
return (
<Select
placeholder="Filter by Aircraft..."
data={
getAircraft.isFetched
? getAircraft.data?.map((item: AircraftSchema) => ({
value: item.tail_no,
label: item.tail_no,
}))
: ""
}
value={aircraft}
onChange={(_value, option) => {
setAircraft(option?.label ?? "");
queryClient.invalidateQueries({
queryKey: [query, aircraft],
});
}}
clearable
/>
);
}
export function FlightsList() { export function FlightsList() {
const location = useLocation(); const location = useLocation();
const page = location.pathname.split("/")[3]; const page = location.pathname.split("/")[3];
const flights = useFlights(); const [aircraft, setAircraft] = useState("");
const client = useApi();
// const flights = useFlights("aircraft", aircraft);
const flights = useQuery({
queryKey: ["flights-list", aircraft],
queryFn: async () =>
await client
.get(
`/flights/by-date?order=1${
aircraft !== "" ? `&filter=aircraft&filter_val=${aircraft}` : ""
}`
)
.then((res) => res.data),
});
const navigate = useNavigate(); const navigate = useNavigate();
return ( return (
<Stack p="0" m="0" gap="0"> <Stack p="0" m="0" gap="0">
<Group grow preventGrowOverflow={false}>
<AircraftFilter aircraft={aircraft} setAircraft={setAircraft} />
<Button <Button
variant="outline" variant="outline"
leftSection={<IconPlus />} leftSection={<IconPlus />}
mb="md"
onClick={() => navigate("/logbook/flights/new")} onClick={() => navigate("/logbook/flights/new")}
> >
Add New Flight
</Button> </Button>
</Group>
<ScrollArea h="calc(100vh - 95px - 50px)"> <ScrollArea h="calc(100vh - 95px - 50px)">
<FlightsListDisplay flights={flights} page={page} /> <FlightsListDisplay flights={flights} page={page} />
</ScrollArea> </ScrollArea>
@ -231,7 +279,21 @@ export function MobileFlightsList() {
const location = useLocation(); const location = useLocation();
const page = location.pathname.split("/")[3]; const page = location.pathname.split("/")[3];
const flights = useFlights(); const [aircraft, setAircraft] = useState("");
const client = useApi();
const flights = useQuery({
queryKey: ["flights-list", aircraft],
queryFn: async () =>
await client
.get(
`/flights/by-date?order=1${
aircraft !== "" ? `&filter=aircraft&filter_val=${aircraft}` : ""
}`
)
.then((res) => res.data),
});
const navigate = useNavigate(); const navigate = useNavigate();
@ -239,15 +301,17 @@ export function MobileFlightsList() {
<Stack p="0" m="0" justify="space-between" h="calc(100vh - 95px)"> <Stack p="0" m="0" justify="space-between" h="calc(100vh - 95px)">
<ScrollArea h="calc(100vh - 95px - 50px"> <ScrollArea h="calc(100vh - 95px - 50px">
<FlightsListDisplay flights={flights} page={page} /> <FlightsListDisplay flights={flights} page={page} />
</ScrollArea> </ScrollArea>{" "}
<Group grow preventGrowOverflow={false} wrap="nowrap">
<AircraftFilter aircraft={aircraft} setAircraft={setAircraft} />
<Button <Button
variant="outline" variant="outline"
leftSection={<IconPlus />} leftSection={<IconPlus />}
mt="md"
onClick={() => navigate("/logbook/flights/new")} onClick={() => navigate("/logbook/flights/new")}
> >
Add Add
</Button> </Button>
</Group>
</Stack> </Stack>
); );
} }

View File

@ -218,6 +218,7 @@ export default function FlightForm({
] ]
: null : null
} }
allowDeselect={false}
value={aircraft} value={aircraft}
{...form.getInputProps("aircraft")} {...form.getInputProps("aircraft")}
onChange={(_value, option) => { onChange={(_value, option) => {

View File

@ -11,3 +11,23 @@ export function useAircraft() {
return aircraft; return aircraft;
} }
export function useFlights(filter: string = "", value: string = "") {
const client = useApi();
const flights = useQuery({
queryKey: ["flights-list"],
queryFn: async () =>
await client
.get(
`/flights/by-date?order=1${
filter !== "" && value !== ""
? `&filter=${filter}&value=${value}`
: ""
}`
)
.then((res) => res.data),
});
return flights;
}