188 lines
6.1 KiB
TypeScript
188 lines
6.1 KiB
TypeScript
import AppInput from "../AppInput";
|
||
import discountRed from "../../assets/icons/product/discount-red.svg";
|
||
import tomanBlack from "../../assets/icons/product/tomanBlack.svg";
|
||
import tomanGray from "../../assets/icons/product/tomanGray.svg";
|
||
import { RadioGroup, RadioGroupItem } from "../ui/radio-group";
|
||
import { useState, useEffect } from "react";
|
||
import { formatPrice, getPersianTextOfPrice } from "../../utils/helpers";
|
||
import { useRootData } from "~/hooks/use-root-data";
|
||
import { Percent } from "lucide-react";
|
||
|
||
interface PricingFormProps {
|
||
productPrice: string;
|
||
finalPrice: string;
|
||
onPriceChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||
onFinalPriceChange: (finalPrice: string) => void;
|
||
}
|
||
|
||
export const PricingForm: React.FC<PricingFormProps> = ({
|
||
productPrice,
|
||
onPriceChange,
|
||
finalPrice,
|
||
onFinalPriceChange,
|
||
}: PricingFormProps) => {
|
||
const { theme } = useRootData();
|
||
const [hasDiscount, setHasDiscount] = useState("");
|
||
const [discountPercent, setDiscountPercent] = useState("");
|
||
const [discountAmount, setDiscountAmount] = useState("");
|
||
|
||
useEffect(() => {
|
||
if (!productPrice || !hasDiscount) {
|
||
onFinalPriceChange(productPrice || "");
|
||
return;
|
||
}
|
||
|
||
let finalPrice = parseInt(productPrice);
|
||
|
||
if (discountPercent) {
|
||
finalPrice = finalPrice * (1 - parseInt(discountPercent) / 100);
|
||
} else if (discountAmount) {
|
||
finalPrice = finalPrice - parseInt(discountAmount);
|
||
}
|
||
if (finalPrice < 0) {
|
||
finalPrice = 0;
|
||
} else if (finalPrice > 1000000000) {
|
||
finalPrice = 1000000000;
|
||
}
|
||
onFinalPriceChange(finalPrice.toFixed(0).toString());
|
||
}, [
|
||
productPrice,
|
||
hasDiscount,
|
||
discountPercent,
|
||
discountAmount,
|
||
onFinalPriceChange,
|
||
]);
|
||
|
||
// وقتی discount percent تغییر کرد، discount amount را خالی کن
|
||
const handleDiscountPercentChange = (
|
||
e: React.ChangeEvent<HTMLInputElement>
|
||
) => {
|
||
setDiscountPercent(e.target.value);
|
||
setDiscountAmount("");
|
||
};
|
||
|
||
// وقتی discount amount تغییر کرد، discount percent را خالی کن
|
||
const handleDiscountAmountChange = (
|
||
e: React.ChangeEvent<HTMLInputElement>
|
||
) => {
|
||
setDiscountAmount(e.target.value);
|
||
setDiscountPercent("");
|
||
};
|
||
|
||
return (
|
||
<div className="flex flex-col gap-6 p-6 bg-WHITE rounded-lg border border-WHITE2">
|
||
{/* قیمت اصلی */}
|
||
<div className="space-y-4">
|
||
<AppInput
|
||
inputTitle="قیمت اصلی:"
|
||
inputValue={productPrice}
|
||
inputPlaceholder=""
|
||
inputIcon={theme === "dark" ? tomanGray : tomanBlack}
|
||
inputOnChange={onPriceChange}
|
||
inputDir="ltr"
|
||
/>
|
||
</div>
|
||
|
||
{/* Radio buttons for جدید/ندارد */}
|
||
<div className="flex flex-col gap-4 w-full border rounded-xl p-4">
|
||
<div className="flex items-center gap-6">
|
||
<div className="flex items-center gap-2">
|
||
<img src={discountRed} alt="discount" />
|
||
<span className="text-R14">تخفیف:</span>
|
||
</div>
|
||
<RadioGroup
|
||
onValueChange={(value) => {
|
||
setHasDiscount(value);
|
||
if (!value) {
|
||
setDiscountPercent("");
|
||
setDiscountAmount("");
|
||
}
|
||
}}
|
||
value={hasDiscount}
|
||
className="flex gap-4 px-4"
|
||
dir="rtl"
|
||
>
|
||
<RadioGroupItem
|
||
value={"true"}
|
||
id={`withDiscount`}
|
||
className="size-5"
|
||
/>
|
||
<label htmlFor={`withDiscount`} className="flex flex-col gap-1">
|
||
<p className="text-R14">دارد</p>
|
||
</label>
|
||
<RadioGroupItem
|
||
value={""}
|
||
id={`withoutDiscount`}
|
||
className="size-5"
|
||
/>
|
||
<label htmlFor={`withoutDiscount`} className="flex flex-col gap-1">
|
||
<p className="text-R14">ندارد</p>
|
||
</label>
|
||
</RadioGroup>
|
||
</div>
|
||
<div className="space-y-4">
|
||
<div className="flex gap-4">
|
||
<p className="text-R14 text-GRAY text-center leading-[48px]">
|
||
مقدار تخفیف:{" "}
|
||
</p>
|
||
<div className="flex-1 flex flex-col gap-1 justify-center">
|
||
<AppInput
|
||
disabled={!hasDiscount}
|
||
inputTitle=""
|
||
inputValue={discountPercent}
|
||
inputIcon={hasDiscount ? Percent : undefined}
|
||
inputPlaceholder=""
|
||
inputOnChange={handleDiscountPercentChange}
|
||
inputDir="ltr"
|
||
type="number"
|
||
/>
|
||
</div>
|
||
{/* <div>This is an dummy text for testing code rabbit</div> */}
|
||
<p className="text-R12 text-GRAY text-center leading-[48px]">یا</p>
|
||
<div className="flex-1">
|
||
<AppInput
|
||
disabled={!hasDiscount}
|
||
inputTitle=""
|
||
inputValue={discountAmount}
|
||
inputIcon={
|
||
!hasDiscount
|
||
? theme === "dark"
|
||
? tomanBlack
|
||
: tomanGray
|
||
: theme === "dark"
|
||
? tomanGray
|
||
: tomanBlack
|
||
}
|
||
type="number"
|
||
inputPlaceholder=""
|
||
inputOnChange={handleDiscountAmountChange}
|
||
inputDir="ltr"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* قیمت بعد از تخفیف */}
|
||
<div className="mt-4">
|
||
<AppInput
|
||
disabled={true}
|
||
inputTitle="قیمت بعد از تخفیف:"
|
||
inputValue={finalPrice ? formatPrice(finalPrice) : ""}
|
||
inputIcon={theme === "dark" ? tomanGray : tomanBlack}
|
||
inputPlaceholder=""
|
||
inputOnChange={() => {}}
|
||
inputDir="ltr"
|
||
/>
|
||
</div>
|
||
{finalPrice && (
|
||
<div className="mt-2 text-sm text-BLACK2 text-right">
|
||
{getPersianTextOfPrice(finalPrice)}
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* تخفیف section */}
|
||
</div>
|
||
);
|
||
};
|