import React, { useState, useEffect } from 'react'; import { useAuth } from '../contexts/AuthContext'; import { createAccessCode, listAccessCodes, deleteAccessCode, getCompanies } from '../services/apiService'; import { Plus, Trash2, Copy, Check, ChevronDown } from 'lucide-react'; import { UserRole } from '../types'; interface AccessCode { id: string; codigo: string; descricao: string; validade_dias: number; criado_em: string; expira_em: string; ativo: boolean; usos: number; empresa_id?: string; empresa_nome?: string; } export const AccessCodes: React.FC = () => { const { token, user } = useAuth(); const [codes, setCodes] = useState([]); const [loading, setLoading] = useState(false); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [companies, setCompanies] = useState>([]); // Form State const [newCode, setNewCode] = useState(''); const [days, setDays] = useState(30); const [customDays, setCustomDays] = useState(''); const [copiedId, setCopiedId] = useState(null); const [selectedCompanyId, setSelectedCompanyId] = useState(''); useEffect(() => { if (token) fetchCodes(); }, [token]); const fetchCompanies = async () => { const res = await getCompanies(); if (res.data) { setCompanies(res.data); } }; const openCreateModal = () => { setIsCreateModalOpen(true); fetchCompanies(); }; const fetchCodes = async () => { setLoading(true); const res = await listAccessCodes(token!); if (res.data) { setCodes(res.data); } setLoading(false); }; const handleCreate = async (e: React.FormEvent) => { e.preventDefault(); const codeToCreate = newCode.trim() || generateRandomCode(); const payload: any = { codigo: codeToCreate, validade_dias: days, descricao: 'Gerado via Painel' }; if (selectedCompanyId) { payload.empresa_id = selectedCompanyId; } const res = await createAccessCode(token!, payload); if (res.error) { alert('Erro ao criar: ' + res.error); } else { setIsCreateModalOpen(false); setNewCode(''); setSelectedCompanyId(''); fetchCodes(); } }; const handleDelete = async (id: string) => { if (!confirm('Excluir este código? Ele não poderá mais ser usado.')) return; const res = await deleteAccessCode(token!, id); if (!res.error) { fetchCodes(); } else { alert('Erro ao excluir'); } }; const generateRandomCode = () => { const year = new Date().getFullYear(); const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0'); return `PHOTUM${year}-${random}`; }; const copyToClipboard = (text: string, id: string) => { navigator.clipboard.writeText(text); setCopiedId(id); setTimeout(() => setCopiedId(null), 2000); }; const formatDate = (dateStr: string) => { return new Date(dateStr).toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); }; if (!user || (user.role !== UserRole.SUPERADMIN && user.role !== UserRole.BUSINESS_OWNER)) { return
Acesso restrito.
; } return (

Gerenciar Códigos de Acesso

Crie e gerencie códigos de acesso temporários para novos cadastros

{loading ? ( ) : codes.length === 0 ? ( ) : ( codes.map(code => ( )) )}
Status Código Empresa Validade (Dias) Data de Criação Data de Expiração Ações
Carregando...
Nenhum código gerado.
{code.validade_dias === -1 ? 'Infinito' : `${code.validade_dias} dias`}
{code.codigo}
{code.empresa_nome || Todas as empresas} {code.validade_dias === -1 ? 'Nunca expira' : `${code.validade_dias} dias`} {formatDate(code.criado_em)} {code.validade_dias === -1 ? '-' : formatDate(code.expira_em)}
{/* Modal Create */} {isCreateModalOpen && (

Novo Código de Acesso

setNewCode(e.target.value.toUpperCase())} placeholder={generateRandomCode()} className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-[#492E61] focus:border-transparent outline-none" />

Deixe em branco para gerar automaticamente.

Deixe em branco para permitir uso por todas as empresas.

{[7, 15, 30, 60, 90].map(d => ( ))}
{days !== -1 && (
Outro: { const val = parseInt(e.target.value); setCustomDays(e.target.value); if (!isNaN(val) && val > 0) setDays(val); }} className="w-24 border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:ring-2 focus:ring-[#492E61] focus:border-transparent outline-none" placeholder="Dias" />
)}
)}
); };