feat: lessons station + technician workbench + polish
All checks were successful
CI / ci (pull_request) Successful in 26s
CI / e2e (pull_request) Successful in 1m8s

Phase 3: Technician workbench
- Focused single-ticket view with Work, Parts, Photos, Notes sections
- Template quick-add for line items, inline add/delete
- Ticket selector for multiple assigned tickets

Phase 4: Lessons desk view
- Today overview: all instructors' sessions, group by time/instructor
- Quick check-in (attended/missed/cancelled) buttons
- Highlights upcoming and overdue sessions
- Schedule view: weekly grid with instructor filter, open slots

Phase 5: Lessons instructor view
- My Sessions (today) + Week calendar sub-views
- Session detail with attendance, notes, plan items
- Week calendar with session blocks, click to open detail dialog

Phase 6: Polish
- Permission-based routing: desk vs tech/instructor views
- Build and lint clean

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
ryan
2026-04-06 01:46:51 +00:00
parent 0411df57eb
commit 3b0daeae0c
7 changed files with 747 additions and 11 deletions

View File

@@ -0,0 +1,56 @@
import { useState } from 'react'
import { usePOSStore } from '@/stores/pos.store'
import { Button } from '@/components/ui/button'
import { CalendarDays, CalendarRange } from 'lucide-react'
import { LessonsTodayOverview } from './lessons-today-overview'
import { LessonsWeekView } from './lessons-week-view'
interface LessonsInstructorViewProps {
canEdit: boolean
}
export function LessonsInstructorView({ canEdit }: LessonsInstructorViewProps) {
const [subView, setSubView] = useState<'today' | 'week'>('today')
const cashier = usePOSStore((s) => s.cashier)
// TODO: Map cashier user ID to instructor ID
// For now, the instructor view shows the same data as desk view
// but filtered by the logged-in user's instructor record
return (
<div className="flex flex-col h-full">
{/* Sub-view toggle */}
<div className="flex items-center gap-1 px-3 py-2 border-b border-border shrink-0 bg-card/50">
<Button
variant={subView === 'today' ? 'default' : 'ghost'}
size="sm"
className="h-8 gap-1.5"
onClick={() => setSubView('today')}
>
<CalendarDays className="h-3.5 w-3.5" />
My Sessions
</Button>
<Button
variant={subView === 'week' ? 'default' : 'ghost'}
size="sm"
className="h-8 gap-1.5"
onClick={() => setSubView('week')}
>
<CalendarRange className="h-3.5 w-3.5" />
Week
</Button>
{cashier && (
<span className="text-xs text-muted-foreground ml-auto">
{cashier.firstName} {cashier.lastName}
</span>
)}
</div>
{/* Content */}
<div className="flex-1 min-h-0 overflow-hidden">
{subView === 'today' && <LessonsTodayOverview canEdit={canEdit} />}
{subView === 'week' && <LessonsWeekView canEdit={canEdit} />}
</div>
</div>
)
}