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 { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '../ui/table'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../ui/select'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from '../ui/dropdown-menu'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '../ui/dialog'; import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, } from '../ui/sheet'; import { Checkbox } from '../ui/checkbox'; import { Separator } from '../ui/separator'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../ui/tooltip'; import { toast } from "sonner@2.0.3"; import { Plus, Search, MoreHorizontal, Edit, Settings, Copy, Trash2, ArrowUpDown, FileText, Target, CheckCircle, XCircle, AlertCircle, Save, X, Info } from 'lucide-react'; interface SectionConfigurationManagerProps { onNavigate: (route: string) => void; onLogout: () => void; user: any; } // Mock section configuration templates const sectionConfigTemplates = [ { id: "template_leadership_360", name: "Leadership 360 - Standard", description: "Standard 360-degree leadership assessment configuration", questionType: "Ipsative", sections: [ { name: "Strategic Thinking", numberOfStatements: 4, order: 1 }, { name: "Communication Skills", numberOfStatements: 3, order: 2 }, { name: "Team Leadership", numberOfStatements: 5, order: 3 }, { name: "Results Orientation", numberOfStatements: 4, order: 4 } ], usage: 12, createdBy: "Dr. Rajesh Mehta", createdAt: "2025-08-01T10:00:00Z" }, { id: "template_communication_likert", name: "Communication Assessment - Likert", description: "Comprehensive communication skills assessment using Likert scales", questionType: "Likert", sections: [ { name: "Verbal Communication", numberOfOptions: 5, order: 1 }, { name: "Written Communication", numberOfOptions: 7, order: 2 }, { name: "Active Listening", numberOfOptions: 5, order: 3 }, { name: "Non-verbal Communication", numberOfOptions: 5, order: 4 } ], usage: 8, createdBy: "Prof. Priya Sinha", createdAt: "2025-08-05T14:30:00Z" }, { id: "template_innovation_tf", name: "Innovation Mindset - True/False", description: "Innovation capabilities assessment using binary choices", questionType: "True/False", sections: [ { name: "Creative Thinking", order: 1 }, { name: "Risk Taking", order: 2 }, { name: "Problem Solving", order: 3 }, { name: "Adaptability", order: 4 } ], usage: 5, createdBy: "Dr. Amit Sharma", createdAt: "2025-08-10T09:15:00Z" }, { id: "template_strategy_matching", name: "Strategic Thinking - Matching", description: "Strategic capabilities assessment using matching exercises", questionType: "Matching", sections: [ { name: "Strategic Analysis", order: 1 }, { name: "Strategy Formulation", order: 2 }, { name: "Strategy Implementation", order: 3 } ], usage: 3, createdBy: "Prof. Sunita Agarwal", createdAt: "2025-08-12T16:45:00Z" }, { id: "template_culture_descriptive", name: "Team Culture Survey - Descriptive", description: "Open-ended team culture and engagement assessment", questionType: "Descriptive", sections: [ { name: "Culture Anchors", order: 1 }, { name: "Core Values", order: 2 }, { name: "Team Communication", order: 3 }, { name: "Collaboration", order: 4 }, { name: "Employee Engagement", order: 5 } ], usage: 7, createdBy: "Dr. Neha Shah", createdAt: "2025-08-15T11:20:00Z" } ]; // Section configuration rules based on question type const questionTypeConfig = { "Ipsative": { label: "Ipsative (Forced Choice)", description: "Users choose between ranked statements", configField: "numberOfStatements", configLabel: "Number of Statements", defaultValue: 4, minValue: 2, maxValue: 10, helpText: "Statements users will rank in order of preference" }, "Likert": { label: "Likert Scale", description: "Users rate items on a scale", configField: "numberOfOptions", configLabel: "Scale Points", defaultValue: 5, minValue: 3, maxValue: 10, helpText: "Number of points on the rating scale (e.g., 1-5, 1-7)" }, "True/False": { label: "True/False", description: "Binary choice questions", configField: null, configLabel: "No additional configuration", defaultValue: null, helpText: "Binary questions don't require additional configuration" }, "Matching": { label: "Matching Exercise", description: "Match items from different lists", configField: null, configLabel: "No additional configuration", defaultValue: null, helpText: "Matching exercises are configured per question" }, "Descriptive": { label: "Open Text", description: "Free-form text responses", configField: null, configLabel: "No additional configuration", defaultValue: null, helpText: "Descriptive questions don't require section-level configuration" } }; export function SectionConfigurationManager({ onNavigate, onLogout, user }: SectionConfigurationManagerProps) { // State management const [searchTerm, setSearchTerm] = useState(""); const [questionTypeFilter, setQuestionTypeFilter] = useState("all"); const [selectedTemplates, setSelectedTemplates] = useState([]); // Dialog and drawer states const [isCreateTemplateOpen, setIsCreateTemplateOpen] = useState(false); const [isEditTemplateOpen, setIsEditTemplateOpen] = useState(false); const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); const [isCloneTemplateOpen, setIsCloneTemplateOpen] = useState(false); const [isBulkDeleteDialogOpen, setIsBulkDeleteDialogOpen] = useState(false); // Template management states const [editingTemplate, setEditingTemplate] = useState(null); const [deletingTemplate, setDeletingTemplate] = useState(null); const [cloningTemplate, setCloningTemplate] = useState(null); // Form states const [newTemplate, setNewTemplate] = useState({ name: "", description: "", questionType: "", sections: [] }); const [editSections, setEditSections] = useState([]); const breadcrumbs = [ { label: "Admin", href: "/dashboard" }, { label: "Content", href: "/content" }, { label: "Profilers", href: "/profilers" }, { label: "Section Configuration" } ]; // Filter templates const filteredTemplates = sectionConfigTemplates.filter(template => { const matchesSearch = template.name.toLowerCase().includes(searchTerm.toLowerCase()) || template.description.toLowerCase().includes(searchTerm.toLowerCase()) || template.createdBy.toLowerCase().includes(searchTerm.toLowerCase()); const matchesQuestionType = questionTypeFilter === "all" || template.questionType === questionTypeFilter; return matchesSearch && matchesQuestionType; }); // Question type filter options const questionTypeOptions = [ { value: "all", label: "All Question Types", count: sectionConfigTemplates.length }, { value: "Ipsative", label: "Ipsative", count: sectionConfigTemplates.filter(t => t.questionType === "Ipsative").length }, { value: "Likert", label: "Likert", count: sectionConfigTemplates.filter(t => t.questionType === "Likert").length }, { value: "True/False", label: "True/False", count: sectionConfigTemplates.filter(t => t.questionType === "True/False").length }, { value: "Matching", label: "Matching", count: sectionConfigTemplates.filter(t => t.questionType === "Matching").length }, { value: "Descriptive", label: "Descriptive", count: sectionConfigTemplates.filter(t => t.questionType === "Descriptive").length } ]; // Utility functions const getQuestionTypeConfig = (questionType: string) => { return questionTypeConfig[questionType as keyof typeof questionTypeConfig] || questionTypeConfig["True/False"]; }; const addSection = () => { const config = getQuestionTypeConfig(newTemplate.questionType); const newSection: any = { id: `section_${Date.now()}`, name: "", order: editSections.length + 1 }; if (config.configField) { newSection[config.configField] = config.defaultValue; } setEditSections([...editSections, newSection]); }; const updateSection = (index: number, field: string, value: any) => { const updated = [...editSections]; updated[index] = { ...updated[index], [field]: value }; setEditSections(updated); }; const removeSection = (index: number) => { const updated = editSections.filter((_, i) => i !== index); // Reorder sections const reordered = updated.map((section, i) => ({ ...section, order: i + 1 })); setEditSections(reordered); }; const moveSection = (index: number, direction: 'up' | 'down') => { if ((direction === 'up' && index === 0) || (direction === 'down' && index === editSections.length - 1)) { return; } const updated = [...editSections]; const targetIndex = direction === 'up' ? index - 1 : index + 1; // Swap sections [updated[index], updated[targetIndex]] = [updated[targetIndex], updated[index]]; // Update order updated[index].order = index + 1; updated[targetIndex].order = targetIndex + 1; setEditSections(updated); }; // Action handlers const handleCreateTemplate = () => { setNewTemplate({ name: "", description: "", questionType: "", sections: [] }); setEditSections([]); setIsCreateTemplateOpen(true); }; const handleEditTemplate = (template: any) => { setEditingTemplate(template); setNewTemplate({ name: template.name, description: template.description, questionType: template.questionType, sections: template.sections }); setEditSections([...template.sections]); setIsEditTemplateOpen(true); }; const handleCloneTemplate = (template: any) => { setCloningTemplate(template); setNewTemplate({ name: `${template.name} (Copy)`, description: template.description, questionType: template.questionType, sections: template.sections }); setEditSections([...template.sections]); setIsCloneTemplateOpen(true); }; const handleDeleteTemplate = (template: any) => { setDeletingTemplate(template); setIsDeleteDialogOpen(true); }; const saveTemplate = () => { if (!newTemplate.name.trim()) { toast.error("Template name is required"); return; } if (!newTemplate.questionType) { toast.error("Question type is required"); return; } if (editSections.length === 0) { toast.error("At least one section is required"); return; } // Validate sections for (const section of editSections) { if (!section.name.trim()) { toast.error("All sections must have names"); return; } } const templateData = { ...newTemplate, sections: editSections }; if (isEditTemplateOpen) { toast.success(`Template "${newTemplate.name}" updated successfully`); setIsEditTemplateOpen(false); } else { toast.success(`Template "${newTemplate.name}" created successfully`); setIsCreateTemplateOpen(false); setIsCloneTemplateOpen(false); } // Reset form setNewTemplate({ name: "", description: "", questionType: "", sections: [] }); setEditSections([]); }; const confirmDelete = () => { if (deletingTemplate) { toast.success(`Template "${deletingTemplate.name}" deleted successfully`); setIsDeleteDialogOpen(false); setDeletingTemplate(null); } }; const handleBulkDelete = () => { toast.success(`${selectedTemplates.length} templates deleted successfully`); setSelectedTemplates([]); setIsBulkDeleteDialogOpen(false); }; // Filter chip component const FilterChip = ({ label, count, active, onClick }: { label: string; count?: number; active: boolean; onClick: () => void }) => ( ); return (
{/* Header */}

Section Configuration Templates

Manage reusable section configurations for profiler assessments

{/* Filter Bar */} {/* Search */}
setSearchTerm(e.target.value)} className="pl-10 min-h-[44px]" />
{/* Filter Chips */}
{questionTypeOptions.map(option => ( setQuestionTypeFilter(option.value)} /> ))}
{/* Bulk Action Bar */} {selectedTemplates.length > 0 && (
{selectedTemplates.length} template{selectedTemplates.length > 1 ? 's' : ''} selected
)} {/* Templates Table */} {filteredTemplates.length === 0 ? (

No section configuration templates found

Create reusable section configurations to standardize your profiler assessments.

) : (
{ if (checked) { setSelectedTemplates(filteredTemplates.map(t => t.id)); } else { setSelectedTemplates([]); } }} /> Template Name Question Type Sections Usage Created By Created Actions {filteredTemplates.map((template) => ( { if (checked) { setSelectedTemplates([...selectedTemplates, template.id]); } else { setSelectedTemplates(selectedTemplates.filter(id => id !== template.id)); } }} />
{template.name}
{template.description}
{template.questionType}
{template.sections.length} section{template.sections.length > 1 ? 's' : ''}
{template.sections.map((section, index) => (
{section.name} {section.numberOfStatements && ` (${section.numberOfStatements} statements)`} {section.numberOfOptions && ` (${section.numberOfOptions}-point scale)`}
))}
Used in {template.usage} profiler{template.usage > 1 ? 's' : ''}
{template.createdBy} {new Date(template.createdAt).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' })} handleEditTemplate(template)}> Edit Template handleCloneTemplate(template)}> Clone Template handleDeleteTemplate(template)} className="text-red-600 hover:text-red-700" > Delete Template
))}
)} {/* Create/Edit Template Dialog */} { if (!open) { setIsCreateTemplateOpen(false); setIsEditTemplateOpen(false); setIsCloneTemplateOpen(false); setNewTemplate({ name: "", description: "", questionType: "", sections: [] }); setEditSections([]); } }}> {isEditTemplateOpen ? 'Edit Template' : isCloneTemplateOpen ? 'Clone Template' : 'Create New Template'} {isEditTemplateOpen ? 'Modify the section configuration template' : isCloneTemplateOpen ? 'Create a copy of the section configuration template' : 'Create a reusable section configuration template for profiler assessments'}
{/* Basic Information */}
setNewTemplate({ ...newTemplate, name: e.target.value })} placeholder="Enter template name" className="min-h-[44px]" />