Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35fdea5df5 | ||
|
|
8d44f2e771 | ||
|
|
ef6dc1f6a8 | ||
|
|
352762b9d2 | ||
|
|
58cc93bb2f | ||
|
|
5eaa94818f | ||
|
|
66a81ad9a3 | ||
|
|
39e1bf61d3 | ||
|
|
b5a1f70d1d | ||
|
|
9d231322b8 | ||
|
|
098ff990a6 | ||
|
|
ff59618a2a | ||
|
|
44e343eca7 | ||
|
|
c77e958f04 | ||
|
|
08fc4174cb |
No files matched your search
@@ -12,6 +12,12 @@ import { createEpaycoClient, type EpaycoEnv } from "../../../../lib/epayco";
|
|||||||
// contra el sandbox real en esta sesion -- se prueban los nombres de
|
// contra el sandbox real en esta sesion -- se prueban los nombres de
|
||||||
// campo mas probables (bankCode/bankName y variantes) y se degrada a
|
// campo mas probables (bankCode/bankName y variantes) y se degrada a
|
||||||
// lista vacia si no matchea nada, en vez de romper el checkout entero.
|
// lista vacia si no matchea nada, en vez de romper el checkout entero.
|
||||||
|
//
|
||||||
|
// Verificado en vivo despues (navegador real, Playwright): el sandbox
|
||||||
|
// real de ePayco incluye un primer elemento placeholder
|
||||||
|
// (bankCode "0", "A continuación seleccione su banco...") mezclado con
|
||||||
|
// los bancos reales -- ningun banco PSE real tiene codigo "0", asi que
|
||||||
|
// se filtra explicitamente en vez de mostrarlo como opcion seleccionable.
|
||||||
const CACHE_TTL_MS = 6 * 60 * 60 * 1000;
|
const CACHE_TTL_MS = 6 * 60 * 60 * 1000;
|
||||||
let cache: { banks: Array<{ pseCode: string; description: string }>; fetchedAt: number } | null = null;
|
let cache: { banks: Array<{ pseCode: string; description: string }>; fetchedAt: number } | null = null;
|
||||||
|
|
||||||
@@ -42,7 +48,7 @@ export async function GET(req: MedusaRequest, res: MedusaResponse) {
|
|||||||
? { pseCode: String(pseCode), description: String(description ?? pseCode) }
|
? { pseCode: String(pseCode), description: String(description ?? pseCode) }
|
||||||
: null;
|
: null;
|
||||||
})
|
})
|
||||||
.filter((bank): bank is { pseCode: string; description: string } => bank !== null);
|
.filter((bank): bank is { pseCode: string; description: string } => bank !== null && bank.pseCode !== "0");
|
||||||
|
|
||||||
cache = { banks, fetchedAt: Date.now() };
|
cache = { banks, fetchedAt: Date.now() };
|
||||||
res.json({ banks });
|
res.json({ banks });
|
||||||
|
|||||||
@@ -244,9 +244,12 @@ reubicó su contenedor según el breakpoint.
|
|||||||
## Consecuencias
|
## Consecuencias
|
||||||
|
|
||||||
- Checkout real de punta a punta (pago + envío calculado) queda
|
- Checkout real de punta a punta (pago + envío calculado) queda
|
||||||
desplegado y verificado a nivel API/backend, pero **ambos proveedores
|
desplegado y verificado con navegador real hasta la redirección al
|
||||||
siguen en modo sandbox** — no se ha completado ni un pago real ni un
|
banco de PSE (ver nota de implementación 2026-09-10 abajo), pero
|
||||||
envío real todavía. Ver checklist de pruebas abajo.
|
**ambos proveedores siguen en modo sandbox** — no se ha completado ni
|
||||||
|
un pago real ni un envío real todavía, y el login bancario de PSE
|
||||||
|
tampoco se completó (falta credencial de prueba). Ver checklist
|
||||||
|
ampliado abajo.
|
||||||
- La precisión de la tarifa de envío depende de cargar peso/dimensiones
|
- La precisión de la tarifa de envío depende de cargar peso/dimensiones
|
||||||
reales por producto — deuda de datos explícita, no de código; candidato
|
reales por producto — deuda de datos explícita, no de código; candidato
|
||||||
natural a extender el importador CSV existente con columnas nuevas.
|
natural a extender el importador CSV existente con columnas nuevas.
|
||||||
@@ -262,37 +265,142 @@ reubicó su contenedor según el breakpoint.
|
|||||||
|
|
||||||
## Checklist de pruebas reales desde el storefront (pendiente, no ejecutado en este ADR)
|
## Checklist de pruebas reales desde el storefront (pendiente, no ejecutado en este ADR)
|
||||||
|
|
||||||
Todo lo de arriba se verificó a nivel API/backend con llamadas directas
|
Todo lo de arriba se verificó primero a nivel API/backend con llamadas
|
||||||
o carritos de prueba armados por API — **no** todavía manejando el
|
directas o carritos de prueba armados por API, sin manejar el
|
||||||
storefront real como lo haría un comprador. Pendiente, con la próxima
|
storefront real como lo haría un comprador. Esa parte del checklist se
|
||||||
sesión que tenga acceso a un navegador real:
|
cerró el 2026-09-10 (ver nota de implementación abajo) usando un
|
||||||
|
navegador real de verdad, no curl.
|
||||||
|
|
||||||
1. **Pago PSE completo:** agregar un producto real al carrito → checkout
|
### RESUELTO (2026-09-10) — navegador real vía Docker en la NAS
|
||||||
→ elegir PSE → seleccionar un banco del listado real (sandbox) →
|
|
||||||
confirmar que la redirección al banco ocurre (esto es justo lo que
|
El shell donde corren los comandos de esta sesión tiene su propia red
|
||||||
nunca se probó — el nombre del campo de URL de `bank.create()` está
|
restringida para `npm` (un proxy interno que rompe algunas descargas de
|
||||||
manejado a la defensiva y podría no matchear ningún candidato) →
|
paquetes — no relacionado con la red real del lab). **Docker en la NAS
|
||||||
volver a `/checkout/pse/return` → confirmar que la orden queda en
|
sí sale a internet real, sin ese filtro** — confirmado en vivo
|
||||||
estado correcto.
|
(`docker pull` normal, un contenedor de Node golpeando
|
||||||
2. **Envío calculado real:** en el paso de dirección del checkout,
|
`registry.npmjs.org` sin problema). Se armó un harness reutilizable con
|
||||||
confirmar que el precio de envío mostrado ya no es el fijo de
|
la imagen oficial `mcr.microsoft.com/playwright:v1.51.1-jammy`
|
||||||
$15.000 sino el que devuelve EnvíoClick en vivo para esa dirección
|
(Chromium real) corrida puntualmente contra `shop.cruzcloud.net`,
|
||||||
(visible también sin completar el pago, solo llegando al paso de
|
guardado en `.browser-scratch/` en la raíz del lab (`checks.mjs` +
|
||||||
shipping).
|
`README.md` con el comando exacto para reactivarlo — no hace falta
|
||||||
3. **Resiliencia del fallback de envío:** si es posible, forzar una
|
ningún contenedor corriendo de forma persistente, la imagen y las
|
||||||
dirección o producto que haga fallar la cotización real (por ejemplo,
|
dependencias ya quedan cacheadas localmente en la NAS).
|
||||||
un DANE code inválido) y confirmar que el checkout sigue avanzando
|
|
||||||
con el precio de respaldo en vez de romperse — el comportamiento
|
**Hallazgo no obvio:** el daemon de Docker de la NAS ve un filesystem
|
||||||
documentado en `calculatePrice()`, nunca ejercitado con un fallo real.
|
distinto al que ve el shell de esta sesión (que corre en su propio
|
||||||
4. **Banner dinámico:** confirmar en `/` que el carrusel muestra
|
sandbox, aunque monte los mismos repos git) — un volumen `-v` apuntando
|
||||||
productos reales del catálogo (no las tres imágenes viejas
|
a un path de `/tmp` del shell no tira error pero monta un directorio
|
||||||
hardcodeadas) y que cada slide lleva al producto correcto al hacer
|
vacío del lado del contenedor. Hay que usar un path bajo
|
||||||
clic.
|
`/media/HDD-Storage/AppData/k3d-lab-v3/lab-cruzcloud/` (montaje real
|
||||||
5. **Buscador:** en un viewport mobile real (no solo devtools), confirmar
|
compartido) para que el contenedor vea los archivos de verdad.
|
||||||
que el buscador ya no se ve recortado y que el autocompletado
|
|
||||||
despliega bien debajo de la fila nueva a todo el ancho.
|
**Resultados, con capturas reales:**
|
||||||
6. **Webhook de ePayco con un pago real de sandbox:** confirmar que,
|
|
||||||
tras completar un pago PSE de prueba desde el banco sandbox, el
|
1. **Pago PSE completo — FUNCIONA.** Carrito → dirección Bogotá →
|
||||||
webhook mueve la orden a completada sin intervención manual (hoy solo
|
envío calculado → banco PSE (sandbox) → **la redirección real
|
||||||
se confirmó que el endpoint responde `200` a un `POST` sintético, no
|
funcionó**: el nombre de campo manejado a la defensiva en
|
||||||
con un webhook real disparado por ePayco).
|
`bank.create()`/`initiatePayment` matcheó al primer intento, y el
|
||||||
|
navegador llegó a la página real de autorización de PSE
|
||||||
|
(`registro.desarrollo.pse.com.co`, ambiente de desarrollo/sandbox
|
||||||
|
de PSE Colombia). No se completó el login bancario (requiere
|
||||||
|
credenciales de prueba específicas de PSE que no se tenían a mano) —
|
||||||
|
sigue pendiente confirmar el webhook con un pago sandbox completado
|
||||||
|
de principio a fin (ver checklist nuevo abajo).
|
||||||
|
2. **Envío calculado real — FUNCIONA.** El paso de pago mostró
|
||||||
|
`Envío $8.941` (mismo valor ya visto en la verificación por API de
|
||||||
|
la sección anterior) en vez del fijo de $15.000, para una dirección
|
||||||
|
real de Bogotá.
|
||||||
|
3. **Banner dinámico — funciona, pero destapó un bug real:** un
|
||||||
|
producto marcado `featured: true` pero **sin stock**
|
||||||
|
(`available: false`, "Toy Story 5 - Rex") salía primero en el
|
||||||
|
carrusel con botón "Comprar ahora" hacia una página donde en
|
||||||
|
realidad no se puede comprar. Corregido en el mismo commit que este
|
||||||
|
hallazgo (filtro adicional `&& product.available` en
|
||||||
|
`app/page.tsx`).
|
||||||
|
4. **Buscador mobile — funciona.** El buscador ya no se ve recortado,
|
||||||
|
y el autocompletado despliega bien debajo de la fila nueva a todo el
|
||||||
|
ancho (probado con el viewport de un iPhone 13 real, no devtools).
|
||||||
|
5. **Bug adicional encontrado, no buscado:** el sandbox real de ePayco
|
||||||
|
(`bank.getBanks()`) devuelve un primer elemento placeholder
|
||||||
|
(`bankCode: "0"`, `"A continuación seleccione su banco..."` con el
|
||||||
|
texto mal decodificado — unicode escapado literal) mezclado con los
|
||||||
|
bancos reales, mostrado como una opción más, seleccionable, en el
|
||||||
|
`<select>` del checkout. Ningún banco PSE real tiene código "0" —
|
||||||
|
se filtra explícitamente en `pse-banks/route.ts`.
|
||||||
|
|
||||||
|
### Pendiente — checklist ampliado para la próxima sesión con navegador
|
||||||
|
|
||||||
|
3. **Resiliencia del fallback de envío:** forzar una dirección o
|
||||||
|
producto que haga fallar la cotización real de EnvíoClick (ej. un
|
||||||
|
DANE code inválido) y confirmar que el checkout sigue avanzando con
|
||||||
|
el precio de respaldo ($15.000) en vez de romperse — comportamiento
|
||||||
|
documentado en `calculatePrice()`, nunca ejercitado con un fallo
|
||||||
|
real.
|
||||||
|
6. **Webhook de ePayco con un pago real de sandbox completado:**
|
||||||
|
conseguir credenciales de prueba reales de PSE (persona/clave de
|
||||||
|
algún banco del ambiente `desarrollo`), completar el login bancario
|
||||||
|
de punta a punta, y confirmar que el webhook mueve la orden a
|
||||||
|
completada sin intervención manual — hoy solo se confirmó que el
|
||||||
|
endpoint responde `200` a un `POST` sintético y que la redirección
|
||||||
|
al banco ocurre, no el ciclo completo con notificación real.
|
||||||
|
Ampliado 2026-09-10 con el resto de la superficie real del storefront
|
||||||
|
(4 páginas + `components/{account,cart,catalog,checkout,home,layout,
|
||||||
|
product,search,wishlist}`), agrupado por riesgo:
|
||||||
|
|
||||||
|
**Checkout / pagos**
|
||||||
|
|
||||||
|
7. **Pago cancelado o rechazado en el banco PSE:** confirmar que la
|
||||||
|
orden no queda en un estado ambiguo ("colgada" en
|
||||||
|
`pending_authorization` para siempre) cuando el comprador cancela o
|
||||||
|
el banco rechaza — hoy solo se probó el camino feliz hasta la
|
||||||
|
redirección.
|
||||||
|
8. **Persona jurídica + NIT** en el formulario de PSE — solo se probó
|
||||||
|
persona natural con cédula.
|
||||||
|
9. **`/checkout` con carrito vacío** (acceso directo por URL, sin pasar
|
||||||
|
por un producto primero).
|
||||||
|
10. **Fallback "Confirmar por WhatsApp"** (visible cuando falla la
|
||||||
|
lista de bancos o como alternativa siempre disponible): que el link
|
||||||
|
arme el mensaje correcto con los datos del pedido.
|
||||||
|
|
||||||
|
**Catálogo y búsqueda**
|
||||||
|
|
||||||
|
11. **Filtros de `/catalog`** (categoría/colección/marca/precio — las
|
||||||
|
facetas de Meilisearch, ver ADR 0006) con navegador real: que
|
||||||
|
aplicar/combinar filtros actualice los resultados y la URL.
|
||||||
|
12. **Búsqueda sin resultados** — confirmar que muestra un mensaje
|
||||||
|
claro en vez de quedar vacío sin explicación.
|
||||||
|
|
||||||
|
**Producto**
|
||||||
|
|
||||||
|
13. **Selección de variantes** (cuando un producto tiene más de una) y
|
||||||
|
que el precio/disponibilidad mostrado cambie según la variante
|
||||||
|
elegida.
|
||||||
|
14. **Slug de producto inválido** → debe caer en `not-found.tsx`
|
||||||
|
(`app/not-found.tsx`), no en un error sin manejar.
|
||||||
|
15. **Zoom interactivo del producto** (hover + modal click-to-zoom,
|
||||||
|
`product-gallery.tsx`) — re-verificar con navegador real, la última
|
||||||
|
vez que se probó fue antes de esta tanda de cambios al storefront.
|
||||||
|
|
||||||
|
**Cuenta y wishlist**
|
||||||
|
|
||||||
|
16. **Login/registro de cliente real** (Google OAuth de punta a punta
|
||||||
|
incluyendo `/auth/google/callback`, y con contraseña) — nunca
|
||||||
|
ejercitado con un navegador real en ninguna sesión.
|
||||||
|
17. **Wishlist/favoritos** (`wishlist-drawer.tsx`): agregar/quitar y
|
||||||
|
confirmar que persiste entre recargas (guardado en `localStorage`,
|
||||||
|
por-viewer — no hay forma de verificarlo por API).
|
||||||
|
|
||||||
|
**Transversal**
|
||||||
|
|
||||||
|
18. **Bug conocido de Firefox Android** (ver memoria de proyecto,
|
||||||
|
`known-bug-firefox-android-layout`): el layout se corta/desplaza
|
||||||
|
solo en Firefox Android — Playwright puede emular Android/Chrome
|
||||||
|
pero no Firefox; si se necesita reproducir esto específicamente hace
|
||||||
|
falta `playwright-firefox` o un dispositivo real.
|
||||||
|
19. **Otros viewports** (tablet, desktop grande) para el banner y el
|
||||||
|
buscador — solo se probaron mobile (iPhone 13) y desktop 1280px.
|
||||||
|
20. **Página 404** (`app/not-found.tsx`) — nunca visitada con navegador
|
||||||
|
real.
|
||||||
|
21. **Accesibilidad básica**: navegación completa por teclado (tab
|
||||||
|
order, foco visible) en el checkout y el buscador — Playwright
|
||||||
|
puede simular esto (`page.keyboard`), no probado todavía.
|
||||||
@@ -25,7 +25,7 @@ spec:
|
|||||||
runAsNonRoot: false
|
runAsNonRoot: false
|
||||||
containers:
|
containers:
|
||||||
- name: app
|
- name: app
|
||||||
image: gitea.cruzcloud.net/devops/docs-portal:v1.0.224
|
image: gitea.cruzcloud.net/devops/docs-portal:v1.0.242
|
||||||
# El base saca TODAS las capabilities. Probado en vivo y
|
# El base saca TODAS las capabilities. Probado en vivo y
|
||||||
# revertido: con drop: ALL (aunque se agregue NET_BIND_SERVICE
|
# revertido: con drop: ALL (aunque se agregue NET_BIND_SERVICE
|
||||||
# de vuelta) el propio entrypoint de nginx:1.27-alpine falla al
|
# de vuelta) el propio entrypoint de nginx:1.27-alpine falla al
|
||||||
|
|||||||
@@ -21,9 +21,13 @@ export default async function HomePage() {
|
|||||||
// ADR 0010: el banner toma primero productos destacados (curaduria
|
// ADR 0010: el banner toma primero productos destacados (curaduria
|
||||||
// explicita del admin via el flag "featured"); si no hay ninguno,
|
// explicita del admin via el flag "featured"); si no hay ninguno,
|
||||||
// cae a los mismos "tesoros" (nuevos/destacados) de la seccion de
|
// cae a los mismos "tesoros" (nuevos/destacados) de la seccion de
|
||||||
// abajo para no repetir la logica de seleccion.
|
// abajo para no repetir la logica de seleccion. Se exige ademas
|
||||||
const featuredProducts = products.filter((product) => product.featured);
|
// "available" -- encontrado probando en vivo con un navegador real
|
||||||
const bannerProducts = featuredProducts.length > 0 ? featuredProducts : treasures;
|
// (Playwright): un producto featured pero sin stock disponible salio
|
||||||
|
// primero en el carrusel con boton "Comprar ahora" hacia una pagina
|
||||||
|
// donde en realidad no se puede comprar.
|
||||||
|
const featuredProducts = products.filter((product) => product.featured && product.available);
|
||||||
|
const bannerProducts = featuredProducts.length > 0 ? featuredProducts : treasures.filter((product) => product.available);
|
||||||
return <><HeroCarousel products={bannerProducts} /><TrustBar /><div className="content-auto"><CategoryTiles categories={categories} /></div><section className="content-auto mx-auto max-w-7xl px-4 py-14"><div className="mb-8 flex items-end justify-between gap-5"><div><span className="text-xs font-black uppercase tracking-[.18em] text-ari-coral">Novedades</span><h2 className="mt-2 text-4xl font-black tracking-tight sm:text-5xl">Tesoros recién llegados</h2><p className="mt-3 text-slate-500">Desliza y encuentra nuevos favoritos.</p></div><Button asChild variant="outline" className="hidden sm:inline-flex"><Link href="/catalog">Ver catálogo <ArrowRight className="size-4" /></Link></Button></div><ProductCarousel products={treasures} /></section><section className="content-auto mx-auto max-w-7xl px-4 pb-20"><div className="grid overflow-hidden rounded-[2rem] bg-ari-marino text-white shadow-2xl lg:grid-cols-[1fr_.7fr]"><div className="p-8 sm:p-12"><span className="text-xs font-black uppercase tracking-[.18em] text-ari-coral-claro">Club ARI</span><h2 className="mt-3 text-4xl font-black tracking-tight sm:text-6xl">Promociones, lanzamientos y mucha diversión.</h2><p className="mt-5 max-w-xl text-white/80">Únete a nuestra comunidad y recibe primero las novedades del catálogo.</p><Button variant="yellow" size="lg" className="mt-7">Quiero unirme</Button></div>{/* No hay herramienta de generacion de imagenes disponible para crear un
|
return <><HeroCarousel products={bannerProducts} /><TrustBar /><div className="content-auto"><CategoryTiles categories={categories} /></div><section className="content-auto mx-auto max-w-7xl px-4 py-14"><div className="mb-8 flex items-end justify-between gap-5"><div><span className="text-xs font-black uppercase tracking-[.18em] text-ari-coral">Novedades</span><h2 className="mt-2 text-4xl font-black tracking-tight sm:text-5xl">Tesoros recién llegados</h2><p className="mt-3 text-slate-500">Desliza y encuentra nuevos favoritos.</p></div><Button asChild variant="outline" className="hidden sm:inline-flex"><Link href="/catalog">Ver catálogo <ArrowRight className="size-4" /></Link></Button></div><ProductCarousel products={treasures} /></section><section className="content-auto mx-auto max-w-7xl px-4 pb-20"><div className="grid overflow-hidden rounded-[2rem] bg-ari-marino text-white shadow-2xl lg:grid-cols-[1fr_.7fr]"><div className="p-8 sm:p-12"><span className="text-xs font-black uppercase tracking-[.18em] text-ari-coral-claro">Club ARI</span><h2 className="mt-3 text-4xl font-black tracking-tight sm:text-6xl">Promociones, lanzamientos y mucha diversión.</h2><p className="mt-5 max-w-xl text-white/80">Únete a nuestra comunidad y recibe primero las novedades del catálogo.</p><Button variant="yellow" size="lg" className="mt-7">Quiero unirme</Button></div>{/* No hay herramienta de generacion de imagenes disponible para crear un
|
||||||
asset nuevo -- se reconstruye el mismo efecto (fondo punteado +
|
asset nuevo -- se reconstruye el mismo efecto (fondo punteado +
|
||||||
fotos estilo polaroid) con CSS y fotos reales de producto ya
|
fotos estilo polaroid) con CSS y fotos reales de producto ya
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ spec:
|
|||||||
memory: 64Mi
|
memory: 64Mi
|
||||||
|
|
||||||
- name: migrations
|
- name: migrations
|
||||||
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.234
|
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.239
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- node
|
- node
|
||||||
@@ -86,7 +86,7 @@ spec:
|
|||||||
|
|
||||||
containers:
|
containers:
|
||||||
- name: app
|
- name: app
|
||||||
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.234
|
image: gitea.cruzcloud.net/devops/ecommerce-medusa:v1.0.239
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
|
|||||||
@@ -87,6 +87,18 @@ export function PredictiveSearch() {
|
|||||||
Buscando…
|
Buscando…
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{/* Encontrado probando en vivo con navegador real: sin este bloque,
|
||||||
|
una busqueda de 2+ caracteres sin coincidencias no mostraba nada
|
||||||
|
(ni "buscando" ni un mensaje) -- el usuario se quedaba sin ningun
|
||||||
|
feedback de que su busqueda de verdad corrio. Se ofrece igual el
|
||||||
|
boton de buscar en todo el catalogo porque esa busqueda completa
|
||||||
|
puede usar criterios mas amplios que el autocompletado. */}
|
||||||
|
{!loading && normalized.length >= 2 && matches.length === 0 && (
|
||||||
|
<div className="absolute left-0 right-0 top-[calc(100%+10px)] z-50 rounded-2xl border border-slate-200 bg-white p-2 text-center shadow-2xl">
|
||||||
|
<p className="p-3 text-sm text-slate-500">No encontramos resultados para “{query.trim()}”.</p>
|
||||||
|
<button type="submit" className="w-full rounded-xl bg-ari-marino px-4 py-3 text-sm font-black text-white hover:brightness-110">Buscar “{query.trim()}” en todo el catálogo</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{matches.length > 0 && (
|
{matches.length > 0 && (
|
||||||
<div className="absolute left-0 right-0 top-[calc(100%+10px)] z-50 overflow-hidden rounded-2xl border border-slate-200 bg-white p-2 shadow-2xl">
|
<div className="absolute left-0 right-0 top-[calc(100%+10px)] z-50 overflow-hidden rounded-2xl border border-slate-200 bg-white p-2 shadow-2xl">
|
||||||
{matches.map((product) => (
|
{matches.map((product) => (
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ spec:
|
|||||||
runAsUser: 1001
|
runAsUser: 1001
|
||||||
containers:
|
containers:
|
||||||
- name: app
|
- name: app
|
||||||
image: gitea.cruzcloud.net/devops/ecommerce-frontend:v1.0.235
|
image: gitea.cruzcloud.net/devops/ecommerce-frontend:v1.0.240
|
||||||
env:
|
env:
|
||||||
- name: HEADLESS_PROVIDER
|
- name: HEADLESS_PROVIDER
|
||||||
value: medusa
|
value: medusa
|
||||||
|
|||||||
Reference in new issue
Block a user