Germinal commited on
Commit
c039555
·
verified ·
1 Parent(s): 9659d4a

Upload components/Dashboard.jsx with huggingface_hub

Browse files
Files changed (1) hide show
  1. components/Dashboard.jsx +234 -0
components/Dashboard.jsx ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState, useEffect } from 'react';
2
+ import { Bar, Pie, Line } from 'react-chartjs-2';
3
+ import { Chart as ChartJS, CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend, ArcElement, PointElement, LineElement } from 'chart.js';
4
+ import { FiBarChart2, FiPieChart, FiTrendingUp, FiUsers, FiAlertTriangle } from 'react-icons/fi';
5
+
6
+ ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend, ArcElement, PointElement, LineElement);
7
+
8
+ export default function Dashboard({ results }) {
9
+ const [activeTab, setActiveTab] = useState('overview');
10
+ const [chartData, setChartData] = useState(null);
11
+
12
+ useEffect(() => {
13
+ if (results && results.length > 0) {
14
+ const statusCounts = results.reduce((acc, agent) => {
15
+ acc[agent.status] = (acc[agent.status] || 0) + 1;
16
+ return acc;
17
+ }, {});
18
+
19
+ const positionCounts = results.reduce((acc, agent) => {
20
+ acc[agent.position] = (acc[agent.position] || 0) + 1;
21
+ return acc;
22
+ }, {});
23
+
24
+ setChartData({
25
+ status: {
26
+ labels: Object.keys(statusCounts),
27
+ datasets: [{
28
+ label: 'Status dos Agentes',
29
+ data: Object.values(statusCounts),
30
+ backgroundColor: [
31
+ 'rgba(16, 185, 129, 0.7)',
32
+ 'rgba(239, 68, 68, 0.7)',
33
+ 'rgba(245, 158, 11, 0.7)'
34
+ ],
35
+ borderColor: [
36
+ 'rgba(16, 185, 129, 1)',
37
+ 'rgba(239, 68, 68, 1)',
38
+ 'rgba(245, 158, 11, 1)'
39
+ ],
40
+ borderWidth: 1
41
+ }]
42
+ },
43
+ positions: {
44
+ labels: Object.keys(positionCounts),
45
+ datasets: [{
46
+ label: 'Cargos',
47
+ data: Object.values(positionCounts),
48
+ backgroundColor: 'rgba(59, 130, 246, 0.7)',
49
+ borderColor: 'rgba(59, 130, 246, 1)',
50
+ borderWidth: 1
51
+ }]
52
+ },
53
+ timeline: {
54
+ labels: results.map((_, i) => `Agente ${i+1}`),
55
+ datasets: [{
56
+ label: 'Análise de Risco',
57
+ data: results.map(agent => agent.riskScore || Math.random() * 100),
58
+ borderColor: 'rgba(239, 68, 68, 1)',
59
+ backgroundColor: 'rgba(239, 68, 68, 0.1)',
60
+ tension: 0.4,
61
+ fill: true
62
+ }]
63
+ }
64
+ });
65
+ }
66
+ }, [results]);
67
+
68
+ if (!results || results.length === 0) {
69
+ return (
70
+ <div className="bg-gray-50 rounded-lg p-6 text-center">
71
+ <FiAlertTriangle className="mx-auto h-12 w-12 text-gray-400 mb-4" />
72
+ <p className="text-gray-600">Nenhum dado disponível para exibir no dashboard</p>
73
+ </div>
74
+ );
75
+ }
76
+
77
+ return (
78
+ <div className="bg-white rounded-lg shadow-md p-6">
79
+ <div className="border-b border-gray-200 mb-6">
80
+ <nav className="-mb-px flex space-x-8" aria-label="Tabs">
81
+ {['overview', 'status', 'positions', 'risk'].map((tab) => (
82
+ <button
83
+ key={tab}
84
+ onClick={() => setActiveTab(tab)}
85
+ className={`${
86
+ activeTab === tab
87
+ ? 'border-primary text-primary'
88
+ : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
89
+ } whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm`}
90
+ >
91
+ {tab === 'overview' && <><FiBarChart2 className="inline mr-1" /> Visão Geral</>}
92
+ {tab === 'status' && <><FiUsers className="inline mr-1" /> Status</>}
93
+ {tab === 'positions' && <><FiPieChart className="inline mr-1" /> Cargos</>}
94
+ {tab === 'risk' && <><FiTrendingUp className="inline mr-1" /> Risco</>}
95
+ </button>
96
+ ))}
97
+ </nav>
98
+ </div>
99
+
100
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
101
+ <div className="bg-blue-50 rounded-lg p-4">
102
+ <div className="flex items-center">
103
+ <div className="bg-primary rounded-full h-10 w-10 flex items-center justify-center mr-3">
104
+ <FiUsers className="text-white" />
105
+ </div>
106
+ <div>
107
+ <p className="text-sm text-gray-600">Total de Agentes</p>
108
+ <p className="text-2xl font-bold text-gray-900">{results.length}</p>
109
+ </div>
110
+ </div>
111
+ </div>
112
+
113
+ <div className="bg-green-50 rounded-lg p-4">
114
+ <div className="flex items-center">
115
+ <div className="bg-success rounded-full h-10 w-10 flex items-center justify-center mr-3">
116
+ <FiUsers className="text-white" />
117
+ </div>
118
+ <div>
119
+ <p className="text-sm text-gray-600">Ativos</p>
120
+ <p className="text-2xl font-bold text-gray-900">
121
+ {results.filter(r => r.status === 'ativo').length}
122
+ </p>
123
+ </div>
124
+ </div>
125
+ </div>
126
+
127
+ <div className="bg-red-50 rounded-lg p-4">
128
+ <div className="flex items-center">
129
+ <div className="bg-danger rounded-full h-10 w-10 flex items-center justify-center mr-3">
130
+ <FiAlertTriangle className="text-white" />
131
+ </div>
132
+ <div>
133
+ <p className="text-sm text-gray-600">Inativos</p>
134
+ <p className="text-2xl font-bold text-gray-900">
135
+ {results.filter(r => r.status === 'inativo').length}
136
+ </p>
137
+ </div>
138
+ </div>
139
+ </div>
140
+ </div>
141
+
142
+ <div className="bg-gray-50 rounded-lg p-6">
143
+ {activeTab === 'overview' && chartData && (
144
+ <div className="space-y-6">
145
+ <div>
146
+ <h3 className="text-lg font-medium text-gray-900 mb-2">Distribuição por Status</h3>
147
+ <div className="h-64">
148
+ <Pie
149
+ data={chartData.status}
150
+ options={{
151
+ responsive: true,
152
+ maintainAspectRatio: false,
153
+ plugins: {
154
+ legend: {
155
+ position: 'right',
156
+ },
157
+ },
158
+
159
+ />
160
+ </div>
161
+ </div>
162
+ </div>
163
+ )}
164
+
165
+ {activeTab === 'status' && chartData && (
166
+ <div>
167
+ <h3 className="text-lg font-medium text-gray-900 mb-2">Status dos Agentes</h3>
168
+ <div className="h-64">
169
+ <Bar
170
+ data={chartData.status}
171
+ options={{
172
+ responsive: true,
173
+ maintainAspectRatio: false,
174
+ plugins: {
175
+ legend: {
176
+ display: false,
177
+ },
178
+ },
179
+
180
+ />
181
+ </div>
182
+ </div>
183
+ )}
184
+
185
+ {activeTab === 'positions' && chartData && (
186
+ <div>
187
+ <h3 className="text-lg font-medium text-gray-900 mb-2">Distribuição de Cargos</h3>
188
+ <div className="h-64">
189
+ <Bar
190
+ data={chartData.positions}
191
+ options={{
192
+ responsive: true,
193
+ maintainAspectRatio: false,
194
+ plugins: {
195
+ legend: {
196
+ display: false,
197
+ },
198
+ },
199
+ indexAxis: 'y',
200
+
201
+ />
202
+ </div>
203
+ </div>
204
+ )}
205
+
206
+ {activeTab === 'risk' && chartData && (
207
+ <div>
208
+ <h3 className="text-lg font-medium text-gray-900 mb-2">Análise de Risco</h3>
209
+ <div className="h-64">
210
+ <Line
211
+ data={chartData.timeline}
212
+ options={{
213
+ responsive: true,
214
+ maintainAspectRatio: false,
215
+ plugins: {
216
+ legend: {
217
+ display: false,
218
+ },
219
+ },
220
+ scales: {
221
+ y: {
222
+ beginAtZero: true,
223
+ max: 100
224
+ }
225
+ }
226
+
227
+ />
228
+ </div>
229
+ </div>
230
+ )}
231
+ </div>
232
+ </div>
233
+ );
234
+ }