gear-orders/web/vite/src/Dashboard.tsx
2026-03-09 11:50:50 -05:00

76 lines
2.2 KiB
TypeScript

import React from "react";
import { Text, Title, Flex, Card, Image } from "@mantine/core";
import { useLoaderData } from "react-router";
import { IconPencil } from "@tabler/icons-react";
import { NavigateButton } from "./NavigateButton";
import { OrderSetProps, OrderSets } from "./OrderSets";
import { useUserContext } from "./UserContext";
import { TimelineList } from "./TimelineList";
export const subsListLoader = () =>
Promise.all([
fetch("/api/orders/").then((response) => response.json()),
fetch("/api/subs").then((response) => response.json()),
fetch("/api/timeline").then((response) => response.json()),
]);
interface SubsListProps {
subs: { sub_username: string; telegram_photo_url: string }[];
}
const SubsList: React.FC<SubsListProps> = ({ subs }) => (
<>
<Title order={1} mb="lg">
Subs
</Title>
<Flex gap="md" wrap="wrap">
{subs.map(({ sub_username, telegram_photo_url }) => (
<Card
key={sub_username}
shadow="sm"
padding="lg"
radius="md"
withBorder
bg="gray.2"
w="320px"
>
{telegram_photo_url ? (
<Card.Section>
<Image
src={telegram_photo_url}
height={280}
alt={`Profile picture for ${sub_username}`}
/>
</Card.Section>
) : null}
<Flex direction="column" gap="md" mt="md" h="100%">
<Text fw={500}>{sub_username}</Text>
<Flex gap="md" justify="end">
<NavigateButton to={`/orders/${sub_username}`}>
<IconPencil style={{ marginRight: "0.5rem" }} />
Edit
</NavigateButton>
</Flex>
</Flex>
</Card>
))}
</Flex>
</>
);
export const Dashboard: React.FC = () => {
const [orderSets, subs, timeline] =
useLoaderData<
[OrderSetProps["orderSets"], SubsListProps["subs"], TimelineEvent[]]
>();
const { username } = useUserContext();
return (
<>
{timeline.length > 0 ? <TimelineList timeline={timeline} /> : null}
<OrderSets orderSets={orderSets} username={username} />
{subs.length > 0 ? <SubsList subs={subs} /> : null}
</>
);
};