import React, { useState, useEffect } from 'react'; import { AuthenticatedLayout } from '../layout/AuthenticatedLayout'; import { Card, CardContent, CardHeader, CardTitle } from '../ui/card'; import { Button } from '../ui/button'; import { Badge } from '../ui/badge'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; import { Textarea } from '../ui/textarea'; import { Checkbox } from '../ui/checkbox'; import { RadioGroup, RadioGroupItem } from '../ui/radio-group'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../ui/select'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; import { Progress } from '../ui/progress'; import { Separator } from '../ui/separator'; import { toast } from "sonner"; import { ChevronLeft, ChevronRight, Calendar, Users, FileUp, Download, AlertCircle, Clock, MapPin, User, Building2, CheckCircle } from 'lucide-react'; import { klcMockData } from '../../data/mockData'; import { Route } from '../../types/routes'; interface CourseAssignmentProps { courseId: string; onNavigate: (route: Route) => void; onLogout: () => void; user: any; } interface AssignmentData { type: 'course'; itemId: string; scope: 'organization' | 'individual'; organizationId?: string; userId?: string; hrContacts: string[]; startDate: string; endDate: string; completionDate?: string; maxParticipants: number; integrationId?: string; flags: { allowAddFeedbackGiver: boolean; hrAccessReports: boolean; hrAccessCertificate: boolean; onlineProgram: boolean; blockSystemEmails: boolean; }; participantsSource: 'directory' | 'upload'; participants: string[]; participantsFile?: File; feedbackGiversFile?: File; } // Mock integration options const integrationOptions = [ { id: 'int_001', name: 'Microsoft Teams' }, { id: 'int_002', name: 'Zoom Workplace' }, { id: 'int_003', name: 'Google Workspace' }, { id: 'int_004', name: 'Slack Enterprise' }, { id: 'int_005', name: 'Custom API' } ]; export function CourseAssignment({ courseId, onNavigate, onLogout, user }: CourseAssignmentProps) { const [currentStep, setCurrentStep] = useState(1); const [assignmentData, setAssignmentData] = useState({ type: 'course', itemId: courseId, scope: 'organization', hrContacts: [], startDate: '', endDate: '', maxParticipants: 25, flags: { allowAddFeedbackGiver: false, hrAccessReports: false, hrAccessCertificate: false, onlineProgram: false, blockSystemEmails: false, }, participantsSource: 'directory', participants: [], }); // Get course data const course = klcMockData.courses?.find(c => c.id === courseId); // Mock organizations and users data const organizations = klcMockData.users?.organizations || []; const [filteredLearners, setFilteredLearners] = useState([]); const [selectedParticipants, setSelectedParticipants] = useState([]); const [participantsTab, setParticipantsTab] = useState('directory'); const [hrContactInput, setHrContactInput] = useState(''); // Load learners when organization changes useEffect(() => { if (assignmentData.organizationId) { // Mock learners for selected organization const mockLearners = [ { id: 'usr_001', name: 'Ravi Kumar', email: 'ravi.kumar@org.example', department: 'Technology' }, { id: 'usr_002', name: 'Priya Sharma', email: 'priya.sharma@org.example', department: 'Marketing' }, { id: 'usr_003', name: 'Amit Singh', email: 'amit.singh@org.example', department: 'Operations' }, { id: 'usr_004', name: 'Sneha Patel', email: 'sneha.patel@org.example', department: 'HR' }, { id: 'usr_005', name: 'Rajesh Kumar', email: 'rajesh.kumar@org.example', department: 'Finance' } ]; setFilteredLearners(mockLearners); } }, [assignmentData.organizationId]); const updateAssignmentData = (updates: Partial) => { setAssignmentData(prev => ({ ...prev, ...updates })); }; const validateStep = (step: number): boolean => { switch (step) { case 1: if (assignmentData.scope === 'organization' && !assignmentData.organizationId) { toast.error("Please select an organization"); return false; } if (assignmentData.scope === 'individual' && !assignmentData.userId) { toast.error("Please select a user"); return false; } if (assignmentData.hrContacts.length === 0) { toast.error("Please enter at least one HR contact"); return false; } if (assignmentData.maxParticipants <= 0) { toast.error("Max participants must be greater than 0"); return false; } return true; case 2: if (!assignmentData.startDate) { toast.error("Please select a start date"); return false; } if (!assignmentData.endDate) { toast.error("Please select an end date"); return false; } if (new Date(assignmentData.endDate) < new Date(assignmentData.startDate)) { toast.error("End date must be after start date"); return false; } if (assignmentData.completionDate && new Date(assignmentData.completionDate) < new Date(assignmentData.endDate)) { toast.error("Completion date must be after end date"); return false; } return true; case 3: if (participantsTab === 'directory' && selectedParticipants.length === 0) { toast.error("Please select at least one participant"); return false; } if (selectedParticipants.length > assignmentData.maxParticipants) { toast.error(`Cannot exceed maximum of ${assignmentData.maxParticipants} participants`); return false; } return true; default: return true; } }; const handleNext = () => { if (validateStep(currentStep)) { setCurrentStep(prev => Math.min(prev + 1, 4)); } }; const handleBack = () => { setCurrentStep(prev => Math.max(prev - 1, 1)); }; const handleAssign = () => { if (validateStep(3)) { toast.success("Assignment created."); // Navigate to assignment details or back to courses onNavigate('/courses'); } }; const addHrContact = () => { if (hrContactInput.trim()) { updateAssignmentData({ hrContacts: [...assignmentData.hrContacts, hrContactInput.trim()] }); setHrContactInput(''); } }; const removeHrContact = (index: number) => { const newContacts = assignmentData.hrContacts.filter((_, i) => i !== index); updateAssignmentData({ hrContacts: newContacts }); }; const toggleParticipant = (participantId: string) => { setSelectedParticipants(prev => prev.includes(participantId) ? prev.filter(id => id !== participantId) : [...prev, participantId] ); }; // Check if course has feedback components (profilers) const hasFeedbackComponents = course?.assessments?.some((assessment: any) => assessment.type === 'Profiler' || assessment.title.toLowerCase().includes('360') ); const breadcrumbItems = [ { label: "Admin", href: "/dashboard" }, { label: "Courses", href: "/courses" }, { label: course?.title || "Course", href: `/courses/${courseId}` }, { label: "Assign", current: true } ]; const renderStepIndicator = () => (
{[1, 2, 3, 4].map((step) => (
{step < currentStep ? : step}
{step < 4 && (
)}
))}
); const renderSummaryCard = () => ( Course Summary

{course?.title}

{course?.id}

{course?.status}

{course?.instructor}

{course?.duration}

{course?.linkedIntegrations && course.linkedIntegrations.length > 0 && (

{course.linkedIntegrations.join(', ')}

)}
); const renderStep1 = () => (

Who to assign

updateAssignmentData({ scope: value, organizationId: undefined, userId: undefined }) } className="mt-2" >
{assignmentData.scope === 'organization' ? (
) : (
)}
setHrContactInput(e.target.value)} placeholder="Enter HR contact name" className="min-h-[44px]" onKeyPress={(e) => e.key === 'Enter' && addHrContact()} />

