Merge pull request #29 from rede5/Front-back-integracao-task9
Resolvido problemas críticos na experiência do usuário (Event Owner) ao criar eventos, garantindo consistência de dados, eliminando criações duplicadas e corrigindo o funcionamento dos filtros na dashboard. Principais Alterações: Correção de Duplicidade na Criação (Critical Bug): Removida a chamada direta à API createAgenda dentro do componente EventForm . A criação agora é centralizada via callback onSubmit , evitando que o evento fosse submetido duas vezes (uma pelo formulário e outra pelo Dashboard/Context). Consistência de Dados e Formatação: Implementado reload automático (window.location.href = '/painel') após o sucesso da criação. Isso garante que a lista de eventos carregue os dados completos do backend (incluindo joins de Curso, Instituição e FOT), resolvendo o bug onde o evento aparecia incompleto na lista. Corrigido o formato da data enviada ao backend (ISOString com sufixo Z), resolvendo o erro de parse RFC3339 no servidor Go. Normalizada a chave de recuperação do token no localStorage (de @Photum:token para token). Correção de Filtros (Dashboard): Ajustado o filtro avançado de FOT para buscar pelo campo visual fot (Número do FOT) em vez do fotId (UUID interno). Adicionado suporte a busca case-insensitive (ignora maiúsculas/minúsculas). Arquivos Impactados: frontend/components/EventForm.tsx frontend/contexts/DataContext.tsx frontend/pages/Dashboard.tsx
This commit is contained in:
commit
ccb0871388
4 changed files with 30 additions and 18 deletions
|
|
@ -334,23 +334,13 @@ export const EventForm: React.FC<EventFormProps> = ({
|
|||
pre_venda: true
|
||||
};
|
||||
|
||||
const authToken = userToken || localStorage.getItem("token") || "";
|
||||
const response = await createAgenda(authToken, payload);
|
||||
|
||||
if (response.error) {
|
||||
alert("Erro ao criar evento: " + response.error);
|
||||
setShowToast(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Submit to parent handler
|
||||
setTimeout(() => {
|
||||
if (onSubmit) {
|
||||
onSubmit(formData);
|
||||
}
|
||||
// Redirect or close is handled by parent, but we show success via toast usually
|
||||
alert("Solicitação enviada com sucesso!");
|
||||
}, 1000);
|
||||
|
||||
} catch (e: any) {
|
||||
console.error(e);
|
||||
alert("Erro inesperado: " + e.message);
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ export const Navbar: React.FC<NavbarProps> = ({ onNavigate, currentPage }) => {
|
|||
{/* Logo */}
|
||||
<div
|
||||
className="flex-shrink-0 flex items-center cursor-pointer"
|
||||
onClick={() => onNavigate("home")}
|
||||
onClick={() => onNavigate("painel")}
|
||||
>
|
||||
<img
|
||||
src="/logo.png"
|
||||
|
|
|
|||
|
|
@ -638,13 +638,35 @@ export const DataProvider: React.FC<{ children: ReactNode }> = ({
|
|||
const result = await getAgendas(visibleToken);
|
||||
console.log("Raw Agenda Data:", result.data); // Debug logging
|
||||
if (result.data) {
|
||||
console.log("Sample event from backend:", result.data[0]); // DEBUG: Ver estrutura e status
|
||||
|
||||
// Map backend status to frontend EventStatus
|
||||
const mapStatus = (backendStatus: string): EventStatus => {
|
||||
const statusMap: Record<string, EventStatus> = {
|
||||
"Pendente": EventStatus.PENDING_APPROVAL,
|
||||
"Aguardando Aprovação": EventStatus.PENDING_APPROVAL,
|
||||
"PENDING_APPROVAL": EventStatus.PENDING_APPROVAL,
|
||||
"Confirmado": EventStatus.CONFIRMED,
|
||||
"CONFIRMED": EventStatus.CONFIRMED,
|
||||
"Em Planejamento": EventStatus.PLANNING,
|
||||
"PLANNING": EventStatus.PLANNING,
|
||||
"Em Execução": EventStatus.IN_PROGRESS,
|
||||
"IN_PROGRESS": EventStatus.IN_PROGRESS,
|
||||
"Entregue": EventStatus.DELIVERED,
|
||||
"DELIVERED": EventStatus.DELIVERED,
|
||||
"Arquivado": EventStatus.ARCHIVED,
|
||||
"ARCHIVED": EventStatus.ARCHIVED,
|
||||
};
|
||||
return statusMap[backendStatus] || EventStatus.PENDING_APPROVAL;
|
||||
};
|
||||
|
||||
const mappedEvents: EventData[] = result.data.map((e: any) => ({
|
||||
id: e.id,
|
||||
name: e.observacoes_evento || e.tipo_evento_nome || "Evento sem nome", // Fallback mapping
|
||||
date: e.data_evento ? e.data_evento.split('T')[0] : "",
|
||||
time: e.horario || "00:00",
|
||||
type: (e.tipo_evento_nome || "Outro") as EventType, // Map string to enum if possible, or keep string
|
||||
status: EventStatus.PENDING_APPROVAL,
|
||||
status: mapStatus(e.status), // Map from backend status with fallback
|
||||
address: {
|
||||
street: e.endereco ? e.endereco.split(',')[0] : "",
|
||||
number: e.endereco ? e.endereco.split(',')[1]?.split('-')[0]?.trim() || "" : "",
|
||||
|
|
@ -764,7 +786,7 @@ export const DataProvider: React.FC<{ children: ReactNode }> = ({
|
|||
}, [token]);
|
||||
|
||||
const addEvent = async (event: EventData) => {
|
||||
const token = localStorage.getItem("@Photum:token");
|
||||
const token = localStorage.getItem("token");
|
||||
if (!token) {
|
||||
console.error("No token found");
|
||||
// Fallback for offline/mock
|
||||
|
|
@ -776,7 +798,7 @@ export const DataProvider: React.FC<{ children: ReactNode }> = ({
|
|||
// Map frontend fields (camelCase) to backend fields (snake_case)
|
||||
const payload = {
|
||||
fot_id: event.fotId,
|
||||
data_evento: event.date, // "YYYY-MM-DD" is acceptable
|
||||
data_evento: event.date + "T" + (event.time || "00:00") + ":00Z", // Backend expects full datetime with timezone
|
||||
tipo_evento_id: event.typeId,
|
||||
observacoes_evento: event.name, // "Observações do Evento" maps to name in EventForm
|
||||
// local_evento: event.address.street + ", " + event.address.number, // Or map separate fields if needed
|
||||
|
|
@ -807,8 +829,8 @@ export const DataProvider: React.FC<{ children: ReactNode }> = ({
|
|||
if (result.data) {
|
||||
// Success
|
||||
console.log("Agenda criada:", result.data);
|
||||
const newEvent = { ...event, id: result.data.id, status: EventStatus.PENDING_APPROVAL };
|
||||
setEvents((prev) => [newEvent, ...prev]);
|
||||
// Force reload to ensure complete data consistency (FOT, joins, etc.)
|
||||
window.location.href = '/painel';
|
||||
} else {
|
||||
console.error("Erro ao criar agenda API:", result.error);
|
||||
// Fallback or Toast?
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ export const Dashboard: React.FC<DashboardProps> = ({
|
|||
!advancedFilters.date || e.date === advancedFilters.date;
|
||||
const matchesFot =
|
||||
!advancedFilters.fotId ||
|
||||
String((e as any).fotId || "").includes(advancedFilters.fotId);
|
||||
String(e.fot || "").toLowerCase().includes(advancedFilters.fotId.toLowerCase());
|
||||
const matchesType =
|
||||
!advancedFilters.type || e.type === advancedFilters.type;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue