"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 { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { BarChart, Bar, XAxis, YAxis, CartesianGrid, ResponsiveContainer } from "recharts" import { TrendingUp, TrendingDown, Calendar, AlertTriangle, Target, Users, DollarSign, Activity, Zap, Award, } from "lucide-react" import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart" // 使用真實資料庫數據 import { KPI } from '@/lib/database' // 預設 KPI 數據(當資料庫無數據時使用) const defaultKpiData = [ { id: '1', name: "營收成長率", current_value: 85, target_value: 100, category: "financial", weight: 30, color: "emerald" }, { id: '2', name: "團隊滿意度", current_value: 92, target_value: 90, category: "team", weight: 25, color: "blue" }, { id: '3', name: "市場佔有率", current_value: 68, target_value: 75, category: "operational", weight: 20, color: "purple" }, { id: '4', name: "創新指數", current_value: 45, target_value: 80, category: "innovation", weight: 25, color: "orange" }, ] const teamRankingData = [ { name: "業務部", performance: 95, color: "#10b981" }, { name: "行銷部", performance: 88, color: "#3b82f6" }, { name: "產品部", performance: 82, color: "#8b5cf6" }, { name: "營運部", performance: 76, color: "#f59e0b" }, { name: "人資部", performance: 71, color: "#ef4444" }, ] const reviewReminders = [ { id: 1, employee: "陳雅雯", role: "業務副總", dueDate: "2024-02-15", type: "季度審查", priority: "high", color: "red", }, { id: 2, employee: "王志明", role: "技術長", dueDate: "2024-02-18", type: "一對一面談", priority: "medium", color: "yellow", }, { id: 3, employee: "李美玲", role: "行銷長", dueDate: "2024-02-20", type: "目標設定", priority: "low", color: "green", }, ] const chartConfig = { performance: { label: "Performance %", color: "hsl(var(--chart-1))", }, } function CircularProgress({ value, size = 120, color = "blue" }: { value: number; size?: number; color?: string }) { const radius = (size - 20) / 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", } return (
{value}%
) } export default function Dashboard() { const [mounted, setMounted] = useState(false) const [kpiData, setKpiData] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { setMounted(true) fetchKPIData() }, []) const fetchKPIData = async () => { try { setLoading(true) // 使用預設用戶 ID,實際應用中應該從認證系統獲取 const response = await fetch('/api/kpi?userId=user_admin') if (response.ok) { const data = await response.json() setKpiData(data) } else { // 如果 API 失敗,使用預設數據 setKpiData(defaultKpiData as any) } } catch (error) { console.error('獲取 KPI 數據失敗:', error) setError('無法載入 KPI 數據') // 使用預設數據 setKpiData(defaultKpiData as any) } finally { setLoading(false) } } if (!mounted) return null // 轉換數據格式以匹配 UI 需求 const displayKpiData = kpiData.map(kpi => ({ ...kpi, current: kpi.current_value, target: kpi.target_value, color: kpi.category === 'financial' ? 'emerald' : kpi.category === 'team' ? 'blue' : kpi.category === 'operational' ? 'purple' : 'orange' })) const underperformingKPIs = displayKpiData.filter((kpi) => kpi.current < 70) const overallScore = Math.round(displayKpiData.reduce((acc, kpi) => acc + (kpi.current * kpi.weight) / 100, 0)) return (
{/* Header */}
公司 Logo

高階主管績效管理儀表板

策略導向 KPI 管理與審查系統

= 80 ? "border-emerald-400 text-emerald-700 bg-emerald-50" : overallScore >= 60 ? "border-yellow-400 text-yellow-700 bg-yellow-50" : "border-red-400 text-red-700 bg-red-50" }`} > 整體評分: {overallScore}% CEO
{/* Performance Alerts */} {underperformingKPIs.length > 0 && ( 績效警示 {underperformingKPIs.length} 個 KPI 低於 70% 目標: {underperformingKPIs.map((kpi) => kpi.name).join(", ")} )} {/* KPI Overview Cards */}
{loading ? ( // 載入中狀態 Array.from({ length: 4 }).map((_, index) => (
)) ) : ( displayKpiData.map((kpi) => (
{kpi.name}
{kpi.category === "financial" && } {kpi.category === "team" && } {kpi.category === "operational" && } {kpi.category === "innovation" && }
目標: {kpi.target}% {kpi.current >= kpi.target ? ( ) : ( )}
= 70 ? "default" : "destructive"} className={`text-xs ${ kpi.current >= 70 ? "bg-gradient-to-r from-green-500 to-emerald-500" : "bg-gradient-to-r from-red-500 to-pink-500" }`} > 權重: {kpi.weight}%
)) )}
{/* Team Performance Ranking */}
團隊績效排名
部門績效比較
} /> entry.color} radius={[0, 8, 8, 0]} />
{/* Review Reminders */}
即將到來的審查
預定的績效審查和一對一面談
{reviewReminders.map((review) => (
{review.employee.charAt(0) || "U"}

{review.employee}

{review.role}

{review.type}

{review.dueDate}

))}
{/* Quick Actions */}
快速操作
常用管理工具
) }