new file: public/favicon.svg

deleted:    src/assets/hero.png
modified:   src/components/AppShell.jsx
modified:   src/components/calendar/AgendaDailyView.jsx
modified:   src/components/calendar/AgendaMonthlyView.jsx
modified:   src/components/calendar/AgendaWeeklyView.jsx
modified:   src/hooks/useAgenda.js
modified:   src/index.css
modified:   src/mappers/appointmentMapper.js
modified:   src/mappers/reportMapper.js
modified:   src/pages/AgendaPage.jsx
modified:   src/pages/AuthPages.jsx
modified:   src/pages/HomePage.jsx
modified:   src/pages/MessagesPage.jsx
modified:   src/pages/PatientsPage.jsx
modified:   src/pages/ProfilePage.jsx
modified:   src/pages/ReportsPage.jsx
modified:   src/pages/SettingsPage.jsx
modified:   src/repositories/appointmentRepository.js
modified:   src/repositories/settingsRepository.js
This commit is contained in:
2026-05-08 01:32:46 -03:00
parent bc900fbdd4
commit 94dab58d85
20 changed files with 1206 additions and 447 deletions

View File

@@ -542,14 +542,16 @@ function TemplateCard({ onEdit, onUse, template }) {
}
function MessageComposer({ allowedChannelKeys, draft, onChange, onClose, onSubmit, patients, templates }) {
const [patientSearch, setPatientSearch] = useState('')
const [patientSearch, setPatientSearch] = useState(draft.patient || '')
const filteredPatients = useMemo(() => {
const query = patientSearch.trim().toLowerCase()
const query = normalizeSearch(patientSearch)
if (!query) return patients
return patients.filter((patient) =>
[patient.name, patient.phone, patient.document]
.join(' ')
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.toLowerCase()
.includes(query),
)
@@ -559,15 +561,14 @@ function MessageComposer({ allowedChannelKeys, draft, onChange, onClose, onSubmi
onChange((current) => ({ ...current, [field]: value }))
}
function selectPatient(patientId) {
const patient = patients.find((item) => item.id === patientId)
function selectPatient(patient) {
onChange((current) => ({
...current,
patientId,
patientId: patient?.id || '',
patient: patient?.name || '',
phone: patient?.phone || current.phone,
}))
setPatientSearch(patient?.name || '')
}
function applyTemplate(templateName) {
@@ -589,31 +590,44 @@ function MessageComposer({ allowedChannelKeys, draft, onChange, onClose, onSubmi
return (
<ModalFrame onClose={onClose} title="Nova Mensagem">
<form className="space-y-4" onSubmit={onSubmit}>
<div className="grid gap-4 md:grid-cols-2">
<DarkField label="Paciente">
<DarkField label="Paciente">
<div className="space-y-2">
<input
className={inputClass}
onChange={(event) => setPatientSearch(event.target.value)}
onChange={(event) => {
setPatientSearch(event.target.value)
onChange((current) => ({ ...current, patientId: '', patient: '' }))
}}
placeholder="Digite nome, CPF ou telefone"
type="search"
value={patientSearch}
/>
</DarkField>
<DarkField label="Selecionar paciente">
<select
className={inputClass}
onChange={(event) => selectPatient(event.target.value)}
value={draft.patientId}
>
<option value="">Selecione um paciente</option>
{filteredPatients.map((patient) => (
<option key={patient.id} value={patient.id}>
{patient.name}
</option>
))}
</select>
</DarkField>
</div>
<div className="max-h-44 overflow-y-auto rounded-md border border-[#404040] bg-[#1f1f1f]">
{filteredPatients.length ? (
filteredPatients.slice(0, 8).map((patient) => {
const isSelected = String(patient.id) === String(draft.patientId)
return (
<button
className={`block w-full px-3 py-2 text-left text-sm transition ${
isSelected ? 'bg-[#3b82f6]/20 text-[#e5e5e5]' : 'text-[#a3a3a3] hover:bg-[#303030] hover:text-[#e5e5e5]'
}`}
key={patient.id}
onClick={() => selectPatient(patient)}
type="button"
>
<span className="block font-semibold">{patient.name}</span>
<span className="mt-0.5 block text-xs text-[#737373]">
{[patient.document, patient.phone].filter(Boolean).join(' | ') || 'Sem documento informado'}
</span>
</button>
)
})
) : (
<p className="px-3 py-2 text-xs text-[#737373]">Nenhum paciente encontrado.</p>
)}
</div>
</div>
</DarkField>
<div className="grid gap-4 md:grid-cols-2">
<DarkField label="Paciente selecionado">
@@ -749,6 +763,14 @@ function DarkField({ children, label }) {
)
}
function normalizeSearch(value) {
return String(value || '')
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.trim()
.toLowerCase()
}
function CommIcon({ className = 'size-4', name }) {
const common = {
className,