diff --git a/backend/package.json b/backend/package.json index af9e3fc..5400e19 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "rosterchirp-backend", - "version": "0.12.16", + "version": "0.12.17", "description": "RosterChirp backend server", "main": "src/index.js", "scripts": { diff --git a/build.sh b/build.sh index 2fac1c2..681bfa3 100644 --- a/build.sh +++ b/build.sh @@ -13,7 +13,7 @@ # ───────────────────────────────────────────────────────────── set -euo pipefail -VERSION="${1:-0.12.16}" +VERSION="${1:-0.12.17}" ACTION="${2:-}" REGISTRY="${REGISTRY:-}" IMAGE_NAME="rosterchirp" diff --git a/frontend/package.json b/frontend/package.json index af85a38..b22db4d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "rosterchirp-frontend", - "version": "0.12.16", + "version": "0.12.17", "private": true, "scripts": { "dev": "vite", diff --git a/frontend/src/components/SchedulePage.jsx b/frontend/src/components/SchedulePage.jsx index d6970cd..1e38115 100644 --- a/frontend/src/components/SchedulePage.jsx +++ b/frontend/src/components/SchedulePage.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback, useRef } from 'react'; +import { useState, useEffect, useCallback, useRef, useMemo } from 'react'; import ReactDOM from 'react-dom'; import { api } from '../utils/api.js'; import { useToast } from '../contexts/ToastContext.jsx'; @@ -231,10 +231,36 @@ function TimeInput({ value, onChange, style }) { } // ── Mini Calendar (desktop) ─────────────────────────────────────────────────── -function MiniCalendar({ selected, onChange, eventDates=new Set() }) { +function MiniCalendar({ selected, onChange, events=[] }) { const [cur, setCur] = useState(()=>{ const d=new Date(selected||Date.now()); d.setDate(1); return d; }); + + // BUG FIX: sync displayed month when selected date changes (e.g. switching Day/Week/Month view resets to today) + useEffect(() => { + const n = new Date(selected || Date.now()); + n.setDate(1); n.setHours(0,0,0,0); + setCur(prev => (prev.getFullYear()===n.getFullYear()&&prev.getMonth()===n.getMonth()) ? prev : n); + }, [selected]); + const y=cur.getFullYear(), m=cur.getMonth(), first=new Date(y,m,1).getDay(), total=daysInMonth(y,m), today=new Date(); const cells=[]; for(let i=0;i { + const rangeStart = new Date(y, m, 1); + const rangeEnd = new Date(y, m+1, 0, 23, 59, 59); + const s = new Set(); + for (const ev of events) { + const occs = expandRecurringEvent(ev, rangeStart, rangeEnd); + for (const occ of occs) { + if (!occ.start_at) continue; + const d = new Date(occ.start_at); + if (d.getFullYear()===y && d.getMonth()===m) + s.add(`${y}-${String(m+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`); + } + } + return s; + }, [events, y, m]); + return (
@@ -1469,7 +1495,7 @@ export default function SchedulePage({ isToolManager, isMobile, onProfile, onHel setFilterKeyword(''); setFilterTypeId(''); setFilterAvailability(false); - }} eventDates={eventDates}/> + }} events={events}/>
{/* List view filters — only shown in Schedule list view */}