Files
star-erp/resources/js/Pages/Dashboard.tsx

212 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
import { Link, Head } from '@inertiajs/react';
import { cn } from "@/lib/utils";
import {
Package,
Users,
ShoppingCart,
Warehouse as WarehouseIcon,
AlertTriangle,
Clock,
TrendingUp,
ChevronRight
} from 'lucide-react';
interface Stats {
productsCount: number;
vendorsCount: number;
purchaseOrdersCount: number;
warehousesCount: number;
totalInventoryValue: number;
pendingOrdersCount: number;
lowStockCount: number;
}
interface Props {
stats: Stats;
}
export default function Dashboard({ stats }: Props) {
const cardData = [
{
label: '商品總數',
value: stats.productsCount,
icon: <Package className="h-6 w-6 text-[#01ab83]" />,
description: '目前系統中的商品種類',
color: 'bg-[#01ab83]/10',
},
{
label: '合作廠商',
value: stats.vendorsCount,
icon: <Users className="h-6 w-6 text-blue-600" />,
description: '已建立資料的供應商',
color: 'bg-blue-50',
},
{
label: '採購單據',
value: stats.purchaseOrdersCount,
icon: <ShoppingCart className="h-6 w-6 text-purple-600" />,
description: '歷年累計採購單數量',
color: 'bg-purple-50',
},
{
label: '倉庫站點',
value: stats.warehousesCount,
icon: <WarehouseIcon className="h-6 w-6 text-orange-600" />,
description: '目前營運中的倉庫環境',
color: 'bg-orange-50',
},
];
const alertData = [
{
label: '待處理採購單',
value: stats.pendingOrdersCount,
icon: <Clock className="h-5 w-5" />,
status: stats.pendingOrdersCount > 0 ? 'warning' : 'normal',
},
{
label: '低庫存警示',
value: stats.lowStockCount,
icon: <AlertTriangle className="h-5 w-5" />,
status: stats.lowStockCount > 0 ? 'error' : 'normal',
},
];
return (
<AuthenticatedLayout>
<Head title="控制台 - 小小冰室 ERP" />
<div className="p-8 max-w-7xl mx-auto">
<div className="mb-8">
<h1 className="text-2xl font-bold text-grey-0 flex items-center gap-2">
<TrendingUp className="h-6 w-6 text-[#01ab83]" />
</h1>
<p className="text-gray-500 mt-1"> ERP </p>
</div>
{/* 主要數據卡片 */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-10">
{cardData.map((card, index) => (
<div key={index} className="bg-white p-6 rounded-2xl border border-grey-4 shadow-sm hover:shadow-md transition-shadow">
<div className="flex items-start justify-between mb-4">
<div className={`p-3 rounded-xl ${card.color}`}>
{card.icon}
</div>
<span className="text-xs font-medium text-grey-3 bg-grey-5 px-2 py-1 rounded-full border border-grey-4">
</span>
</div>
<div>
<h3 className="text-grey-2 text-sm font-medium mb-1">{card.label}</h3>
<div className="flex items-baseline gap-2">
<span className="text-2xl font-bold text-grey-0">{card.value}</span>
</div>
<p className="text-xs text-grey-3 mt-2">{card.description}</p>
</div>
</div>
))}
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{/* 警示與通知 */}
<div className="lg:col-span-1 space-y-6">
<h2 className="text-xl font-bold text-grey-0 flex items-center gap-2">
<TrendingUp className="h-5 w-5 text-[#01ab83]" />
</h2>
<div className="bg-white rounded-2xl border border-grey-4 shadow-sm divide-y divide-grey-4">
{alertData.map((alert, index) => (
<div key={index} className="p-6 flex items-center justify-between group cursor-pointer hover:bg-background-light transition-colors">
<div className="flex items-center gap-4">
<div className={cn(
"p-2 rounded-lg",
alert.status === 'error' ? "bg-red-50 text-red-600" :
alert.status === 'warning' ? "bg-amber-50 text-amber-600" : "bg-grey-5 text-grey-2"
)}>
{alert.icon}
</div>
<div>
<p className="text-sm font-medium text-grey-1">{alert.label}</p>
<p className="text-xs text-grey-3"></p>
</div>
</div>
<div className="flex items-center gap-2">
<span className={cn(
"text-lg font-bold",
alert.status === 'error' ? "text-red-600" :
alert.status === 'warning' ? "text-amber-600" : "text-grey-1"
)}>
{alert.value}
</span>
<ChevronRight className="h-4 w-4 text-grey-4 group-hover:translate-x-1 transition-transform" />
</div>
</div>
))}
</div>
<div className="bg-primary/5 rounded-2xl p-6 border border-primary/10">
<h4 className="text-sm font-bold text-primary mb-2"></h4>
<p className="text-xs text-grey-1 leading-relaxed">
</p>
</div>
</div>
{/* 快速捷徑 */}
<div className="lg:col-span-2 space-y-6">
<h2 className="text-xl font-bold text-grey-0"></h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<Link href="/products" className="group h-full">
<div className="bg-white p-6 rounded-2xl border border-grey-4 shadow-sm hover:border-[#01ab83] transition-all h-full flex flex-col justify-between">
<div>
<h3 className="font-bold text-grey-0 mb-1 group-hover:text-[#01ab83]"></h3>
<p className="text-sm text-grey-2"></p>
</div>
<div className="mt-4 flex items-center text-xs font-bold text-[#01ab83] group-hover:gap-2 transition-all">
<ChevronRight className="h-3 w-3" />
</div>
</div>
</Link>
<Link href="/purchase-orders" className="group h-full">
<div className="bg-white p-6 rounded-2xl border border-grey-4 shadow-sm hover:border-purple-500 transition-all h-full flex flex-col justify-between">
<div>
<h3 className="font-bold text-grey-0 mb-1 group-hover:text-purple-600"></h3>
<p className="text-sm text-grey-2"></p>
</div>
<div className="mt-4 flex items-center text-xs font-bold text-purple-600 group-hover:gap-2 transition-all">
<ChevronRight className="h-3 w-3" />
</div>
</div>
</Link>
<Link href="/vendors" className="group h-full">
<div className="bg-white p-6 rounded-2xl border border-grey-4 shadow-sm hover:border-blue-500 transition-all h-full flex flex-col justify-between">
<div>
<h3 className="font-bold text-grey-0 mb-1 group-hover:text-blue-600"></h3>
<p className="text-sm text-grey-2"></p>
</div>
<div className="mt-4 flex items-center text-xs font-bold text-blue-600 group-hover:gap-2 transition-all">
<ChevronRight className="h-3 w-3" />
</div>
</div>
</Link>
<Link href="/warehouses" className="group h-full">
<div className="bg-white p-6 rounded-2xl border border-grey-4 shadow-sm hover:border-orange-500 transition-all h-full flex flex-col justify-between">
<div>
<h3 className="font-bold text-grey-0 mb-1 group-hover:text-orange-600"></h3>
<p className="text-sm text-grey-2"></p>
</div>
<div className="mt-4 flex items-center text-xs font-bold text-orange-600 group-hover:gap-2 transition-all">
<ChevronRight className="h-3 w-3" />
</div>
</div>
</Link>
</div>
</div>
</div>
</div>
</AuthenticatedLayout>
);
}