diff --git a/client/src/components/parts-order-modal/parts-order-modal-price-change.component.jsx b/client/src/components/parts-order-modal/parts-order-modal-price-change.component.jsx index aa6ef3384..dc613245b 100644 --- a/client/src/components/parts-order-modal/parts-order-modal-price-change.component.jsx +++ b/client/src/components/parts-order-modal/parts-order-modal-price-change.component.jsx @@ -1,94 +1,121 @@ import { DownOutlined } from "@ant-design/icons"; -import { Dropdown, InputNumber, Space } from "antd"; +import { Button, Divider, Dropdown, InputNumber, Space, theme } from "antd"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; import { logImEXEvent } from "../../firebase/firebase.utils"; +const DISCOUNT_PRESETS = [5, 10, 15, 20, 25, 40]; + export default function PartsOrderModalPriceChange({ form, field }) { const { t } = useTranslation(); - const menu = { - items: [ - { - key: "5", - label: t("parts_orders.labels.discount", { percent: "5%" }) - }, - { - key: "10", - label: t("parts_orders.labels.discount", { percent: "10%" }) - }, - { - key: "15", - label: t("parts_orders.labels.discount", { percent: "15%" }) - }, - { - key: "20", - label: t("parts_orders.labels.discount", { percent: "20%" }) - }, - { - key: "25", - label: t("parts_orders.labels.discount", { percent: "25%" }) - }, - { - key: "40", - label: t("parts_orders.labels.discount", { percent: "40%" }) - }, - { - key: "custom", - label: ( - - e.stopPropagation()} - onKeyUp={(e) => { - if (e.key === "Enter") { - const values = form.getFieldsValue(); - const { parts_order_lines } = values; + const { token } = theme.useToken(); - form.setFieldsValue({ - parts_order_lines: { - data: parts_order_lines.data.map((p, idx) => { - if (idx !== field.name) return p; - console.log(p, e.target.value, (p.act_price || 0) * ((100 - (e.target.value || 0)) / 100)); - return { - ...p, - act_price: (p.act_price || 0) * ((100 - (e.target.value || 0)) / 100) - }; - }) - } - }); - e.target.value = 0; - } - }} - min={0} - max={100} - /> - % - - ) + const [open, setOpen] = useState(false); + const [customPercent, setCustomPercent] = useState(0); + + const applyDiscountPercent = (percent) => { + const pct = Number(percent) || 0; + + const values = form.getFieldsValue(); + const parts_order_lines = values?.parts_order_lines; + const data = Array.isArray(parts_order_lines?.data) ? parts_order_lines.data : []; + if (!data.length) return; + + form.setFieldsValue({ + parts_order_lines: { + data: data.map((p, idx) => { + if (idx !== field.name) return p; + return { + ...p, + act_price: (p.act_price || 0) * ((100 - pct) / 100) + }; + }) } - ], + }); + }; + + const applyCustom = () => { + logImEXEvent("parts_order_manual_discount", {}); + applyDiscountPercent(customPercent); + setCustomPercent(0); + setOpen(false); + }; + + const menu = { + // Kill the menu “card” styling so our wrapper becomes the single card. + style: { + background: "transparent", + boxShadow: "none" + }, + items: DISCOUNT_PRESETS.map((pct) => ({ + key: String(pct), + label: t("parts_orders.labels.discount", { percent: `${pct}%` }) + })), onClick: ({ key }) => { logImEXEvent("parts_order_manual_discount", {}); - if (key === "custom") return; - const values = form.getFieldsValue(); - const { parts_order_lines } = values; - form.setFieldsValue({ - parts_order_lines: { - data: parts_order_lines.data.map((p, idx) => { - if (idx !== field.name) return p; - return { - ...p, - act_price: (p.act_price || 0) * ((100 - key) / 100) - }; - }) - } - }); + applyDiscountPercent(key); + setOpen(false); } }; return ( - + setOpen(nextOpen)} + getPopupContainer={(triggerNode) => triggerNode?.parentElement ?? document.body} + popupRender={(menus) => ( +
e.stopPropagation()} + onKeyDown={(e) => e.stopPropagation()} + > + {menus} + + + +
+ + (v === null || v === undefined ? "" : `${v}%`)} + parser={(v) => + String(v ?? "") + .replace("%", "") + .trim() + } + onChange={(v) => setCustomPercent(v ?? 0)} + onKeyDown={(e) => { + e.stopPropagation(); + if (e.key === "Enter") { + e.preventDefault(); + applyCustom(); + } + }} + /> + + +
+
+ )} + > - % - + %
); diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 8d44f02f1..af14320db 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -1288,6 +1288,7 @@ "vehicle": "Vehicle" }, "labels": { + "apply": "Apply", "actions": "Actions", "areyousure": "Are you sure?", "barcode": "Barcode", diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index d91462672..5c7a31350 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -1288,6 +1288,7 @@ "vehicle": "" }, "labels": { + "apply": "", "actions": "Comportamiento", "areyousure": "", "barcode": "código de barras", diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index 9542b4b16..e74e06bf0 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -1288,6 +1288,7 @@ "vehicle": "" }, "labels": { + "apply": "", "actions": "actes", "areyousure": "", "barcode": "code à barre",