"use client"; import { Fragment, useEffect, useState } from 'react'; import { Menu, Transition } from '@headlessui/react'; import ConfirmDialog from '@/components/layout/ConfirmDialog'; import { useToast } from '@/components/layout/ToastContext'; import { SparklesIcon, TrashIcon, PencilIcon, EllipsisVerticalIcon, MagnifyingGlassIcon, PlusIcon, XMarkIcon, UserGroupIcon, ChartBarIcon, FolderIcon, LifebuoyIcon, CreditCardIcon, DocumentTextIcon, ArchiveBoxIcon, ShareIcon } from '@heroicons/react/24/outline'; // Mapeamento de ícones para cada solução const SOLUTION_ICONS: Record> = { 'crm': UserGroupIcon, 'erp': ChartBarIcon, 'projetos': FolderIcon, 'helpdesk': LifebuoyIcon, 'pagamentos': CreditCardIcon, 'contratos': DocumentTextIcon, 'documentos': ArchiveBoxIcon, 'social': ShareIcon, }; interface Solution { id: string; name: string; slug: string; icon: string; description: string; is_active: boolean; created_at: string; updated_at: string; } export default function SolutionsPage() { const toast = useToast(); const [solutions, setSolutions] = useState([]); const [loading, setLoading] = useState(true); const [isModalOpen, setIsModalOpen] = useState(false); const [editingSolution, setEditingSolution] = useState(null); const [confirmOpen, setConfirmOpen] = useState(false); const [solutionToDelete, setSolutionToDelete] = useState(null); const [searchTerm, setSearchTerm] = useState(''); // Form state const [formData, setFormData] = useState({ name: '', slug: '', icon: '', description: '', is_active: true, }); useEffect(() => { fetchSolutions(); }, []); const fetchSolutions = async () => { try { const response = await fetch('/api/admin/solutions', { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}`, }, }); if (response.ok) { const data = await response.json(); setSolutions(data.solutions || []); } } catch (error) { console.error('Error fetching solutions:', error); } finally { setLoading(false); } }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); const url = editingSolution ? `/api/admin/solutions/${editingSolution.id}` : '/api/admin/solutions'; const method = editingSolution ? 'PUT' : 'POST'; try { const response = await fetch(url, { method, headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}`, 'Content-Type': 'application/json', }, body: JSON.stringify(formData), }); if (response.ok) { toast.success( editingSolution ? 'Solução atualizada' : 'Solução criada', editingSolution ? 'A solução foi atualizada com sucesso.' : 'A nova solução foi criada com sucesso.' ); fetchSolutions(); handleCloseModal(); } else { const error = await response.json(); toast.error('Erro', error.message || 'Não foi possível salvar a solução.'); } } catch (error) { console.error('Error saving solution:', error); toast.error('Erro', 'Ocorreu um erro ao salvar a solução.'); } }; const handleEdit = (solution: Solution) => { setEditingSolution(solution); setFormData({ name: solution.name, slug: solution.slug, icon: solution.icon, description: solution.description, is_active: solution.is_active, }); setIsModalOpen(true); }; const handleDeleteClick = (id: string) => { setSolutionToDelete(id); setConfirmOpen(true); }; const handleConfirmDelete = async () => { if (!solutionToDelete) return; try { const response = await fetch(`/api/admin/solutions/${solutionToDelete}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}`, }, }); if (response.ok) { setSolutions(solutions.filter(s => s.id !== solutionToDelete)); toast.success('Solução excluída', 'A solução foi excluída com sucesso.'); } else { toast.error('Erro ao excluir', 'Não foi possível excluir a solução.'); } } catch (error) { console.error('Error deleting solution:', error); toast.error('Erro ao excluir', 'Ocorreu um erro ao excluir a solução.'); } finally { setConfirmOpen(false); setSolutionToDelete(null); } }; const handleCloseModal = () => { setIsModalOpen(false); setEditingSolution(null); setFormData({ name: '', slug: '', icon: '', description: '', is_active: true, }); }; const filteredSolutions = solutions.filter((solution) => { const searchLower = searchTerm.toLowerCase(); return ( (solution.name?.toLowerCase() || '').includes(searchLower) || (solution.slug?.toLowerCase() || '').includes(searchLower) || (solution.description?.toLowerCase() || '').includes(searchLower) ); }); return (
{/* Header */}

Soluções

Gerencie as soluções disponíveis na plataforma (CRM, ERP, etc.)

{/* Search */}
setSearchTerm(e.target.value)} />
{/* Table */} {loading ? (
) : filteredSolutions.length === 0 ? (

Nenhuma solução encontrada

{searchTerm ? 'Nenhuma solução corresponde à sua busca.' : 'Comece criando sua primeira solução.'}

) : (
{filteredSolutions.map((solution) => { const Icon = SOLUTION_ICONS[solution.slug] || FolderIcon; return ( handleEdit(solution)}> ); })}
Solução Slug Descrição Status Ações
{solution.name}
{solution.slug} {solution.description || '-'} {solution.is_active ? 'Ativo' : 'Inativo'} e.stopPropagation()}>
{({ active }) => ( )}
{({ active }) => ( )}
)} {/* Modal */} {isModalOpen && (

{editingSolution ? 'Editar Solução' : 'Nova Solução'}

{editingSolution ? 'Atualize as informações da solução.' : 'Configure uma nova solução para a plataforma.'}

setFormData({ ...formData, name: e.target.value })} placeholder="Ex: CRM" required className="w-full px-3 py-2.5 border border-zinc-200 dark:border-zinc-700 rounded-lg bg-white dark:bg-zinc-900 text-zinc-900 dark:text-white placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-[var(--brand-color)] focus:border-transparent transition-all" />
setFormData({ ...formData, slug: e.target.value })} placeholder="Ex: crm" required className="w-full px-3 py-2.5 border border-zinc-200 dark:border-zinc-700 rounded-lg bg-white dark:bg-zinc-900 text-zinc-900 dark:text-white placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-[var(--brand-color)] focus:border-transparent transition-all" />
setFormData({ ...formData, icon: e.target.value })} placeholder="Ex: 📊 ou users" className="w-full px-3 py-2.5 border border-zinc-200 dark:border-zinc-700 rounded-lg bg-white dark:bg-zinc-900 text-zinc-900 dark:text-white placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-[var(--brand-color)] focus:border-transparent transition-all" />