dandydow commited on
Commit
6f0f303
·
verified ·
1 Parent(s): e9d115c

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +1576 -19
  3. prompts.txt +2 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Dashmaster
3
- emoji: 🌖
4
- colorFrom: blue
5
- colorTo: green
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: dashmaster
3
+ emoji: 🐳
4
+ colorFrom: purple
5
+ colorTo: gray
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,1576 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="pt-BR">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Painel de Controle Inteligente</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
9
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
10
+ <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
11
+ <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
12
+ <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
13
+ <style>
14
+ .dark {
15
+ --bg-primary: #1a1a2e;
16
+ --bg-secondary: #16213e;
17
+ --text-primary: #e6e6e6;
18
+ --text-secondary: #b8b8b8;
19
+ --accent: #4f46e5;
20
+ }
21
+
22
+ .light {
23
+ --bg-primary: #f8fafc;
24
+ --bg-secondary: #ffffff;
25
+ --text-primary: #1e293b;
26
+ --text-secondary: #64748b;
27
+ --accent: #4f46e5;
28
+ }
29
+
30
+ body {
31
+ background-color: var(--bg-primary);
32
+ color: var(--text-primary);
33
+ transition: all 0.3s ease;
34
+ }
35
+
36
+ .sidebar {
37
+ background-color: var(--bg-secondary);
38
+ border-right: 1px solid rgba(255, 255, 255, 0.1);
39
+ }
40
+
41
+ .card {
42
+ background-color: var(--bg-secondary);
43
+ border: 1px solid rgba(255, 255, 255, 0.1);
44
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
45
+ }
46
+
47
+ .card:hover {
48
+ transform: translateY(-2px);
49
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2);
50
+ }
51
+
52
+ .usage-bar {
53
+ height: 4px;
54
+ position: absolute;
55
+ bottom: 0;
56
+ left: 0;
57
+ border-radius: 0 0 0.375rem 0.375rem;
58
+ }
59
+
60
+ .terminal {
61
+ font-family: 'Courier New', monospace;
62
+ background-color: #1e1e1e;
63
+ color: #f8f8f2;
64
+ }
65
+
66
+ .blink {
67
+ animation: blink 1s step-end infinite;
68
+ }
69
+
70
+ @keyframes blink {
71
+ from, to { opacity: 1; }
72
+ 50% { opacity: 0; }
73
+ }
74
+
75
+ .container-status {
76
+ border-left-width: 4px;
77
+ }
78
+
79
+ .container-status.running {
80
+ border-left-color: #10b981;
81
+ }
82
+
83
+ .container-status.stopped {
84
+ border-left-color: #ef4444;
85
+ }
86
+
87
+ .container-status.restarting {
88
+ border-left-color: #f59e0b;
89
+ }
90
+ </style>
91
+ </head>
92
+ <body class="dark">
93
+ <div id="root"></div>
94
+
95
+ <script type="text/babel">
96
+ const { useState, useEffect } = React;
97
+
98
+ // Componentes principais
99
+ const App = () => {
100
+ const [darkMode, setDarkMode] = useState(true);
101
+ const [activeSection, setActiveSection] = useState('dashboard');
102
+ const [vpsList, setVpsList] = useState([]);
103
+ const [botList, setBotList] = useState([]);
104
+ const [contentList, setContentList] = useState([]);
105
+ const [user, setUser] = useState({
106
+ name: 'Admin',
107
+ role: 'admin',
108
+ email: 'admin@painel.com'
109
+ });
110
+ const [notifications, setNotifications] = useState([]);
111
+ const [showAddVpsModal, setShowAddVpsModal] = useState(false);
112
+ const [showAddBotModal, setShowAddBotModal] = useState(false);
113
+ const [showAddContentModal, setShowAddContentModal] = useState(false);
114
+ const [terminalOutput, setTerminalOutput] = useState([]);
115
+
116
+ // Dados mockados
117
+ useEffect(() => {
118
+ // Mock VPS data
119
+ setVpsList([
120
+ {
121
+ id: 1,
122
+ name: 'Servidor Principal',
123
+ ip: '192.168.1.100',
124
+ status: 'online',
125
+ cpu: 45,
126
+ memory: 65,
127
+ storage: 30,
128
+ containers: 5,
129
+ lastUpdated: new Date()
130
+ },
131
+ {
132
+ id: 2,
133
+ name: 'Servidor de Backup',
134
+ ip: '192.168.1.101',
135
+ status: 'offline',
136
+ cpu: 0,
137
+ memory: 0,
138
+ storage: 0,
139
+ containers: 0,
140
+ lastUpdated: new Date(Date.now() - 86400000)
141
+ }
142
+ ]);
143
+
144
+ // Mock Bot data
145
+ setBotList([
146
+ {
147
+ id: 1,
148
+ name: 'Bot de Notícias',
149
+ type: 'scraping',
150
+ status: 'running',
151
+ lastRun: new Date(),
152
+ nextRun: new Date(Date.now() + 3600000),
153
+ logs: ['Iniciado às 10:00', 'Coletou 15 notícias']
154
+ },
155
+ {
156
+ id: 2,
157
+ name: 'Bot de Redes Sociais',
158
+ type: 'social',
159
+ status: 'stopped',
160
+ lastRun: new Date(Date.now() - 86400000),
161
+ nextRun: null,
162
+ logs: ['Parado pelo usuário']
163
+ }
164
+ ]);
165
+
166
+ // Mock Content data
167
+ setContentList([
168
+ {
169
+ id: 1,
170
+ title: 'Análise do Mercado de IA em 2023',
171
+ source: 'Google News',
172
+ status: 'approved',
173
+ created: new Date(),
174
+ published: new Date(),
175
+ author: 'Sistema de IA'
176
+ },
177
+ {
178
+ id: 2,
179
+ title: 'Novas Tendências em Desenvolvimento Web',
180
+ source: 'Tech Blogs',
181
+ status: 'pending',
182
+ created: new Date(),
183
+ published: null,
184
+ author: 'Sistema de IA'
185
+ }
186
+ ]);
187
+
188
+ // Mock notifications
189
+ setNotifications([
190
+ {
191
+ id: 1,
192
+ message: 'Novo conteúdo aguardando aprovação',
193
+ type: 'content',
194
+ read: false,
195
+ date: new Date()
196
+ },
197
+ {
198
+ id: 2,
199
+ message: 'Servidor de Backup está offline',
200
+ type: 'vps',
201
+ read: false,
202
+ date: new Date(Date.now() - 3600000)
203
+ }
204
+ ]);
205
+
206
+ // Mock terminal output
207
+ setTerminalOutput([
208
+ { id: 1, text: 'Bem-vindo ao Terminal do Painel de Controle', type: 'system' },
209
+ { id: 2, text: 'Digite "help" para ver os comandos disponíveis', type: 'system' }
210
+ ]);
211
+ }, []);
212
+
213
+ const toggleDarkMode = () => {
214
+ setDarkMode(!darkMode);
215
+ document.body.classList.toggle('dark');
216
+ document.body.classList.toggle('light');
217
+ };
218
+
219
+ const executeCommand = (command) => {
220
+ const newOutput = [
221
+ ...terminalOutput,
222
+ { id: terminalOutput.length + 1, text: `$ ${command}`, type: 'command' },
223
+ { id: terminalOutput.length + 2, text: 'Comando executado com sucesso', type: 'response' }
224
+ ];
225
+ setTerminalOutput(newOutput);
226
+ };
227
+
228
+ const renderSection = () => {
229
+ switch (activeSection) {
230
+ case 'dashboard':
231
+ return <DashboardSection
232
+ vpsList={vpsList}
233
+ botList={botList}
234
+ contentList={contentList}
235
+ notifications={notifications}
236
+ />;
237
+ case 'vps':
238
+ return <VpsSection
239
+ vpsList={vpsList}
240
+ setShowAddVpsModal={setShowAddVpsModal}
241
+ executeCommand={executeCommand}
242
+ terminalOutput={terminalOutput}
243
+ />;
244
+ case 'bots':
245
+ return <BotsSection
246
+ botList={botList}
247
+ setShowAddBotModal={setShowAddBotModal}
248
+ />;
249
+ case 'content':
250
+ return <ContentSection
251
+ contentList={contentList}
252
+ setShowAddContentModal={setShowAddContentModal}
253
+ />;
254
+ case 'settings':
255
+ return <SettingsSection
256
+ user={user}
257
+ darkMode={darkMode}
258
+ toggleDarkMode={toggleDarkMode}
259
+ />;
260
+ default:
261
+ return <DashboardSection
262
+ vpsList={vpsList}
263
+ botList={botList}
264
+ contentList={contentList}
265
+ notifications={notifications}
266
+ />;
267
+ }
268
+ };
269
+
270
+ return (
271
+ <div className="flex h-screen overflow-hidden">
272
+ {/* Sidebar */}
273
+ <Sidebar
274
+ activeSection={activeSection}
275
+ setActiveSection={setActiveSection}
276
+ user={user}
277
+ notifications={notifications}
278
+ />
279
+
280
+ {/* Main Content */}
281
+ <div className="flex-1 overflow-auto">
282
+ {/* Header */}
283
+ <Header
284
+ activeSection={activeSection}
285
+ darkMode={darkMode}
286
+ toggleDarkMode={toggleDarkMode}
287
+ user={user}
288
+ setShowAddVpsModal={setShowAddVpsModal}
289
+ setShowAddBotModal={setShowAddBotModal}
290
+ setShowAddContentModal={setShowAddContentModal}
291
+ />
292
+
293
+ {/* Main Content */}
294
+ <main className="p-6">
295
+ {renderSection()}
296
+ </main>
297
+ </div>
298
+
299
+ {/* Modals */}
300
+ {showAddVpsModal && (
301
+ <AddVpsModal
302
+ setShowAddVpsModal={setShowAddVpsModal}
303
+ setVpsList={setVpsList}
304
+ />
305
+ )}
306
+
307
+ {showAddBotModal && (
308
+ <AddBotModal
309
+ setShowAddBotModal={setShowAddBotModal}
310
+ setBotList={setBotList}
311
+ />
312
+ )}
313
+
314
+ {showAddContentModal && (
315
+ <AddContentModal
316
+ setShowAddContentModal={setShowAddContentModal}
317
+ setContentList={setContentList}
318
+ />
319
+ )}
320
+ </div>
321
+ );
322
+ };
323
+
324
+ // Componentes de layout
325
+ const Sidebar = ({ activeSection, setActiveSection, user, notifications }) => {
326
+ const unreadNotifications = notifications.filter(n => !n.read).length;
327
+
328
+ return (
329
+ <div className="sidebar w-64 flex-shrink-0 flex flex-col">
330
+ <div className="p-4 border-b border-gray-700 flex items-center justify-between">
331
+ <h1 className="text-xl font-bold text-white flex items-center">
332
+ <i className="fas fa-robot text-indigo-500 mr-2"></i>
333
+ <span>Painel AI</span>
334
+ </h1>
335
+ </div>
336
+
337
+ <div className="flex-1 overflow-y-auto">
338
+ <nav className="p-4">
339
+ <div className="mb-6">
340
+ <h3 className="text-xs uppercase font-semibold text-gray-400 mb-3">GERAL</h3>
341
+ <ul>
342
+ <li className="mb-2">
343
+ <button
344
+ onClick={() => setActiveSection('dashboard')}
345
+ className={`w-full text-left flex items-center p-2 rounded-lg ${activeSection === 'dashboard' ? 'bg-indigo-500/20 text-indigo-400' : 'hover:bg-gray-700'}`}
346
+ >
347
+ <i className="fas fa-tachometer-alt mr-3"></i>
348
+ Dashboard
349
+ </button>
350
+ </li>
351
+ </ul>
352
+ </div>
353
+
354
+ <div className="mb-6">
355
+ <h3 className="text-xs uppercase font-semibold text-gray-400 mb-3">GERENCIAMENTO</h3>
356
+ <ul>
357
+ <li className="mb-2">
358
+ <button
359
+ onClick={() => setActiveSection('vps')}
360
+ className={`w-full text-left flex items-center p-2 rounded-lg ${activeSection === 'vps' ? 'bg-indigo-500/20 text-indigo-400' : 'hover:bg-gray-700'}`}
361
+ >
362
+ <i className="fas fa-server mr-3"></i>
363
+ VPS
364
+ </button>
365
+ </li>
366
+ <li className="mb-2">
367
+ <button
368
+ onClick={() => setActiveSection('bots')}
369
+ className={`w-full text-left flex items-center p-2 rounded-lg ${activeSection === 'bots' ? 'bg-indigo-500/20 text-indigo-400' : 'hover:bg-gray-700'}`}
370
+ >
371
+ <i className="fas fa-robot mr-3"></i>
372
+ Bots
373
+ </button>
374
+ </li>
375
+ <li className="mb-2">
376
+ <button
377
+ onClick={() => setActiveSection('content')}
378
+ className={`w-full text-left flex items-center p-2 rounded-lg ${activeSection === 'content' ? 'bg-indigo-500/20 text-indigo-400' : 'hover:bg-gray-700'}`}
379
+ >
380
+ <i className="fas fa-newspaper mr-3"></i>
381
+ Conteúdo
382
+ {unreadNotifications > 0 && (
383
+ <span className="ml-auto bg-red-500 text-white text-xs px-2 py-1 rounded-full">
384
+ {unreadNotifications}
385
+ </span>
386
+ )}
387
+ </button>
388
+ </li>
389
+ </ul>
390
+ </div>
391
+
392
+ <div className="mb-6">
393
+ <h3 className="text-xs uppercase font-semibold text-gray-400 mb-3">CONFIGURAÇÕES</h3>
394
+ <ul>
395
+ <li className="mb-2">
396
+ <button
397
+ onClick={() => setActiveSection('settings')}
398
+ className={`w-full text-left flex items-center p-2 rounded-lg ${activeSection === 'settings' ? 'bg-indigo-500/20 text-indigo-400' : 'hover:bg-gray-700'}`}
399
+ >
400
+ <i className="fas fa-cog mr-3"></i>
401
+ Configurações
402
+ </button>
403
+ </li>
404
+ </ul>
405
+ </div>
406
+ </nav>
407
+ </div>
408
+
409
+ <div className="p-4 border-t border-gray-700">
410
+ <div className="flex items-center justify-between">
411
+ <div className="flex items-center">
412
+ <div className="w-10 h-10 rounded-full bg-indigo-500 flex items-center justify-center">
413
+ <i className="fas fa-user text-white"></i>
414
+ </div>
415
+ <div className="ml-3">
416
+ <p className="text-sm font-medium">{user.name}</p>
417
+ <p className="text-xs text-gray-400">{user.role}</p>
418
+ </div>
419
+ </div>
420
+ <button className="text-gray-400 hover:text-white">
421
+ <i className="fas fa-sign-out-alt"></i>
422
+ </button>
423
+ </div>
424
+ </div>
425
+ </div>
426
+ );
427
+ };
428
+
429
+ const Header = ({
430
+ activeSection,
431
+ darkMode,
432
+ toggleDarkMode,
433
+ user,
434
+ setShowAddVpsModal,
435
+ setShowAddBotModal,
436
+ setShowAddContentModal
437
+ }) => {
438
+ const sectionTitles = {
439
+ dashboard: 'Dashboard',
440
+ vps: 'Gerenciamento de VPS',
441
+ bots: 'Controle de Bots',
442
+ content: 'Gestão de Conteúdo',
443
+ settings: 'Configurações'
444
+ };
445
+
446
+ const handleAddNew = () => {
447
+ switch (activeSection) {
448
+ case 'vps':
449
+ setShowAddVpsModal(true);
450
+ break;
451
+ case 'bots':
452
+ setShowAddBotModal(true);
453
+ break;
454
+ case 'content':
455
+ setShowAddContentModal(true);
456
+ break;
457
+ default:
458
+ break;
459
+ }
460
+ };
461
+
462
+ return (
463
+ <header className="bg-gray-800 border-b border-gray-700 p-4 flex justify-between items-center">
464
+ <h2 className="text-xl font-semibold">{sectionTitles[activeSection]}</h2>
465
+
466
+ <div className="flex items-center space-x-4">
467
+ <div className="relative">
468
+ <i className="fas fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
469
+ <input
470
+ type="text"
471
+ placeholder="Pesquisar..."
472
+ className="bg-gray-700 border border-gray-600 rounded-lg pl-10 pr-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500"
473
+ />
474
+ </div>
475
+
476
+ <button
477
+ onClick={toggleDarkMode}
478
+ className="text-gray-400 hover:text-white p-2"
479
+ >
480
+ {darkMode ? (
481
+ <i className="fas fa-sun"></i>
482
+ ) : (
483
+ <i className="fas fa-moon"></i>
484
+ )}
485
+ </button>
486
+
487
+ {(activeSection === 'vps' || activeSection === 'bots' || activeSection === 'content') && (
488
+ <button
489
+ onClick={handleAddNew}
490
+ className="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg flex items-center"
491
+ >
492
+ <i className="fas fa-plus mr-2"></i>
493
+ Adicionar
494
+ </button>
495
+ )}
496
+ </div>
497
+ </header>
498
+ );
499
+ };
500
+
501
+ // Componentes de seção
502
+ const DashboardSection = ({ vpsList, botList, contentList, notifications }) => {
503
+ const onlineVps = vpsList.filter(vps => vps.status === 'online').length;
504
+ const runningBots = botList.filter(bot => bot.status === 'running').length;
505
+ const pendingContent = contentList.filter(content => content.status === 'pending').length;
506
+
507
+ return (
508
+ <div className="space-y-6">
509
+ {/* Quick Stats */}
510
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
511
+ <div className="card rounded-lg p-6 relative">
512
+ <div className="flex justify-between items-start">
513
+ <div>
514
+ <p className="text-gray-400">VPS Online</p>
515
+ <h3 className="text-2xl font-bold mt-1">{onlineVps}/{vpsList.length}</h3>
516
+ </div>
517
+ <div className="bg-blue-500/10 p-3 rounded-full">
518
+ <i className="fas fa-server text-blue-500"></i>
519
+ </div>
520
+ </div>
521
+ <div className="usage-bar bg-blue-500" style={{ width: `${(onlineVps / vpsList.length) * 100}%` }}></div>
522
+ </div>
523
+
524
+ <div className="card rounded-lg p-6 relative">
525
+ <div className="flex justify-between items-start">
526
+ <div>
527
+ <p className="text-gray-400">Bots Ativos</p>
528
+ <h3 className="text-2xl font-bold mt-1">{runningBots}/{botList.length}</h3>
529
+ </div>
530
+ <div className="bg-green-500/10 p-3 rounded-full">
531
+ <i className="fas fa-robot text-green-500"></i>
532
+ </div>
533
+ </div>
534
+ <div className="usage-bar bg-green-500" style={{ width: `${(runningBots / botList.length) * 100}%` }}></div>
535
+ </div>
536
+
537
+ <div className="card rounded-lg p-6 relative">
538
+ <div className="flex justify-between items-start">
539
+ <div>
540
+ <p className="text-gray-400">Conteúdo Pendente</p>
541
+ <h3 className="text-2xl font-bold mt-1">{pendingContent}</h3>
542
+ </div>
543
+ <div className="bg-yellow-500/10 p-3 rounded-full">
544
+ <i className="fas fa-newspaper text-yellow-500"></i>
545
+ </div>
546
+ </div>
547
+ <div className="usage-bar bg-yellow-500" style={{ width: `${(pendingContent / (contentList.length || 1)) * 100}%` }}></div>
548
+ </div>
549
+
550
+ <div className="card rounded-lg p-6 relative">
551
+ <div className="flex justify-between items-start">
552
+ <div>
553
+ <p className="text-gray-400">Notificações</p>
554
+ <h3 className="text-2xl font-bold mt-1">{notifications.filter(n => !n.read).length}</h3>
555
+ </div>
556
+ <div className="bg-red-500/10 p-3 rounded-full">
557
+ <i className="fas fa-bell text-red-500"></i>
558
+ </div>
559
+ </div>
560
+ <div className="usage-bar bg-red-500" style={{ width: `${(notifications.filter(n => !n.read).length / (notifications.length || 1)) * 100}%` }}></div>
561
+ </div>
562
+ </div>
563
+
564
+ {/* Charts */}
565
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
566
+ <div className="card rounded-lg p-4">
567
+ <h3 className="font-medium mb-4">Uso de Recursos das VPS</h3>
568
+ <canvas id="resourceChart" height="200"></canvas>
569
+ </div>
570
+
571
+ <div className="card rounded-lg p-4">
572
+ <h3 className="font-medium mb-4">Atividade de Bots</h3>
573
+ <canvas id="botActivityChart" height="200"></canvas>
574
+ </div>
575
+ </div>
576
+
577
+ {/* Recent Activity */}
578
+ <div className="card rounded-lg">
579
+ <div className="border-b border-gray-700 p-4">
580
+ <h3 className="font-semibold">Atividade Recente</h3>
581
+ </div>
582
+ <div className="p-4">
583
+ <div className="space-y-4">
584
+ {notifications.slice(0, 5).map(notification => (
585
+ <div key={notification.id} className="flex items-start">
586
+ <div className={`p-2 rounded-full mr-3 ${
587
+ notification.type === 'vps' ? 'bg-blue-500/10 text-blue-500' :
588
+ notification.type === 'content' ? 'bg-yellow-500/10 text-yellow-500' :
589
+ 'bg-gray-500/10 text-gray-500'
590
+ }`}>
591
+ <i className={
592
+ notification.type === 'vps' ? 'fas fa-server' :
593
+ notification.type === 'content' ? 'fas fa-newspaper' :
594
+ 'fas fa-info-circle'
595
+ }></i>
596
+ </div>
597
+ <div>
598
+ <p className="text-sm">{notification.message}</p>
599
+ <p className="text-xs text-gray-400">{new Date(notification.date).toLocaleString()}</p>
600
+ </div>
601
+ </div>
602
+ ))}
603
+ </div>
604
+ </div>
605
+ </div>
606
+ </div>
607
+ );
608
+ };
609
+
610
+ const VpsSection = ({ vpsList, setShowAddVpsModal, executeCommand, terminalOutput }) => {
611
+ const [selectedVps, setSelectedVps] = useState(null);
612
+ const [command, setCommand] = useState('');
613
+
614
+ useEffect(() => {
615
+ // Initialize charts
616
+ if (selectedVps) {
617
+ const cpuCtx = document.getElementById('vpsCpuChart').getContext('2d');
618
+ const memoryCtx = document.getElementById('vpsMemoryChart').getContext('2d');
619
+
620
+ new Chart(cpuCtx, {
621
+ type: 'line',
622
+ data: {
623
+ labels: Array(24).fill().map((_, i) => `${i}h`),
624
+ datasets: [{
625
+ label: 'Uso de CPU',
626
+ data: Array(24).fill().map(() => Math.random() * 100),
627
+ borderColor: '#3B82F6',
628
+ backgroundColor: 'rgba(59, 130, 246, 0.1)',
629
+ tension: 0.4,
630
+ fill: true
631
+ }]
632
+ },
633
+ options: {
634
+ responsive: true,
635
+ plugins: {
636
+ legend: { display: false }
637
+ },
638
+ scales: {
639
+ y: { beginAtZero: true, max: 100 }
640
+ }
641
+ }
642
+ });
643
+
644
+ new Chart(memoryCtx, {
645
+ type: 'line',
646
+ data: {
647
+ labels: Array(24).fill().map((_, i) => `${i}h`),
648
+ datasets: [{
649
+ label: 'Uso de Memória',
650
+ data: Array(24).fill().map(() => Math.random() * 100),
651
+ borderColor: '#8B5CF6',
652
+ backgroundColor: 'rgba(139, 92, 246, 0.1)',
653
+ tension: 0.4,
654
+ fill: true
655
+ }]
656
+ },
657
+ options: {
658
+ responsive: true,
659
+ plugins: {
660
+ legend: { display: false }
661
+ },
662
+ scales: {
663
+ y: { beginAtZero: true, max: 100 }
664
+ }
665
+ }
666
+ });
667
+ }
668
+ }, [selectedVps]);
669
+
670
+ const handleCommandSubmit = (e) => {
671
+ e.preventDefault();
672
+ if (command.trim()) {
673
+ executeCommand(command);
674
+ setCommand('');
675
+ }
676
+ };
677
+
678
+ return (
679
+ <div className="space-y-6">
680
+ <div className="flex justify-between items-center">
681
+ <h3 className="text-lg font-semibold">Servidores VPS</h3>
682
+ <button
683
+ onClick={() => setShowAddVpsModal(true)}
684
+ className="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg flex items-center"
685
+ >
686
+ <i className="fas fa-plus mr-2"></i>
687
+ Adicionar VPS
688
+ </button>
689
+ </div>
690
+
691
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
692
+ {/* VPS List */}
693
+ <div className="lg:col-span-1">
694
+ <div className="card rounded-lg">
695
+ <div className="border-b border-gray-700 p-4">
696
+ <h3 className="font-semibold">Lista de Servidores</h3>
697
+ </div>
698
+ <div className="p-4 space-y-3">
699
+ {vpsList.map(vps => (
700
+ <div
701
+ key={vps.id}
702
+ onClick={() => setSelectedVps(vps)}
703
+ className={`p-3 rounded-lg cursor-pointer ${selectedVps?.id === vps.id ? 'bg-indigo-500/10 border border-indigo-500/30' : 'hover:bg-gray-700'}`}
704
+ >
705
+ <div className="flex justify-between items-center">
706
+ <h4 className="font-medium">{vps.name}</h4>
707
+ <span className={`px-2 py-1 text-xs rounded-full ${
708
+ vps.status === 'online' ? 'bg-green-500/20 text-green-400' : 'bg-red-500/20 text-red-400'
709
+ }`}>
710
+ {vps.status === 'online' ? 'Online' : 'Offline'}
711
+ </span>
712
+ </div>
713
+ <p className="text-sm text-gray-400">{vps.ip}</p>
714
+ <div className="flex justify-between mt-2 text-xs">
715
+ <span className="text-blue-400">CPU: {vps.cpu}%</span>
716
+ <span className="text-purple-400">RAM: {vps.memory}%</span>
717
+ <span className="text-yellow-400">DISK: {vps.storage}%</span>
718
+ </div>
719
+ </div>
720
+ ))}
721
+ </div>
722
+ </div>
723
+ </div>
724
+
725
+ {/* VPS Details */}
726
+ <div className="lg:col-span-2 space-y-6">
727
+ {selectedVps ? (
728
+ <>
729
+ <div className="card rounded-lg p-6">
730
+ <div className="flex justify-between items-center mb-4">
731
+ <h3 className="text-xl font-semibold">{selectedVps.name}</h3>
732
+ <div className="flex space-x-2">
733
+ <button className="bg-green-600 hover:bg-green-700 text-white px-3 py-1 rounded text-sm">
734
+ <i className="fas fa-play mr-1"></i> Iniciar
735
+ </button>
736
+ <button className="bg-yellow-600 hover:bg-yellow-700 text-white px-3 py-1 rounded text-sm">
737
+ <i className="fas fa-redo mr-1"></i> Reiniciar
738
+ </button>
739
+ <button className="bg-red-600 hover:bg-red-700 text-white px-3 py-1 rounded text-sm">
740
+ <i className="fas fa-stop mr-1"></i> Parar
741
+ </button>
742
+ </div>
743
+ </div>
744
+
745
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
746
+ <div className="bg-gray-700/50 p-3 rounded-lg">
747
+ <p className="text-gray-400 text-sm">Endereço IP</p>
748
+ <p className="font-medium">{selectedVps.ip}</p>
749
+ </div>
750
+ <div className="bg-gray-700/50 p-3 rounded-lg">
751
+ <p className="text-gray-400 text-sm">Status</p>
752
+ <p className={`font-medium ${
753
+ selectedVps.status === 'online' ? 'text-green-400' : 'text-red-400'
754
+ }`}>
755
+ {selectedVps.status === 'online' ? 'Online' : 'Offline'}
756
+ </p>
757
+ </div>
758
+ <div className="bg-gray-700/50 p-3 rounded-lg">
759
+ <p className="text-gray-400 text-sm">Última Atualização</p>
760
+ <p className="font-medium">{new Date(selectedVps.lastUpdated).toLocaleString()}</p>
761
+ </div>
762
+ </div>
763
+
764
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
765
+ <div>
766
+ <h4 className="font-medium mb-3">Uso de CPU</h4>
767
+ <canvas id="vpsCpuChart" height="150"></canvas>
768
+ </div>
769
+ <div>
770
+ <h4 className="font-medium mb-3">Uso de Memória</h4>
771
+ <canvas id="vpsMemoryChart" height="150"></canvas>
772
+ </div>
773
+ </div>
774
+ </div>
775
+
776
+ <div className="card rounded-lg">
777
+ <div className="border-b border-gray-700 p-4">
778
+ <h3 className="font-semibold">Terminal</h3>
779
+ </div>
780
+ <div className="p-4">
781
+ <div className="terminal rounded-lg p-4 mb-4 h-48 overflow-y-auto">
782
+ {terminalOutput.map(line => (
783
+ <div
784
+ key={line.id}
785
+ className={`terminal-line ${line.type === 'command' ? 'text-blue-400' : line.type === 'error' ? 'text-red-400' : 'text-gray-400'}`}
786
+ >
787
+ {line.text}
788
+ </div>
789
+ ))}
790
+ <div className="terminal-line text-green-400">
791
+ <span className="mr-2">$</span>
792
+ <span className="blink">_</span>
793
+ </div>
794
+ </div>
795
+
796
+ <form onSubmit={handleCommandSubmit} className="flex">
797
+ <input
798
+ type="text"
799
+ value={command}
800
+ onChange={(e) => setCommand(e.target.value)}
801
+ placeholder="Digite um comando..."
802
+ className="flex-1 bg-gray-700 border border-gray-600 rounded-l-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500"
803
+ />
804
+ <button
805
+ type="submit"
806
+ className="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-r-lg"
807
+ >
808
+ Executar
809
+ </button>
810
+ </form>
811
+ </div>
812
+ </div>
813
+ </>
814
+ ) : (
815
+ <div className="card rounded-lg p-6 flex flex-col items-center justify-center h-full">
816
+ <i className="fas fa-server text-4xl text-gray-500 mb-4"></i>
817
+ <p className="text-gray-400">Selecione um servidor para visualizar os detalhes</p>
818
+ </div>
819
+ )}
820
+ </div>
821
+ </div>
822
+ </div>
823
+ );
824
+ };
825
+
826
+ const BotsSection = ({ botList, setShowAddBotModal }) => {
827
+ const [selectedBot, setSelectedBot] = useState(null);
828
+
829
+ return (
830
+ <div className="space-y-6">
831
+ <div className="flex justify-between items-center">
832
+ <h3 className="text-lg font-semibold">Controle de Bots</h3>
833
+ <button
834
+ onClick={() => setShowAddBotModal(true)}
835
+ className="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg flex items-center"
836
+ >
837
+ <i className="fas fa-plus mr-2"></i>
838
+ Adicionar Bot
839
+ </button>
840
+ </div>
841
+
842
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
843
+ {/* Bot List */}
844
+ <div className="lg:col-span-1">
845
+ <div className="card rounded-lg">
846
+ <div className="border-b border-gray-700 p-4">
847
+ <h3 className="font-semibold">Lista de Bots</h3>
848
+ </div>
849
+ <div className="p-4 space-y-3">
850
+ {botList.map(bot => (
851
+ <div
852
+ key={bot.id}
853
+ onClick={() => setSelectedBot(bot)}
854
+ className={`p-3 rounded-lg cursor-pointer ${selectedBot?.id === bot.id ? 'bg-indigo-500/10 border border-indigo-500/30' : 'hover:bg-gray-700'}`}
855
+ >
856
+ <div className="flex justify-between items-center">
857
+ <h4 className="font-medium">{bot.name}</h4>
858
+ <span className={`px-2 py-1 text-xs rounded-full ${
859
+ bot.status === 'running' ? 'bg-green-500/20 text-green-400' :
860
+ bot.status === 'stopped' ? 'bg-red-500/20 text-red-400' :
861
+ 'bg-yellow-500/20 text-yellow-400'
862
+ }`}>
863
+ {bot.status === 'running' ? 'Ativo' : bot.status === 'stopped' ? 'Parado' : 'Pendente'}
864
+ </span>
865
+ </div>
866
+ <p className="text-sm text-gray-400 capitalize">{bot.type}</p>
867
+ <div className="flex justify-between mt-2 text-xs">
868
+ <span className="text-gray-400">Última execução: {new Date(bot.lastRun).toLocaleTimeString()}</span>
869
+ </div>
870
+ </div>
871
+ ))}
872
+ </div>
873
+ </div>
874
+ </div>
875
+
876
+ {/* Bot Details */}
877
+ <div className="lg:col-span-2">
878
+ {selectedBot ? (
879
+ <div className="card rounded-lg p-6">
880
+ <div className="flex justify-between items-center mb-4">
881
+ <h3 className="text-xl font-semibold">{selectedBot.name}</h3>
882
+ <div className="flex space-x-2">
883
+ <button className={`px-3 py-1 rounded text-sm ${
884
+ selectedBot.status === 'running' ? 'bg-red-600 hover:bg-red-700' : 'bg-green-600 hover:bg-green-700'
885
+ } text-white`}
886
+ >
887
+ <i className={`fas ${selectedBot.status === 'running' ? 'fa-stop' : 'fa-play'} mr-1`}></i>
888
+ {selectedBot.status === 'running' ? 'Parar' : 'Iniciar'}
889
+ </button>
890
+ <button className="bg-indigo-600 hover:bg-indigo-700 text-white px-3 py-1 rounded text-sm">
891
+ <i className="fas fa-cog mr-1"></i> Configurar
892
+ </button>
893
+ </div>
894
+ </div>
895
+
896
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
897
+ <div className="bg-gray-700/50 p-3 rounded-lg">
898
+ <p className="text-gray-400 text-sm">Tipo</p>
899
+ <p className="font-medium capitalize">{selectedBot.type}</p>
900
+ </div>
901
+ <div className="bg-gray-700/50 p-3 rounded-lg">
902
+ <p className="text-gray-400 text-sm">Status</p>
903
+ <p className={`font-medium ${
904
+ selectedBot.status === 'running' ? 'text-green-400' :
905
+ selectedBot.status === 'stopped' ? 'text-red-400' :
906
+ 'text-yellow-400'
907
+ }`}>
908
+ {selectedBot.status === 'running' ? 'Ativo' :
909
+ selectedBot.status === 'stopped' ? 'Parado' :
910
+ 'Pendente'}
911
+ </p>
912
+ </div>
913
+ <div className="bg-gray-700/50 p-3 rounded-lg">
914
+ <p className="text-gray-400 text-sm">Última Execução</p>
915
+ <p className="font-medium">{new Date(selectedBot.lastRun).toLocaleString()}</p>
916
+ </div>
917
+ <div className="bg-gray-700/50 p-3 rounded-lg">
918
+ <p className="text-gray-400 text-sm">Próxima Execução</p>
919
+ <p className="font-medium">
920
+ {selectedBot.nextRun ? new Date(selectedBot.nextRun).toLocaleString() : 'Não agendado'}
921
+ </p>
922
+ </div>
923
+ </div>
924
+
925
+ <div>
926
+ <h4 className="font-medium mb-3">Logs de Execução</h4>
927
+ <div className="bg-gray-800 border border-gray-700 rounded-lg p-4 h-48 overflow-y-auto">
928
+ {selectedBot.logs.map((log, index) => (
929
+ <div key={index} className="text-sm font-mono mb-1">
930
+ <span className="text-gray-500">[{new Date().toLocaleTimeString()}]</span> {log}
931
+ </div>
932
+ ))}
933
+ </div>
934
+ </div>
935
+ </div>
936
+ ) : (
937
+ <div className="card rounded-lg p-6 flex flex-col items-center justify-center h-full">
938
+ <i className="fas fa-robot text-4xl text-gray-500 mb-4"></i>
939
+ <p className="text-gray-400">Selecione um bot para visualizar os detalhes</p>
940
+ </div>
941
+ )}
942
+ </div>
943
+ </div>
944
+ </div>
945
+ );
946
+ };
947
+
948
+ const ContentSection = ({ contentList, setShowAddContentModal }) => {
949
+ const [selectedContent, setSelectedContent] = useState(null);
950
+ const [filter, setFilter] = useState('all');
951
+
952
+ const filteredContent = contentList.filter(content => {
953
+ if (filter === 'all') return true;
954
+ return content.status === filter;
955
+ });
956
+
957
+ return (
958
+ <div className="space-y-6">
959
+ <div className="flex justify-between items-center">
960
+ <h3 className="text-lg font-semibold">Gestão de Conteúdo</h3>
961
+ <button
962
+ onClick={() => setShowAddContentModal(true)}
963
+ className="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg flex items-center"
964
+ >
965
+ <i className="fas fa-plus mr-2"></i>
966
+ Novo Conteúdo
967
+ </button>
968
+ </div>
969
+
970
+ <div className="flex space-x-2 overflow-x-auto pb-2">
971
+ <button
972
+ onClick={() => setFilter('all')}
973
+ className={`px-4 py-1 rounded-full text-sm whitespace-nowrap ${
974
+ filter === 'all' ? 'bg-indigo-600 text-white' : 'bg-gray-700 hover:bg-gray-600'
975
+ }`}
976
+ >
977
+ Todos
978
+ </button>
979
+ <button
980
+ onClick={() => setFilter('pending')}
981
+ className={`px-4 py-1 rounded-full text-sm whitespace-nowrap ${
982
+ filter === 'pending' ? 'bg-yellow-600 text-white' : 'bg-gray-700 hover:bg-gray-600'
983
+ }`}
984
+ >
985
+ Pendentes
986
+ </button>
987
+ <button
988
+ onClick={() => setFilter('approved')}
989
+ className={`px-4 py-1 rounded-full text-sm whitespace-nowrap ${
990
+ filter === 'approved' ? 'bg-green-600 text-white' : 'bg-gray-700 hover:bg-gray-600'
991
+ }`}
992
+ >
993
+ Aprovados
994
+ </button>
995
+ <button
996
+ onClick={() => setFilter('rejected')}
997
+ className={`px-4 py-1 rounded-full text-sm whitespace-nowrap ${
998
+ filter === 'rejected' ? 'bg-red-600 text-white' : 'bg-gray-700 hover:bg-gray-600'
999
+ }`}
1000
+ >
1001
+ Rejeitados
1002
+ </button>
1003
+ </div>
1004
+
1005
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
1006
+ {/* Content List */}
1007
+ <div className="lg:col-span-1">
1008
+ <div className="card rounded-lg">
1009
+ <div className="border-b border-gray-700 p-4">
1010
+ <h3 className="font-semibold">Lista de Conteúdos</h3>
1011
+ </div>
1012
+ <div className="p-4 space-y-3">
1013
+ {filteredContent.map(content => (
1014
+ <div
1015
+ key={content.id}
1016
+ onClick={() => setSelectedContent(content)}
1017
+ className={`p-3 rounded-lg cursor-pointer ${selectedContent?.id === content.id ? 'bg-indigo-500/10 border border-indigo-500/30' : 'hover:bg-gray-700'}`}
1018
+ >
1019
+ <div className="flex justify-between items-center">
1020
+ <h4 className="font-medium truncate">{content.title}</h4>
1021
+ <span className={`px-2 py-1 text-xs rounded-full ${
1022
+ content.status === 'approved' ? 'bg-green-500/20 text-green-400' :
1023
+ content.status === 'pending' ? 'bg-yellow-500/20 text-yellow-400' :
1024
+ 'bg-red-500/20 text-red-400'
1025
+ }`}>
1026
+ {content.status === 'approved' ? 'Aprovado' :
1027
+ content.status === 'pending' ? 'Pendente' :
1028
+ 'Rejeitado'}
1029
+ </span>
1030
+ </div>
1031
+ <p className="text-sm text-gray-400">{content.source}</p>
1032
+ <div className="flex justify-between mt-2 text-xs">
1033
+ <span className="text-gray-400">Criado em: {new Date(content.created).toLocaleDateString()}</span>
1034
+ </div>
1035
+ </div>
1036
+ ))}
1037
+ </div>
1038
+ </div>
1039
+ </div>
1040
+
1041
+ {/* Content Details */}
1042
+ <div className="lg:col-span-2">
1043
+ {selectedContent ? (
1044
+ <div className="card rounded-lg p-6">
1045
+ <div className="flex justify-between items-center mb-4">
1046
+ <h3 className="text-xl font-semibold">{selectedContent.title}</h3>
1047
+ <div className="flex space-x-2">
1048
+ {selectedContent.status === 'pending' && (
1049
+ <>
1050
+ <button className="bg-green-600 hover:bg-green-700 text-white px-3 py-1 rounded text-sm">
1051
+ <i className="fas fa-check mr-1"></i> Aprovar
1052
+ </button>
1053
+ <button className="bg-red-600 hover:bg-red-700 text-white px-3 py-1 rounded text-sm">
1054
+ <i className="fas fa-times mr-1"></i> Rejeitar
1055
+ </button>
1056
+ </>
1057
+ )}
1058
+ <button className="bg-indigo-600 hover:bg-indigo-700 text-white px-3 py-1 rounded text-sm">
1059
+ <i className="fas fa-edit mr-1"></i> Editar
1060
+ </button>
1061
+ </div>
1062
+ </div>
1063
+
1064
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
1065
+ <div className="bg-gray-700/50 p-3 rounded-lg">
1066
+ <p className="text-gray-400 text-sm">Fonte</p>
1067
+ <p className="font-medium">{selectedContent.source}</p>
1068
+ </div>
1069
+ <div className="bg-gray-700/50 p-3 rounded-lg">
1070
+ <p className="text-gray-400 text-sm">Status</p>
1071
+ <p className={`font-medium ${
1072
+ selectedContent.status === 'approved' ? 'text-green-400' :
1073
+ selectedContent.status === 'pending' ? 'text-yellow-400' :
1074
+ 'text-red-400'
1075
+ }`}>
1076
+ {selectedContent.status === 'approved' ? 'Aprovado' :
1077
+ selectedContent.status === 'pending' ? 'Pendente' :
1078
+ 'Rejeitado'}
1079
+ </p>
1080
+ </div>
1081
+ <div className="bg-gray-700/50 p-3 rounded-lg">
1082
+ <p className="text-gray-400 text-sm">Criado em</p>
1083
+ <p className="font-medium">{new Date(selectedContent.created).toLocaleString()}</p>
1084
+ </div>
1085
+ <div className="bg-gray-700/50 p-3 rounded-lg">
1086
+ <p className="text-gray-400 text-sm">Publicado em</p>
1087
+ <p className="font-medium">
1088
+ {selectedContent.published ? new Date(selectedContent.published).toLocaleString() : 'Não publicado'}
1089
+ </p>
1090
+ </div>
1091
+ </div>
1092
+
1093
+ <div>
1094
+ <h4 className="font-medium mb-3">Conteúdo</h4>
1095
+ <div className="bg-gray-800 border border-gray-700 rounded-lg p-4">
1096
+ <p className="text-gray-300">
1097
+ Este é um exemplo de conteúdo gerado automaticamente pelo sistema de IA.
1098
+ O conteúdo real seria exibido aqui com formatação adequada.
1099
+ </p>
1100
+ <p className="text-gray-300 mt-2">
1101
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam auctor, nisl eget ultricies tincidunt, nisl nisl aliquam nisl, eget ultricies nisl nisl eget nisl.
1102
+ </p>
1103
+ </div>
1104
+ </div>
1105
+ </div>
1106
+ ) : (
1107
+ <div className="card rounded-lg p-6 flex flex-col items-center justify-center h-full">
1108
+ <i className="fas fa-newspaper text-4xl text-gray-500 mb-4"></i>
1109
+ <p className="text-gray-400">Selecione um conteúdo para visualizar os detalhes</p>
1110
+ </div>
1111
+ )}
1112
+ </div>
1113
+ </div>
1114
+ </div>
1115
+ );
1116
+ };
1117
+
1118
+ const SettingsSection = ({ user, darkMode, toggleDarkMode }) => {
1119
+ const [currentTab, setCurrentTab] = useState('profile');
1120
+
1121
+ return (
1122
+ <div className="space-y-6">
1123
+ <h3 className="text-lg font-semibold">Configurações</h3>
1124
+
1125
+ <div className="grid grid-cols-1 lg:grid-cols-4 gap-6">
1126
+ {/* Settings Menu */}
1127
+ <div className="lg:col-span-1">
1128
+ <div className="card rounded-lg">
1129
+ <div className="border-b border-gray-700 p-4">
1130
+ <h3 className="font-semibold">Menu</h3>
1131
+ </div>
1132
+ <div className="p-4 space-y-2">
1133
+ <button
1134
+ onClick={() => setCurrentTab('profile')}
1135
+ className={`w-full text-left p-3 rounded-lg ${
1136
+ currentTab === 'profile' ? 'bg-indigo-500/20 text-indigo-400' : 'hover:bg-gray-700'
1137
+ }`}
1138
+ >
1139
+ <i className="fas fa-user mr-2"></i> Perfil
1140
+ </button>
1141
+ <button
1142
+ onClick={() => setCurrentTab('account')}
1143
+ className={`w-full text-left p-3 rounded-lg ${
1144
+ currentTab === 'account' ? 'bg-indigo-500/20 text-indigo-400' : 'hover:bg-gray-700'
1145
+ }`}
1146
+ >
1147
+ <i className="fas fa-cog mr-2"></i> Conta
1148
+ </button>
1149
+ <button
1150
+ onClick={() => setCurrentTab('security')}
1151
+ className={`w-full text-left p-3 rounded-lg ${
1152
+ currentTab === 'security' ? 'bg-indigo-500/20 text-indigo-400' : 'hover:bg-gray-700'
1153
+ }`}
1154
+ >
1155
+ <i className="fas fa-shield-alt mr-2"></i> Segurança
1156
+ </button>
1157
+ <button
1158
+ onClick={() => setCurrentTab('notifications')}
1159
+ className={`w-full text-left p-3 rounded-lg ${
1160
+ currentTab === 'notifications' ? 'bg-indigo-500/20 text-indigo-400' : 'hover:bg-gray-700'
1161
+ }`}
1162
+ >
1163
+ <i className="fas fa-bell mr-2"></i> Notificações
1164
+ </button>
1165
+ <button
1166
+ onClick={() => setCurrentTab('appearance')}
1167
+ className={`w-full text-left p-3 rounded-lg ${
1168
+ currentTab === 'appearance' ? 'bg-indigo-500/20 text-indigo-400' : 'hover:bg-gray-700'
1169
+ }`}
1170
+ >
1171
+ <i className="fas fa-palette mr-2"></i> Aparência
1172
+ </button>
1173
+ </div>
1174
+ </div>
1175
+ </div>
1176
+
1177
+ {/* Settings Content */}
1178
+ <div className="lg:col-span-3">
1179
+ <div className="card rounded-lg p-6">
1180
+ {currentTab === 'profile' && (
1181
+ <div>
1182
+ <h3 className="text-xl font-semibold mb-6">Perfil</h3>
1183
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
1184
+ <div>
1185
+ <label className="block text-sm font-medium text-gray-400 mb-1">Nome</label>
1186
+ <input
1187
+ type="text"
1188
+ defaultValue={user.name}
1189
+ className="w-full bg-gray-700 border border-gray-600 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500"
1190
+ />
1191
+ </div>
1192
+ <div>
1193
+ <label className="block text-sm font-medium text-gray-400 mb-1">Email</label>
1194
+ <input
1195
+ type="email"
1196
+ defaultValue={user.email}
1197
+ className="w-full bg-gray-700 border border-gray-600 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500"
1198
+ />
1199
+ </div>
1200
+ <div>
1201
+ <label className="block text-sm font-medium text-gray-400 mb-1">Cargo</label>
1202
+ <input
1203
+ type="text"
1204
+ defaultValue={user.role}
1205
+ className="w-full bg-gray-700 border border-gray-600 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500"
1206
+ disabled
1207
+ />
1208
+ </div>
1209
+ <div>
1210
+ <label className="block text-sm font-medium text-gray-400 mb-1">Foto</label>
1211
+ <div className="flex items-center">
1212
+ <div className="w-16 h-16 rounded-full bg-indigo-500 flex items-center justify-center mr-4">
1213
+ <i className="fas fa-user text-white text-xl"></i>
1214
+ </div>
1215
+ <button className="bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-lg">
1216
+ Alterar
1217
+ </button>
1218
+ </div>
1219
+ </div>
1220
+ </div>
1221
+ <div className="mt-6 flex justify-end">
1222
+ <button className="bg-indigo-600 hover:bg-indigo-700 text-white px-6 py-2 rounded-lg">
1223
+ Salvar Alterações
1224
+ </button>
1225
+ </div>
1226
+ </div>
1227
+ )}
1228
+
1229
+ {currentTab === 'account' && (
1230
+ <div>
1231
+ <h3 className="text-xl font-semibold mb-6">Configurações da Conta</h3>
1232
+ <div className="space-y-6">
1233
+ <div className="bg-gray-700/50 p-4 rounded-lg">
1234
+ <h4 className="font-medium mb-3">Plano Atual</h4>
1235
+ <div className="flex items-center justify-between">
1236
+ <div>
1237
+ <p className="text-2xl font-bold">Premium</p>
1238
+ <p className="text-gray-400">Acesso completo a todos os recursos</p>
1239
+ </div>
1240
+ <button className="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg">
1241
+ Gerenciar Plano
1242
+ </button>
1243
+ </div>
1244
+ </div>
1245
+
1246
+ <div className="bg-gray-700/50 p-4 rounded-lg">
1247
+ <h4 className="font-medium mb-3">Limites de Uso</h4>
1248
+ <div className="space-y-3">
1249
+ <div>
1250
+ <div className="flex justify-between mb-1">
1251
+ <span className="text-gray-400">VPS</span>
1252
+ <span className="font-medium">2/5</span>
1253
+ </div>
1254
+ <div className="w-full bg-gray-600 rounded-full h-2">
1255
+ <div className="bg-indigo-600 h-2 rounded-full" style={{ width: '40%' }}></div>
1256
+ </div>
1257
+ </div>
1258
+ <div>
1259
+ <div className="flex justify-between mb-1">
1260
+ <span className="text-gray-400">Bots</span>
1261
+ <span className="font-medium">3/10</span>
1262
+ </div>
1263
+ <div className="w-full bg-gray-600 rounded-full h-2">
1264
+ <div className="bg-indigo-600 h-2 rounded-full" style={{ width: '30%' }}></div>
1265
+ </div>
1266
+ </div>
1267
+ <div>
1268
+ <div className="flex justify-between mb-1">
1269
+ <span className="text-gray-400">Armazenamento</span>
1270
+ <span className="font-medium">15GB/50GB</span>
1271
+ </div>
1272
+ <div className="w-full bg-gray-600 rounded-full h-2">
1273
+ <div className="bg-indigo-600 h-2 rounded-full" style={{ width: '30%' }}></div>
1274
+ </div>
1275
+ </div>
1276
+ </div>
1277
+ </div>
1278
+
1279
+ <div className="bg-red-500/10 border border-red-500/30 p-4 rounded-lg">
1280
+ <h4 className="font-medium mb-3 text-red-400">Zona de Perigo</h4>
1281
+ <div className="flex justify-between items-center">
1282
+ <div>
1283
+ <p className="text-sm">Excluir permanentemente sua conta</p>
1284
+ <p className="text-xs text-gray-400">Esta ação não pode ser desfeita</p>
1285
+ </div>
1286
+ <button className="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg text-sm">
1287
+ Excluir Conta
1288
+ </button>
1289
+ </div>
1290
+ </div>
1291
+ </div>
1292
+ </div>
1293
+ )}
1294
+
1295
+ {currentTab === 'security' && (
1296
+ <div>
1297
+ <h3 className="text-xl font-semibold mb-6">Segurança</h3>
1298
+ <div className="space-y-6">
1299
+ <div className="bg-gray-700/50 p-4 rounded-lg">
1300
+ <h4 className="font-medium mb-3">Alterar Senha</h4>
1301
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
1302
+ <div>
1303
+ <label className="block text-sm font-medium text-gray-400 mb-1">Senha Atual</label>
1304
+ <input
1305
+ type="password"
1306
+ className="w-full bg-gray-700 border border-gray-600 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500"
1307
+ />
1308
+ </div>
1309
+ <div>
1310
+ <label className="block text-sm font-medium text-gray-400 mb-1">Nova Senha</label>
1311
+ <input
1312
+ type="password"
1313
+ className="w-full bg-gray-700 border border-gray-600 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500"
1314
+ />
1315
+ </div>
1316
+ <div>
1317
+ <label className="block text-sm font-medium text-gray-400 mb-1">Confirmar Nova Senha</label>
1318
+ <input
1319
+ type="password"
1320
+ className="w-full bg-gray-700 border border-gray-600 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500"
1321
+ />
1322
+ </div>
1323
+ </div>
1324
+ <div className="mt-4 flex justify-end">
1325
+ <button className="bg-indigo-600 hover:bg-indigo-700 text-white px-6 py-2 rounded-lg">
1326
+ Alterar Senha
1327
+ </button>
1328
+ </div>
1329
+ </div>
1330
+
1331
+ <div className="bg-gray-700/50 p-4 rounded-lg">
1332
+ <h4 className="font-medium mb-3">Autenticação de Dois Fatores</h4>
1333
+ <div className="flex justify-between items-center">
1334
+ <div>
1335
+ <p className="font-medium">2FA Desativado</p>
1336
+ <p className="text-sm text-gray-400">Proteja sua conta com um segundo fator de autenticação</p>
1337
+ </div>
1338
+ <button className="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg">
1339
+ Ativar 2FA
1340
+ </button>
1341
+ </div>
1342
+ </div>
1343
+
1344
+ <div className="bg-gray-700/50 p-4 rounded-lg">
1345
+ <h4 className="font-medium mb-3">Sessões Ativas</h4>
1346
+ <div className="space-y-3">
1347
+ <div className="flex justify-between items-center p-3 bg-gray-800 rounded-lg">
1348
+ <div>
1349
+ <p className="font-medium">Chrome - Windows</p>
1350
+ <p className="text-sm text-gray-400">192.168.1.5 - Ativo agora</p>
1351
+ </div>
1352
+ <button className="text-red-500 hover:text-red-700">
1353
+ <i className="fas fa-sign-out-alt"></i> Sair
1354
+ </button>
1355
+ </div>
1356
+ <div className="flex justify-between items-center p-3 bg-gray-800 rounded-lg">
1357
+ <div>
1358
+ <p className="font-medium">Firefox - Linux</p>
1359
+ <p className="text-sm text-gray-400">192.168.1.10 - 2 horas atrás</p>
1360
+ </div>
1361
+ <button className="text-red-500 hover:text-red-700">
1362
+ <i className="fas fa-sign-out-alt"></i> Sair
1363
+ </button>
1364
+ </div>
1365
+ </div>
1366
+ </div>
1367
+ </div>
1368
+ </div>
1369
+ )}
1370
+
1371
+ {currentTab === 'notifications' && (
1372
+ <div>
1373
+ <h3 className="text-xl font-semibold mb-6">Notificações</h3>
1374
+ <div className="space-y-6">
1375
+ <div className="bg-gray-700/50 p-4 rounded-lg">
1376
+ <h4 className="font-medium mb-3">Preferências de Notificação</h4>
1377
+ <div className="space-y-4">
1378
+ <div className="flex justify-between items-center">
1379
+ <div>
1380
+ <p className="font-medium">Notificações por Email</p>
1381
+ <p className="text-sm text-gray-400">Receba notificações importantes por email</p>
1382
+ </div>
1383
+ <label className="relative inline-flex items-center cursor-pointer">
1384
+ <input type="checkbox" className="sr-only peer" defaultChecked />
1385
+ <div className="w-11 h-6 bg-gray-600 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-indigo-600"></div>
1386
+ </label>
1387
+ </div>
1388
+ <div className="flex justify-between items-center">
1389
+ <div>
1390
+ <p className="font-medium">Notificações Push</p>
1391
+ <p className="text-sm text-gray-400">Receba notificações no navegador</p>
1392
+ </div>
1393
+ <label className="relative inline-flex items-center cursor-pointer">
1394
+ <input type="checkbox" className="sr-only peer" />
1395
+ <div className="w-11 h-6 bg-gray-600 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-indigo-600"></div>
1396
+ </label>
1397
+ </div>
1398
+ <div className="flex justify-between items-center">
1399
+ <div>
1400
+ <p className="font-medium">Alertas de Segurança</p>
1401
+ <p className="text-sm text-gray-400">Receba alertas sobre atividades suspeitas</p>
1402
+ </div>
1403
+ <label className="relative inline-flex items-center cursor-pointer">
1404
+ <input type="checkbox" className="sr-only peer" defaultChecked />
1405
+ <div className="w-11 h-6 bg-gray-600 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-indigo-600"></div>
1406
+ </label>
1407
+ </div>
1408
+ </div>
1409
+ </div>
1410
+
1411
+ <div className="bg-gray-700/50 p-4 rounded-lg">
1412
+ <h4 className="font-medium mb-3">Tipos de Notificação</h4>
1413
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
1414
+ <div className="flex items-center">
1415
+ <input type="checkbox" id="notif-vps" className="w-4 h-4 text-indigo-600 bg-gray-700 border-gray-600 rounded focus:ring-indigo-500" defaultChecked />
1416
+ <label htmlFor="notif-vps" className="ml-2 text-sm font-medium text-gray-300">Status da VPS</label>
1417
+ </div>
1418
+ <div className="flex items-center">
1419
+ <input type="checkbox" id="notif-bots" className="w-4 h-4 text-indigo-600 bg-gray-700 border-gray-600 rounded focus:ring-indigo-500" defaultChecked />
1420
+ <label htmlFor="notif-bots" className="ml-2 text-sm font-medium text-gray-300">Atividade de Bots</label>
1421
+ </div>
1422
+ <div className="flex items-center">
1423
+ <input type="checkbox" id="notif-content" className="w-4 h-4 text-indigo-600 bg-gray-700 border-gray-600 rounded focus:ring-indigo-500" defaultChecked />
1424
+ <label htmlFor="notif-content" className="ml-2 text-sm font-medium text-gray-300">Conteúdo Pendente</label>
1425
+ </div>
1426
+ <div className="flex items-center">
1427
+ <input type="checkbox" id="notif-security" className="w-4 h-4 text-indigo-600 bg-gray-700 border-gray-600 rounded focus:ring-indigo-500" defaultChecked />
1428
+ <label htmlFor="notif-security" className="ml-2 text-sm font-medium text-gray-300">Alertas de Segurança</label>
1429
+ </div>
1430
+ <div className="flex items-center">
1431
+ <input type="checkbox" id="notif-updates" className="w-4 h-4 text-indigo-600 bg-gray-700 border-gray-600 rounded focus:ring-indigo-500" />
1432
+ <label htmlFor="notif-updates" className="ml-2 text-sm font-medium text-gray-300">Atualizações do Sistema</label>
1433
+ </div>
1434
+ <div className="flex items-center">
1435
+ <input type="checkbox" id="notif-news" className="w-4 h-4 text-indigo-600 bg-gray-700 border-gray-600 rounded focus:ring-indigo-500" />
1436
+ <label htmlFor="notif-news" className="ml-2 text-sm font-medium text-gray-300">Novidades e Promoções</label>
1437
+ </div>
1438
+ </div>
1439
+ </div>
1440
+ </div>
1441
+ </div>
1442
+ )}
1443
+
1444
+ {currentTab === 'appearance' && (
1445
+ <div>
1446
+ <h3 className="text-xl font-semibold mb-6">Aparência</h3>
1447
+ <div className="space-y-6">
1448
+ <div className="bg-gray-700/50 p-4 rounded-lg">
1449
+ <h4 className="font-medium mb-3">Tema</h4>
1450
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
1451
+ <button
1452
+ onClick={toggleDarkMode}
1453
+ className={`p-4 rounded-lg border ${darkMode ? 'border-indigo-500 bg-indigo-500/10' : 'border-gray-600 hover:border-gray-500'}`}
1454
+ >
1455
+ <div className="flex flex-col items-center">
1456
+ <i className={`fas ${darkMode ? 'fa-moon' : 'fa-sun'} text-2xl mb-2 ${darkMode ? 'text-indigo-400' : 'text-yellow-400'}`}></i>
1457
+ <span>{darkMode ? 'Escuro' : 'Claro'}</span>
1458
+ </div>
1459
+ </button>
1460
+ <button className="p-4 rounded-lg border border-gray-600 hover:border-gray-500">
1461
+ <div className="flex flex-col items-center">
1462
+ <i className="fas fa-desktop text-2xl mb-2 text-gray-400"></i>
1463
+ <span>Seguir Sistema</span>
1464
+ </div>
1465
+ </button>
1466
+ </div>
1467
+ </div>
1468
+
1469
+ <div className="bg-gray-700/50 p-4 rounded-lg">
1470
+ <h4 className="font-medium mb-3">Densidade da Interface</h4>
1471
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
1472
+ <button className="p-4 rounded-lg border border-gray-600 hover:border-gray-500">
1473
+ <div className="flex flex-col items-center">
1474
+ <i className="fas fa-compress text-2xl mb-2 text-gray-400"></i>
1475
+ <span>Compacto</span>
1476
+ </div>
1477
+ </button>
1478
+ <button className="p-4 rounded-lg border border-indigo-500 bg-indigo-500/10">
1479
+ <div className="flex flex-col items-center">
1480
+ <i className="fas fa-expand text-2xl mb-2 text-indigo-400"></i>
1481
+ <span>Confortável</span>
1482
+ </div>
1483
+ </button>
1484
+ <button className="p-4 rounded-lg border border-gray-600 hover:border-gray-500">
1485
+ <div className="flex flex-col items-center">
1486
+ <i className="fas fa-text-height text-2xl mb-2 text-gray-400"></i>
1487
+ <span>Espaçoso</span>
1488
+ </div>
1489
+ </button>
1490
+ </div>
1491
+ </div>
1492
+
1493
+ <div className="bg-gray-700/50 p-4 rounded-lg">
1494
+ <h4 className="font-medium mb-3">Cor de Destaque</h4>
1495
+ <div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-3">
1496
+ {['indigo', 'blue', 'green', 'yellow', 'red', 'purple'].map(color => (
1497
+ <button
1498
+ key={color}
1499
+ className={`w-10 h-10 rounded-full bg-${color}-500 flex items-center justify-center`}
1500
+ >
1501
+ {color === 'indigo' && <i className="fas fa-check text-white"></i>}
1502
+ </button>
1503
+ ))}
1504
+ </div>
1505
+ </div>
1506
+ </div>
1507
+ </div>
1508
+ )}
1509
+ </div>
1510
+ </div>
1511
+ </div>
1512
+ </div>
1513
+ );
1514
+ };
1515
+
1516
+ // Componentes de modal
1517
+ const AddVpsModal = ({ setShowAddVpsModal, setVpsList }) => {
1518
+ const [formData, setFormData] = useState({
1519
+ name: '',
1520
+ ip: '',
1521
+ sshPort: '22',
1522
+ sshUser: 'root',
1523
+ sshKey: '',
1524
+ tags: []
1525
+ });
1526
+
1527
+ const handleSubmit = (e) => {
1528
+ e.preventDefault();
1529
+ const newVps = {
1530
+ id: Date.now(),
1531
+ name: formData.name,
1532
+ ip: formData.ip,
1533
+ status: 'online',
1534
+ cpu: 0,
1535
+ memory: 0,
1536
+ storage: 0,
1537
+ containers: 0,
1538
+ lastUpdated: new Date()
1539
+ };
1540
+
1541
+ setVpsList(prev => [...prev, newVps]);
1542
+ setShowAddVpsModal(false);
1543
+ };
1544
+
1545
+ return (
1546
+ <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
1547
+ <div className="bg-gray-800 rounded-lg border border-gray-700 w-full max-w-2xl">
1548
+ <div className="border-b border-gray-700 p-4 flex justify-between items-center">
1549
+ <h3 className="font-semibold">Adicionar Nova VPS</h3>
1550
+ <button
1551
+ onClick={() => setShowAddVpsModal(false)}
1552
+ className="text-gray-400 hover:text-white"
1553
+ >
1554
+ <i className="fas fa-times"></i>
1555
+ </button>
1556
+ </div>
1557
+
1558
+ <form onSubmit={handleSubmit} className="p-6">
1559
+ <div className="space-y-4">
1560
+ <div>
1561
+ <label className="block text-sm font-medium text-gray-400 mb-1">Nome da VPS</label>
1562
+ <input
1563
+ type="text"
1564
+ value={formData.name}
1565
+ onChange={(e) => setFormData({...formData, name: e.target.value})}
1566
+ className="w-full bg-gray-700 border border-gray-600 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500"
1567
+ required
1568
+ />
1569
+ </div>
1570
+
1571
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
1572
+ <div>
1573
+ <label className="block text-sm font-medium text-gray-400 mb-1">Endereço IP</label>
1574
+ <input
1575
+ type="text"
1576
+ </html>
prompts.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ Fazer modificações como: Painel. Dentro dele Será monitorado os projetos separedos por conteiner (Docker), mostrar o ip da servidor conectado. em monitoramento usar cores no bloco completo mudando de tom de cor conforme for sendo usando (tom mais fraco menos usa, tom mais forte mais uso) mostrar trafego na rede. Opções de incluir app externo tipo n8n, evolution, redis, sql, etx. Usar com mo delo e ideia o Ease Panel. Deixar esse Painel Mais moderno e com funcões que cubra, tudo que usa VPS precise. criar contaas de emal, Opçõa de escolher o nome do Panel Baseado na VPS para maio controle. Criar o front e backend juntos, pronto para usar.
2
+ Recomeçar: Primeira decisão: Recomeçar com stack moderna Sim, refaz com stack real de app, porque HTML estático vai limitar muito: 🔧 Tech Stack ideal: Frontend: React + Tailwind + ShadCN UI (leve, moderno e estiloso) Usa Vite ou Next.js pra acelerar Backend/API: Node.js + Fastify (rápido) ou Python + FastAPI (perfeito se os bots forem Python) Cria endpoints REST ou GraphQL Banco: PostgreSQL ou MongoDB (dependendo da estrutura dos dados) Redis (pra cache, fila, jobs de bot e IA) Auth: JWT com roles ou integração com Auth0 ou Clerk Orquestração de tarefas: n8n (que você já usa) + Rasa + MCP → Integrado por API Hosting: VPS ou mesmo um Docker Swarm / Portainer se quiser escalar ou monitorar múltiplas VPS. Funcionalidades do painel (Free/Premium futuramente) Módulo 1 – Controle de VPS Adicionar/remover VPS (com conexão por SSH ou API tipo Agent) Status de CPU, RAM, processos, uso de disco (via script) Logs em tempo real (tail) Módulo 2 – Bots & Automações Criar/executar/pausar bots (por script ou trigger) Visualizar histórico de execuções Configurar fluxos com IA (Rasa, OpenAI, Ollama, etc) API Key pessoal para usar os bots remotamente Módulo 3 – IA & Conteúdo Criar artigo/matéria a partir de scrapings + IA Permitir aprovação manual antes de publicar Crosspost (Telegram, Twitter, site, etc) Módulo 4 – Sistema de Permissões Controle de acesso (admin, editor, bot user) Modo anônimo (pra denúncia segura, se quiser manter) Módulo 5 – SaaS Premium Conta gratuita com 1 VPS e bots básicos Conta paga com mais VPSs, scraping, integração Telegram, scraping avançado, IA com contexto, Estrutura de pastas sugerida /painel-ai-control ├── frontend/ (React) │ ├── src/components/ │ ├── src/pages/ │ ├── src/services/api.js │ └── ... ├── backend/ (Node.js ou FastAPI) │ ├── api/ │ ├── bots/ │ ├── controllers/ │ ├── database/ │ └── ... ├── docker-compose.yml ├── .env Refaz o painel com frontend em React + Tailwind, e já prepara pra conectar com um backend (Node.js ou FastAPI). O front não precisa ser 100% funcional ainda, mas precisa estar pronto pra receber dados de API. PROJETO: PAINEL DE CONTROLE INTELIGENTE Um sistema web moderno para controlar VPS, bots, automações com IA, e gerenciar conteúdos. Foco em: desempenho, visual bonito, API conectável e estrutura modular. 🧠 OBJETIVO Criar um painel completo com: Frontend moderno e bonito Backend preparado pra automação Estrutura API-first Integrações futuras com: bots, IA, scraping, publicação automática Controle de várias VPS, containers, e tarefas 📦 STACK TECNOLÓGICA 🎨 FRONTEND React (com Vite ou Next.js) TailwindCSS + ShadCN UI (visual moderno, responsivo e bonito) Componentes reutilizáveis Axios para chamadas de API Dashboard com temas escuros, responsivos e interativos 🔧 BACKEND Node.js com Fastify (leve, rápido e fácil de manter) ou Python com FastAPI (ideal se os bots forem em Python) Módulos obrigatórios: API RESTful (exemplo: /vps/status, /bots/start, /conteudos/aprovar) Banco de dados: PostgreSQL (estruturado) ou MongoDB (flexível) Fila de tarefas e cache: Redis Sistema de logs e eventos JWT para autenticação 🖥️ FUNCIONALIDADES DO SISTEMA 1. Painel Geral (Dashboard) Quantidade de VPS Status de bots Atividade recente Recursos ativos (CPU/RAM/Containers) 2. Gerenciador de VPS Adicionar nova VPS Ver uso de recursos (CPU, RAM, disco) Executar comandos via SSH remoto Criar container (Docker) ou reiniciar serviços 3. Controle de Bots Adicionar/remover/editar bots (com agendamento) Status: rodando/parado Logs de execução Integração com n8n, Rasa, MCP, etc 4. Gestão de Conteúdo com IA Área para aprovar conteúdos gerados por scraping + IA Opção de editar antes de publicar Publicação manual ou automática (com webhook) 5. Configurações e Permissões Controle de usuários (admin/editor) Temas (claro/escuro) Logs de login/ações 📂 ORGANIZAÇÃO DO PROJETO /painel-inteligente ├── frontend/ (React) │ ├��─ src/ │ │ ├── components/ │ │ ├── pages/ │ │ ├── styles/ │ │ └── services/api.js │ └── vite.config.js │ ├── backend/ (Node ou Python) │ ├── api/ │ ├── controllers/ │ ├── models/ │ ├── database/ │ ├── middlewares/ │ └── main.js ou main.py │ ├── docker-compose.yml ├── .env └── README.md 🎯 ENTREGA ESPERADA (MVP) Front pronto com páginas: Dashboard VPS Bots Conteúdos (raspagem/IA) Configurações API funcional com: Login Listar VPS Executar comandos Iniciar/parar bots Criar conteúdo com IA simulada (mocked) Visual bonito e escalável 🤖 PRÓXIMAS INTEGRAÇÕES FUTURAS (já deixa preparado) n8n (por webhook) Rasa + OpenAI (via API) Pinecone / Weaviate (busca semântica) Automatização com scraping (Twitter, Google News, etc)