diff --git a/frontend/src/components/Calendar/MainCalendar.jsx b/frontend/src/components/Calendar/MainCalendar.jsx
index 2e90d98..37c9eb4 100644
--- a/frontend/src/components/Calendar/MainCalendar.jsx
+++ b/frontend/src/components/Calendar/MainCalendar.jsx
@@ -14,11 +14,12 @@ import EventTooltip from './EventTooltip'
import WorkloadHeatmap from './WorkloadHeatmap'
export default function MainCalendar({ onCalendarReady }) {
- const calRef = useRef(null)
+ const calRef = useRef(null)
+ const wrapperRef = useRef(null)
const { projects, updateDeliverable: storeUpdate, removeDeliverable } = useProjectStore()
- const openFocus = useFocusStore(s => s.openFocus)
+ const openFocus = useFocusStore(s => s.openFocus)
const { showHeatmap, toggleHeatmap } = useUIStore()
- const addToast = useToastStore(s => s.addToast)
+ const addToast = useToastStore(s => s.addToast)
const [modal, setModal] = useState({ open: false, deliverable: null, defaultDate: '' })
const [contextMenu, setContextMenu] = useState(null)
@@ -31,6 +32,18 @@ export default function MainCalendar({ onCalendarReady }) {
}
}, [])
+ // ResizeObserver: call updateSize() on every frame the container changes width
+ // during the sidebar CSS transition so FullCalendar reflows smoothly
+ useEffect(() => {
+ const el = wrapperRef.current
+ if (!el) return
+ const ro = new ResizeObserver(() => {
+ calRef.current?.getApi().updateSize()
+ })
+ ro.observe(el)
+ return () => ro.disconnect()
+ }, [])
+
const events = projects.flatMap(p =>
(p.deliverables || []).map(d => ({
id: String(d.id),
@@ -69,12 +82,12 @@ export default function MainCalendar({ onCalendarReady }) {
})
}, [storeUpdate, addToast])
- // Click empty date — open add modal
+ // Click empty date - open add modal
const handleDateClick = useCallback(({ dateStr }) => {
setModal({ open: true, deliverable: null, defaultDate: dateStr.substring(0, 10) })
}, [])
- // Date range drag-select — pre-fill modal with start date
+ // Date range drag-select - pre-fill modal with start date
const handleSelect = useCallback(({ startStr }) => {
setModal({ open: true, deliverable: null, defaultDate: startStr.substring(0, 10) })
}, [])
@@ -107,11 +120,11 @@ export default function MainCalendar({ onCalendarReady }) {
setContextMenu({
x: e.clientX, y: e.clientY,
items: [
- { icon: '✎', label: 'Edit Deliverable', action: () => setModal({ open: true, deliverable, defaultDate: '' }) },
- { icon: '◎', label: 'Open Focus View', action: () => openFocus(projectId, deliverableId) },
- ...(project?.drive_url ? [{ icon: '⬡', label: 'Open Drive Folder', action: () => window.open(project.drive_url, '_blank') }] : []),
+ { icon: '\u2714\ufe0e', label: 'Edit Deliverable', action: () => setModal({ open: true, deliverable, defaultDate: '' }) },
+ { icon: '\u2756', label: 'Open Focus View', action: () => openFocus(projectId, deliverableId) },
+ ...(project?.drive_url ? [{ icon: '\u2b21', label: 'Open Drive Folder', action: () => window.open(project.drive_url, '_blank') }] : []),
{ separator: true },
- { icon: '✕', label: 'Delete Deliverable', danger: true,
+ { icon: '\u2715', label: 'Delete Deliverable', danger: true,
action: async () => {
if (window.confirm(`Delete "${deliverable.title}"?`)) {
await deleteDeliverable(deliverableId); removeDeliverable(deliverableId)
@@ -133,7 +146,7 @@ export default function MainCalendar({ onCalendarReady }) {
? 'bg-gold text-surface border-gold'
: 'bg-surface-elevated border-surface-border text-text-muted hover:border-gold/40 hover:text-gold'
}`}>
- {showHeatmap ? '← Calendar' : '⬡ Heatmap'}
+ {showHeatmap ? '\u2190 Calendar' : '\u2b21 Heatmap'}
@@ -142,7 +155,7 @@ export default function MainCalendar({ onCalendarReady }) {
{showHeatmap ? (