Implement basic API interaction

This commit is contained in:
april
2024-01-02 17:41:11 -06:00
parent a456f8155b
commit 73b11482ff
20 changed files with 2867 additions and 189 deletions

View File

@@ -0,0 +1,53 @@
import {
AppShell,
Burger,
Group,
Title,
UnstyledButton,
Image,
Avatar,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import ThemeToggle from "../theme-toggle";
import { Link, useNavigate } from "@remix-run/react";
import Navbar from "./navbar";
export function TailfinAppShell({ children }: { children: React.ReactNode }) {
const [opened, { toggle }] = useDisclosure();
const navigate = useNavigate();
return (
<AppShell
header={{ height: 60 }}
navbar={{ width: 300, breakpoint: "sm", collapsed: { mobile: !opened } }}
padding="md"
>
<AppShell.Header>
<Group h="100%" justify="space-between" px="md">
<Group h="100%" px="md">
<Burger
opened={opened}
onClick={toggle}
hiddenFrom="sm"
size="sm"
/>
</Group>
<Group gap="xs">
<Avatar src="/logo.png" component={Link} to="/logbook" />
<UnstyledButton onClick={() => navigate("/logbook")}>
<Title order={2} fw="normal">
Tailfin
</Title>
</UnstyledButton>
</Group>
<ThemeToggle />
</Group>
</AppShell.Header>
<AppShell.Navbar>
<Navbar />
</AppShell.Navbar>
<AppShell.Main>{children}</AppShell.Main>
</AppShell>
);
}

68
web/app/ui/nav/navbar.tsx Normal file
View File

@@ -0,0 +1,68 @@
import { useMe, useSignOut } from "@/util/hooks";
import { Stack, NavLink, ActionIcon } from "@mantine/core";
import { Link, useLocation } from "@remix-run/react";
import {
IconBook2,
IconLogout,
IconMapRoute,
IconPlaneDeparture,
IconUser,
} from "@tabler/icons-react";
export default function Navbar() {
const location = useLocation();
const page = location.pathname.split("/")[2];
const me = useMe();
const signOut = useSignOut();
return (
<Stack justify="space-between" h="100%">
<Stack gap="0">
<NavLink
p="md"
component={Link}
to="/logbook"
label="Dashboard"
leftSection={<IconPlaneDeparture />}
active={page == null}
/>
<NavLink
p="md"
component={Link}
to="/logbook/flights"
label="Flights"
leftSection={<IconBook2 />}
active={page === "flights"}
/>
</Stack>
<Stack gap="0">
<NavLink
p="md"
label={
me.isError
? me.error.message
: me.isFetched
? me.data?.username
: "Not Logged In"
}
leftSection={<IconUser />}
>
<NavLink
p="md"
component={Link}
to="/logbook/me"
label="Account"
leftSection={<IconUser />}
/>
<NavLink
p="md"
onClick={() => signOut()}
label="Sign Out"
leftSection={<IconLogout />}
/>
</NavLink>
</Stack>
</Stack>
);
}

View File

@@ -0,0 +1,30 @@
import {
ActionIcon,
Tooltip,
useComputedColorScheme,
useMantineColorScheme,
} from "@mantine/core";
import { IconMoonStars, IconSun } from "@tabler/icons-react";
const ThemeToggle = () => {
const { colorScheme, setColorScheme } = useMantineColorScheme();
const comoputedColorScheme = useComputedColorScheme("dark");
const toggleColorScheme = () => {
setColorScheme(comoputedColorScheme === "dark" ? "light" : "dark");
};
return (
<Tooltip label={(colorScheme === "dark" ? "Light" : "Dark") + " Theme"}>
<ActionIcon
variant="default"
radius="xl"
size="lg"
aria-label="Toggle Dark Theme"
onClick={toggleColorScheme}
>
{colorScheme === "dark" ? <IconSun /> : <IconMoonStars />}
</ActionIcon>
</Tooltip>
);
};
export default ThemeToggle;