This commit is contained in:
@@ -23,11 +23,16 @@ import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { z } from "zod";
|
||||
import { getSubscribeUnitPrice } from "./utils";
|
||||
import {
|
||||
formatCurrency,
|
||||
getSubscribeDiscounts,
|
||||
getSubscribeUnitPrice,
|
||||
} from "./utils";
|
||||
|
||||
const priceSchema = z.object({
|
||||
rule_id: z.number().min(1),
|
||||
promo_rule_id: z.number().min(1),
|
||||
subscribe_id: z.number().min(1),
|
||||
quantity: z.number().min(1),
|
||||
promo_price: z.number().min(1),
|
||||
});
|
||||
|
||||
@@ -51,26 +56,42 @@ export default function PriceForm({
|
||||
const form = useForm<PriceFormValues>({
|
||||
resolver: zodResolver(priceSchema),
|
||||
defaultValues: {
|
||||
rule_id: 0,
|
||||
promo_rule_id: 0,
|
||||
subscribe_id: 0,
|
||||
quantity: 0,
|
||||
promo_price: 0,
|
||||
},
|
||||
});
|
||||
const subscribeId = form.watch("subscribe_id");
|
||||
const quantity = form.watch("quantity");
|
||||
const subscribe = subscribes.find((item) => item.id === subscribeId);
|
||||
const discounts = getSubscribeDiscounts(subscribe);
|
||||
const unitPrice = getSubscribeUnitPrice(subscribe);
|
||||
const originalPrice = unitPrice * quantity;
|
||||
const hasSelectedSubscribe = subscribeId > 0;
|
||||
const hasDiscounts = discounts.length > 0;
|
||||
|
||||
async function handleSubmit(values: PriceFormValues) {
|
||||
if (unitPrice > 0 && values.promo_price >= unitPrice) {
|
||||
const maxPrice = unitPrice * values.quantity;
|
||||
if (maxPrice > 0 && values.promo_price >= maxPrice) {
|
||||
form.setError("promo_price", {
|
||||
message: t(
|
||||
"form.promoPriceLessThanUnitPrice",
|
||||
"Promo price must be lower than unit price"
|
||||
"form.promoPriceLessThanOriginalPrice",
|
||||
"Promo price must be lower than original price"
|
||||
),
|
||||
});
|
||||
return;
|
||||
}
|
||||
const success = await onSubmit(values);
|
||||
const success = await onSubmit({
|
||||
promo_rule_id: values.promo_rule_id,
|
||||
items: [
|
||||
{
|
||||
subscribe_id: values.subscribe_id,
|
||||
quantity: values.quantity,
|
||||
promo_price: values.promo_price,
|
||||
},
|
||||
],
|
||||
});
|
||||
if (success) setOpen(false);
|
||||
}
|
||||
|
||||
@@ -79,7 +100,12 @@ export default function PriceForm({
|
||||
<SheetTrigger asChild>
|
||||
<Button
|
||||
onClick={() => {
|
||||
form.reset({ rule_id: 0, subscribe_id: 0, promo_price: 0 });
|
||||
form.reset({
|
||||
promo_rule_id: 0,
|
||||
subscribe_id: 0,
|
||||
quantity: 0,
|
||||
promo_price: 0,
|
||||
});
|
||||
setOpen(true);
|
||||
}}
|
||||
size="sm"
|
||||
@@ -99,7 +125,7 @@ export default function PriceForm({
|
||||
>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="rule_id"
|
||||
name="promo_rule_id"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("rule", "Rule")}</FormLabel>
|
||||
@@ -126,7 +152,14 @@ export default function PriceForm({
|
||||
<FormLabel>{t("subscribe", "Subscribe")}</FormLabel>
|
||||
<FormControl>
|
||||
<Combobox<number>
|
||||
onChange={field.onChange}
|
||||
onChange={(value) => {
|
||||
field.onChange(value);
|
||||
form.setValue("quantity", 0, {
|
||||
shouldDirty: true,
|
||||
shouldValidate: true,
|
||||
});
|
||||
form.clearErrors(["quantity", "promo_price"]);
|
||||
}}
|
||||
options={subscribes
|
||||
.filter((item) => typeof item.id === "number")
|
||||
.map((item) => ({
|
||||
@@ -144,6 +177,41 @@ export default function PriceForm({
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="quantity"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("quantity", "Quantity")}</FormLabel>
|
||||
<FormControl>
|
||||
<Combobox<number>
|
||||
onChange={field.onChange}
|
||||
options={discounts.map((item) => ({
|
||||
label: `${item.quantity} x ${t(
|
||||
subscribe?.unit_time || "Month",
|
||||
subscribe?.unit_time || "Month"
|
||||
)}`,
|
||||
value: item.quantity,
|
||||
}))}
|
||||
placeholder={t(
|
||||
"form.selectQuantity",
|
||||
"Select discount quantity"
|
||||
)}
|
||||
value={field.value}
|
||||
/>
|
||||
</FormControl>
|
||||
{hasSelectedSubscribe && !hasDiscounts && (
|
||||
<p className="text-destructive text-xs">
|
||||
{t(
|
||||
"form.noDiscounts",
|
||||
"This subscribe has no discount quantities and cannot be configured."
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="promo_price"
|
||||
@@ -165,10 +233,10 @@ export default function PriceForm({
|
||||
value={field.value}
|
||||
/>
|
||||
</FormControl>
|
||||
{unitPrice > 0 && (
|
||||
{originalPrice > 0 && (
|
||||
<p className="text-muted-foreground text-xs">
|
||||
{t("unitPriceHint", "Unit price")}:{" "}
|
||||
{unitConversion("centsToDollars", unitPrice)}
|
||||
{t("originalPriceHint", "Original price")}:{" "}
|
||||
{formatCurrency(originalPrice)}
|
||||
</p>
|
||||
)}
|
||||
<FormMessage />
|
||||
@@ -178,7 +246,11 @@ export default function PriceForm({
|
||||
</form>
|
||||
</Form>
|
||||
<SheetFooter>
|
||||
<Button disabled={loading} form="promo-price-form" type="submit">
|
||||
<Button
|
||||
disabled={loading || (hasSelectedSubscribe && !hasDiscounts)}
|
||||
form="promo-price-form"
|
||||
type="submit"
|
||||
>
|
||||
{t("confirm", "Confirm")}
|
||||
</Button>
|
||||
</SheetFooter>
|
||||
|
||||
Reference in New Issue
Block a user