new changes in api base url

This commit is contained in:
2026-07-09 15:49:45 +05:30
parent 7cd0ae85ef
commit 4ef9cd9085
29 changed files with 2714 additions and 1191 deletions

View File

@@ -58,6 +58,7 @@ export default function StoreCatalogView({ locationid, storeName = 'your store',
const [view, setView] = useState<'catalogue' | 'inventory' | 'requests'>('catalogue');
const [search, setSearch] = useState('');
const [selectedCategories, setSelectedCategories] = useState<string[]>([]);
const [requestDate, setRequestDate] = useState(() => new Date().toISOString().split('T')[0]);
const [stockHealthFilter, setStockHealthFilter] = useState<string[]>([]);
const [selectedProduct, setSelectedProduct] = useState<any>(null);
const [hoveredProduct, setHoveredProduct] = useState<any>(null);
@@ -82,7 +83,7 @@ export default function StoreCatalogView({ locationid, storeName = 'your store',
[storeCat.items],
);
const stockRequestsQ = useFiestaGetStockRequests({ tenantid, locationid: locationid ?? 0, pagesize: 500 });
const stockRequestsQ = useFiestaGetStockRequests({ tenantid, locationid: locationid ?? 0, pagesize: 500, date: requestDate });
const [picks, setPicks] = useState<Record<string, { qty: number; status: 'Pending' | 'Approved' | 'Rejected' | 'Cancelled' | 'Received'; requestedAt: string; resolvedAt?: string }>>({});
useEffect(() => {
@@ -108,43 +109,45 @@ export default function StoreCatalogView({ locationid, storeName = 'your store',
const togglePick = (id: string) => {
setNotice(false);
setPicks((prev) => {
const next = { ...prev };
if (next[id] != null && next[id].status !== 'Cancelled') {
next[id] = { ...next[id], status: 'Cancelled', resolvedAt: new Date().toISOString() };
} else {
next[id] = { qty: 1, status: 'Pending', requestedAt: new Date().toISOString() };
createRequestMutation.mutate({
tenantid,
locationid: locationid ?? FIESTA_PRIMARY_LOCATION_ID,
productid: Number(id),
qty: 1,
status: 'Pending'
});
}
return next;
});
const existing = picks[id];
if (existing != null && existing.status !== 'Cancelled') {
setPicks(prev => ({ ...prev, [id]: { ...prev[id], status: 'Cancelled', resolvedAt: new Date().toISOString() } }));
} else {
setPicks(prev => ({ ...prev, [id]: { qty: 1, status: 'Pending', requestedAt: new Date().toISOString() } }));
createRequestMutation.mutate({
tenantid,
locationid: locationid ?? FIESTA_PRIMARY_LOCATION_ID,
productid: Number(id),
qty: 1,
status: 'Pending',
locationname: storeName
});
}
};
const setPickQty = (id: string, qty: number) => setPicks((prev) => {
const existing = prev[id] || {};
const setPickQty = (id: string, qty: number) => {
const safeQty = Math.max(1, Math.round(qty) || 1);
setPicks((prev) => {
const existing = prev[id] || {};
return {
...prev,
[id]: {
...existing,
qty: safeQty,
status: 'Pending',
requestedAt: new Date().toISOString()
}
};
});
createRequestMutation.mutate({
tenantid,
locationid: locationid ?? FIESTA_PRIMARY_LOCATION_ID,
productid: Number(id),
qty: safeQty,
status: 'Pending'
status: 'Pending',
locationname: storeName
});
return {
...prev,
[id]: {
...existing,
qty: safeQty,
status: 'Pending',
requestedAt: new Date().toISOString()
}
};
});
};
const pickCount = Object.keys(picks).length;
// Store inventory (live stock) for the "My Store Inventory" tab + "In Store" tags.
@@ -512,7 +515,21 @@ export default function StoreCatalogView({ locationid, storeName = 'your store',
{/* ── My Requests ── */}
{view === 'requests' && (
Object.keys(picks).length === 0 ? (
<div className="flex flex-col gap-4">
<div className="flex items-center justify-end bg-white px-4 py-3 rounded-2xl border border-slate-200 shadow-sm">
<div className="flex items-center gap-3">
<label htmlFor="requestDate" className="text-sm font-bold text-slate-500">Date:</label>
<input
type="date"
id="requestDate"
value={requestDate}
onChange={(e) => setRequestDate(e.target.value)}
className="px-3 py-1.5 border border-slate-200 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 text-sm font-medium text-slate-700 bg-slate-50"
/>
</div>
</div>
{(!stockRequestsQ.data || stockRequestsQ.data.length === 0) ? (
<CenterState
icon={<Inbox size={34} />}
title="No stock requested yet"
@@ -524,45 +541,48 @@ export default function StoreCatalogView({ locationid, storeName = 'your store',
<table className="w-full text-left border-collapse" style={{ minWidth: 800 }}>
<thead>
<tr className="bg-slate-50/80 border-b border-slate-200">
{['Requested At', 'Product', 'Qty', 'Status', 'Resolved At', ''].map((h, i) => (
{['Requested At', 'Store', 'Product', 'Qty', 'Status', 'Resolved At', ''].map((h, i) => (
<th key={i} className="px-5 py-4 text-[10px] font-black uppercase tracking-widest text-slate-500 whitespace-nowrap">{h}</th>
))}
</tr>
</thead>
<tbody className="divide-y divide-slate-100">
{Object.entries(picks).map(([pid, data]: [string, any]) => {
const prod = products.find(p => p.id === pid);
{(stockRequestsQ.data || []).map((data: any) => {
const pid = String(data.productid);
const prod = products.find(p => String(p.id) === pid);
const isApproved = data.status === 'Approved';
const isRejected = data.status === 'Rejected';
const isCancelled = data.status === 'Cancelled';
return (
<tr key={pid} className="transition-all duration-200 hover:bg-slate-50/80 group">
<tr key={data.requestid} className="transition-all duration-200 hover:bg-slate-50/80 group">
<td className="px-5 py-4 whitespace-nowrap">
<div className="flex flex-col">
<span className="text-sm font-semibold text-slate-900">
{data.requestedAt ? new Date(data.requestedAt).toLocaleDateString('en-IN', { day: 'numeric', month: 'short' }) : '—'}
{data.created ? new Date(data.created).toLocaleDateString('en-IN', { day: 'numeric', month: 'short' }) : '—'}
</span>
<span className="text-xs font-medium text-slate-500">
{data.requestedAt ? new Date(data.requestedAt).toLocaleTimeString('en-IN', { hour: '2-digit', minute: '2-digit' }) : ''}
{data.created ? new Date(data.created).toLocaleTimeString('en-IN', { hour: '2-digit', minute: '2-digit' }) : ''}
</span>
</div>
</td>
<td className="px-5 py-4 whitespace-nowrap">
<div className="inline-flex items-center gap-2 px-3 py-1.5 rounded-lg bg-indigo-50/50 text-indigo-700 border border-indigo-100/50">
<Store size={14} className="text-indigo-500" />
<span className="font-bold text-xs">{storeName}</span>
</div>
</td>
<td className="px-5 py-4">
<div className="flex items-center gap-3">
{prod ? (
<>
<div className="relative w-10 h-10 rounded-xl overflow-hidden border border-slate-200 bg-white shadow-sm shrink-0 group-hover:shadow transition-shadow">
<img src={prod.image} alt={prod.name} className="w-full h-full object-cover" />
<img src={data.productimage || prod?.image || PLACEHOLDER} alt={data.productname || prod?.name || 'Product'} className="w-full h-full object-cover" />
</div>
<div className="min-w-0 flex-1">
<p className="font-bold text-sm text-slate-900 truncate group-hover:text-indigo-700 transition-colors">{prod.name}</p>
<p className="text-xs font-medium text-slate-500 truncate mt-0.5">{prod.sku}</p>
<p className="font-bold text-sm text-slate-900 truncate group-hover:text-indigo-700 transition-colors">{data.productname || prod?.name}</p>
<p className="text-xs font-medium text-slate-500 truncate mt-0.5">{prod?.sku || `SKU-${data.productid}`}</p>
</div>
</>
) : (
<span className="text-xs text-slate-400">Product Not Found ({pid})</span>
)}
</div>
</td>
<td className="px-5 py-4 whitespace-nowrap">
@@ -588,7 +608,7 @@ export default function StoreCatalogView({ locationid, storeName = 'your store',
</td>
<td className="px-5 py-4 whitespace-nowrap">
<span className="text-xs font-medium text-slate-500">
{data.resolvedAt ? new Date(data.resolvedAt).toLocaleString('en-IN', { dateStyle: 'medium', timeStyle: 'short' }) : '—'}
{data.updated ? new Date(data.updated).toLocaleString('en-IN', { dateStyle: 'medium', timeStyle: 'short' }) : '—'}
</span>
</td>
<td className="px-5 py-4 whitespace-nowrap text-right">
@@ -599,7 +619,7 @@ export default function StoreCatalogView({ locationid, storeName = 'your store',
updateRequestMutation.mutate({
tenantid,
locationid: locationid ?? FIESTA_PRIMARY_LOCATION_ID,
productid: Number(pid),
productid: Number(data.productid),
requestid: data.requestid,
status: 'Received'
});
@@ -612,12 +632,13 @@ export default function StoreCatalogView({ locationid, storeName = 'your store',
</td>
</tr>
);
})}
</tbody>
</table>
})}
</tbody>
</table>
</div>
</div>
</div>
)
)}
</div>
)}
{/* ── My Store Inventory ── */}