import { useState, useEffect } from 'react'; import { Tag, Plus, Search, Edit, Trash2, CheckCircle, XCircle, TrendingUp, X } from 'lucide-react'; import { ToastContainer, useToast } from '../../UI/Toast'; import Table, { Column } from '../../UI/Table'; import ActionButtons from '../../UI/ActionButtons'; import ButtonUI from '../../UI/ButtonUI'; import Pagination from '../../UI/Pagination'; import ToggleSwitch from '../../UI/ToggleSwitch'; import CustomInput from '../../UI/CustomInput'; import CustomSelect from '../../UI/CustomSelect'; interface SkillTag { id: string; name: string; skillLevel: string; description: string; status: 'Active' | 'Inactive'; createdAt: string; updatedAt?: string; } // Create/Edit Modal Component - Manages its own state interface ModalProps { isOpen: boolean; onClose: () => void; onSave: (data: { name: string; skillLevel: string; description: string }) => void; title: string; initialData?: { name: string; skillLevel: string; description: string } | null; skillLevelOptions: string[]; } const Modal = ({ isOpen, onClose, onSave, title, initialData, skillLevelOptions }: ModalProps) => { const [formData, setFormData] = useState({ name: initialData?.name || '', skillLevel: initialData?.skillLevel || '', description: initialData?.description || '', }); // Update form when initialData changes useEffect(() => { if (initialData) { setFormData({ name: initialData.name || '', skillLevel: initialData.skillLevel || '', description: initialData.description || '', }); } }, [initialData]); // Reset form when modal opens useEffect(() => { if (isOpen && !initialData) { setFormData({ name: '', skillLevel: '', description: '', }); } }, [isOpen, initialData]); if (!isOpen) return null; const handleInputChange = (field: string, value: any) => { setFormData((prev) => ({ ...prev, [field]: value })); }; const handleSubmit = () => { if (!formData.name || !formData.skillLevel) { // Toast will be shown from parent return; } onSave(formData); }; return ( <>

{title}

