Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 912x 1291x 1291x 1291x 1291x 1291x 5x 3x 1291x 1291x 486x 1291x 1291x 18x 1273x 3453x 6x 6x 6x | import type React from "react";
import { useTranslation } from "react-i18next";
import { z } from "zod";
import { useTrpcMutationState } from "~app/hooks/use-trpc-mutation-state";
import { useAppForm } from "~app/utils/forms";
import { useTRPC } from "~app/utils/trpc";
import { quantitySchema, quantitySchemaDecimal } from "~app/utils/validation";
import { Spinner } from "~components/spinner";
import { Text } from "~components/text";
import { cn } from "~components/utils";
import { View } from "~components/view";
import { useActionsHooksContext, useReceiptContext } from "./context";
import { useCanEdit } from "./hooks";
import type { Item } from "./state";
type Props = {
item: Item;
isDisabled: boolean;
className?: string;
};
export const ReceiptItemQuantityInput: React.FC<Props> = ({
item,
isDisabled: isExternalDisabled,
className,
}) => {
const { t } = useTranslation("receipts");
const { receiptDisabled } = useReceiptContext();
const { updateItemQuantity } = useActionsHooksContext();
const canEdit = useCanEdit();
const form = useAppForm({
defaultValues: { value: item.quantity },
validators: { onChange: z.object({ value: quantitySchema }) },
onSubmit: ({ value }) => {
Iif (value.value === item.quantity) {
return;
}
updateItemQuantity(item.id, value.value);
},
});
const trpc = useTRPC();
const updateMutationState = useTrpcMutationState<"receiptItems.update">(
trpc.receiptItems.update.mutationKey(),
(vars) => vars.update.type === "quantity" && vars.id === item.id,
);
const isDisabled = receiptDisabled || isExternalDisabled;
if (!canEdit) {
return (
<View className="flex-row items-center gap-1">
<Text>{t("item.quantity", { quantity: item.quantity })}</Text>
</View>
);
}
return (
<form.AppField name="value">
{(field) => (
<field.NumberField
value={field.state.value}
onValueChange={field.setValue}
name={field.name}
onBlur={() => {
field.handleBlur();
Eif (!isDisabled && updateMutationState?.status !== "pending") {
void field.form.handleSubmit();
}
}}
fieldError={
field.state.meta.isDirty ? field.state.meta.errors : undefined
}
fractionDigits={quantitySchemaDecimal}
aria-label={t("item.form.quantity.label")}
mutation={updateMutationState}
isDisabled={isDisabled}
className={cn("shrink-0 basis-40", className)}
labelPlacement="outside-left"
endContent={
<View className="flex-row gap-2">
{updateMutationState?.status === "pending" ? (
<Spinner size="sm" />
) : null}
<Text>{t("item.quantityPostfix")}</Text>
</View>
}
/>
)}
</form.AppField>
);
};
|