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) => (
),
},
{
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 */}
{/* 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;