90 lines
3.7 KiB
Markdown
90 lines
3.7 KiB
Markdown
# F-061 — Implementer evidence
|
||
|
||
## Scope delivered
|
||
|
||
On the product detail page (`/products/[slug]`) the image container had
|
||
`aspect-[5/7] max-h-[500px]`. That bounded the container to roughly 357×500
|
||
even when the grid cell was ~616 px wide on desktop (lg+ 2-col layout), so
|
||
the container was left-aligned inside its cell with empty space on the
|
||
right. The same problem appeared at tablet widths where the single
|
||
column cell is much wider than 357 px. The user pointed at `/checkout`
|
||
as the reference behaviour: the checkout layout lets each cell's
|
||
content fill the cell width and centres the visual content inside via
|
||
`flex items-center justify-center` / `object-contain`.
|
||
|
||
## Change
|
||
|
||
`project/frontend/src/app/products/[slug]/page.tsx`
|
||
|
||
The image container no longer enforces `aspect-[5/7]`. It now uses the
|
||
same pattern as `/checkout`: the container fills the column and the
|
||
image is centred inside via `object-contain`:
|
||
|
||
```tsx
|
||
<div className="relative w-full max-h-[500px] bg-gray-50 rounded-2xl border border-gray-100 overflow-hidden">
|
||
{product.images?.[0] ? (
|
||
<Image
|
||
src={product.images[0].url}
|
||
alt={product.name}
|
||
fill
|
||
className="object-contain"
|
||
priority
|
||
sizes="(max-width: 1024px) 100vw, 50vw"
|
||
/>
|
||
) : (
|
||
<span className="absolute inset-0 flex items-center justify-center text-8xl">🌿</span>
|
||
)}
|
||
</div>
|
||
```
|
||
|
||
Why this is the right pattern:
|
||
|
||
- `w-full` makes the container fill the grid cell on every breakpoint
|
||
(desktop, tablet, mobile). The image is therefore always horizontally
|
||
centred within its block.
|
||
- `max-h-[500px]` still bounds the height so very tall images don't
|
||
push the rest of the page down.
|
||
- The `<Image fill>` + `object-contain` keeps the source aspect ratio
|
||
intact; non-square images are letterboxed inside the wide container
|
||
with the empty space shared equally on both sides — which is the
|
||
expected behaviour for product imagery.
|
||
- The 🌿 fallback uses `absolute inset-0 flex items-center justify-center`
|
||
so it stays centred even without an `<Image>`.
|
||
|
||
## Acceptance traceability
|
||
|
||
| Acceptance criterion | How it is met |
|
||
| -------------------- | ------------- |
|
||
| Image container centred horizontally inside its grid cell on desktop (2 cols) and mobile (1 col) | `w-full` makes the container span the full cell width; `object-contain` centres the visual image inside the container. |
|
||
| No empty space on the right of the image on desktop with 2-col layout | The container now fills the column, so the image is centred, not pinned to the left edge. |
|
||
| Image stays inside its bounding box on tablet widths (`max-w` cap) | `max-h-[500px]` caps the height. `w-full` lets the container span the cell, but the container never exceeds `max-h-[500px]` so the page layout is preserved. |
|
||
| Description cell unchanged | The `<div>` containing brand, price, stock, button, description, categories, SKU was not touched. |
|
||
| `verify.sh` is green | Exit 0. |
|
||
|
||
## Manual verification
|
||
|
||
```
|
||
$ curl http://192.168.18.93:3003/products/proteina-guisante-ecologica | grep -oE 'relative w-full max-h-\[500px\][^"]*'
|
||
relative w-full max-h-[500px] bg-gray-50 rounded-2xl border border-gray-100 overflow-hidden
|
||
|
||
$ curl http://192.168.18.93:3003/products/proteina-guisante-ecologica | grep -oE 'aspect-\[5/7\]'
|
||
(no match in the image container)
|
||
```
|
||
|
||
The container fills the column; the image is rendered with
|
||
`object-contain`, so a square source (800×800) displays at the cell's
|
||
natural aspect (e.g. 600×500 on desktop, 358×500 on mobile) with the
|
||
image centred.
|
||
|
||
## Build verification
|
||
|
||
- `npx tsc --noEmit` (frontend) — exit 0
|
||
- `./scripts/verify.sh` — exit 0
|
||
- Frontend service restarted via `monolith.sh prod restart frontend`
|
||
→ HTTP 200 on `/products/[slug]`
|
||
|
||
## Files touched
|
||
|
||
```
|
||
project/frontend/src/app/products/[slug]/page.tsx (modified)
|
||
``` |