From 7dd012f926e29da0e9b612f8536ed2590ca02956 Mon Sep 17 00:00:00 2001 From: DeepnaPooja Date: Mon, 28 Sep 2026 12:36:21 +0530 Subject: [PATCH] Add PO confirmation btutton and the status badge --- .../app/(dashboard)/sales/[id]/edit/page.tsx | 65 +++++++++++++++++-- .../sales/_components/sales-client.tsx | 17 ++--- 2 files changed, 65 insertions(+), 17 deletions(-) diff --git a/distribution_fe/app/(dashboard)/sales/[id]/edit/page.tsx b/distribution_fe/app/(dashboard)/sales/[id]/edit/page.tsx index fd9fb9c..e941765 100644 --- a/distribution_fe/app/(dashboard)/sales/[id]/edit/page.tsx +++ b/distribution_fe/app/(dashboard)/sales/[id]/edit/page.tsx @@ -16,16 +16,18 @@ import { SelectValue, } from '@/components/ui/select' import { Button } from '@/components/ui/button' +import { Badge } from '@/components/ui/badge' import { Separator } from '@/components/ui/separator' import { toast } from '@/components/ui/toast' import { shopPos as shopPosApi, items as itemsApi, priceLists as priceListsApi, + users as usersApi, getApiError, getPaginatedItems, } from '@/lib/api/index' -import type { ItemSummaryResponse, ShopPOResponse } from '@/types/api' +import type { ItemSummaryResponse, ShopPOResponse, UserResponse } from '@/types/api' const lineItemSchema = z.object({ itemId: z.string().min(1, 'Item is required'), @@ -51,6 +53,9 @@ export default function EditShopPOPage() { const [po, setPo] = useState(null) const [itemsList, setItemsList] = useState([]) const [loading, setLoading] = useState(true) + const [usersList, setUsersList] = useState([]) + const [confirmedByUserId, setConfirmedByUserId] = useState('') + const [confirming, setConfirming] = useState(false) const form = useForm({ resolver: zodResolver(schema), @@ -71,10 +76,11 @@ export default function EditShopPOPage() { ) useEffect(() => { - Promise.all([shopPosApi.get(id), itemsApi.list({ pageSize: 200 })]) - .then(([poRes, items]) => { + Promise.all([shopPosApi.get(id), itemsApi.list({ pageSize: 200 }), usersApi.list({ pageSize: 200 })]) + .then(([poRes, items, users]) => { setPo(poRes) setItemsList(getPaginatedItems(items)) + setUsersList(getPaginatedItems(users)) form.reset({ items: poRes.items .filter((i) => i.isActive) @@ -88,6 +94,20 @@ export default function EditShopPOPage() { // eslint-disable-next-line react-hooks/exhaustive-deps }, [id]) + async function handleConfirmPO() { + if (!po || !confirmedByUserId) return + setConfirming(true) + try { + const updated = await shopPosApi.confirm(po.id, confirmedByUserId) + setPo(updated) + toast.add({ title: 'Shop PO confirmed', type: 'success' }) + } catch (err) { + toast.add({ title: 'Failed to confirm Shop PO', description: getApiError(err), type: 'error' }) + } finally { + setConfirming(false) + } + } + async function resolveAndSetPrice(index: number, itemId: string) { const today = new Date().toISOString().slice(0, 10) if (po) { @@ -126,7 +146,14 @@ export default function EditShopPOPage() { Back
-

Edit Shop PO

+
+

Edit Shop PO

+ {po.confirmedAt ? ( + Confirmed + ) : ( + Unconfirmed + )} +

{po.storeName} — items can only be changed before the PO is confirmed.

@@ -136,6 +163,7 @@ export default function EditShopPOPage() { {locked && (

This Shop PO is {po.confirmedAt ? 'confirmed' : 'cancelled'} and can no longer be edited. + {po.confirmedAt && po.confirmedByName && ` Confirmed by ${po.confirmedByName}.`}

)} @@ -271,6 +299,35 @@ export default function EditShopPOPage() { Cancel
+ + {!locked && ( + <> + +

Confirm PO

+

+ Select who is confirming this PO, then confirm it. +

+
+ + +
+ + )} diff --git a/distribution_fe/app/(dashboard)/sales/_components/sales-client.tsx b/distribution_fe/app/(dashboard)/sales/_components/sales-client.tsx index 6443765..d2704bb 100644 --- a/distribution_fe/app/(dashboard)/sales/_components/sales-client.tsx +++ b/distribution_fe/app/(dashboard)/sales/_components/sales-client.tsx @@ -27,7 +27,6 @@ import { } from '@/lib/api/index' import type { ShopPOResponse, ShopPOStatus, UserResponse, RouteResponse, StoreResponse } from '@/types/api' -import { ConfirmShopPODialog } from './confirm-shop-po-dialog' import { CancelShopPODialog } from './cancel-shop-po-dialog' const ALL = '__all__' @@ -63,8 +62,6 @@ export function SalesClient() { const [shopId, setShopId] = useState('') const [confirmedFilter, setConfirmedFilter] = useState('all') - const [confirmOpen, setConfirmOpen] = useState(false) - const [selectedPO, setSelectedPO] = useState(null) const [cancelOpen, setCancelOpen] = useState(false) const [cancelPO, setCancelPO] = useState(null) @@ -124,8 +121,7 @@ export function SalesClient() { } function handleConfirm(row: ShopPOResponse) { - setSelectedPO(row) - setConfirmOpen(true) + router.push(`/sales/${row.id}/edit`) } function handleCancel(row: ShopPOResponse) { @@ -194,14 +190,15 @@ export function SalesClient() { minWidth: 160, cellRender: (row) => row.confirmedByName ? ( -
+
+ Confirmed {row.confirmedByName} {row.confirmedByRole && ( {row.confirmedByRole} )}
) : ( - — + Unconfirmed ), }, { @@ -365,12 +362,6 @@ export function SalesClient() { }} /> - setConfirmOpen(false)} - onSuccess={() => fetchData(page, pageSize)} - po={selectedPO} - /> setCancelOpen(false)}