Overview
ScheduleTimelineBlock provides a visual timeline interface for managing project phases. It includes two views: Calendar (for date-based SYNC phases) and Journeys (for day-based ASYNC phases). Both views support interactive drag operations for creating, moving, and resizing phases.
Key Features
- Tabbed interface with Calendar and Journeys views
- Drag-to-create: draw a new phase by dragging on empty space
- Drag-to-move: reposition phases by dragging them
- Drag-to-resize: adjust start/end by dragging edge handles
- Snap-to-day boundaries for precise positioning
- Visual feedback with ghost preview and cursor tooltip
When to Use
- Visualizing project phase schedules in a Gantt-style timeline
- Managing calendar-based phases with specific start and end dates
- Managing journey phases with relative day ranges (Day 1-7, Day 8-14, etc.)
- Desktop admin interfaces requiring direct manipulation of schedules
Drag Interactions
Create
Drag on empty space to create a new phase
Move
Drag a phase to move it
Hold Shift to move all subsequent phases together
Resize Start
Drag the left edge to change start date
Resize End
Drag the right edge to change end date
Interactive Examples
Calendar Timeline
Gantt-style timeline for SYNC phases with date-based positioning. Try dragging to create, move, or resize phases.
import { CalendarTimeline } from '@/ui/blocks';
<CalendarTimeline
phases={calendarPhases}
onPhaseClick={(id) => console.log('Clicked:', id)}
onCreatePhase={({ startsAt, endsAt }) => {
// Open create dialog with pre-filled dates
openCreateDialog({ startsAt, endsAt });
}}
onUpdatePhase={(id, { startsAt, endsAt }) => {
// Update phase dates
updatePhase(id, { startsAt, endsAt });
}}
/>Journey Timeline
Timeline for ASYNC phases using relative day numbers. Each user experiences these phases based on their start date.
Gated Timeline
Sequential phases unlocked by completing all resources in the previous phase. Drag to reorder.
| # | Phase | Resources | Audience | |
|---|---|---|---|---|
| 1 | Orientation Module | No resources | All users | |
| 2 | Core Training | No resources | All users | |
| 3 | Advanced Topics | No resources | 1 tags | |
| 4 | Certification Exam | No resources | All users |
Full Block with Tabs
Complete ScheduleTimelineBlock with tabbed Calendar and Journeys views.
Read-Only Mode
Timeline in read-only mode for displaying schedules without edit capabilities.
Props Reference
ScheduleTimelineBlock Props
| Prop | Type | Default | Description |
|---|---|---|---|
schedule | ScheduleWithPhases | null | required | Schedule object with timezone and phases |
onPhaseClick | (phaseId: string) => void | - | Handler called when a phase is clicked |
isLoading | boolean | false | Show skeleton loading state |
readOnly | boolean | false | Disable all interactive features |
className | string | - | Additional CSS class name |
CalendarTimeline / JourneyTimeline Props
| Prop | Type | Default | Description |
|---|---|---|---|
phases | PhaseWithJourneyCount[] | required | Array of phases to display on the timeline |
onPhaseClick | (phaseId: string) => void | - | Handler called when a phase is clicked |
onCreatePhase | (data: { startsAt: Date; endsAt: Date }) => void | - | Handler called when user drags to create a new phase |
onUpdatePhase | (phaseId: string, updates) => void | - | Handler called when user moves or resizes a phase |
onCascadeMove | (updates: Array<{ phaseId: string; startsAt: Date; endsAt: Date }>) => void | - | Handler called when user Shift+drags to move multiple phases |
readOnly | boolean | false | Disable all interactive features |
Usage
import { ScheduleTimelineBlock } from '@/ui/blocks';
// Schedule data from API
const schedule = {
id: 'schedule-1',
timezone: 'America/Los_Angeles',
phases: [
{
id: 'phase-1',
name: 'Onboarding',
mode: 'SYNC',
startsAt: new Date('2024-12-01'),
endsAt: new Date('2024-12-14'),
},
{
id: 'phase-2',
name: 'Exploration',
mode: 'ASYNC',
startDay: 1,
endDay: 7,
},
],
};
<ScheduleTimelineBlock
schedule={schedule}
onPhaseClick={(phaseId) => openEditor(phaseId)}
/>