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

5.7 KiB

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:

const [dateFilters, setDateFilters] = useState({
    startDate: "",
    endDate: "",
    includeWeekends: true,
});
const [showDateFilters, setShowDateFilters] = useState(false);

Algoritmo de Filtragem:

// 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:

<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):
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
};
  1. Upload (ProfessionalRegister.tsx):
// 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