Orders Pools - Improve UI
This commit is contained in:
parent
257461307e
commit
b194b19a15
5 changed files with 153 additions and 92 deletions
|
|
@ -140,6 +140,8 @@ def my_order_sets():
|
|||
'punishment_pool_name': op.punishment_pool.name if op.punishment_pool is not None else None,
|
||||
'orders': [{
|
||||
'id': order.id,
|
||||
'name': order.name,
|
||||
'weight': order.weight
|
||||
} for order in op.orders]
|
||||
}
|
||||
for op
|
||||
|
|
@ -162,6 +164,8 @@ def sub_order_sets(username, sub):
|
|||
'punishment_pool_name': op.punishment_pool.name if op.punishment_pool is not None else None,
|
||||
'orders': [{
|
||||
'id': order.id,
|
||||
'name': order.name,
|
||||
'weight': order.weight
|
||||
} for order in op.orders]
|
||||
}
|
||||
for op
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
"vite": "^5.0.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mantine/charts": "^8.3.13",
|
||||
"@mantine/core": "^8.3.12",
|
||||
"@mantine/dates": "^8.3.13",
|
||||
"@mantine/form": "^8.3.13",
|
||||
|
|
@ -23,6 +24,7 @@
|
|||
"react": "^19.2.3",
|
||||
"react-dom": "^19.2.3",
|
||||
"react-router": "^7.12.0",
|
||||
"recharts": "^3.8.0",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,11 +113,12 @@ export const OrderSet: React.FC = () => {
|
|||
}
|
||||
: {
|
||||
scheduled: false,
|
||||
time: [""],
|
||||
orders: [],
|
||||
},
|
||||
validate: {
|
||||
name: (value: string) =>
|
||||
value.length < 1 ? "Please enter a name" : null,
|
||||
!value || value.length < 1 ? "Please enter a name" : null,
|
||||
time: (value: string, values: FormOrderSet) =>
|
||||
values.scheduled && (!value || value.length < 1 || !value[0])
|
||||
? "Please set a time"
|
||||
|
|
@ -281,7 +282,7 @@ export const OrderSet: React.FC = () => {
|
|||
label="Time"
|
||||
error={form.getInputProps("time").error}
|
||||
>
|
||||
{(form.getValues().time as string[]).map((time, idx) => (
|
||||
{((form.getValues().time ?? []) as string[]).map((time, idx) => (
|
||||
<Flex key={idx} gap="xs">
|
||||
<TimeInput
|
||||
key={time}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,22 @@ import { ConfirmDialogButton } from "./ConfirmDialogButton";
|
|||
import { NavigateButton } from "./NavigateButton";
|
||||
import { Link, useFetcher } from "react-router";
|
||||
import { useUserContext } from "./UserContext";
|
||||
import { DonutChart } from "@mantine/charts";
|
||||
|
||||
const COLORS_ROTATION = [
|
||||
"teal",
|
||||
"pink",
|
||||
"lime",
|
||||
"violet",
|
||||
"orange",
|
||||
"blue",
|
||||
"yellow",
|
||||
"grape",
|
||||
"green",
|
||||
"red",
|
||||
"cyan",
|
||||
"gray",
|
||||
];
|
||||
|
||||
export interface OrderSetProps {
|
||||
orderSets: (Pick<
|
||||
|
|
@ -30,7 +46,7 @@ export interface OrderSetProps {
|
|||
| "orders"
|
||||
| "probability"
|
||||
> & {
|
||||
orders: Pick<OrderSetOrder, "id" | "name">;
|
||||
orders: Pick<OrderSetOrder, "id" | "name" | "weight">;
|
||||
punishment_pool_name: string;
|
||||
})[];
|
||||
username: string;
|
||||
|
|
@ -56,6 +72,7 @@ export const OrderSets: React.FC<OrderSetProps> = ({
|
|||
|
||||
const [isMastodonSet, setIsMastodonSet] = React.useState(true);
|
||||
React.useEffect(() => {
|
||||
if (username) {
|
||||
fetch(`/api/subs/${username}`)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
|
|
@ -63,8 +80,11 @@ export const OrderSets: React.FC<OrderSetProps> = ({
|
|||
setIsMastodonSet(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [username]);
|
||||
|
||||
const [portalRef, setPortalRef] = React.useState<HTMLElement | null>();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box mb="lg">
|
||||
|
|
@ -92,6 +112,13 @@ export const OrderSets: React.FC<OrderSetProps> = ({
|
|||
</Alert>
|
||||
</Flex>
|
||||
)}
|
||||
<div
|
||||
ref={(node) => {
|
||||
if (portalRef == null && node != null) {
|
||||
setPortalRef(node);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Flex gap="md" wrap="wrap">
|
||||
{orderSets
|
||||
? orderSets.map(
|
||||
|
|
@ -114,16 +141,23 @@ export const OrderSets: React.FC<OrderSetProps> = ({
|
|||
withBorder
|
||||
bg="gray.2"
|
||||
w="400px"
|
||||
mb="0"
|
||||
>
|
||||
<Flex direction="column" gap="md" h="100%">
|
||||
<Title order={4}>{name}</Title>
|
||||
{scheduled ? (
|
||||
<>
|
||||
<Flex gap="xs">
|
||||
<Text>Scheduled:</Text>
|
||||
<Text>
|
||||
<b>Scheduled:</b>
|
||||
</Text>
|
||||
{time.split(",").map((time) => (
|
||||
<div key={time}>
|
||||
<TimeValue key={time} value={time} format="12h" />
|
||||
<TimeValue
|
||||
key={time}
|
||||
value={time}
|
||||
format="12h"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</Flex>
|
||||
|
|
@ -135,8 +169,13 @@ export const OrderSets: React.FC<OrderSetProps> = ({
|
|||
<Badge color="blue">Weekends</Badge>
|
||||
) : null}
|
||||
<RingProgress
|
||||
size={80}
|
||||
label={<Text size="xs">{probability * 100}%</Text>}
|
||||
size={30}
|
||||
thickness={5}
|
||||
label={
|
||||
<Text size="xs" ml="lg">
|
||||
{probability * 100}%
|
||||
</Text>
|
||||
}
|
||||
sections={[
|
||||
{ color: "cyan", value: probability * 100 },
|
||||
]}
|
||||
|
|
@ -144,14 +183,26 @@ export const OrderSets: React.FC<OrderSetProps> = ({
|
|||
</Flex>
|
||||
</>
|
||||
) : null}
|
||||
<Text mb="md" flex={1}>
|
||||
Orders: {orders.length}
|
||||
<br />
|
||||
{punishment_pool_name
|
||||
? `Punishments: ${punishment_pool_name}`
|
||||
: null}
|
||||
{punishment_pool_name ? (
|
||||
<Text flex={1}>
|
||||
<b>Punishments:</b> {punishment_pool_name}
|
||||
</Text>
|
||||
<Flex gap="md" justify="end">
|
||||
) : null}
|
||||
<Flex justify="end" align="flex-end" gap="md">
|
||||
{orders.length > 0 ? (
|
||||
<DonutChart
|
||||
flex={1}
|
||||
size={130}
|
||||
thickness={30}
|
||||
data={orders.map(({ name, weight }, idx) => ({
|
||||
name,
|
||||
value: weight,
|
||||
color:
|
||||
COLORS_ROTATION[idx % COLORS_ROTATION.length],
|
||||
}))}
|
||||
tooltipDataSource="segment"
|
||||
/>
|
||||
) : null}
|
||||
<ConfirmDialogButton
|
||||
buttonColor="red.8"
|
||||
buttonText="Delete"
|
||||
|
|
@ -171,11 +222,13 @@ export const OrderSets: React.FC<OrderSetProps> = ({
|
|||
)
|
||||
: null}
|
||||
</Flex>
|
||||
</div>
|
||||
<Box my="lg">
|
||||
<NavigateButton to={`/orders/${username}/new`}>
|
||||
<IconPlus style={{ marginRight: "0.5rem" }} />
|
||||
New
|
||||
</NavigateButton>
|
||||
<Box mb="lg"></Box>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { Notifications } from "@mantine/notifications";
|
|||
import "@mantine/core/styles.css";
|
||||
import "@mantine/dates/styles.css";
|
||||
import "@mantine/notifications/styles.css";
|
||||
import "@mantine/charts/styles.css";
|
||||
|
||||
import { Dashboard, subsListLoader } from "./Dashboard";
|
||||
import { SubOrderSets, subOrderSetsLoader } from "./SubOrderSets";
|
||||
|
|
|
|||
Loading…
Reference in a new issue