fix: version 4.8.1 -- Agenda medica abre en vista Mes como el Calendario

Barra igual a la del Calendario (Hoy, anterior/siguiente, mes y ano; vista a la
derecha), vista Mes por defecto y aviso cuando no hay medicos configurados (antes
la vista Dia quedaba vacia).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Milton Gonzalez
2026-10-28 13:45:58 -05:00
parent 91e15e8318
commit 00aaf1ebef
11 changed files with 38 additions and 15 deletions
+3 -3
View File
@@ -1,12 +1,12 @@
{
"name": "project-linkedcorp-frontend",
"version": "4.8.0",
"version": "4.8.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "project-linkedcorp-frontend",
"version": "4.8.0",
"version": "4.8.1",
"dependencies": {
"dompurify": "^3.4.16",
"highlight.js": "^11.12.0",
@@ -2748,7 +2748,7 @@
"license": "MIT"
},
"node_modules/@vitejs/plugin-react": {
"version": "4.8.0",
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz",
"integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==",
"dev": true,
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "project-linkedcorp-frontend",
"private": true,
"version": "4.8.0",
"version": "4.8.1",
"type": "module",
"scripts": {
"dev": "vite",
+2 -2
View File
@@ -21,7 +21,7 @@ export const messages = {
clinic_block: 'Bloqueo',
clinic_view_day: 'Día',
clinic_view_week: 'Semana',
clinic_view_list: 'Lista', clinic_view_month: 'Mes', clinic_more: 'más',
clinic_view_list: 'Agenda', clinic_view_month: 'Mes', clinic_no_doctors: 'Aún no hay médicos configurados en la agenda. Pide a un administrador que los registre.', clinic_no_doctors_admin: 'Aún no hay médicos configurados. Regístralos con su horario en la pestaña Configuración de agenda.', clinic_more: 'más',
clinic_doctors: 'Médicos',
clinic_doctor: 'Médico',
clinic_status: 'Estado',
@@ -713,7 +713,7 @@ export const messages = {
clinic_block: 'Block',
clinic_view_day: 'Day',
clinic_view_week: 'Week',
clinic_view_list: 'List', clinic_view_month: 'Month', clinic_more: 'more',
clinic_view_list: 'Agenda', clinic_view_month: 'Month', clinic_no_doctors: 'No doctors are set up in the schedule yet. Ask an administrator to add them.', clinic_no_doctors_admin: 'No doctors are set up yet. Add them with their hours in the Schedule settings tab.', clinic_more: 'more',
clinic_doctors: 'Doctors',
clinic_doctor: 'Doctor',
clinic_status: 'Status',
@@ -100,6 +100,7 @@ const readStored = (key, fallback) => {
export default function AgendaMedicaPage() {
const {
t,
lang,
openDialog,
pushToast
} = useUi();
@@ -113,7 +114,7 @@ export default function AgendaMedicaPage() {
[types, setTypes] = useState([]),
[allTypes, setAllTypes] = useState([]);
const [tab, setTab] = useState('agenda'),
[view, setView] = useState(() => { const v = readStored('plc_clinic_view', 'day'); return ['day', 'week', 'month', 'list'].includes(v) ? v : 'day'; }),
[view, setView] = useState(() => { const v = readStored('plc_clinic_view_v2', 'month'); return ['day', 'week', 'month', 'list'].includes(v) ? v : 'month'; }),
[day, setDay] = useState(today);
const [doctorFilter, setDoctorFilter] = useState(() => {
const value = readStored('plc_clinic_doctors', []);
@@ -239,7 +240,7 @@ export default function AgendaMedicaPage() {
}, [me?.user_id, period.from, period.to]);
useEffect(() => {
try {
localStorage.setItem('plc_clinic_view', JSON.stringify(view));
localStorage.setItem('plc_clinic_view_v2', JSON.stringify(view));
} catch {}
}, [view]);
useEffect(() => {
@@ -429,6 +430,13 @@ export default function AgendaMedicaPage() {
actions
});
}
const periodTitle = (() => {
const d = new Date(`${day}T12:00:00`);
if (view === 'month' || view === 'list') return d.toLocaleDateString(lang, { month: 'long', year: 'numeric' });
if (view === 'day') return d.toLocaleDateString(lang, { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' });
const a = new Date(`${period.from.slice(0, 10)}T12:00:00`), b = new Date(`${move(period.to.slice(0, 10), -1)}T12:00:00`);
return `${a.toLocaleDateString(lang, { day: 'numeric', month: 'short' })} – ${b.toLocaleDateString(lang, { day: 'numeric', month: 'short', year: 'numeric' })}`;
})();
const doctorColor = id => doctors.find(d => d.id === id)?.color || 'rgb(var(--accent))';
const doctorShort = id => (doctors.find(d => d.id === id)?.name || '').split(' ').slice(0, 2).join(' ');
const weekLabels = [t('calendar_mon'), t('calendar_tue'), t('calendar_wed'), t('calendar_thu'), t('calendar_fri'), t('calendar_sat'), t('calendar_sun')];
@@ -475,7 +483,7 @@ export default function AgendaMedicaPage() {
const current = popup ? draft : tab === 'config' ? [staffDraft, typeDraft, scheduleDraft].find(x => x.isDirty) : null;
void guardedClose(current, () => setTab(key));
}} />
{tab === 'agenda' && <><div className="clinic-controls"><Button icon={ChevronLeft} onClick={() => setDay(step(-1))}>{t('calendar_previous')}</Button><DatePicker value={day} onChange={setDay} label={t('calendar_date')} /><Button icon={ChevronRight} onClick={() => setDay(step(1))}>{t('calendar_next')}</Button><ComboBox value={view} onChange={setView} options={['day', 'week', 'month', 'list'].map(x => ({
{tab === 'agenda' && <><div className="toolbar clinic-toolbar"><div className="toolbar-left"><Button onClick={() => setDay(today())}>{t('calendar_today')}</Button><Button icon={ChevronLeft} onClick={() => setDay(step(-1))} aria-label={t('calendar_previous')} /><Button icon={ChevronRight} onClick={() => setDay(step(1))} aria-label={t('calendar_next')} /><strong className="clinic-period">{periodTitle}</strong></div><div className="toolbar-left clinic-controls"><ComboBox value={view} onChange={setView} options={['month', 'week', 'day', 'list'].map(x => ({
value: x,
label: t(`clinic_view_${x}`)
}))} /><CheckListDropdown label={t('clinic_doctors')} options={doctors.map(d => ({
@@ -484,7 +492,8 @@ export default function AgendaMedicaPage() {
}))} values={doctorFilter} onChange={setDoctorFilter} /><CheckListDropdown label={t('clinic_status')} options={['scheduled', 'confirmed', 'attended', 'no_show'].map(x => ({
value: x,
label: t(`clinic_status_${x}`)
}))} values={statusFilter} onChange={setStatusFilter} /></div>
}))} values={statusFilter} onChange={setStatusFilter} /><DatePicker value={day} onChange={setDay} label={t('calendar_date')} /></div></div>
{me && doctors.length === 0 && <InfoBar tone="warning">{isAdmin ? t('clinic_no_doctors_admin') : t('clinic_no_doctors')}</InfoBar>}
{(view === 'week' || view === 'month') && <div className="clinic-legend">{selectedDoctors.map(d => <span key={d.id}><span className="clinic-swatch" style={{ background: d.color || 'rgb(var(--accent))' }} />{d.name}</span>)}<span><span className="clinic-swatch block" />{t('clinic_blocks')}</span></div>}
{view === 'day' ? <div className="clinic-day-grid">{selectedDoctors.map(d => <div className="clinic-doctor" key={d.id}><h3 style={{
borderTop: `3px solid ${d.color || 'rgb(var(--accent))'}`
@@ -14,3 +14,9 @@
.clinic-swatch{width:12px;height:12px;border-radius:3px;display:inline-block}
.clinic-swatch.block{background:repeating-linear-gradient(135deg,rgb(var(--warning)) 0 3px,transparent 3px 6px);border:1px solid rgb(var(--warning)/.6)}
.clinic-page .calendar-cell{min-height:104px}
/* Barra igual a la del Calendario: Hoy, anterior/siguiente y titulo del periodo; a la derecha vista y filtros. */
.clinic-toolbar{margin:12px 0}
.clinic-toolbar .clinic-controls{margin:0}
.clinic-period{display:inline-block}.clinic-period::first-letter{text-transform:uppercase}
.clinic-toolbar .clinic-controls .combobox{width:140px;min-width:0;flex:0 0 140px}
.clinic-toolbar .clinic-controls .datepicker-trigger{flex:0 0 150px;width:150px}