Merge pull request 'fix-reponse' (#71) from backup/reports into develop
Reviewed-on: #71
This commit is contained in:
commit
82c5f61f2a
@ -351,22 +351,22 @@ export default function LaudoPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main Content Area */}
|
{/* Main Content Area */}
|
||||||
<div className="flex justify-center py-12 px-4 print:py-0 print:px-0 min-h-[calc(100vh-80px)] print:min-h-screen">
|
<div className="flex justify-center py-6 sm:py-8 md:py-12 px-2 sm:px-4 print:py-0 print:px-0 min-h-[calc(100vh-80px)] print:min-h-screen">
|
||||||
{/* Document Container */}
|
{/* Document Container */}
|
||||||
<div className={`w-full max-w-4xl transition-colors duration-300 shadow-2xl rounded-xl overflow-hidden print:shadow-none print:rounded-none print:max-w-full ${
|
<div className={`w-full max-w-2xl sm:max-w-3xl md:max-w-4xl transition-colors duration-300 shadow-lg sm:shadow-xl rounded-lg sm:rounded-xl overflow-hidden print:shadow-none print:rounded-none print:max-w-full ${
|
||||||
isDark ? 'bg-slate-800' : 'bg-white'
|
isDark ? 'bg-slate-800' : 'bg-white'
|
||||||
}`}>
|
}`}>
|
||||||
{/* Document Content */}
|
{/* Document Content */}
|
||||||
<div className="p-16 space-y-8 print:p-12 print:space-y-6">
|
<div className="p-4 sm:p-8 md:p-12 lg:p-16 space-y-4 sm:space-y-6 md:space-y-8 print:p-12 print:space-y-6">
|
||||||
|
|
||||||
{/* Title */}
|
{/* Title */}
|
||||||
<div className={`text-center mb-12 pb-8 border-b-2 ${
|
<div className={`text-center mb-6 sm:mb-8 md:mb-12 pb-4 sm:pb-6 md:pb-8 border-b-2 ${
|
||||||
isDark ? 'border-blue-900' : 'border-blue-200'
|
isDark ? 'border-blue-900' : 'border-blue-200'
|
||||||
}`}>
|
}`}>
|
||||||
<h1 className={`text-4xl font-bold mb-4 ${isDark ? 'text-white' : 'text-slate-900'}`}>
|
<h1 className={`text-2xl sm:text-3xl md:text-4xl font-bold mb-2 sm:mb-4 ${isDark ? 'text-white' : 'text-slate-900'}`}>
|
||||||
RELATÓRIO MÉDICO
|
RELATÓRIO MÉDICO
|
||||||
</h1>
|
</h1>
|
||||||
<div className={`text-sm space-y-1 ${isDark ? 'text-slate-300' : 'text-slate-700'}`}>
|
<div className={`text-xs sm:text-sm space-y-0.5 sm:space-y-1 ${isDark ? 'text-slate-300' : 'text-slate-700'}`}>
|
||||||
<p className="font-medium">
|
<p className="font-medium">
|
||||||
<span className={isDark ? 'text-slate-400' : 'text-slate-500'}>Data:</span> {reportDate}
|
<span className={isDark ? 'text-slate-400' : 'text-slate-500'}>Data:</span> {reportDate}
|
||||||
</p>
|
</p>
|
||||||
@ -380,28 +380,28 @@ export default function LaudoPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Patient/Header Info */}
|
{/* Patient/Header Info */}
|
||||||
<div className={`rounded-lg p-6 border transition-colors duration-300 ${
|
<div className={`rounded-lg p-3 sm:p-4 md:p-6 border transition-colors duration-300 ${
|
||||||
isDark
|
isDark
|
||||||
? 'bg-slate-900 border-slate-700'
|
? 'bg-slate-900 border-slate-700'
|
||||||
: 'bg-slate-50 border-slate-200'
|
: 'bg-slate-50 border-slate-200'
|
||||||
}`}>
|
}`}>
|
||||||
<div className="grid grid-cols-2 gap-6 text-sm">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4 md:gap-6 text-xs sm:text-sm">
|
||||||
{cid && (
|
{cid && (
|
||||||
<div>
|
<div>
|
||||||
<label className={`text-xs uppercase font-semibold tracking-wide block mb-2 ${
|
<label className={`text-xs uppercase font-semibold tracking-wide block mb-1.5 sm:mb-2 ${
|
||||||
isDark ? 'text-slate-400' : 'text-slate-600'
|
isDark ? 'text-slate-400' : 'text-slate-600'
|
||||||
}`}>CID</label>
|
}`}>CID</label>
|
||||||
<p className={`text-lg font-semibold ${isDark ? 'text-white' : 'text-slate-900'}`}>
|
<p className={`text-base sm:text-lg font-semibold ${isDark ? 'text-white' : 'text-slate-900'}`}>
|
||||||
{cid}
|
{cid}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{exam && (
|
{exam && (
|
||||||
<div>
|
<div>
|
||||||
<label className={`text-xs uppercase font-semibold tracking-wide block mb-2 ${
|
<label className={`text-xs uppercase font-semibold tracking-wide block mb-1.5 sm:mb-2 ${
|
||||||
isDark ? 'text-slate-400' : 'text-slate-600'
|
isDark ? 'text-slate-400' : 'text-slate-600'
|
||||||
}`}>Exame / Tipo</label>
|
}`}>Exame / Tipo</label>
|
||||||
<p className={`text-lg font-semibold ${isDark ? 'text-white' : 'text-slate-900'}`}>
|
<p className={`text-base sm:text-lg font-semibold ${isDark ? 'text-white' : 'text-slate-900'}`}>
|
||||||
{exam}
|
{exam}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -411,11 +411,11 @@ export default function LaudoPage() {
|
|||||||
|
|
||||||
{/* Diagnosis Section */}
|
{/* Diagnosis Section */}
|
||||||
{diagnosis && (
|
{diagnosis && (
|
||||||
<div className="space-y-3">
|
<div className="space-y-2 sm:space-y-3">
|
||||||
<h2 className={`text-xl font-bold uppercase tracking-wide ${
|
<h2 className={`text-lg sm:text-xl font-bold uppercase tracking-wide ${
|
||||||
isDark ? 'text-blue-400' : 'text-blue-700'
|
isDark ? 'text-blue-400' : 'text-blue-700'
|
||||||
}`}>Diagnóstico</h2>
|
}`}>Diagnóstico</h2>
|
||||||
<div className={`whitespace-pre-wrap text-base leading-relaxed rounded-lg p-4 border-l-4 border-blue-500 transition-colors duration-300 ${
|
<div className={`whitespace-pre-wrap text-sm sm:text-base leading-relaxed rounded-lg p-3 sm:p-4 border-l-4 border-blue-500 transition-colors duration-300 ${
|
||||||
isDark
|
isDark
|
||||||
? 'bg-slate-900 text-slate-200'
|
? 'bg-slate-900 text-slate-200'
|
||||||
: 'bg-blue-50 text-slate-800'
|
: 'bg-blue-50 text-slate-800'
|
||||||
@ -427,11 +427,11 @@ export default function LaudoPage() {
|
|||||||
|
|
||||||
{/* Conclusion Section */}
|
{/* Conclusion Section */}
|
||||||
{conclusion && (
|
{conclusion && (
|
||||||
<div className="space-y-3">
|
<div className="space-y-2 sm:space-y-3">
|
||||||
<h2 className={`text-xl font-bold uppercase tracking-wide ${
|
<h2 className={`text-lg sm:text-xl font-bold uppercase tracking-wide ${
|
||||||
isDark ? 'text-blue-400' : 'text-blue-700'
|
isDark ? 'text-blue-400' : 'text-blue-700'
|
||||||
}`}>Conclusão</h2>
|
}`}>Conclusão</h2>
|
||||||
<div className={`whitespace-pre-wrap text-base leading-relaxed rounded-lg p-4 border-l-4 border-blue-500 transition-colors duration-300 ${
|
<div className={`whitespace-pre-wrap text-sm sm:text-base leading-relaxed rounded-lg p-3 sm:p-4 border-l-4 border-blue-500 transition-colors duration-300 ${
|
||||||
isDark
|
isDark
|
||||||
? 'bg-slate-900 text-slate-200'
|
? 'bg-slate-900 text-slate-200'
|
||||||
: 'bg-blue-50 text-slate-800'
|
: 'bg-blue-50 text-slate-800'
|
||||||
@ -443,13 +443,13 @@ export default function LaudoPage() {
|
|||||||
|
|
||||||
{/* Notes/Content Section */}
|
{/* Notes/Content Section */}
|
||||||
{(notesHtml || notesText) && (
|
{(notesHtml || notesText) && (
|
||||||
<div className="space-y-3">
|
<div className="space-y-2 sm:space-y-3">
|
||||||
<h2 className={`text-xl font-bold uppercase tracking-wide ${
|
<h2 className={`text-lg sm:text-xl font-bold uppercase tracking-wide ${
|
||||||
isDark ? 'text-blue-400' : 'text-blue-700'
|
isDark ? 'text-blue-400' : 'text-blue-700'
|
||||||
}`}>Notas do Profissional</h2>
|
}`}>Notas do Profissional</h2>
|
||||||
{notesHtml ? (
|
{notesHtml ? (
|
||||||
<div
|
<div
|
||||||
className={`prose prose-sm max-w-none rounded-lg p-4 border-l-4 border-blue-500 transition-colors duration-300 ${
|
className={`prose prose-sm max-w-none rounded-lg p-3 sm:p-4 border-l-4 border-blue-500 transition-colors duration-300 text-xs sm:text-sm ${
|
||||||
isDark
|
isDark
|
||||||
? 'prose-invert bg-slate-900 text-slate-200'
|
? 'prose-invert bg-slate-900 text-slate-200'
|
||||||
: 'bg-blue-50 text-slate-800'
|
: 'bg-blue-50 text-slate-800'
|
||||||
@ -457,7 +457,7 @@ export default function LaudoPage() {
|
|||||||
dangerouslySetInnerHTML={{ __html: String(notesHtml) }}
|
dangerouslySetInnerHTML={{ __html: String(notesHtml) }}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div className={`whitespace-pre-wrap text-base leading-relaxed rounded-lg p-4 border-l-4 border-blue-500 transition-colors duration-300 ${
|
<div className={`whitespace-pre-wrap text-sm sm:text-base leading-relaxed rounded-lg p-3 sm:p-4 border-l-4 border-blue-500 transition-colors duration-300 ${
|
||||||
isDark
|
isDark
|
||||||
? 'bg-slate-900 text-slate-200'
|
? 'bg-slate-900 text-slate-200'
|
||||||
: 'bg-blue-50 text-slate-800'
|
: 'bg-blue-50 text-slate-800'
|
||||||
@ -470,9 +470,9 @@ export default function LaudoPage() {
|
|||||||
|
|
||||||
{/* Signature Section */}
|
{/* Signature Section */}
|
||||||
{report.doctor_signature && (
|
{report.doctor_signature && (
|
||||||
<div className={`pt-8 border-t-2 ${isDark ? 'border-slate-600' : 'border-slate-300'}`}>
|
<div className={`pt-6 sm:pt-8 border-t-2 ${isDark ? 'border-slate-600' : 'border-slate-300'}`}>
|
||||||
<div className="flex flex-col items-center gap-4">
|
<div className="flex flex-col items-center gap-3 sm:gap-4">
|
||||||
<div className={`rounded-lg p-4 border transition-colors duration-300 ${
|
<div className={`rounded-lg p-2 sm:p-4 border transition-colors duration-300 ${
|
||||||
isDark
|
isDark
|
||||||
? 'bg-slate-900 border-slate-600'
|
? 'bg-slate-900 border-slate-600'
|
||||||
: 'bg-slate-100 border-slate-300'
|
: 'bg-slate-100 border-slate-300'
|
||||||
@ -482,16 +482,16 @@ export default function LaudoPage() {
|
|||||||
alt="Assinatura do profissional"
|
alt="Assinatura do profissional"
|
||||||
width={150}
|
width={150}
|
||||||
height={100}
|
height={100}
|
||||||
className="h-20 w-auto"
|
className="h-16 sm:h-20 w-auto"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{doctorName && (
|
{doctorName && (
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<p className={`text-sm font-bold ${isDark ? 'text-white' : 'text-slate-900'}`}>
|
<p className={`text-xs sm:text-sm font-bold ${isDark ? 'text-white' : 'text-slate-900'}`}>
|
||||||
{doctorName}
|
{doctorName}
|
||||||
</p>
|
</p>
|
||||||
{doctor?.crm && (
|
{doctor?.crm && (
|
||||||
<p className={`text-xs mt-1 ${isDark ? 'text-slate-400' : 'text-slate-600'}`}>
|
<p className={`text-xs mt-0.5 sm:mt-1 ${isDark ? 'text-slate-400' : 'text-slate-600'}`}>
|
||||||
CRM: {doctor.crm}
|
CRM: {doctor.crm}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -741,28 +741,28 @@ export default function PacientePage() {
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
{/* Date Navigation */}
|
{/* Date Navigation */}
|
||||||
<div className="flex flex-col gap-3 sm:gap-4 rounded-2xl border border-primary/20 bg-linear-to-r from-primary/5 to-primary/10 p-3 sm:p-4 md:p-6 sm:flex-row sm:items-center sm:justify-between shadow-sm">
|
<div className="flex flex-col gap-2 sm:gap-3 rounded-2xl border border-primary/20 bg-linear-to-r from-primary/5 to-primary/10 p-3 sm:p-4 md:p-6 shadow-sm">
|
||||||
<div className="flex items-center gap-2 sm:gap-3">
|
<div className="flex items-center gap-1.5 sm:gap-2 flex-wrap">
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="icon"
|
size="icon"
|
||||||
onClick={(e: any) => { e.stopPropagation(); e.preventDefault(); navigateDate('prev') }}
|
onClick={(e: any) => { e.stopPropagation(); e.preventDefault(); navigateDate('prev') }}
|
||||||
aria-label="Dia anterior"
|
aria-label="Dia anterior"
|
||||||
className={`group shadow-sm hover:bg-primary! hover:text-white! hover:border-primary! transition-all ${hoverPrimaryIconClass}`}
|
className={`shadow-sm hover:bg-primary! hover:text-white! hover:border-primary! transition-all p-1.5 sm:p-2`}
|
||||||
>
|
>
|
||||||
<ChevronLeft className="h-4 w-4 sm:h-5 sm:w-5 transition group-hover:text-white" />
|
<ChevronLeft className="h-4 w-4 sm:h-4 sm:w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<span className="text-sm sm:text-base md:text-lg font-semibold text-foreground min-w-fit">{formatDatePt(currentDate)}</span>
|
<span className="text-xs sm:text-sm md:text-base font-semibold text-foreground flex-1 sm:flex-none line-clamp-1">{formatDatePt(currentDate)}</span>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="icon"
|
size="icon"
|
||||||
onClick={(e: any) => { e.stopPropagation(); e.preventDefault(); navigateDate('next') }}
|
onClick={(e: any) => { e.stopPropagation(); e.preventDefault(); navigateDate('next') }}
|
||||||
aria-label="Próximo dia"
|
aria-label="Próximo dia"
|
||||||
className={`group shadow-sm hover:bg-primary! hover:text-white! hover:border-primary! transition-all ${hoverPrimaryIconClass}`}
|
className={`shadow-sm hover:bg-primary! hover:text-white! hover:border-primary! transition-all p-1.5 sm:p-2`}
|
||||||
>
|
>
|
||||||
<ChevronRight className="h-4 w-4 sm:h-5 sm:w-5 transition group-hover:text-white" />
|
<ChevronRight className="h-4 w-4 sm:h-4 sm:w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
{isSelectedDateToday && (
|
{isSelectedDateToday && (
|
||||||
<Button
|
<Button
|
||||||
@ -771,14 +771,13 @@ export default function PacientePage() {
|
|||||||
size="sm"
|
size="sm"
|
||||||
onClick={goToToday}
|
onClick={goToToday}
|
||||||
disabled
|
disabled
|
||||||
className="border border-border/50 text-foreground focus-visible:ring-2 focus-visible:ring-primary/40 active:scale-[0.97] hover:bg-primary/5 hover:text-foreground transition-colors disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-foreground text-xs sm:text-sm"
|
className="border border-border/50 text-foreground focus-visible:ring-2 focus-visible:ring-primary/40 active:scale-[0.97] hover:bg-primary/5 hover:text-foreground transition-colors disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-foreground text-xs px-2 py-1 h-auto"
|
||||||
>
|
>
|
||||||
Hoje
|
Hoje
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs sm:text-sm font-medium text-muted-foreground bg-background/50 px-3 sm:px-4 py-1.5 sm:py-2 rounded-lg">
|
<div className="text-xs sm:text-sm font-medium text-muted-foreground bg-background/50 px-3 py-1.5 rounded-lg w-fit">
|
||||||
|
|
||||||
<span className="text-primary font-semibold">{_todaysAppointments.length}</span> consulta{_todaysAppointments.length !== 1 ? 's' : ''} agendada{_todaysAppointments.length !== 1 ? 's' : ''}
|
<span className="text-primary font-semibold">{_todaysAppointments.length}</span> consulta{_todaysAppointments.length !== 1 ? 's' : ''} agendada{_todaysAppointments.length !== 1 ? 's' : ''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1781,40 +1780,45 @@ export default function PacientePage() {
|
|||||||
<div className="grid grid-cols-1 md:grid-cols-[200px_1fr] lg:grid-cols-[220px_1fr] gap-4 sm:gap-5 md:gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-[200px_1fr] lg:grid-cols-[220px_1fr] gap-4 sm:gap-5 md:gap-6">
|
||||||
{/* Sidebar vertical - sticky */}
|
{/* Sidebar vertical - sticky */}
|
||||||
<aside className="sticky top-24 h-fit md:top-24">
|
<aside className="sticky top-24 h-fit md:top-24">
|
||||||
<nav aria-label="Navegação do dashboard" className="bg-card shadow-md rounded-lg border border-border p-2 sm:p-3 md:p-3 space-y-1 z-30 flex md:flex-col flex-row md:overflow-auto overflow-x-auto">
|
<nav aria-label="Navegação do dashboard" className="bg-card shadow-md rounded-lg border border-border p-1.5 sm:p-2 md:p-3 z-30">
|
||||||
<Button
|
<div className="grid grid-cols-2 md:grid-cols-1 gap-1 sm:gap-1.5">
|
||||||
variant={tab==='dashboard'?'default':'ghost'}
|
<Button
|
||||||
aria-current={tab==='dashboard'}
|
variant={tab==='dashboard'?'default':'ghost'}
|
||||||
onClick={()=>setTab('dashboard')}
|
aria-current={tab==='dashboard'}
|
||||||
className={`flex-1 md:flex-none md:w-full flex items-center justify-center md:justify-start gap-1 md:gap-2 transition-colors hover:bg-primary! hover:text-white! cursor-pointer text-xs sm:text-sm`}
|
onClick={()=>setTab('dashboard')}
|
||||||
>
|
className={`flex flex-col md:flex-row items-center justify-center md:justify-start gap-0.5 md:gap-2 transition-colors hover:bg-primary! hover:text-white! cursor-pointer text-xs px-1.5 sm:px-3 py-1.5 sm:py-2 h-auto`}
|
||||||
<Calendar className="h-3 w-3 sm:h-4 sm:w-4 md:h-4 md:w-4 flex-shrink-0" /><span>{strings.dashboard}</span>
|
title="Dashboard"
|
||||||
</Button>
|
>
|
||||||
<Button
|
<Calendar className="h-4 w-4 sm:h-4 sm:w-4 md:h-4 md:w-4 flex-shrink-0" /><span className="text-xs sm:text-sm">{strings.dashboard}</span>
|
||||||
variant={tab==='consultas'?'default':'ghost'}
|
</Button>
|
||||||
aria-current={tab==='consultas'}
|
<Button
|
||||||
onClick={()=>setTab('consultas')}
|
variant={tab==='consultas'?'default':'ghost'}
|
||||||
className={`flex-1 md:flex-none md:w-full flex items-center justify-center md:justify-start gap-1 md:gap-2 transition-colors hover:bg-primary! hover:text-white! cursor-pointer text-xs sm:text-sm`}
|
aria-current={tab==='consultas'}
|
||||||
>
|
onClick={()=>setTab('consultas')}
|
||||||
<Calendar className="h-3 w-3 sm:h-4 sm:w-4 md:h-4 md:w-4 flex-shrink-0" /><span>{strings.consultas}</span>
|
className={`flex flex-col md:flex-row items-center justify-center md:justify-start gap-0.5 md:gap-2 transition-colors hover:bg-primary! hover:text-white! cursor-pointer text-xs px-1.5 sm:px-3 py-1.5 sm:py-2 h-auto`}
|
||||||
</Button>
|
title="Consultas"
|
||||||
<Button
|
>
|
||||||
variant={tab==='exames'?'default':'ghost'}
|
<Calendar className="h-4 w-4 sm:h-4 sm:w-4 md:h-4 md:w-4 flex-shrink-0" /><span className="text-xs sm:text-sm">{strings.consultas}</span>
|
||||||
aria-current={tab==='exames'}
|
</Button>
|
||||||
onClick={()=>setTab('exames')}
|
<Button
|
||||||
className={`flex-1 md:flex-none md:w-full flex items-center justify-center md:justify-start gap-1 md:gap-2 transition-colors hover:bg-primary! hover:text-white! cursor-pointer text-xs sm:text-sm`}
|
variant={tab==='exames'?'default':'ghost'}
|
||||||
>
|
aria-current={tab==='exames'}
|
||||||
<FileText className="h-3 w-3 sm:h-4 sm:w-4 md:h-4 md:w-4 flex-shrink-0" /><span>{strings.exames}</span>
|
onClick={()=>setTab('exames')}
|
||||||
</Button>
|
className={`flex flex-col md:flex-row items-center justify-center md:justify-start gap-0.5 md:gap-2 transition-colors hover:bg-primary! hover:text-white! cursor-pointer text-xs px-1.5 sm:px-3 py-1.5 sm:py-2 h-auto`}
|
||||||
|
title="Exames"
|
||||||
<Button
|
>
|
||||||
variant={tab==='perfil'?'default':'ghost'}
|
<FileText className="h-4 w-4 sm:h-4 sm:w-4 md:h-4 md:w-4 flex-shrink-0" /><span className="text-xs sm:text-sm">{strings.exames}</span>
|
||||||
aria-current={tab==='perfil'}
|
</Button>
|
||||||
onClick={()=>setTab('perfil')}
|
<Button
|
||||||
className={`flex-1 md:flex-none md:w-full flex items-center justify-center md:justify-start gap-1 md:gap-2 transition-colors hover:bg-primary! hover:text-white! cursor-pointer text-xs sm:text-sm`}
|
variant={tab==='perfil'?'default':'ghost'}
|
||||||
>
|
aria-current={tab==='perfil'}
|
||||||
<UserCog className="h-3 w-3 sm:h-4 sm:w-4 md:h-4 md:w-4 flex-shrink-0" /><span>{strings.perfil}</span>
|
onClick={()=>setTab('perfil')}
|
||||||
</Button>
|
className={`flex flex-col md:flex-row items-center justify-center md:justify-start gap-0.5 md:gap-2 transition-colors hover:bg-primary! hover:text-white! cursor-pointer text-xs px-1.5 sm:px-3 py-1.5 sm:py-2 h-auto`}
|
||||||
|
title="Perfil"
|
||||||
|
>
|
||||||
|
<UserCog className="h-4 w-4 sm:h-4 sm:w-4 md:h-4 md:w-4 flex-shrink-0" /><span className="text-xs sm:text-sm">{strings.perfil}</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
|
|||||||
@ -786,45 +786,45 @@ const ProfissionalPage = () => {
|
|||||||
const todayEvents = getTodayEvents();
|
const todayEvents = getTodayEvents();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="bg-card shadow-md rounded-lg border border-border p-6 overflow-x-hidden">{/* adicionada overflow-x-hidden */}
|
<section className="bg-card shadow-md rounded-lg border border-border p-3 sm:p-4 md:p-6 overflow-x-hidden">
|
||||||
<div className="flex justify-between items-center mb-4">
|
<div className="flex justify-between items-center mb-3 sm:mb-4">
|
||||||
<h2 className="text-xl sm:text-2xl font-bold">Agenda do Dia</h2>
|
<h2 className="text-lg sm:text-xl md:text-2xl font-bold">Agenda do Dia</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Navegação de Data - Responsiva */}
|
{/* Navegação de Data - Responsiva */}
|
||||||
<div className="flex items-center justify-between mb-6 p-3 sm:p-4 bg-blue-50 rounded-lg dark:bg-muted flex-wrap gap-2 sm:gap-4">
|
<div className="flex flex-col gap-2 sm:gap-3 mb-4 sm:mb-6 p-2 sm:p-3 md:p-4 bg-blue-50 rounded-lg dark:bg-muted">
|
||||||
<div className="flex items-center gap-2 sm:gap-4">
|
<div className="flex items-center gap-1.5 sm:gap-2 md:gap-4 flex-wrap">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => navigateDate('prev')}
|
onClick={() => navigateDate('prev')}
|
||||||
className="p-2 hover:bg-primary! hover:text-white! cursor-pointer transition-colors"
|
className="p-1.5 sm:p-2 hover:bg-primary! hover:text-white! cursor-pointer transition-colors h-auto"
|
||||||
>
|
>
|
||||||
<ChevronLeft className="h-4 w-4" />
|
<ChevronLeft className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<h3 className="text-base sm:text-lg font-medium text-foreground whitespace-nowrap line-clamp-2">
|
<h3 className="text-sm sm:text-base md:text-lg font-medium text-foreground flex-1 line-clamp-1">
|
||||||
{formatDate(currentCalendarDate)}
|
{formatDate(currentCalendarDate)}
|
||||||
</h3>
|
</h3>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => navigateDate('next')}
|
onClick={() => navigateDate('next')}
|
||||||
className="p-2 hover:bg-primary! hover:text-white! cursor-pointer transition-colors"
|
className="p-1.5 sm:p-2 hover:bg-primary! hover:text-white! cursor-pointer transition-colors h-auto"
|
||||||
>
|
>
|
||||||
<ChevronRight className="h-4 w-4" />
|
<ChevronRight className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs sm:text-sm text-gray-600 dark:text-muted-foreground whitespace-nowrap">
|
<div className="text-xs sm:text-sm text-gray-600 dark:text-muted-foreground">
|
||||||
{todayEvents.length} consulta{todayEvents.length !== 1 ? 's' : ''}
|
<span className="font-semibold">{todayEvents.length}</span> consulta{todayEvents.length !== 1 ? 's' : ''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Lista de Pacientes do Dia */}
|
{/* Lista de Pacientes do Dia */}
|
||||||
<div className="space-y-4 max-h-[calc(100vh-450px)] overflow-y-auto overflow-x-hidden pr-2">{/* adicionada overflow-x-hidden */}
|
<div className="space-y-2 sm:space-y-3 max-h-[calc(100vh-450px)] overflow-y-auto overflow-x-hidden pr-2">
|
||||||
{todayEvents.length === 0 ? (
|
{todayEvents.length === 0 ? (
|
||||||
<div className="text-center py-6 sm:py-8 text-gray-600 dark:text-muted-foreground">
|
<div className="text-center py-6 sm:py-8 text-gray-600 dark:text-muted-foreground">
|
||||||
<CalendarIcon className="h-10 sm:h-12 w-10 sm:w-12 mx-auto mb-3 sm:mb-4 text-gray-400 dark:text-muted-foreground/50" />
|
<CalendarIcon className="h-8 sm:h-10 md:h-12 w-8 sm:w-10 md:w-12 mx-auto mb-2 sm:mb-3 text-gray-400 dark:text-muted-foreground/50" />
|
||||||
<p className="text-base sm:text-lg mb-2">Nenhuma consulta agendada para este dia</p>
|
<p className="text-sm sm:text-base font-medium mb-1">Nenhuma consulta agendada para este dia</p>
|
||||||
<p className="text-xs sm:text-sm">Agenda livre para este dia</p>
|
<p className="text-xs sm:text-sm">Agenda livre para este dia</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@ -833,42 +833,42 @@ const ProfissionalPage = () => {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={appointment.id}
|
key={appointment.id}
|
||||||
className="border-l-4 border-t border-r border-b p-3 sm:p-4 rounded-lg shadow-sm bg-card border-border"
|
className="border-l-4 border-t border-r border-b p-2.5 sm:p-3 md:p-4 rounded-lg shadow-sm bg-card border-border hover:shadow-md transition-shadow"
|
||||||
style={{ borderLeftColor: getStatusColor(appointment.type) }}
|
style={{ borderLeftColor: getStatusColor(appointment.type) }}
|
||||||
>
|
>
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-2 sm:gap-4 items-center">
|
<div className="flex flex-col sm:grid sm:grid-cols-2 md:grid-cols-4 gap-2 sm:gap-3 md:gap-4 items-start sm:items-center">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-start sm:items-center gap-2 min-w-0">
|
||||||
<div
|
<div
|
||||||
className="w-3 h-3 rounded-full flex-shrink-0"
|
className="w-2.5 h-2.5 rounded-full flex-shrink-0 mt-1 sm:mt-0"
|
||||||
style={{ backgroundColor: getStatusColor(appointment.type) }}
|
style={{ backgroundColor: getStatusColor(appointment.type) }}
|
||||||
></div>
|
></div>
|
||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
<div className="font-medium text-sm sm:text-base flex items-center gap-2">
|
<div className="font-medium text-xs sm:text-sm md:text-base flex items-center gap-1.5 flex-wrap">
|
||||||
<User className="h-3 w-3 sm:h-4 sm:w-4 text-gray-500 dark:text-muted-foreground flex-shrink-0" />
|
<User className="h-3 w-3 sm:h-3.5 sm:w-3.5 text-gray-500 dark:text-muted-foreground flex-shrink-0" />
|
||||||
<span className="truncate">{appointment.title}</span>
|
<span className="truncate">{appointment.title}</span>
|
||||||
</div>
|
</div>
|
||||||
{paciente && (
|
{paciente && (
|
||||||
<div className="text-xs text-gray-600 dark:text-muted-foreground truncate">
|
<div className="text-xs text-gray-600 dark:text-muted-foreground truncate mt-0.5">
|
||||||
CPF: {getPatientCpf(paciente)} • {getPatientAge(paciente)} anos
|
CPF: {getPatientCpf(paciente)} • {getPatientAge(paciente)} anos
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-1.5 sm:gap-2 text-xs sm:text-sm md:text-base">
|
||||||
<Clock className="h-3 w-3 sm:h-4 sm:w-4 text-gray-500 dark:text-muted-foreground flex-shrink-0" />
|
<Clock className="h-3 w-3 sm:h-3.5 sm:w-3.5 text-gray-500 dark:text-muted-foreground flex-shrink-0" />
|
||||||
<span className="font-medium text-sm sm:text-base">{appointment.time}</span>
|
<span className="font-medium">{appointment.time}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<div
|
<div
|
||||||
className="px-2 sm:px-3 py-1 rounded-full text-xs sm:text-sm font-medium text-white whitespace-nowrap"
|
className="px-2 sm:px-2.5 md:px-3 py-1 rounded-full text-xs font-medium text-white whitespace-nowrap"
|
||||||
style={{ backgroundColor: getStatusColor(appointment.type) }}
|
style={{ backgroundColor: getStatusColor(appointment.type) }}
|
||||||
>
|
>
|
||||||
{appointment.type}
|
{appointment.type}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-end">
|
<div className="hidden md:flex items-center justify-end">
|
||||||
<div className="relative group">
|
<div className="relative group">
|
||||||
<div className="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-3 py-1 bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 text-xs rounded-md opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none whitespace-nowrap z-50">
|
<div className="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-2 py-1 bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 text-xs rounded-md opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none whitespace-nowrap z-50">
|
||||||
Ver informações do paciente
|
Ver informações do paciente
|
||||||
<div className="absolute top-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-gray-900 dark:border-t-gray-100"></div>
|
<div className="absolute top-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-gray-900 dark:border-t-gray-100"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -2051,43 +2051,43 @@ const ProfissionalPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 z-50 bg-black/50 flex items-center justify-center p-4">
|
<div className="fixed inset-0 z-50 bg-black/50 flex items-center justify-center p-2 sm:p-4">
|
||||||
<div className="bg-background rounded-none md:rounded-lg shadow-xl w-full h-full md:h-auto md:max-w-6xl max-h-[90vh] overflow-hidden flex flex-col">
|
<div className="bg-background rounded-none md:rounded-lg shadow-xl w-full h-full md:h-auto md:max-w-6xl max-h-[95vh] overflow-hidden flex flex-col">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="border-b border-border">
|
<div className="border-b border-border">
|
||||||
<div className="flex items-center justify-between p-4">
|
<div className="flex items-center justify-between p-2 sm:p-4">
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-xl font-bold text-foreground">
|
<h2 className="text-base sm:text-xl font-bold text-foreground">
|
||||||
{isNewLaudo ? "Novo Laudo Médico" : "Editar Laudo Existente"}
|
{isNewLaudo ? "Novo Laudo Médico" : "Editar Laudo Existente"}
|
||||||
</h2>
|
</h2>
|
||||||
{isNewLaudo ? (
|
{isNewLaudo ? (
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-xs sm:text-sm text-muted-foreground">
|
||||||
Crie um novo laudo selecionando um paciente
|
Crie um novo laudo selecionando um paciente
|
||||||
</p>
|
</p>
|
||||||
) : (
|
) : (
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-xs sm:text-sm text-muted-foreground">
|
||||||
Paciente: {getPatientName(pacienteSelecionado) || getPatientName(laudo?.paciente) || getPatientName(laudo) || '-'} | CPF: {getReportPatientCpf(laudo) ?? laudo?.patient_cpf ?? '-'} | {laudo?.especialidade}
|
Paciente: {getPatientName(pacienteSelecionado) || getPatientName(laudo?.paciente) || getPatientName(laudo) || '-'} | CPF: {getReportPatientCpf(laudo) ?? laudo?.patient_cpf ?? '-'} | {laudo?.especialidade}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Button variant="ghost" size="sm" onClick={onClose}>
|
<Button variant="ghost" size="sm" onClick={onClose} className="h-8 w-8 p-0 flex-shrink-0">
|
||||||
<X className="w-4 h-4" />
|
<X className="w-4 h-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Seleção de Paciente (apenas para novos laudos) */}
|
{/* Seleção de Paciente (apenas para novos laudos) */}
|
||||||
{isNewLaudo && (
|
{isNewLaudo && (
|
||||||
<div className="px-4 pb-4">
|
<div className="px-2 sm:px-4 pb-2 sm:pb-4">
|
||||||
{!pacienteSelecionado ? (
|
{!pacienteSelecionado ? (
|
||||||
<div className="bg-muted border border-border rounded-lg p-4">
|
<div className="bg-muted border border-border rounded-lg p-2 sm:p-4">
|
||||||
<Label htmlFor="select-paciente" className="text-sm font-medium mb-2 block">
|
<Label htmlFor="select-paciente" className="text-xs sm:text-sm font-medium mb-2 block">
|
||||||
Selecionar Paciente *
|
Selecionar Paciente *
|
||||||
</Label>
|
</Label>
|
||||||
<Select onValueChange={(value) => {
|
<Select onValueChange={(value) => {
|
||||||
const paciente = listaPacientes.find(p => p.id === value);
|
const paciente = listaPacientes.find(p => p.id === value);
|
||||||
if (paciente) setPacienteSelecionado(paciente);
|
if (paciente) setPacienteSelecionado(paciente);
|
||||||
}}>
|
}}>
|
||||||
<SelectTrigger className="w-full">
|
<SelectTrigger className="w-full text-xs sm:text-sm">
|
||||||
<SelectValue placeholder="Escolha um paciente para criar o laudo" />
|
<SelectValue placeholder="Escolha um paciente para criar o laudo" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
@ -2100,9 +2100,9 @@ const ProfissionalPage = () => {
|
|||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="bg-primary/10 border border-primary/20 rounded-lg p-3 flex items-center justify-between">
|
<div className="bg-primary/10 border border-primary/20 rounded-lg p-2 sm:p-3 flex items-center justify-between gap-2">
|
||||||
<div>
|
<div>
|
||||||
<div className="font-semibold text-primary">{getPatientName(pacienteSelecionado)}</div>
|
<div className="font-semibold text-primary text-sm sm:text-base">{getPatientName(pacienteSelecionado)}</div>
|
||||||
<div className="text-xs text-muted-foreground">
|
<div className="text-xs text-muted-foreground">
|
||||||
{getPatientCpf(pacienteSelecionado) ? `CPF: ${getPatientCpf(pacienteSelecionado)} | ` : ''}
|
{getPatientCpf(pacienteSelecionado) ? `CPF: ${getPatientCpf(pacienteSelecionado)} | ` : ''}
|
||||||
{pacienteSelecionado?.birth_date ? `Nascimento: ${pacienteSelecionado.birth_date}` : (getPatientAge(pacienteSelecionado) ? `Idade: ${getPatientAge(pacienteSelecionado)} anos` : '')}
|
{pacienteSelecionado?.birth_date ? `Nascimento: ${pacienteSelecionado.birth_date}` : (getPatientAge(pacienteSelecionado) ? `Idade: ${getPatientAge(pacienteSelecionado)} anos` : '')}
|
||||||
@ -2114,25 +2114,26 @@ const ProfissionalPage = () => {
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => setPacienteSelecionado(null)}
|
onClick={() => setPacienteSelecionado(null)}
|
||||||
|
className="text-xs flex-shrink-0"
|
||||||
>
|
>
|
||||||
Trocar Paciente
|
Trocar
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/* Novos campos: Solicitante e Prazo */}
|
{/* Novos campos: Solicitante e Prazo */}
|
||||||
<div className="mt-3 grid grid-cols-1 md:grid-cols-2 gap-3">
|
<div className="mt-2 sm:mt-3 grid grid-cols-1 md:grid-cols-2 gap-2 sm:gap-3">
|
||||||
<div>
|
<div>
|
||||||
<Label htmlFor="solicitante">Solicitante</Label>
|
<Label htmlFor="solicitante" className="text-xs sm:text-sm">Solicitante</Label>
|
||||||
{/* Mostrar o nome do usuário logado de forma estática (não editável) */}
|
{/* Mostrar o nome do usuário logado de forma estática (não editável) */}
|
||||||
<Input id="solicitante" value={displaySolicitante} readOnly disabled />
|
<Input id="solicitante" value={displaySolicitante} readOnly disabled className="text-xs sm:text-sm h-8 sm:h-10" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label htmlFor="prazoDate">Prazo do Laudo</Label>
|
<Label htmlFor="prazoDate" className="text-xs sm:text-sm">Prazo do Laudo</Label>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-1 sm:gap-2">
|
||||||
<Input id="prazoDate" type="date" value={prazoDate} onChange={(e) => setPrazoDate(e.target.value)} />
|
<Input id="prazoDate" type="date" value={prazoDate} onChange={(e) => setPrazoDate(e.target.value)} className="text-xs sm:text-sm h-8 sm:h-10" />
|
||||||
<Input id="prazoTime" type="time" value={prazoTime} onChange={(e) => setPrazoTime(e.target.value)} />
|
<Input id="prazoTime" type="time" value={prazoTime} onChange={(e) => setPrazoTime(e.target.value)} className="text-xs sm:text-sm h-8 sm:h-10" />
|
||||||
</div>
|
</div>
|
||||||
<p className="text-xs text-muted-foreground mt-1">Defina a data e hora do prazo (opcional).</p>
|
<p className="text-xs text-muted-foreground mt-1">Defina a data e hora do prazo (opcional).</p>
|
||||||
</div>
|
</div>
|
||||||
@ -2142,11 +2143,11 @@ const ProfissionalPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Tabs */}
|
{/* Tabs */}
|
||||||
<div className="flex border-b border-border">
|
<div className="flex border-b border-border overflow-x-auto">
|
||||||
{/* Informações tab removed - only Editor/Imagens/Campos/Pré-visualização remain */}
|
{/* Informações tab removed - only Editor/Imagens/Campos/Pré-visualização remain */}
|
||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab("editor")}
|
onClick={() => setActiveTab("editor")}
|
||||||
className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
|
className={`px-2 sm:px-4 py-1.5 sm:py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
||||||
activeTab === "editor"
|
activeTab === "editor"
|
||||||
? "border-blue-500 text-blue-600"
|
? "border-blue-500 text-blue-600"
|
||||||
: "border-transparent text-gray-600 dark:text-muted-foreground dark:hover:text-foreground dark:hover:bg-blue-900"
|
: "border-transparent text-gray-600 dark:text-muted-foreground dark:hover:text-foreground dark:hover:bg-blue-900"
|
||||||
@ -2172,7 +2173,7 @@ const ProfissionalPage = () => {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab("imagens")}
|
onClick={() => setActiveTab("imagens")}
|
||||||
className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
|
className={`px-2 sm:px-4 py-1.5 sm:py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
||||||
activeTab === "imagens"
|
activeTab === "imagens"
|
||||||
? "border-blue-500 text-blue-600"
|
? "border-blue-500 text-blue-600"
|
||||||
: "border-transparent text-gray-600 dark:text-muted-foreground dark:hover:text-foreground dark:hover:bg-blue-900"
|
: "border-transparent text-gray-600 dark:text-muted-foreground dark:hover:text-foreground dark:hover:bg-blue-900"
|
||||||
@ -2198,7 +2199,7 @@ const ProfissionalPage = () => {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab("campos")}
|
onClick={() => setActiveTab("campos")}
|
||||||
className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
|
className={`px-2 sm:px-4 py-1.5 sm:py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
||||||
activeTab === "campos"
|
activeTab === "campos"
|
||||||
? "border-blue-500 text-blue-600"
|
? "border-blue-500 text-blue-600"
|
||||||
: "border-transparent text-gray-600 dark:text-muted-foreground dark:hover:text-foreground dark:hover:bg-blue-900"
|
: "border-transparent text-gray-600 dark:text-muted-foreground dark:hover:text-foreground dark:hover:bg-blue-900"
|
||||||
@ -2224,7 +2225,7 @@ const ProfissionalPage = () => {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => setShowPreview(!showPreview)}
|
onClick={() => setShowPreview(!showPreview)}
|
||||||
className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
|
className={`px-2 sm:px-4 py-1.5 sm:py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
||||||
showPreview
|
showPreview
|
||||||
? "border-green-500 text-green-600"
|
? "border-green-500 text-green-600"
|
||||||
: "border-transparent text-gray-600 dark:text-muted-foreground dark:hover:text-foreground dark:hover:bg-blue-900"
|
: "border-transparent text-gray-600 dark:text-muted-foreground dark:hover:text-foreground dark:hover:bg-blue-900"
|
||||||
@ -2259,26 +2260,26 @@ const ProfissionalPage = () => {
|
|||||||
{activeTab === "editor" && (
|
{activeTab === "editor" && (
|
||||||
<div className="flex-1 flex flex-col">
|
<div className="flex-1 flex flex-col">
|
||||||
{/* Toolbar */}
|
{/* Toolbar */}
|
||||||
<div className="p-3 border-b border-border">
|
<div className="p-1.5 sm:p-3 border-b border-border overflow-x-auto">
|
||||||
<div className="flex flex-wrap gap-2 items-center">
|
<div className="flex flex-wrap gap-1 sm:gap-2 items-center">
|
||||||
{/* Tamanho da fonte */}
|
{/* Tamanho da fonte */}
|
||||||
<label className="text-xs mr-1">Tamanho</label>
|
<label className="text-xs mr-0.5 sm:mr-1 whitespace-nowrap">Tamanho</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
min={8}
|
min={8}
|
||||||
max={32}
|
max={32}
|
||||||
defaultValue={14}
|
defaultValue={14}
|
||||||
onBlur={e => formatText('font-size', e.target.value)}
|
onBlur={e => formatText('font-size', e.target.value)}
|
||||||
className="w-14 border rounded px-1 py-0.5 text-xs mr-2"
|
className="w-12 border rounded px-1 py-0.5 text-xs mr-1 sm:mr-2"
|
||||||
title="Tamanho da fonte"
|
title="Tamanho da fonte"
|
||||||
/>
|
/>
|
||||||
{/* Família da fonte */}
|
{/* Família da fonte */}
|
||||||
<label className="text-xs mr-1">Fonte</label>
|
<label className="text-xs mr-0.5 sm:mr-1 whitespace-nowrap">Fonte</label>
|
||||||
<select
|
<select
|
||||||
defaultValue={'Arial'}
|
defaultValue={'Arial'}
|
||||||
onBlur={e => formatText('font-family', e.target.value)}
|
onBlur={e => formatText('font-family', e.target.value)}
|
||||||
className="border rounded px-1 py-0.5 text-xs mr-2 bg-white text-gray-900 dark:bg-gray-800 dark:text-white"
|
className="border rounded px-1 py-0.5 text-xs mr-1 sm:mr-2 bg-white text-gray-900 dark:bg-gray-800 dark:text-white"
|
||||||
style={{ minWidth: 140, fontWeight: 500 }}
|
style={{ minWidth: 100, fontWeight: 500 }}
|
||||||
title="Família da fonte"
|
title="Família da fonte"
|
||||||
>
|
>
|
||||||
<option value="Arial" style={{ color: '#222', background: '#fff', fontWeight: 600 }}>Arial</option>
|
<option value="Arial" style={{ color: '#222', background: '#fff', fontWeight: 600 }}>Arial</option>
|
||||||
@ -2327,52 +2328,51 @@ const ProfissionalPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Editor */}
|
{/* Editor */}
|
||||||
<div className="flex-1 p-4 overflow-auto max-h-[500px]">
|
<div className="flex-1 p-2 sm:p-4 overflow-y-auto scrollbar-thin scrollbar-thumb-blue-500 scrollbar-track-blue-100 dark:scrollbar-thumb-blue-400 dark:scrollbar-track-blue-950 max-h-[calc(100vh-500px)] sm:max-h-[calc(100vh-400px)]">
|
||||||
<Textarea
|
<Textarea
|
||||||
value={content}
|
value={content}
|
||||||
onChange={(e) => setContent(e.target.value)}
|
onChange={(e) => setContent(e.target.value)}
|
||||||
placeholder="Digite o conteúdo do laudo aqui. Use ** para negrito, * para itálico, <u></u> para sublinhado."
|
placeholder="Digite o conteúdo do laudo aqui. Use ** para negrito, * para itálico, <u></u> para sublinhado."
|
||||||
className="h-full min-h-[400px] resize-none scrollbar-thin scrollbar-thumb-blue-400 scrollbar-track-blue-100"
|
className="w-full min-h-[200px] sm:min-h-[300px] resize-none text-xs sm:text-sm"
|
||||||
style={{ maxHeight: 400, overflow: 'auto' }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === "imagens" && (
|
{activeTab === "imagens" && (
|
||||||
<div className="flex-1 p-4">
|
<div className="flex-1 p-2 sm:p-4 overflow-y-auto">
|
||||||
<div className="mb-4">
|
<div className="mb-3 sm:mb-4">
|
||||||
<Label htmlFor="upload-images">Upload de Imagens</Label>
|
<Label htmlFor="upload-images" className="text-xs sm:text-sm">Upload de Imagens</Label>
|
||||||
<Input
|
<Input
|
||||||
id="upload-images"
|
id="upload-images"
|
||||||
type="file"
|
type="file"
|
||||||
multiple
|
multiple
|
||||||
accept="image/*,.pdf"
|
accept="image/*,.pdf"
|
||||||
onChange={handleImageUpload}
|
onChange={handleImageUpload}
|
||||||
className="mt-1"
|
className="mt-1 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
<div className="grid grid-cols-2 md:grid-cols-3 gap-2 sm:gap-4">
|
||||||
{imagens.map((img) => (
|
{imagens.map((img) => (
|
||||||
<div key={img.id} className="border border-border rounded-lg p-2">
|
<div key={img.id} className="border border-border rounded-lg p-1.5 sm:p-2">
|
||||||
{img.type.startsWith('image/') ? (
|
{img.type.startsWith('image/') ? (
|
||||||
// eslint-disable-next-line @next/next/no-img-element
|
// eslint-disable-next-line @next/next/no-img-element
|
||||||
<img
|
<img
|
||||||
src={img.url}
|
src={img.url}
|
||||||
alt={img.name}
|
alt={img.name}
|
||||||
className="w-full h-32 object-cover rounded"
|
className="w-full h-24 sm:h-32 object-cover rounded"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full h-32 bg-muted rounded flex items-center justify-center">
|
<div className="w-full h-24 sm:h-32 bg-muted rounded flex items-center justify-center">
|
||||||
<FileText className="w-8 h-8 text-muted-foreground" />
|
<FileText className="w-6 sm:w-8 h-6 sm:h-8 text-muted-foreground" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<p className="text-xs text-muted-foreground mt-1 truncate">{img.name}</p>
|
<p className="text-xs text-muted-foreground mt-1 truncate">{img.name}</p>
|
||||||
<Button
|
<Button
|
||||||
variant="destructive"
|
variant="destructive"
|
||||||
size="sm"
|
size="sm"
|
||||||
className="w-full mt-1"
|
className="w-full mt-1 text-xs"
|
||||||
onClick={() => setImagens(prev => prev.filter(i => i.id !== img.id))}
|
onClick={() => setImagens(prev => prev.filter(i => i.id !== img.id))}
|
||||||
>
|
>
|
||||||
Remover
|
Remover
|
||||||
@ -2384,54 +2384,59 @@ const ProfissionalPage = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === "campos" && (
|
{activeTab === "campos" && (
|
||||||
<div className="flex-1 p-4 space-y-4 max-h-[500px] overflow-y-auto">
|
<div className="flex-1 p-2 sm:p-4 space-y-2 sm:space-y-4 overflow-y-auto">
|
||||||
<div>
|
<div>
|
||||||
<Label htmlFor="cid">CID</Label>
|
<Label htmlFor="cid" className="text-xs sm:text-sm">CID</Label>
|
||||||
<Input
|
<Input
|
||||||
id="cid"
|
id="cid"
|
||||||
value={campos.cid}
|
value={campos.cid}
|
||||||
onChange={(e) => setCampos(prev => ({ ...prev, cid: e.target.value }))}
|
onChange={(e) => setCampos(prev => ({ ...prev, cid: e.target.value }))}
|
||||||
placeholder="Ex: M25.5, I10, etc."
|
placeholder="Ex: M25.5, I10, etc."
|
||||||
|
className="text-xs sm:text-sm h-8 sm:h-10"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label htmlFor="exame">Exame</Label>
|
<Label htmlFor="exame" className="text-xs sm:text-sm">Exame</Label>
|
||||||
<Input
|
<Input
|
||||||
id="exame"
|
id="exame"
|
||||||
value={campos.exame}
|
value={campos.exame}
|
||||||
onChange={(e) => setCampos(prev => ({ ...prev, exame: e.target.value }))}
|
onChange={(e) => setCampos(prev => ({ ...prev, exame: e.target.value }))}
|
||||||
placeholder="Exame realizado"
|
placeholder="Exame realizado"
|
||||||
|
className="text-xs sm:text-sm h-8 sm:h-10"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label htmlFor="diagnostico">Diagnóstico</Label>
|
<Label htmlFor="diagnostico" className="text-xs sm:text-sm">Diagnóstico</Label>
|
||||||
<Textarea
|
<Textarea
|
||||||
id="diagnostico"
|
id="diagnostico"
|
||||||
value={campos.diagnostico}
|
value={campos.diagnostico}
|
||||||
onChange={(e) => setCampos(prev => ({ ...prev, diagnostico: e.target.value }))}
|
onChange={(e) => setCampos(prev => ({ ...prev, diagnostico: e.target.value }))}
|
||||||
placeholder="Diagnóstico principal"
|
placeholder="Diagnóstico principal"
|
||||||
rows={3}
|
rows={2}
|
||||||
|
className="text-xs sm:text-sm"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label htmlFor="conclusao">Conclusão</Label>
|
<Label htmlFor="conclusao" className="text-xs sm:text-sm">Conclusão</Label>
|
||||||
<Textarea
|
<Textarea
|
||||||
id="conclusao"
|
id="conclusao"
|
||||||
value={campos.conclusao}
|
value={campos.conclusao}
|
||||||
onChange={(e) => setCampos(prev => ({ ...prev, conclusao: e.target.value }))}
|
onChange={(e) => setCampos(prev => ({ ...prev, conclusao: e.target.value }))}
|
||||||
placeholder="Conclusão do laudo"
|
placeholder="Conclusão do laudo"
|
||||||
rows={3}
|
rows={2}
|
||||||
|
className="text-xs sm:text-sm"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-1.5 sm:space-y-2">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
id="mostrar-data"
|
id="mostrar-data"
|
||||||
checked={campos.mostrarData}
|
checked={campos.mostrarData}
|
||||||
onChange={(e) => setCampos(prev => ({ ...prev, mostrarData: e.target.checked }))}
|
onChange={(e) => setCampos(prev => ({ ...prev, mostrarData: e.target.checked }))}
|
||||||
|
className="w-4 h-4"
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="mostrar-data">Mostrar data no laudo</Label>
|
<Label htmlFor="mostrar-data" className="text-xs sm:text-sm">Mostrar data no laudo</Label>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<input
|
<input
|
||||||
@ -2439,8 +2444,9 @@ const ProfissionalPage = () => {
|
|||||||
id="mostrar-assinatura"
|
id="mostrar-assinatura"
|
||||||
checked={campos.mostrarAssinatura}
|
checked={campos.mostrarAssinatura}
|
||||||
onChange={(e) => setCampos(prev => ({ ...prev, mostrarAssinatura: e.target.checked }))}
|
onChange={(e) => setCampos(prev => ({ ...prev, mostrarAssinatura: e.target.checked }))}
|
||||||
|
className="w-4 h-4"
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="mostrar-assinatura">Mostrar assinatura no laudo</Label>
|
<Label htmlFor="mostrar-assinatura" className="text-xs sm:text-sm">Mostrar assinatura no laudo</Label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Assinatura Digital removida dos campos */}
|
{/* Assinatura Digital removida dos campos */}
|
||||||
@ -2450,106 +2456,98 @@ const ProfissionalPage = () => {
|
|||||||
|
|
||||||
{/* Preview Panel */}
|
{/* Preview Panel */}
|
||||||
{showPreview && (
|
{showPreview && (
|
||||||
<div className="w-1/2 border-l border-border bg-muted/20">
|
<div className="hidden md:flex md:w-1/2 border-l border-border bg-muted/20 flex-col">
|
||||||
<div className="p-4 border-b border-border">
|
<div className="p-2 md:p-2.5 border-b border-border flex-shrink-0">
|
||||||
<h3 className="font-semibold text-foreground">Pré-visualização do Laudo</h3>
|
<h3 className="font-semibold text-xs md:text-sm text-foreground">Pré-visualização do Laudo</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-4 max-h-[600px] overflow-y-auto">
|
<div className="flex-1 overflow-y-auto p-1.5 md:p-2">
|
||||||
<div className="bg-background border border-border rounded-lg p-6 shadow-sm">
|
<div className="bg-background border border-border rounded p-2 md:p-2.5 text-xs">
|
||||||
{/* Header do Laudo */}
|
{/* Header do Laudo */}
|
||||||
<div className="text-center mb-6">
|
<div className="text-center mb-2 pb-2 border-b border-border/40">
|
||||||
<h2 className="text-lg font-bold">
|
<h2 className="text-sm font-bold leading-tight">
|
||||||
LAUDO MÉDICO {campos.especialidade ? `- ${campos.especialidade.toUpperCase()}` : ''}
|
LAUDO MÉDICO {campos.especialidade ? `- ${campos.especialidade.toUpperCase()}` : ''}
|
||||||
</h2>
|
</h2>
|
||||||
{campos.exame && (
|
{campos.exame && (
|
||||||
<h3 className="text-md font-semibold mt-2">{campos.exame}</h3>
|
<p className="text-xs font-semibold mt-1">{campos.exame}</p>
|
||||||
)}
|
|
||||||
{campos.cid && (
|
|
||||||
<h3 className="text-md font-semibold mt-2">CID: {campos.cid}</h3>
|
|
||||||
)}
|
|
||||||
{campos.diagnostico && (
|
|
||||||
<h3 className="text-md font-semibold mt-2">Diagnóstico: {campos.diagnostico}</h3>
|
|
||||||
)}
|
|
||||||
{campos.conclusao && (
|
|
||||||
<h3 className="text-md font-semibold mt-2">Conclusão: {campos.conclusao}</h3>
|
|
||||||
)}
|
)}
|
||||||
{campos.mostrarData && (
|
{campos.mostrarData && (
|
||||||
<p className="text-sm text-muted-foreground mt-1">
|
<p className="text-xs text-muted-foreground mt-0.5">
|
||||||
Data: {new Date().toLocaleDateString('pt-BR')}
|
Data: {new Date().toLocaleDateString('pt-BR')}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Dados do Paciente */}
|
{/* Dados do Paciente - Compacto */}
|
||||||
{(isNewLaudo ? pacienteSelecionado : laudo?.paciente) && (
|
{(isNewLaudo ? pacienteSelecionado : laudo?.paciente) && (
|
||||||
<div className="mb-4 p-3 bg-muted rounded">
|
<div className="mb-2 pb-2 border-b border-border/40 space-y-0.5">
|
||||||
<h3 className="font-semibold mb-2">Dados do Paciente:</h3>
|
<div><span className="font-semibold">Paciente:</span> {isNewLaudo ? getPatientName(pacienteSelecionado) : getPatientName(laudo?.paciente)}</div>
|
||||||
{isNewLaudo && pacienteSelecionado ? (
|
<div><span className="font-semibold">CPF:</span> {isNewLaudo ? getPatientCpf(pacienteSelecionado) : getPatientCpf(laudo?.paciente)}</div>
|
||||||
<>
|
<div><span className="font-semibold">Idade:</span> {isNewLaudo ? getPatientAge(pacienteSelecionado) : getPatientAge(laudo?.paciente)} anos</div>
|
||||||
<p><strong>Nome:</strong> {getPatientName(pacienteSelecionado)}</p>
|
<div><span className="font-semibold">Sexo:</span> {isNewLaudo ? getPatientSex(pacienteSelecionado) : getPatientSex(laudo?.paciente)}</div>
|
||||||
<p><strong>ID:</strong> {getPatientId(pacienteSelecionado)}</p>
|
|
||||||
<p><strong>CPF:</strong> {getPatientCpf(pacienteSelecionado)}</p>
|
|
||||||
<p><strong>Idade:</strong> {getPatientAge(pacienteSelecionado)} anos</p>
|
|
||||||
<p><strong>Sexo:</strong> {getPatientSex(pacienteSelecionado)}</p>
|
|
||||||
<p><strong>CID:</strong> {campos.cid || '---'}</p>
|
|
||||||
<p><strong>Diagnóstico:</strong> {campos.diagnostico || '---'}</p>
|
|
||||||
<p><strong>Conclusão:</strong> {campos.conclusao || '---'}</p>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<p><strong>Nome:</strong> {getPatientName(laudo?.paciente)}</p>
|
|
||||||
<p><strong>ID:</strong> {getPatientId(laudo?.paciente)}</p>
|
|
||||||
<p><strong>CPF:</strong> {getPatientCpf(laudo?.paciente)}</p>
|
|
||||||
<p><strong>Idade:</strong> {getPatientAge(laudo?.paciente)} anos</p>
|
|
||||||
<p><strong>Sexo:</strong> {getPatientSex(laudo?.paciente)}</p>
|
|
||||||
<p><strong>CID:</strong> {campos.cid || laudo?.cid || '---'}</p>
|
|
||||||
<p><strong>Diagnóstico:</strong> {campos.diagnostico || laudo?.diagnostico || '---'}</p>
|
|
||||||
<p><strong>Conclusão:</strong> {campos.conclusao || laudo?.conclusao || '---'}</p>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Conteúdo */}
|
{/* Informações Clínicas */}
|
||||||
<div className="mb-4">
|
<div className="mb-2 pb-2 border-b border-border/40 space-y-0.5">
|
||||||
<div
|
{campos.cid && (
|
||||||
dangerouslySetInnerHTML={{
|
<div><span className="font-semibold">CID:</span> <span className="text-blue-600 dark:text-blue-400 font-semibold">{campos.cid}</span></div>
|
||||||
__html: processContent(content)
|
)}
|
||||||
}}
|
{campos.diagnostico && (
|
||||||
/>
|
<div><span className="font-semibold">Diagnóstico:</span> {campos.diagnostico}</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Imagens */}
|
{/* Conteúdo Principal */}
|
||||||
|
{content && (
|
||||||
|
<div className="mb-2 pb-2 border-b border-border/40">
|
||||||
|
<div
|
||||||
|
className="text-xs leading-normal [&_p]:my-0.5 [&_br]:mb-0.5 whitespace-pre-wrap"
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: processContent(content)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Conclusão */}
|
||||||
|
{campos.conclusao && (
|
||||||
|
<div className="mb-2 pb-2 border-b border-border/40">
|
||||||
|
<div><span className="font-semibold">Conclusão:</span></div>
|
||||||
|
<div className="text-xs leading-normal mt-0.5">{campos.conclusao}</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Imagens Compactas */}
|
||||||
{imagens.length > 0 && (
|
{imagens.length > 0 && (
|
||||||
<div className="mb-4">
|
<div className="mb-2 pb-2 border-b border-border/40">
|
||||||
<h3 className="font-semibold mb-2">Imagens:</h3>
|
<div className="font-semibold mb-1">Imagens:</div>
|
||||||
<div className="grid grid-cols-2 gap-2">
|
<div className="grid grid-cols-2 gap-1">
|
||||||
{imagens.map((img) => (
|
{imagens.map((img) => (
|
||||||
// eslint-disable-next-line @next/next/no-img-element
|
// eslint-disable-next-line @next/next/no-img-element
|
||||||
<img
|
<img
|
||||||
key={img.id}
|
key={img.id}
|
||||||
src={img.url}
|
src={img.url}
|
||||||
alt={img.name}
|
alt={img.name}
|
||||||
className="w-full h-32 object-cover rounded border"
|
className="w-full h-14 object-cover rounded border border-border/40"
|
||||||
|
title={img.name}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Assinatura Digital em tempo real */}
|
{/* Assinatura Digital - Compacta */}
|
||||||
{campos.mostrarAssinatura && (
|
{campos.mostrarAssinatura && (
|
||||||
<div className="mt-8 text-center">
|
<div className="pt-1 mt-1 border-t border-border/40 text-center">
|
||||||
{assinaturaImg && assinaturaImg.length > 30 ? (
|
{assinaturaImg && assinaturaImg.length > 30 ? (
|
||||||
// eslint-disable-next-line @next/next/no-img-element
|
// eslint-disable-next-line @next/next/no-img-element
|
||||||
<img src={assinaturaImg} alt="Assinatura Digital" className="mx-auto h-16 object-contain mb-2" />
|
<img src={assinaturaImg} alt="Assinatura Digital" className="mx-auto h-8 object-contain mb-0.5" />
|
||||||
) : (
|
) : (
|
||||||
<div className="h-16 mb-2 text-xs text-muted-foreground">Assine no campo ao lado para visualizar aqui.</div>
|
<div className="text-xs text-muted-foreground italic">Assinatura pendente</div>
|
||||||
)}
|
)}
|
||||||
<div className="border-b border-border mb-2"></div>
|
<div className="border-t border-border/40 my-0.5"></div>
|
||||||
<p className="text-sm">{((profileData as any)?.nome || (profileData as any)?.nome_social) || user?.name || 'Squad-20'}</p>
|
<p className="text-xs font-semibold">{((profileData as any)?.nome || (profileData as any)?.nome_social) || user?.name || 'Squad-20'}</p>
|
||||||
{(((profileData as any)?.crm) || ((user?.profile as any)?.crm)) ? (
|
{(((profileData as any)?.crm) || ((user?.profile as any)?.crm)) ? (
|
||||||
// Ensure we render a single 'CRM ' prefix followed by the raw number
|
|
||||||
<p className="text-xs text-muted-foreground">CRM {(((profileData as any)?.crm) || (user?.profile as any)?.crm).toString().replace(/^(?:CRM\s*)+/i, '').trim()}</p>
|
<p className="text-xs text-muted-foreground">CRM {(((profileData as any)?.crm) || (user?.profile as any)?.crm).toString().replace(/^(?:CRM\s*)+/i, '').trim()}</p>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
@ -2561,13 +2559,13 @@ const ProfissionalPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Footer */}
|
{/* Footer */}
|
||||||
<div className="p-4 border-t border-border bg-muted/20">
|
<div className="p-2 sm:p-4 border-t border-border bg-muted/20">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-2">
|
||||||
<div className="text-xs text-muted-foreground">
|
<div className="text-xs text-muted-foreground hidden sm:block">
|
||||||
Este editor permite escrever relatórios de forma livre, com formatação de texto rica.
|
Este editor permite escrever relatórios de forma livre, com formatação de texto rica.
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2 w-full sm:w-auto">
|
||||||
<Button variant="outline" onClick={onClose} className="hover:bg-primary! hover:text-white! transition-colors">
|
<Button variant="outline" onClick={onClose} className="flex-1 sm:flex-none hover:bg-primary! hover:text-white! transition-colors text-xs sm:text-sm">
|
||||||
Cancelar
|
Cancelar
|
||||||
</Button>
|
</Button>
|
||||||
{/* botão 'Salvar Rascunho' removido por não ser utilizado */}
|
{/* botão 'Salvar Rascunho' removido por não ser utilizado */}
|
||||||
@ -2676,6 +2674,7 @@ const ProfissionalPage = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
className="flex-1 sm:flex-none text-xs sm:text-sm"
|
||||||
>
|
>
|
||||||
{isNewLaudo ? "Liberar Laudo" : "Atualizar Laudo"}
|
{isNewLaudo ? "Liberar Laudo" : "Atualizar Laudo"}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
10
susconecta/pnpm-lock.yaml
generated
10
susconecta/pnpm-lock.yaml
generated
@ -137,6 +137,9 @@ importers:
|
|||||||
geist:
|
geist:
|
||||||
specifier: ^1.3.1
|
specifier: ^1.3.1
|
||||||
version: 1.5.1(next@15.5.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
|
version: 1.5.1(next@15.5.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
|
||||||
|
html2canvas:
|
||||||
|
specifier: ^1.4.1
|
||||||
|
version: 1.4.1
|
||||||
input-otp:
|
input-otp:
|
||||||
specifier: latest
|
specifier: latest
|
||||||
version: 1.4.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 1.4.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
@ -4860,8 +4863,7 @@ snapshots:
|
|||||||
|
|
||||||
balanced-match@1.0.2: {}
|
balanced-match@1.0.2: {}
|
||||||
|
|
||||||
base64-arraybuffer@1.0.2:
|
base64-arraybuffer@1.0.2: {}
|
||||||
optional: true
|
|
||||||
|
|
||||||
baseline-browser-mapping@2.8.4: {}
|
baseline-browser-mapping@2.8.4: {}
|
||||||
|
|
||||||
@ -4982,7 +4984,6 @@ snapshots:
|
|||||||
css-line-break@2.1.0:
|
css-line-break@2.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
utrie: 1.0.2
|
utrie: 1.0.2
|
||||||
optional: true
|
|
||||||
|
|
||||||
csstype@3.1.3: {}
|
csstype@3.1.3: {}
|
||||||
|
|
||||||
@ -5634,7 +5635,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
css-line-break: 2.1.0
|
css-line-break: 2.1.0
|
||||||
text-segmentation: 1.0.3
|
text-segmentation: 1.0.3
|
||||||
optional: true
|
|
||||||
|
|
||||||
ignore@5.3.2: {}
|
ignore@5.3.2: {}
|
||||||
|
|
||||||
@ -6582,7 +6582,6 @@ snapshots:
|
|||||||
text-segmentation@1.0.3:
|
text-segmentation@1.0.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
utrie: 1.0.2
|
utrie: 1.0.2
|
||||||
optional: true
|
|
||||||
|
|
||||||
tiny-invariant@1.3.3: {}
|
tiny-invariant@1.3.3: {}
|
||||||
|
|
||||||
@ -6729,7 +6728,6 @@ snapshots:
|
|||||||
utrie@1.0.2:
|
utrie@1.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
base64-arraybuffer: 1.0.2
|
base64-arraybuffer: 1.0.2
|
||||||
optional: true
|
|
||||||
|
|
||||||
uuid@13.0.0: {}
|
uuid@13.0.0: {}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user