"use client"; import React, { useState, useTransition, useCallback, useEffect } from "react"; import Link from "next/link"; import { AcademicCapIcon, PlusIcon, PencilSquareIcon, TrashIcon, EyeIcon, DocumentDuplicateIcon, } from "@heroicons/react/24/outline"; import ActionBtn from "@/app/(protected)/dashboard/components/ActionBtn"; import Card from "@/app/(protected)/dashboard/components/Card"; import SectionHeader from "@/app/(protected)/dashboard/components/SectionHeader"; import Label from "@/app/(protected)/components/shared/Label"; import { deleteExamTemplate, duplicateExamTemplate } from "@/app/lib/actions/examActions"; export default function TemplateList({ templates: initialTemplates = [], setTemplates: setTemplatesProp }) { const [templates, setTemplates] = useState(initialTemplates); const [isPending, startTransition] = useTransition(); const [pendingDeleteId, setPendingDeleteId] = useState(null); // Sync with parent prop when it changes useEffect(() => { setTemplates(initialTemplates); }, [initialTemplates]); // Wrapper to update both local and parent state const updateTemplates = useCallback((updater) => { setTemplates(updater); if (setTemplatesProp) { setTemplatesProp(typeof updater === 'function' ? updater(templates) : updater); } }, [setTemplatesProp, templates]); const handleDelete = useCallback(async (templateId) => { if (!confirm("Tem certeza que deseja excluir este template?")) { return; } // Set pending state for UI feedback setPendingDeleteId(templateId); startTransition(() => { // Perform the delete operation deleteExamTemplate(templateId).then((result) => { if (result.success) { updateTemplates((prev) => prev.filter((t) => t._id !== templateId)); } else { alert(result.error || "Erro ao excluir template"); } }).catch((error) => { console.error("Erro ao excluir template:", error); alert("Erro ao excluir template"); }).finally(() => { setPendingDeleteId(null); }); }); }, [updateTemplates]); const handleDuplicate = useCallback(async (templateId) => { startTransition(() => { duplicateExamTemplate(templateId).then((result) => { if (result.success && result.data) { // Ensure the duplicated template has a unique _id const newTemplate = result.data; console.log('Duplicated template _id:', newTemplate._id); updateTemplates((prev) => { // Check if _id already exists if (prev.some(t => t._id === newTemplate._id)) { console.warn('Duplicate _id detected, forcing refresh'); window.location.reload(); return prev; } return [newTemplate, ...prev]; }); } else { alert(result.error || "Erro ao duplicar template"); } }).catch((error) => { console.error("Erro ao duplicar template:", error); alert("Erro ao duplicar template"); }); }); }, [updateTemplates]); // Use templates for rendering const displayTemplates = templates; return (
} /> } label="Novo Template" onClick={() => { // This will be handled by the parent component window.dispatchEvent(new CustomEvent('open-template-form', { detail: null })); }} />
{displayTemplates.length === 0 ? (

Nenhum template criado ainda.

) : ( displayTemplates.map((template) => (

{template.title}

{template.isPublic && ( )} {template.category && ( )}
{template.description && (

{template.description}

)}
{template.questions?.length || 0} questões {template.totalPoints || 0} pontos {template.timeLimit && {template.timeLimit} min} Usado {template.usageCount || 0}x
{template.tags && template.tags.length > 0 && (
{template.tags.map((tag, idx) => ( {tag} ))}
)}
} label="Duplicar" onClick={() => handleDuplicate(template._id)} variant="secondary" small disabled={isPending || pendingDeleteId === template._id} /> } label="Editar" onClick={() => { // This will be handled by the parent component window.dispatchEvent(new CustomEvent('open-template-form', { detail: template })); }} variant="secondary" small /> } label="Excluir" onClick={() => handleDelete(template._id)} variant="secondary" small disabled={isPending || pendingDeleteId === template._id} />
)) )}
); }