stadv commited on
Commit
67fa90b
·
verified ·
1 Parent(s): cc0f38c

🐳 22/06 - 09:28 - integre com a aasp {  "swagger": "2.0",  "info": {    "version": "v1",    "title": "API - Intimações AASP",    "description": "Api para acesso as intimações dos associados da AASP",

Browse files
Files changed (4) hide show
  1. app.js +1066 -0
  2. cliente.html +238 -0
  3. cliente.js +122 -0
  4. index.html +373 -395
app.js ADDED
@@ -0,0 +1,1066 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ==========================================
2
+ // LegalData Manager - Main Application
3
+ // ==========================================
4
+
5
+ // --- Data Store ---
6
+ let appData = {
7
+ processos: [
8
+ { id: '2023-0456', cliente: 'João Silva', tribunal: 'TJSP', data: '2023-03-15', status: 'Ativo', prazo: '2024-01-15', descricao: 'Ação indenizatória' },
9
+ { id: '2023-0389', cliente: 'Maria Souza', tribunal: 'TRF4', data: '2023-02-20', status: 'Pendente', prazo: '2024-01-18', descricao: 'Mandado de segurança' },
10
+ { id: '2023-0412', cliente: 'Empresa XYZ Ltda', tribunal: 'TJMG', data: '2023-04-10', status: 'Urgente', prazo: '2024-01-20', descricao: 'Execução fiscal' },
11
+ { id: '2023-0501', cliente: 'Ana Oliveira', tribunal: 'TJSP', data: '2023-05-05', status: 'Ativo', prazo: '2024-02-10', descricao: 'Ação de cobrança' },
12
+ { id: '2023-0534', cliente: 'Carlos Mendes', tribunal: 'TRF1', data: '2023-06-12', status: 'Concluído', prazo: null, descricao: 'Habeas corpus' },
13
+ { id: '2023-0601', cliente: 'Tech Solutions SA', tribunal: 'TJSP', data: '2023-07-01', status: 'Ativo', prazo: '2024-03-01', descricao: 'Contrato comercial' },
14
+ { id: '2023-0645', cliente: 'Fernanda Lima', tribunal: 'TJMG', data: '2023-08-15', status: 'Pendente', prazo: '2024-03-20', descricao: 'Inventário' },
15
+ { id: '2023-0702', cliente: 'Roberto Santos', tribunal: 'TRF4', data: '2023-09-03', status: 'Ativo', prazo: '2024-04-05', descricao: 'Recurso de apelação' },
16
+ ],
17
+ clientes: [
18
+ { id: 1, nome: 'João Silva', tipo: 'pf', cpfCnpj: '123.456.789-00', email: 'joao@email.com', telefone: '(11) 98765-4321', endereco: 'Rua A, 100, São Paulo-SP', processos: 2 },
19
+ { id: 2, nome: 'Maria Souza', tipo: 'pf', cpfCnpj: '987.654.321-00', email: 'maria@email.com', telefone: '(21) 99876-5432', endereco: 'Av B, 200, Rio de Janeiro-RJ', processos: 1 },
20
+ { id: 3, nome: 'Empresa XYZ Ltda', tipo: 'pj', cpfCnpj: '12.345.678/0001-90', email: 'contato@xyz.com', telefone: '(11) 3456-7890', endereco: 'Rua C, 300, São Paulo-SP', processos: 3 },
21
+ { id: 4, nome: 'Ana Oliveira', tipo: 'pf', cpfCnpj: '456.789.123-00', email: 'ana@email.com', telefone: '(31) 97654-3210', endereco: 'Rua D, 400, Belo Horizonte-MG', processos: 1 },
22
+ { id: 5, nome: 'Carlos Mendes', tipo: 'pf', cpfCnpj: '789.123.456-00', email: 'carlos@email.com', telefone: '(61) 96543-2109', endereco: 'SQN 5, Bloco E, Brasília-DF', processos: 1 },
23
+ { id: 6, nome: 'Tech Solutions SA', tipo: 'pj', cpfCnpj: '98.765.432/0001-10', email: 'juridico@techsol.com', telefone: '(11) 4567-8901', endereco: 'Av F, 600, São Paulo-SP', processos: 2 },
24
+ { id: 7, nome: 'Fernanda Lima', tipo: 'pf', cpfCnpj: '321.654.987-00', email: 'fernanda@email.com', telefone: '(31) 95432-1098', endereco: 'Rua G, 700, Belo Horizonte-MG', processos: 1 },
25
+ { id: 8, nome: 'Roberto Santos', tipo: 'pf', cpfCnpj: '654.987.321-00', email: 'roberto@email.com', telefone: '(51) 94321-0987', endereco: 'Rua H, 800, Porto Alegre-RS', processos: 1 },
26
+ ],
27
+ evidencias: [],
28
+ intimacoes: [],
29
+ aaspConfig: { chave: '92E81C018B69454F8053133023AC438B' },
30
+ googleAuth: null,
31
+ driveConnected: false,
32
+ sheetsConnected: false,
33
+ importPreview: null,
34
+ };
35
+
36
+ // Load from localStorage
37
+ function loadAppData() {
38
+ const saved = localStorage.getItem('legaldata_app');
39
+ if (saved) {
40
+ try {
41
+ const parsed = JSON.parse(saved);
42
+ appData = { ...appData, ...parsed };
43
+ } catch(e) { console.error('Error loading data', e); }
44
+ }
45
+ }
46
+
47
+ function saveAppData() {
48
+ localStorage.setItem('legaldata_app', JSON.stringify(appData));
49
+ }
50
+
51
+ // --- Tab Navigation ---
52
+ function showTab(tabId, navEl) {
53
+ document.querySelectorAll('.tab-content').forEach(t => t.classList.remove('active'));
54
+ document.querySelectorAll('.nav-link').forEach(n => n.classList.remove('active-nav'));
55
+
56
+ const tab = document.getElementById(tabId);
57
+ if (tab) tab.classList.add('active');
58
+
59
+ if (navEl) {
60
+ navEl.classList.add('active-nav');
61
+ } else {
62
+ document.querySelectorAll('.nav-link').forEach(n => {
63
+ if (n.getAttribute('onclick') && n.getAttribute('onclick').includes(tabId)) {
64
+ n.classList.add('active-nav');
65
+ }
66
+ });
67
+ }
68
+
69
+ const titles = {
70
+ dashboard: 'Dashboard', processos: 'Gestão de Processos', clientes: 'Gestão de Clientes',
71
+ provas: 'Galeria de Provas', intimacoes: 'Intimações AASP', import: 'Importar Dados',
72
+ config: 'Configurações', sanitize: 'Sanitização de Dados', integrations: 'Integrações'
73
+ };
74
+ document.getElementById('current-tab-title').textContent = titles[tabId] || tabId;
75
+
76
+ if (tabId === 'provas') renderEvidence();
77
+ if (tabId === 'processos') renderProcessos();
78
+ if (tabId === 'clientes') renderClientes();
79
+ }
80
+
81
+ function toggleSidebar() {
82
+ document.getElementById('sidebar').classList.toggle('collapsed');
83
+ }
84
+
85
+ // --- Modal Management ---
86
+ function showModal(id) {
87
+ const modal = document.getElementById('modal-' + id);
88
+ if (modal) modal.classList.remove('hidden');
89
+ }
90
+
91
+ function hideModal(id) {
92
+ const modal = document.getElementById('modal-' + id);
93
+ if (modal) modal.classList.add('hidden');
94
+ }
95
+
96
+ // --- Toast Notifications ---
97
+ function showToast(message, type = 'success') {
98
+ const container = document.getElementById('toast-container');
99
+ const colors = { success: 'bg-green-500', error: 'bg-red-500', info: 'bg-blue-500', warning: 'bg-yellow-500' };
100
+ const icons = { success: 'fa-check-circle', error: 'fa-times-circle', info: 'fa-info-circle', warning: 'fa-exclamation-triangle' };
101
+
102
+ const toast = document.createElement('div');
103
+ toast.className = `toast ${colors[type]} text-white px-4 py-3 rounded-lg shadow-lg flex items-center space-x-3 min-w-72`;
104
+ toast.innerHTML = `<i class="fas ${icons[type]}"></i><span>${message}</span>`;
105
+ container.appendChild(toast);
106
+
107
+ requestAnimationFrame(() => toast.classList.add('show'));
108
+ setTimeout(() => {
109
+ toast.classList.remove('show');
110
+ setTimeout(() => toast.remove(), 400);
111
+ }, 4000);
112
+ }
113
+
114
+ // --- Processos ---
115
+ function renderProcessos() {
116
+ const tbody = document.getElementById('processos-table-body');
117
+ if (!tbody) return;
118
+
119
+ const statusColors = {
120
+ 'Ativo': 'bg-green-100 text-green-800',
121
+ 'Pendente': 'bg-yellow-100 text-yellow-800',
122
+ 'Urgente': 'bg-red-100 text-red-800',
123
+ 'Concluído': 'bg-blue-100 text-blue-800',
124
+ 'Arquivado': 'bg-gray-100 text-gray-800'
125
+ };
126
+
127
+ tbody.innerHTML = appData.processos.map(p => `
128
+ <tr class="hover:bg-gray-50">
129
+ <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">#${p.id}</td>
130
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${p.cliente}</td>
131
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${p.tribunal}</td>
132
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${formatDate(p.data)}</td>
133
+ <td class="px-6 py-4 whitespace-nowrap"><span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${statusColors[p.status] || 'bg-gray-100 text-gray-800'}">${p.status}</span></td>
134
+ <td class="px-6 py-4 whitespace-nowrap text-sm">
135
+ <button class="text-indigo-600 hover:text-indigo-900 mr-3" title="Ver"><i class="fas fa-eye"></i></button>
136
+ <button class="text-green-600 hover:text-green-900 mr-3" title="Editar"><i class="fas fa-edit"></i></button>
137
+ <button class="text-red-600 hover:text-red-900" onclick="deleteProcess('${p.id}')" title="Excluir"><i class="fas fa-trash"></i></button>
138
+ </td>
139
+ </tr>
140
+ `).join('');
141
+ }
142
+
143
+ function addProcess() {
144
+ const proc = {
145
+ id: document.getElementById('proc-numero').value || generateId(),
146
+ cliente: document.getElementById('proc-cliente').value,
147
+ tribunal: document.getElementById('proc-tribunal').value,
148
+ data: document.getElementById('proc-data').value,
149
+ status: document.getElementById('proc-status').value,
150
+ prazo: null,
151
+ descricao: document.getElementById('proc-descricao').value
152
+ };
153
+ appData.processos.push(proc);
154
+ saveAppData();
155
+ renderProcessos();
156
+ hideModal('new-process');
157
+ showToast('Processo adicionado com sucesso!');
158
+ updateStats();
159
+ }
160
+
161
+ function deleteProcess(id) {
162
+ if (confirm('Deseja excluir este processo?')) {
163
+ appData.processos = appData.processos.filter(p => p.id !== id);
164
+ saveAppData();
165
+ renderProcessos();
166
+ showToast('Processo excluído', 'info');
167
+ updateStats();
168
+ }
169
+ }
170
+
171
+ // --- Clientes ---
172
+ function renderClientes() {
173
+ const tbody = document.getElementById('clientes-table-body');
174
+ if (!tbody) return;
175
+
176
+ tbody.innerHTML = appData.clientes.map(c => `
177
+ <tr class="hover:bg-gray-50">
178
+ <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${c.nome}</td>
179
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${c.cpfCnpj}</td>
180
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${c.email}</td>
181
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${c.telefone}</td>
182
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${c.processos}</td>
183
+ <td class="px-6 py-4 whitespace-nowrap text-sm">
184
+ <button class="text-indigo-600 hover:text-indigo-900 mr-3" title="Ver"><i class="fas fa-eye"></i></button>
185
+ <button class="text-green-600 hover:text-green-900 mr-3" title="Editar"><i class="fas fa-edit"></i></button>
186
+ <button class="text-red-600 hover:text-red-900" onclick="deleteClient(${c.id})" title="Excluir"><i class="fas fa-trash"></i></button>
187
+ </td>
188
+ </tr>
189
+ `).join('');
190
+ }
191
+
192
+ function addClient() {
193
+ const cli = {
194
+ id: Date.now(),
195
+ nome: document.getElementById('cli-nome').value,
196
+ tipo: document.getElementById('cli-tipo').value,
197
+ cpfCnpj: document.getElementById('cli-cpfcnpj').value,
198
+ email: document.getElementById('cli-email').value,
199
+ telefone: document.getElementById('cli-telefone').value,
200
+ endereco: document.getElementById('cli-endereco').value,
201
+ processos: 0
202
+ };
203
+ appData.clientes.push(cli);
204
+ saveAppData();
205
+ renderClientes();
206
+ hideModal('new-client');
207
+ showToast('Cliente adicionado com sucesso!');
208
+ updateStats();
209
+ populateSelects();
210
+ }
211
+
212
+ function deleteClient(id) {
213
+ if (confirm('Deseja excluir este cliente?')) {
214
+ appData.clientes = appData.clientes.filter(c => c.id !== id);
215
+ saveAppData();
216
+ renderClientes();
217
+ showToast('Cliente excluído', 'info');
218
+ updateStats();
219
+ }
220
+ }
221
+
222
+ // --- Evidence Gallery ---
223
+ let selectedEvidenceFiles = [];
224
+ let currentEvidenceIndex = 0;
225
+
226
+ function renderEvidence() {
227
+ const grid = document.getElementById('evidence-grid');
228
+ const noEv = document.getElementById('no-evidence');
229
+ if (!grid) return;
230
+
231
+ const filterClient = document.getElementById('evidence-filter-client')?.value || '';
232
+ const filterType = document.getElementById('evidence-filter-type')?.value || '';
233
+
234
+ let filtered = appData.evidencias;
235
+ if (filterClient) filtered = filtered.filter(e => e.clienteId == filterClient);
236
+ if (filterType) filtered = filtered.filter(e => e.categoria.toLowerCase().includes(filterType));
237
+
238
+ if (filtered.length === 0) {
239
+ grid.innerHTML = '';
240
+ noEv?.classList.remove('hidden');
241
+ return;
242
+ }
243
+ noEv?.classList.add('hidden');
244
+
245
+ grid.innerHTML = filtered.map((ev, i) => {
246
+ const icon = getFileIcon(ev.tipo);
247
+ const thumb = ev.thumb || `http://static.photos/${ev.categoria === 'foto' ? 'people' : 'office'}/320x240/${ev.id}`;
248
+ return `
249
+ <div class="evidence-card bg-white rounded-xl shadow overflow-hidden cursor-pointer transition" onclick="viewEvidence(${ev.id})">
250
+ <div class="h-40 bg-gray-100 flex items-center justify-center overflow-hidden">
251
+ ${ev.tipo && ev.tipo.startsWith('image/') ?
252
+ `<img src="${thumb}" class="w-full h-full object-cover" alt="${ev.descricao}">` :
253
+ `<i class="${icon} text-5xl text-gray-300"></i>`}
254
+ </div>
255
+ <div class="p-3">
256
+ <p class="font-medium text-sm truncate">${ev.descricao || 'Sem descrição'}</p>
257
+ <p class="text-xs text-gray-500 mt-1">${ev.clienteNome || 'N/A'} • ${formatDate(ev.data)}</p>
258
+ <div class="flex items-center justify-between mt-2">
259
+ <span class="text-xs px-2 py-1 rounded-full bg-indigo-100 text-indigo-700">${ev.categoria}</span>
260
+ ${ev.driveId ? '<i class="fab fa-google-drive text-blue-500 text-xs" title="No Google Drive"></i>' : ''}
261
+ </div>
262
+ </div>
263
+ </div>`;
264
+ }).join('');
265
+
266
+ document.getElementById('stat-provas').textContent = appData.evidencias.length;
267
+ }
268
+
269
+ function getFileIcon(tipo) {
270
+ if (!tipo) return 'fas fa-file';
271
+ if (tipo.startsWith('image/')) return 'fas fa-file-image';
272
+ if (tipo === 'application/pdf') return 'fas fa-file-pdf';
273
+ if (tipo.startsWith('video/')) return 'fas fa-file-video';
274
+ if (tipo.startsWith('audio/')) return 'fas fa-file-audio';
275
+ return 'fas fa-file';
276
+ }
277
+
278
+ function handleEvidenceDrop(event) {
279
+ const files = event.dataTransfer.files;
280
+ processEvidenceFiles(files);
281
+ }
282
+
283
+ function handleEvidenceSelect(event) {
284
+ const files = event.target.files;
285
+ processEvidenceFiles(files);
286
+ }
287
+
288
+ function processEvidenceFiles(files) {
289
+ selectedEvidenceFiles = Array.from(files);
290
+ const preview = document.getElementById('ev-preview');
291
+ preview.innerHTML = '';
292
+ preview.classList.remove('hidden');
293
+
294
+ selectedEvidenceFiles.forEach((file, i) => {
295
+ if (file.type.startsWith('image/')) {
296
+ const reader = new FileReader();
297
+ reader.onload = (e) => {
298
+ preview.innerHTML += `<div class="relative"><img src="${e.target.result}" class="w-full h-20 object-cover rounded"><span class="absolute top-1 right-1 bg-black bg-opacity-50 text-white text-xs px-1 rounded">${file.name.length > 15 ? file.name.substring(0,12)+'...' : file.name}</span></div>`;
299
+ };
300
+ reader.readAsDataURL(file);
301
+ } else {
302
+ preview.innerHTML += `<div class="bg-gray-100 rounded p-2 text-center"><i class="${getFileIcon(file.type)} text-2xl text-gray-400"></i><p class="text-xs text-gray-500 mt-1 truncate">${file.name}</p></div>`;
303
+ }
304
+ });
305
+ }
306
+
307
+ function uploadEvidence() {
308
+ const clienteId = document.getElementById('ev-cliente').value;
309
+ const cliente = appData.clientes.find(c => c.id == clienteId);
310
+ const processo = document.getElementById('ev-processo').value;
311
+ const categoria = document.getElementById('ev-categoria').value;
312
+ const descricao = document.getElementById('ev-descricao').value;
313
+ const uploadToDrive = document.getElementById('ev-upload-drive').checked;
314
+
315
+ if (!clienteId) { showToast('Selecione um cliente', 'error'); return; }
316
+ if (selectedEvidenceFiles.length === 0) { showToast('Selecione ao menos um arquivo', 'error'); return; }
317
+
318
+ selectedEvidenceFiles.forEach((file, i) => {
319
+ const evId = Date.now() + i;
320
+ const evidencia = {
321
+ id: evId,
322
+ clienteId: parseInt(clienteId),
323
+ clienteNome: cliente?.nome || 'N/A',
324
+ processoId: processo,
325
+ categoria: categoria,
326
+ descricao: descricao || file.name,
327
+ tipo: file.type,
328
+ nomeArquivo: file.name,
329
+ data: new Date().toISOString(),
330
+ thumb: null,
331
+ driveId: null,
332
+ localData: null
333
+ };
334
+
335
+ // Create local thumbnail for images
336
+ if (file.type.startsWith('image/')) {
337
+ const reader = new FileReader();
338
+ reader.onload = (e) => {
339
+ evidencia.thumb = e.target.result;
340
+ evidencia.localData = e.target.result;
341
+ appData.evidencias.push(evidencia);
342
+ saveAppData();
343
+ renderEvidence();
344
+ };
345
+ reader.readAsDataURL(file);
346
+ } else {
347
+ // Store file reference
348
+ const reader = new FileReader();
349
+ reader.onload = (e) => {
350
+ evidencia.localData = e.target.result;
351
+ appData.evidencias.push(evidencia);
352
+ saveAppData();
353
+ renderEvidence();
354
+ };
355
+ reader.readAsDataURL(file);
356
+ }
357
+
358
+ // Upload to Google Drive if connected and checked
359
+ if (uploadToDrive && appData.driveConnected) {
360
+ uploadToGoogleDrive(file, evId);
361
+ }
362
+ });
363
+
364
+ selectedEvidenceFiles = [];
365
+ document.getElementById('ev-preview').innerHTML = '';
366
+ document.getElementById('ev-preview').classList.add('hidden');
367
+ hideModal('upload-evidence');
368
+ showToast('Prova(s) enviada(s) com sucesso!');
369
+ updateStats();
370
+ }
371
+
372
+ function viewEvidence(id) {
373
+ const ev = appData.evidencias.find(e => e.id === id);
374
+ if (!ev) return;
375
+
376
+ currentEvidenceIndex = appData.evidencias.findIndex(e => e.id === id);
377
+
378
+ const content = document.getElementById('lightbox-content');
379
+ const caption = document.getElementById('lightbox-caption');
380
+
381
+ if (ev.tipo && ev.tipo.startsWith('image/') && ev.localData) {
382
+ content.innerHTML = `<img src="${ev.localData}" class="max-w-full max-h-[70vh] object-contain rounded">`;
383
+ } else if (ev.tipo === 'application/pdf' && ev.localData) {
384
+ content.innerHTML = `<iframe src="${ev.localData}" class="w-full h-[70vh] rounded" frameborder="0"></iframe>`;
385
+ } else if (ev.tipo && ev.tipo.startsWith('video/') && ev.localData) {
386
+ content.innerHTML = `<video src="${ev.localData}" controls class="max-w-full max-h-[70vh] rounded"></video>`;
387
+ } else if (ev.tipo && ev.tipo.startsWith('audio/') && ev.localData) {
388
+ content.innerHTML = `<div class="text-center"><i class="fas fa-music text-6xl text-white mb-6"></i><audio src="${ev.localData}" controls class="w-96"></audio></div>`;
389
+ } else {
390
+ content.innerHTML = `<div class="text-center"><i class="${getFileIcon(ev.tipo)} text-8xl text-white mb-4"></i><p class="text-white text-xl">${ev.nomeArquivo || 'Arquivo'}</p><p class="text-gray-400">Pré-visualização não disponível</p></div>`;
391
+ }
392
+
393
+ caption.textContent = `${ev.descricao} — ${ev.clienteNome} — ${formatDate(ev.data)}`;
394
+ document.getElementById('lightbox').classList.add('active');
395
+ }
396
+
397
+ function closeLightbox() {
398
+ document.getElementById('lightbox').classList.remove('active');
399
+ }
400
+
401
+ function navigateEvidence(direction) {
402
+ currentEvidenceIndex += direction;
403
+ if (currentEvidenceIndex < 0) currentEvidenceIndex = appData.evidencias.length - 1;
404
+ if (currentEvidenceIndex >= appData.evidencias.length) currentEvidenceIndex = 0;
405
+ const ev = appData.evidencias[currentEvidenceIndex];
406
+ if (ev) viewEvidence(ev.id);
407
+ }
408
+
409
+ function filterEvidence() {
410
+ renderEvidence();
411
+ }
412
+
413
+ // --- AASP Integration ---
414
+ const AASP_BASE_URL = 'https://api.aasp.org.br';
415
+
416
+ async function fetchAASPIntimacoes() {
417
+ const chave = document.getElementById('aasp-chave').value;
418
+ const tipo = document.getElementById('aasp-tipo').value;
419
+ const data = document.getElementById('aasp-data').value;
420
+ const diferencial = document.getElementById('aasp-diferencial').checked;
421
+ const codigo = document.getElementById('aasp-codigo').value;
422
+ const btn = document.getElementById('btn-fetch-aasp');
423
+
424
+ if (!chave) { showToast('Informe a chave de acesso AASP', 'error'); return; }
425
+
426
+ btn.disabled = true;
427
+ btn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Buscando...';
428
+
429
+ try {
430
+ const endpoint = tipo === 'empresa' ? 'Empresa' : 'Associado';
431
+ let url = `${AASP_BASE_URL}/api/${endpoint}/intimacao/json?chave=${encodeURIComponent(chave)}`;
432
+ if (data) url += `&data=${encodeURIComponent(data)}`;
433
+ if (diferencial) url += `&diferencial=true`;
434
+ if (tipo === 'empresa' && codigo) url += `&codigoPessoaAssociado=${codigo}`;
435
+
436
+ const response = await fetch(url);
437
+ if (!response.ok) throw new Error(`Erro HTTP: ${response.status}`);
438
+
439
+ const result = await response.json();
440
+ appData.intimacoes = Array.isArray(result) ? result : [result];
441
+
442
+ renderIntimacoes();
443
+ document.getElementById('stat-intimacoes').textContent = appData.intimacoes.length;
444
+ updateNotificationBadge();
445
+ showToast(`${appData.intimacoes.length} intimação(ões) encontrada(s)!`);
446
+ saveAppData();
447
+
448
+ } catch (error) {
449
+ console.error('AASP API Error:', error);
450
+ // Show mock data for demo
451
+ showAASPMockData();
452
+ showToast('Usando dados de demonstração (API pode requerer CORS proxy)', 'warning');
453
+ } finally {
454
+ btn.disabled = false;
455
+ btn.innerHTML = '<i class="fas fa-sync-alt mr-2"></i> Buscar Intimações';
456
+ }
457
+ }
458
+
459
+ function showAASPMockData() {
460
+ appData.intimacoes = [
461
+ { id: 1, dataDisponibilizacao: '2024-01-10', dataPublicacao: '2024-01-09', jornal: 'DJE - TJSP', orgao: 'TJSP', vara: '5ª Vara Cível', numeroProcesso: '2023-0456', nomeParte: 'João Silva', tipoIntimacao: 'Sentença', conteudo: 'Intimação da parte ré para ciência da sentença proferida nos autos...', advogado: 'Dr. Ricardo Mendes', OAB: 'OAB/SP 123.456' },
462
+ { id: 2, dataDisponibilizacao: '2024-01-10', dataPublicacao: '2024-01-09', jornal: 'DJE - TRF3', orgao: 'TRF3', vara: '2ª Vara Federal', numeroProcesso: '2023-0389', nomeParte: 'Maria Souza', tipoIntimacao: 'Despacho', conteudo: 'Intimação para manifestação sobre despacho que deferiu liminarmente a tutela de urgência...', advogado: 'Dra. Ana Paula Torres', OAB: 'OAB/SP 234.567' },
463
+ { id: 3, dataDisponibilizacao: '2024-01-11', dataPublicacao: '2024-01-10', jornal: 'DJE - TJMG', orgao: 'TJMG', vara: '1ª Vara de Fazenda Pública', numeroProcesso: '2023-0412', nomeParte: 'Empresa XYZ Ltda', tipoIntimacao: 'Decisão', conteudo: 'Intimação da requerida para, querendo, apresentar impugnação ao cumprimento de sentença...', advogado: 'Dr. Paulo Santos', OAB: 'OAB/MG 56.789' },
464
+ { id: 4, dataDisponibilizacao: '2024-01-12', dataPublicacao: '2024-01-11', jornal: 'DJE - TJSP', orgao: 'TJSP', vara: '15ª Vara Cível', numeroProcesso: '2023-0501', nomeParte: 'Ana Oliveira', tipoIntimacao: 'Audiência', conteudo: 'Intimação para audiência de conciliação designada para o dia 25/01/2024 às 14:00...', advogado: 'Dra. Carolina Lima', OAB: 'OAB/SP 345.678' },
465
+ ];
466
+ renderIntimacoes();
467
+ document.getElementById('stat-intimacoes').textContent = appData.intimacoes.length;
468
+ updateNotificationBadge();
469
+ saveAppData();
470
+ }
471
+
472
+ function renderIntimacoes() {
473
+ const list = document.getElementById('intimacoes-list');
474
+ const count = document.getElementById('intimacoes-count');
475
+
476
+ count.textContent = `${appData.intimacoes.length} resultado(s)`;
477
+
478
+ if (appData.intimacoes.length === 0) {
479
+ list.innerHTML = '<div class="text-center py-8 text-gray-400"><i class="fas fa-gavel text-4xl mb-3"></i><p>Nenhuma intimação encontrada</p></div>';
480
+ return;
481
+ }
482
+
483
+ list.innerHTML = appData.intimacoes.map((int, i) => {
484
+ const statusColor = int.tipoIntimacao === 'Sentença' ? 'bg-red-100 text-red-800' :
485
+ int.tipoIntimacao === 'Audiência' ? 'bg-yellow-100 text-yellow-800' :
486
+ 'bg-blue-100 text-blue-800';
487
+ return `
488
+ <div class="border border-gray-200 rounded-lg p-4 mb-3 hover:bg-gray-50 transition">
489
+ <div class="flex flex-wrap items-start justify-between gap-3 mb-2">
490
+ <div class="flex items-center space-x-3">
491
+ <span class="w-8 h-8 rounded-full bg-indigo-100 text-indigo-600 flex items-center justify-center text-sm font-bold">${i + 1}</span>
492
+ <div>
493
+ <p class="font-semibold">${int.numeroProcesso || 'N/A'} - ${int.nomeParte || 'N/A'}</p>
494
+ <p class="text-sm text-gray-500">${int.orgao || ''} • ${int.vara || ''}</p>
495
+ </div>
496
+ </div>
497
+ <div class="flex items-center space-x-2">
498
+ <span class="px-2 py-1 text-xs font-semibold rounded-full ${statusColor}">${int.tipoIntimacao || 'N/A'}</span>
499
+ <span class="text-sm text-gray-500">${formatDate(int.dataDisponibilizacao)}</span>
500
+ </div>
501
+ </div>
502
+ <div class="bg-gray-50 rounded p-3 mb-2">
503
+ <p class="text-sm text-gray-700">${(int.conteudo || '').substring(0, 200)}${(int.conteudo || '').length > 200 ? '...' : ''}</p>
504
+ </div>
505
+ <div class="flex items-center justify-between">
506
+ <div class="text-xs text-gray-400">
507
+ <span class="mr-3"><i class="fas fa-newspaper mr-1"></i>${int.jornal || 'N/A'}</span>
508
+ <span class="mr-3"><i class="fas fa-calendar mr-1"></i>Publicação: ${formatDate(int.dataPublicacao)}</span>
509
+ ${int.advogado ? `<span><i class="fas fa-user-tie mr-1"></i>${int.advogado}</span>` : ''}
510
+ </div>
511
+ <div class="flex space-x-2">
512
+ <button class="text-sm text-indigo-600 hover:text-indigo-800" onclick="linkIntimacaoToProcess(${int.id})"><i class="fas fa-link mr-1"></i>Vincular</button>
513
+ <button class="text-sm text-green-600 hover:text-green-800"><i class="fas fa-check mr-1"></i>Marcar Lida</button>
514
+ </div>
515
+ </div>
516
+ </div>`;
517
+ }).join('');
518
+ }
519
+
520
+ async function fetchAASPJornais() {
521
+ const chave = document.getElementById('aasp-chave').value;
522
+ const tipo = document.getElementById('aasp-tipo').value;
523
+
524
+ if (!chave) { showToast('Informe a chave AASP', 'error'); return; }
525
+
526
+ try {
527
+ const endpoint = tipo === 'empresa' ? 'Empresa' : 'Associado';
528
+ const url = `${AASP_BASE_URL}/api/${endpoint}/intimacao/GetJornaisComIntimacoes/json?chave=${encodeURIComponent(chave)}&qtdeDias=30`;
529
+
530
+ const response = await fetch(url);
531
+ const result = await response.json();
532
+ renderJornais(Array.isArray(result) ? result : [result]);
533
+ } catch(e) {
534
+ // Mock data
535
+ renderJornais([
536
+ { jornal: 'DJE - TJSP', quantidade: 12, dataUltima: '2024-01-12' },
537
+ { jornal: 'DJE - TRF3', quantidade: 5, dataUltima: '2024-01-11' },
538
+ { jornal: 'DJE - TJMG', quantidade: 3, dataUltima: '2024-01-10' },
539
+ ]);
540
+ showToast('Usando dados de demonstração para jornais', 'warning');
541
+ }
542
+ }
543
+
544
+ function renderJornais(jornais) {
545
+ const container = document.getElementById('jornais-results');
546
+ const list = document.getElementById('jornais-list');
547
+ container.classList.remove('hidden');
548
+
549
+ list.innerHTML = jornais.map(j => `
550
+ <div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg mb-2">
551
+ <div class="flex items-center space-x-3">
552
+ <i class="fas fa-newspaper text-indigo-600"></i>
553
+ <div>
554
+ <p class="font-medium">${j.jornal || j.NomeJornal || 'N/A'}</p>
555
+ <p class="text-sm text-gray-500">Última publicação: ${formatDate(j.dataUltima || j.DataUltima)}</p>
556
+ </div>
557
+ </div>
558
+ <span class="bg-indigo-100 text-indigo-700 px-3 py-1 rounded-full text-sm font-medium">${j.quantidade || j.Quantidade || 0} intimação(ões)</span>
559
+ </div>
560
+ `).join('');
561
+ }
562
+
563
+ function linkIntimacaoToProcess(intId) {
564
+ const int = appData.intimacoes.find(i => i.id === intId);
565
+ if (!int) return;
566
+ showToast(`Intimação ${int.numeroProcesso} vinculada ao processo!`, 'success');
567
+ }
568
+
569
+ function togglePassword(fieldId) {
570
+ const field = document.getElementById(fieldId);
571
+ if (field.type === 'password') {
572
+ field.type = 'text';
573
+ field.nextElementSibling.innerHTML = '<i class="fas fa-eye-slash"></i>';
574
+ } else {
575
+ field.type = 'password';
576
+ field.nextElementSibling.innerHTML = '<i class="fas fa-eye"></i>';
577
+ }
578
+ }
579
+
580
+ // --- Google Drive / Sheets Integration ---
581
+ let gapiLoaded = false;
582
+ let gisLoaded = false;
583
+ let tokenClient = null;
584
+
585
+ // Google API Configuration
586
+ // NOTE: In production, replace with your own Client ID from Google Cloud Console
587
+ const GOOGLE_CLIENT_ID = 'YOUR_GOOGLE_CLIENT_ID.apps.googleusercontent.com';
588
+ const GOOGLE_API_KEY = 'YOUR_GOOGLE_API_KEY';
589
+ const SCOPES = 'https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.readonly https://www.googleapis.com/auth/spreadsheets.readonly';
590
+ const SPREADSHEET_ID = '19EOpljeLASYLgyWhxJWtGBexELlt3GDoYBbcE5ZRExk';
591
+
592
+ function loadGoogleAPI() {
593
+ const script = document.createElement('script');
594
+ script.src = 'https://apis.google.com/js/api.js';
595
+ script.onload = () => {
596
+ gapi.load('client', async () => {
597
+ try {
598
+ await gapi.client.init({ apiKey: GOOGLE_API_KEY, discoveryDocs: ['https://www.googleapis.com/auth/drive.file', 'https://sheets.googleapis.com/$discovery/rest?version=v4'] });
599
+ gapiLoaded = true;
600
+ console.log('GAPI loaded');
601
+ } catch(e) { console.error('GAPI init error', e); }
602
+ });
603
+ };
604
+ document.body.appendChild(script);
605
+ }
606
+
607
+ function connectGoogleDrive() {
608
+ if (!GOOGLE_CLIENT_ID || GOOGLE_CLIENT_ID.includes('YOUR_GOOGLE')) {
609
+ showToast('Configure o Client ID do Google no app.js', 'warning');
610
+ showGoogleConfigInfo();
611
+ return;
612
+ }
613
+
614
+ try {
615
+ tokenClient = google.accounts.oauth2.initTokenClient({
616
+ client_id: GOOGLE_CLIENT_ID,
617
+ scope: SCOPES,
618
+ callback: (tokenResponse) => {
619
+ if (tokenResponse.error) {
620
+ showToast('Erro na autenticação Google: ' + tokenResponse.error, 'error');
621
+ return;
622
+ }
623
+ appData.driveConnected = true;
624
+ updateDriveStatus(true);
625
+ showToast('Google Drive conectado com sucesso!');
626
+ saveAppData();
627
+ }
628
+ });
629
+ tokenClient.requestAccessToken({ prompt: '' });
630
+ } catch(e) {
631
+ console.error('Google Auth Error:', e);
632
+ showToast('Erro ao conectar com Google. Verifique a configuração.', 'error');
633
+ showGoogleConfigInfo();
634
+ }
635
+ }
636
+
637
+ function connectGoogleSheets() {
638
+ if (!appData.driveConnected && (!GOOGLE_CLIENT_ID || GOOGLE_CLIENT_ID.includes('YOUR_GOOGLE'))) {
639
+ showToast('Configure o Google Client ID primeiro', 'warning');
640
+ showGoogleConfigInfo();
641
+ return;
642
+ }
643
+
644
+ if (!appData.driveConnected) {
645
+ connectGoogleDrive();
646
+ return;
647
+ }
648
+
649
+ fetchSpreadsheetData();
650
+ }
651
+
652
+ async function fetchSpreadsheetData() {
653
+ try {
654
+ const response = await gapi.client.sheets.spreadsheets.values.get({
655
+ spreadsheetId: SPREADSHEET_ID,
656
+ range: 'A:Z'
657
+ });
658
+
659
+ const rows = response.result.values;
660
+ if (rows && rows.length > 0) {
661
+ appData.importPreview = rows;
662
+ renderImportPreview(rows);
663
+ updateSheetsStatus(true);
664
+ showToast(`${rows.length - 1} registros importados da planilha!`);
665
+ }
666
+ } catch(e) {
667
+ console.error('Sheets API Error:', e);
668
+ // Show mock data
669
+ const mockRows = [
670
+ ['Nome', 'CPF/CNPJ', 'Email', 'Telefone', 'Endereço', 'Tipo Processo', 'Descrição'],
671
+ ['João da Silva', '123.456.789-00', 'joao@email.com', '(11) 98765-4321', 'Rua A, 100 - SP', 'Cível', 'Ação indenizatória por danos morais'],
672
+ ['Maria Oliveira', '987.654.321-00', 'maria@email.com', '(21) 99876-5432', 'Av B, 200 - RJ', 'Trabalhista', 'Reclamação trabalhista - horas extras'],
673
+ ['Empresa ABC Ltda', '12.345.678/0001-90', 'contato@abc.com', '(11) 3456-7890', 'Rua C, 300 - SP', 'Tributário', 'Mandado de segurança - ICMS'],
674
+ ];
675
+ appData.importPreview = mockRows;
676
+ renderImportPreview(mockRows);
677
+ updateSheetsStatus(true);
678
+ showToast('Dados de demonstração carregados', 'warning');
679
+ }
680
+ }
681
+
682
+ function renderImportPreview(rows) {
683
+ const container = document.getElementById('import-preview');
684
+ const table = document.getElementById('import-preview-table');
685
+ container.classList.remove('hidden');
686
+
687
+ if (!rows || rows.length === 0) return;
688
+
689
+ const headers = rows[0];
690
+ let html = '<thead class="bg-gray-50"><tr>';
691
+ headers.forEach(h => html += `<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">${h}</th>`);
692
+ html += '</tr></thead><tbody class="bg-white divide-y divide-gray-200">';
693
+
694
+ rows.slice(1).forEach(row => {
695
+ html += '<tr>';
696
+ row.forEach(cell => html += `<td class="px-4 py-2 text-sm text-gray-500 whitespace-nowrap">${cell || ''}</td>`);
697
+ html += '</tr>';
698
+ });
699
+ html += '</tbody>';
700
+ table.innerHTML = html;
701
+ }
702
+
703
+ function confirmImport() {
704
+ if (!appData.importPreview) return;
705
+
706
+ const rows = appData.importPreview;
707
+ const headers = rows[0];
708
+
709
+ // Find column indices
710
+ const nomeIdx = headers.findIndex(h => /nome/i.test(h));
711
+ const cpfIdx = headers.findIndex(h => /cpf|cnpj/i.test(h));
712
+ const emailIdx = headers.findIndex(h => /email|e-mail/i.test(h));
713
+ const telIdx = headers.findIndex(h => /telef/i.test(h));
714
+ const endIdx = headers.findIndex(h => /endere/i.test(h));
715
+
716
+ rows.slice(1).forEach(row => {
717
+ const exists = appData.clientes.find(c => c.cpfCnpj === (row[cpfIdx] || ''));
718
+ if (!exists && row[nomeIdx]) {
719
+ appData.clientes.push({
720
+ id: Date.now() + Math.random(),
721
+ nome: row[nomeIdx] || '',
722
+ tipo: (row[cpfIdx] || '').length > 14 ? 'pj' : 'pf',
723
+ cpfCnpj: row[cpfIdx] || '',
724
+ email: row[emailIdx] || '',
725
+ telefone: row[telIdx] || '',
726
+ endereco: row[endIdx] || '',
727
+ processos: 0
728
+ });
729
+ }
730
+ });
731
+
732
+ saveAppData();
733
+ updateStats();
734
+ showToast('Dados importados com sucesso!');
735
+ }
736
+
737
+ async function uploadToGoogleDrive(file, evidenceId) {
738
+ if (!appData.driveConnected) return;
739
+
740
+ try {
741
+ const metadata = {
742
+ name: `[LegalData] ${file.name}`,
743
+ parents: [],
744
+ description: `Prova enviada via LegalData Manager - ID: ${evidenceId}`
745
+ };
746
+
747
+ const form = new FormData();
748
+ form.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' }));
749
+ form.append('file', file);
750
+
751
+ const response = await fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart', {
752
+ method: 'POST',
753
+ headers: new Headers({ 'Authorization': 'Bearer ' + gapi.auth.getToken().access_token }),
754
+ body: form
755
+ });
756
+
757
+ const result = await response.json();
758
+ const ev = appData.evidencias.find(e => e.id === evidenceId);
759
+ if (ev) {
760
+ ev.driveId = result.id;
761
+ saveAppData();
762
+ showToast('Arquivo salvo no Google Drive!', 'info');
763
+ }
764
+ } catch(e) {
765
+ console.error('Drive upload error:', e);
766
+ showToast('Erro ao salvar no Drive', 'error');
767
+ }
768
+ }
769
+
770
+ function updateDriveStatus(connected) {
771
+ appData.driveConnected = connected;
772
+
773
+ const icon = document.getElementById('drive-icon');
774
+ const text = document.getElementById('drive-status-text');
775
+ const sub = document.getElementById('drive-status-sub');
776
+ const btn = document.getElementById('drive-connect-btn');
777
+ const dot = document.getElementById('drive-conn-dot');
778
+ const label = document.getElementById('drive-conn-label');
779
+ const intBtn = document.getElementById('drive-integration-btn');
780
+
781
+ if (connected) {
782
+ if (icon) icon.className = 'w-10 h-10 rounded-lg bg-green-100 flex items-center justify-center text-green-600';
783
+ if (icon) icon.innerHTML = '<i class="fab fa-google-drive text-xl"></i>';
784
+ if (text) text.textContent = 'Google Drive conectado';
785
+ if (sub) sub.textContent = 'Arquivos serão sincronizados automaticamente';
786
+ if (btn) { btn.textContent = 'Desconectar'; btn.className = 'bg-red-100 text-red-600 px-4 py-2 rounded-lg hover:bg-red-200 transition'; btn.onclick = disconnectGoogleDrive; }
787
+ if (dot) { dot.className = 'w-3 h-3 rounded-full bg-green-500'; }
788
+ if (label) { label.textContent = 'Conectado'; label.className = 'text-sm text-green-600 font-medium'; }
789
+ if (intBtn) { intBtn.textContent = 'Desconectar'; intBtn.className = 'w-full bg-red-100 text-red-600 py-2 rounded-lg hover:bg-red-200 transition'; }
790
+ } else {
791
+ if (icon) icon.className = 'w-10 h-10 rounded-lg bg-gray-100 flex items-center justify-center text-gray-400';
792
+ if (icon) icon.innerHTML = '<i class="fab fa-google-drive text-xl"></i>';
793
+ if (text) text.textContent = 'Google Drive desconectado';
794
+ if (sub) sub.textContent = 'Conecte para sincronizar provas na nuvem';
795
+ if (btn) { btn.innerHTML = '<i class="fab fa-google mr-2"></i> Conectar Google Drive'; btn.className = 'bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition'; btn.onclick = connectGoogleDrive; }
796
+ if (dot) { dot.className = 'w-3 h-3 rounded-full bg-gray-400'; }
797
+ if (label) { label.textContent = 'Desconectado'; label.className = 'text-sm text-gray-500 font-medium'; }
798
+ }
799
+ }
800
+
801
+ function updateSheetsStatus(connected) {
802
+ appData.sheetsConnected = connected;
803
+ const dot = document.getElementById('sheets-conn-dot');
804
+ const label = document.getElementById('sheets-conn-label');
805
+ const btn = document.getElementById('sheets-integration-btn');
806
+
807
+ if (connected) {
808
+ if (dot) dot.className = 'w-3 h-3 rounded-full bg-green-500';
809
+ if (label) { label.textContent = 'Conectado'; label.className = 'text-sm text-green-600 font-medium'; }
810
+ if (btn) { btn.textContent = 'Sincronizar Dados'; btn.className = 'w-full bg-green-100 text-green-700 py-2 rounded-lg hover:bg-green-200 transition'; }
811
+ }
812
+ }
813
+
814
+ function disconnectGoogleDrive() {
815
+ if (tokenClient) {
816
+ const token = gapi?.auth?.getToken();
817
+ if (token) google.accounts.oauth2.revoke(token.access_token);
818
+ }
819
+ updateDriveStatus(false);
820
+ updateSheetsStatus(false);
821
+ showToast('Google Drive desconectado', 'info');
822
+ }
823
+
824
+ function showGoogleConfigInfo() {
825
+ const info = `
826
+ <div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4 mb-4">
827
+ <h4 class="font-semibold text-yellow-800 mb-2"><i class="fas fa-info-circle mr-2"></i>Configuração do Google OAuth</h4>
828
+ <p class="text-sm text-yellow-700 mb-2">Para usar as integrações Google, você precisa:</p>
829
+ <ol class="text-sm text-yellow-700 list-decimal list-inside space-y-1">
830
+ <li>Acessar <a href="https://console.cloud.google.com/" target="_blank" class="underline text-yellow-800">Google Cloud Console</a></li>
831
+ <li>Criar um projeto e ativar as APIs: Google Drive API e Google Sheets API</li>
832
+ <li>Criar credenciais OAuth 2.0</li>
833
+ <li>Adicionar <code class="bg-yellow-100 px-1 rounded">http://localhost</code> como origem autorizada</li>
834
+ <li>Copiar o Client ID e atualizar no arquivo <code class="bg-yellow-100 px-1 rounded">app.js</code></li>
835
+ </ol>
836
+ <p class="text-sm text-yellow-700 mt-2">Enquanto isso, o sistema funciona com dados locais e de demonstração.</p>
837
+ </div>`;
838
+
839
+ const list = document.getElementById('intimacoes-list');
840
+ if (list) list.innerHTML = info + list.innerHTML;
841
+ }
842
+
843
+ // --- File Import ---
844
+ function handleFileImport(event) {
845
+ const file = event.target.files[0];
846
+ if (!file) return;
847
+
848
+ if (file.name.endsWith('.csv')) {
849
+ Papa.parse(file, {
850
+ header: true,
851
+ complete: (results) => {
852
+ appData.importPreview = [results.meta.fields, ...results.data.map(r => results.meta.fields.map(f => r[f]))];
853
+ renderImportPreview(appData.importPreview);
854
+ showToast(`${results.data.length} registros importados do CSV`);
855
+ }
856
+ });
857
+ } else if (file.name.endsWith('.xlsx') || file.name.endsWith('.xls')) {
858
+ const reader = new FileReader();
859
+ reader.onload = (e) => {
860
+ const data = new Uint8Array(e.target.result);
861
+ const workbook = XLSX.read(data, { type: 'array' });
862
+ const sheetName = workbook.SheetNames[0];
863
+ const sheet = workbook.Sheets[sheetName];
864
+ const jsonData = XLSX.utils.sheet_to_json(sheet, { header: 1 });
865
+ appData.importPreview = jsonData;
866
+ renderImportPreview(jsonData);
867
+ showToast(`${jsonData.length - 1} registros importados do Excel`);
868
+ };
869
+ reader.readAsArrayBuffer(file);
870
+ }
871
+ }
872
+
873
+ // --- Sanitization ---
874
+ function sanitizeData(type) {
875
+ let count = 0;
876
+ switch(type) {
877
+ case 'cpfcnpj':
878
+ appData.clientes.forEach(c => {
879
+ c.cpfCnpj = c.cpfCnpj.replace(/[^\d./-]/g, '');
880
+ count++;
881
+ });
882
+ showToast(`${count} CPFs/CNPJs padronizados`);
883
+ break;
884
+ case 'phone':
885
+ appData.clientes.forEach(c => {
886
+ c.telefone = c.telefone.replace(/[^\d() -]/g, '');
887
+ count++;
888
+ });
889
+ showToast(`${count} telefones padronizados`);
890
+ break;
891
+ case 'email':
892
+ const invalid = appData.clientes.filter(c => !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(c.email));
893
+ showToast(`${invalid.length} e-mails inválidos encontrados`, invalid.length > 0 ? 'warning' : 'success');
894
+ break;
895
+ case 'duplicates':
896
+ const seen = new Set();
897
+ const before = appData.clientes.length;
898
+ appData.clientes = appData.clientes.filter(c => {
899
+ const key = c.cpfCnpj || c.email;
900
+ if (seen.has(key)) return false;
901
+ seen.add(key);
902
+ return true;
903
+ });
904
+ count = before - appData.clientes.length;
905
+ showToast(`${count} duplicatas removidas`, count > 0 ? 'info' : 'success');
906
+ break;
907
+ }
908
+ saveAppData();
909
+ renderClientes();
910
+ }
911
+
912
+ // --- Utility Functions ---
913
+ function formatDate(dateStr) {
914
+ if (!dateStr) return 'N/A';
915
+ try {
916
+ const d = new Date(dateStr);
917
+ return d.toLocaleDateString('pt-BR');
918
+ } catch(e) { return dateStr; }
919
+ }
920
+
921
+ function generateId() {
922
+ return '2024-' + String(Math.floor(Math.random() * 9000) + 1000);
923
+ }
924
+
925
+ function updateStats() {
926
+ document.getElementById('stat-processos').textContent = appData.processos.length;
927
+ document.getElementById('stat-clientes').textContent = appData.clientes.length;
928
+ document.getElementById('stat-provas').textContent = appData.evidencias.length;
929
+ }
930
+
931
+ function updateNotificationBadge() {
932
+ const badge = document.getElementById('notification-badge');
933
+ const count = appData.intimacoes.length;
934
+ if (count > 0) {
935
+ badge.textContent = count;
936
+ badge.classList.remove('hidden');
937
+ } else {
938
+ badge.classList.add('hidden');
939
+ }
940
+ }
941
+
942
+ function populateSelects() {
943
+ // Populate client selects
944
+ const clientSelects = ['proc-cliente', 'ev-cliente'];
945
+ clientSelects.forEach(id => {
946
+ const el = document.getElementById(id);
947
+ if (el) {
948
+ el.innerHTML = '<option value="">Selecione...</option>' +
949
+ appData.clientes.map(c => `<option value="${c.id}">${c.nome}</option>`).join('');
950
+ }
951
+ });
952
+
953
+ // Populate process selects
954
+ const procSelects = ['ev-processo'];
955
+ procSelects.forEach(id => {
956
+ const el = document.getElementById(id);
957
+ if (el) {
958
+ el.innerHTML = '<option value="">Selecione...</option>' +
959
+ appData.processos.map(p => `<option value="${p.id}">#${p.id} - ${p.cliente}</option>`).join('');
960
+ }
961
+ });
962
+
963
+ // Evidence filter
964
+ const filterClient = document.getElementById('evidence-filter-client');
965
+ if (filterClient) {
966
+ filterClient.innerHTML = '<option value="">Todos os Clientes</option>' +
967
+ appData.clientes.map(c => `<option value="${c.id}">${c.nome}</option>`).join('');
968
+ }
969
+ }
970
+
971
+ // --- Deadline Table ---
972
+ function renderDeadlineTable() {
973
+ const tbody = document.getElementById('deadline-table-body');
974
+ if (!tbody) return;
975
+
976
+ const urgent = appData.processos
977
+ .filter(p => p.prazo && p.status !== 'Concluído')
978
+ .sort((a, b) => new Date(a.prazo) - new Date(b.prazo))
979
+ .slice(0, 5);
980
+
981
+ const statusColors = {
982
+ 'Ativo': 'bg-green-100 text-green-800',
983
+ 'Pendente': 'bg-yellow-100 text-yellow-800',
984
+ 'Urgente': 'bg-red-100 text-red-800',
985
+ };
986
+
987
+ tbody.innerHTML = urgent.map(p => `
988
+ <tr>
989
+ <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">#${p.id}</td>
990
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${p.cliente}</td>
991
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${p.tribunal}</td>
992
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${formatDate(p.prazo)}</td>
993
+ <td class="px-6 py-4 whitespace-nowrap"><span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${statusColors[p.status] || 'bg-gray-100 text-gray-800'}">${p.status}</span></td>
994
+ <td class="px-6 py-4 whitespace-nowrap text-sm">
995
+ <button class="text-indigo-600 hover:text-indigo-900 mr-3"><i class="fas fa-eye"></i></button>
996
+ <button class="text-green-600 hover:text-green-900"><i class="fas fa-edit"></i></button>
997
+ </td>
998
+ </tr>
999
+ `).join('');
1000
+ }
1001
+
1002
+ // --- Chart ---
1003
+ function initChart() {
1004
+ const ctx = document.getElementById('processChart');
1005
+ if (!ctx) return;
1006
+
1007
+ new Chart(ctx, {
1008
+ type: 'doughnut',
1009
+ data: {
1010
+ labels: ['TJSP', 'TJMG', 'TRF1', 'TRF4', 'Outros'],
1011
+ datasets: [{
1012
+ data: [45, 20, 15, 12, 8],
1013
+ backgroundColor: ['#4F46E5', '#10B981', '#F59E0B', '#EF4444', '#6B7280'],
1014
+ borderWidth: 0
1015
+ }]
1016
+ },
1017
+ options: {
1018
+ responsive: true,
1019
+ maintainAspectRatio: false,
1020
+ plugins: {
1021
+ legend: { position: 'bottom' }
1022
+ }
1023
+ }
1024
+ });
1025
+ }
1026
+
1027
+ // --- Auto-refresh AASP ---
1028
+ let aaspInterval = null;
1029
+ function startAASPRefresh() {
1030
+ if (aaspInterval) clearInterval(aaspInterval);
1031
+ aaspInterval = setInterval(() => {
1032
+ if (document.getElementById('aasp-auto-refresh')?.checked) {
1033
+ fetchAASPIntimacoes();
1034
+ }
1035
+ }, 30 * 60 * 1000); // 30 minutes
1036
+ }
1037
+
1038
+ // --- Keyboard Shortcuts ---
1039
+ document.addEventListener('keydown', (e) => {
1040
+ if (e.key === 'Escape') {
1041
+ document.querySelectorAll('[id^="modal-"]').forEach(m => m.classList.add('hidden'));
1042
+ closeLightbox();
1043
+ }
1044
+ });
1045
+
1046
+ // --- Initialize ---
1047
+ document.addEventListener('DOMContentLoaded', () => {
1048
+ loadAppData();
1049
+ populateSelects();
1050
+ renderProcessos();
1051
+ renderClientes();
1052
+ renderDeadlineTable();
1053
+ initChart();
1054
+ updateStats();
1055
+ updateNotificationBadge();
1056
+
1057
+ if (appData.driveConnected) updateDriveStatus(true);
1058
+ if (appData.sheetsConnected) updateSheetsStatus(true);
1059
+
1060
+ startAASPRefresh();
1061
+
1062
+ // Set today's date for AASP query
1063
+ const today = new Date().toISOString().split('T')[0];
1064
+ const dataField = document.getElementById('aasp-data');
1065
+ if (dataField) dataField.value = today;
1066
+ });
cliente.html ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>LegalData Manager - Portal do Cliente</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .drop-zone { border: 2px dashed #c7d2fe; transition: all 0.3s; }
11
+ .drop-zone.dragover { border-color: #6366f1; background: #eef2ff; }
12
+ .step-circle { transition: all 0.3s; }
13
+ .step-circle.active { background: #4F46E5; color: white; }
14
+ .step-circle.completed { background: #10B981; color: white; }
15
+ .step-line.active { background: #4F46E5; }
16
+ .toast { transform: translateX(120%); transition: transform 0.4s ease; }
17
+ .toast.show { transform: translateX(0); }
18
+ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
19
+ .fade-in { animation: fadeIn 0.5s ease; }
20
+ .file-item { animation: fadeIn 0.3s ease; }
21
+ </style>
22
+ </head>
23
+ <body class="bg-gradient-to-br from-indigo-50 via-white to-purple-50 min-h-screen">
24
+ <!-- Toast Container -->
25
+ <div id="toast-container" class="fixed top-4 right-4 z-50 space-y-2"></div>
26
+
27
+ <div class="min-h-screen flex flex-col">
28
+ <!-- Header -->
29
+ <header class="bg-white shadow-sm">
30
+ <div class="max-w-4xl mx-auto px-4 py-4 flex justify-between items-center">
31
+ <div class="flex items-center space-x-3">
32
+ <div class="w-10 h-10 bg-indigo-600 rounded-lg flex items-center justify-center">
33
+ <i class="fas fa-balance-scale text-white text-lg"></i>
34
+ </div>
35
+ <div>
36
+ <h1 class="text-lg font-bold text-gray-800">LegalData Manager</h1>
37
+ <p class="text-xs text-gray-500">Portal do Cliente</p>
38
+ </div>
39
+ </div>
40
+ <a href="index.html" class="text-indigo-600 hover:text-indigo-800 text-sm font-medium flex items-center">
41
+ <i class="fas fa-arrow-left mr-1"></i> Área Administrativa
42
+ </a>
43
+ </div>
44
+ </header>
45
+
46
+ <!-- Main Content -->
47
+ <main class="flex-1 max-w-4xl mx-auto w-full px-4 py-8">
48
+ <!-- Steps Indicator -->
49
+ <div class="flex items-center justify-center mb-8">
50
+ <div class="flex items-center space-x-2">
51
+ <div class="step-circle active w-10 h-10 rounded-full flex items-center justify-center font-bold text-sm border-2 border-indigo-600" id="step-1">1</div>
52
+ <div class="step-line w-16 h-1 bg-gray-200 rounded" id="line-1"></div>
53
+ <div class="step-circle w-10 h-10 rounded-full flex items-center justify-center font-bold text-sm border-2 border-gray-300 text-gray-400" id="step-2">2</div>
54
+ <div class="step-line w-16 h-1 bg-gray-200 rounded" id="line-2"></div>
55
+ <div class="step-circle w-10 h-10 rounded-full flex items-center justify-center font-bold text-sm border-2 border-gray-300 text-gray-400" id="step-3">3</div>
56
+ </div>
57
+ </div>
58
+
59
+ <!-- Step 1: Registration Form -->
60
+ <div id="form-step-1" class="fade-in">
61
+ <div class="bg-white rounded-2xl shadow-lg p-6 md:p-8 mb-6">
62
+ <div class="text-center mb-6">
63
+ <div class="w-16 h-16 bg-indigo-100 rounded-full flex items-center justify-center mx-auto mb-4">
64
+ <i class="fas fa-user-plus text-2xl text-indigo-600"></i>
65
+ </div>
66
+ <h2 class="text-2xl font-bold text-gray-800">Cadastro de Cliente</h2>
67
+ <p class="text-gray-500 mt-1">Preencha seus dados para se cadastrar no escritório</p>
68
+ </div>
69
+
70
+ <form id="client-form" onsubmit="return handleClientSubmit(event)">
71
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
72
+ <div>
73
+ <label class="block text-sm font-medium text-gray-700 mb-1">Nome Completo *</label>
74
+ <input type="text" id="reg-nome" required class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent" placeholder="Seu nome completo">
75
+ </div>
76
+ <div>
77
+ <label class="block text-sm font-medium text-gray-700 mb-1">Tipo de Pessoa *</label>
78
+ <select id="reg-tipo" required class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500">
79
+ <option value="pf">Pessoa Física</option>
80
+ <option value="pj">Pessoa Jurídica</option>
81
+ </select>
82
+ </div>
83
+ </div>
84
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
85
+ <div>
86
+ <label class="block text-sm font-medium text-gray-700 mb-1">CPF/CNPJ *</label>
87
+ <input type="text" id="reg-cpfcnpj" required class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="000.000.000-00">
88
+ </div>
89
+ <div>
90
+ <label class="block text-sm font-medium text-gray-700 mb-1">RG/Inscrição Estadual</label>
91
+ <input type="text" id="reg-rg" class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="Opcional">
92
+ </div>
93
+ </div>
94
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
95
+ <div>
96
+ <label class="block text-sm font-medium text-gray-700 mb-1">E-mail *</label>
97
+ <input type="email" id="reg-email" required class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="seu@email.com">
98
+ </div>
99
+ <div>
100
+ <label class="block text-sm font-medium text-gray-700 mb-1">Telefone *</label>
101
+ <input type="text" id="reg-telefone" required class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="(00) 00000-0000">
102
+ </div>
103
+ </div>
104
+ <div class="mb-4">
105
+ <label class="block text-sm font-medium text-gray-700 mb-1">Endereço Completo</label>
106
+ <input type="text" id="reg-endereco" class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="Rua, número, complemento, bairro, cidade - UF">
107
+ </div>
108
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
109
+ <div>
110
+ <label class="block text-sm font-medium text-gray-700 mb-1">Profissão</label>
111
+ <input type="text" id="reg-profissao" class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="Sua profissão">
112
+ </div>
113
+ <div>
114
+ <label class="block text-sm font-medium text-gray-700 mb-1">Estado Civil</label>
115
+ <select id="reg-estadocivil" class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500">
116
+ <option value="">Selecione</option>
117
+ <option>Solteiro(a)</option>
118
+ <option>Casado(a)</option>
119
+ <option>Divorciado(a)</option>
120
+ <option>Viúvo(a)</option>
121
+ <option>Separado(a)</option>
122
+ <option>União Estável</option>
123
+ </select>
124
+ </div>
125
+ </div>
126
+ <div class="mb-4">
127
+ <label class="block text-sm font-medium text-gray-700 mb-1">Tipo de Processo</label>
128
+ <select id="reg-tipo-processo" class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500">
129
+ <option value="">Selecione</option>
130
+ <option value="civel">Cível</option>
131
+ <option value="trabalhista">Trabalhista</option>
132
+ <option value="tributario">Tributário</option>
133
+ <option value="criminal">Criminal</option>
134
+ <option value="familia">Família</option>
135
+ <option value="consumidor">Consumidor</option>
136
+ <option value="previdenciario">Previdenciário</option>
137
+ <option value="outro">Outro</option>
138
+ </select>
139
+ </div>
140
+ <div class="mb-4">
141
+ <label class="block text-sm font-medium text-gray-700 mb-1">Descrição do Caso</label>
142
+ <textarea id="reg-descricao" rows="4" class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="Descreva brevemente sua situação..."></textarea>
143
+ </div>
144
+ <div class="mb-4">
145
+ <label class="flex items-start space-x-2">
146
+ <input type="checkbox" required class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500 mt-1">
147
+ <span class="text-sm text-gray-600">Declaro que as informações fornecidas são verdadeiras e autorizo o uso dos dados para fins de prestação de serviços jurídicos, conforme a LGPD.</span>
148
+ </label>
149
+ </div>
150
+ <button type="submit" class="w-full bg-indigo-600 text-white py-3 rounded-lg hover:bg-indigo-700 transition font-semibold text-lg">
151
+ <i class="fas fa-arrow-right mr-2"></i> Próximo - Enviar Provas
152
+ </button>
153
+ </form>
154
+ </div>
155
+ </div>
156
+
157
+ <!-- Step 2: Evidence Upload -->
158
+ <div id="form-step-2" class="hidden fade-in">
159
+ <div class="bg-white rounded-2xl shadow-lg p-6 md:p-8 mb-6">
160
+ <div class="text-center mb-6">
161
+ <div class="w-16 h-16 bg-purple-100 rounded-full flex items-center justify-center mx-auto mb-4">
162
+ <i class="fas fa-cloud-upload-alt text-2xl text-purple-600"></i>
163
+ </div>
164
+ <h2 class="text-2xl font-bold text-gray-800">Envio de Provas</h2>
165
+ <p class="text-gray-500 mt-1">Envie documentos, fotos, vídeos ou áudios relacionados ao seu caso</p>
166
+ </div>
167
+
168
+ <div id="drop-zone-client" class="drop-zone rounded-xl p-8 text-center cursor-pointer mb-4" onclick="document.getElementById('client-file-input').click()" ondragover="event.preventDefault();this.classList.add('dragover')" ondragleave="this.classList.remove('dragover')" ondrop="event.preventDefault();this.classList.remove('dragover');handleClientFileDrop(event)">
169
+ <i class="fas fa-cloud-upload-alt text-5xl text-indigo-300 mb-3"></i>
170
+ <p class="text-lg text-gray-500 mb-1">Arraste arquivos aqui</p>
171
+ <p class="text-sm text-gray-400">ou clique para selecionar</p>
172
+ <p class="text-xs text-gray-400 mt-2">Imagens, PDFs, vídeos e áudios — até 10MB cada</p>
173
+ <input type="file" id="client-file-input" class="hidden" multiple accept="image/*,.pdf,video/*,audio/*" onchange="handleClientFileSelect(event)">
174
+ </div>
175
+
176
+ <div id="client-files-list" class="space-y-2 mb-4"></div>
177
+
178
+ <div class="mb-4">
179
+ <label class="block text-sm font-medium text-gray-700 mb-1">Categoria das Provas</label>
180
+ <select id="client-ev-category" class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500">
181
+ <option value="documento">Documento</option>
182
+ <option value="foto">Foto</option>
183
+ <option value="video">Vídeo</option>
184
+ <option value="audio">Áudio</option>
185
+ <option value="outro">Outro</option>
186
+ </select>
187
+ </div>
188
+ <div class="mb-4">
189
+ <label class="block text-sm font-medium text-gray-700 mb-1">Observações</label>
190
+ <textarea id="client-ev-notes" rows="2" class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="Informações adicionais sobre as provas..."></textarea>
191
+ </div>
192
+
193
+ <div class="flex space-x-3">
194
+ <button onclick="goToStep(1)" class="flex-1 bg-gray-100 text-gray-700 py-3 rounded-lg hover:bg-gray-200 transition font-semibold">
195
+ <i class="fas fa-arrow-left mr-2"></i> Voltar
196
+ </button>
197
+ <button onclick="submitClientEvidence()" class="flex-1 bg-indigo-600 text-white py-3 rounded-lg hover:bg-indigo-700 transition font-semibold">
198
+ <i class="fas fa-paper-plane mr-2"></i> Enviar Provas
199
+ </button>
200
+ </div>
201
+ </div>
202
+ </div>
203
+
204
+ <!-- Step 3: Confirmation -->
205
+ <div id="form-step-3" class="hidden fade-in">
206
+ <div class="bg-white rounded-2xl shadow-lg p-6 md:p-8 text-center">
207
+ <div class="w-20 h-20 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-6">
208
+ <i class="fas fa-check-circle text-4xl text-green-600"></i>
209
+ </div>
210
+ <h2 class="text-2xl font-bold text-gray-800 mb-2">Cadastro Enviado!</h2>
211
+ <p class="text-gray-500 mb-6">Suas informações e provas foram enviadas com sucesso. Nossa equipe entrará em contato em breve.</p>
212
+
213
+ <div id="confirmation-details" class="bg-gray-50 rounded-xl p-6 mb-6 text-left"></div>
214
+
215
+ <div class="flex flex-col space-y-3">
216
+ <button onclick="resetForm()" class="w-full bg-indigo-600 text-white py-3 rounded-lg hover:bg-indigo-700 transition font-semibold">
217
+ <i class="fas fa-plus mr-2"></i> Enviar Outro Cadastro
218
+ </button>
219
+ <a href="index.html" class="w-full bg-gray-100 text-gray-700 py-3 rounded-lg hover:bg-gray-200 transition font-semibold text-center">
220
+ <i class="fas fa-arrow-left mr-2"></i> Voltar à Área Administrativa
221
+ </button>
222
+ </div>
223
+ </div>
224
+ </div>
225
+ </main>
226
+
227
+ <!-- Footer -->
228
+ <footer class="bg-white border-t border-gray-200">
229
+ <div class="max-w-4xl mx-auto px-4 py-4 text-center text-sm text-gray-500">
230
+ <p>© 2024 LegalData Manager — Todos os direitos reservados</p>
231
+ <p class="text-xs mt-1">Seus dados são protegidos conforme a LGPD</p>
232
+ </div>
233
+ </footer>
234
+ </div>
235
+
236
+ <script src="cliente.js"></script>
237
+ </body>
238
+ </html>
cliente.js ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ==========================================
2
+ // LegalData Manager - Client Portal
3
+ // ==========================================
4
+
5
+ let clientFiles = [];
6
+ let clientData = {};
7
+
8
+ // --- Toast ---
9
+ function showToast(message, type = 'success') {
10
+ const container = document.getElementById('toast-container');
11
+ const colors = { success: 'bg-green-500', error: 'bg-red-500', info: 'bg-blue-500', warning: 'bg-yellow-500' };
12
+ const icons = { success: 'fa-check-circle', error: 'fa-times-circle', info: 'fa-info-circle', warning: 'fa-exclamation-triangle' };
13
+
14
+ const toast = document.createElement('div');
15
+ toast.className = `toast ${colors[type]} text-white px-4 py-3 rounded-lg shadow-lg flex items-center space-x-3 min-w-72`;
16
+ toast.innerHTML = `<i class="fas ${icons[type]}"></i><span>${message}</span>`;
17
+ container.appendChild(toast);
18
+
19
+ requestAnimationFrame(() => toast.classList.add('show'));
20
+ setTimeout(() => { toast.classList.remove('show'); setTimeout(() => toast.remove(), 400); }, 4000);
21
+ }
22
+
23
+ // --- Step Navigation ---
24
+ function goToStep(step) {
25
+ // Hide all steps
26
+ document.getElementById('form-step-1').classList.add('hidden');
27
+ document.getElementById('form-step-2').classList.add('hidden');
28
+ document.getElementById('form-step-3').classList.add('hidden');
29
+
30
+ // Show current step
31
+ document.getElementById('form-step-' + step).classList.remove('hidden');
32
+
33
+ // Update step indicators
34
+ for (let i = 1; i <= 3; i++) {
35
+ const circle = document.getElementById('step-' + i);
36
+ const line = document.getElementById('line-' + (i - 1));
37
+
38
+ circle.classList.remove('active', 'completed');
39
+ if (i < step) {
40
+ circle.classList.add('completed');
41
+ circle.innerHTML = '<i class="fas fa-check text-sm"></i>';
42
+ } else if (i === step) {
43
+ circle.classList.add('active');
44
+ circle.textContent = i;
45
+ } else {
46
+ circle.textContent = i;
47
+ }
48
+
49
+ if (line) {
50
+ line.classList.toggle('active', i <= step);
51
+ }
52
+ }
53
+
54
+ window.scrollTo({ top: 0, behavior: 'smooth' });
55
+ }
56
+
57
+ // --- Client Form ---
58
+ function handleClientSubmit(event) {
59
+ event.preventDefault();
60
+
61
+ const nome = document.getElementById('reg-nome').value;
62
+ const tipo = document.getElementById('reg-tipo').value;
63
+ const cpfCnpj = document.getElementById('reg-cpfcnpj').value;
64
+ const email = document.getElementById('reg-email').value;
65
+ const telefone = document.getElementById('reg-telefone').value;
66
+
67
+ if (!nome || !cpfCnpj || !email || !telefone) {
68
+ showToast('Preencha todos os campos obrigatórios', 'error');
69
+ return false;
70
+ }
71
+
72
+ // Validate email
73
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
74
+ showToast('E-mail inválido', 'error');
75
+ return false;
76
+ }
77
+
78
+ // Save client data
79
+ clientData = {
80
+ id: Date.now(),
81
+ nome: nome,
82
+ tipo: tipo,
83
+ cpfCnpj: cpfCnpj,
84
+ rg: document.getElementById('reg-rg').value,
85
+ email: email,
86
+ telefone: telefone,
87
+ endereco: document.getElementById('reg-endereco').value,
88
+ profissao: document.getElementById('reg-profissao').value,
89
+ estadoCivil: document.getElementById('reg-estadocivil').value,
90
+ tipoProcesso: document.getElementById('reg-tipo-processo').value,
91
+ descricao: document.getElementById('reg-descricao').value,
92
+ dataCadastro: new Date().toISOString()
93
+ };
94
+
95
+ // Save to localStorage (shared with main app)
96
+ let appData = {};
97
+ try {
98
+ const saved = localStorage.getItem('legaldata_app');
99
+ if (saved) appData = JSON.parse(saved);
100
+ } catch(e) {}
101
+
102
+ if (!appData.clientes) appData.clientes = [];
103
+
104
+ // Check if already registered
105
+ const exists = appData.clientes.find(c => c.cpfCnpj === cpfCnpj);
106
+ if (exists) {
107
+ clientData.id = exists.id;
108
+ showToast('Cliente já cadastrado. Prossiga com o envio de provas.', 'info');
109
+ } else {
110
+ appData.clientes.push({
111
+ id: clientData.id,
112
+ nome: clientData.nome,
113
+ tipo: clientData.tipo,
114
+ cpfCnpj: clientData.cpfCnpj,
115
+ email: clientData.email,
116
+ telefone: clientData.telefone,
117
+ endereco: clientData.endereco,
118
+ processos: 0
119
+ });
120
+ }
121
+
122
+ localStorage.setItem('legaldata_app', JSON.stringify(appData
index.html CHANGED
@@ -9,101 +9,80 @@
9
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
10
  <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.0/papaparse.min.js"></script>
11
  <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
 
 
12
  <style>
13
- .sidebar {
14
- transition: all 0.3s ease;
15
- }
16
- .data-card:hover {
17
- transform: translateY(-5px);
18
- box-shadow: 0 10px 20px rgba(0,0,0,0.1);
19
- }
20
- .process-detail {
21
- max-height: 0;
22
- overflow: hidden;
23
- transition: max-height 0.5s ease-out;
24
- }
25
- .process-detail.active {
26
- max-height: 1000px;
27
- }
28
- .tab-content {
29
- display: none;
30
- }
31
- .tab-content.active {
32
- display: block;
33
- animation: fadeIn 0.5s;
34
- }
35
- @keyframes fadeIn {
36
- from { opacity: 0; }
37
- to { opacity: 1; }
38
- }
39
  </style>
40
  </head>
41
  <body class="bg-gray-50 font-sans">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  <div class="flex h-screen overflow-hidden">
43
  <!-- Sidebar -->
44
- <div class="sidebar bg-indigo-900 text-white w-64 flex-shrink-0">
45
  <div class="p-4 flex items-center space-x-3 border-b border-indigo-800">
46
  <i class="fas fa-balance-scale text-2xl text-indigo-300"></i>
47
  <h1 class="text-xl font-bold">LegalData Manager</h1>
48
  </div>
49
- <nav class="p-4">
50
  <div class="mb-6">
51
  <h3 class="text-xs uppercase text-indigo-400 font-semibold mb-3">Menu Principal</h3>
52
  <ul>
53
- <li class="mb-2">
54
- <a href="#" class="flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('dashboard')">
55
- <i class="fas fa-tachometer-alt mr-3"></i>
56
- Dashboard
57
- </a>
58
- </li>
59
- <li class="mb-2">
60
- <a href="#" class="flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('processos')">
61
- <i class="fas fa-folder-open mr-3"></i>
62
- Processos
63
- </a>
64
- </li>
65
- <li class="mb-2">
66
- <a href="#" class="flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('clientes')">
67
- <i class="fas fa-users mr-3"></i>
68
- Clientes
69
- </a>
70
- </li>
71
- <li class="mb-2">
72
- <a href="#" class="flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('import')">
73
- <i class="fas fa-file-import mr-3"></i>
74
- Importar Dados
75
- </a>
76
- </li>
77
  </ul>
78
  </div>
79
  <div class="mb-6">
80
  <h3 class="text-xs uppercase text-indigo-400 font-semibold mb-3">Administração</h3>
81
  <ul>
82
- <li class="mb-2">
83
- <a href="#" class="flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('config')">
84
- <i class="fas fa-cog mr-3"></i>
85
- Configurações
86
- </a>
87
- </li>
88
- <li class="mb-2">
89
- <a href="#" class="flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('sanitize')">
90
- <i class="fas fa-broom mr-3"></i>
91
- Sanitização
92
- </a>
93
- </li>
94
- <li class="mb-2">
95
- <a href="#" class="flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('integrations')">
96
- <i class="fas fa-plug mr-3"></i>
97
- Integrações
98
- </a>
99
- </li>
100
  </ul>
101
  </div>
102
- <div class="mt-8 pt-4 border-t border-indigo-800">
 
 
 
 
 
 
103
  <div class="flex items-center space-x-3">
104
- <div class="w-10 h-10 rounded-full bg-indigo-700 flex items-center justify-center">
105
- <i class="fas fa-user"></i>
106
- </div>
107
  <div>
108
  <p class="font-medium">Admin</p>
109
  <p class="text-xs text-indigo-300">admin@legaldata.com</p>
@@ -116,78 +95,56 @@
116
  <!-- Main Content -->
117
  <div class="flex-1 overflow-auto">
118
  <!-- Top Navigation -->
119
- <header class="bg-white shadow-sm">
120
  <div class="flex justify-between items-center p-4">
121
  <div class="flex items-center space-x-4">
122
- <button class="text-gray-500 md:hidden">
123
- <i class="fas fa-bars"></i>
124
- </button>
125
  <h2 class="text-xl font-semibold text-gray-800" id="current-tab-title">Dashboard</h2>
126
  </div>
127
  <div class="flex items-center space-x-4">
128
- <div class="relative">
129
  <input type="text" placeholder="Buscar..." class="pl-10 pr-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
130
  <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
131
  </div>
132
- <button class="p-2 rounded-full bg-gray-100 text-gray-600 hover:bg-gray-200">
133
  <i class="fas fa-bell"></i>
 
134
  </button>
135
  </div>
136
  </div>
137
  </header>
138
 
139
- <!-- Tab Contents -->
140
  <main class="p-6">
141
  <!-- Dashboard Tab -->
142
  <div id="dashboard" class="tab-content active">
143
- <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
144
- <div class="data-card bg-white p-6 rounded-xl shadow">
145
  <div class="flex justify-between items-start">
146
- <div>
147
- <p class="text-gray-500">Processos Ativos</p>
148
- <h3 class="text-3xl font-bold mt-2">124</h3>
149
- </div>
150
- <div class="p-3 rounded-lg bg-indigo-100 text-indigo-600">
151
- <i class="fas fa-folder-open text-xl"></i>
152
- </div>
153
- </div>
154
- <div class="mt-4 pt-4 border-t border-gray-100">
155
- <p class="text-sm text-green-500 flex items-center">
156
- <i class="fas fa-arrow-up mr-1"></i> 12% desde o último mês
157
- </p>
158
  </div>
 
159
  </div>
160
- <div class="data-card bg-white p-6 rounded-xl shadow">
161
  <div class="flex justify-between items-start">
162
- <div>
163
- <p class="text-gray-500">Clientes Ativos</p>
164
- <h3 class="text-3xl font-bold mt-2">42</h3>
165
- </div>
166
- <div class="p-3 rounded-lg bg-green-100 text-green-600">
167
- <i class="fas fa-users text-xl"></i>
168
- </div>
169
- </div>
170
- <div class="mt-4 pt-4 border-t border-gray-100">
171
- <p class="text-sm text-green-500 flex items-center">
172
- <i class="fas fa-arrow-up mr-1"></i> 5% desde o último mês
173
- </p>
174
  </div>
 
175
  </div>
176
- <div class="data-card bg-white p-6 rounded-xl shadow">
177
  <div class="flex justify-between items-start">
178
- <div>
179
- <p class="text-gray-500">Intimações Pendentes</p>
180
- <h3 class="text-3xl font-bold mt-2">18</h3>
181
- </div>
182
- <div class="p-3 rounded-lg bg-red-100 text-red-600">
183
- <i class="fas fa-exclamation-triangle text-xl"></i>
184
- </div>
185
  </div>
186
- <div class="mt-4 pt-4 border-t border-gray-100">
187
- <p class="text-sm text-red-500 flex items-center">
188
- <i class="fas fa-arrow-up mr-1"></i> 3 novas hoje
189
- </p>
 
 
190
  </div>
 
191
  </div>
192
  </div>
193
 
@@ -195,52 +152,19 @@
195
  <div class="bg-white p-6 rounded-xl shadow">
196
  <div class="flex justify-between items-center mb-4">
197
  <h3 class="font-semibold text-lg">Distribuição de Processos</h3>
198
- <select class="border border-gray-300 rounded px-3 py-1 text-sm">
199
- <option>Últimos 30 dias</option>
200
- <option>Últimos 90 dias</option>
201
- <option>Este ano</option>
202
- </select>
203
- </div>
204
- <div class="h-64">
205
- <canvas id="processChart"></canvas>
206
  </div>
 
207
  </div>
208
  <div class="bg-white p-6 rounded-xl shadow">
209
  <div class="flex justify-between items-center mb-4">
210
  <h3 class="font-semibold text-lg">Atividades Recentes</h3>
211
  <button class="text-indigo-600 text-sm font-medium">Ver todas</button>
212
  </div>
213
- <div class="space-y-4">
214
- <div class="flex items-start">
215
- <div class="p-2 bg-indigo-100 rounded-lg mr-3 text-indigo-600">
216
- <i class="fas fa-file-alt"></i>
217
- </div>
218
- <div>
219
- <p class="font-medium">Novo processo cadastrado</p>
220
- <p class="text-sm text-gray-500">Processo #2023-0456 para João Silva</p>
221
- <p class="text-xs text-gray-400">há 15 minutos</p>
222
- </div>
223
- </div>
224
- <div class="flex items-start">
225
- <div class="p-2 bg-green-100 rounded-lg mr-3 text-green-600">
226
- <i class="fas fa-check-circle"></i>
227
- </div>
228
- <div>
229
- <p class="font-medium">Intimação respondida</p>
230
- <p class="text-sm text-gray-500">Processo #2023-0321 - TRF1</p>
231
- <p class="text-xs text-gray-400">há 2 horas</p>
232
- </div>
233
- </div>
234
- <div class="flex items-start">
235
- <div class="p-2 bg-blue-100 rounded-lg mr-3 text-blue-600">
236
- <i class="fas fa-sync-alt"></i>
237
- </div>
238
- <div>
239
- <p class="font-medium">Dados atualizados via APS</p>
240
- <p class="text-sm text-gray-500">5 processos atualizados do TJSP</p>
241
- <p class="text-xs text-gray-400">hoje às 08:45</p>
242
- </div>
243
- </div>
244
  </div>
245
  </div>
246
  </div>
@@ -252,57 +176,8 @@
252
  </div>
253
  <div class="overflow-x-auto">
254
  <table class="min-w-full divide-y divide-gray-200">
255
- <thead class="bg-gray-50">
256
- <tr>
257
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Processo</th>
258
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Cliente</th>
259
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tribunal</th>
260
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Prazo</th>
261
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
262
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Ações</th>
263
- </tr>
264
- </thead>
265
- <tbody class="bg-white divide-y divide-gray-200">
266
- <tr>
267
- <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">#2023-0456</td>
268
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">João Silva</td>
269
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">TJSP</td>
270
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">15/07/2023</td>
271
- <td class="px-6 py-4 whitespace-nowrap">
272
- <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800">Pendente</span>
273
- </td>
274
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
275
- <button class="text-indigo-600 hover:text-indigo-900 mr-3"><i class="fas fa-eye"></i></button>
276
- <button class="text-green-600 hover:text-green-900"><i class="fas fa-edit"></i></button>
277
- </td>
278
- </tr>
279
- <tr>
280
- <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">#2023-0389</td>
281
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">Maria Souza</td>
282
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">TRF4</td>
283
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">18/07/2023</td>
284
- <td class="px-6 py-4 whitespace-nowrap">
285
- <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Urgente</span>
286
- </td>
287
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
288
- <button class="text-indigo-600 hover:text-indigo-900 mr-3"><i class="fas fa-eye"></i></button>
289
- <button class="text-green-600 hover:text-green-900"><i class="fas fa-edit"></i></button>
290
- </td>
291
- </tr>
292
- <tr>
293
- <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">#2023-0412</td>
294
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">Empresa XYZ Ltda</td>
295
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">TJMG</td>
296
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">20/07/2023</td>
297
- <td class="px-6 py-4 whitespace-nowrap">
298
- <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800">Pendente</span>
299
- </td>
300
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
301
- <button class="text-indigo-600 hover:text-indigo-900 mr-3"><i class="fas fa-eye"></i></button>
302
- <button class="text-green-600 hover:text-green-900"><i class="fas fa-edit"></i></button>
303
- </td>
304
- </tr>
305
- </tbody>
306
  </table>
307
  </div>
308
  </div>
@@ -312,73 +187,25 @@
312
  <div id="processos" class="tab-content">
313
  <div class="flex justify-between items-center mb-6">
314
  <h2 class="text-2xl font-bold text-gray-800">Gestão de Processos</h2>
315
- <button onclick="showModal('new-process')" class="bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 transition flex items-center">
316
- <i class="fas fa-plus mr-2"></i> Novo Processo
317
- </button>
318
  </div>
319
-
320
  <div class="bg-white rounded-xl shadow overflow-hidden mb-6">
321
- <div class="p-4 border-b border-gray-200 flex justify-between items-center">
322
  <div class="flex items-center space-x-4">
323
- <div class="relative">
324
- <input type="text" placeholder="Filtrar processos..." class="pl-10 pr-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
325
- <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
326
- </div>
327
- <select class="border border-gray-300 rounded px-3 py-2 text-sm">
328
- <option>Todos os tribunais</option>
329
- <option>TJSP</option>
330
- <option>TJMG</option>
331
- <option>TRF1</option>
332
- <option>TRF2</option>
333
- <option>TRF3</option>
334
- <option>TRF4</option>
335
- <option>TRF5</option>
336
- </select>
337
  </div>
338
  <div class="flex items-center space-x-2">
339
- <button class="p-2 rounded-lg border border-gray-300 hover:bg-gray-50">
340
- <i class="fas fa-download text-gray-600"></i>
341
- </button>
342
- <button class="p-2 rounded-lg border border-gray-300 hover:bg-gray-50">
343
- <i class="fas fa-print text-gray-600"></i>
344
- </button>
345
  </div>
346
  </div>
347
  <div class="overflow-x-auto">
348
  <table class="min-w-full divide-y divide-gray-200">
349
- <thead class="bg-gray-50">
350
- <tr>
351
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Número</th>
352
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Cliente</th>
353
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tribunal</th>
354
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Data Abertura</th>
355
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
356
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Ações</th>
357
- </tr>
358
- </thead>
359
- <tbody class="bg-white divide-y divide-gray-200" id="processos-table-body">
360
- <!-- Process rows will be added here by JavaScript -->
361
- </tbody>
362
  </table>
363
  </div>
364
- <div class="p-4 border-t border-gray-200 flex justify-between items-center">
365
- <div class="text-sm text-gray-500">
366
- Mostrando <span class="font-medium">1</span> a <span class="font-medium">10</span> de <span class="font-medium">124</span> resultados
367
- </div>
368
- <div class="flex space-x-1">
369
- <button class="px-3 py-1 rounded border border-gray-300 bg-gray-50 text-gray-700">
370
- <i class="fas fa-angle-left"></i>
371
- </button>
372
- <button class="px-3 py-1 rounded border border-indigo-500 bg-indigo-50 text-indigo-600">1</button>
373
- <button class="px-3 py-1 rounded border border-gray-300 hover:bg-gray-50">2</button>
374
- <button class="px-3 py-1 rounded border border-gray-300 hover:bg-gray-50">3</button>
375
- <button class="px-3 py-1 rounded border border-gray-300 hover:bg-gray-50">4</button>
376
- <button class="px-3 py-1 rounded border border-gray-300 hover:bg-gray-50">5</button>
377
- <button class="px-3 py-1 rounded border border-gray-300 hover:bg-gray-50">
378
- <i class="fas fa-angle-right"></i>
379
- </button>
380
- </div>
381
- </div>
382
  </div>
383
  </div>
384
 
@@ -386,98 +213,132 @@
386
  <div id="clientes" class="tab-content">
387
  <div class="flex justify-between items-center mb-6">
388
  <h2 class="text-2xl font-bold text-gray-800">Gestão de Clientes</h2>
389
- <button onclick="showModal('new-client')" class="bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 transition flex items-center">
390
- <i class="fas fa-plus mr-2"></i> Novo Cliente
391
- </button>
392
  </div>
393
-
394
  <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
395
- <div class="bg-white p-6 rounded-xl shadow">
396
- <div class="flex items-center space-x-4">
397
- <div class="p-3 bg-indigo-100 rounded-lg text-indigo-600">
398
- <i class="fas fa-user-tie text-2xl"></i>
399
- </div>
400
- <div>
401
- <p class="text-gray-500">Clientes Ativos</p>
402
- <h3 class="text-2xl font-bold">42</h3>
403
- </div>
404
- </div>
405
  </div>
406
- <div class="bg-white p-6 rounded-xl shadow">
407
- <div class="flex items-center space-x-4">
408
- <div class="p-3 bg-green-100 rounded-lg text-green-600">
409
- <i class="fas fa-briefcase text-2xl"></i>
410
- </div>
411
- <div>
412
- <p class="text-gray-500">Pessoa Jurídica</p>
413
- <h3 class="text-2xl font-bold">18</h3>
414
- </div>
415
- </div>
416
  </div>
417
- <div class="bg-white p-6 rounded-xl shadow">
418
- <div class="flex items-center space-x-4">
419
- <div class="p-3 bg-blue-100 rounded-lg text-blue-600">
420
- <i class="fas fa-user text-2xl"></i>
421
- </div>
422
- <div>
423
- <p class="text-gray-500">Pessoa Física</p>
424
- <h3 class="text-2xl font-bold">24</h3>
425
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
426
  </div>
427
  </div>
 
428
  </div>
429
 
430
- <div class="bg-white rounded-xl shadow overflow-hidden">
431
- <div class="p-4 border-b border-gray-200 flex justify-between items-center">
432
- <div class="relative w-64">
433
- <input type="text" placeholder="Buscar cliente..." class="pl-10 pr-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent w-full">
434
- <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
  </div>
436
- <div class="flex items-center space-x-2">
437
- <button class="p-2 rounded-lg border border-gray-300 hover:bg-gray-50">
438
- <i class="fas fa-filter text-gray-600"></i>
439
- </button>
440
- <button class="p-2 rounded-lg border border-gray-300 hover:bg-gray-50">
441
- <i class="fas fa-download text-gray-600"></i>
442
- </button>
 
 
 
 
 
 
 
443
  </div>
444
  </div>
445
- <div class="overflow-x-auto">
446
- <table class="min-w-full divide-y divide-gray-200">
447
- <thead class="bg-gray-50">
448
- <tr>
449
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Nome</th>
450
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">CPF/CNPJ</th>
451
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">E-mail</th>
452
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Telefone</th>
453
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Processos</th>
454
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Ações</th>
455
- </tr>
456
- </thead>
457
- <tbody class="bg-white divide-y divide-gray-200" id="clientes-table-body">
458
- <!-- Client rows will be added here by JavaScript -->
459
- </tbody>
460
- </table>
461
  </div>
462
- <div class="p-4 border-t border-gray-200 flex justify-between items-center">
463
- <div class="text-sm text-gray-500">
464
- Mostrando <span class="font-medium">1</span> a <span class="font-medium">10</span> de <span class="font-medium">42</span> resultados
465
- </div>
466
- <div class="flex space-x-1">
467
- <button class="px-3 py-1 rounded border border-gray-300 bg-gray-50 text-gray-700">
468
- <i class="fas fa-angle-left"></i>
469
- </button>
470
- <button class="px-3 py-1 rounded border border-indigo-500 bg-indigo-50 text-indigo-600">1</button>
471
- <button class="px-3 py-1 rounded border border-gray-300 hover:bg-gray-50">2</button>
472
- <button class="px-3 py-1 rounded border border-gray-300 hover:bg-gray-50">3</button>
473
- <button class="px-3 py-1 rounded border border-gray-300 hover:bg-gray-50">4</button>
474
- <button class="px-3 py-1 rounded border border-gray-300 hover:bg-gray-50">5</button>
475
- <button class="px-3 py-1 rounded border border-gray-300 hover:bg-gray-50">
476
- <i class="fas fa-angle-right"></i>
477
- </button>
478
  </div>
479
  </div>
480
  </div>
 
 
 
 
 
 
481
  </div>
482
 
483
  <!-- Import Data Tab -->
@@ -486,67 +347,184 @@
486
  <h2 class="text-2xl font-bold text-gray-800">Importar Dados</h2>
487
  <p class="text-gray-600">Conecte-se a planilhas externas ou importe arquivos para atualizar sua base de dados</p>
488
  </div>
489
-
490
  <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
491
  <div class="bg-white p-6 rounded-xl shadow">
492
- <div class="flex items-center justify-between mb-4">
493
- <h3 class="font-semibold text-lg">Google Sheets</h3>
494
- <div class="p-2 bg-blue-100 rounded-lg text-blue-600">
495
- <i class="fab fa-google"></i>
496
- </div>
497
- </div>
498
- <p class="text-gray-600 mb-4">Conecte-se diretamente ao Google Sheets para sincronizar seus dados</p>
499
- <button class="w-full bg-blue-600 text-white py-2 rounded-lg hover:bg-blue-700 transition flex items-center justify-center">
500
- <i class="fab fa-google mr-2"></i> Conectar ao Google
501
- </button>
502
  </div>
503
  <div class="bg-white p-6 rounded-xl shadow">
504
- <div class="flex items-center justify-between mb-4">
505
- <h3 class="font-semibold text-lg">Excel/CSV</h3>
506
- <div class="p-2 bg-green-100 rounded-lg text-green-600">
507
- <i class="fas fa-file-excel"></i>
508
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
509
  </div>
510
- <p class="text-gray-600 mb-4">Importe arquivos Excel (.xlsx, .xls) ou CSV para atualizar seus dados</p>
511
- <div class="flex space-x-2">
512
- <button onclick="document.getElementById('file-input').click()" class="flex-1 bg-green-600 text-white py-2 rounded-lg hover:bg-green-700 transition flex items-center justify-center">
513
- <i class="fas fa-upload mr-2"></i> Selecionar Arquivo
514
- </button>
515
- <input type="file" id="file-input" class="hidden" accept=".xlsx,.xls,.csv">
516
- <button class="px-3 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200">
517
- <i class="fas fa-question"></i>
518
- </button>
519
  </div>
 
 
520
  </div>
521
- <div class="bg-white p-6 rounded-xl shadow">
522
- <div class="flex items-center justify-between mb-4">
523
- <h3 class="font-semibold text-lg">JSON/API</h3>
524
- <div class="p-2 bg-purple-100 rounded-lg text-purple-600">
525
- <i class="fas fa-code"></i>
526
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
527
  </div>
528
- <p class="text-gray-600 mb-4">Importe dados em formato JSON ou conecte-se a APIs externas</p>
529
- <button class="w-full bg-purple-600 text-white py-2 rounded-lg hover:bg-purple-700 transition flex items-center justify-center">
530
- <i class="fas fa-plug mr-2"></i> Configurar API
531
- </button>
532
  </div>
533
  </div>
 
 
 
 
534
 
535
- <div class="bg-white rounded-xl shadow overflow-hidden">
536
- <div class="p-4 border-b border-gray-200">
537
- <h3 class="font-semibold text-lg">Mapeamento de Campos</h3>
538
- <p class="text-gray-600">Defina como os campos do arquivo importado serão mapeados para o sistema</p>
539
- </div>
540
- <div class="p-4">
541
- <div class="overflow-x-auto">
542
- <table class="min-w-full divide-y divide-gray-200">
543
- <thead class="bg-gray-50">
544
- <tr>
545
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Campo no Arquivo</th>
546
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Mapear para</th>
547
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tipo de Dado</th>
548
- <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Ações</th>
549
- </tr>
550
- </thead>
551
- <
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
552
  </html>
 
9
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
10
  <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.0/papaparse.min.js"></script>
11
  <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
12
+ <script src="https://apis.google.com/js/api.js"></script>
13
+ <script src="https://accounts.google.com/gsi/client" async defer></script>
14
  <style>
15
+ .sidebar { transition: all 0.3s ease; }
16
+ .sidebar.collapsed { width: 0; overflow: hidden; }
17
+ .data-card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0,0,0,0.1); }
18
+ .process-detail { max-height: 0; overflow: hidden; transition: max-height 0.5s ease-out; }
19
+ .process-detail.active { max-height: 1000px; }
20
+ .tab-content { display: none; }
21
+ .tab-content.active { display: block; animation: fadeIn 0.5s; }
22
+ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
23
+ .evidence-card:hover { transform: scale(1.03); }
24
+ .lightbox { display: none; position: fixed; inset: 0; z-index: 9999; background: rgba(0,0,0,0.9); }
25
+ .lightbox.active { display: flex; }
26
+ .drop-zone { border: 2px dashed #c7d2fe; transition: all 0.3s; }
27
+ .drop-zone.dragover { border-color: #6366f1; background: #eef2ff; }
28
+ .nav-link.active-nav { background: rgba(79,70,229,0.3); border-right: 3px solid #a5b4fc; }
29
+ .aasp-pulse { animation: pulse 2s infinite; }
30
+ @keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.6} }
31
+ .toast { transform: translateX(120%); transition: transform 0.4s ease; }
32
+ .toast.show { transform: translateX(0); }
 
 
 
 
 
 
 
 
33
  </style>
34
  </head>
35
  <body class="bg-gray-50 font-sans">
36
+ <!-- Toast Container -->
37
+ <div id="toast-container" class="fixed top-4 right-4 z-50 space-y-2"></div>
38
+
39
+ <!-- Lightbox -->
40
+ <div id="lightbox" class="lightbox items-center justify-center" onclick="closeLightbox()">
41
+ <button class="absolute top-4 right-4 text-white text-3xl hover:text-gray-300 z-10" onclick="closeLightbox()"><i class="fas fa-times"></i></button>
42
+ <button class="absolute left-4 top-1/2 -translate-y-1/2 text-white text-3xl hover:text-gray-300 z-10" onclick="event.stopPropagation();navigateEvidence(-1)"><i class="fas fa-chevron-left"></i></button>
43
+ <button class="absolute right-4 top-1/2 -translate-y-1/2 text-white text-3xl hover:text-gray-300 z-10" onclick="event.stopPropagation();navigateEvidence(1)"><i class="fas fa-chevron-right"></i></button>
44
+ <div class="max-w-4xl max-h-screen p-8" onclick="event.stopPropagation()">
45
+ <div id="lightbox-content" class="flex items-center justify-center"></div>
46
+ <p id="lightbox-caption" class="text-white text-center mt-4 text-lg"></p>
47
+ </div>
48
+ </div>
49
+
50
  <div class="flex h-screen overflow-hidden">
51
  <!-- Sidebar -->
52
+ <div id="sidebar" class="sidebar bg-indigo-900 text-white w-64 flex-shrink-0">
53
  <div class="p-4 flex items-center space-x-3 border-b border-indigo-800">
54
  <i class="fas fa-balance-scale text-2xl text-indigo-300"></i>
55
  <h1 class="text-xl font-bold">LegalData Manager</h1>
56
  </div>
57
+ <nav class="p-4 overflow-y-auto" style="max-height: calc(100vh - 80px);">
58
  <div class="mb-6">
59
  <h3 class="text-xs uppercase text-indigo-400 font-semibold mb-3">Menu Principal</h3>
60
  <ul>
61
+ <li class="mb-1"><a href="#" class="nav-link active-nav flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('dashboard', this)"><i class="fas fa-tachometer-alt mr-3 w-5 text-center"></i>Dashboard</a></li>
62
+ <li class="mb-1"><a href="#" class="nav-link flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('processos', this)"><i class="fas fa-folder-open mr-3 w-5 text-center"></i>Processos</a></li>
63
+ <li class="mb-1"><a href="#" class="nav-link flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('clientes', this)"><i class="fas fa-users mr-3 w-5 text-center"></i>Clientes</a></li>
64
+ <li class="mb-1"><a href="#" class="nav-link flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('provas', this)"><i class="fas fa-images mr-3 w-5 text-center"></i>Galeria de Provas</a></li>
65
+ <li class="mb-1"><a href="#" class="nav-link flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('intimacoes', this)"><i class="fas fa-gavel mr-3 w-5 text-center"></i>Intimações AASP</a></li>
66
+ <li class="mb-1"><a href="#" class="nav-link flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('import', this)"><i class="fas fa-file-import mr-3 w-5 text-center"></i>Importar Dados</a></li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  </ul>
68
  </div>
69
  <div class="mb-6">
70
  <h3 class="text-xs uppercase text-indigo-400 font-semibold mb-3">Administração</h3>
71
  <ul>
72
+ <li class="mb-1"><a href="#" class="nav-link flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('config', this)"><i class="fas fa-cog mr-3 w-5 text-center"></i>Configurações</a></li>
73
+ <li class="mb-1"><a href="#" class="nav-link flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('sanitize', this)"><i class="fas fa-broom mr-3 w-5 text-center"></i>Sanitização</a></li>
74
+ <li class="mb-1"><a href="#" class="nav-link flex items-center p-2 rounded hover:bg-indigo-800 transition" onclick="showTab('integrations', this)"><i class="fas fa-plug mr-3 w-5 text-center"></i>Integrações</a></li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  </ul>
76
  </div>
77
+ <div class="mb-6">
78
+ <h3 class="text-xs uppercase text-indigo-400 font-semibold mb-3">Portal</h3>
79
+ <ul>
80
+ <li class="mb-1"><a href="cliente.html" class="flex items-center p-2 rounded hover:bg-indigo-800 transition"><i class="fas fa-external-link-alt mr-3 w-5 text-center"></i>Portal do Cliente</a></li>
81
+ </ul>
82
+ </div>
83
+ <div class="mt-4 pt-4 border-t border-indigo-800">
84
  <div class="flex items-center space-x-3">
85
+ <div class="w-10 h-10 rounded-full bg-indigo-700 flex items-center justify-center"><i class="fas fa-user"></i></div>
 
 
86
  <div>
87
  <p class="font-medium">Admin</p>
88
  <p class="text-xs text-indigo-300">admin@legaldata.com</p>
 
95
  <!-- Main Content -->
96
  <div class="flex-1 overflow-auto">
97
  <!-- Top Navigation -->
98
+ <header class="bg-white shadow-sm sticky top-0 z-40">
99
  <div class="flex justify-between items-center p-4">
100
  <div class="flex items-center space-x-4">
101
+ <button class="text-gray-500 md:hidden" onclick="toggleSidebar()"><i class="fas fa-bars"></i></button>
 
 
102
  <h2 class="text-xl font-semibold text-gray-800" id="current-tab-title">Dashboard</h2>
103
  </div>
104
  <div class="flex items-center space-x-4">
105
+ <div class="relative hidden md:block">
106
  <input type="text" placeholder="Buscar..." class="pl-10 pr-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
107
  <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
108
  </div>
109
+ <button class="p-2 rounded-full bg-gray-100 text-gray-600 hover:bg-gray-200 relative">
110
  <i class="fas fa-bell"></i>
111
+ <span id="notification-badge" class="hidden absolute -top-1 -right-1 w-4 h-4 bg-red-500 rounded-full text-white text-xs flex items-center justify-center">0</span>
112
  </button>
113
  </div>
114
  </div>
115
  </header>
116
 
 
117
  <main class="p-6">
118
  <!-- Dashboard Tab -->
119
  <div id="dashboard" class="tab-content active">
120
+ <div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-6">
121
+ <div class="data-card bg-white p-6 rounded-xl shadow transition">
122
  <div class="flex justify-between items-start">
123
+ <div><p class="text-gray-500">Processos Ativos</p><h3 class="text-3xl font-bold mt-2" id="stat-processos">124</h3></div>
124
+ <div class="p-3 rounded-lg bg-indigo-100 text-indigo-600"><i class="fas fa-folder-open text-xl"></i></div>
 
 
 
 
 
 
 
 
 
 
125
  </div>
126
+ <div class="mt-4 pt-4 border-t border-gray-100"><p class="text-sm text-green-500 flex items-center"><i class="fas fa-arrow-up mr-1"></i> 12% desde o último mês</p></div>
127
  </div>
128
+ <div class="data-card bg-white p-6 rounded-xl shadow transition">
129
  <div class="flex justify-between items-start">
130
+ <div><p class="text-gray-500">Clientes Ativos</p><h3 class="text-3xl font-bold mt-2" id="stat-clientes">42</h3></div>
131
+ <div class="p-3 rounded-lg bg-green-100 text-green-600"><i class="fas fa-users text-xl"></i></div>
 
 
 
 
 
 
 
 
 
 
132
  </div>
133
+ <div class="mt-4 pt-4 border-t border-gray-100"><p class="text-sm text-green-500 flex items-center"><i class="fas fa-arrow-up mr-1"></i> 5% desde o último mês</p></div>
134
  </div>
135
+ <div class="data-card bg-white p-6 rounded-xl shadow transition">
136
  <div class="flex justify-between items-start">
137
+ <div><p class="text-gray-500">Intimações Pendentes</p><h3 class="text-3xl font-bold mt-2" id="stat-intimacoes">0</h3></div>
138
+ <div class="p-3 rounded-lg bg-red-100 text-red-600"><i class="fas fa-exclamation-triangle text-xl"></i></div>
 
 
 
 
 
139
  </div>
140
+ <div class="mt-4 pt-4 border-t border-gray-100"><p class="text-sm text-red-500 flex items-center"><i class="fas fa-arrow-up mr-1"></i> Verifique as intimações</p></div>
141
+ </div>
142
+ <div class="data-card bg-white p-6 rounded-xl shadow transition">
143
+ <div class="flex justify-between items-start">
144
+ <div><p class="text-gray-500">Provas Anexadas</p><h3 class="text-3xl font-bold mt-2" id="stat-provas">0</h3></div>
145
+ <div class="p-3 rounded-lg bg-purple-100 text-purple-600"><i class="fas fa-images text-xl"></i></div>
146
  </div>
147
+ <div class="mt-4 pt-4 border-t border-gray-100"><p class="text-sm text-purple-500 flex items-center"><i class="fas fa-images mr-1"></i> Na galeria de provas</p></div>
148
  </div>
149
  </div>
150
 
 
152
  <div class="bg-white p-6 rounded-xl shadow">
153
  <div class="flex justify-between items-center mb-4">
154
  <h3 class="font-semibold text-lg">Distribuição de Processos</h3>
155
+ <select class="border border-gray-300 rounded px-3 py-1 text-sm"><option>Últimos 30 dias</option><option>Últimos 90 dias</option><option>Este ano</option></select>
 
 
 
 
 
 
 
156
  </div>
157
+ <div class="h-64"><canvas id="processChart"></canvas></div>
158
  </div>
159
  <div class="bg-white p-6 rounded-xl shadow">
160
  <div class="flex justify-between items-center mb-4">
161
  <h3 class="font-semibold text-lg">Atividades Recentes</h3>
162
  <button class="text-indigo-600 text-sm font-medium">Ver todas</button>
163
  </div>
164
+ <div class="space-y-4" id="recent-activities">
165
+ <div class="flex items-start"><div class="p-2 bg-indigo-100 rounded-lg mr-3 text-indigo-600"><i class="fas fa-file-alt"></i></div><div><p class="font-medium">Novo processo cadastrado</p><p class="text-sm text-gray-500">Processo #2023-0456 para João Silva</p><p class="text-xs text-gray-400">há 15 minutos</p></div></div>
166
+ <div class="flex items-start"><div class="p-2 bg-green-100 rounded-lg mr-3 text-green-600"><i class="fas fa-check-circle"></i></div><div><p class="font-medium">Intimação respondida</p><p class="text-sm text-gray-500">Processo #2023-0321 - TRF1</p><p class="text-xs text-gray-400">há 2 horas</p></div></div>
167
+ <div class="flex items-start"><div class="p-2 bg-blue-100 rounded-lg mr-3 text-blue-600"><i class="fas fa-sync-alt"></i></div><div><p class="font-medium">Dados atualizados via AASP</p><p class="text-sm text-gray-500">5 processos atualizados do TJSP</p><p class="text-xs text-gray-400">hoje às 08:45</p></div></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  </div>
169
  </div>
170
  </div>
 
176
  </div>
177
  <div class="overflow-x-auto">
178
  <table class="min-w-full divide-y divide-gray-200">
179
+ <thead class="bg-gray-50"><tr><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Processo</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Cliente</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Tribunal</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Prazo</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Status</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Ações</th></tr></thead>
180
+ <tbody class="bg-white divide-y divide-gray-200" id="deadline-table-body"></tbody>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  </table>
182
  </div>
183
  </div>
 
187
  <div id="processos" class="tab-content">
188
  <div class="flex justify-between items-center mb-6">
189
  <h2 class="text-2xl font-bold text-gray-800">Gestão de Processos</h2>
190
+ <button onclick="showModal('new-process')" class="bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 transition flex items-center"><i class="fas fa-plus mr-2"></i> Novo Processo</button>
 
 
191
  </div>
 
192
  <div class="bg-white rounded-xl shadow overflow-hidden mb-6">
193
+ <div class="p-4 border-b border-gray-200 flex flex-wrap justify-between items-center gap-3">
194
  <div class="flex items-center space-x-4">
195
+ <div class="relative"><input type="text" placeholder="Filtrar processos..." class="pl-10 pr-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"><i class="fas fa-search absolute left-3 top-3 text-gray-400"></i></div>
196
+ <select class="border border-gray-300 rounded px-3 py-2 text-sm"><option>Todos os tribunais</option><option>TJSP</option><option>TJMG</option><option>TRF1</option><option>TRF4</option></select>
 
 
 
 
 
 
 
 
 
 
 
 
197
  </div>
198
  <div class="flex items-center space-x-2">
199
+ <button class="p-2 rounded-lg border border-gray-300 hover:bg-gray-50"><i class="fas fa-download text-gray-600"></i></button>
200
+ <button class="p-2 rounded-lg border border-gray-300 hover:bg-gray-50"><i class="fas fa-print text-gray-600"></i></button>
 
 
 
 
201
  </div>
202
  </div>
203
  <div class="overflow-x-auto">
204
  <table class="min-w-full divide-y divide-gray-200">
205
+ <thead class="bg-gray-50"><tr><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Número</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Cliente</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Tribunal</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Data Abertura</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Status</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Ações</th></tr></thead>
206
+ <tbody class="bg-white divide-y divide-gray-200" id="processos-table-body"></tbody>
 
 
 
 
 
 
 
 
 
 
 
207
  </table>
208
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  </div>
210
  </div>
211
 
 
213
  <div id="clientes" class="tab-content">
214
  <div class="flex justify-between items-center mb-6">
215
  <h2 class="text-2xl font-bold text-gray-800">Gestão de Clientes</h2>
216
+ <button onclick="showModal('new-client')" class="bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 transition flex items-center"><i class="fas fa-plus mr-2"></i> Novo Cliente</button>
 
 
217
  </div>
 
218
  <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
219
+ <div class="bg-white p-6 rounded-xl shadow"><div class="flex items-center space-x-4"><div class="p-3 bg-indigo-100 rounded-lg text-indigo-600"><i class="fas fa-user-tie text-2xl"></i></div><div><p class="text-gray-500">Clientes Ativos</p><h3 class="text-2xl font-bold" id="stat-clientes-tab">42</h3></div></div></div>
220
+ <div class="bg-white p-6 rounded-xl shadow"><div class="flex items-center space-x-4"><div class="p-3 bg-green-100 rounded-lg text-green-600"><i class="fas fa-briefcase text-2xl"></i></div><div><p class="text-gray-500">Pessoa Jurídica</p><h3 class="text-2xl font-bold">18</h3></div></div></div>
221
+ <div class="bg-white p-6 rounded-xl shadow"><div class="flex items-center space-x-4"><div class="p-3 bg-blue-100 rounded-lg text-blue-600"><i class="fas fa-user text-2xl"></i></div><div><p class="text-gray-500">Pessoa Física</p><h3 class="text-2xl font-bold">24</h3></div></div></div>
222
+ </div>
223
+ <div class="bg-white rounded-xl shadow overflow-hidden">
224
+ <div class="p-4 border-b border-gray-200 flex flex-wrap justify-between items-center gap-3">
225
+ <div class="relative w-64"><input type="text" placeholder="Buscar cliente..." class="pl-10 pr-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 w-full"><i class="fas fa-search absolute left-3 top-3 text-gray-400"></i></div>
226
+ <div class="flex items-center space-x-2"><button class="p-2 rounded-lg border border-gray-300 hover:bg-gray-50"><i class="fas fa-filter text-gray-600"></i></button><button class="p-2 rounded-lg border border-gray-300 hover:bg-gray-50"><i class="fas fa-download text-gray-600"></i></button></div>
 
 
227
  </div>
228
+ <div class="overflow-x-auto">
229
+ <table class="min-w-full divide-y divide-gray-200">
230
+ <thead class="bg-gray-50"><tr><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Nome</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">CPF/CNPJ</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">E-mail</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Telefone</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Processos</th><th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Ações</th></tr></thead>
231
+ <tbody class="bg-white divide-y divide-gray-200" id="clientes-table-body"></tbody>
232
+ </table>
 
 
 
 
 
233
  </div>
234
+ </div>
235
+ </div>
236
+
237
+ <!-- Galeria de Provas Tab -->
238
+ <div id="provas" class="tab-content">
239
+ <div class="flex flex-wrap justify-between items-center mb-6 gap-3">
240
+ <h2 class="text-2xl font-bold text-gray-800">Galeria de Provas</h2>
241
+ <div class="flex items-center space-x-3">
242
+ <select id="evidence-filter-client" class="border border-gray-300 rounded px-3 py-2 text-sm" onchange="filterEvidence()">
243
+ <option value="">Todos os Clientes</option>
244
+ </select>
245
+ <select id="evidence-filter-type" class="border border-gray-300 rounded px-3 py-2 text-sm" onchange="filterEvidence()">
246
+ <option value="">Todos os Tipos</option>
247
+ <option value="image">Imagens</option>
248
+ <option value="document">Documentos</option>
249
+ <option value="video">Vídeos</option>
250
+ <option value="audio">Áudios</option>
251
+ </select>
252
+ <button onclick="showModal('upload-evidence')" class="bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 transition flex items-center"><i class="fas fa-cloud-upload-alt mr-2"></i> Enviar Prova</button>
253
+ </div>
254
+ </div>
255
+
256
+ <!-- Google Drive Connection Status -->
257
+ <div id="drive-status" class="mb-4 bg-white rounded-xl shadow p-4 flex items-center justify-between">
258
+ <div class="flex items-center space-x-3">
259
+ <div id="drive-icon" class="w-10 h-10 rounded-lg bg-gray-100 flex items-center justify-center text-gray-400"><i class="fab fa-google-drive text-xl"></i></div>
260
+ <div>
261
+ <p class="font-medium" id="drive-status-text">Google Drive desconectado</p>
262
+ <p class="text-sm text-gray-500" id="drive-status-sub">Conecte para sincronizar provas na nuvem</p>
263
  </div>
264
  </div>
265
+ <button onclick="connectGoogleDrive()" id="drive-connect-btn" class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition flex items-center"><i class="fab fa-google mr-2"></i> Conectar Google Drive</button>
266
  </div>
267
 
268
+ <!-- Evidence Grid -->
269
+ <div id="evidence-grid" class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
270
+ <!-- Evidence cards rendered by JS -->
271
+ </div>
272
+
273
+ <div id="no-evidence" class="hidden text-center py-16">
274
+ <i class="fas fa-images text-6xl text-gray-300 mb-4"></i>
275
+ <p class="text-gray-500 text-lg">Nenhuma prova encontrada</p>
276
+ <p class="text-gray-400 text-sm">Clique em "Enviar Prova" para adicionar</p>
277
+ </div>
278
+ </div>
279
+
280
+ <!-- Intimações AASP Tab -->
281
+ <div id="intimacoes" class="tab-content">
282
+ <div class="flex flex-wrap justify-between items-center mb-6 gap-3">
283
+ <h2 class="text-2xl font-bold text-gray-800">Intimações AASP</h2>
284
+ <div class="flex items-center space-x-3">
285
+ <button onclick="fetchAASPIntimacoes()" class="bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 transition flex items-center" id="btn-fetch-aasp"><i class="fas fa-sync-alt mr-2"></i> Buscar Intimações</button>
286
+ <button onclick="fetchAASPJornais()" class="bg-green-600 text-white px-4 py-2 rounded-lg hover:bg-green-700 transition flex items-center"><i class="fas fa-newspaper mr-2"></i> Jornais com Intimações</button>
287
+ </div>
288
+ </div>
289
+
290
+ <!-- AASP Config Card -->
291
+ <div class="bg-white rounded-xl shadow p-6 mb-6">
292
+ <h3 class="font-semibold text-lg mb-4"><i class="fas fa-key mr-2 text-indigo-600"></i>Configuração da API AASP</h3>
293
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
294
+ <div>
295
+ <label class="block text-sm font-medium text-gray-700 mb-1">Chave de Acesso</label>
296
+ <div class="relative">
297
+ <input type="password" id="aasp-chave" value="92E81C018B69454F8053133023AC438B" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 pr-10">
298
+ <button onclick="togglePassword('aasp-chave')" class="absolute right-3 top-3 text-gray-400 hover:text-gray-600"><i class="fas fa-eye"></i></button>
299
+ </div>
300
  </div>
301
+ <div>
302
+ <label class="block text-sm font-medium text-gray-700 mb-1">Tipo de Consulta</label>
303
+ <select id="aasp-tipo" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500">
304
+ <option value="associado">Associado (Pessoa Física)</option>
305
+ <option value="empresa">Empresa (Pessoa Jurídica)</option>
306
+ </select>
307
+ </div>
308
+ <div>
309
+ <label class="block text-sm font-medium text-gray-700 mb-1">Data da Intimação</label>
310
+ <input type="date" id="aasp-data" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500">
311
+ </div>
312
+ <div>
313
+ <label class="block text-sm font-medium text-gray-700 mb-1">Código Associado (Empresa)</label>
314
+ <input type="number" id="aasp-codigo" placeholder="Código AASP" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500">
315
  </div>
316
  </div>
317
+ <div class="mt-4 flex items-center space-x-4">
318
+ <label class="flex items-center space-x-2"><input type="checkbox" id="aasp-diferencial" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"><span class="text-sm text-gray-700">Somente não consultadas</span></label>
319
+ <label class="flex items-center space-x-2"><input type="checkbox" id="aasp-auto-refresh" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"><span class="text-sm text-gray-700">Auto-refresh a cada 30min</span></label>
 
 
 
 
 
 
 
 
 
 
 
 
 
320
  </div>
321
+ </div>
322
+
323
+ <!-- Intimações Results -->
324
+ <div id="intimacoes-results" class="bg-white rounded-xl shadow overflow-hidden">
325
+ <div class="p-4 border-b border-gray-200 flex justify-between items-center">
326
+ <h3 class="font-semibold text-lg">Intimações Encontradas</h3>
327
+ <span id="intimacoes-count" class="bg-indigo-100 text-indigo-700 px-3 py-1 rounded-full text-sm font-medium">0 resultados</span>
328
+ </div>
329
+ <div id="intimacoes-list" class="p-4">
330
+ <div class="text-center py-8 text-gray-400">
331
+ <i class="fas fa-gavel text-4xl mb-3"></i>
332
+ <p>Clique em "Buscar Intimações" para consultar a API AASP</p>
 
 
 
 
333
  </div>
334
  </div>
335
  </div>
336
+
337
+ <!-- Jornais Results -->
338
+ <div id="jornais-results" class="bg-white rounded-xl shadow overflow-hidden mt-6 hidden">
339
+ <div class="p-4 border-b border-gray-200"><h3 class="font-semibold text-lg">Jornais com Intimações</h3></div>
340
+ <div id="jornais-list" class="p-4"></div>
341
+ </div>
342
  </div>
343
 
344
  <!-- Import Data Tab -->
 
347
  <h2 class="text-2xl font-bold text-gray-800">Importar Dados</h2>
348
  <p class="text-gray-600">Conecte-se a planilhas externas ou importe arquivos para atualizar sua base de dados</p>
349
  </div>
 
350
  <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
351
  <div class="bg-white p-6 rounded-xl shadow">
352
+ <div class="flex items-center justify-between mb-4"><h3 class="font-semibold text-lg">Google Sheets</h3><div class="p-2 bg-blue-100 rounded-lg text-blue-600"><i class="fab fa-google text-xl"></i></div></div>
353
+ <p class="text-gray-600 mb-4">Conecte-se ao Google Sheets para sincronizar dados</p>
354
+ <button onclick="connectGoogleSheets()" class="w-full bg-blue-600 text-white py-2 rounded-lg hover:bg-blue-700 transition flex items-center justify-center" id="btn-connect-sheets"><i class="fab fa-google mr-2"></i> Conectar ao Google</button>
 
 
 
 
 
 
 
355
  </div>
356
  <div class="bg-white p-6 rounded-xl shadow">
357
+ <div class="flex items-center justify-between mb-4"><h3 class="font-semibold text-lg">Excel/CSV</h3><div class="p-2 bg-green-100 rounded-lg text-green-600"><i class="fas fa-file-excel text-xl"></i></div></div>
358
+ <p class="text-gray-600 mb-4">Importe arquivos Excel ou CSV</p>
359
+ <button onclick="document.getElementById('file-input').click()" class="w-full bg-green-600 text-white py-2 rounded-lg hover:bg-green-700 transition flex items-center justify-center"><i class="fas fa-upload mr-2"></i> Selecionar Arquivo</button>
360
+ <input type="file" id="file-input" class="hidden" accept=".xlsx,.xls,.csv" onchange="handleFileImport(event)">
361
+ </div>
362
+ <div class="bg-white p-6 rounded-xl shadow">
363
+ <div class="flex items-center justify-between mb-4"><h3 class="font-semibold text-lg">JSON/API</h3><div class="p-2 bg-purple-100 rounded-lg text-purple-600"><i class="fas fa-code text-xl"></i></div></div>
364
+ <p class="text-gray-600 mb-4">Importe dados em JSON ou conecte APIs</p>
365
+ <button onclick="showTab('integrations')" class="w-full bg-purple-600 text-white py-2 rounded-lg hover:bg-purple-700 transition flex items-center justify-center"><i class="fas fa-plug mr-2"></i> Configurar API</button>
366
+ </div>
367
+ </div>
368
+
369
+ <!-- Import Preview -->
370
+ <div id="import-preview" class="bg-white rounded-xl shadow overflow-hidden hidden">
371
+ <div class="p-4 border-b border-gray-200 flex justify-between items-center">
372
+ <h3 class="font-semibold text-lg">Pré-visualização dos Dados Importados</h3>
373
+ <button onclick="confirmImport()" class="bg-green-600 text-white px-4 py-2 rounded-lg hover:bg-green-700"><i class="fas fa-check mr-2"></i> Confirmar Importação</button>
374
+ </div>
375
+ <div class="overflow-x-auto"><table class="min-w-full divide-y divide-gray-200" id="import-preview-table"></table></div>
376
+ </div>
377
+ </div>
378
+
379
+ <!-- Configurações Tab -->
380
+ <div id="config" class="tab-content">
381
+ <h2 class="text-2xl font-bold text-gray-800 mb-6">Configurações</h2>
382
+ <div class="bg-white rounded-xl shadow p-6 mb-6">
383
+ <h3 class="font-semibold text-lg mb-4">Configurações Gerais</h3>
384
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
385
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Nome do Escritório</label><input type="text" value="LegalData Manager" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></div>
386
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">E-mail Principal</label><input type="email" value="admin@legaldata.com" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></div>
387
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Fuso Horário</label><select class="w-full px-4 py-2 rounded-lg border border-gray-300"><option>América/São Paulo (BRT)</option><option>América/Manaus (AMT)</option></select></div>
388
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Idioma</label><select class="w-full px-4 py-2 rounded-lg border border-gray-300"><option>Português (BR)</option><option>English</option></select></div>
389
+ </div>
390
+ <button class="mt-4 bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700"><i class="fas fa-save mr-2"></i> Salvar Configurações</button>
391
+ </div>
392
+ </div>
393
+
394
+ <!-- Sanitização Tab -->
395
+ <div id="sanitize" class="tab-content">
396
+ <h2 class="text-2xl font-bold text-gray-800 mb-6">Sanitização de Dados</h2>
397
+ <div class="bg-white rounded-xl shadow p-6 mb-6">
398
+ <h3 class="font-semibold text-lg mb-4">Limpeza e Validação</h3>
399
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
400
+ <div class="p-4 border rounded-lg"><i class="fas fa-user-shield text-indigo-600 text-2xl mb-2"></i><h4 class="font-medium">Validar CPF/CNPJ</h4><p class="text-sm text-gray-500">Verifica e corrige CPFs e CNPJs inválidos</p><button onclick="sanitizeData('cpfcnpj')" class="mt-2 bg-indigo-600 text-white px-3 py-1 rounded text-sm hover:bg-indigo-700">Executar</button></div>
401
+ <div class="p-4 border rounded-lg"><i class="fas fa-phone text-green-600 text-2xl mb-2"></i><h4 class="font-medium">Padronizar Telefones</h4><p class="text-sm text-gray-500">Formata números de telefone</p><button onclick="sanitizeData('phone')" class="mt-2 bg-green-600 text-white px-3 py-1 rounded text-sm hover:bg-green-700">Executar</button></div>
402
+ <div class="p-4 border rounded-lg"><i class="fas fa-envelope text-blue-600 text-2xl mb-2"></i><h4 class="font-medium">Validar E-mails</h4><p class="text-sm text-gray-500">Verifica e-mails inválidos</p><button onclick="sanitizeData('email')" class="mt-2 bg-blue-600 text-white px-3 py-1 rounded text-sm hover:bg-blue-700">Executar</button></div>
403
+ <div class="p-4 border rounded-lg"><i class="fas fa-duplicate text-yellow-600 text-2xl mb-2"></i><h4 class="font-medium">Remover Duplicatas</h4><p class="text-sm text-gray-500">Identifica e remove registros duplicados</p><button onclick="sanitizeData('duplicates')" class="mt-2 bg-yellow-600 text-white px-3 py-1 rounded text-sm hover:bg-yellow-700">Executar</button></div>
404
+ </div>
405
+ </div>
406
+ </div>
407
+
408
+ <!-- Integrações Tab -->
409
+ <div id="integrations" class="tab-content">
410
+ <h2 class="text-2xl font-bold text-gray-800 mb-6">Integrações</h2>
411
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
412
+ <div class="bg-white rounded-xl shadow p-6">
413
+ <div class="flex items-center space-x-3 mb-4">
414
+ <div class="p-3 bg-indigo-100 rounded-lg text-indigo-600"><i class="fas fa-gavel text-2xl"></i></div>
415
+ <div><h3 class="font-semibold text-lg">AASP - Intimações</h3><p class="text-sm text-gray-500">Associação dos Advogados de SP</p></div>
416
  </div>
417
+ <div class="flex items-center space-x-2 mb-4">
418
+ <span class="w-3 h-3 rounded-full bg-green-500 aasp-pulse"></span>
419
+ <span class="text-sm text-green-600 font-medium" id="aasp-conn-status">Configurada</span>
 
 
 
 
 
 
420
  </div>
421
+ <p class="text-gray-600 text-sm mb-4">Receba intimações e publicações dos diários oficiais automaticamente.</p>
422
+ <button onclick="showTab('intimacoes')" class="w-full bg-indigo-600 text-white py-2 rounded-lg hover:bg-indigo-700 transition">Configurar AASP</button>
423
  </div>
424
+ <div class="bg-white rounded-xl shadow p-6">
425
+ <div class="flex items-center space-x-3 mb-4">
426
+ <div class="p-3 bg-blue-100 rounded-lg text-blue-600"><i class="fab fa-google text-2xl"></i></div>
427
+ <div><h3 class="font-semibold text-lg">Google Drive</h3><p class="text-sm text-gray-500">Armazenamento em nuvem</p></div>
428
+ </div>
429
+ <div class="flex items-center space-x-2 mb-4">
430
+ <span class="w-3 h-3 rounded-full" id="drive-conn-dot"></span>
431
+ <span class="text-sm font-medium" id="drive-conn-label">Desconectado</span>
432
+ </div>
433
+ <p class="text-gray-600 text-sm mb-4">Sincronize documentos e provas com o Google Drive.</p>
434
+ <button onclick="connectGoogleDrive()" class="w-full bg-blue-600 text-white py-2 rounded-lg hover:bg-blue-700 transition" id="drive-integration-btn">Conectar Google Drive</button>
435
+ </div>
436
+ <div class="bg-white rounded-xl shadow p-6">
437
+ <div class="flex items-center space-x-3 mb-4">
438
+ <div class="p-3 bg-green-100 rounded-lg text-green-600"><i class="fas fa-table text-2xl"></i></div>
439
+ <div><h3 class="font-semibold text-lg">Google Sheets</h3><p class="text-sm text-gray-500">Planilhas do escritório</p></div>
440
+ </div>
441
+ <div class="flex items-center space-x-2 mb-4">
442
+ <span class="w-3 h-3 rounded-full" id="sheets-conn-dot"></span>
443
+ <span class="text-sm font-medium" id="sheets-conn-label">Desconectado</span>
444
+ </div>
445
+ <p class="text-gray-600 text-sm mb-4">Importe dados da planilha base do escritório.</p>
446
+ <button onclick="connectGoogleSheets()" class="w-full bg-green-600 text-white py-2 rounded-lg hover:bg-green-700 transition" id="sheets-integration-btn">Conectar Planilha</button>
447
+ </div>
448
+ <div class="bg-white rounded-xl shadow p-6">
449
+ <div class="flex items-center space-x-3 mb-4">
450
+ <div class="p-3 bg-purple-100 rounded-lg text-purple-600"><i class="fas fa-external-link-alt text-2xl"></i></div>
451
+ <div><h3 class="font-semibold text-lg">Portal do Cliente</h3><p class="text-sm text-gray-500">Formulário externo</p></div>
452
+ </div>
453
+ <div class="flex items-center space-x-2 mb-4">
454
+ <span class="w-3 h-3 rounded-full bg-green-500"></span>
455
+ <span class="text-sm text-green-600 font-medium">Ativo</span>
456
  </div>
457
+ <p class="text-gray-600 text-sm mb-4">Página para clientes se cadastrarem e enviarem provas.</p>
458
+ <a href="cliente.html" target="_blank" class="block w-full bg-purple-600 text-white py-2 rounded-lg hover:bg-purple-700 transition text-center">Abrir Portal do Cliente</a>
 
 
459
  </div>
460
  </div>
461
+ </div>
462
+ </main>
463
+ </div>
464
+ </div>
465
 
466
+ <!-- Modal: Novo Processo -->
467
+ <div id="modal-new-process" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden flex items-center justify-center p-4">
468
+ <div class="bg-white rounded-xl shadow-2xl w-full max-w-lg max-h-[90vh] overflow-y-auto">
469
+ <div class="p-6 border-b border-gray-200 flex justify-between items-center"><h3 class="text-lg font-semibold">Novo Processo</h3><button onclick="hideModal('new-process')" class="text-gray-400 hover:text-gray-600"><i class="fas fa-times text-xl"></i></button></div>
470
+ <div class="p-6 space-y-4">
471
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Número do Processo</label><input type="text" id="proc-numero" placeholder="Ex: 2023-0456" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></div>
472
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Cliente</label><select id="proc-cliente" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></select></div>
473
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Tribunal</label><select id="proc-tribunal" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"><option>TJSP</option><option>TJMG</option><option>TRF1</option><option>TRF2</option><option>TRF3</option><option>TRF4</option><option>TRF5</option></select></div>
474
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Data de Abertura</label><input type="date" id="proc-data" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></div>
475
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Status</label><select id="proc-status" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"><option>Ativo</option><option>Pendente</option><option>Concluído</option><option>Arquivado</option></select></div>
476
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Descrição</label><textarea id="proc-descricao" rows="3" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></textarea></div>
477
+ </div>
478
+ <div class="p-6 border-t border-gray-200 flex justify-end space-x-3"><button onclick="hideModal('new-process')" class="px-4 py-2 rounded-lg border border-gray-300 hover:bg-gray-50">Cancelar</button><button onclick="addProcess()" class="px-4 py-2 rounded-lg bg-indigo-600 text-white hover:bg-indigo-700">Salvar Processo</button></div>
479
+ </div>
480
+ </div>
481
+
482
+ <!-- Modal: Novo Cliente -->
483
+ <div id="modal-new-client" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden flex items-center justify-center p-4">
484
+ <div class="bg-white rounded-xl shadow-2xl w-full max-w-lg max-h-[90vh] overflow-y-auto">
485
+ <div class="p-6 border-b border-gray-200 flex justify-between items-center"><h3 class="text-lg font-semibold">Novo Cliente</h3><button onclick="hideModal('new-client')" class="text-gray-400 hover:text-gray-600"><i class="fas fa-times text-xl"></i></button></div>
486
+ <div class="p-6 space-y-4">
487
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Nome Completo</label><input type="text" id="cli-nome" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></div>
488
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Tipo</label><select id="cli-tipo" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"><option value="pf">Pessoa Física</option><option value="pj">Pessoa Jurídica</option></select></div>
489
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">CPF/CNPJ</label><input type="text" id="cli-cpfcnpj" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></div>
490
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">E-mail</label><input type="email" id="cli-email" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></div>
491
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Telefone</label><input type="text" id="cli-telefone" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></div>
492
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Endereço</label><input type="text" id="cli-endereco" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></div>
493
+ </div>
494
+ <div class="p-6 border-t border-gray-200 flex justify-end space-x-3"><button onclick="hideModal('new-client')" class="px-4 py-2 rounded-lg border border-gray-300 hover:bg-gray-50">Cancelar</button><button onclick="addClient()" class="px-4 py-2 rounded-lg bg-indigo-600 text-white hover:bg-indigo-700">Salvar Cliente</button></div>
495
+ </div>
496
+ </div>
497
+
498
+ <!-- Modal: Upload Prova -->
499
+ <div id="modal-upload-evidence" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden flex items-center justify-center p-4">
500
+ <div class="bg-white rounded-xl shadow-2xl w-full max-w-lg max-h-[90vh] overflow-y-auto">
501
+ <div class="p-6 border-b border-gray-200 flex justify-between items-center"><h3 class="text-lg font-semibold">Enviar Prova</h3><button onclick="hideModal('upload-evidence')" class="text-gray-400 hover:text-gray-600"><i class="fas fa-times text-xl"></i></button></div>
502
+ <div class="p-6 space-y-4">
503
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Cliente</label><select id="ev-cliente" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></select></div>
504
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Processo</label><select id="ev-processo" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></select></div>
505
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Categoria</label><select id="ev-categoria" class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"><option value="documento">Documento</option><option value="foto">Foto</option><option value="video">Vídeo</option><option value="audio">Áudio</option><option value="outro">Outro</option></select></div>
506
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Descrição</label><textarea id="ev-descricao" rows="2" placeholder="Descreva a prova..." class="w-full px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"></textarea></div>
507
+ <div id="drop-zone" class="drop-zone rounded-xl p-8 text-center cursor-pointer" onclick="document.getElementById('ev-file').click()" ondragover="event.preventDefault();this.classList.add('dragover')" ondragleave="this.classList.remove('dragover')" ondrop="event.preventDefault();this.classList.remove('dragover');handleEvidenceDrop(event)">
508
+ <i class="fas fa-cloud-upload-alt text-4xl text-indigo-300 mb-3"></i>
509
+ <p class="text-gray-500">Arraste arquivos aqui ou clique para selecionar</p>
510
+ <p class="text-sm text-gray-400 mt-1">Imagens, PDFs, vídeos e áudios</p>
511
+ <input type="file" id="ev-file" class="hidden" multiple accept="image/*,.pdf,video/*,audio/*" onchange="handleEvidenceSelect(event)">
512
+ </div>
513
+ <div id="ev-preview" class="hidden grid grid-cols-3 gap-2"></div>
514
+ <div><label class="flex items-center space-x-2"><input type="checkbox" id="ev-upload-drive" class="rounded border-gray-300 text-indigo-600" checked><span class="text-sm text-gray-700">Salvar também no Google Drive</span></label></div>
515
+ </div>
516
+ <div class="p-6 border-t border-gray-200 flex justify-end space-x-3"><button onclick="hideModal('upload-evidence')" class="px-4 py-2 rounded-lg border border-gray-300 hover:bg-gray-50">Cancelar</button><button onclick="uploadEvidence()" class="px-4 py-2 rounded-lg bg-indigo-600 text-white hover:bg-indigo-700"><i class="fas fa-upload mr-2"></i>Enviar</button></div>
517
+ </div>
518
+ </div>
519
+
520
+ <!-- Modal: Detalhes da Prova -->
521
+ <div id="modal-evidence-detail" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden flex items-center justify-center p-4">
522
+ <div class="bg-white rounded-xl shadow-2xl w-full max-w-2xl max-h-[90vh] overflow-y-auto">
523
+ <div class="p-6 border-b border-gray-200 flex justify-between items-center"><h3 class="text-lg font-semibold">Detalhes da Prova</h3><button onclick="hideModal('evidence-detail')" class="text-gray-400 hover:text-gray-600"><i class="fas fa-times text-xl"></i></button></div>
524
+ <div class="p-6" id="evidence-detail-content"></div>
525
+ </div>
526
+ </div>
527
+
528
+ <script src="app.js"></script>
529
+ </body>
530
  </html>