Skip to content

Commit

Permalink
Improved demanding
Browse files Browse the repository at this point in the history
  • Loading branch information
marek-hanzal committed Jan 31, 2025
1 parent a9c116f commit 58c35d8
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const Route = createFileRoute(
amount: z.number(),
available: z.number(),
limit: z.number(),
transport: z.number(),
transport: z.number().nullish(),
}),
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export namespace DemandPanel {
amount: number;
available: number;
limit: number;
transport: number;
transport?: number | null;
}

export interface Props extends Panel.PropsEx {
Expand Down
29 changes: 4 additions & 25 deletions apps/pico/src/app/derivean/game/GameMap2/Building/Demand/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type { FC } from "react";
import { kysely } from "~/app/derivean/db/kysely";
import type { DemandPanel } from "~/app/derivean/game/GameMap2/Building/Demand/DemandPanel";
import { DemandIcon } from "~/app/derivean/icon/DemandIcon";
import { PackageIcon } from "~/app/derivean/icon/PackageIcon";

export namespace Item {
export interface Props {
Expand All @@ -31,7 +32,7 @@ export const Item: FC<Item.Props> = ({ demand }) => {
},
});

const limit = demand.limit - demand.transport - demand.available;
const limit = demand.limit - (demand.transport || 0) - demand.available;

return (
<div
Expand Down Expand Up @@ -59,9 +60,9 @@ export const Item: FC<Item.Props> = ({ demand }) => {
])}
>
<div className={"flex flex-row gap-2 items-center"}>
{demand.transport > 0 ?
{(demand.transport || 0) > 0 ?
<Icon icon={DemandIcon} />
: null}
: <Icon icon={PackageIcon} />}
<div className={"font-bold"}>{demand.name}</div>
</div>

Expand All @@ -81,28 +82,6 @@ export const Item: FC<Item.Props> = ({ demand }) => {
>
x{toHumanNumber({ number: demand.amount })}
</Badge>
{demand.limit > 0 ?
<>
<div>/</div>
<Badge
css={{
base:
demand.transport ?
[
"bg-green-50",
"border-green-400",
"hover:bg-green-50",
"hover:border-green-400",
]
: undefined,
}}
>
{toHumanNumber({
number: limit,
})}
</Badge>
</>
: null}

<Button
iconEnabled={TrashIcon}
Expand Down
132 changes: 113 additions & 19 deletions apps/pico/src/app/derivean/game/GameMap2/Inventory/Item.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,44 @@
import { zodResolver } from "@hookform/resolvers/zod";
import { useMutation } from "@tanstack/react-query";
import {
Button,
FormCss,
FormError,
FormInput,
Icon,
Modal,
onSubmit,
Progress,
toast,
TrashIcon,
Tx,
useInvalidator,
} from "@use-pico/client";
import { genId, toHumanNumber, translator, tvc } from "@use-pico/common";
import {
genId,
toHumanNumber,
translator,
tvc,
withFloatSchema,
} from "@use-pico/common";
import type { FC } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { kysely } from "~/app/derivean/db/kysely";
import type { InventoryPanel } from "~/app/derivean/game/GameMap2/Inventory/InventoryPanel";
import { DemandIcon } from "~/app/derivean/icon/DemandIcon";
import { PackageIcon } from "~/app/derivean/icon/PackageIcon";
import { SupplyIcon } from "~/app/derivean/icon/SupplyIcon";

const DemandSchema = z.object({
buildingId: z.string().min(1),
resourceId: z.string().min(1),
mapId: z.string().min(1),
userId: z.string().min(1),
amount: withFloatSchema(),
});
type DemandSchema = typeof DemandSchema;

export namespace Item {
export interface Props {
mapId: string;
Expand Down Expand Up @@ -66,12 +90,14 @@ export const Item: FC<Item.Props> = ({ mapId, userId, inventory }) => {
demandId,
mapId,
userId,
amount,
}: {
buildingId: string;
resourceId: string;
demandId?: string | null;
mapId: string;
userId: string;
amount: number;
}) {
return kysely.transaction().execute(async (tx) => {
if (demandId) {
Expand All @@ -85,7 +111,7 @@ export const Item: FC<Item.Props> = ({ mapId, userId, inventory }) => {
.where("t.targetId", "=", buildingId)
.executeTakeFirstOrThrow();

const request = inventory.limit - inventory.amount - sum;
const request = amount + (sum || 0);

if (inventory.limit > 0 && request <= 0) {
toast.error(
Expand Down Expand Up @@ -116,6 +142,21 @@ export const Item: FC<Item.Props> = ({ mapId, userId, inventory }) => {
},
});

const form = useForm<z.infer<DemandSchema>>({
resolver: zodResolver(DemandSchema),
defaultValues: {
mapId,
userId,
buildingId: inventory.buildingId,
resourceId: inventory.resourceId,
amount: inventory.limit > 0 ? inventory.limit - inventory.amount : 1,
},
});
const formTva = FormCss({
isLoading: form.formState.isLoading,
isSubmitting: form.formState.isSubmitting,
}).slots;

return (
<div
className={tvc([
Expand Down Expand Up @@ -189,24 +230,77 @@ export const Item: FC<Item.Props> = ({ mapId, userId, inventory }) => {
: <Tx label={"Supply resource (label)"} />}
</Button>

<Button
iconEnabled={inventory.demandId ? TrashIcon : DemandIcon}
loading={toggleDemandMutation.isPending}
onClick={() => {
toggleDemandMutation.mutate({
mapId,
userId,
buildingId: inventory.buildingId,
resourceId: inventory.resourceId,
demandId: inventory.demandId,
});
}}
variant={{ variant: "subtle" }}
>
{inventory.demandId ?
{inventory.demandId ?
<Button
iconEnabled={TrashIcon}
loading={toggleDemandMutation.isPending}
onClick={() => {
toggleDemandMutation.mutate({
mapId,
userId,
buildingId: inventory.buildingId,
resourceId: inventory.resourceId,
amount: 0,
/**
* Providing demandId will do the removal.
*/
demandId: inventory.demandId,
});
}}
variant={{ variant: "subtle" }}
>
<Tx label={"Cancel demand (label)"} />
: <Tx label={"Demand resource (label)"} />}
</Button>
</Button>
: <Modal
textTitle={<Tx label={"Demand resource (title)"} />}
target={
<Button
iconEnabled={DemandIcon}
variant={{ variant: "subtle" }}
>
<Tx label={"Demand resource (label)"} />
</Button>
}
css={{
modal: ["w-1/3"],
}}
>
<form
className={formTva.base()}
onSubmit={onSubmit<DemandSchema>({
form,
mutation: toggleDemandMutation,
})}
>
<FormError
variant={{ highlight: true }}
error={form.formState.errors.root}
/>

<FormInput
formState={form.formState}
name={"amount"}
label={<Tx label={"Demanded amount (label)"} />}
>
<input
type={"number"}
min={1}
max={inventory.limit - inventory.amount}
className={formTva.input()}
{...form.register("amount")}
/>
</FormInput>

<Button
iconEnabled={DemandIcon}
iconDisabled={PackageIcon}
type={"submit"}
>
<Tx label={"Submit demand (submit)"} />
</Button>
</form>
</Modal>
}
</div>
{inventory.limit > 0 ?
<Progress
Expand Down

0 comments on commit 58c35d8

Please sign in to comment.