Merge pull request 'stockform optimization and split into components' (#92) from feature/pricebulkchanges into main

Reviewed-on: Pozomind/pozo-retail-app#92
This commit is contained in:
karthikalakshmi 2026-02-06 14:36:37 +05:30
commit ca56cced6e
8 changed files with 523 additions and 106 deletions

View File

@ -1,5 +1,4 @@
import React, { useState, useRef, useEffect } from 'react';
import { AppstoreOutlined, MailOutlined, SettingOutlined, } from '@ant-design/icons';
import { useState, useRef, useEffect } from 'react';
import { FaCaretRight } from "react-icons/fa";
import './PozoMenu.scss';
@ -8,7 +7,6 @@ const PozoMenu = ({ items = [], mode = "vertical", style = {}, onClick, collapse
const [openKeys, setOpenKeys] = useState([]);
const [selectedKey, setSelectedKey] = useState('');
const [dropdownPositions, setDropdownPositions] = useState({});
console.log(dropdownPositions, "dropdownPositions")
const [isMobile, setIsMobile] = useState(window.innerWidth <= 768);
const menuRef = useRef();
@ -115,7 +113,7 @@ const PozoMenu = ({ items = [], mode = "vertical", style = {}, onClick, collapse
// Image 2: No space on right, space on left - open to LEFT
position.left = rect.left - dropdownWidth - gap + scrollX;
position.direction = 'left';
console.log('✅ Opening LEFT - no space on right');
} else {
// Edge case: Limited space on both sides
if (spaceRight >= spaceLeft) {
@ -245,7 +243,7 @@ const PozoMenu = ({ items = [], mode = "vertical", style = {}, onClick, collapse
// Calculate position and add to dropdown positions
const position = calculatePosition(event.currentTarget, parentKeys.length);
console.log('🎯 Setting position for', itemKey, ':', position);
setDropdownPositions(prev => {
// Remove positions for closed items
@ -254,7 +252,6 @@ const PozoMenu = ({ items = [], mode = "vertical", style = {}, onClick, collapse
if (prev[key]) newPos[key] = prev[key];
});
newPos[itemKey] = position;
console.log('🎯 Updated dropdown positions:', newPos);
return newPos;
});
@ -276,11 +273,6 @@ const PozoMenu = ({ items = [], mode = "vertical", style = {}, onClick, collapse
});
}
console.log('Menu item clicked:', {
key: item.key,
keyPath: [...parentKeys, item.key],
label: item.label
});
}
};
@ -415,8 +407,6 @@ const PozoMenu = ({ items = [], mode = "vertical", style = {}, onClick, collapse
}, [items, openKeys]);
console.log(submenuRefs, "menuRef")
return (
<div
className={`pozo-menu pozo-menu-${mode}`}

View File

@ -123,38 +123,46 @@ export const postPurchaseData = createAsyncThunk(
export const getPurchaseData = createAsyncThunk(
'Stock/getPurchaseData',
async (ProdData) => {
console.log(ProdData, 'ProdData');
if (
ProdData?.CompId != null &&
ProdData?.CompId != undefined &&
ProdData?.BranchId != null &&
ProdData?.BranchId != undefined &&
ProdData?.AppId != null &&
ProdData?.AppId != undefined &&
ProdData?.OrderFromDate &&
ProdData?.OrderToDate
ProdData?.AppId != null
) {
const params = new URLSearchParams({
compId: ProdData.CompId,
branchId: ProdData.BranchId,
appId: ProdData.AppId,
fromDate: ProdData.OrderFromDate,
toDate: ProdData.OrderToDate,
});
// ✅ Add dates only if present
if (ProdData?.OrderFromDate) {
params.append('fromDate', ProdData.OrderFromDate);
}
if (ProdData?.OrderToDate) {
params.append('toDate', ProdData.OrderToDate);
}
// ✅ Search
if (ProdData?.search) {
params.append('searchText', ProdData.search);
}
// ✅ Pagination
if (ProdData?.PageNumber) {
params.append('pageNumber', ProdData.PageNumber);
}
return await axiosRetailInstanceData.get(
return axiosRetailInstanceData.get(
`/Purchase?${params.toString()}`
);
}
// optional safety
return Promise.reject('Missing required parameters');
}
);
export const putStockData = createAsyncThunk(
'Stock/postStockData',
async (putData) => {

View File

@ -0,0 +1,151 @@
import { Tooltip } from 'antd';
import { v4 as uuidv4 } from 'uuid';
const AddAllProductsButton = ({
productData = [],
purchaseData = [],
setPurchaseData,
form,
setIsLoading,
setLoadingText,
batchSize = 100,
SelectedPurcTaxType,
}) => {
// This function just returns a prepared product object, no state changes
const ProductDropDownChange = async (
VariantName,
ProdId,
option,
productsList,
extractedProduct = false,
extractedItem
) => {
const ProductData1 = (productsList || productData)?.find(
(p) => p.ProdId === ProdId && p.ProdVariantName === VariantName
);
if (!ProductData1) return null;
const DefaultVariant = ProductData1?.ProdVariantPriceDetails?.find(
(item) => item?.DefaultVariant === 'Y' && item?.ReceivedQty === 0
)?.DefaultVariant;
const qty = extractedProduct
? parseFloat(extractedItem?.parsedData?.qty) || 0
: 0;
const acceptedQty = extractedProduct
? parseFloat(extractedItem?.parsedData?.qty) || 0
: 0;
const rate = extractedProduct
? parseFloat(extractedItem?.parsedData?.rate) || 0
: 0;
return {
DefaultVariant,
ProdId: ProductData1.ProdId,
MRP: ProductData1.MRP,
ProdName: ProductData1.ProdName,
UomName: ProductData1.UomName,
SellPrice: ProductData1.SellPrice,
StockAvailable: ProductData1.StockAvailable,
OnePcsAvailable: ProductData1.OnePcsAvailable,
OnePcsPrice: ProductData1.OnePcsPrice,
NoOfPcs: ProductData1.NoOfPcs,
TaxId: ProductData1.TaxId,
TaxPercentage: ProductData1.TaxPercentage,
ProdVariantName: ProductData1.ProdVariantName,
PurchaseTax: parseFloat(extractedItem?.parsedData?.tax) || 0,
BalanceQty: qty,
InwardPrice: rate,
PurcDisc: 0,
Amount: isNaN(rate) || isNaN(acceptedQty) ? 0 : rate * acceptedQty,
WhSalePrice: 0,
ReceivedQty: qty,
AcceptedQty: acceptedQty,
RejectedQty: qty - acceptedQty,
OfferPrice: 0,
SpecialPrice: 0,
FreeItem: 0,
TaxAmt: 0,
TaxType: SelectedPurcTaxType || 0,
PurcDiscType: 'P',
refImage: extractedItem?.parsedData?.image,
PurchaseHSNCode: extractedItem?.parsedData?.hsn || '',
localId: uuidv4(),
};
};
const handleAddAll = async () => {
try {
setIsLoading(true);
setLoadingText('Adding products...');
// allow UI paint
await new Promise((r) => requestAnimationFrame(r));
const allValidProducts = [];
const allFormValues = {};
for (let i = 0; i < productData.length; i += batchSize) {
const batch = productData.slice(i, i + batchSize);
setLoadingText(
`Processing ${Math.min(i + batchSize, productData.length)} / ${
productData.length
}`
);
const batchProducts = await Promise.all(
batch.map((product) =>
ProductDropDownChange(
product.ProdVariantName,
product.ProdId,
{
label: `${product.ProdName} (${product.Size} ${product.UomName})${
product.BrandName ? ` - ${product.BrandName}` : ''
}`,
},
productData
)
)
);
const valid = batchProducts.filter(Boolean);
allValidProducts.push(...valid);
valid.forEach((p) => {
const id = p.localId;
allFormValues[`SellPrice${id}`] = p.SellPrice;
allFormValues[`PurchaseTax${id}`] = p.PurchaseTax;
allFormValues[`BalanceQty${id}`] = p.BalanceQty;
allFormValues[`ReceivedQty${id}`] = p.ReceivedQty;
allFormValues[`AcceptedQty${id}`] = p.AcceptedQty;
allFormValues[`RejectedQty${id}`] = p.RejectedQty;
allFormValues[`InwardPrice${id}`] = p.InwardPrice;
allFormValues[`Amount${id}`] = p.Amount;
});
await new Promise((r) => setTimeout(r, 0));
}
// ONE state update
setPurchaseData((prev) => [...allValidProducts, ...prev]);
// ONE form update
form?.setFieldsValue(allFormValues);
} finally {
setIsLoading(false);
setLoadingText('');
}
};
return (
<Tooltip title="Add All Products" placement="top">
<button type="button" className="addallProductTBN" onClick={handleAddAll}>
Add All
</button>
</Tooltip>
);
};
export default AddAllProductsButton;

View File

@ -0,0 +1,99 @@
import React, { useState } from 'react';
import { Tooltip } from '@mui/material';
import { IoSettingsOutline } from 'react-icons/io5';
import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx';
const SettingsIconWithModal = ({
tooltipTitle = 'Add Fields',
tableFieldPreferences = [],
selectedAdditionalColumn = [],
onSubmit,
}) => {
const [open, setOpen] = useState(false);
const [selectedFields, setSelectedFields] = useState([]);
const [tempSelectedColumns, setTempSelectedColumns] = useState([]);
const handleIconClick = () => {
// map labels values
const mappedFields = selectedAdditionalColumn
.map(
(col) =>
tableFieldPreferences.find((pref) => pref.label === col)?.value
)
.filter(Boolean);
setSelectedFields(mappedFields);
setTempSelectedColumns([...selectedAdditionalColumn]);
setOpen(true);
};
const handleCancel = () => {
setOpen(false);
setTempSelectedColumns([]);
};
const handleApply = () => {
onSubmit({
selectedFields,
tempSelectedColumns,
closeModal: () => setOpen(false),
resetTemp: () => setTempSelectedColumns([]),
});
};
return (
<>
{/* ⚙️ ICON ONLY */}
<Tooltip title={tooltipTitle} placement="left">
<IoSettingsOutline
style={{ cursor: 'pointer', fontSize: '20px' }}
onClick={handleIconClick}
/>
</Tooltip>
{/* MODAL */}
<DefaultModal
title="Select Additional Fields"
open={open}
footer
buttonText="Apply"
destroyOnClose
handleSubmit={handleApply}
handleCancel={handleCancel}
>
<div style={{ padding: '20px' }}>
{tableFieldPreferences.map((option) => (
<div key={option.value} className="Customized_QuickAdd">
<label>
<input
type="checkbox"
checked={selectedFields.includes(option.value)}
onChange={(e) => {
const checked = e.target.checked;
setSelectedFields((prev) =>
checked
? [...prev, option.value]
: prev.filter((v) => v !== option.value)
);
setTempSelectedColumns((prev) =>
checked
? [...prev, option.label]
: prev.filter((v) => v !== option.label)
);
}}
style={{ marginRight: '8px' }}
/>
{option.label}
</label>
</div>
))}
</div>
</DefaultModal>
</>
);
};
export default SettingsIconWithModal;

View File

@ -2,7 +2,7 @@ import { useState, useEffect, useRef, useCallback } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { PlusOutlined, EyeOutlined, PrinterFilled } from '@ant-design/icons';
import { Image, Pagination, Space, Table } from 'antd';
import { Image, Pagination, Space, Table, Tooltip } from 'antd';
import {
changeBreadCrumb,
getEmpAccess,
@ -59,6 +59,7 @@ import StickerPrintTemplates from '../Product/StickerTemplates.jsx';
import QRCodeCopiesModal from '../Product/QRCodeCopiesModal.jsx';
import { DatePicker } from 'antd';
import {
formatDateForAPI,
generateBarcode,
generateCodeImage,
generateQRCode,
@ -142,7 +143,6 @@ const StockList = () => {
const [selectedRecords, setSelectedRecords] = useState([]);
const [activeTab, setActiveTab] = useState('stock');
const [MultiCode, setMultiCode] = useState(true);
const [TotalCount, setTotalCount] = useState(null);
const [dateStrings, setDateStrings] = useState([
dayjs().format('YYYY-MM-DD'),
dayjs().format('YYYY-MM-DD'),
@ -233,16 +233,15 @@ const StockList = () => {
AppId: AppId,
BranchId: BranchId,
CompId: CompId,
OrderFromDate: dates?.[0] ?? '',
OrderToDate: dates?.[1] ?? '',
OrderFromDate: formatDateForAPI(dates?.[0]) ?? '',
OrderToDate: formatDateForAPI(dates?.[1]) ?? '',
PageNumber: page,
})
).unwrap();
if (Response?.data?.statusCode === 1) {
setTotalCount(Response?.data?.TotalCount);
return Response?.data?.data;
} else {
setTotalCount(0);
return [];
}
};
@ -287,17 +286,16 @@ const StockList = () => {
AppId: AppId,
BranchId: BranchId,
CompId: CompId,
OrderFromDate: dateStrings?.[0] ?? '',
OrderToDate: dateStrings?.[1] ?? '',
// OrderFromDate: dateStrings?.[0] ?? '',
// OrderToDate: dateStrings?.[1] ?? '',
search: SearchText,
})
).unwrap();
if (Response?.data?.statusCode === 1) {
setTotalCount(Response?.data?.TotalCount);
setpage(1);
return Response?.data?.data;
} else {
setTotalCount(0);
return [];
}
}
@ -703,9 +701,9 @@ const StockList = () => {
dispatch(
getSupplierData({ AppId: AppId, BranchId: BranchId, CompId: CompId })
);
dispatch(
getPurchaseData({ AppId: AppId, BranchId: BranchId, CompId: CompId })
);
// dispatch(
// getPurchaseData({ AppId: AppId, BranchId: BranchId, CompId: CompId })
// );
let ProdData = {
AppId: AppId,
@ -894,25 +892,25 @@ const StockList = () => {
PaymentAmount: PaymentAmount.toFixed(2),
InvoiceDate: groupInfo.InwardDate
? moment(groupInfo.InwardDate, 'YYYY-MM-DD').format(
'YYYY-MM-DDTHH:mm:ss'
)
'YYYY-MM-DDTHH:mm:ss'
)
: null,
SuppInvoiceNo: groupInfo.SupplierInvoiceNumber,
SuppInvoiceDate: groupInfo.SupplierInvoiceDate
? moment(groupInfo.SupplierInvoiceDate, 'YYYY-MM-DD').format(
'YYYY-MM-DDTHH:mm:ss'
)
'YYYY-MM-DDTHH:mm:ss'
)
: null,
DeliveryChallanNo: groupInfo.DeliveryChallanNo,
DeliveryInvoiceDate: groupInfo.DeliveryInvoiceDate
? moment(groupInfo.DeliveryInvoiceDate, 'YYYY-MM-DD').format(
'YYYY-MM-DDTHH:mm:ss'
)
'YYYY-MM-DDTHH:mm:ss'
)
: null,
DueDate: groupInfo.DueDate
? moment(groupInfo.DueDate, 'YYYY-MM-DD').format(
'YYYY-MM-DDTHH:mm:ss'
)
'YYYY-MM-DDTHH:mm:ss'
)
: null,
InvoiceAmount: Totalamount.toFixed(2),
TaxAmount: Totaltax.toFixed(2),
@ -930,13 +928,13 @@ const StockList = () => {
FreeQty: item.FreeQty,
ManufDate: item.ManufactureDate
? moment(item.ManufactureDate, 'YYYY-MM-DD').format(
'YYYY-MM-DDTHH:mm:ss'
)
'YYYY-MM-DDTHH:mm:ss'
)
: null,
ExpDate: item.ExpireDate
? moment(item.ExpireDate, 'YYYY-MM-DD').format(
'YYYY-MM-DDTHH:mm:ss'
)
'YYYY-MM-DDTHH:mm:ss'
)
: null,
BatchNo: item.BatchNo,
ModelNo: item.ModelNo,
@ -989,14 +987,10 @@ const StockList = () => {
const productName = checkComponent('Product Name');
setPrintProductName(productName);
};
// const ProductName = Productdata ?.map((e)=>e.ProdName+' '(+e.Size+' '+e.UomName))
const ProductName = Productdata?.map(
(e) => `${e.ProdName} (${e.Size} ${e.UomName})`
);
// const ProductName = Varientdata?.map((e)=>e.ProdName)
// const ProductName = Productdata?.map((e)=>e.ProdName)
// const ProductSize = Productdata ?.map((e)=>e.Size)
// const ProductUomName = Productdata ?.map((e)=>e.UomName)
const SupplierNames = SupplierData?.map((e) => e.SuppName);
@ -1012,33 +1006,8 @@ const StockList = () => {
const InwardDtlIds = Varientdata?.map((e) => e.InwardDtlId);
const StockProductId = Varientdata?.map((e) => e.ProdId);
// let proddetail = StockData?.map((e) => {
// return {
// ...e,
// ProdDetails: e.ProdDetails?.map((d) => ({
// ...d,
// InvoiceNo: e.InvoiceNo,
// InvoiceDate: e.InvoiceDate,
// InvoiceAmt: e.InvoiceAmount
// }))
// };
// });
// let subObjectsArray = [];
// // Iterate over mainObjects and concatenate subObjects arrays
// proddetail.forEach(obj => {
// subObjectsArray = subObjectsArray.concat(obj.ProdDetails);
// });
// function safeRound(amountStr) {
// if (amountStr == null) return allowDecimal ? '0.00' : '0';
// const cleaned = String(amountStr).replace(/[^0-9.-]+/g, '');
// const num = Number(cleaned);
// if (isNaN(num)) return allowDecimal ? '0.00' : '0';
// return allowDecimal ? num.toFixed(2) : Math.round(num).toString();
// }
const onFinish = async () => {
const template = barcodeTemplateDetails?.find(
@ -1194,7 +1163,8 @@ const StockList = () => {
? countData?.length
? countData?.length
: 0
: TotalCount;
: data?.[0]?.TotalCount;
console.log(debouncedSearchText, countData, data, "kkkk", countOfProduct)
return (
<div className="userPageTable">
<div className="userPageContent">
@ -1210,14 +1180,15 @@ const StockList = () => {
<div
className="searchAddDiv"
style={{ justifyContent: 'flex-start' }}
>
<div className="formSearch" style={{ Width: '200px' }}>
<Search
placeholder="Search by Invoice No"
onSearch={onSearch}
onSearchChange={onSearchChange}
/>
</div>
><Tooltip title="Search using Invoice No,Supp Name">
<div className="formSearch" style={{ Width: '200px' }}>
<Search
placeholder="Search by Invoice No"
onSearch={onSearch}
onSearchChange={onSearchChange}
/>
</div>
</Tooltip>
<div style={{ width: '200px' }}>
<RangePicker
placeholder={['Start Date', 'End Date']}
@ -1258,7 +1229,7 @@ const StockList = () => {
data={filteredData}
dataSource={filteredData}
onChange={handleChange}
// pagination={handlePageChange}
// pagination={handlePageChange}
/>{' '}
{countOfProduct > 10 && (
<Pagination

View File

@ -0,0 +1,16 @@
import { useRef, useCallback } from 'react';
export const useDebounce = (fn, delay = 300) => {
const timer = useRef(null);
return useCallback(
(...args) => {
if (timer.current) clearTimeout(timer.current);
timer.current = setTimeout(() => {
fn(...args);
}, delay);
},
[fn, delay]
);
};

View File

@ -0,0 +1,171 @@
import { useRef } from 'react';
import { useVirtualizer } from '@tanstack/react-virtual';
const VirtualizedTable = ({
dataSource = [],
columns = [],
rowHeight = 54,
height = '50vh',
overscan = 10,
rowKey = 'id',
}) => {
const parentRef = useRef();
const headerRef = useRef();
const rowVirtualizer = useVirtualizer({
count: dataSource.length,
getScrollElement: () => parentRef.current,
estimateSize: () => rowHeight,
overscan,
});
const handleBodyScroll = (e) => {
if (headerRef.current) {
headerRef.current.scrollLeft = e.target.scrollLeft;
}
};
const virtualItems = rowVirtualizer.getVirtualItems();
const totalSize = rowVirtualizer.getTotalSize();
return (
<div
style={{
border: '1px solid #d1d1d1',
borderRadius: '4px',
width: '100%',
overflow: 'hidden',
}}
>
{/* Header */}
<div ref={headerRef} style={{ overflowX: 'hidden', overflowY: 'hidden' }}>
<table
style={{
borderCollapse: 'collapse',
width: '100%',
tableLayout: 'auto',
}}
>
<thead style={{ background: '#2c88ee', color: '#fff' }}>
<tr className="proReceiptTD">
{columns.map((col) => (
<th
key={col.key || col.dataIndex}
style={{
padding: '10px 6px',
textAlign: col.align || 'left',
fontWeight: 600,
fontSize: '13px',
borderRight: '1px solid rgba(255,255,255,0.3)',
boxSizing: 'border-box',
width: col.width || 'auto',
minWidth: col.width || 80,
whiteSpace: 'nowrap',
}}
>
{col.title}
</th>
))}
</tr>
</thead>
</table>
</div>
{/* Body */}
<div
ref={parentRef}
onScroll={handleBodyScroll}
style={{
height,
overflowY: 'auto',
overflowX: 'auto',
position: 'relative',
scrollbarWidth: 'thin',
}}
>
<div style={{ height: `${totalSize}px`, position: 'relative' }}>
{virtualItems.map((virtualRow) => {
const record = dataSource[virtualRow.index];
const key = record?.[rowKey] || virtualRow.index;
return (
<div
className="UppertablePR"
key={key}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: `${rowHeight}px`,
transform: `translateY(${virtualRow.start}px)`,
}}
>
<table
style={{
borderCollapse: 'collapse',
width: '100%',
tableLayout: 'auto',
height: '100%',
}}
>
<tbody>
<tr
className="proReceiptTD"
style={{
backgroundColor:
virtualRow.index % 2 === 0 ? '#e2e2e2' : '#fff',
borderBottom: '1px solid #f0f0f0',
}}
>
{columns.map((col) => (
<td
className="tdProductrecipt"
key={col.key || col.dataIndex}
style={{
padding: '6px',
borderRight: '1px solid #f0f0f0',
fontSize: '12px',
fontWeight: 500,
boxSizing: 'border-box',
width: col.width || 'auto',
minWidth: col.width || 80,
textAlign: col.align || 'left',
verticalAlign: 'middle',
}}
>
{col.render
? col.render(
record?.[col.dataIndex],
record,
virtualRow.index
)
: record?.[col.dataIndex]}
</td>
))}
</tr>
</tbody>
</table>
</div>
);
})}
</div>
</div>
{dataSource.length === 0 && (
<div
style={{
textAlign: 'center',
padding: '20px',
color: '#999',
fontSize: '14px',
}}
>
No data
</div>
)}
</div>
);
};
export default VirtualizedTable;

View File

@ -36,7 +36,6 @@
}
.Product-table {
table {
border-spacing: unset;
}
@ -88,7 +87,7 @@
width: 180px !important;
}
>div:nth-child(2) {
> div:nth-child(2) {
p {
display: none !important;
}
@ -146,7 +145,7 @@
max-width: 130px !important;
}
>td:nth-child(3) {
> td:nth-child(3) {
.ant-input {
width: max-content !important;
max-width: 70px !important;
@ -154,7 +153,7 @@
}
}
>td:nth-child(5) {
> td:nth-child(5) {
.ant-input {
width: max-content !important;
max-width: 100px !important;
@ -325,12 +324,12 @@
}
.purchase-status {
>div:nth-child(1) {
> div:nth-child(1) {
display: flex;
align-items: center;
gap: 10px;
>p {
> p {
padding-bottom: 0 !important;
}
}
@ -448,7 +447,7 @@
.invoice-date {
.ant-form-item-control-input-content {
>label {
> label {
font-family: 'Poppins';
font-weight: 500;
}
@ -474,7 +473,7 @@
gap: 1rem;
margin-bottom: 10px;
>button {
> button {
font-family: 'Poppins';
background-color: #ef4444;
color: #fff;
@ -482,8 +481,8 @@
align-items: center;
.ant-btn-icon {
>span {
>svg {
> span {
> svg {
width: 13px;
height: 13px;
}
@ -566,8 +565,6 @@
width: 100%;
}
.stock-input {
// width: 100vw;
width: 100%;
@ -608,8 +605,6 @@
width: 100%;
}
.stock-input {
width: 100vw;
}
@ -781,13 +776,12 @@
}
}
.addallProductTBN {
border: none;
outline: none;
padding: 8px 16px;
width: max-content;
font-family: "Poppins";
font-family: 'Poppins';
font-weight: 500;
font-size: 14px;
cursor: pointer;
@ -822,9 +816,26 @@
}
.imeiSNTable {
.ant-input {
padding: 4px 4px !important;
text-align: center;
}
}
.proReceiptTD {
.ant-input {
width: 100% !important;
height: 35px !important;
padding: 2px !important;
text-align: center;
}
}
@media (max-width: 500px) {
.tdProductrecipt,
.proReceiptTD {
font-size: 12px !important;
}
}