"use client" import { useState, useEffect } from "react" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Textarea } from "@/components/ui/textarea" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { Avatar, AvatarFallback } from "@/components/ui/avatar" import { Progress } from "@/components/ui/progress" import { Target, Plus, Edit, Trash2, TrendingUp, TrendingDown, DollarSign, Users, Activity, Zap, AlertTriangle, CheckCircle, BarChart3, Download, } from "lucide-react" // 使用真實資料庫數據 import { KPI } from '@/lib/database' // 預設 KPI 數據(當資料庫無數據時使用) const defaultKpiData = [ { id: 1, title: "營收成長率", description: "年度營收成長百分比目標", category: "financial", weight: 30, targetValue: 100, currentValue: 85, unit: "%", startDate: "2024-01-01", endDate: "2024-12-31", status: "active", owner: "陳雅雯", lastUpdated: "2024-02-10", color: "emerald", trend: "up", }, { id: 2, title: "團隊滿意度", description: "員工滿意度調查分數", category: "team", weight: 25, targetValue: 90, currentValue: 92, unit: "分", startDate: "2024-01-01", endDate: "2024-12-31", status: "active", owner: "王志明", lastUpdated: "2024-02-08", color: "blue", trend: "up", }, { id: 3, title: "市場佔有率", description: "公司在目標市場的佔有率", category: "operational", weight: 20, targetValue: 75, currentValue: 68, unit: "%", startDate: "2024-01-01", endDate: "2024-12-31", status: "active", owner: "李美玲", lastUpdated: "2024-02-05", color: "purple", trend: "down", }, { id: 4, title: "創新指數", description: "新產品開發和創新項目數量", category: "innovation", weight: 25, targetValue: 80, currentValue: 45, unit: "項", startDate: "2024-01-01", endDate: "2024-12-31", status: "at_risk", owner: "張建國", lastUpdated: "2024-02-03", color: "orange", trend: "down", }, { id: 5, title: "客戶滿意度", description: "客戶服務滿意度評分", category: "operational", weight: 20, targetValue: 95, currentValue: 88, unit: "分", startDate: "2024-01-01", endDate: "2024-12-31", status: "active", owner: "林小華", lastUpdated: "2024-02-12", color: "cyan", trend: "up", }, { id: 6, title: "成本控制率", description: "營運成本控制效率", category: "financial", weight: 15, targetValue: 85, currentValue: 78, unit: "%", startDate: "2024-01-01", endDate: "2024-12-31", status: "pending", owner: "黃大明", lastUpdated: "2024-02-01", color: "red", trend: "stable", }, ] const categoryColors = { financial: { bg: "from-emerald-50 to-green-100", border: "border-emerald-200", text: "text-emerald-700" }, team: { bg: "from-blue-50 to-cyan-100", border: "border-blue-200", text: "text-blue-700" }, operational: { bg: "from-purple-50 to-violet-100", border: "border-purple-200", text: "text-purple-700" }, innovation: { bg: "from-orange-50 to-amber-100", border: "border-orange-200", text: "text-orange-700" }, } const statusColors = { active: { bg: "bg-green-100", text: "text-green-800", border: "border-green-300" }, at_risk: { bg: "bg-red-100", text: "text-red-800", border: "border-red-300" }, pending: { bg: "bg-yellow-100", text: "text-yellow-800", border: "border-yellow-300" }, completed: { bg: "bg-blue-100", text: "text-blue-800", border: "border-blue-300" }, } function CircularProgress({ value, size = 60, color = "blue" }: { value: number; size?: number; color?: string }) { const radius = (size - 8) / 2 const circumference = 2 * Math.PI * radius const strokeDasharray = circumference const strokeDashoffset = circumference - (value / 100) * circumference const colorMap = { emerald: value >= 70 ? "#10b981" : "#ef4444", blue: value >= 70 ? "#3b82f6" : "#ef4444", purple: value >= 70 ? "#8b5cf6" : "#ef4444", orange: value >= 70 ? "#f59e0b" : "#ef4444", cyan: value >= 70 ? "#06b6d4" : "#ef4444", red: value >= 70 ? "#ef4444" : "#dc2626", } return (
{value}%
) } export default function KPIPage() { const [activeTab, setActiveTab] = useState("overview") const [isDialogOpen, setIsDialogOpen] = useState(false) const [selectedCategory, setSelectedCategory] = useState("all") const [selectedStatus, setSelectedStatus] = useState("all") const [kpiData, setKpiData] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { fetchKPIData() }, []) const fetchKPIData = async () => { try { setLoading(true) const response = await fetch('/api/kpi?userId=user_admin') if (response.ok) { const data = await response.json() setKpiData(data) } else { setKpiData(defaultKpiData as any) } } catch (error) { console.error('獲取 KPI 數據失敗:', error) setError('無法載入 KPI 數據') setKpiData(defaultKpiData as any) } finally { setLoading(false) } } // 轉換數據格式以匹配 UI 需求 const displayKpiData = kpiData.map(kpi => ({ ...kpi, currentValue: kpi.current_value, targetValue: kpi.target_value, lastUpdated: kpi.updated_at, color: kpi.category === 'financial' ? 'emerald' : kpi.category === 'team' ? 'blue' : kpi.category === 'operational' ? 'purple' : 'orange', trend: kpi.current_value >= kpi.target_value ? 'up' : 'down' })) const filteredKPIs = displayKpiData.filter((kpi) => { const categoryMatch = selectedCategory === "all" || kpi.category === selectedCategory const statusMatch = selectedStatus === "all" || kpi.status === selectedStatus return categoryMatch && statusMatch }) const kpiStats = { total: displayKpiData.length, active: displayKpiData.filter((k) => k.status === "active").length, atRisk: displayKpiData.filter((k) => k.status === "at_risk").length, completed: displayKpiData.filter((k) => k.status === "completed").length, avgProgress: Math.round( displayKpiData.reduce((acc, k) => acc + (k.currentValue / k.targetValue) * 100, 0) / displayKpiData.length, ), } return (
{/* Header */}
公司 Logo

KPI 管理中心

關鍵績效指標設定與追蹤

建立新的 KPI 設定關鍵績效指標的詳細資訊