photum/frontend/docs/CHANGELOG_19JAN2026.md
JoaoVitorMS0 93d603da6c feat: implementa visualização de agenda para profissionais e melhorias no sistema
- Adiciona role 'agenda_viewer' para profissionais visualizarem apenas suas agendas
- Implementa middleware de autorização baseado em roles
- Adiciona validação de permissões nos endpoints de agenda
- Melhora exibição de dados financeiros e logísticos
- Atualiza componentes frontend para melhor UX
- Adiciona documentação sobre o papel de visualização de agenda
2026-01-19 17:06:27 -03:00

198 lines
5.7 KiB
Markdown

# Melhorias em Filtros Financeiros e Cadastro - Changelog
**Data de Implementação:** 19 de janeiro de 2026
**Branch:** dev
## 📋 Visão Geral
Implementação de filtros avançados de data na página de Extrato Financeiro e validação obrigatória de foto de perfil no cadastro de profissionais, visando melhorar o controle financeiro e a qualidade dos dados cadastrais.
## 🚀 Funcionalidades Implementadas
### 1. Sistema de Filtros Avançados de Data - Extrato Financeiro
**Objetivo:** Fornecer controle granular sobre visualização de transações financeiras
**Implementações:**
- ✅ Filtro de data de início para definir período inicial
- ✅ Filtro de data final para definir período final
- ✅ Opção para incluir/excluir finais de semana
- ✅ Painel expansível/recolhível para organização da interface
- ✅ Botão de limpeza rápida de filtros
- ✅ Integração com filtros existentes (FOT, Evento, Serviço, etc.)
**Funcionalidades:**
- ✅ Painel de filtros com indicador visual (▶/▼)
- ✅ Layout responsivo com grid para desktop
- ✅ Cálculo automático de intervalos de datas
- ✅ Exclusão automática de sábados e domingos quando desabilitado
- ✅ Mensagem visual quando filtros estão ativos
- ✅ Preservação de filtros de coluna existentes
**Arquivos Modificados:**
- `frontend/pages/Finance.tsx`
### 2. Validação Obrigatória de Foto de Perfil
**Objetivo:** Garantir que todos os profissionais tenham foto de perfil cadastrada
**Implementações:**
**No Formulário (ProfessionalForm):**
- ✅ Validação no `handleSubmit` antes do envio
- ✅ Label atualizado com asterisco (*) indicando obrigatoriedade
- ✅ Mensagem de erro clara: "A foto de perfil é obrigatória!"
- ✅ Bloqueio do envio se foto não estiver presente
**No Registro (ProfessionalRegister):**
- ✅ Validação adicional antes do upload
- ✅ Tratamento de erro específico para foto ausente
- ✅ Upload obrigatório (não mais opcional)
- ✅ Mensagem de erro: "A foto de perfil é obrigatória."
**Arquivos Modificados:**
- `frontend/components/ProfessionalForm.tsx`
- `frontend/pages/ProfessionalRegister.tsx`
## 🔧 Detalhes Técnicos
### 1. Filtros Avançados de Data
**Novos Estados Implementados:**
```typescript
const [dateFilters, setDateFilters] = useState({
startDate: "",
endDate: "",
includeWeekends: true,
});
const [showDateFilters, setShowDateFilters] = useState(false);
```
**Algoritmo de Filtragem:**
```typescript
// Advanced date filters
if (dateFilters.startDate || dateFilters.endDate || !dateFilters.includeWeekends) {
result = result.filter(t => {
// Parse date from dataRaw (YYYY-MM-DD) or data (DD/MM/YYYY)
let dateToCheck: Date;
if (t.dataRaw) {
dateToCheck = new Date(t.dataRaw);
} else {
const parts = t.data.split('/');
if (parts.length === 3) {
dateToCheck = new Date(
parseInt(parts[2]),
parseInt(parts[1]) - 1,
parseInt(parts[0])
);
} else {
return true; // Keep if can't parse
}
}
// Check date range
if (dateFilters.startDate) {
const startDate = new Date(dateFilters.startDate);
if (dateToCheck < startDate) return false;
}
if (dateFilters.endDate) {
const endDate = new Date(dateFilters.endDate);
endDate.setHours(23, 59, 59, 999);
if (dateToCheck > endDate) return false;
}
// Check weekends
if (!dateFilters.includeWeekends) {
const dayOfWeek = dateToCheck.getDay();
if (dayOfWeek === 0 || dayOfWeek === 6) return false;
}
return true;
});
}
```
**Lógica de Exclusão de Finais de Semana:**
- `dayOfWeek === 0` → Domingo
- `dayOfWeek === 6` → Sábado
- Exclusão automática quando checkbox desmarcado
**Interface de Usuário:**
```tsx
<div className="bg-white rounded shadow p-4 grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
<div>
<label>Data Início</label>
<input type="date" />
</div>
<div>
<label>Data Final</label>
<input type="date" />
</div>
<div>
<label>
<input type="checkbox" />
Incluir finais de semana
</label>
</div>
</div>
```
### 2. Validação de Foto Obrigatória
**Fluxo de Validação:**
1. **Formulário (ProfessionalForm.tsx):**
```typescript
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Validação de foto de perfil
if (!formData.avatar) {
alert("A foto de perfil é obrigatória!");
return;
}
// ... restante das validações
};
```
2. **Upload (ProfessionalRegister.tsx):**
```typescript
// Upload de Avatar (obrigatório)
if (!professionalData.avatar) {
throw new Error("A foto de perfil é obrigatória.");
}
try {
console.log("Iniciando upload do avatar...");
const uploadRes = await getUploadURL(
professionalData.avatar.name,
professionalData.avatar.type
);
if (uploadRes.error || !uploadRes.data) {
throw new Error(uploadRes.error || "Erro ao obter URL de upload");
}
await uploadFileToSignedUrl(
uploadRes.data.upload_url,
professionalData.avatar
);
avatarUrl = uploadRes.data.public_url;
console.log("Upload concluído. URL:", avatarUrl);
} catch (err) {
console.error("Erro no upload do avatar:", err);
throw new Error(
"Falha ao enviar foto de perfil: " +
(err instanceof Error ? err.message : "Erro desconhecido")
);
}
```
**Indicadores Visuais:**
- Label com asterisco vermelho: "Foto de Perfil *"
- Preview circular da foto com borda destacada (#B9CF33)
- Botão de remoção (X) quando foto está carregada
- Placeholder visual quando não há foto