Catálogos y administración
Las cuatro secciones de esta página son exclusivas del rol ADMIN (/methods, /reasons, /users, /warehouses están en PROTECTED_ROUTES): un ATC o STORE ni las ve en el menú ni puede entrar por URL. Ver Roles y control de acceso.
Todas siguen el mismo patrón: listado con DataTable precargado en servidor, hidratado con SWR, y edición mediante un hook useEdit* que combina react-hook-form + zod + useSWRMutation + mutate() + toast.
1. Métodos de devolución (/methods)
Los métodos son lo que el cliente elige en el paso 3 de ambos wizards: punto de recogida, mensajería a domicilio, devolución en tienda, etc., con su precio por país.
| Operación | Acción | Endpoint de robo-api |
|---|---|---|
| Listar | getMethods | GET /return-method/info |
| Ver uno | getMethod | POST /return-method/search con id_return_method |
| Buscar por país | getSearchMethods | POST /return-method/search con country |
| Crear | newMethod | POST /return-method/new |
| Editar | editMethod | PUT /return-method/edit/{id} |
| Borrar | deleteMethod | DELETE /return-method/delete/{id} |
Campos y validación (useEditMethod)
countries: z.string().array().min(1) // al menos un país
price: z.number().min(0)
currency: z.string().min(1)
translations: z.record(z.string(), { title, description, instructions }) // los tres, no vacíos
enabled: z.boolean()
priceless: z.boolean()
countriesse elige concountries-popoversobreconstants/countries.ts;currencyconcurrencies-popover.enabledcontrola si el método se ofrece al cliente: los dos portales filtran porenabled === true.pricelesshace que el método no muestre ni descuente precio.- Los valores por defecto al crear son
price: 1,currency: EUR,countries: [ES]y un bloque de traducciones enesvacío.
Traducciones
Cada método lleva un objeto translations indexado por idioma con título, descripción e instrucciones. Se gestiona con dos piezas:
LanguageSelector— añade o quita idiomas del objeto (de los 7 deconstants/languages.ts). Al quitar el último idioma no deja el objeto vacío.RichTextEditor(react-simple-wysiwyg) — edita descripción e instrucciones en HTML, con negrita, cursiva, subrayado, lista, enlace y un botón para ver/editar el HTML crudo.
Ese HTML se renderiza tal cual en los dos portales (dangerouslySetInnerHTML) y se convierte a componentes de PDF en el portal del cliente, que solo soporta un subconjunto de etiquetas (p, ul, li, a, strong, b, em, i, span, br). Etiquetas fuera de esa lista se degradan a texto plano en el PDF. Ver PDFs y URLs firmadas.
2. Motivos de devolución (/reasons)
Los motivos son lo que el cliente selecciona por artículo en el portal público.
| Operación | Acción | Endpoint |
|---|---|---|
| Listar | getReasons | GET /return-reason/info |
| Ver uno | getReason | POST /return-reason/search |
| Crear | newReason | POST /return-reason/new |
| Editar | editReason | PUT /return-reason/edit/{id} |
| Borrar | deleteReason | DELETE /return-reason/delete/{id} |
Esquema mucho más simple que el de métodos (useEditReason):
translations: z.record(z.string(), z.string().min(1)) // un texto por idioma
enabled: z.boolean()
El listado incluye filtros rápidos propios (components/reasons/quick-filters.tsx) y un EnableButton en la columna de acciones para activar/desactivar sin entrar al detalle.
3. Usuarios (/users)
Gestiona los usuarios de Auth0 que tienen acceso al back-office, con su rol y el almacén al que pertenecen.
| Operación | Acción | Endpoint |
|---|---|---|
| Listar | getUsers | GET /return-auth0-user/info |
| Ver uno | getUser | GET /return-auth0-user/info/{id} |
| Crear | newUser | POST /return-auth0-user/new |
| Editar | editUser | PUT /return-auth0-user/edit/{id} |
Columnas del listado: id, email y role.
Validación (useEditUser):
role: z.enum(["ADMIN", "ATC", "STORE", "CUSTOMER"]) // desde constants/roles.ts
id_return_store: z.number() // almacén asignado
La edición envía solo id_return_store y role; el resto de datos del usuario (email, nombre) se administran en Auth0, no aquí. El almacén se elige con warehouse-selector, que ofrece búsqueda sobre el catálogo de almacenes.
El rol asignado aquí es el que después aparece en el claim robo-hawkers.eu.auth0.com/roles del ID token y determina el acceso: cambiar el rol de un usuario cambia lo que ve en el back-office (y, vía scopes, lo que puede hacer contra robo-api).
4. Almacenes (/warehouses)
Asocia cada almacén de devolución con los sources (canales de venta) cuyos pedidos puede recibir.
| Operación | Acción | Endpoint |
|---|---|---|
| Listar | getWarehouses | GET /return-store/info (ordenado por nombre en cliente) |
| Sources | getSources | GET /source/info (ordenado por cd_source_type) |
| Editar | editWarehouse | PUT /return-store/edit/{id} |
Columnas: name, sites (los sources asignados) y una columna para añadir. La edición envía únicamente { sources: id_source } — no se crean ni se borran almacenes desde aquí, solo se reasignan sus canales.
Este catálogo es el que alimenta:
- El selector de almacén de las líneas en el detalle de una devolución.
- El almacén por defecto del alta manual (con la excepción del almacén 61 para Grecia).
- El filtro Almacenes del listado y la columna correspondiente del CSV.