Primary, secondary HR contacts

{assignmentData.hrContacts.length > 0 && (
{assignmentData.hrContacts.map((contact, index) => ( {contact} ))}
)}
updateAssignmentData({ maxParticipants: parseInt(e.target.value) || 0 })} className="min-h-[44px]" min="1" />
updateAssignmentData({ flags: { ...assignmentData.flags, allowAddFeedbackGiver: !!checked } }) } />
updateAssignmentData({ flags: { ...assignmentData.flags, hrAccessReports: !!checked } }) } />
updateAssignmentData({ flags: { ...assignmentData.flags, hrAccessCertificate: !!checked } }) } />
updateAssignmentData({ flags: { ...assignmentData.flags, onlineProgram: !!checked } }) } />
updateAssignmentData({ flags: { ...assignmentData.flags, blockSystemEmails: !!checked } }) } />
{assignmentData.flags.blockSystemEmails && (

No onboarding emails will be sent for this assignment.

)}
); const renderStep2 = () => (

Schedule & Completion

Dates apply to this assignment and are not set on the master course.

updateAssignmentData({ startDate: e.target.value })} className="min-h-[44px]" />
updateAssignmentData({ endDate: e.target.value })} className="min-h-[44px]" />
updateAssignmentData({ completionDate: e.target.value })} className="min-h-[44px]" />
); const renderStep3 = () => (

Participants (and Feedback Givers)

Add from Directory Upload {assignmentData.scope === 'organization' ? ( assignmentData.organizationId ? (

Select participants from {organizations.find(o => o.id === assignmentData.organizationId)?.name}

{filteredLearners.map((learner) => (
toggleParticipant(learner.id)} />

{learner.email} • {learner.department}

))}
) : (

Select an organization to browse learners.

) ) : (

Individual user will be automatically added as participant.

{assignmentData.userId && ( {filteredLearners.find(u => u.id === assignmentData.userId)?.name || 'Selected User'} )}
)}

Upload participant list

{hasFeedbackComponents && (

Upload feedback givers list

)}
Participants selected: {selectedParticipants.length} (Max {assignmentData.maxParticipants})
); const renderStep4 = () => (

Review & Assign

{course?.title}

{assignmentData.scope === 'organization' ? organizations.find(o => o.id === assignmentData.organizationId)?.name : filteredLearners.find(u => u.id === assignmentData.userId)?.name }

{assignmentData.hrContacts.join(', ')}

{assignmentData.maxParticipants}

{assignmentData.startDate} • {assignmentData.endDate} {assignmentData.completionDate && ` • ${assignmentData.completionDate}`}

{assignmentData.integrationId ? integrationOptions.find(i => i.id === assignmentData.integrationId)?.name : 'None selected' }

Allow Participant to add Feedback Giver: {assignmentData.flags.allowAddFeedbackGiver ? 'Yes' : 'No'}

Allow HR to Access Reports: {assignmentData.flags.hrAccessReports ? 'Yes' : 'No'}

Allow HR to Access Certificate: {assignmentData.flags.hrAccessCertificate ? 'Yes' : 'No'}

Online Program: {assignmentData.flags.onlineProgram ? 'Yes' : 'No'}

Block System Generated Emails: {assignmentData.flags.blockSystemEmails ? 'Yes' : 'No'}

{participantsTab === 'directory' ? `${selectedParticipants.length} selected from directory` : 'Via upload' }

{hasFeedbackComponents && ( <>

Via upload

)}
); const stepTitles = [ 'Who to assign', 'Schedule & Completion', 'Participants (and Feedback Givers)', 'Review & Assign' ]; return (

Assignment — Course

Assign course to organizations or individuals

{stepTitles[currentStep - 1]} Step {currentStep} of 4
{renderStepIndicator()}
{currentStep === 1 && renderStep1()} {currentStep === 2 && renderStep2()} {currentStep === 3 && renderStep3()} {currentStep === 4 && renderStep4()}
{currentStep < 4 ? ( ) : ( )}
{renderSummaryCard()}
); }