- Pasta renomeada: /var/www/pointcontrol → /var/www/noidle - PM2 renomeado: pointcontrol-api → noidle-api - Package.json backend atualizado - Package.json frontend atualizado - Todas as referências de código atualizadas - Documentação atualizada - Script de migração executado com sucesso - Backup criado em /tmp/ - Sistema testado e funcionando Resolução: Organização completa da estrutura bagunçada
499 lines
13 KiB
Markdown
499 lines
13 KiB
Markdown
# 🎨 Dashboard Frontend - NoIdle (estilo JumpCloud)
|
||
|
||
## 📋 Visão Geral
|
||
|
||
Dashboard moderno e funcional para o NoIdle, inspirado no design do JumpCloud, com estatísticas em tempo real, alertas e notificações.
|
||
|
||
---
|
||
|
||
## ✨ Componentes Criados
|
||
|
||
### 1. **MainDashboard.jsx** (400 linhas)
|
||
|
||
Componente principal do dashboard com:
|
||
|
||
**Estatísticas Principais (Cards grandes):**
|
||
- 👥 Usuários
|
||
- 👥 Times
|
||
- 💻 Dispositivos
|
||
- 🛡️ Políticas MDM
|
||
- 📊 Atividades Hoje
|
||
|
||
**Cards de Alertas (8 cards):**
|
||
- ⚠️ Dispositivos Offline (7+ dias)
|
||
- ℹ️ Sem Atividade (24h)
|
||
- ❌ Políticas Falhadas (24h)
|
||
- ✅ Comandos Pendentes
|
||
- 🔄 Precisam Atualização
|
||
- 💾 Espaço em Disco Baixo
|
||
- 🟢 Online Agora
|
||
- 👤 Usuários Inativos (30d)
|
||
|
||
**Status do Sistema:**
|
||
- API Backend
|
||
- Banco de Dados
|
||
- Sistema MDM
|
||
- Última Atualização
|
||
|
||
**Notificações:**
|
||
- Dispositivos
|
||
- Atividade Recente
|
||
|
||
---
|
||
|
||
## 🎨 Preview do Design
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ Bem-vindo, Admin! 👋 [Atualizar] [Configurações] │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐│
|
||
│ │ 77 │ │ 14 │ │ 143 │ │ 8 │ │ 1.2K ││
|
||
│ │ Usuários │ │ Times │ │Disposit. │ │Políticas │ │Ativid. ││
|
||
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └────────┘│
|
||
│ │
|
||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||
│ │ [●] 0 │ │ [✓] 0 │ │ [!] 0 │ │ [i] 0 │ │
|
||
│ │ Offline │ │Sem Ativ. │ │Políticas │ │Comandos │ │
|
||
│ │ 7+ dias │ │ 24h │ │ Falhadas │ │Pendentes │ │
|
||
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
||
│ │
|
||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||
│ │ [↑] 0 │ │ [!] 0 │ │ [✓] 45 │ │ [i] 0 │ │
|
||
│ │Precisam │ │ Disco │ │ Online │ │Inativos │ │
|
||
│ │Atualiz. │ │ Baixo │ │ Agora │ │ 30d │ │
|
||
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
||
│ │
|
||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||
│ │ Status do Sistema [✓] OK │ │
|
||
│ │ ✅ Todos os serviços estão operacionais │ │
|
||
│ │ • API Backend: Online │ │
|
||
│ │ • Banco de Dados: Conectado │ │
|
||
│ │ • Sistema MDM: Ativo │ │
|
||
│ └──────────────────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─────────────────────────┐ ┌────────────────────────────┐ │
|
||
│ │ Notificações │ │ Atividade Recente │ │
|
||
│ │ • Offline 7+ dias: 12 │ │ • Dispositivos online: 45 │ │
|
||
│ │ • Sem atividade: 8 │ │ • Políticas exec. hoje: - │ │
|
||
│ │ • Precisam update: 5 │ │ • Comandos pendentes: 3 │ │
|
||
│ └─────────────────────────┘ └────────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 Implementação
|
||
|
||
### 1. Instalar Dependências
|
||
|
||
```bash
|
||
cd /var/www/noidle/frontend
|
||
npm install @mui/material @emotion/react @emotion/styled @mui/icons-material
|
||
```
|
||
|
||
### 2. Criar Estrutura de Pastas
|
||
|
||
```bash
|
||
mkdir -p components/Dashboard
|
||
mkdir -p pages/dashboard
|
||
```
|
||
|
||
### 3. Copiar Componente
|
||
|
||
Arquivo já criado:
|
||
- `frontend/components/Dashboard/MainDashboard.jsx`
|
||
|
||
### 4. Criar Página Next.js
|
||
|
||
```javascript
|
||
// pages/dashboard/index.js
|
||
import MainDashboard from '../../components/Dashboard/MainDashboard';
|
||
import Layout from '../../components/Layout';
|
||
|
||
export default function DashboardPage() {
|
||
return (
|
||
<Layout>
|
||
<MainDashboard />
|
||
</Layout>
|
||
);
|
||
}
|
||
```
|
||
|
||
### 5. Atualizar Navegação
|
||
|
||
No menu lateral, adicionar link para `/dashboard`.
|
||
|
||
---
|
||
|
||
## 📊 API Endpoint
|
||
|
||
### GET /api/dashboard/stats
|
||
|
||
**Resposta:**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"stats": {
|
||
"users": 77,
|
||
"teams": 14,
|
||
"devices": 143,
|
||
"policies": 8,
|
||
"activities_today": 1234,
|
||
"devices_online": 45,
|
||
"devices_offline": 98,
|
||
"pending_commands": 3
|
||
},
|
||
"alerts": {
|
||
"devices_offline_7days": 12,
|
||
"devices_no_activity_24h": 8,
|
||
"failed_policies_24h": 2,
|
||
"devices_need_update": 5,
|
||
"low_disk_space": 1,
|
||
"inactive_users": 3
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🎨 Customização de Cores
|
||
|
||
### Paleta de Cores Usada:
|
||
|
||
```javascript
|
||
const colors = {
|
||
primary: '#2563eb', // Azul - Usuários
|
||
secondary: '#7c3aed', // Roxo - Times
|
||
success: '#059669', // Verde - Dispositivos
|
||
danger: '#dc2626', // Vermelho - Políticas
|
||
warning: '#f59e0b', // Laranja - Avisos
|
||
info: '#3b82f6', // Azul claro - Informações
|
||
orange: '#ea580c', // Laranja escuro - Atividades
|
||
gray: '#6b7280' // Cinza - Inativos
|
||
};
|
||
```
|
||
|
||
### Customizar no Theme:
|
||
|
||
```javascript
|
||
// theme.js
|
||
import { createTheme } from '@mui/material/styles';
|
||
|
||
const theme = createTheme({
|
||
palette: {
|
||
primary: {
|
||
main: '#2563eb',
|
||
},
|
||
secondary: {
|
||
main: '#7c3aed',
|
||
},
|
||
success: {
|
||
main: '#10b981',
|
||
},
|
||
error: {
|
||
main: '#dc2626',
|
||
},
|
||
warning: {
|
||
main: '#f59e0b',
|
||
},
|
||
info: {
|
||
main: '#3b82f6',
|
||
},
|
||
},
|
||
typography: {
|
||
fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif',
|
||
h4: {
|
||
fontWeight: 700,
|
||
},
|
||
h6: {
|
||
fontWeight: 600,
|
||
},
|
||
},
|
||
shape: {
|
||
borderRadius: 8,
|
||
},
|
||
});
|
||
|
||
export default theme;
|
||
```
|
||
|
||
---
|
||
|
||
## 🔄 Atualização em Tempo Real
|
||
|
||
O componente atualiza automaticamente a cada 30 segundos:
|
||
|
||
```javascript
|
||
useEffect(() => {
|
||
fetchDashboardData();
|
||
const interval = setInterval(fetchDashboardData, 30000);
|
||
return () => clearInterval(interval);
|
||
}, []);
|
||
```
|
||
|
||
Para desabilitar:
|
||
```javascript
|
||
// Remover o setInterval
|
||
```
|
||
|
||
Para mudar frequência:
|
||
```javascript
|
||
const interval = setInterval(fetchDashboardData, 60000); // 1 minuto
|
||
```
|
||
|
||
---
|
||
|
||
## 📱 Responsividade
|
||
|
||
### Breakpoints Material-UI:
|
||
|
||
```javascript
|
||
// xs: 0-600px (mobile)
|
||
// sm: 600-960px (tablet)
|
||
// md: 960-1280px (laptop)
|
||
// lg: 1280-1920px (desktop)
|
||
// xl: 1920px+ (large screens)
|
||
```
|
||
|
||
### Grid Responsivo:
|
||
|
||
```javascript
|
||
<Grid item xs={12} sm={6} md={2.4}> // 5 cards em desktop, 2 em tablet, 1 em mobile
|
||
<StatCard ... />
|
||
</Grid>
|
||
|
||
<Grid item xs={12} sm={6} md={3}> // 4 cards em desktop, 2 em tablet, 1 em mobile
|
||
<AlertCard ... />
|
||
</Grid>
|
||
```
|
||
|
||
---
|
||
|
||
## 🧪 Testes
|
||
|
||
### Testar Componente:
|
||
|
||
```javascript
|
||
// __tests__/MainDashboard.test.js
|
||
import { render, screen, waitFor } from '@testing-library/react';
|
||
import MainDashboard from '../components/Dashboard/MainDashboard';
|
||
|
||
global.fetch = jest.fn(() =>
|
||
Promise.resolve({
|
||
json: () => Promise.resolve({
|
||
success: true,
|
||
stats: {
|
||
users: 77,
|
||
teams: 14,
|
||
devices: 143,
|
||
// ...
|
||
},
|
||
alerts: {
|
||
devices_offline_7days: 12,
|
||
// ...
|
||
}
|
||
})
|
||
})
|
||
);
|
||
|
||
test('renders dashboard with stats', async () => {
|
||
render(<MainDashboard />);
|
||
|
||
await waitFor(() => {
|
||
expect(screen.getByText('77')).toBeInTheDocument();
|
||
expect(screen.getByText('Usuários')).toBeInTheDocument();
|
||
});
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
## 🎯 Funcionalidades Futuras
|
||
|
||
### 1. Gráficos e Charts
|
||
```javascript
|
||
import { LineChart, BarChart } from 'recharts';
|
||
|
||
// Gráfico de atividades dos últimos 7 dias
|
||
// Gráfico de políticas executadas
|
||
// Gráfico de dispositivos online vs offline
|
||
```
|
||
|
||
### 2. Filtros Avançados
|
||
```javascript
|
||
// Filtrar por período (hoje, semana, mês)
|
||
// Filtrar por time
|
||
// Filtrar por status
|
||
```
|
||
|
||
### 3. Ações Rápidas
|
||
```javascript
|
||
// Executar política em dispositivos selecionados
|
||
// Enviar notificação para usuários
|
||
// Gerar relatório
|
||
```
|
||
|
||
### 4. Notificações em Tempo Real
|
||
```javascript
|
||
// WebSocket para notificações push
|
||
// Toast notifications
|
||
// Badge de contador
|
||
```
|
||
|
||
---
|
||
|
||
## 📝 Checklist de Implementação
|
||
|
||
### Backend:
|
||
- [x] Criar rota `/api/dashboard/stats`
|
||
- [x] Queries para estatísticas
|
||
- [x] Queries para alertas
|
||
- [ ] Testar endpoint com Postman
|
||
|
||
### Frontend:
|
||
- [x] Criar componente `MainDashboard.jsx`
|
||
- [ ] Criar página `pages/dashboard/index.js`
|
||
- [ ] Adicionar ao menu de navegação
|
||
- [ ] Configurar tema Material-UI
|
||
- [ ] Testar responsividade
|
||
- [ ] Adicionar loading states
|
||
- [ ] Adicionar error handling
|
||
|
||
### Integrações:
|
||
- [ ] Conectar com sistema MDM
|
||
- [ ] Conectar com políticas
|
||
- [ ] Conectar com dispositivos
|
||
- [ ] Conectar com usuários
|
||
|
||
---
|
||
|
||
## 🚀 Deploy
|
||
|
||
### 1. Build Frontend:
|
||
```bash
|
||
cd /var/www/noidle/frontend
|
||
npm run build
|
||
```
|
||
|
||
### 2. Start Production:
|
||
```bash
|
||
npm start
|
||
# ou
|
||
pm2 start npm --name "noidle-frontend" -- start
|
||
```
|
||
|
||
### 3. Configurar Proxy Nginx:
|
||
```nginx
|
||
location / {
|
||
proxy_pass http://localhost:3000;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Upgrade $http_upgrade;
|
||
proxy_set_header Connection 'upgrade';
|
||
proxy_set_header Host $host;
|
||
proxy_cache_bypass $http_upgrade;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 📖 Documentação de Componentes
|
||
|
||
### StatCard
|
||
|
||
```javascript
|
||
<StatCard
|
||
title="Usuários"
|
||
value={77}
|
||
icon={GroupIcon}
|
||
color="#2563eb"
|
||
link="/users"
|
||
/>
|
||
```
|
||
|
||
**Props:**
|
||
- `title` (string): Título do card
|
||
- `value` (number): Valor numérico
|
||
- `icon` (Component): Ícone Material-UI
|
||
- `color` (string): Cor do ícone (hex)
|
||
- `link` (string): URL para navegação
|
||
|
||
### AlertCard
|
||
|
||
```javascript
|
||
<AlertCard
|
||
title="Dispositivos Offline"
|
||
value={12}
|
||
icon={WarningIcon}
|
||
color="#dc2626"
|
||
link="/devices?status=offline"
|
||
/>
|
||
```
|
||
|
||
**Props:**
|
||
- `title` (string): Título do alerta
|
||
- `value` (number): Valor numérico
|
||
- `icon` (Component): Ícone Material-UI
|
||
- `color` (string): Cor da barra lateral
|
||
- `link` (string): URL para ver detalhes
|
||
|
||
---
|
||
|
||
## 🎨 Screenshots Esperados
|
||
|
||
### Desktop (1920x1080):
|
||
- 5 cards de estatísticas principais em linha
|
||
- 4 cards de alertas por linha (2 linhas = 8 cards)
|
||
- 2 cards de notificações lado a lado
|
||
|
||
### Tablet (768x1024):
|
||
- 2 cards de estatísticas por linha
|
||
- 2 cards de alertas por linha
|
||
- 2 cards de notificações empilhados
|
||
|
||
### Mobile (375x667):
|
||
- 1 card por linha (empilhados)
|
||
- Scroll vertical
|
||
|
||
---
|
||
|
||
## ✅ Status
|
||
|
||
| Componente | Status | Progresso |
|
||
|------------|--------|-----------|
|
||
| MainDashboard.jsx | ✅ Criado | 100% |
|
||
| API /dashboard/stats | ✅ Criada | 100% |
|
||
| Página Next.js | ⏳ Pendente | 0% |
|
||
| Tema Material-UI | ⏳ Pendente | 0% |
|
||
| Testes | ⏳ Pendente | 0% |
|
||
| Deploy | ⏳ Pendente | 0% |
|
||
|
||
---
|
||
|
||
## 🆘 Troubleshooting
|
||
|
||
### Erro: "Module not found: @mui/material"
|
||
```bash
|
||
npm install @mui/material @emotion/react @emotion/styled
|
||
```
|
||
|
||
### Erro: "fetch is not defined" (SSR)
|
||
```javascript
|
||
// Usar SWR ou adicionar polyfill
|
||
import 'isomorphic-fetch';
|
||
```
|
||
|
||
### Cards não responsivos
|
||
```javascript
|
||
// Verificar breakpoints do Grid
|
||
<Grid item xs={12} sm={6} md={3}>
|
||
```
|
||
|
||
---
|
||
|
||
**Dashboard Frontend Implementado e Pronto! 🎉**
|
||
|
||
**Próximo passo:** Criar a página Next.js e integrar no menu.
|
||
|