From d3cc3ffa964f188135c97f0a8d2fcb95bb5cdcf6 Mon Sep 17 00:00:00 2001 From: lucy-04 Date: Wed, 15 Jul 2026 00:05:08 +0530 Subject: [PATCH 1/2] fix: resolve preceding zeros in input fields --- src/components/ui/Input.tsx | 21 +++++++++++++++++++++ src/modules/inventory/InventoryModule.tsx | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/components/ui/Input.tsx b/src/components/ui/Input.tsx index 0d3b0bd..59feb0f 100644 --- a/src/components/ui/Input.tsx +++ b/src/components/ui/Input.tsx @@ -17,12 +17,29 @@ export const Input: React.FC = ({ rightIcon, className = '', id, + type, + value, + onChange, + onBlur, ...props }) => { const inputId = id || `input-${Math.random().toString(36).substr(2, 9)}`; const { language } = useUiStore(); const isUrdu = language === 'ur'; + const isNumber = type === 'number'; + const [buffer, setBuffer] = React.useState(null); + const displayValue = isNumber ? (buffer ?? (value === 0 || value == null ? '' : String(value))) : value; + + const handleChange = (e: React.ChangeEvent) => { + if (isNumber) setBuffer(e.target.value); // remember the literal text + onChange?.(e); // still call the parent's onChange + }; + + const handleBlur = (e: React.FocusEvent) => { + if (isNumber) setBuffer(null); // done typing → show clean number + onBlur?.(e); +}; return (
{label && ( @@ -42,6 +59,10 @@ export const Input: React.FC = ({
setStockAdjustment({ ...stockAdjustment, quantity_change: parseInt(e.target.value) || 0 })} placeholder={t("adjust_placeholder")} className="w-full" From fcdf148a23f2c461ed7f634da46c012931215b1f Mon Sep 17 00:00:00 2001 From: lucy-04 Date: Thu, 16 Jul 2026 16:11:00 +0530 Subject: [PATCH 2/2] fix/numeric inputs snap back to 0/1 and cannot be cleared while editing --- src/components/ui/Input.tsx | 9 ++++++++- .../CreateDeliveryChallanModule.tsx | 14 ++++++++------ src/modules/invoices/CreateInvoiceModule.tsx | 9 +++++---- src/modules/quotations/CreateQuotationModule.tsx | 10 ++++++++-- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/components/ui/Input.tsx b/src/components/ui/Input.tsx index 59feb0f..830fb1f 100644 --- a/src/components/ui/Input.tsx +++ b/src/components/ui/Input.tsx @@ -21,6 +21,7 @@ export const Input: React.FC = ({ value, onChange, onBlur, + onFocus, ...props }) => { const inputId = id || `input-${Math.random().toString(36).substr(2, 9)}`; @@ -39,7 +40,12 @@ export const Input: React.FC = ({ const handleBlur = (e: React.FocusEvent) => { if (isNumber) setBuffer(null); // done typing → show clean number onBlur?.(e); -}; + }; + + const handleFocus = (e: React.FocusEvent) => { + if (isNumber) e.target.select(); // highlight the whole number + onFocus?.(e); // still call any parent onFocus + }; return (
{label && ( @@ -63,6 +69,7 @@ export const Input: React.FC = ({ value={displayValue} onChange={handleChange} onBlur={handleBlur} + onFocus={handleFocus} className={` w-full h-[46px] bg-background border rounded-xl py-3 ${isUrdu ? "text-xs" : "text-sm"} transition-all outline-none focus:ring-4 diff --git a/src/modules/deliveryChallan/CreateDeliveryChallanModule.tsx b/src/modules/deliveryChallan/CreateDeliveryChallanModule.tsx index c87ea87..92cbc37 100644 --- a/src/modules/deliveryChallan/CreateDeliveryChallanModule.tsx +++ b/src/modules/deliveryChallan/CreateDeliveryChallanModule.tsx @@ -16,6 +16,7 @@ import { useTranslation } from "react-i18next"; import { CreateProductModal } from "../../components/modals/CreateProductModal"; import { CreateCustomerModal } from "../../components/modals/CreateCustomerModal"; import { useUiStore } from "../../store/uiStore"; +import { Input } from "../../components/ui/Input"; type ChallanItem = { product_id: number; @@ -41,7 +42,7 @@ export function CreateDeliveryChallanModule() { const [selectedCustomer, setSelectedCustomer] = useState(null); const [challanItems, setChallanItems] = useState([]); const [selectedProduct, setSelectedProduct] = useState(null); - const [quantity, setQuantity] = useState(1); + const [quantity, setQuantity] = useState(0); const [previewExpanded, setPreviewExpanded] = useState(false); const CUSTOM_FIELDS_KEY = 'teebot_challan_custom_fields'; @@ -167,7 +168,7 @@ export function CreateDeliveryChallanModule() { }]); } setSelectedProduct(null); - setQuantity(1); + setQuantity(0); }; const handleUpdateItemQty = (productId: number, delta: number) => { @@ -185,7 +186,7 @@ export function CreateDeliveryChallanModule() { }; const handleSetItemQty = (productId: number, newQty: number) => { - if (isNaN(newQty) || newQty < 1) return; + if (isNaN(newQty) || newQty < 0) return; setChallanItems(items => items.map(item => { if (item.product_id !== productId) return item; @@ -419,7 +420,7 @@ export function CreateDeliveryChallanModule() { /> {selectedProduct && (
- setQuantity(Number(e.target.value))} @@ -441,9 +442,10 @@ export function CreateDeliveryChallanModule() {
- handleSetItemQty(item.product_id, Number(e.target.value))} + onBlur={() => { if (item.quantity < 1) handleSetItemQty(item.product_id, 1); }} className="w-10 h-6 text-center text-[10px] font-black border-0 bg-transparent focus:ring-0" /> diff --git a/src/modules/invoices/CreateInvoiceModule.tsx b/src/modules/invoices/CreateInvoiceModule.tsx index 2a6f7d2..ff240e4 100644 --- a/src/modules/invoices/CreateInvoiceModule.tsx +++ b/src/modules/invoices/CreateInvoiceModule.tsx @@ -507,18 +507,19 @@ export function CreateInvoiceModule() {
- updateItem(idx, 'quantity', Number(e.target.value))} + onBlur={() => { if (item.quantity < 1) updateItem(idx, 'quantity', 1); }} className="w-full h-8 bg-surface border border-border rounded px-2 text-sm font-bold" />
{item.uom}
- updateItem(idx, 'unit_price', Number(e.target.value))} className="w-full h-8 bg-surface border border-border rounded px-2 text-sm font-bold" /> diff --git a/src/modules/quotations/CreateQuotationModule.tsx b/src/modules/quotations/CreateQuotationModule.tsx index fdc5e8b..621dee0 100644 --- a/src/modules/quotations/CreateQuotationModule.tsx +++ b/src/modules/quotations/CreateQuotationModule.tsx @@ -307,10 +307,16 @@ export function CreateQuotationModule() {
- { + { const newItems = [...quotationItems]; - newItems[idx].quantity = parseInt(e.target.value) || 1; + newItems[idx].quantity = parseInt(e.target.value) || 0; setQuotationItems(newItems); + }} onBlur={() => { + if (item.quantity < 1) { + const newItems = [...quotationItems]; + newItems[idx].quantity = 1; + setQuotationItems(newItems); + } }} className="w-12 text-center text-[11px] font-black tabular-nums bg-transparent outline-none" />