Commit Graph
5 Commits
Author SHA1 Message Date
bermudalambandClaude Opus 5 f537314259 fix(admin): theme, American English, and inventory/reservation tooling (#27)
SonarQube Analysis / sonarqube (pull_request) Successful in 4m23s
Tests / backend-unit (pull_request) Successful in 1m6s
Tests / backend-integration (pull_request) Failing after 4m55s
Tests / frontend-e2e (pull_request) Failing after 12m41s
Seven reported items, of which the first four had two root causes.

The active tab was invisible in dark mode because colorPrimary was
hardcoded to #1a1a1a in both themes. The accent now inverts with the
theme, and colorTextLightSolid inverts with it, or a near-white accent
would get antd's default white label and disappear.

The Category tab, Tag tab, and item-form category selector ignored the
theme entirely. antd declares main: lib/index.js and module: es/index.js,
so importing from 'antd' resolves to the ES build while 'antd/lib/...'
loads the CommonJS one — two copies, two React contexts, and no
ConfigProvider for anything deep-imported. Switching those files to
antd/es/* keeps the deep-import convention and shares the instance. This
was introduced by my own use of the lib path; es is correct under Vite.
Two storefront components had the same latent bug.

"Colour" is now "Color".

The Customers tab shows how many items each customer is holding, as a
link opening the item list with a Release button. Release mirrors the
customer's own cart removal — drop the cart row, return the item to
available, guarded on 'reserved' so it can never resurrect a sold item —
and deliberately sends no email about an action the customer did not
take. The count is a subquery rather than another join, which would have
multiplied rows and inflated order_count and total_spent_cents.

The Inventory tab filters by category, tags, price, and status, reusing
the storefront's parser and query builder so the two cannot drift.
Reserved is one option in a Status filter rather than a standalone toggle.

Also fixes two defects the screenshots exposed: the reserved-count link
bubbled to the row handler and opened the customer drawer behind the
dialog, and .admin-category-node had no CSS at all, so the tree node name,
item count, and actions ran together as one string.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 15:49:05 -05:00
bermudalambandClaude Opus 5 dd51621956 fix: reset the header and return home when a customer logs out (#21)
SonarQube Analysis / sonarqube (pull_request) Successful in 3m47s
Tests / backend-unit (pull_request) Successful in 45s
Tests / backend-integration (pull_request) Failing after 1m40s
Tests / frontend-e2e (pull_request) Failing after 9m31s
Logging out destroyed the server session and navigated home, but never
told CustomerAuthContext, so `customer` stayed in React state and the
header kept offering "My Account" instead of "Log in" and "Sign up". A
reload appeared to fix it, because fetchMe then returned null, which is
why the symptom looked intermittent. The cart badge had the same cause:
CartContext only clears its items once `customer` goes null.

Logout now lives on the auth context, which clears `customer` itself
rather than triggering a refetch — a refetch would leave a window where
the session is gone but the UI still shows the customer signed in.

logoutCustomer also ignored res.ok. A failed logout leaves the session
cookie valid, so reporting success signed the customer back in on their
next reload. It now rejects, and the account page reports the failure and
stays put instead of pretending. Logout is not routed through handle()
because the endpoint answers 204 with no body.

Navigation uses replace, so Back no longer returns to the account page,
which would only bounce to /login now the session is gone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 13:55:36 -05:00
bermudalambandClaude Opus 5 b7c8c37447 fix: add the missing /verify-email page
SonarQube Analysis / sonarqube (pull_request) Successful in 3m42s
Tests / backend-unit (pull_request) Successful in 59s
Tests / backend-integration (pull_request) Successful in 1m30s
Tests / frontend-e2e (pull_request) Failing after 5m21s
Verification emails linked to /verify-email?token=..., but no such route
existed in main.tsx and nothing in the frontend ever called
POST /api/customers/verify-email. The SPA catch-all served index.html, no
route matched, and the page rendered blank -- so the token was never
redeemed and accounts stayed unverified forever.

The gap was invisible until SMTP was configured, because no verification
email had ever actually been delivered.

Adds VerifyEmail.tsx (verifying / verified / failed states), a verifyEmail
call in customerApi, and the route. The request is pinned to a single
firing via a ref: the endpoint deletes the token on success, so StrictMode's
double effect invocation in dev would otherwise overwrite the success state
with "invalid or expired token".

Verified end to end against a local stack: a real token flips
customers.email_verified to true and is consumed from customer_tokens.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-15 18:16:32 -05:00
bermudalamb 9ab689e624 feat: add customer cart with expiry, shipping addresses with USPS validation, and multi-item PayPal checkout
SonarQube Analysis / sonarqube (pull_request) Failing after 59s
Tests / backend-unit (pull_request) Successful in 34s
Tests / backend-integration (pull_request) Failing after 1m33s
Tests / frontend-e2e (pull_request) Failing after 1m5s
2026-08-14 14:02:25 -05:00
bermudalamb 9be4986dd3 Initial commit: redefined-designs storefront 2026-08-13 21:07:54 +00:00