diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fbd25a..8928da3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog - project.linkedcorp.net +## [4.8.1] - 2026-10-28 +### Fixed +- Agenda médica: abre en vista **Mes** con la misma barra que el Calendario (Hoy, anterior/siguiente, + mes y año; vista Mes/Semana/Día/Agenda a la derecha). Antes abría en Día y, sin médicos + configurados, la pantalla quedaba vacía. Aviso cuando aún no hay médicos registrados. + ## [4.8.0] - 2026-10-28 ### Added - Agenda médica: vista **Mes** tipo calendario (hasta 4 citas/bloqueos por día, clic abre el día) y diff --git a/ESTADO.md b/ESTADO.md index 0254f72..6e06e8a 100644 --- a/ESTADO.md +++ b/ESTADO.md @@ -6,6 +6,8 @@ autorregistro/aprobacion/SMTP. ## Agenda médica (v4.7.0, sin desplegar) +- v4.8.1: abre en Mes con barra igual al Calendario; aviso si no hay médicos (en prod se veía vacío + porque la 4.8.0 abría en Día y aún no hay médicos configurados). - v4.8.0: vistas Mes (calendario) y Semana con todos los médicos filtrados, color por médico. Sin migración. Revisado en dev con datos temporales (ya borrados), sin errores de consola. diff --git a/SPEC.md b/SPEC.md index a341172..dddb6cb 100644 --- a/SPEC.md +++ b/SPEC.md @@ -100,7 +100,7 @@ tiene cada cosa — sin que cargar la información sea tedioso para quien lo usa Los médicos conservan el resto de sus módulos y no se crea un rol del sistema. - Admin/superadmin con acceso a `clinic` y fila de staff configuran personal, horarios por tramos y tipos de cita desde la pestaña Configuración de agenda. -- Vistas (v4.8.0, la elegida se recuerda): **Día** con una columna por médico; **Semana** como +- Vistas (v4.8.0; desde v4.8.1 abre en Mes con la barra del Calendario; la elegida se recuerda): **Día** con una columna por médico; **Semana** como calendario de 7 días con las citas de todos los médicos filtrados, coloreadas por médico; **Mes** como calendario mensual (hasta 4 entradas por día + "N más"; clic en un día abre su vista Día); **Lista** con citas y bloqueos. Leyenda de colores por médico en Semana y Mes. diff --git a/VERSION b/VERSION index 88f1811..697e993 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.8.0 +4.8.1 diff --git a/backend/package-lock.json b/backend/package-lock.json index 9e5c311..204e355 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1,12 +1,12 @@ { "name": "project-linkedcorp-backend", - "version": "4.8.0", + "version": "4.8.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "project-linkedcorp-backend", - "version": "4.8.0", + "version": "4.8.1", "dependencies": { "bcryptjs": "^2.4.3", "cors": "^2.8.5", diff --git a/backend/package.json b/backend/package.json index 2848dbe..964fb16 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "project-linkedcorp-backend", - "version": "4.8.0", + "version": "4.8.1", "private": true, "type": "module", "main": "src/server.js", diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 3684c52..c6fe251 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -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, diff --git a/frontend/package.json b/frontend/package.json index ef5f122..90cb44f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "project-linkedcorp-frontend", "private": true, - "version": "4.8.0", + "version": "4.8.1", "type": "module", "scripts": { "dev": "vite", diff --git a/frontend/src/i18n/messages.js b/frontend/src/i18n/messages.js index 05a8ca4..642c532 100644 --- a/frontend/src/i18n/messages.js +++ b/frontend/src/i18n/messages.js @@ -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', diff --git a/frontend/src/pages/AgendaMedica/AgendaMedicaPage.jsx b/frontend/src/pages/AgendaMedica/AgendaMedicaPage.jsx index 5beb574..96759e7 100644 --- a/frontend/src/pages/AgendaMedica/AgendaMedicaPage.jsx +++ b/frontend/src/pages/AgendaMedica/AgendaMedicaPage.jsx @@ -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' && <>
({ + {tab === 'agenda' && <>
({ value: x, label: t(`clinic_view_${x}`) }))} /> ({ @@ -484,7 +492,8 @@ export default function AgendaMedicaPage() { }))} values={doctorFilter} onChange={setDoctorFilter} /> ({ value: x, label: t(`clinic_status_${x}`) - }))} values={statusFilter} onChange={setStatusFilter} />
+ }))} values={statusFilter} onChange={setStatusFilter} />
+ {me && doctors.length === 0 && {isAdmin ? t('clinic_no_doctors_admin') : t('clinic_no_doctors')}} {(view === 'week' || view === 'month') &&
{selectedDoctors.map(d => {d.name})}{t('clinic_blocks')}
} {view === 'day' ?
{selectedDoctors.map(d =>