feat: 更新庫存報表、銷售匯入及採購單相關功能
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
|
||||
import { Head, Link, router } from '@inertiajs/react';
|
||||
import { Button } from '@/Components/ui/button';
|
||||
import { Plus, Search, FileText, RotateCcw, Calendar, ChevronDown, ChevronUp } from 'lucide-react';
|
||||
import { Plus, Search, FileText, RotateCcw, Calendar } from 'lucide-react';
|
||||
import { Input } from '@/Components/ui/input';
|
||||
import { Label } from '@/Components/ui/label';
|
||||
import { SearchableSelect } from '@/Components/ui/searchable-select';
|
||||
@@ -49,9 +49,7 @@ export default function GoodsReceiptIndex({ receipts, filters, warehouses }: Pro
|
||||
const [dateRangeType, setDateRangeType] = useState('custom');
|
||||
|
||||
// Advanced Filter Toggle
|
||||
const [showAdvanced, setShowAdvanced] = useState(
|
||||
!!(filters.date_start || filters.date_end)
|
||||
);
|
||||
|
||||
|
||||
// Sync filters from props
|
||||
useEffect(() => {
|
||||
@@ -149,55 +147,12 @@ export default function GoodsReceiptIndex({ receipts, filters, warehouses }: Pro
|
||||
</div>
|
||||
|
||||
{/* Filter Bar */}
|
||||
<div className="bg-white p-5 rounded-lg shadow-sm border border-gray-200 mb-6">
|
||||
{/* Row 1: Search, Status, Warehouse */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-12 gap-4 mb-4">
|
||||
<div className="md:col-span-4 space-y-1">
|
||||
<Label className="text-xs font-medium text-grey-1">關鍵字搜尋</Label>
|
||||
<div className="relative">
|
||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" />
|
||||
<Input
|
||||
placeholder="搜尋單號..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
className="pl-10 h-9 block"
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleFilter()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-4 space-y-1">
|
||||
<Label className="text-xs font-medium text-grey-1">狀態</Label>
|
||||
<Select value={status} onValueChange={setStatus}>
|
||||
<SelectTrigger className="h-9">
|
||||
<SelectValue placeholder="選擇狀態" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{statusOptions.map(opt => (
|
||||
<SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-4 space-y-1">
|
||||
<Label className="text-xs font-medium text-grey-1">倉庫</Label>
|
||||
<SearchableSelect
|
||||
value={warehouseId}
|
||||
onValueChange={setWarehouseId}
|
||||
options={warehouseOptions}
|
||||
placeholder="選擇倉庫"
|
||||
className="w-full h-9"
|
||||
showSearch={warehouses.length > 10}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Row 2: Date Filters (Collapsible) */}
|
||||
{showAdvanced && (
|
||||
<div className="grid grid-cols-1 md:grid-cols-12 gap-4 items-end animate-in fade-in slide-in-from-top-2 duration-200">
|
||||
<div className="md:col-span-6 space-y-2">
|
||||
<Label className="text-xs font-medium text-grey-1">快速時間區間</Label>
|
||||
<div className="bg-white rounded-xl shadow-sm border border-grey-4 p-5 mb-6">
|
||||
<div className="space-y-4">
|
||||
{/* Row 1: Date Range & Quick Buttons */}
|
||||
<div className="flex flex-col lg:flex-row gap-4 lg:items-end">
|
||||
<div className="flex-none space-y-2">
|
||||
<Label className="text-xs font-medium text-grey-2">快速時間區間</Label>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{[
|
||||
{ label: "今日", value: "today" },
|
||||
@@ -222,8 +177,9 @@ export default function GoodsReceiptIndex({ receipts, filters, warehouses }: Pro
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-6">
|
||||
<div className="grid grid-cols-2 gap-4 items-end">
|
||||
{/* Date Inputs */}
|
||||
<div className="w-full lg:flex-1">
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs text-grey-2 font-medium">開始日期</Label>
|
||||
<div className="relative">
|
||||
@@ -257,45 +213,71 @@ export default function GoodsReceiptIndex({ receipts, filters, warehouses }: Pro
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex items-center justify-end border-t border-gray-100 pt-5 gap-3 mt-4">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setShowAdvanced(!showAdvanced)}
|
||||
className="mr-auto text-gray-500 hover:text-gray-900 h-9"
|
||||
>
|
||||
{showAdvanced ? (
|
||||
<>
|
||||
<ChevronUp className="h-4 w-4 mr-1" />
|
||||
收合篩選
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<ChevronDown className="h-4 w-4 mr-1" />
|
||||
進階篩選
|
||||
{(dateStart || dateEnd) && (
|
||||
<span className="ml-2 w-2 h-2 rounded-full bg-primary-main" />
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={handleReset}
|
||||
className="flex items-center gap-2 button-outlined-primary h-9"
|
||||
>
|
||||
<RotateCcw className="h-4 w-4" />
|
||||
重置
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleFilter}
|
||||
className="flex items-center gap-2 button-filled-primary h-9 px-6"
|
||||
>
|
||||
<Search className="h-4 w-4" />
|
||||
查詢
|
||||
</Button>
|
||||
{/* Row 2: Filters & Actions */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-12 gap-4 items-end">
|
||||
{/* Search */}
|
||||
<div className="md:col-span-4 space-y-1">
|
||||
<Label className="text-xs font-medium text-grey-1">關鍵字搜尋</Label>
|
||||
<div className="relative">
|
||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" />
|
||||
<Input
|
||||
placeholder="搜尋單號..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
className="pl-10 h-9 block"
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleFilter()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Status */}
|
||||
<div className="md:col-span-2 space-y-1">
|
||||
<Label className="text-xs font-medium text-grey-1">狀態</Label>
|
||||
<Select value={status} onValueChange={setStatus}>
|
||||
<SelectTrigger className="h-9">
|
||||
<SelectValue placeholder="選擇狀態" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{statusOptions.map(opt => (
|
||||
<SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
{/* Warehouse */}
|
||||
<div className="md:col-span-3 space-y-1">
|
||||
<Label className="text-xs font-medium text-grey-1">倉庫</Label>
|
||||
<SearchableSelect
|
||||
value={warehouseId}
|
||||
onValueChange={setWarehouseId}
|
||||
options={warehouseOptions}
|
||||
placeholder="選擇倉庫"
|
||||
className="w-full h-9"
|
||||
showSearch={warehouses.length > 10}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Actions */}
|
||||
<div className="md:col-span-3 flex items-center justify-end gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={handleReset}
|
||||
className="flex-1 flex items-center justify-center gap-2 button-outlined-primary h-9"
|
||||
>
|
||||
<RotateCcw className="h-4 w-4" />
|
||||
重置
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleFilter}
|
||||
className="flex-1 flex items-center justify-center gap-2 button-filled-primary h-9"
|
||||
>
|
||||
<Search className="h-4 w-4" />
|
||||
查詢
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user