'use client'; import React, { useState, useEffect } from 'react'; import { Users, UserPlus, Shield, ShieldCheck, UserCheck, MessageCircle, Mail, Phone, MapPin, Eye, EyeOff, Trash2, Edit, Check, X, Lock, Key } from 'lucide-react'; import { User } from '@/types'; export default function AdminUsersPage() { const [users, setUsers] = useState([]); const [search, setSearch] = useState(''); const [roleFilter, setRoleFilter] = useState<'all' | 'admin' | 'operator' | 'customer'>('all'); const [statusFilter, setStatusFilter] = useState<'all' | 'active' | 'inactive'>('all'); const [isModalOpen, setIsModalOpen] = useState(false); const [editingUser, setEditingUser] = useState(null); const [toastMessage, setToastMessage] = useState(null); // New user modal form const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [phone, setPhone] = useState(''); const [city, setCity] = useState('Cali'); const [address, setAddress] = useState(''); const [role, setRole] = useState<'admin' | 'operator' | 'customer'>('operator'); const [password, setPassword] = useState(''); // Edit user modal form const [editName, setEditName] = useState(''); const [editEmail, setEditEmail] = useState(''); const [editPhone, setEditPhone] = useState(''); const [editCity, setEditCity] = useState('Cali'); const [editAddress, setEditAddress] = useState(''); const [editRole, setEditRole] = useState<'admin' | 'operator' | 'customer'>('operator'); const [editPassword, setEditPassword] = useState(''); useEffect(() => { fetchUsers(); }, []); const fetchUsers = async () => { try { const res = await fetch('/api/users'); const data = await res.json(); if (data.success) { setUsers(data.users); } } catch (e) { console.error(e); } }; const handleToggleStatus = async (user: User) => { const newStatus = !user.isActive; setUsers((prev) => prev.map((u) => (u.id === user.id ? { ...u, isActive: newStatus } : u))); try { await fetch('/api/users', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: user.id, updates: { isActive: newStatus } }), }); setToastMessage(`Estado de ${user.name} actualizado a ${newStatus ? '🟢 ACTIVO' : '⚪ INACTIVO'}.`); } catch (e) { console.error(e); } }; const handleChangeRole = async (user: User, newRole: 'admin' | 'operator' | 'customer') => { setUsers((prev) => prev.map((u) => (u.id === user.id ? { ...u, role: newRole } : u))); try { await fetch('/api/users', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: user.id, updates: { role: newRole } }), }); setToastMessage(`Rol de ${user.name} actualizado a [${newRole.toUpperCase()}].`); } catch (e) { console.error(e); } }; const handleDeleteUser = async (id: string, name: string) => { if (!confirm(`¿Estás seguro de eliminar permanentemente al usuario ${name}?`)) return; setUsers((prev) => prev.filter((u) => u.id !== id)); try { await fetch(`/api/users?id=${id}`, { method: 'DELETE' }); setToastMessage(`🗑️ Usuario ${name} eliminado del sistema.`); } catch (e) { console.error(e); } }; const handleCreateUser = async (e: React.FormEvent) => { e.preventDefault(); try { const res = await fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, email, phone, city, address, role, password }), }); const data = await res.json(); if (data.success) { setUsers((prev) => [data.user, ...prev]); setIsModalOpen(false); setName(''); setEmail(''); setPhone(''); setAddress(''); setPassword(''); setToastMessage(`✨ Usuario "${data.user.name}" registrado con éxito.`); } else { alert(data.error); } } catch (e) { console.error(e); } }; const handleOpenEdit = (user: User) => { setEditingUser(user); setEditName(user.name); setEditEmail(user.email); setEditPhone(user.phone); setEditCity(user.city || 'Cali'); setEditAddress(user.address || ''); setEditRole(user.role); setEditPassword(user.password || ''); }; const handleSaveEdit = async (e: React.FormEvent) => { e.preventDefault(); if (!editingUser) return; const updates = { name: editName, email: editEmail, phone: editPhone, city: editCity, address: editAddress, role: editRole, password: editPassword, }; setUsers((prev) => prev.map((u) => (u.id === editingUser.id ? { ...u, ...updates } : u))); try { const res = await fetch('/api/users', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: editingUser.id, updates }), }); const data = await res.json(); if (data.success) { setEditingUser(null); setToastMessage(`✅ Datos de "${editName}" actualizados correctamente.`); } } catch (e) { console.error(e); } }; const handleWhatsApp = (user: User) => { const cleanPhone = user.phone.startsWith('57') ? user.phone : `57${user.phone}`; const text = encodeURIComponent(`Hola ${user.name}! Te escribimos del equipo administrativo de DripZone 🟣`); window.open(`https://wa.me/${cleanPhone}?text=${text}`, '_blank'); }; const filtered = users.filter((u) => { const matchSearch = u.name.toLowerCase().includes(search.toLowerCase()) || u.email.toLowerCase().includes(search.toLowerCase()) || u.phone.includes(search) || (u.city && u.city.toLowerCase().includes(search.toLowerCase())); if (!matchSearch) return false; if (roleFilter !== 'all' && u.role !== roleFilter) return false; if (statusFilter === 'active' && !u.isActive) return false; if (statusFilter === 'inactive' && u.isActive) return false; return true; }); const adminsCount = users.filter((u) => u.role === 'admin').length; const operatorsCount = users.filter((u) => u.role === 'operator').length; const customersCount = users.filter((u) => u.role === 'customer').length; return (
{/* Header */}

Control de Usuarios, Roles & Permisos ({users.length})

Crea, edita, activa/inactiva y asigna roles a Administradores, Operadores de Despachos y Clientes.

{toastMessage && (
{toastMessage}
)} {/* KPI Stats Cards */}

Super Administradores

{adminsCount}

Operadores LogĂ­sticos

{operatorsCount}

Clientes Registrados

{customersCount}

{/* Filters Toolbar */}
{/* Role Pills */}
{/* Search */}
setSearch(e.target.value)} className="w-full bg-neutral-900 border border-neutral-800 rounded-xl px-3.5 py-2 text-xs text-white outline-hidden focus:border-purple-400" />
{/* Users Table */}
{filtered.length === 0 ? ( ) : ( filtered.map((user) => { return ( {/* Active Status Toggle */} {/* User Avatar & Name */} {/* Contact */} {/* City */} {/* Role Dropdown */} {/* Last Login */} {/* Actions (CRUD: Edit & Delete) */} ); }) )}
Estado Usuario Contacto Directo Ciudad / DirecciĂłn Rol & Permisos Ăšltimo Acceso Acciones (CRUD)
No se encontraron usuarios con el filtro seleccionado.
{user.name.charAt(0).toUpperCase()}

{user.name}

{user.email}
{user.city || 'Cali'} {user.address &&

{user.address}

}
{user.lastLogin || user.createdAt}
{/* Modal Create User (POST) */} {isModalOpen && (

Registrar Nuevo Usuario / Admin

setName(e.target.value)} className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
setEmail(e.target.value)} className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
setPhone(e.target.value)} className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
setCity(e.target.value)} className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
setPassword(e.target.value)} className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
setAddress(e.target.value)} className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
)} {/* Modal Edit User (PUT) */} {editingUser && (

Editar Usuario: {editingUser.name}

setEditName(e.target.value)} className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
setEditEmail(e.target.value)} className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
setEditPhone(e.target.value)} className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
setEditCity(e.target.value)} className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
setEditPassword(e.target.value)} className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
setEditAddress(e.target.value)} className="w-full bg-neutral-950 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
)}
); }