File size: 8,873 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
import { ProjectData } from "@/types/project";
import { calculateCompleteness, getMissingFields } from "@/lib/projectUtils";
import { AlertCircle, CheckCircle2, X } from "lucide-react";
import { Button } from "@/components/ui/button";

interface ProjectAuditPanelProps {
  project: ProjectData;
  onClose: () => void;
}

export default function ProjectAuditPanel({ project, onClose }: ProjectAuditPanelProps) {
  const completeness = calculateCompleteness(project);
  const missingFields = getMissingFields(project);
  const missingCount = missingFields.length;
  const totalFields = 10;
  const filledCount = totalFields - missingCount;

  // Progress bar color based on completeness
  const getProgressColor = () => {
    if (completeness >= 100) return "bg-emerald-500";
    if (completeness >= 50) return "bg-blue-500";
    return "bg-red-500";
  };

  const getProgressBgColor = () => {
    if (completeness >= 100) return "bg-emerald-100";
    if (completeness >= 50) return "bg-blue-100";
    return "bg-red-100";
  };

  // Pie chart using conic gradient
  const pieChartStyle = {
    background: `conic-gradient(
      #10b981 0deg ${(completeness / 100) * 360}deg,
      #e2e8f0 ${(completeness / 100) * 360}deg 360deg
    )`,
  };

  return (
    <div className="fixed inset-0 z-50 bg-black/50 flex items-center justify-center p-4 animate-in fade-in duration-300">
      <div className="bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-y-auto animate-in slide-in-from-bottom duration-300">
        {/* Header */}
        <div className="sticky top-0 bg-white border-b border-slate-200 px-6 py-4 flex items-center justify-between">
          <div>
            <h2 className="text-2xl font-bold text-slate-800">项目审计面板</h2>
            <p className="text-sm text-slate-600 mt-1">
              {project.identity.projectName} • {project.identity.moldNumber}
            </p>
          </div>
          <Button
            variant="ghost"
            size="icon"
            onClick={onClose}
            className="h-10 w-10"
          >
            <X className="h-5 w-5" />
          </Button>
        </div>

        {/* Content */}
        <div className="p-6 space-y-6">
          {/* Completeness Overview */}
          <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
            {/* Progress Bar Section */}
            <div className="bg-slate-50 rounded-lg p-6 border border-slate-200">
              <div className="flex items-center justify-between mb-4">
                <h3 className="text-lg font-bold text-slate-700">项目完成度</h3>
                <span className="text-3xl font-bold text-slate-800">{completeness}%</span>
              </div>

              {/* Progress Bar */}
              <div className={`h-6 rounded-full ${getProgressBgColor()} overflow-hidden`}>
                <div
                  className={`h-full ${getProgressColor()} transition-all duration-500 ease-out flex items-center justify-end pr-2`}
                  style={{ width: `${completeness}%` }}
                >
                  {completeness > 10 && (
                    <span className="text-xs font-semibold text-white">
                      {filledCount}/{totalFields}
                    </span>
                  )}
                </div>
              </div>

              {/* Status Message */}
              <div className="mt-4 flex items-start gap-2">
                {completeness >= 100 ? (
                  <>
                    <CheckCircle2 className="h-5 w-5 text-emerald-600 flex-shrink-0 mt-0.5" />
                    <p className="text-sm text-slate-700">
                      <span className="font-semibold text-emerald-600">数据完整!</span> 所有必填字段已填写。
                    </p>
                  </>
                ) : completeness >= 50 ? (
                  <>
                    <AlertCircle className="h-5 w-5 text-blue-600 flex-shrink-0 mt-0.5" />
                    <p className="text-sm text-slate-700">
                      <span className="font-semibold text-blue-600">进行中</span> 还有 {missingCount} 个字段待完善。
                    </p>
                  </>
                ) : (
                  <>
                    <AlertCircle className="h-5 w-5 text-red-600 flex-shrink-0 mt-0.5" />
                    <p className="text-sm text-slate-700">
                      <span className="font-semibold text-red-600">严重数据缺口!</span> 缺失 {missingCount} 个关键字段。
                    </p>
                  </>
                )}
              </div>
            </div>

            {/* Pie Chart Section */}
            <div className="bg-slate-50 rounded-lg p-6 border border-slate-200">
              <h3 className="text-lg font-bold text-slate-700 mb-4">项目工序</h3>
              
              <div className="flex items-center justify-center gap-8">
                {/* Pie Chart */}
                <div className="relative">
                  <div
                    className="w-32 h-32 rounded-full"
                    style={pieChartStyle}
                  />
                  {/* Center Label */}
                  <div className="absolute inset-0 flex flex-col items-center justify-center">
                    <div className="w-20 h-20 bg-white rounded-full flex flex-col items-center justify-center shadow-inner">
                      <span className="text-2xl font-bold text-slate-800">{missingCount}</span>
                      <span className="text-xs text-slate-600">剩余</span>
                    </div>
                  </div>
                </div>

                {/* Legend */}
                <div className="space-y-3">
                  <div className="flex items-center gap-2">
                    <div className="w-4 h-4 rounded-full bg-emerald-500" />
                    <span className="text-sm text-slate-700">
                      已完成: <span className="font-semibold">{filledCount}</span>
                    </span>
                  </div>
                  <div className="flex items-center gap-2">
                    <div className="w-4 h-4 rounded-full bg-slate-300" />
                    <span className="text-sm text-slate-700">
                      待完成: <span className="font-semibold">{missingCount}</span>
                    </span>
                  </div>
                </div>
              </div>
            </div>
          </div>

          {/* Missing Fields Table */}
          {missingFields.length > 0 && (
            <div className="bg-red-50 border border-red-200 rounded-lg p-6">
              <h3 className="text-lg font-bold text-red-800 mb-4 flex items-center gap-2">
                <AlertCircle className="h-5 w-5" />
                缺失字段清单
              </h3>
              
              <div className="bg-white rounded-lg border border-red-200 overflow-hidden">
                <table className="w-full">
                  <thead className="bg-red-100">
                    <tr>
                      <th className="px-4 py-3 text-left text-sm font-semibold text-red-900">
                        序号
                      </th>
                      <th className="px-4 py-3 text-left text-sm font-semibold text-red-900">
                        字段名称
                      </th>
                    </tr>
                  </thead>
                  <tbody className="divide-y divide-red-100">
                    {missingFields.map((field, index) => (
                      <tr key={index} className="hover:bg-red-50 transition-colors">
                        <td className="px-4 py-3 text-sm text-slate-600">
                          {index + 1}
                        </td>
                        <td className="px-4 py-3 text-sm font-medium text-slate-800">
                          {field}
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>

              <p className="mt-4 text-sm text-red-700">
                <span className="font-semibold">提示:</span> 请尽快补充以上缺失字段,以确保项目数据完整性。
              </p>
            </div>
          )}

          {/* Success Message */}
          {missingFields.length === 0 && (
            <div className="bg-emerald-50 border border-emerald-200 rounded-lg p-6 text-center">
              <CheckCircle2 className="h-12 w-12 text-emerald-600 mx-auto mb-3" />
              <h3 className="text-lg font-bold text-emerald-800 mb-2">
                数据完整度100%
              </h3>
              <p className="text-sm text-emerald-700">
                项目所有工序已全部完成!
              </p>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}