feat(inventory): 統一庫存調整與調撥模組 UI,實作多選、搜尋與明細欄位重構
This commit is contained in:
@@ -15,7 +15,6 @@ import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/Components/ui/dialog";
|
||||
@@ -138,7 +137,7 @@ export default function Index({ docs, warehouses, filters }: { docs: DocsPaginat
|
||||
const { data, setData, post, processing, reset } = useForm({
|
||||
count_doc_id: null as string | null,
|
||||
warehouse_id: '',
|
||||
reason: '',
|
||||
reason: '手動調整庫存',
|
||||
remarks: '',
|
||||
});
|
||||
|
||||
@@ -375,13 +374,16 @@ export default function Index({ docs, warehouses, filters }: { docs: DocsPaginat
|
||||
|
||||
<div className="py-4 space-y-6">
|
||||
{/* Option 1: Scan/Select from Count Docs */}
|
||||
<div className="space-y-4">
|
||||
<Label className="text-sm font-semibold text-grey-700">方法一:關聯盤點單 (推薦)</Label>
|
||||
<div className="space-y-4 p-4 rounded-xl bg-primary-lightest/50 border border-primary-light/20 shadow-sm">
|
||||
<Label className="text-sm font-bold text-primary-main flex items-center gap-2">
|
||||
<ClipboardCheck className="h-4 w-4" />
|
||||
方法一:關聯盤點單 (推薦)
|
||||
</Label>
|
||||
<div className="relative">
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-grey-400" />
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-grey-3" />
|
||||
<Input
|
||||
placeholder="掃描盤點單號或搜尋..."
|
||||
className="pl-9 h-11 border-primary-100 focus:ring-primary-main"
|
||||
className="pl-9 h-9"
|
||||
value={scanSearch}
|
||||
onChange={(e) => {
|
||||
setScanSearch(e.target.value);
|
||||
@@ -390,26 +392,26 @@ export default function Index({ docs, warehouses, filters }: { docs: DocsPaginat
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="max-height-[300px] overflow-y-auto rounded-md border border-grey-100 bg-grey-50">
|
||||
<div className="max-h-[200px] overflow-y-auto rounded-lg border-2 border-grey-3 bg-white">
|
||||
{loadingPending ? (
|
||||
<div className="p-8 text-center text-sm text-grey-400">載入中...</div>
|
||||
<div className="p-8 text-center text-sm text-grey-3">載入中...</div>
|
||||
) : pendingCounts.length === 0 ? (
|
||||
<div className="p-8 text-center text-sm text-grey-400">
|
||||
查無可供盤調的盤點單 (需為已完成狀態)
|
||||
<div className="p-8 text-center text-sm text-grey-3">
|
||||
查無可供盤調的盤點單 (需為已核准狀態)
|
||||
</div>
|
||||
) : (
|
||||
<div className="divide-y divide-grey-100">
|
||||
<div className="divide-y divide-grey-4">
|
||||
{pendingCounts.map((c: any) => (
|
||||
<div
|
||||
key={c.id}
|
||||
className="p-3 hover:bg-white flex items-center justify-between cursor-pointer group transition-colors"
|
||||
className="p-3 hover:bg-primary-lightest flex items-center justify-between cursor-pointer group transition-colors"
|
||||
onClick={() => handleCreate(c.id)}
|
||||
>
|
||||
<div>
|
||||
<p className="font-bold text-grey-900 group-hover:text-primary-main">{c.doc_no}</p>
|
||||
<p className="text-xs text-grey-500">{c.warehouse_name} | 完成於: {c.completed_at}</p>
|
||||
<p className="font-bold text-grey-0 group-hover:text-primary-main">{c.doc_no}</p>
|
||||
<p className="text-xs text-grey-2">{c.warehouse_name} | 完成於: {c.completed_at}</p>
|
||||
</div>
|
||||
<Button size="sm" variant="outline" className="button-outlined-primary">
|
||||
<Button size="sm" variant="outline" className="button-outlined-primary h-7 text-xs">
|
||||
選擇並載入
|
||||
</Button>
|
||||
</div>
|
||||
@@ -419,47 +421,48 @@ export default function Index({ docs, warehouses, filters }: { docs: DocsPaginat
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 flex items-center"><span className="w-full border-t border-grey-200" /></div>
|
||||
<div className="relative flex justify-center text-xs uppercase"><span className="bg-white px-2 text-grey-400 font-medium">或</span></div>
|
||||
<div className="relative flex items-center py-2">
|
||||
<div className="flex-grow border-t border-grey-4"></div>
|
||||
<span className="flex-shrink mx-4 text-xs font-semibold text-grey-3 uppercase tracking-wider">或</span>
|
||||
<div className="flex-grow border-t border-grey-4"></div>
|
||||
</div>
|
||||
|
||||
{/* Option 2: Manual (Optional, though less common in this flow) */}
|
||||
<div className="space-y-4">
|
||||
<Label className="text-sm font-semibold text-grey-700">方法二:手動建立調整</Label>
|
||||
<div className="space-y-4 px-1">
|
||||
<Label className="text-sm font-bold text-grey-0">方法二:手動建立調整</Label>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label className="text-xs">選擇倉庫</Label>
|
||||
<Label className="text-xs font-semibold text-grey-1">選擇倉庫</Label>
|
||||
<SearchableSelect
|
||||
options={warehouses.map(w => ({ value: w.id, label: w.name }))}
|
||||
value={data.warehouse_id}
|
||||
onValueChange={(val) => setData('warehouse_id', val)}
|
||||
placeholder="選擇倉庫"
|
||||
className="h-9"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label className="text-xs">調整原因</Label>
|
||||
<Label className="text-xs font-semibold text-grey-1">調整原因</Label>
|
||||
<Input
|
||||
placeholder="例如: 報廢, 破損..."
|
||||
value={data.reason}
|
||||
onChange={(e) => setData('reason', e.target.value)}
|
||||
className="h-10"
|
||||
className="h-9"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-end gap-2 pt-2">
|
||||
<Button variant="outline" className="button-outlined-primary" onClick={() => setIsDialogOpen(false)}>取消</Button>
|
||||
<Button
|
||||
className="button-filled-primary"
|
||||
disabled={processing || !data.warehouse_id || !data.reason}
|
||||
onClick={() => handleCreate()}
|
||||
>
|
||||
新增
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter className="bg-gray-50 -mx-6 -mb-6 p-4 rounded-b-lg gap-2">
|
||||
<Button variant="outline" className="button-outlined-primary" onClick={() => setIsDialogOpen(false)}>取消</Button>
|
||||
<Button
|
||||
className="button-filled-primary"
|
||||
disabled={processing || !data.warehouse_id || !data.reason}
|
||||
onClick={() => handleCreate()}
|
||||
>
|
||||
新增
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</AuthenticatedLayout>
|
||||
|
||||
Reference in New Issue
Block a user