Skip to content

feat(admin,products): add seller detail page, product status actions, and confirm modal#101

Merged
henri318 merged 7 commits into
mainfrom
sdd/admin-seller-products-slice-d
Jun 30, 2026
Merged

feat(admin,products): add seller detail page, product status actions, and confirm modal#101
henri318 merged 7 commits into
mainfrom
sdd/admin-seller-products-slice-d

Conversation

@henri318

@henri318 henri318 commented Jun 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add admin seller detail/edit page with inline form and i18n
  • Add ELIMINATED product status as terminal state with valid transitions
  • Add ChangeProductStatusUseCase and PATCH endpoint (ADMIN + DESIGNER roles)
  • Add ConfirmModal component using native
  • Add ProductActions with suspend/activate/eliminate buttons
  • Add status badges to seller and admin products pages
  • Eliminate action shows confirmation modal (not alert)
  • Fix pagination on admin seller products page
  • Update seed: link designer@test.com to 728 Store
  • Full TDD coverage

Changes

File Change
\prisma/migrations/*/migration.sql\ Make index creation idempotent
\prisma/seed.ts\ Link designer user to 728 Store
\modules/products/domain/value-objects/product-status.ts\ Add ELIMINATED status
\modules/products/application/change-product-status-use-case.ts\ New use case
\modules/products/presentation/schemas/change-product-status-schema.ts\ New schema
\�pp/api/products/[id]/status/route.ts\ New PATCH endpoint
\shared/presentation/components/confirm-modal.tsx\ New modal component
\�pp/[locale]/seller/products/product-actions.tsx\ New actions component
\�pp/[locale]/seller/products/page.tsx\ Status badges + actions
\�pp/[locale]/admin/sellers/[sellerId]/page.tsx\ New seller detail/edit page
\�pp/[locale]/admin/sellers/[sellerId]/products/page.tsx\ Status badges + actions + pagination fix
\�pp/[locale]/admin/sellers/page.tsx\ Edit link in sellers list
\shared/i18n/locales/es.json, cat.json\ Product statuses, actions, seller detail
\shared/i18n/dictionary-context.tsx\ Updated AdminDictionary type
\ ests/\ Full TDD coverage

Test Plan

  • Unit tests pass for use case, route, pages, and components

  • pm run typecheck\ passes

Notes

Slice D of the admin-seller-products SDD change. Slices A/B were merged in PR #96, Slice C in PR #99.

Summary by CodeRabbit

  • New Features
    • Se añadió la edición de vendedores en el panel de administración con formulario y mensajes de éxito/error.
    • Se incorporaron acciones por producto (activar/suspender/eliminar) con confirmación al eliminar.
    • Los estados de vendedores y productos ahora se muestran como etiquetas traducidas y más claras (incluye “eliminated”).
  • Bug Fixes
    • Se mejoró la paginación de listados de vendedores y productos.
    • Se reforzó el control de acceso y la validación al cambiar estados de producto.

… and confirm modal

- Add admin seller detail/edit page with inline form
- Add ELIMINATED product status as terminal state with valid transitions
- Add ChangeProductStatusUseCase with full validation
- Add PATCH /api/products/[id]/status endpoint (ADMIN + DESIGNER)
- Add ConfirmModal component using native <dialog>
- Add ProductActions with suspend/activate/eliminate buttons
- Add status badges to seller and admin products pages
- Add eliminate confirmation popup (HTML modal, not alert)
- Update seed: link designer@test.com to 728 Store
- Update i18n for product statuses, actions, and seller detail
- Fix pagination on admin seller products page
- Full TDD coverage for all new features
@henri318 henri318 added the type:feature New feature label Jun 30, 2026
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@henri318, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 45 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 672aa7a6-8184-4a85-9876-9e9ca86f7672

📥 Commits

Reviewing files that changed from the base of the PR and between 9e1c46b and 0e1268f.

📒 Files selected for processing (1)
  • tests/unit/app/[locale]/seller/products/page.test.tsx
📝 Walkthrough

Walkthrough

Se añade ELIMINATED al dominio de productos, se implementa el cambio de estado con endpoint PATCH, se crea ProductActions con confirmación, se añade la edición de vendedor para admins y se actualizan traducciones, tablas, seed y migración.

Cambios

Ciclo de vida de estado de producto y edición de vendedor

Layer / File(s) Resumen
Dominio de estado de producto
modules/products/domain/value-objects/product-status.ts, modules/products/presentation/schemas/change-product-status-schema.ts, tests/unit/modules/products/domain/value-objects/product-status.test.ts
Se añade ELIMINATED al enum, se actualiza VALID_TRANSITIONS, se crea el schema Zod para status y se amplía la cobertura de tests para estados y transiciones.
Cambio de estado de producto
modules/products/application/change-product-status-use-case.ts, app/api/products/[id]/status/route.ts, tests/unit/modules/products/application/change-product-status-use-case.test.ts, tests/unit/app/api/products/[id]/status/route.test.ts
Se implementa el caso de uso y el endpoint PATCH con validación, permisos por rol, ownership, persistencia y respuesta con updatedAt, junto con sus tests.
ConfirmModal compartido
shared/presentation/components/confirm-modal.tsx, shared/presentation/components/confirm-modal.module.css
Se añade un modal de confirmación basado en <dialog> con variante danger y estilos asociados.
ProductActions para seller
app/[locale]/seller/products/product-actions.tsx, app/[locale]/seller/products/product-actions.module.css, tests/unit/app/[locale]/seller/products/product-actions.test.tsx
Se introduce el componente cliente que cambia estados de producto, usa ConfirmModal para eliminar y se cubre con tests de render, interacción y carga.
Contrato i18n y traducciones
shared/i18n/dictionary-context.tsx, shared/i18n/locales/es.json, shared/i18n/locales/cat.json
Se tipa el diccionario con secciones concretas y se añaden claves de estados, acciones y sellerDetail en ambos locales.
Detalle y edición de vendedor admin
app/[locale]/admin/sellers/[sellerId]/page.tsx, app/[locale]/admin/sellers/[sellerId]/page.module.css, app/[locale]/admin/sellers/[sellerId]/seller-detail-form.tsx, tests/unit/app/[locale]/admin/sellers/[sellerId]/page.test.tsx, tests/unit/app/[locale]/admin/sellers/[sellerId]/seller-detail-form.test.tsx
Se crea la página de detalle con formulario editable, control de acceso, carga del vendedor y tests de render, submit, redirect y errores.
Lista de vendedores admin
app/[locale]/admin/sellers/page.tsx, app/[locale]/admin/sellers/page.module.css, tests/unit/app/[locale]/admin/sellers/page.test.tsx
Se añade getStatusLabel, el enlace de edición por vendedor y el estilo correspondiente, con tests de enlace y redirección.
Productos del seller en admin
app/[locale]/admin/sellers/[sellerId]/products/page.tsx, app/[locale]/admin/sellers/[sellerId]/products/page.module.css, tests/unit/app/[locale]/admin/sellers/[sellerId]/products/page.test.tsx
Se muestran badges de estado traducidos, acciones por fila y paginación sin resumen total.
Productos del seller
app/[locale]/seller/products/page.tsx, app/[locale]/seller/products/page.module.css, tests/unit/app/[locale]/seller/products/page.test.tsx
Se replica la actualización de badges, acciones y paginación en la vista del seller.
Seed y migración
prisma/seed.ts, prisma/migrations/20260623140000_restore_category_slug_index/migration.sql
Se reordena el seed para crear el seller bajo un usuario DESIGNER y se ajusta la creación del índice con IF NOT EXISTS.

Sequence Diagram(s)

sequenceDiagram
  participant Usuario
  participant ProductActions
  participant ConfirmModal
  participant PATCHHandler as PATCH /api/products/[id]/status
  participant UseCase as ChangeProductStatusUseCase
  participant ProductRepository

  Usuario->>ProductActions: Click en una acción
  ProductActions->>ConfirmModal: Abrir confirmación para ELIMINATED
  Usuario->>ConfirmModal: Confirmar
  ConfirmModal->>ProductActions: onConfirm()
  ProductActions->>PATCHHandler: PATCH { status }
  PATCHHandler->>UseCase: execute(productId, sellerId, status)
  UseCase->>ProductRepository: findById(productId)
  ProductRepository-->>UseCase: product
  UseCase->>ProductRepository: update(product actualizado)
  ProductRepository-->>UseCase: updatedProduct
  UseCase-->>PATCHHandler: updatedProduct
  PATCHHandler-->>ProductActions: 200 { id, status, updatedAt }
  ProductActions->>ProductActions: actualizar estado local / refresh
Loading

Esfuerzo estimado de revisión

🎯 4 (Complex) | ⏱️ ~60 minutos

PRs posiblemente relacionados

  • henri318/728-store#77: Modifica la lista de vendedores admin y su estilo, sobre la misma pantalla de app/[locale]/admin/sellers/page.tsx.
  • henri318/728-store#96: Toca la vista de productos del seller/admin y la representación de estado/acciones en tablas relacionadas.
  • henri318/728-store#86: También cambia el render de estados y acciones en la lista de vendedores admin.

Poema

🐇 Brinca el conejo, ¡qué buen color!
badges y botones cambian de valor.
ELIMINATED salta al tablero,
y un diálogo cuida el clic viajero.
El seller edita, el estado va y viene,
y la luna sonríe: todo se mantiene.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed El título resume con claridad las novedades principales: página de detalle del vendedor, acciones de estado de producto y modal de confirmación.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sdd/admin-seller-products-slice-d

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
shared/presentation/components/confirm-modal.module.css (1)

1-75: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Este archivo sigue rompiendo el pipeline de calidad.

Stylelint ya está fallando aquí por los selectores en camelCase y por la notación de color, así que CI no va a pasar mientras no se ajuste al patrón configurado del repo.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shared/presentation/components/confirm-modal.module.css` around lines 1 - 75,
La hoja de estilos de confirm-modal está rompiendo Stylelint por usar selectores
en camelCase y por la notación de color; ajusta los nombres de clases en
confirm-modal.module.css y cualquier referencia relacionada en el componente que
use .dialog, .cancelButton, .confirmButton, etc., al patrón de nombres
configurado en el repo, y normaliza los colores a la forma que exige la regla de
lint.

Sources: Linters/SAST tools, Pipeline failures

🧹 Nitpick comments (2)
modules/products/domain/value-objects/product-status.ts (1)

27-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Haz que el mapa sea exhaustivo a nivel de tipos.

Partial<Record<...>> hace que una omisión accidental se interprete igual que un estado terminal intencional. Si más adelante añadís otro ProductStatus, TypeScript no avisará y ese estado quedará terminal por defecto. Aquí compensa tiparlo como Record<Exclude<ProductStatus, ProductStatus.ELIMINATED>, readonly ProductStatus[]> para dejar ELIMINATED como excepción explícita.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@modules/products/domain/value-objects/product-status.ts` around lines 27 -
42, The VALID_TRANSITIONS map in product-status.ts is typed too loosely with
Partial<Record<...>>, so missing statuses can be mistaken for intentional
terminal states. Update the type on VALID_TRANSITIONS to a fully exhaustive
Record over all non-terminal ProductStatus values, keeping
ProductStatus.ELIMINATED as the explicit exception, and ensure the existing
DRAFT, ACTIVE, and ARCHIVED entries still satisfy the stricter type.
tests/unit/app/[locale]/seller/products/product-actions.test.tsx (1)

35-110: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Añade una prueba del flujo real de eliminación.

La suite no verifica que pulsar Eliminate abra el modal y que el PATCH solo salga tras confirmar, ni que cancelar lo evite. Ese es el camino nuevo más frágil del componente y ahora mismo puede romperse sin que fallen los tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/app/`[locale]/seller/products/product-actions.test.tsx around
lines 35 - 110, The ProductActions test suite only covers the status-change
click path and misses the real elimination flow. Add an interaction test around
ProductActions that renders an ARCHIVED product, clicks the Eliminate button,
verifies the confirmation modal opens, then confirms to assert the PATCH request
is sent only after confirmation; also add the cancel path to ensure dismissing
the modal does not call fetch. Use the existing ProductActions component, the
Eliminate button, and the modal/confirm controls to locate the flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/`[locale]/admin/sellers/[sellerId]/page.module.css:
- Around line 11-18: This stylesheet is failing Stylelint because several class
selectors still use camelCase and some alpha colors use decimal notation. Update
the affected selectors in page.module.css (including backLink and the other
class names flagged in this module) to the configured kebab-case pattern, and
change all alpha values like 0.08 and 0.25 to the required percentage notation.
Make the edits across the same CSS module so the lint rules pass consistently.

In `@app/`[locale]/admin/sellers/[sellerId]/products/page.module.css:
- Around line 174-200: Rename the CSS module selector .statusBadge to kebab-case
to satisfy selector-class-pattern, and update every reference in the products
page to match the new class name. Use the existing status badge styling block in
page.module.css and the class usage in the page component (the span rendering
product status) to keep the class name consistent and prevent lint/CI failures.

In `@app/`[locale]/admin/sellers/[sellerId]/seller-detail-form.tsx:
- Around line 66-74: The fallback error message in seller save handling is
hardcoded, so it bypasses localization when `fetch` fails or the response has no
usable text. Update `SellerDetailForm` to source this fallback from the same
locale dictionary used for `saveLabel` and `savedLabel`, and use that translated
string in the `catch` path and any `throw new Error(...)` fallback so `setError`
always shows a localized message.

In `@app/`[locale]/admin/sellers/page.module.css:
- Around line 191-209: The `.editLink` selector is failing the
`selector-class-pattern` lint because it is not kebab-case. Rename the CSS class
in `page.module.css` to `.edit-link` and update the matching class reference in
`app/[locale]/admin/sellers/page.tsx` (where the sellers page uses this style)
so the component and stylesheet stay in sync.

In `@app/`[locale]/seller/products/page.module.css:
- Around line 163-189: The .statusBadge selector is violating the repo’s
selector-class-pattern naming convention and is causing lint failures. Rename
the class in this stylesheet to match the configured pattern and update any
corresponding references in the seller products page styles/components that use
statusBadge, while keeping the existing data-status variants for active, draft,
archived, and eliminated aligned with the new class name.

In `@app/`[locale]/seller/products/page.tsx:
- Around line 163-182: The product status badge can become stale because the
table row still renders from the server-provided product.status while
ProductActions only updates its own local state. Update the flow so the row
reflects the patched status after activate/suspend/delete, either by lifting the
status state into the parent table or by triggering a route refresh/invalidation
from ProductActions after the mutation; use ProductActions, the status badge
render, and the setStatus mutation path to keep the row and actions in sync.

In `@app/`[locale]/seller/products/product-actions.tsx:
- Around line 52-53: After the successful PATCH in ProductActions, the update
only calls setStatus with data.status and leaves the parent row stale. Update
the parent product state as well (or trigger a row refresh) from the same
success path so any UI still reading product.status from the page stays in sync
with the new status immediately after save.

In `@shared/i18n/dictionary-context.tsx`:
- Around line 7-13: The SellerDetailDictionary contract only includes success
strings, so the save-failure path in seller-detail-form.tsx still falls back to
a hardcoded English message. Add a new i18n key for the save error to
SellerDetailDictionary and then update the save flow in seller-detail-form.tsx
to use that dictionary entry instead of "Failed to save seller", keeping the new
seller detail screen fully localized.

In `@shared/presentation/components/confirm-modal.tsx`:
- Around line 29-40: The ConfirmModal logic is unmounting the <dialog> before
the close path runs, so the native close behavior is skipped. Update
confirm-modal.tsx in the ConfirmModal component so the dialog stays mounted even
when open becomes false, let the useEffect control showModal()/close() via
dialogRef, and remove the early return that nulls the component before
dialog.close() can execute.

In `@tests/unit/app/api/products/`[id]/status/route.test.ts:
- Around line 9-25: The test setup is missing a mock for getUserLookup(), so the
handler fails before reaching the intended status-route cases. Add a hoisted
mock for container.getUserLookup() that returns an object with findById, and
wire it into the existing mocks alongside getSessionMock, findByIdMock, and
updateMock so the route test can exercise the 400/403/404/200 paths correctly.
- Around line 94-103: The module-load wiring test for PATCH only verifies the
first requireRole argument, so it can miss removal of ADMIN from the route
guard. Update the test in route.test.ts around the route authorization block to
assert that route wiring for PATCH includes both ADMIN and DESIGNER in the
requireRole call(s), using the existing requireRoleMock calls captured from the
PATCH export so the contract is checked explicitly instead of only checking the
first role.

---

Outside diff comments:
In `@shared/presentation/components/confirm-modal.module.css`:
- Around line 1-75: La hoja de estilos de confirm-modal está rompiendo Stylelint
por usar selectores en camelCase y por la notación de color; ajusta los nombres
de clases en confirm-modal.module.css y cualquier referencia relacionada en el
componente que use .dialog, .cancelButton, .confirmButton, etc., al patrón de
nombres configurado en el repo, y normaliza los colores a la forma que exige la
regla de lint.

---

Nitpick comments:
In `@modules/products/domain/value-objects/product-status.ts`:
- Around line 27-42: The VALID_TRANSITIONS map in product-status.ts is typed too
loosely with Partial<Record<...>>, so missing statuses can be mistaken for
intentional terminal states. Update the type on VALID_TRANSITIONS to a fully
exhaustive Record over all non-terminal ProductStatus values, keeping
ProductStatus.ELIMINATED as the explicit exception, and ensure the existing
DRAFT, ACTIVE, and ARCHIVED entries still satisfy the stricter type.

In `@tests/unit/app/`[locale]/seller/products/product-actions.test.tsx:
- Around line 35-110: The ProductActions test suite only covers the
status-change click path and misses the real elimination flow. Add an
interaction test around ProductActions that renders an ARCHIVED product, clicks
the Eliminate button, verifies the confirmation modal opens, then confirms to
assert the PATCH request is sent only after confirmation; also add the cancel
path to ensure dismissing the modal does not call fetch. Use the existing
ProductActions component, the Eliminate button, and the modal/confirm controls
to locate the flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8d6cf804-a307-4266-b927-4bfccdb5651f

📥 Commits

Reviewing files that changed from the base of the PR and between 9b7a678 and 5e9585a.

📒 Files selected for processing (30)
  • app/[locale]/admin/sellers/[sellerId]/page.module.css
  • app/[locale]/admin/sellers/[sellerId]/page.tsx
  • app/[locale]/admin/sellers/[sellerId]/products/page.module.css
  • app/[locale]/admin/sellers/[sellerId]/products/page.tsx
  • app/[locale]/admin/sellers/[sellerId]/seller-detail-form.tsx
  • app/[locale]/admin/sellers/page.module.css
  • app/[locale]/admin/sellers/page.tsx
  • app/[locale]/seller/products/page.module.css
  • app/[locale]/seller/products/page.tsx
  • app/[locale]/seller/products/product-actions.module.css
  • app/[locale]/seller/products/product-actions.tsx
  • app/api/products/[id]/status/route.ts
  • modules/products/application/change-product-status-use-case.ts
  • modules/products/domain/value-objects/product-status.ts
  • modules/products/presentation/schemas/change-product-status-schema.ts
  • prisma/migrations/20260623140000_restore_category_slug_index/migration.sql
  • prisma/seed.ts
  • shared/i18n/dictionary-context.tsx
  • shared/i18n/locales/cat.json
  • shared/i18n/locales/es.json
  • shared/presentation/components/confirm-modal.module.css
  • shared/presentation/components/confirm-modal.tsx
  • tests/unit/app/[locale]/admin/sellers/[sellerId]/page.test.tsx
  • tests/unit/app/[locale]/admin/sellers/[sellerId]/products/page.test.tsx
  • tests/unit/app/[locale]/admin/sellers/[sellerId]/seller-detail-form.test.tsx
  • tests/unit/app/[locale]/admin/sellers/page.test.tsx
  • tests/unit/app/[locale]/seller/products/page.test.tsx
  • tests/unit/app/[locale]/seller/products/product-actions.test.tsx
  • tests/unit/app/api/products/[id]/status/route.test.ts
  • tests/unit/modules/products/application/change-product-status-use-case.test.ts

Comment on lines +11 to +18
.backLink {
display: inline-flex;
margin-bottom: var(--spacing-sm);
color: var(--color-green-dark);
font-weight: var(--font-weight-medium);
}

.backLink:hover {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Este módulo no pasa las reglas de Stylelint configuradas.

Ahora mismo hay errores por selector-class-pattern (selectores en camelCase) y alpha-value-notation (0.08/0.25), así que el lint seguirá fallando hasta normalizar esos selectores y valores alpha.

Also applies to: 41-41, 44-49, 57-57, 69-69, 72-72, 104-111

🧰 Tools
🪛 Stylelint (17.14.0)

[error] 11-11: Expected class selector ".backLink" to be kebab-case (selector-class-pattern)

(selector-class-pattern)


[error] 18-18: Expected class selector ".backLink" to be kebab-case (selector-class-pattern)

(selector-class-pattern)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/`[locale]/admin/sellers/[sellerId]/page.module.css around lines 11 - 18,
This stylesheet is failing Stylelint because several class selectors still use
camelCase and some alpha colors use decimal notation. Update the affected
selectors in page.module.css (including backLink and the other class names
flagged in this module) to the configured kebab-case pattern, and change all
alpha values like 0.08 and 0.25 to the required percentage notation. Make the
edits across the same CSS module so the lint rules pass consistently.

Source: Linters/SAST tools

Comment on lines +174 to +200
.statusBadge {
display: inline-block;
padding: 0.2rem 0.6rem;
border-radius: 4px;
font-size: 0.8rem;
font-weight: var(--font-weight-medium);
}

.statusBadge[data-status='active'] {
background: var(--color-green-light);
color: var(--color-green-dark);
}

.statusBadge[data-status='draft'] {
background: var(--color-lila);
color: var(--color-white);
}

.statusBadge[data-status='archived'] {
background: var(--color-coral);
color: var(--color-white);
}

.statusBadge[data-status='eliminated'] {
background: var(--color-gray);
color: var(--color-white);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Renombra .statusBadge para no romper el lint.

La regla selector-class-pattern exige kebab-case y este selector falla en las cinco apariciones del bloque. Si no se renombra aquí y en el uso de la página, este cambio seguirá rompiendo CI.

💡 Cambio propuesto
-.statusBadge {
+.status-badge {
   display: inline-block;
   padding: 0.2rem 0.6rem;
   border-radius: 4px;
   font-size: 0.8rem;
   font-weight: var(--font-weight-medium);
 }

-.statusBadge[data-status='active'] {
+.status-badge[data-status='active'] {
   background: var(--color-green-light);
   color: var(--color-green-dark);
 }

-.statusBadge[data-status='draft'] {
+.status-badge[data-status='draft'] {
   background: var(--color-lila);
   color: var(--color-white);
 }

-.statusBadge[data-status='archived'] {
+.status-badge[data-status='archived'] {
   background: var(--color-coral);
   color: var(--color-white);
 }

-.statusBadge[data-status='eliminated'] {
+.status-badge[data-status='eliminated'] {
   background: var(--color-gray);
   color: var(--color-white);
 }
<span className={styles['status-badge']} data-status={product.status.toLowerCase()}>
🧰 Tools
🪛 Stylelint (17.14.0)

[error] 174-174: Expected class selector ".statusBadge" to be kebab-case (selector-class-pattern)

(selector-class-pattern)


[error] 182-182: Expected class selector ".statusBadge" to be kebab-case (selector-class-pattern)

(selector-class-pattern)


[error] 187-187: Expected class selector ".statusBadge" to be kebab-case (selector-class-pattern)

(selector-class-pattern)


[error] 192-192: Expected class selector ".statusBadge" to be kebab-case (selector-class-pattern)

(selector-class-pattern)


[error] 197-197: Expected class selector ".statusBadge" to be kebab-case (selector-class-pattern)

(selector-class-pattern)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/`[locale]/admin/sellers/[sellerId]/products/page.module.css around lines
174 - 200, Rename the CSS module selector .statusBadge to kebab-case to satisfy
selector-class-pattern, and update every reference in the products page to match
the new class name. Use the existing status badge styling block in
page.module.css and the class usage in the page component (the span rendering
product status) to keep the class name consistent and prevent lint/CI failures.

Source: Linters/SAST tools

Comment thread app/[locale]/admin/sellers/[sellerId]/seller-detail-form.tsx Outdated
Comment on lines +191 to +209
.editLink {
display: inline-flex;
align-items: center;
gap: var(--spacing-xs);
padding: 0.35rem 0.8rem;
border: 1px solid var(--color-green-dark);
border-radius: 4px;
color: var(--color-green-dark);
font-size: 0.8rem;
font-weight: var(--font-weight-medium);
transition:
background 0.15s ease,
color 0.15s ease;
}

.editLink:hover {
background: var(--color-green-dark);
color: var(--color-white);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Renombra esta clase a kebab-case para pasar el lint.

Stylelint ya está marcando este bloque por selector-class-pattern. Aquí conviene usar algo como .edit-link y actualizar el acceso correspondiente en app/[locale]/admin/sellers/page.tsx.

🧰 Tools
🪛 Stylelint (17.14.0)

[error] 191-191: Expected class selector ".editLink" to be kebab-case (selector-class-pattern)

(selector-class-pattern)


[error] 206-206: Expected class selector ".editLink" to be kebab-case (selector-class-pattern)

(selector-class-pattern)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/`[locale]/admin/sellers/page.module.css around lines 191 - 209, The
`.editLink` selector is failing the `selector-class-pattern` lint because it is
not kebab-case. Rename the CSS class in `page.module.css` to `.edit-link` and
update the matching class reference in `app/[locale]/admin/sellers/page.tsx`
(where the sellers page uses this style) so the component and stylesheet stay in
sync.

Source: Linters/SAST tools

Comment on lines +163 to +189
.statusBadge {
display: inline-block;
padding: 0.2rem 0.6rem;
border-radius: 4px;
font-size: 0.8rem;
font-weight: var(--font-weight-medium);
}

.statusBadge[data-status='active'] {
background: var(--color-green-light);
color: var(--color-green-dark);
}

.statusBadge[data-status='draft'] {
background: var(--color-lila);
color: var(--color-white);
}

.statusBadge[data-status='archived'] {
background: var(--color-coral);
color: var(--color-white);
}

.statusBadge[data-status='eliminated'] {
background: var(--color-gray);
color: var(--color-white);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Estos selectores no pasan la regla de naming del repo.

statusBadge está chocando con selector-class-pattern, así que esta hoja seguirá fallando el lint mientras no se adapte a la convención configurada.

🧰 Tools
🪛 Stylelint (17.14.0)

[error] 163-163: Expected class selector ".statusBadge" to be kebab-case (selector-class-pattern)

(selector-class-pattern)


[error] 171-171: Expected class selector ".statusBadge" to be kebab-case (selector-class-pattern)

(selector-class-pattern)


[error] 176-176: Expected class selector ".statusBadge" to be kebab-case (selector-class-pattern)

(selector-class-pattern)


[error] 181-181: Expected class selector ".statusBadge" to be kebab-case (selector-class-pattern)

(selector-class-pattern)


[error] 186-186: Expected class selector ".statusBadge" to be kebab-case (selector-class-pattern)

(selector-class-pattern)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/`[locale]/seller/products/page.module.css around lines 163 - 189, The
.statusBadge selector is violating the repo’s selector-class-pattern naming
convention and is causing lint failures. Rename the class in this stylesheet to
match the configured pattern and update any corresponding references in the
seller products page styles/components that use statusBadge, while keeping the
existing data-status variants for active, draft, archived, and eliminated
aligned with the new class name.

Source: Linters/SAST tools

Comment thread app/[locale]/seller/products/product-actions.tsx
Comment on lines +7 to +13
export interface SellerDetailDictionary {
editTitle: string;
nameLabel: string;
descriptionLabel: string;
save: string;
saved: string;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Añade una clave i18n para el error de guardado.

seller-detail-form.tsx:33-79 todavía cae en "Failed to save seller" cuando falla el PATCH, y este contrato solo cubre el estado de éxito (save/saved). Sin una clave aquí, la pantalla nueva queda parcialmente en inglés.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shared/i18n/dictionary-context.tsx` around lines 7 - 13, The
SellerDetailDictionary contract only includes success strings, so the
save-failure path in seller-detail-form.tsx still falls back to a hardcoded
English message. Add a new i18n key for the save error to SellerDetailDictionary
and then update the save flow in seller-detail-form.tsx to use that dictionary
entry instead of "Failed to save seller", keeping the new seller detail screen
fully localized.

Comment thread shared/presentation/components/confirm-modal.tsx Outdated
Comment thread tests/unit/app/api/products/[id]/status/route.test.ts
Comment thread tests/unit/app/api/products/[id]/status/route.test.ts
Developer added 4 commits June 30, 2026 10:53
…s change, fix dialog close timing

- SellerDetailForm: add errorLabel prop for localized error fallback instead of hardcoded English string
- ProductActions: call router.refresh() after successful status change to sync parent server component
- ConfirmModal: remove early return that unmounted dialog before native close() could execute
@henri318 henri318 merged commit d7d15be into main Jun 30, 2026
3 checks passed
@henri318 henri318 deleted the sdd/admin-seller-products-slice-d branch June 30, 2026 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant