diff --git a/frontend/components/AgendaDetailModal.tsx b/frontend/components/AgendaDetailModal.tsx index c748940..fbaa05a 100644 --- a/frontend/components/AgendaDetailModal.tsx +++ b/frontend/components/AgendaDetailModal.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useState } from 'react'; import { StackModal, StackPage, useStackModal } from './StackModal.tsx'; +import { fmtHora, fmtDataCurta, fmtDataHora } from '../utils/appTime.ts'; import { HybridBackend } from '../services/backend.ts'; import { useToast } from '../contexts/ToastContext.tsx'; import { AvaliacaoEditor } from './AvaliacaoEditor.tsx'; @@ -137,9 +138,9 @@ const HistoryPage: React.FC<{ appointmentId: string }> = ({ appointmentId }) =>

{new Date(h.at).toLocaleString('pt-BR')}

{h.detalhes?.de && h.detalhes?.para && (

- {new Date(h.detalhes.de.start).toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' })} + {fmtDataHora(h.detalhes.de.start)} {' → '} - {new Date(h.detalhes.para.start).toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' })} + {fmtDataHora(h.detalhes.para.start)}

)} @@ -304,8 +305,8 @@ const DentistaRestritoView: React.FC<{ ag: any; nome: string; dentNome: string;
-

{ag.start ? new Date(ag.start).toLocaleDateString('pt-BR', { weekday: 'short', day: 'numeric', month: 'short' }) : '—'}

-

{ag.start ? new Date(ag.start).toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' }) : '—'}

+

{ag.start ? fmtDataCurta(ag.start) : '—'}

+

{ag.start ? fmtHora(ag.start) : '—'}

@@ -421,8 +422,8 @@ const DetailPage: React.FC = (p) => {
-

{ag.start ? new Date(ag.start).toLocaleDateString('pt-BR', { weekday: 'short', day: 'numeric', month: 'short' }) : '—'}

-

{ag.start ? new Date(ag.start).toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' }) : '—'}

+

{ag.start ? fmtDataCurta(ag.start) : '—'}

+

{ag.start ? fmtHora(ag.start) : '—'}

diff --git a/frontend/utils/appTime.ts b/frontend/utils/appTime.ts new file mode 100644 index 0000000..99b54fe --- /dev/null +++ b/frontend/utils/appTime.ts @@ -0,0 +1,18 @@ +// Fuso de REFERÊNCIA do armazenamento. As colunas de horário (agendamentos.start_time) +// são `timestamp` naive; o backend (container) roda em America/Sao_Paulo, então o node-pg +// serializa o wall-clock naive nesse fuso. Para exibir o horário LITERAL (o mesmo que a +// Secretária ofereceu/gravou) em qualquer navegador, formatamos SEMPRE neste fuso — e não +// no fuso local do navegador (que causaria o deslocamento de ±1h). +export const STORAGE_TZ = 'America/Sao_Paulo'; + +const D = (v?: string | number | Date | null) => (v === null || v === undefined || v === '' ? null : new Date(v)); + +export const fmtHora = (v?: string | number | Date | null): string => { + const d = D(v); return d ? d.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit', timeZone: STORAGE_TZ }) : '—'; +}; +export const fmtDataCurta = (v?: string | number | Date | null): string => { + const d = D(v); return d ? d.toLocaleDateString('pt-BR', { weekday: 'short', day: 'numeric', month: 'short', timeZone: STORAGE_TZ }) : '—'; +}; +export const fmtDataHora = (v?: string | number | Date | null): string => { + const d = D(v); return d ? d.toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit', timeZone: STORAGE_TZ }) : '—'; +}; diff --git a/frontend/views/AgendaView.tsx b/frontend/views/AgendaView.tsx index 2956873..13ca5cd 100644 --- a/frontend/views/AgendaView.tsx +++ b/frontend/views/AgendaView.tsx @@ -3,6 +3,7 @@ import FullCalendar from '@fullcalendar/react'; import dayGridPlugin from '@fullcalendar/daygrid'; import timeGridPlugin from '@fullcalendar/timegrid'; import interactionPlugin from '@fullcalendar/interaction'; +import { fmtDataHora } from '../utils/appTime.ts'; import { Calendar as CalendarIcon, Plus, X, Loader2, GripVertical, Settings as GearIcon, Edit, Trash2, CalendarRange, Clock, User, Stethoscope, AlertCircle, CheckCircle2, Bell, CalendarClock, History, Download, PanelLeftClose, PanelLeftOpen } from 'lucide-react'; import { AgendaSettingsModal } from '../components/AgendaSettingsModal.tsx'; import { HorariosConfig } from '../components/HorariosConfig.tsx'; @@ -749,6 +750,7 @@ export const AgendaView: React.FC<{ onNavigate?: (view: string) => void; sidebar void; sidebar

- {new Date(i.start_time).toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' })} + {fmtDataHora(i.start_time)}

{i.status}