Add user selection to Shop PO flow
This commit is contained in:
@@ -24,10 +24,11 @@ import {
|
||||
stores as storesApi,
|
||||
items as itemsApi,
|
||||
priceLists as priceListsApi,
|
||||
users as usersApi,
|
||||
getApiError,
|
||||
getPaginatedItems,
|
||||
} from '@/lib/api/index'
|
||||
import type { ItemSummaryResponse, StoreResponse } from '@/types/api'
|
||||
import type { ItemSummaryResponse, StoreResponse, UserResponse } from '@/types/api'
|
||||
|
||||
const lineItemSchema = z.object({
|
||||
itemId: z.string().min(1, 'Item is required'),
|
||||
@@ -37,6 +38,7 @@ const lineItemSchema = z.object({
|
||||
|
||||
const schema = z.object({
|
||||
storeId: z.string().min(1, 'Store is required'),
|
||||
raisedByUserId: z.string().min(1, 'Raised by is required'),
|
||||
items: z.array(lineItemSchema).min(1, 'At least one item is required'),
|
||||
})
|
||||
|
||||
@@ -52,12 +54,13 @@ export default function NewShopPOPage() {
|
||||
const router = useRouter()
|
||||
const [storesList, setStoresList] = useState<StoreResponse[]>([])
|
||||
const [itemsList, setItemsList] = useState<ItemSummaryResponse[]>([])
|
||||
const [usersList, setUsersList] = useState<UserResponse[]>([])
|
||||
const [priceMinByIndex, setPriceMinByIndex] = useState<Record<number, number | null>>({})
|
||||
const [priceRetailByIndex, setPriceRetailByIndex] = useState<Record<number, number | null>>({})
|
||||
|
||||
const form = useForm<FormValues>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: { storeId: '', items: [createDefaultItem()] },
|
||||
defaultValues: { storeId: '', raisedByUserId: '', items: [createDefaultItem()] },
|
||||
})
|
||||
|
||||
const { fields, append, remove } = useFieldArray({ control: form.control, name: 'items' })
|
||||
@@ -107,10 +110,12 @@ export default function NewShopPOPage() {
|
||||
Promise.all([
|
||||
storesApi.list({ pageSize: 200 }),
|
||||
itemsApi.list({ pageSize: 200 }),
|
||||
usersApi.list({ pageSize: 200 }),
|
||||
])
|
||||
.then(([stores, items]) => {
|
||||
.then(([stores, items, users]) => {
|
||||
setStoresList(getPaginatedItems(stores))
|
||||
setItemsList(getPaginatedItems(items))
|
||||
setUsersList(getPaginatedItems(users))
|
||||
})
|
||||
.catch((err) => {
|
||||
toast.add({ title: 'Failed to load reference data', description: getApiError(err), type: 'error' })
|
||||
@@ -121,6 +126,7 @@ export default function NewShopPOPage() {
|
||||
try {
|
||||
await shopPosApi.create({
|
||||
storeId: values.storeId,
|
||||
raisedByUserId: values.raisedByUserId,
|
||||
items: values.items,
|
||||
})
|
||||
toast.add({ title: 'Shop PO created', type: 'success' })
|
||||
@@ -147,27 +153,52 @@ export default function NewShopPOPage() {
|
||||
<div className="rounded-2xl border p-6">
|
||||
<h3 className="mb-4 text-sm font-medium text-foreground">Order Details</h3>
|
||||
<FieldGroup>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="storeId"
|
||||
label="Store"
|
||||
required
|
||||
render={({ field }) => (
|
||||
<Select value={field.value as string} onValueChange={field.onChange}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select store..." />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="" disabled>Select store...</SelectItem>
|
||||
{storesList.map((store) => (
|
||||
<SelectItem key={store.id} value={store.id}>
|
||||
{store.storeName} — {store.ownerName}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
<div className="grid gap-6 sm:grid-cols-2">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="storeId"
|
||||
label="Store"
|
||||
required
|
||||
render={({ field }) => (
|
||||
<Select value={field.value as string} onValueChange={field.onChange}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select store..." />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="" disabled>Select store...</SelectItem>
|
||||
{storesList.map((store) => (
|
||||
<SelectItem key={store.id} value={store.id}>
|
||||
{store.storeName} — {store.ownerName}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="raisedByUserId"
|
||||
label="Raised By"
|
||||
description="Temporary — required until auth resolves the logged-in user automatically."
|
||||
required
|
||||
render={({ field }) => (
|
||||
<Select value={field.value as string} onValueChange={field.onChange}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select user..." />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="" disabled>Select user...</SelectItem>
|
||||
{usersList.map((user) => (
|
||||
<SelectItem key={user.id} value={user.id}>
|
||||
{user.fullName}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</FieldGroup>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user