🐳 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- app.js +1066 -0
- cliente.html +238 -0
- cliente.js +122 -0
- 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 |
-
|
| 15 |
-
}
|
| 16 |
-
.
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
}
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
}
|
| 25 |
-
.
|
| 26 |
-
|
| 27 |
-
}
|
| 28 |
-
|
| 29 |
-
|
| 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 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 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 |
-
|
| 84 |
-
|
| 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="
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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-
|
| 144 |
-
<div class="data-card bg-white p-6 rounded-xl shadow">
|
| 145 |
<div class="flex justify-between items-start">
|
| 146 |
-
<div>
|
| 147 |
-
|
| 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 |
-
|
| 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 |
-
|
| 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 |
-
|
| 188 |
-
|
| 189 |
-
|
|
|
|
|
|
|
| 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 |
-
|
| 216 |
-
|
| 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 |
-
|
| 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 |
-
|
| 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 |
-
|
| 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 |
-
|
| 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 |
-
|
| 397 |
-
|
| 398 |
-
|
| 399 |
-
|
| 400 |
-
|
| 401 |
-
|
| 402 |
-
|
| 403 |
-
</div>
|
| 404 |
-
</div>
|
| 405 |
</div>
|
| 406 |
-
<div class="
|
| 407 |
-
<
|
| 408 |
-
<
|
| 409 |
-
|
| 410 |
-
|
| 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 |
-
|
| 418 |
-
|
| 419 |
-
|
| 420 |
-
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 426 |
</div>
|
| 427 |
</div>
|
|
|
|
| 428 |
</div>
|
| 429 |
|
| 430 |
-
<
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 435 |
</div>
|
| 436 |
-
<div
|
| 437 |
-
<
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
|
| 441 |
-
|
| 442 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 443 |
</div>
|
| 444 |
</div>
|
| 445 |
-
<div class="
|
| 446 |
-
<
|
| 447 |
-
|
| 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 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
|
| 469 |
-
|
| 470 |
-
|
| 471 |
-
|
| 472 |
-
<
|
| 473 |
-
<
|
| 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 |
-
|
| 494 |
-
|
| 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 |
-
|
| 506 |
-
|
| 507 |
-
|
| 508 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 509 |
</div>
|
| 510 |
-
<
|
| 511 |
-
|
| 512 |
-
<
|
| 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
|
| 522 |
-
<div class="flex items-center
|
| 523 |
-
<
|
| 524 |
-
<div class="
|
| 525 |
-
|
| 526 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 527 |
</div>
|
| 528 |
-
<p class="text-gray-600 mb-4">
|
| 529 |
-
<
|
| 530 |
-
<i class="fas fa-plug mr-2"></i> Configurar API
|
| 531 |
-
</button>
|
| 532 |
</div>
|
| 533 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 534 |
|
| 535 |
-
|
| 536 |
-
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
| 540 |
-
|
| 541 |
-
|
| 542 |
-
|
| 543 |
-
|
| 544 |
-
|
| 545 |
-
|
| 546 |
-
|
| 547 |
-
|
| 548 |
-
|
| 549 |
-
|
| 550 |
-
|
| 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>
|