Skip to main content

SafePath Training — UI Pages Implementation Plan

Overview

The SafePath Training module backend is fully built across 6 phases (1A–1F) with 45 API routes, complete TypeScript types in src/types/safepath.ts, and frontend API client functions in src/services/api/safepath.api.ts. However, no UI pages, routes, or sidebar navigation exist yet.

This document defines a phased approach to build the complete SafePath UI, following existing patterns from ChemIQ, AdminHQ, and Plan Builder modules.

Existing Infrastructure

LayerStatusLocation
Backend APIComplete (45 routes)tellus-ehs-hazcom-service/app/api/v1/safepath/
TypeScript typesComplete (35+ interfaces)tellus-ehs-hazcom-ui/src/types/safepath.ts
API client functionsComplete (28+ functions)tellus-ehs-hazcom-ui/src/services/api/safepath.api.ts
UI pagesNot started
Sidebar integrationNot started
Route registrationNot started

UI Patterns to Follow

All SafePath pages must follow established patterns:

  • Route registration: Lazy-loaded via const XPage = lazy(() => import(...)) in App.tsx, wrapped in <ProtectedRoute>
  • Page wrapper: <MainLayout> component (accepts children and optional disableScroll)
  • Sidebar: Dedicated SidebarSafePath.tsx component (pattern from SidebarChemIQ.tsx) with feature code → icon/path/permission mapping
  • Auth state: const { user, currentSite, accessToken } = useAppSelector((state) => state.auth)
  • Token: const token = accessToken?.replace(/"/g, '') || ''
  • IDs: const companyId = user?.last_company_id || '', const userId = user?.user_id || ''
  • Data fetching: useCallback + useEffect pattern with loading/error/empty states
  • Icons: Lucide React
  • Notifications: React Hot Toast
  • Permissions: <PermissionGate> component for conditional rendering

Phase Dependency Graph

Phase 2A (Foundation) ──┬──→ Phase 2B (Dashboard)
├──→ Phase 2C (Course List + Detail) ──→ Phase 2D (Course Editor)
├──→ Phase 2E (Matrix & Reports)
├──→ Phase 2F (Assignments & Certifications)
└──→ Phase 2G (Quickstart)


Phase 2H (Polish)

Phases 2B–2G can run in parallel after 2A. Phase 2D depends on 2C. Phase 2H depends on all others.


Phase 2A: Foundation — Routing, Sidebar & Skeleton Pages

Goal: Wire up the entire SafePath section so every page is navigable from the sidebar, even with placeholder content. Establishes URL structure and proves routing/sidebar integration end-to-end.

Files to Create

1. src/components/sidebar/SidebarSafePath.tsx (NEW)

Sidebar section component following the SidebarChemIQ.tsx pattern exactly.

  • Props: features, isExpanded, isInSafePathPath, isPathActive, onToggle, onItemClick
  • Module icon: GraduationCap (from lucide-react, already in Sidebar.tsx icon map)
  • Active color: accent-coral (SafePath module color) or fallback to accent-pink
  • Feature code → navigation mapping:
Feature CodeIconPathPermission
DASHBOARDLayoutDashboard/safepath/dashboardsafepath:dashboard:*
COURSESBookOpen/safepath/coursessafepath:courses:*
ASSIGNMENTSClipboardList/safepath/assignmentssafepath:assignments:*
CERTIFICATIONSAward/safepath/certificationssafepath:certifications:*
MATRIXGrid3X3/safepath/matrixsafepath:matrix:*
REPORTSFileBarChart/safepath/reportssafepath:reports:*
QUICKSTARTRocket/safepath/quickstartsafepath:quickstart:*

2. Skeleton Page Files (9 new files)

Each skeleton page is a default-export React component wrapping <MainLayout> with a coral gradient header and placeholder body. Pattern:

import React from 'react';
import { MainLayout } from '../../../components/MainLayout';
import { GraduationCap } from 'lucide-react';

const SafePathDashboardPage: React.FC = () => {
return (
<MainLayout>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 space-y-6">
{/* Page header */}
<div className="bg-gradient-to-r from-pink-500 via-rose-500 to-orange-400 rounded-xl p-6 text-white">
<div className="flex items-center gap-3">
<GraduationCap className="h-7 w-7" />
<div>
<h1 className="text-2xl font-bold">Training Dashboard</h1>
<p className="text-pink-100 text-sm mt-1">SafePath Training Management</p>
</div>
</div>
</div>
{/* Placeholder content */}
<div className="bg-white rounded-lg border border-border-light p-12 text-center">
<GraduationCap className="h-12 w-12 text-gray-300 mx-auto mb-4" />
<p className="text-text-muted text-lg">Coming soon</p>
<p className="text-text-muted text-sm mt-1">This page is under development.</p>
</div>
</div>
</MainLayout>
);
};

export default SafePathDashboardPage;
#File PathPage Title
1src/pages/safepath/dashboard/index.tsxTraining Dashboard
2src/pages/safepath/courses/index.tsxCourse Library
3src/pages/safepath/courses/CourseDetailPage.tsxCourse Details
4src/pages/safepath/courses/CourseEditorPage.tsxCourse Editor
5src/pages/safepath/assignments/index.tsxTraining Assignments
6src/pages/safepath/certifications/index.tsxCertifications
7src/pages/safepath/matrix/index.tsxTraining Matrix
8src/pages/safepath/reports/index.tsxTraining Reports
9src/pages/safepath/quickstart/index.tsxQuickstart Wizard

Files to Modify

3. src/components/Sidebar.tsx

Add SafePath module support:

// Import
import { SidebarSafePath } from './sidebar/SidebarSafePath';

// State (add alongside existing module states)
const [isSafePathExpanded, setIsSafePathExpanded] = useState(false);

// Module extraction (add alongside existing module lookups)
const safePathModule = modules.find(m => m.module_code === 'SAFEPATH');
const safePathFeatures = safePathModule?.features || [];

// Auto-expand effect (add alongside existing auto-expand effects)
React.useEffect(() => {
if (location.pathname.startsWith('/safepath')) {
setIsSafePathExpanded(true);
}
}, [location.pathname]);

// Render (add after Plan Builder section, before generic module loop)
<PermissionGate permission="safepath:*">
<SidebarSafePath
features={safePathFeatures}
isExpanded={isSafePathExpanded}
isInSafePathPath={location.pathname.startsWith('/safepath')}
isPathActive={isPathActive}
onToggle={() => setIsSafePathExpanded(!isSafePathExpanded)}
onItemClick={() => setIsMobileOpen(false)}
/>
</PermissionGate>

4. src/App.tsx

Add lazy imports and routes:

// Lazy-loaded SafePath pages (add after Plan Builder lazy imports)
const SafePathDashboardPage = lazy(() => import('./pages/safepath/dashboard'));
const SafePathCoursesPage = lazy(() => import('./pages/safepath/courses'));
const CourseDetailPage = lazy(() => import('./pages/safepath/courses/CourseDetailPage'));
const CourseEditorPage = lazy(() => import('./pages/safepath/courses/CourseEditorPage'));
const SafePathAssignmentsPage = lazy(() => import('./pages/safepath/assignments'));
const SafePathCertificationsPage = lazy(() => import('./pages/safepath/certifications'));
const SafePathMatrixPage = lazy(() => import('./pages/safepath/matrix'));
const SafePathReportsPage = lazy(() => import('./pages/safepath/reports'));
const SafePathQuickstartPage = lazy(() => import('./pages/safepath/quickstart'));

// Routes (add after Plan Builder routes, before AdminHQ routes)
{/* SafePath Training Routes */}
<Route path="/safepath" element={<Navigate to="/safepath/dashboard" replace />} />
<Route path="/safepath/dashboard" element={<ProtectedRoute><SafePathDashboardPage /></ProtectedRoute>} />
<Route path="/safepath/courses" element={<ProtectedRoute><SafePathCoursesPage /></ProtectedRoute>} />
<Route path="/safepath/courses/new" element={<ProtectedRoute><CourseEditorPage /></ProtectedRoute>} />
<Route path="/safepath/courses/:courseId" element={<ProtectedRoute><CourseDetailPage /></ProtectedRoute>} />
<Route path="/safepath/courses/:courseId/edit" element={<ProtectedRoute><CourseEditorPage /></ProtectedRoute>} />
<Route path="/safepath/assignments" element={<ProtectedRoute><SafePathAssignmentsPage /></ProtectedRoute>} />
<Route path="/safepath/certifications" element={<ProtectedRoute><SafePathCertificationsPage /></ProtectedRoute>} />
<Route path="/safepath/matrix" element={<ProtectedRoute><SafePathMatrixPage /></ProtectedRoute>} />
<Route path="/safepath/reports" element={<ProtectedRoute><SafePathReportsPage /></ProtectedRoute>} />
<Route path="/safepath/quickstart" element={<ProtectedRoute><SafePathQuickstartPage /></ProtectedRoute>} />

Verification Checklist — Phase 2A

  • App compiles without TypeScript errors
  • Navigating to /safepath redirects to /safepath/dashboard
  • All 10 SafePath routes render their skeleton pages
  • Sidebar shows "SafePath" section with GraduationCap icon
  • Sidebar auto-expands when URL starts with /safepath
  • Each sidebar item navigates to correct route
  • Active sidebar item highlights correctly
  • Permission gating: section hidden if user lacks safepath:* permission
  • Lazy loading works (PageLoader spinner appears during load)

Dependencies

None (this is the foundation phase).


Phase 2B: Dashboard Pages (Employee + Admin)

Goal: Build the dual-view Training Dashboard — Employee Dashboard for regular users showing personal training status, and Admin Dashboard for coordinators/admins showing team compliance metrics.

Files to Create

1. src/pages/safepath/dashboard/components/StatCard.tsx (NEW)

Reusable stat card component. Props: { icon: LucideIcon, label: string, value: number | string, color: string, subtitle?: string, onClick?: () => void }.

Styled as a rounded card with icon, large value, label text, and optional click handler for navigation.

2. src/pages/safepath/dashboard/components/EmployeeDashboard.tsx (NEW)

Employee-facing dashboard using getMyDashboard() API.

Sections:

  • Assignment Status Summary: 6 stat cards (pending, in_progress, completed, overdue, expired, total) from AssignmentStatusCounts
  • Upcoming Due: Table of MyAssignmentItem[] — course title, due date, priority badge, progress bar, status badge
  • Overdue Assignments: Red-accented alert list with days-overdue count
  • Recent Completions: Green-accented list of recently completed courses
  • Expiring Certifications: Warning list of MyCertificationItem[] with days-until-expiry countdown
  • Total Hours: Stat card showing total_hours_completed

Data fetching: useCallback + useEffect with getMyDashboard(token, userId, companyId)

3. src/pages/safepath/dashboard/components/AdminDashboard.tsx (NEW)

Admin-facing dashboard using getAdminDashboard() API.

Sections:

  • Company Summary: Assignment count cards from company_summary
  • Completion Rates: 30-day and 90-day completion rate cards with progress bars
  • Team Compliance Table: Sortable table of TeamComplianceItem[] — employee name, email, assigned/completed/overdue counts, compliance percentage bar
  • Course Completions Table: CourseCompletionItem[] with completion rates, average scores
  • Site Compliance: Bar chart of SiteComplianceItem[] (if multiple sites)
  • Overdue Alerts: Priority-sorted list of OverdueAlertItem[] (top 20)
  • Certification Summary: Cards for certifications_expiring_30d and certifications_expired
  • Site Filter: Dropdown that passes site_id to getAdminDashboard()

Files to Modify

4. src/pages/safepath/dashboard/index.tsx (REPLACE skeleton)

  • Detects admin vs employee via permissions or role check
  • Shows tab switcher for admin users (Employee View / Admin View)
  • Renders <EmployeeDashboard> or <AdminDashboard> accordingly
  • Standard auth state extraction pattern

Verification Checklist — Phase 2B

  • Dashboard loads without errors
  • Employee view shows assignment status, upcoming due, overdue, certifications
  • Admin view shows team compliance, course completions, site compliance, overdue alerts
  • Site filter on admin dashboard triggers re-fetch
  • Loading spinner during data fetch
  • Error state with retry button on API failure
  • Empty states with meaningful messages
  • Tab switching works for admin users
  • Stat cards show correct numbers

Dependencies

Phase 2A (routing and skeleton pages).


Phase 2C: Course Library — List and Detail Views

Goal: Build the read-only course browsing experience: filterable course list and full course detail page with lessons and quizzes.

Files to Create

1. src/pages/safepath/courses/components/CourseStatusBadge.tsx (NEW)

Small component rendering status as colored pill badge: Draft (gray), Published (green), Archived (amber).

2. src/pages/safepath/courses/components/CourseListTable.tsx (NEW)

Course list using getCourses() API.

Features:

  • Filter Bar: Search input (title), status dropdown (all/draft/published/archived), category dropdown (from getCategories())
  • Table: CourseListItem[] with title, category, OSHA standard ref, duration, <CourseStatusBadge>, version number, lesson/quiz/assignment counts, dates
  • Sort: Clickable column headers (title, status, created_at)
  • Pagination: Page controls (previous/next, page indicator)
  • Actions: "Create Course" button navigates to /safepath/courses/new
  • Row click: Navigates to /safepath/courses/:courseId

3. src/pages/safepath/courses/components/LessonCard.tsx (NEW)

Renders a lesson in the course detail view. Shows: lesson type icon (video/pdf/slides/text/external_link), title, sort order, completion threshold, asset count. Read-only.

4. src/pages/safepath/courses/components/QuizCard.tsx (NEW)

Renders a quiz with questions in the detail view. Shows: quiz title, question list with type indicators (MCQ/true-false/matching), option list, explanations. Read-only.

Files to Modify

5. src/pages/safepath/courses/index.tsx (REPLACE skeleton)

  • Coral gradient header with "Create Course" button
  • Renders <CourseListTable> as main content

6. src/pages/safepath/courses/CourseDetailPage.tsx (REPLACE skeleton)

  • Extracts courseId from useParams()
  • Fetches getCourse(token, userId, companyId, courseId)
  • Displays: course metadata, lessons via <LessonCard>, quizzes via <QuizCard>
  • Action Bar (permission-gated, status-dependent):
    • Draft → "Publish" button (calls publishCourse())
    • Published → "Archive" + "New Version" buttons
    • Archived → "New Version" button
  • "Edit" button → /safepath/courses/:courseId/edit
  • Back button → /safepath/courses

Verification Checklist — Phase 2C

  • Course list loads with paginated courses
  • Search filter works (debounced, resets pagination)
  • Status and category filters work
  • Pagination works (previous/next)
  • Clicking a course navigates to detail page
  • Course detail shows metadata, lessons, quizzes
  • Publish/Archive/New Version buttons appear per status
  • Action buttons call correct APIs and refresh
  • Loading/error/empty states work
  • "Create Course" button navigates to editor

Dependencies

Phase 2A (routing).


Phase 2D: Course Editor — Create/Edit Wizard

Goal: Multi-step wizard for creating and editing courses, adding lessons, creating quizzes.

Files to Create

1. src/pages/safepath/courses/components/StepIndicator.tsx (NEW)

Step progress indicator: numbered circles connected by lines. States: completed (green check), current (coral filled), upcoming (gray outlined).

2. src/pages/safepath/courses/components/CourseDetailsForm.tsx (NEW)

Step 1 form. Fields for CourseCreatePayload: title (required), description, category (dropdown from getCategories()), OSHA standard ref, estimated duration, passing score percent, max retakes, locale. Controlled form state with validation.

3. src/pages/safepath/courses/components/LessonEditor.tsx (NEW)

Step 2 form:

  • List of existing lessons with up/down arrows for sort order
  • "Add Lesson" opens inline form: title, lesson_type dropdown, content, sort_order, completion_threshold_percent
  • Edit/Delete per lesson
  • Calls addLesson(), updateLesson(), deleteLesson() APIs

4. src/pages/safepath/courses/components/QuizEditor.tsx (NEW)

Step 3 form:

  • "Add Quiz" button → addQuiz() API
  • Per quiz: title, list of questions
  • "Add Question" opens inline form: question_type dropdown, question_text, dynamic options list (add/remove with is_correct checkbox), explanation
  • Edit/Delete per question
  • Calls addQuestion(), updateQuestion(), deleteQuestion() APIs

5. src/pages/safepath/courses/components/CourseReviewStep.tsx (NEW)

Step 4: Read-only summary. Shows all course data, lessons, quizzes. Validation warnings (e.g., "No lessons added", "Quiz has no questions").

6. src/pages/safepath/courses/components/CourseEditorWizard.tsx (NEW)

Container component orchestrating steps 1–4 with <StepIndicator>. Manages:

  • Step navigation (Back/Next)
  • "Save Draft" and "Publish" buttons
  • Create mode: Step 1 calls createCourse() to get courseId, then steps 2–3 use it
  • Edit mode: Step 1 calls updateCourse(), steps 2–3 use existing courseId

Files to Modify

7. src/pages/safepath/courses/CourseEditorPage.tsx (REPLACE skeleton)

  • Checks URL params: courseId present → edit mode (loads existing course), absent → create mode
  • Renders <CourseEditorWizard> with initial data if editing

Verification Checklist — Phase 2D

  • "Create Course" navigates to /safepath/courses/new
  • Step indicator shows all steps, highlights current
  • Course details form validates required fields
  • Category dropdown populated from API
  • After step 1 "Next", course created via createCourse() API
  • Lesson editor: add, edit, delete, reorder works
  • Quiz editor: add quiz, add/edit/delete questions works
  • Question options: add/remove options, toggle is_correct
  • Review step shows complete summary
  • "Save Draft" and "Publish" buttons work
  • Edit mode loads existing course data into wizard
  • Step navigation preserves data
  • Toast notifications on success/error

Dependencies

Phase 2C (course list for navigation context).


Phase 2E: Training Matrix & Reports

Goal: Build the training matrix grid view and the three report pages with export functionality.

Files to Create

1. src/pages/safepath/matrix/components/MatrixGrid.tsx (NEW)

Employee-by-course compliance matrix using getTrainingMatrix() API.

Features:

  • Column Headers: Course titles from MatrixCourseHeader[] — rotated for compact display, tooltip with category/OSHA ref
  • Row Headers: Employee names from MatrixEmployeeRow[] with email, site, role
  • Cells: Color-coded by MatrixCellStatus.status:
    • required → blue
    • in_progress → amber
    • completed → green
    • overdue → red
    • expired → gray
    • not_assigned → empty/dash
  • Filters: Site, role, course, category dropdowns + status filter
  • Summary: Overall compliance percentage
  • Export: Button using getTrainingMatrixExportUrl() → opens download
  • Layout: Horizontal scroll with sticky first column (employee name)

2. src/pages/safepath/matrix/components/MatrixCellTooltip.tsx (NEW)

Tooltip on cell hover showing: assignment_id, due_date, completion_date, score_percent.

3. src/pages/safepath/reports/components/CompletionReportTab.tsx (NEW)

Completion report using getCompletionReport() API.

  • Filters: Site, course, status, date range (date_from/date_to)
  • Summary Cards: Counts from AssignmentStatusCounts
  • Table: CompletionReportRow[] — employee, course, dates, status, score, passed, delivery method, instructor
  • Export: CSV/PDF/XLSX buttons via getCompletionReportExportUrl()

4. src/pages/safepath/reports/components/TranscriptTab.tsx (NEW)

Individual transcript using getIndividualTranscript() API.

  • Employee Selector: Dropdown/search to pick a user
  • Header: Employee name, email, company, generated date
  • Stats: total_completed, total_in_progress, total_hours, certifications_active/expiring
  • Table: IndividualTranscriptRow[] — course, category, dates, scores, certificate info
  • Export: CSV/PDF via getTranscriptExportUrl()

5. src/pages/safepath/reports/components/CertificationReportTab.tsx (NEW)

Certification status report using getCertificationReport() API.

  • Filters: Site, status (active/expiring/expired)
  • Summary: total_active, total_expiring_soon, total_expired
  • Table: CertificationStatusRow[] — employee, cert type, OSHA ref, dates, status, days until expiry, source
  • Export: CSV/PDF via getCertificationReportExportUrl()

6. src/pages/safepath/reports/components/ReportExportButton.tsx (NEW)

Reusable export button with format dropdown. Constructs download URL and opens in new tab.

Files to Modify

7. src/pages/safepath/matrix/index.tsx (REPLACE skeleton)

Gradient header, filter bar, renders <MatrixGrid>.

8. src/pages/safepath/reports/index.tsx (REPLACE skeleton)

Tab navigation with 3 tabs: "Completion Report", "Individual Transcript", "Certification Status". Default: Completion Report.

Verification Checklist — Phase 2E

  • Matrix loads and displays employee × course grid
  • Matrix cells color-coded by status
  • Matrix filters work (site, role, course, category)
  • Matrix horizontal scroll with sticky first column
  • Matrix export downloads file
  • Completion report loads with filters and table
  • Transcript loads for selected employee
  • Certification report loads with filters
  • All export buttons generate correct URLs
  • Report tabs switch correctly
  • Loading/error/empty states work

Dependencies

Phase 2A (routing).


Phase 2F: Assignments & Certifications

Goal: Build assignment management (list, create, bulk assign) and certification tracking (list, create, track expirations).

Types to Add

Add to src/types/safepath.ts:

// Assignment CRUD types
export interface AssignmentListItem {
assignment_id: string;
user_id: string;
employee_name: string;
employee_email: string;
course_id: string;
course_title: string;
assigned_by: string;
assigned_date: string;
due_date: string;
priority: string;
status: string;
progress_percent: number;
delivery_method: string;
score_percent: number | null;
completed_at: string | null;
}

export interface AssignmentListResponse {
items: AssignmentListItem[];
total: number;
page: number;
page_size: number;
}

export interface AssignmentCreatePayload {
user_id: string;
course_id: string;
due_date: string;
priority?: string;
delivery_method?: string;
}

export interface BulkAssignPayload {
user_ids: string[];
course_id: string;
due_date: string;
priority?: string;
}

// Certification CRUD types
export interface CertificationType {
certification_type_id: string;
name: string;
osha_standard_ref: string | null;
validity_months: number | null;
is_system: boolean;
}

export interface CertificationItem {
certification_id: string;
user_id: string;
employee_name: string;
employee_email: string;
certification_type_name: string;
issue_date: string;
expiration_date: string | null;
status: string;
source: string;
certificate_number: string | null;
}

export interface CertificationCreatePayload {
user_id: string;
certification_type_id: string;
issue_date: string;
expiration_date?: string;
certificate_number?: string;
source?: string;
}

API Functions to Add

Add to src/services/api/safepath.api.ts:

// Assignments
getAssignments(token, userId, companyId, params?)
getAssignment(token, userId, companyId, assignmentId)
createAssignment(token, userId, companyId, data)
bulkCreateAssignments(token, userId, companyId, data)
updateAssignment(token, userId, companyId, assignmentId, data)
startAssignment(token, userId, companyId, assignmentId)
submitAssignmentResult(token, userId, companyId, assignmentId, data)

// Auto-Assignment Rules
getAutoAssignRules(token, userId, companyId)
createAutoAssignRule(token, userId, companyId, data)
updateAutoAssignRule(token, userId, companyId, ruleId, data)
deleteAutoAssignRule(token, userId, companyId, ruleId)

// Classroom Sessions
createClassroomSession(token, userId, companyId, data)
updateClassroomSession(token, userId, companyId, sessionId, data)

// Certification Types
getCertificationTypes(token, userId, companyId)
createCertificationType(token, userId, companyId, data)

// Certifications CRUD
getCertifications(token, userId, companyId, params?)
createCertification(token, userId, companyId, data)
updateCertification(token, userId, companyId, certId, data)
deleteCertification(token, userId, companyId, certId)

Also update src/services/api/index.ts to import and re-export these functions.

Files to Create

1. src/pages/safepath/assignments/components/AssignmentList.tsx (NEW)

Assignment list using getAssignments():

  • Filters: Status, course, employee search, date range
  • Table: Rows with employee, course, dates, priority badge, status badge, progress bar
  • Actions: "Create Assignment" and "Bulk Assign" buttons

2. src/pages/safepath/assignments/components/CreateAssignmentModal.tsx (NEW)

Modal form: employee selector, course selector (published courses), due date, priority, delivery method. Submit → createAssignment().

3. src/pages/safepath/assignments/components/BulkAssignModal.tsx (NEW)

Modal: multi-select employee list, course selector, due date, priority. Submit → bulkCreateAssignments().

4. src/pages/safepath/certifications/components/CertificationList.tsx (NEW)

Certification list using getCertifications():

  • Filters: Status (active/expiring/expired), cert type, employee search
  • Table: Employee, type, dates, status badge, days-until-expiry
  • Color coding: Active (green), expiring (amber), expired (red)
  • Actions: "Add Certification" button

5. src/pages/safepath/certifications/components/AddCertificationModal.tsx (NEW)

Modal: employee selector, cert type selector (from getCertificationTypes()), issue date, expiration date, certificate number, source. Submit → createCertification().

6. src/pages/safepath/certifications/components/CertificationTypesPanel.tsx (NEW)

Collapsible panel showing certification types with "Add Type" button → createCertificationType().

Files to Modify

7. src/pages/safepath/assignments/index.tsx (REPLACE skeleton)

Header + <AssignmentList> with create/bulk modals.

8. src/pages/safepath/certifications/index.tsx (REPLACE skeleton)

Header + tabs: "Certifications" and "Certification Types". Each renders its component.

9. src/types/safepath.ts — Add types listed above.

10. src/services/api/safepath.api.ts — Add API functions listed above.

11. src/services/api/index.ts — Re-export new functions.

Verification Checklist — Phase 2F

  • Assignment list loads with filters and pagination
  • Create Assignment modal validates and submits
  • Bulk Assign modal allows multi-select and creates
  • Assignment status badges display correctly
  • Certification list loads with filters
  • Add Certification modal creates successfully
  • Certification types panel shows types
  • Expiring/expired certifications highlighted
  • Toast notifications on all CRUD operations
  • Loading/error/empty states work

Dependencies

Phase 2A (routing). Phase 2C helps (course dropdowns for assignment creation).


Phase 2G: Quickstart Wizard

Goal: Post-onboarding quickstart wizard helping new administrators set up their training program with starter templates.

Files to Create

1. src/pages/safepath/quickstart/components/QuickstartChecklist.tsx (NEW)

Checklist using getQuickstartChecklist() API:

  • Progress bar: completion_percent and estimated_minutes_remaining
  • Ordered QuickstartStep[] items: checkbox (completed=checked, disabled), title, description, "Optional" badge, action button linking to action_url
  • Animated check marks for completed steps

2. src/pages/safepath/quickstart/components/StarterTemplatesPanel.tsx (NEW)

Template selection using getStarterTemplates() API:

  • Grid of StarterTemplateItem[] cards: title, description, category, OSHA ref, duration, lesson count, has_quiz badge, selectable checkbox
  • "Import Selected" button → seedStarterTemplates() with selected template IDs
  • Success message with courses created count

3. src/pages/safepath/quickstart/components/QuickstartStatusBanner.tsx (NEW)

Dashboard banner using getQuickstartStatus():

  • If complete: hidden or "Setup Complete" badge
  • If incomplete: remaining steps count, "Continue Setup" button → /safepath/quickstart

Files to Modify

4. src/pages/safepath/quickstart/index.tsx (REPLACE skeleton)

  • Coral gradient header with rocket icon
  • Two-column: checklist (left) + templates (right)
  • If complete: congratulations message + link to dashboard
  • If incomplete: checklist + templates

5. src/pages/safepath/dashboard/index.tsx (ADD banner)

Add <QuickstartStatusBanner> at top of dashboard when quickstart is incomplete.

Verification Checklist — Phase 2G

  • Quickstart page loads with checklist and templates
  • Checklist shows correct completion per step
  • Progress bar accurate
  • Action buttons navigate to correct pages
  • Templates grid loads and displays cards
  • Selecting and importing creates courses
  • Success toast with course count
  • Courses page shows newly imported courses
  • Dashboard banner shows when incomplete
  • Banner hides when complete

Dependencies

Phase 2A (routing), Phase 2B (dashboard for banner), Phase 2C (courses page for verification).


Phase 2H: Polish, Cross-Linking & Integration

Goal: Final phase — connect pages with cross-navigation links, add reusable header component, ensure consistent UX.

Files to Create

1. src/pages/safepath/components/SafePathPageHeader.tsx (NEW)

Standardized header with coral gradient, icon, title, subtitle, optional action buttons. Replaces repeated inline gradient headers across all pages.

Files to Modify

2. All SafePath page files

  • Replace inline gradient headers with <SafePathPageHeader>
  • Add cross-navigation links:
    • Dashboard stat cards → relevant pages (overdue → assignments, certs → certifications)
    • Course detail "Assign" button → assignment creation with course pre-selected
    • Assignment rows → course detail
    • Report employee names → individual transcript
    • Matrix cells → assignment detail
    • Team compliance rows → transcript
  • Add "quick action" cards on dashboard: Create Course, Assign Training, View Reports, View Matrix

Verification Checklist — Phase 2H

  • Consistent header styling across all pages
  • All cross-navigation links work
  • Dashboard quick actions navigate correctly
  • Responsive design works on tablet/mobile
  • Back buttons work on detail pages
  • No dead links or broken navigation
  • Consistent loading/error/empty patterns

Dependencies

All previous phases (2A–2G).


Complete File Inventory

New Files (~40 total)

#FilePhase
1src/components/sidebar/SidebarSafePath.tsx2A
2src/pages/safepath/dashboard/index.tsx2A→2B
3src/pages/safepath/courses/index.tsx2A→2C
4src/pages/safepath/courses/CourseDetailPage.tsx2A→2C
5src/pages/safepath/courses/CourseEditorPage.tsx2A→2D
6src/pages/safepath/assignments/index.tsx2A→2F
7src/pages/safepath/certifications/index.tsx2A→2F
8src/pages/safepath/matrix/index.tsx2A→2E
9src/pages/safepath/reports/index.tsx2A→2E
10src/pages/safepath/quickstart/index.tsx2A→2G
11src/pages/safepath/dashboard/components/StatCard.tsx2B
12src/pages/safepath/dashboard/components/EmployeeDashboard.tsx2B
13src/pages/safepath/dashboard/components/AdminDashboard.tsx2B
14src/pages/safepath/courses/components/CourseStatusBadge.tsx2C
15src/pages/safepath/courses/components/CourseListTable.tsx2C
16src/pages/safepath/courses/components/LessonCard.tsx2C
17src/pages/safepath/courses/components/QuizCard.tsx2C
18src/pages/safepath/courses/components/StepIndicator.tsx2D
19src/pages/safepath/courses/components/CourseDetailsForm.tsx2D
20src/pages/safepath/courses/components/LessonEditor.tsx2D
21src/pages/safepath/courses/components/QuizEditor.tsx2D
22src/pages/safepath/courses/components/CourseReviewStep.tsx2D
23src/pages/safepath/courses/components/CourseEditorWizard.tsx2D
24src/pages/safepath/matrix/components/MatrixGrid.tsx2E
25src/pages/safepath/matrix/components/MatrixCellTooltip.tsx2E
26src/pages/safepath/reports/components/CompletionReportTab.tsx2E
27src/pages/safepath/reports/components/TranscriptTab.tsx2E
28src/pages/safepath/reports/components/CertificationReportTab.tsx2E
29src/pages/safepath/reports/components/ReportExportButton.tsx2E
30src/pages/safepath/assignments/components/AssignmentList.tsx2F
31src/pages/safepath/assignments/components/CreateAssignmentModal.tsx2F
32src/pages/safepath/assignments/components/BulkAssignModal.tsx2F
33src/pages/safepath/certifications/components/CertificationList.tsx2F
34src/pages/safepath/certifications/components/AddCertificationModal.tsx2F
35src/pages/safepath/certifications/components/CertificationTypesPanel.tsx2F
36src/pages/safepath/quickstart/components/QuickstartChecklist.tsx2G
37src/pages/safepath/quickstart/components/StarterTemplatesPanel.tsx2G
38src/pages/safepath/quickstart/components/QuickstartStatusBanner.tsx2G
39src/pages/safepath/components/SafePathPageHeader.tsx2H

Modified Files

FilePhases
src/App.tsx2A
src/components/Sidebar.tsx2A
src/types/safepath.ts2F
src/services/api/safepath.api.ts2F
src/services/api/index.ts2F