diff --git a/susconecta/app/profissional/page.tsx b/susconecta/app/profissional/page.tsx index f296436..57dcf44 100644 --- a/susconecta/app/profissional/page.tsx +++ b/susconecta/app/profissional/page.tsx @@ -613,13 +613,13 @@ const ProfissionalPage = () => { { id: "92953542", nome: "Carla Menezes", cpf: "111.222.333-44", idade: 67, sexo: "Feminino" }, ]); - const { reports, loadReports, loading: reportsLoading, createNewReport, updateExistingReport } = useReports(); + const { reports, loadReports, loadReportById, loading: reportsLoading, createNewReport, updateExistingReport } = useReports(); const [laudos, setLaudos] = useState([]); const [selectedRange, setSelectedRange] = useState<'todos'|'semana'|'mes'|'custom'>('mes'); const [startDate, setStartDate] = useState(null); const [endDate, setEndDate] = useState(null); - // helper to check if a date string is in range + // helper to check if a date string is in range const isInRange = (dateStr: string | undefined, range: 'todos'|'semana'|'mes'|'custom') => { if (range === 'todos') return true; if (!dateStr) return false; @@ -638,6 +638,27 @@ const ProfissionalPage = () => { return d.getFullYear() === now.getFullYear() && d.getMonth() === now.getMonth(); }; + // helper: ensure report has paciente object populated (fetch by id if necessary) + const ensurePaciente = async (report: any) => { + if (!report) return report; + try { + if (!report.paciente) { + const pid = report.patient_id ?? report.patient ?? report.paciente ?? null; + if (pid) { + try { + const p = await buscarPacientePorId(String(pid)); + if (p) report.paciente = p; + } catch (e) { + // ignore + } + } + } + } catch (e) { + // ignore + } + return report; + }; + // When selectedRange changes (and isn't custom), compute start/end dates useEffect(() => { const now = new Date(); @@ -832,7 +853,7 @@ const ProfissionalPage = () => {
setSearchTerm(e.target.value)} onKeyDown={handleKey} @@ -872,6 +893,11 @@ const ProfissionalPage = () => { const reportsMod = await import('@/lib/reports'); if (typeof reportsMod.listarRelatoriosPorPacientes === 'function') { const batch = await reportsMod.listarRelatoriosPorPacientes(patientIds); + // Filtrar apenas relatórios criados/solicitados por este usuário (evita mostrar laudos de outros médicos) + const mineOnly = (batch || []).filter((r: any) => { + const requester = ((r.requested_by ?? r.created_by ?? r.executante ?? r.requestedBy ?? r.createdBy) || '').toString(); + return user?.id && requester && requester === user.id; + }); // Enrich reports with paciente objects so UI shows name/cpf immediately const enriched = await (async (reportsArr: any[]) => { if (!reportsArr || !reportsArr.length) return reportsArr; @@ -887,7 +913,7 @@ const ProfissionalPage = () => { } catch (e) { return reportsArr; } - })(batch); + })(mineOnly); if (mounted) setLaudos(enriched || []); } else { // fallback: 请求 por paciente individual @@ -895,7 +921,14 @@ const ProfissionalPage = () => { for (const pid of patientIds) { try { const rels = await import('@/lib/reports').then(m => m.listarRelatoriosPorPaciente(pid)); - if (Array.isArray(rels)) allReports.push(...rels); + if (Array.isArray(rels) && rels.length) { + // filtrar por autor (requested_by / created_by / executante) + const mine = rels.filter((r: any) => { + const requester = ((r.requested_by ?? r.created_by ?? r.executante ?? r.requestedBy ?? r.createdBy) || '').toString(); + return user?.id && requester && requester === user.id; + }); + if (mine.length) allReports.push(...mine); + } } catch (err) { console.warn('[LaudoManager] falha ao carregar relatórios para paciente', pid, err); } @@ -921,7 +954,13 @@ const ProfissionalPage = () => { for (const pid of patientIds) { try { const rels = await import('@/lib/reports').then(m => m.listarRelatoriosPorPaciente(pid)); - if (Array.isArray(rels)) allReports.push(...rels); + if (Array.isArray(rels) && rels.length) { + const mine = rels.filter((r: any) => { + const requester = ((r.requested_by ?? r.created_by ?? r.executante ?? r.requestedBy ?? r.createdBy) || '').toString(); + return user?.id && requester && requester === user.id; + }); + if (mine.length) allReports.push(...mine); + } } catch (e) { console.warn('[LaudoManager] falha ao carregar relatórios para paciente', pid, e); } @@ -953,6 +992,21 @@ const ProfissionalPage = () => { if (!laudos || laudos.length === 0) setLaudos(reports || []); }, [reports]); + // Sort reports newest-first (more recent dates at the top) + const sortedLaudos = React.useMemo(() => { + const arr = (filteredLaudos || []).slice(); + arr.sort((a: any, b: any) => { + try { + const da = new Date(getReportDate(a) || 0).getTime() || 0; + const db = new Date(getReportDate(b) || 0).getTime() || 0; + return db - da; + } catch (e) { + return 0; + } + }); + return arr; + }, [filteredLaudos]); + const [activeTab, setActiveTab] = useState("descobrir"); const [laudoSelecionado, setLaudoSelecionado] = useState(null); const [isViewing, setIsViewing] = useState(false); @@ -1006,13 +1060,13 @@ const ProfissionalPage = () => {
- { setStartDate(e.target.value); setSelectedRange('custom'); }} className="p-1 text-sm" /> - - - { setEndDate(e.target.value); setSelectedRange('custom'); }} className="p-1 text-sm" /> + { setStartDate(e.target.value); setSelectedRange('custom'); }} className="p-1 text-sm h-10" /> + - + { setEndDate(e.target.value); setSelectedRange('custom'); }} className="p-1 text-sm h-10" />
-
+
{/* date range buttons: Semana / Mês */}
@@ -1038,8 +1092,8 @@ const ProfissionalPage = () => { - {filteredLaudos.map((laudo) => ( - + {sortedLaudos.map((laudo, idx) => ( +
{laudo.urgente && ( @@ -1058,8 +1112,24 @@ const ProfissionalPage = () => {
-
{laudo?.prazo ?? laudo?.due_at ? formatReportDate(laudo?.due_at ?? laudo?.prazo) : '-'}
-
{laudo?.prazo_hora ?? laudo?.due_time ?? '-'}
+
{(laudo?.prazo ?? laudo?.due_at) ? formatReportDate(laudo?.due_at ?? laudo?.prazo) : '-'}
+
{ + (() => { + // prefer explicit fields + const explicit = laudo?.prazo_hora ?? laudo?.due_time ?? laudo?.hora ?? null; + if (explicit) return explicit; + // fallback: try to parse due_at / prazo datetime and extract time + const due = laudo?.due_at ?? laudo?.prazo ?? laudo?.dueDate ?? laudo?.data ?? null; + if (!due) return '-'; + try { + const d = new Date(due); + if (isNaN(d.getTime())) return '-'; + return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); + } catch (e) { + return '-'; + } + })() + }
@@ -1071,16 +1141,32 @@ const ProfissionalPage = () => {
{getReportPatientCpf(laudo) ? `CPF: ${getReportPatientCpf(laudo)}` : ''}
- {getReportExecutor(laudo) || '-'} + { + (() => { + const possibleName = laudo.requested_by_name ?? laudo.requester_name ?? laudo.requestedByName ?? laudo.executante_name ?? laudo.executante ?? laudo.executante_name ?? laudo.executante; + if (possibleName && typeof possibleName === 'string' && possibleName.trim().length) return possibleName; + const possibleId = (laudo.requested_by ?? laudo.created_by ?? laudo.executante ?? laudo.requestedBy ?? laudo.createdBy) || ''; + if (possibleId && user?.id && possibleId === user.id) return (profileData as any)?.nome || user?.name || possibleId; + return possibleName || possibleId || '-'; + })() + } {getReportExam(laudo) || "-"}
); @@ -1231,7 +1365,6 @@ const ProfissionalPage = () => {

Dados do Paciente:

Nome: {getPatientName(laudo?.paciente) || getPatientName(laudo) || '-'}

-

ID: {getPatientId(laudo?.paciente) ?? getPatientId(laudo) ?? '-'}

CPF: {getPatientCpf(laudo?.paciente) ?? laudo?.patient_cpf ?? '-'}

Idade: {getPatientAge(laudo?.paciente) ? `${getPatientAge(laudo?.paciente)} anos` : (getPatientAge(laudo) ? `${getPatientAge(laudo)} anos` : '-')}

Sexo: {getPatientSex(laudo?.paciente) ?? getPatientSex(laudo) ?? '-'}

@@ -1296,7 +1429,7 @@ const ProfissionalPage = () => { return ( <>

{signatureName}

-

{profileData.crm || 'CRM não informado'} - {laudo.especialidade}

+

{profileData.crm ? `CRM: ${String(profileData.crm).replace(/^(?:CRM\s*)+/i, '').trim()}` : 'CRM não informado'}{laudo.especialidade ? ` - ${laudo.especialidade}` : ''}

Data: {formatReportDate(getReportDate(laudo))}

); @@ -1307,10 +1440,7 @@ const ProfissionalPage = () => { {/* Footer */}
-
-
- Status: {laudo.status} | Executante: {laudo.executante} -
+
@@ -2499,7 +2629,7 @@ const ProfissionalPage = () => {

Conta do profissional

{profileData.nome}

-

{(profileData.crm ? profileData.crm : '') + (profileData.especialidade ? ` • ${profileData.especialidade}` : '')}

+

{(profileData.crm ? `CRM: ${profileData.crm}` : '') + (profileData.especialidade ? ` • ${profileData.especialidade}` : '')}

{user?.email && (

Logado como: {user.email}

)} diff --git a/susconecta/hooks/useReports.ts b/susconecta/hooks/useReports.ts index 01c0b4e..e2185bb 100644 --- a/susconecta/hooks/useReports.ts +++ b/susconecta/hooks/useReports.ts @@ -26,7 +26,7 @@ interface UseReportsReturn { // Ações loadReports: () => Promise; - loadReportById: (id: string) => Promise; + loadReportById: (id: string) => Promise; createNewReport: (data: CreateReportData) => Promise; updateExistingReport: (id: string, data: UpdateReportData) => Promise; deleteExistingReport: (id: string) => Promise; @@ -205,15 +205,17 @@ export function useReports(): UseReportsReturn { }, [handleError]); // Carregar um relatório específico - const loadReportById = useCallback(async (id: string) => { + const loadReportById = useCallback(async (id: string): Promise => { setLoading(true); setError(null); try { const report = await buscarRelatorioPorId(id); setSelectedReport(report); + return report; } catch (err) { handleError(err); + throw err; } finally { setLoading(false); }