feat(time-blocks): Add comprehensive time blocking system with contracts

- Add TimeBlock and Holiday models with recurrence support (one-time, weekly, monthly, yearly, holiday)
- Implement business-level and resource-level blocking with hard/soft block types
- Add multi-select holiday picker for bulk holiday blocking
- Add calendar overlay visualization with distinct colors:
  - Business blocks: Red (hard) / Yellow (soft)
  - Resource blocks: Purple (hard) / Cyan (soft)
- Add month view resource indicators showing 1/n width per resource
- Add yearly calendar view for block overview
- Add My Availability page for staff self-service
- Add contracts module with templates, signing flow, and PDF generation
- Update scheduler with click-to-day navigation in week view

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-04 17:19:12 -05:00
parent cf91bae24f
commit 8d0cc1e90a
63 changed files with 11863 additions and 61 deletions

View File

@@ -15,6 +15,8 @@ import {
HelpCircle,
Clock,
Plug,
FileSignature,
CalendarOff,
} from 'lucide-react';
import { Business, User } from '../types';
import { useLogout } from '../hooks/useAuth';
@@ -121,6 +123,14 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
isCollapsed={isCollapsed}
locked={!canUse('plugins') || !canUse('tasks')}
/>
{(role === 'staff' || role === 'resource') && (
<SidebarItem
to="/my-availability"
icon={CalendarOff}
label={t('nav.myAvailability', 'My Availability')}
isCollapsed={isCollapsed}
/>
)}
</SidebarSection>
{/* Manage Section - Staff+ */}
@@ -145,12 +155,26 @@ const Sidebar: React.FC<SidebarProps> = ({ business, user, isCollapsed, toggleCo
isCollapsed={isCollapsed}
/>
{canViewAdminPages && (
<SidebarItem
to="/staff"
icon={Users}
label={t('nav.staff')}
isCollapsed={isCollapsed}
/>
<>
<SidebarItem
to="/staff"
icon={Users}
label={t('nav.staff')}
isCollapsed={isCollapsed}
/>
<SidebarItem
to="/contracts"
icon={FileSignature}
label={t('nav.contracts', 'Contracts')}
isCollapsed={isCollapsed}
/>
<SidebarItem
to="/time-blocks"
icon={CalendarOff}
label={t('nav.timeBlocks', 'Time Blocks')}
isCollapsed={isCollapsed}
/>
</>
)}
</SidebarSection>
)}