Skip to main content

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ónAcciónEndpoint de robo-api
ListargetMethodsGET /return-method/info
Ver unogetMethodPOST /return-method/search con id_return_method
Buscar por paísgetSearchMethodsPOST /return-method/search con country
CrearnewMethodPOST /return-method/new
EditareditMethodPUT /return-method/edit/{id}
BorrardeleteMethodDELETE /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()
  • countries se elige con countries-popover sobre constants/countries.ts; currency con currencies-popover.
  • enabled controla si el método se ofrece al cliente: los dos portales filtran por enabled === true.
  • priceless hace 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 en es vací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 de constants/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.
caution

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ónAcciónEndpoint
ListargetReasonsGET /return-reason/info
Ver unogetReasonPOST /return-reason/search
CrearnewReasonPOST /return-reason/new
EditareditReasonPUT /return-reason/edit/{id}
BorrardeleteReasonDELETE /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ónAcciónEndpoint
ListargetUsersGET /return-auth0-user/info
Ver unogetUserGET /return-auth0-user/info/{id}
CrearnewUserPOST /return-auth0-user/new
EditareditUserPUT /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ónAcciónEndpoint
ListargetWarehousesGET /return-store/info (ordenado por nombre en cliente)
SourcesgetSourcesGET /source/info (ordenado por cd_source_type)
EditareditWarehousePUT /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.