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:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user