handleInputChange('name', value)} placeholder="Enter Knowledge Tag Name" required icon={} /> handleInputChange('skillLevel', value)} options={skillLevelOptions} placeholder="Select Knowledge Level" required icon={} /> handleInputChange('description', value)} placeholder="Enter Description" rows={3} />
Cancel {initialData ? 'Update Knowledge Tag' : 'Create Knowledge Tag'}
); }; const SkillTag = () => { const toast = useToast(); const [searchTerm, setSearchTerm] = useState(''); const [currentPage, setCurrentPage] = useState(1); const [showEntries, setShowEntries] = useState(10); const [showCreateModal, setShowCreateModal] = useState(false); const [showEditModal, setShowEditModal] = useState(false); const [selectedTag, setSelectedTag] = useState(null); const [showDeleteModal, setShowDeleteModal] = useState(false); const [tagToDelete, setTagToDelete] = useState(null); const [isDeleting, setIsDeleting] = useState(false); // Mock data for skill levels const skillLevelOptions = ['Beginner', 'Intermediate', 'Advanced', 'Expert', 'Master']; // Mock data for skill tags const [skillTags, setSkillTags] = useState([ { id: '1', name: 'JavaScript', skillLevel: 'Advanced', description: 'Advanced JavaScript programming skills', status: 'Active', createdAt: '2024-01-15', }, { id: '2', name: 'Python', skillLevel: 'Intermediate', description: 'Python programming language', status: 'Active', createdAt: '2024-02-10', }, { id: '3', name: 'React', skillLevel: 'Expert', description: 'React.js frontend framework', status: 'Active', createdAt: '2024-03-05', }, { id: '4', name: 'Node.js', skillLevel: 'Intermediate', description: 'Node.js backend development', status: 'Inactive', createdAt: '2024-04-20', }, { id: '5', name: 'SQL', skillLevel: 'Beginner', description: 'SQL database management', status: 'Active', createdAt: '2024-05-15', }, ]); const handleAddTag = () => { setSelectedTag(null); setShowCreateModal(true); }; const handleEditTag = (tag: SkillTag) => { setSelectedTag(tag); setShowEditModal(true); }; const handleDeleteTag = (tag: SkillTag) => { setTagToDelete(tag); setShowDeleteModal(true); }; const handleConfirmDelete = () => { if (!tagToDelete) return; setIsDeleting(true); setTimeout(() => { setSkillTags(skillTags.filter((t) => t.id !== tagToDelete.id)); setShowDeleteModal(false); setTagToDelete(null); setIsDeleting(false); toast.success(`Skill tag "${tagToDelete.name}" deleted successfully!`); }, 1000); }; const handleSaveTag = (formData: { name: string; skillLevel: string; description: string }) => { if (!formData.name || !formData.skillLevel) { toast.error('Please fill in all required fields'); return; } if (selectedTag) { // Edit existing setSkillTags( skillTags.map((t) => t.id === selectedTag.id ? { ...t, name: formData.name, skillLevel: formData.skillLevel, description: formData.description, updatedAt: new Date().toISOString().split('T')[0], } : t, ), ); toast.success('Skill tag updated successfully!'); setShowEditModal(false); setSelectedTag(null); } else { // Add new const newTag: SkillTag = { id: String(skillTags.length + 1), name: formData.name, skillLevel: formData.skillLevel, description: formData.description, status: 'Active', createdAt: new Date().toISOString().split('T')[0], }; setSkillTags([...skillTags, newTag]); toast.success('Skill tag created successfully!'); setShowCreateModal(false); } }; const handleToggleStatus = (id: string) => { setSkillTags(skillTags.map((t) => (t.id === id ? { ...t, status: t.status === 'Active' ? 'Inactive' : 'Active' } : t))); const tag = skillTags.find((t) => t.id === id); toast.info(`Skill tag "${tag?.name}" status changed to ${tag?.status === 'Active' ? 'Inactive' : 'Active'}`); }; // Filter skill tags const filteredTags = skillTags.filter((tag) => { const searchLower = searchTerm.toLowerCase(); return tag.name.toLowerCase().includes(searchLower) || tag.skillLevel.toLowerCase().includes(searchLower) || tag.description.toLowerCase().includes(searchLower); }); // Pagination const totalPages = Math.ceil(filteredTags.length / showEntries); const startIndex = (currentPage - 1) * showEntries; const currentTags = filteredTags.slice(startIndex, startIndex + showEntries); // Define columns const columns: Column[] = [ { key: 'sno', header: 'S.No', align: 'center', accessor: (_row: SkillTag, index: number) => { const page = currentPage || 1; const entries = showEntries || 10; const calculatedIndex = (page - 1) * entries + (index || 0) + 1; return {calculatedIndex}; }, }, { key: 'name', header: 'SKILL TAG', accessor: (row: SkillTag) => (
{row.name}
), }, { key: 'skillLevel', header: 'SKILL LEVEL', accessor: (row: SkillTag) => ( {row.skillLevel} ), }, { key: 'description', header: 'DESCRIPTION', accessor: (row: SkillTag) =>
{row.description || '—'}
, }, { key: 'status', header: 'STATUS', align: 'center', accessor: (row: SkillTag) => handleToggleStatus(row.id)} activeColor="bg-green-600" inactiveColor="bg-gray-300" />, }, { key: 'actions', header: 'ACTION', align: 'center', accessor: (row: SkillTag) => ( handleEditTag(row)} onDelete={() => handleDeleteTag(row)} showView={false} editTooltip="Edit Skill Tag" deleteTooltip="Delete Skill Tag" size="sm" /> ), }, ]; return ( <>
{/* Header */}

Skill Tags

Manage knowledge tags and skill levels

} onClick={handleAddTag}> Add Skill Tag
{/* Stats Cards */}

Total Tags

{skillTags.length}

Active

{skillTags.filter((t) => t.status === 'Active').length}

Inactive

{skillTags.filter((t) => t.status === 'Inactive').length}

{/* Filters */}
Show
setSearchTerm(e.target.value)} className="w-full pl-9 pr-4 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20" />
{/* Table */} {/* Pagination */} {filteredTags.length > 0 && ( )} {/* Create Modal */} { setShowCreateModal(false); setSelectedTag(null); }} onSave={handleSaveTag} title="Create Knowledge Tag" initialData={null} skillLevelOptions={skillLevelOptions} /> {/* Edit Modal */} { setShowEditModal(false); setSelectedTag(null); }} onSave={handleSaveTag} title="Edit Knowledge Tag" initialData={ selectedTag ? { name: selectedTag.name, skillLevel: selectedTag.skillLevel, description: selectedTag.description, } : null } skillLevelOptions={skillLevelOptions} /> {/* Delete Confirmation Modal */} {showDeleteModal && (

Delete Skill Tag

Are you sure you want to delete "{tagToDelete?.name}"? This action cannot be undone.

{ setShowDeleteModal(false); setTagToDelete(null); }} > Cancel {isDeleting ? 'Deleting...' : 'Delete'}
)} ); }; export default SkillTag;