diff --git a/README.md b/README.md
index 8ad933c..134e361 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,6 @@
-# FABDASH
+# FabDash
**Fabrication Dashboard** — A sleek, modern project management & scheduling application built for fabrication workflows.
-Repo: https://github.com/jasonMPM/fabdash


@@ -748,4 +747,4 @@ To add a new column in a future version, append its `ALTER TABLE` statement to t
---
-*Built with intention. No subscriptions. No bloat. Just your fabrication workflow.*
\ No newline at end of file
+*Built with intention. No subscriptions. No bloat. Just your fabrication workflow.*
diff --git a/frontend/index.html b/frontend/index.html
index 2cd8bc8..4537fe6 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -5,8 +5,6 @@
FABDASH
-
-
diff --git a/frontend/src/components/Calendar/MainCalendar.jsx b/frontend/src/components/Calendar/MainCalendar.jsx
index 636aeef..2e90d98 100644
--- a/frontend/src/components/Calendar/MainCalendar.jsx
+++ b/frontend/src/components/Calendar/MainCalendar.jsx
@@ -1 +1,183 @@
-// ...file truncated in this snippet — only the toolbar area is shown changed
+import { useRef, useState, useCallback, useEffect } from 'react'
+import FullCalendar from '@fullcalendar/react'
+import dayGridPlugin from '@fullcalendar/daygrid'
+import timeGridPlugin from '@fullcalendar/timegrid'
+import interactionPlugin from '@fullcalendar/interaction'
+import useProjectStore from '../../store/useProjectStore'
+import useFocusStore from '../../store/useFocusStore'
+import useUIStore from '../../store/useUIStore'
+import useToastStore from '../../store/useToastStore'
+import { updateDeliverable, deleteDeliverable } from '../../api/deliverables'
+import DeliverableModal from '../Deliverables/DeliverableModal'
+import ContextMenu from '../UI/ContextMenu'
+import EventTooltip from './EventTooltip'
+import WorkloadHeatmap from './WorkloadHeatmap'
+
+export default function MainCalendar({ onCalendarReady }) {
+ const calRef = useRef(null)
+ const { projects, updateDeliverable: storeUpdate, removeDeliverable } = useProjectStore()
+ const openFocus = useFocusStore(s => s.openFocus)
+ const { showHeatmap, toggleHeatmap } = useUIStore()
+ const addToast = useToastStore(s => s.addToast)
+
+ const [modal, setModal] = useState({ open: false, deliverable: null, defaultDate: '' })
+ const [contextMenu, setContextMenu] = useState(null)
+ const [tooltip, setTooltip] = useState(null)
+
+ // Expose calendar API to App.jsx for keyboard shortcuts
+ useEffect(() => {
+ if (calRef.current && onCalendarReady) {
+ onCalendarReady(calRef.current.getApi())
+ }
+ }, [])
+
+ const events = projects.flatMap(p =>
+ (p.deliverables || []).map(d => ({
+ id: String(d.id),
+ title: `${p.name}: ${d.title}`,
+ start: d.due_date,
+ allDay: true,
+ backgroundColor: p.color,
+ borderColor: p.color,
+ extendedProps: { deliverableId: d.id, projectId: p.id },
+ }))
+ )
+
+ const getCtx = (projectId, deliverableId) => {
+ const project = projects.find(p => p.id === projectId)
+ const deliverable = project?.deliverables.find(d => d.id === deliverableId)
+ return { project, deliverable }
+ }
+
+ const handleEventClick = useCallback(({ event }) => {
+ const { deliverableId, projectId } = event.extendedProps
+ openFocus(projectId, deliverableId)
+ }, [openFocus])
+
+ // Drag-and-drop with 30-second undo toast
+ const handleEventDrop = useCallback(async ({ event, oldEvent }) => {
+ const { deliverableId } = event.extendedProps
+ const newDate = event.startStr.substring(0, 10)
+ const oldDate = oldEvent.startStr.substring(0, 10)
+ storeUpdate(await updateDeliverable(deliverableId, { due_date: newDate }))
+ addToast({
+ message: `Moved to ${newDate}`,
+ duration: 30,
+ undoFn: async () => {
+ storeUpdate(await updateDeliverable(deliverableId, { due_date: oldDate }))
+ },
+ })
+ }, [storeUpdate, addToast])
+
+ // 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
+ const handleSelect = useCallback(({ startStr }) => {
+ setModal({ open: true, deliverable: null, defaultDate: startStr.substring(0, 10) })
+ }, [])
+
+ // Attach dblclick + contextmenu + tooltip via eventDidMount
+ const handleEventDidMount = useCallback(({ event, el }) => {
+ const { deliverableId, projectId } = event.extendedProps
+
+ el.addEventListener('mouseenter', (e) => {
+ const { project, deliverable } = getCtx(projectId, deliverableId)
+ setTooltip({ x: e.clientX, y: e.clientY, project, deliverable })
+ })
+ el.addEventListener('mouseleave', () => setTooltip(null))
+ el.addEventListener('mousemove', (e) => {
+ setTooltip(prev => prev ? { ...prev, x: e.clientX, y: e.clientY } : null)
+ })
+
+ el.addEventListener('dblclick', (e) => {
+ e.preventDefault(); e.stopPropagation()
+ setTooltip(null)
+ const { deliverable } = getCtx(projectId, deliverableId)
+ if (deliverable) setModal({ open: true, deliverable, defaultDate: '' })
+ })
+
+ el.addEventListener('contextmenu', (e) => {
+ e.preventDefault(); e.stopPropagation()
+ setTooltip(null)
+ const { project, deliverable } = getCtx(projectId, deliverableId)
+ if (!deliverable) return
+ 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') }] : []),
+ { separator: true },
+ { icon: '✕', label: 'Delete Deliverable', danger: true,
+ action: async () => {
+ if (window.confirm(`Delete "${deliverable.title}"?`)) {
+ await deleteDeliverable(deliverableId); removeDeliverable(deliverableId)
+ }
+ }
+ },
+ ],
+ })
+ })
+ }, [projects, openFocus])
+
+ return (
+ e.preventDefault()}>
+ {/* View toggle toolbar */}
+
+
+ {showHeatmap ? '← Calendar' : '⬡ Heatmap'}
+
+
+
+ {/* Main content area */}
+
+ {showHeatmap ? (
+
+ ) : (
+
+
+
+ )}
+
+
+
setModal({ open: false, deliverable: null, defaultDate: '' })}
+ deliverable={modal.deliverable}
+ defaultDate={modal.defaultDate}
+ />
+
+ {contextMenu && (
+ setContextMenu(null)} />
+ )}
+
+
+
+ )
+}