'use client'; import { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { Header } from '@/components/layouts/header'; import { Card, CardContent, CardHeader, CardTitle, CardDescription, Button, Input } from '@horux/shared-ui'; import { useAuthStore } from '@/stores/auth-store'; import { isGlobalAdminRfc } from '@horux/shared'; import { getPaquetesCatalogoAdmin, updatePaqueteCatalogo, type PaqueteCatalogoAdmin, } from '@/lib/api/facturacion'; import { formatCurrency } from '@/lib/utils'; import { Package, ShieldAlert, Loader2, CheckCircle2, AlertTriangle, Save } from 'lucide-react'; export default function TimbresCatalogoPage() { const { user } = useAuthStore(); const queryClient = useQueryClient(); const isGlobalAdmin = isGlobalAdminRfc(user?.tenantRfc, user?.role, user?.platformRoles); const { data: catalogo = [], isLoading } = useQuery({ queryKey: ['timbres-paquetes-catalogo-admin'], queryFn: getPaquetesCatalogoAdmin, enabled: isGlobalAdmin, }); if (!isGlobalAdmin) { return ( <>

Acceso restringido

Solo admin global puede editar el catálogo.

); } return ( <>
Los cambios de precio aplican sólo a compras nuevas. Los paquetes ya vendidos conservan el precio que pagó el cliente (snapshot). Desactivar un paquete lo oculta del catálogo público pero no afecta paquetes vigentes.
Paquetes en el catálogo Edita precio o da de baja. Orden por cantidad ascendente. {isLoading ? (

Cargando...

) : catalogo.length === 0 ? (

No hay paquetes en el catálogo.

) : (
{catalogo.map((p) => ( queryClient.invalidateQueries({ queryKey: ['timbres-paquetes-catalogo-admin'] })} /> ))}
Cantidad Precio actual Precio por timbre Estado Última actualización Acciones
)}
); } function PaqueteRow({ paquete, onSaved }: { paquete: PaqueteCatalogoAdmin; onSaved: () => void }) { const [editing, setEditing] = useState(false); const [precio, setPrecio] = useState(paquete.precio.toString()); const [active, setActive] = useState(paquete.active); const [saved, setSaved] = useState(false); const mutation = useMutation({ mutationFn: () => updatePaqueteCatalogo(paquete.id, { precio: Number(precio), active, }), onSuccess: () => { setEditing(false); setSaved(true); setTimeout(() => setSaved(false), 2000); onSaved(); }, onError: (err: any) => { alert(err?.response?.data?.message || 'Error al guardar'); }, }); const precioNum = Number(precio); const precioValido = precioNum > 0 && !isNaN(precioNum); const hasChanges = Number(precio) !== paquete.precio || active !== paquete.active; return ( {paquete.cantidad.toLocaleString('es-MX')} {editing ? (
$ setPrecio(e.target.value)} className="w-28 h-8" />
) : ( {formatCurrency(paquete.precio)} )} {precioValido ? formatCurrency(precioNum / paquete.cantidad) : '—'} {editing ? ( ) : ( {paquete.active ? 'Activo' : 'Inactivo'} )} {new Date(paquete.updatedAt).toLocaleString('es-MX', { dateStyle: 'short', timeStyle: 'short' })} {saved ? ( Guardado ) : editing ? (
) : ( )} ); }