Estuche abierto · 2026Sistema Administrativo
Joyería
Una sola app para la joyería: taller, inventario de metales, ventas, catálogo público y tienda del cliente.
Desarrollo frontend en equipo (React + TypeScript): 129 de los 246 commits del repositorio; el resto es de un segundo desarrollador.
44.782
líneas de TypeScript/TSX en src/
106
rutas de API consumidas
6
roles de usuario
Estado
En desarrollo activo con despliegue a producción: `.env.production` apunta a https://sandracanizarezapp.store con versión `/prod`, hay carpeta `build/` generada y un `.htaccess` de reescritura SPA para Apache. Último commit: 11-06-2026.
La misma cinta que el vendedor ve bajo la cabecera · pasa el ratón para detenerla
Ningún ERP genérico sabe
cuánto pesa una pieza
Una joyería con taller propio mezcla operaciones que ningún ERP genérico modela bien: el precio de cada pieza depende de la cotización del oro y de la TRM del día, el inventario no se cuenta en unidades sino en gramos de oro 18K, plata 925 o quilates de piedra, y una venta puede ser una orden hecha a mano por un joyero interno con anticipo, medidas y fotos de referencia. A eso se suma que en el negocio conviven perfiles con permisos y necesidades opuestos —el dueño, el vendedor de mostrador, el joyero del taller y el cliente final que compra en línea— y que cada uno necesitaba antes una herramienta distinta: WhatsApp para hablar con el cliente, hojas de cálculo para el inventario y una tienda separada para vender.
Gramos de oro 18K, no unidades
Precio atado a la cotización y a la TRM
WhatsApp, hojas de cálculo y tienda aparte
Un solo bundle que se reparte en cuatro árboles de rutas
Un solo SPA en React + TypeScript que decide en tiempo de arranque, a partir del rol guardado en `localStorage`, cuál de los cuatro árboles de rutas monta, reutilizando el mismo layout (`FooterHeaderSidebar`) y el mismo proveedor de chat global. Sobre esa base se construyeron los módulos verticales del negocio: inventario por tipo de material con recálculo en cascada de precios cuando cambia la cotización del metal, ventas divididas en stock y órdenes a medida con asignación de joyero y vendedor, panel de taller con tabs por estado de orden, tienda del cliente con carrito y checkout, y una landing pública que se alimenta de las categorías y productos reales del API. El chat vive por encima de todas las pantallas con una única conexión WebSocket por usuario, para que la burbuja de mensajes no dependa de estar dentro del chat.
Seis piezas sobre el mismo terciopelo
El rol numérico que devuelve el backend decide, en el arranque, qué aplicación monta el navegador. Layout, chat y ticker se comparten; sólo cambian los destinos.
Admin general
Da de alta joyerías, categorías globales y la compartición de catálogo entre aliadas.
Administrador
Dashboard, ventas, inventario, clientes, catálogo, notificaciones y configuración de su joyería.
Vendedor
Ventas de stock y órdenes personalizadas, con chat por orden y por venta desde el mostrador.
Joyero
Entra directo a /trabajo: pendientes, en progreso y completadas, con el detalle de cada pieza.
Cliente
Tienda con filtros combinables, carrito multi-joyería, checkout y seguimiento de sus compras.
Usuario
Catálogo público y detalle de producto compartible por URL, sin necesidad de sesión.
29 declaraciones de ruta · 17 rutas únicas · un único layout
Cinco piezas bajo el foco
Pasa el cursor: la luz sigue a la pieza que estás mirando, como en el mostrador.
Seis roles, un solo bundle
`App.tsx` traduce el `rol` numérico del backend (1 a 6) a admin general, admin, vendedor, joyero, cliente o usuario, y monta el árbol de `<Route>` correspondiente: 29 declaraciones de ruta sobre 17 rutas únicas, compartiendo layout, chat y modales de mensajes.
Chat en vivo con un único WebSocket global
`useGlobalChatSocket` abre una sola conexión `wss://…/ws/chat/` por usuario, con keepalive de ping cada 30 s y reconexión con backoff exponencial de 1 s a 30 s; el provider combina el contador REST persistente, el evento `unread_update` y las notificaciones para que ningún mensaje se pierda.
Inventario que entiende de metales
Los materiales se registran como metal (con quilataje), piedra (con quilates, color y pureza), componente u 'otros', con movimientos, préstamos externos y un ticker que muestra oro 24K/18K/14K/10K, plata pura/950/925, platino y paladio junto a la TRM del día.
Taller y órdenes a medida
El módulo de órdenes personalizadas captura cliente, joyero asignado, prenda, material del inventario, medidas, peso, mano de obra, anticipo y fotos de referencia recortadas en el navegador; el joyero ve las mismas órdenes en su panel separadas en pendientes, en progreso y completadas.
Escaparate público y tienda del cliente
La landing y el catálogo públicos consumen categorías y productos reales del API, y el cliente registrado entra a una tienda con buscador, filtros por joyería, material, género y rango de precio, vista en grilla o lista, carrito, checkout y seguimiento de sus órdenes y compras.
Paleta de la casa
Joyería clásica colombiana: burdeos profundo de terciopelo, oro cálido, crema de vitrina y tinta parda; elegante, cálido y ligeramente señorial, con el dorado reservado para lo que debe brillar.
src/pages-routes/landing/Landing.css y src/pages-routes/login/Login.css (:root --burgundy #8d0101, --burgundy-dark #5e0101, --gold #b8893b, --gold-soft #c9a24b, --ink #2b2424, --cream #f7f2ec, --line #e7ddd2); tokens de sistema en src/styles/brand.css (--brand-strong #8b0000, --brand-soft #4a0e0e, --cream #f7f2ec) registrados como utilidades Tailwind en src/index.css. El degradado es el del botón dorado `.landing-btn-gold`.
La cara pública, recreada entera
Landing pública de la joyería
Descubre el Brillo
de lo Inolvidable
Piezas hechas a mano en nuestro taller de Cúcuta, pensadas para durar toda una vida.
Joyería Cúcuta · Colombia
Oro, Piedras preciosas
Sets
Anillos
Cadenas
Aretes
Joyas para mamá
Ver Colección →

Tendencias
Ver Colección →

Sets para Regalar
Ver Colección →
Nuestra selección
Piezas destacadas

Anillos
Anillo ANLA043
$ 1.280.000

Anillos
Anillo ANLA047
$ 940.000

Anillos
Anillo oro 18k
$ 2.150.000

Diseña tu propia joya
Cuéntanos qué tienes en mente y lo trabajamos contigo, pieza por pieza.
Asesoría por WhatsApp
Cadenas personalizadas

Pulseras grabadas

Sets a medida

Anillos de compromiso
María C.
✓ Verificada
El anillo quedó idéntico al diseño que llevé. Trabajo impecable.
Jorge R.
✓ Verificada
Me asesoraron por WhatsApp y me lo enviaron a Bogotá en dos días.
Laura P.
✓ Verificada
Compré el set para mi mamá y le encantó. Vuelvo seguro.
Cúcuta, Norte de Santander · Colombia
Lunes a sábado, 9:00 a 19:00
Instagram · Facebook · WhatsApp
Marquesina · vídeo de portada real · colecciones del API · destacados con esqueleto · reseñas · pie burdeos
Lo que ve el cliente
Tienda del cliente
Catálogo de joyeria
Explora las piezas disponibles en todas las joyerías aliadas.
Piezas disponibles
48 productos
DestacadoAnillo ANLA043
Sandra Cañizarez

Anillo ANLA047
Sandra Cañizarez
No DisponibleAnillo oro 18k
Sandra Cañizarez
DestacadoSet completo
Joyería aliada
Dentro del sistema, pieza a pieza
El panel del administrador y el del joyero, recreados sobre el paño oscuro: el mismo layout, el mismo ticker de cotizaciones y dos navegaciones distintas según quién entra.
Dashboard del administrador
Ventas del mes, tendencia, más vendidos, notificaciones y acciones rápidas.
Panel de trabajo del joyero
Tres contadores, tres pestañas y una navegación inferior de sólo dos destinos.
Inventario de materiales
Metales, piedras y componentes del taller
Total materiales
126
Movimientos hoy / ayer
14 / 9
Costo del inventario
$ 318.940.000
Oro 18K
En stockMetal · 18 quilates
Plata 925
En stockMetal · 925
Esmeralda
Stock bajoPiedra · 0,8 ct · verde · VS
Oro 14K
Stock bajoMetal · 14 quilates
Broche mosquetón
En stockComponente
Rodio de baño
Stock bajoOtros
Las maquetas reproducen la interfaz real; los datos que muestran son de ejemplo.
Los materiales que trae la marca
Banners de colección, fotografía de producto y tarjetas de personalización: los assets reales que consume la landing pública. Arrástralos.












Diecisiete cajones que ya abren
Todo lo que está construido y funcionando dentro del mismo bundle.
Con qué está engastado
Base
UI y estilos
Formularios y datos
Integración
Cinco capas dentro de src/
Cada bandeja delega en la de abajo. Nada habla con el backend fuera de la capa de servicios.
App.tsx
Orquestador
Lee token y rol de localStorage, expone AuthContext y elige uno de los cuatro árboles de rutas.
4 árbolespages-routes/
Pantallas
Una carpeta por destino; sólo componen y delegan la lógica en el módulo de dominio.
21 carpetascomponents/<Modulo>/
Dominio
interfaces · functions · modals · ui y un contexto propio: Inventory, Sales, Clients, Settings, Catalog.
5 contextoscomponents/service/
Datos
Un único apiAxios: baseURL de entorno, JSON o multipart según el payload e interceptor de 401.
25 móduloscomponents/ui/
Base
Componentes tipo shadcn sobre Radix; la paleta vive en brand.css y se registra con @theme inline.
53 piezasSPA por capas dentro de `src/`. `App.tsx` es el orquestador: lee token y rol de `localStorage`, expone un `AuthContext` global (usuario, joyería, carrito, estadísticas de notificaciones, modal de mensajes) y elige uno de cuatro árboles de rutas —joyero, cliente/usuario, administrativo y público— todos envueltos por `FooterHeaderSidebar` y por `ChatNotificationsProvider`. Las pantallas viven en `src/pages-routes/` (21 carpetas) y delegan la lógica en módulos de dominio dentro de `src/components/<Modulo>/`, cada uno con la misma estructura: `interfaces/`, `functions/`, `modals/`, `ui/` y un contexto propio (`InventoryContext`, `SalesContext`, `ClientsContext`, `SettingsContext`, `CatalogContext`). Toda la comunicación con el backend pasa por `src/components/service/`, 25 carpetas de servicios tipados que usan un único `apiAxios` con baseURL de entorno, `Accept-Language: es-ES`, selección automática entre JSON, `multipart/form-data` y `x-www-form-urlencoded` según el payload, toast de carga y un interceptor de respuesta que ante un 401 emite el evento `auth:unauthorized` en `window`. La capa de presentación reutiliza 53 componentes base tipo shadcn/ui sobre Radix en `src/components/ui/`, y la paleta de marca se define una sola vez en `src/styles/brand.css` y se registra como tokens de Tailwind en `src/index.css` con `@theme inline`, de modo que cambiar el burdeos cambia toda la app.
Cinco problemas y su solución dentro
Abre cada cajón: arriba lo que se rompía, dentro lo que lo arregló.
La solución
El rol numérico del backend se traduce a un literal de unión tipado (`UserRole`) y `App.tsx` monta un `<Routes>` distinto por familia de rol, con `<Route path="*">` que redirige al home propio de cada uno; el layout, el chat y el ticker de metales se comparten y sólo cambian los `navItems`, filtrados por rol en `FooterHeaderSidebar`.
La solución
El interceptor de respuesta de axios centraliza el caso: ante un 401 despacha un evento `auth:unauthorized` en `window`; `App.tsx` lo escucha, muestra el modal de sesión expirada, limpia token y rol de `localStorage` y redirige a `/iniciar`.
La solución
Una sola conexión montada a nivel de app en `ChatNotificationsProvider`, con `useGlobalChatSocket` (ping cada 30 s, backoff exponencial de 1 s a 30 s y resincronización al reconectar) que combina tres capas: contador REST persistente, evento `unread_update` en vivo y notificaciones almacenadas; si la conversación está abierta se marca leída en vez de avisar.
La solución
Endpoints de sincronización disparables desde la interfaz (`config/metals/sync-prices-cascade/` y `stocktaking/{joyería}/product/sync-prices/`) más un historial de tasas y un ticker permanente con oro 24K a 10K, plata, platino y paladio para que el vendedor vea siempre la referencia vigente.
La solución
`ImageCropperModal` recorta en el navegador con `react-easy-crop` y vuelca el resultado a un canvas antes de subirlo; en desarrollo un proxy `/image-proxy` en `vite.config.ts` reescribe las peticiones al dominio del API, y `ImageWithFallback` cubre las imágenes que aun así fallan.
Lo que hay en la caja
44.782
líneas de TypeScript/TSX en src/
224
archivos .ts y .tsx
106
rutas de API consumidas
25
módulos de servicio
6
roles de usuario
17
rutas de navegación
53
componentes UI base
246
commits en el repositorio
Frontend completo del sistema administrativo de la joyería Sandra Cañizarez (Cúcuta, Colombia): un único SPA en React + TypeScript que sirve simultáneamente a seis roles — admin general, administrador de joyería, vendedor, joyero, cliente y usuario — con un árbol de rutas distinto para cada uno.
No es sólo un panel: incluye la landing pública de la marca (con vídeo de portada, colecciones traídas del API y reseñas), el catálogo público, la tienda con carrito y checkout para el cliente, y el panel de trabajo del joyero con sus órdenes por estado.
El núcleo administrativo cubre ventas de stock y órdenes personalizadas, inventario de materiales (metales por quilataje, piedras, componentes), préstamos externos, clientes, catálogo, notificaciones y configuración de la joyería (cuentas bancarias, empleados y roles, categorías, facturación con logo y firma digital).
Todo el estado del negocio vive en un backend REST propio: 25 módulos de servicio en el front consumen 106 rutas de API distintas, más un WebSocket global para el chat entre cliente, vendedor y joyero.
La capa visual combina Tailwind CSS v4 con tokens de marca propios (burdeos y oro) y una biblioteca de 53 componentes base sobre primitivas de Radix UI.
Sistema Administrativo Joyería
¿Quieres algo así para tu producto?
Un ERP vertical con e-commerce dentro: seis roles, inventario que entiende de metales y chat en vivo, todo en un solo frontend. Si tu negocio tiene un taller detrás del mostrador, es exactamente este terreno.
El estuche se cierra. La pieza queda dentro.