File size: 3,842 Bytes
926b211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
 * StatsPanel - Enterprise SaaS Style
 * 
 * SINGLE SOURCE OF TRUTH: Only displays stats based on 当前节点 (Current Node)
 * 4 Cards: 全部项目 (Gray) | 超时项目 (Red) | 进行中 (Blue) | 已完成 (Green)
 */

import React from 'react';
import { ProjectStats } from '@/types/project';
import { AlertTriangle, Clock, CheckCircle2, FolderOpen } from 'lucide-react';

interface StatsPanelProps {
  stats: ProjectStats;
  onFilterChange?: (status: string) => void;
  activeFilter?: string;
}

export default function StatsPanel({ stats, onFilterChange, activeFilter = 'ALL' }: StatsPanelProps) {
  const statCards = [
    {
      label: '全部项目',
      value: stats.total,
      icon: FolderOpen,
      bgColor: 'from-slate-500/10 to-slate-500/5',
      textColor: 'text-slate-700',
      borderColor: 'border-slate-200',
      filterValue: 'ALL'
    },
    {
      label: '超时项目',
      value: stats.highRisk,
      icon: AlertTriangle,
      bgColor: 'from-red-500/10 to-red-500/5',
      textColor: 'text-red-600',
      borderColor: 'border-red-200',
      filterValue: '已超时'
    },
    {
      label: '进行中',
      value: stats.inProgress,
      icon: Clock,
      bgColor: 'from-blue-500/10 to-blue-500/5',
      textColor: 'text-blue-600',
      borderColor: 'border-blue-200',
      filterValue: '进行中'
    },
    {
      label: '已完成',
      value: stats.completed,
      icon: CheckCircle2,
      bgColor: 'from-emerald-500/10 to-emerald-500/5',
      textColor: 'text-emerald-600',
      borderColor: 'border-emerald-200',
      filterValue: '已完成'
    }
  ];

  return (
    <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-8 mb-12">
      {statCards.map((stat, index) => {
        const Icon = stat.icon;
        return (
          <button
            key={index}
            type="button"
            className="group relative cursor-pointer text-left touch-manipulation select-none"
            onClick={(e) => {
              e.preventDefault();
              e.stopPropagation();
              onFilterChange?.(stat.filterValue);
            }}
          >
            {/* Gradient background */}
            <div className={`absolute inset-0 bg-gradient-to-br ${stat.bgColor} rounded-xl`} />
            
            {/* Main card */}
            <div className={`relative backdrop-blur-sm bg-white/60 border-2 ${stat.borderColor} rounded-xl p-8 transition-all duration-300 ease-out hover:shadow-xl hover:-translate-y-1 hover:scale-105 ${
              activeFilter === stat.filterValue ? 'ring-4 ring-offset-2 ' + (stat.filterValue === 'ALL' ? 'ring-slate-300' : stat.filterValue === '已超时' ? 'ring-red-300' : stat.filterValue === '进行中' ? 'ring-blue-300' : 'ring-emerald-300') : ''
            }`}>
              <div className="flex items-start justify-between">
                <div className="space-y-3 min-w-0">
                  <p className={`text-base font-bold ${stat.textColor} tracking-wide whitespace-nowrap`}>
                    {stat.label}
                  </p>
                  <p className={`text-5xl font-bold ${stat.textColor} tabular-nums whitespace-nowrap`}>
                    {stat.value}
                  </p>
                </div>
                
                {/* Icon */}
                <div className="relative">
                  <div className={`absolute inset-0 ${stat.textColor} opacity-10 rounded-full blur-xl group-hover:opacity-20 transition-opacity duration-300`} />
                  <div className={`relative p-4 rounded-full bg-gradient-to-br ${stat.bgColor}`}>
                    <Icon className={`w-8 h-8 ${stat.textColor}`} strokeWidth={2} />
                  </div>
                </div>
              </div>
            </div>
          </button>
        );
      })}
    </div>
  );
}