WookcomDocsIr a Wookcom ↗

Commerce, authentication and toast UI audit

Read-only audit of all 18 TSX files in the assigned directories. Priorities: P1 = broken/misleading flow or accessibility barrier; P2 = clean-design/state/consistency gap. All findings below are confirmed in source unless marked Browser. Line numbers are per file. No product code changed.

Reachability and scope

  • Active platform UI: AuthLandingScreen is the unauthenticated gate (App.tsx:541–555); StoreManagerModal is lazy loaded and kept mounted (App.tsx:1014–1021), and contains analytics, products, orders and Boxful settings. Export is called from orders manager.
  • Store/site content as well as editor canvas UI: ProductGridElement, ProductCardElement, CartButtonElement, CheckoutFormElement, BoxfulTrackerElement are rendered by CanvasElement.tsx:619–631, LivePreview.tsx:439–467, PublicSiteViewer.tsx:275–303. Their styling changes affect authored storefronts, not merely editor chrome.
  • Shared overlays: CartDrawer and ProductDetailModal are mounted in App.tsx:1023–1024 and again in LivePreview.tsx:483–484; PublicSiteViewer mounts them at 333–334. Browser must check whether opening preview renders duplicate overlays because both instances consume the same context. ToastContainer is mounted globally at App.tsx:1025.
  • Integration calls exist, but availability/authentication/network success was not tested. Checkout currently marks card/PayPal paid based on the selected string, without a payment operation (StoreContext.tsx:451–467), catches shipment failure and still returns an order/clears the cart (476–506). Treat claims of paid/official shipment as unverified and repair the corresponding UI truthfulness before visual polish.

Per-file findings and states

auth/AuthLandingScreen.tsx — active auth UI

  • P1 214–228: unconditional Cloudflare-looking “¡Operación exitosa!” block is shown before any operation; no verification integration backs this block. 344–378 also claim active Firebase sync/export readiness as hard-coded marketing notifications.
  • P1 146–187: labels have no htmlFor/input id association; no autocomplete attributes. 188–194 password reveal is icon-only and unnamed. 129–140 errors/reset success have no live role; 236–238 replaces submit name with an unnamed spinner during submission.
  • P2 334–397: 36px radius, shadow-2xl, glass/blur floating cards, emoji at 106/347/371, decorative rotations and generic promotional photo/copy violate the requested restraint. Photo card remains a minimum 500px tall on mobile (334). Raw slate/blue/emerald and hex button color (234) bypass shared semantic tokens.
  • States: submit pending/disabled, auth error, reset success and input focus present; Google disabled lacks explicit disabled styling (253); buttons lack component focus-visible/active consistency. Browser: AA, small-screen header fit, autofill, keyboard and auth service behavior.

ecommerce/CartButtonElement.tsx — authored storefront/canvas

  • P1 16–21: cart-opening control is a clickable div with no role/tabIndex/keyboard handler, inaccessible by keyboard.
  • P2 21/27: rounded-2xl/shadow and perpetually pulsing quantity badge; hard-coded theme. No explicit focus or active state.
  • States: empty/nonempty count supported; no asynchronous state needed for local open; no accessible announcement of count changes.

ecommerce/ProductCardElement.tsx — authored storefront/canvas

  • P1 37–40: detail opener is clickable div without keyboard semantics. 87–102 quantity icon buttons lack names, decrement never disabled at one, increment unbounded. 112–127 add is not disabled when stock is zero (unlike detail modal).
  • P2 35–57: large radius, hover zoom, glass shipping badge and shadow overlay; 130–133 unconditional secure-purchase/realtime-tracking promise. 21/63/79/130 use small slate-400 text. No image error fallback.
  • States: catalog empty and transient add success present; no load/error, out-of-stock, focus-visible or active styling. Success has no live region. Browser: fixed card height/clipping and contrast.

ecommerce/ProductGridElement.tsx — authored storefront/canvas

  • P1 98–102: product detail clickable div is not keyboard operable. 58–64 search has only placeholder; category selection 74–86 lacks aria-pressed/tab semantics. 156–176 add buttons never use stock/disabled.
  • P2 45/102–123: repeated large radii/shadows/glass/hover zoom; hard-coded theme; unconditional Boxful badge. 183–188 empty result is present but offers no clear-filter action. No image fallback.
  • States: filter active, no-results, add success, hover and weak input ring present; load/error/out-of-stock and explicit keyboard focus absent; success not announced. Browser: responsive breakpoints inside narrow canvas nodes and focus-ring contrast.

ecommerce/CartDrawer.tsx — shared storefront/editor overlay

  • P1 42–71: no dialog semantics, focus entry/trap/restore or Escape handling; close icon unnamed. 103–119 quantity buttons unnamed and only 20px. 179–191 closes drawer even if no checkout exists; App passes no callback, so user may receive no destination/feedback.
  • P1 151–158/208–210: unconditional “Tarifa Live”, encrypted-payment/guaranteed-shipment claims despite shipping only calculated later (168–169).
  • P2 46/50/80: backdrop blur, shadow-2xl, decorative entry animation, nested 16px radii. Mobile uses left padding 40px plus panel padding (49/75), reducing space.
  • States: empty, populated, quantity/removal and hover supported; no transaction pending/errors needed for local cart; no explicit focus/active styles. Browser: mobile item/footer fit, overlay duplication, keyboard containment.

ecommerce/ProductDetailModal.tsx — shared storefront/editor overlay

  • P1 64–91: modal lacks dialog semantics/focus lifecycle/Escape; same problem as drawer. 35–38 local quantity/variant/image state does not reset when product changes. 208–211 visually defaults first variant but handleAddToCart at 51–53 passes undefined until clicked.
  • P1 156–159: fabricated rating 4.9/review count 98 fallbacks; 135–143/329–363 hard-coded delivery/returns/support promises. 245–264 has two equal-weight full-width filled purchase actions; “Checkout Rápido” only opens cart (57–60).
  • P2 69/72/101/187: blur, 24px radii/shadow-2xl, hover zoom, pulsing stock dot (also green when out of stock). Variant buttons lack selected semantics; accordions 280–356 lack aria-expanded/controls. Quantity +/- lack descriptive names and disabled boundaries.
  • States: out-of-stock disables purchase, success and hover present; success not announced; no loading/error/image fallback/explicit focus styles. Browser: narrow price row and long variants, focus trap/duplicate overlays.

ecommerce/CheckoutFormElement.tsx — authored storefront/canvas

  • P1 63–80: shipping errors only console.logged; empty quote response indistinguishable from initial state. Quotes not invalidated after address/cart changes. City/country default to San Salvador/El Salvador (45–47) with no input to change city/country.
  • P1 225–294: all customer labels unassociated; 326–352 selectable quote divs are mouse-only fake radios. Payment buttons (372–408) have no selected semantics. Card/PayPal are selectable but there are no collection/payment flows; context marks them paid without processing (see reachability).
  • P1 110/133–163: completion claims “Guía Oficial”, “Recolectando” and courier registration even when shipment failed and tracking is BOXFUL-PENDING. 150–152 claims copied before clipboard promise succeeds. 423–426 calls subtotal “TOTAL FINAL” while shipping remains pending.
  • P2 115/201/434: large radii/shadows; dense implementation/provider copy throughout. 300–319 and fixed grid-cols-3 payment row (372) need narrow-screen review.
  • States: quoting/submitting and disabled empty-cart submit, success present; errors use blocking alert (65/88/93/102), no field-level validation/live announcements, no true cart empty screen or quote failure retry; focus ring is low-opacity.

ecommerce/StoreManagerModal.tsx — active platform UI

  • P1 98–100: aside acts as a modal without dialog/focus lifecycle/Escape; background remains operable in source. 244–329 form labels unassociated and every field outline-none without replacement focus styling.
  • P1 59–68: save has no pending/error/success state; 389 deletes immediately without undo; 353–398 blank list when products empty. P2 207–229 remains a primary new-product button alongside primary save (334–339).
  • P2 94/100/103/114: glass, 24px radii, custom large shadow, decorative entrance and pulsing “live” badge regardless of connection. 211–220 new-product form prepopulates generic photo/prices/stock. Segmented buttons (138–188) lack selected/tab semantics.
  • States: edit/create/cancel and hover available; missing fetch loading/error, empty recovery, save pending/disabled/error/success and explicit focus/active. Browser: mobile header/tab wrapping and panel position.

ecommerce/ShopifyOrdersManager.tsx — active platform UI

  • P1 170–203/1029–1033: manual create has no pending/error/disabled protection; non-COD manual orders are immediately marked paid (196). Fixed $3.50 shipping (187) is not presented for review before submit.
  • P1 486–530/807–832/902–930: three modal implementations lack dialog semantics, Escape/focus containment/restore, and close buttons are unnamed. Carrier cards (654–674) and manual product selectors (942–960) are mouse-only divs; fields at 969–1020 have unassociated labels and remove outlines without focus replacement.
  • P1 821–856: UI calls label official but creates a simulated barcode from 48 arbitrary bars (844–853), ignores real labelUrl, and print calls window.print (890). Browser: print isolation/pagination and whether label is usable; source proves barcode is not encoded from tracking number.
  • P1 630–641: status update writes context but selectedOrder is a snapshot, so controlled select/details can remain stale; no mutation pending/error feedback. 391–400 labels every unpaid order “Contra Entrega”, including unpaid card/PayPal. Toast navigation can open manager's retained/default analytics tab rather than orders (context only sets manager open; this component consumes selected number only when orders tab mounts).
  • P2 312–345: search plus two shrink-0 action buttons in an unwrapped mobile row; 544 gradient, 492/813/910 shadow-2xl/large radii/blur, emoji CTA at 703. Filters have no aria-pressed; search is placeholder-only. Dense 9–11px metadata/slate-400 text.
  • States: filter active, order empty, dispatch loading/disabled/error/success present; empty filtered state falsely implies no orders (475–480) with no clear filters. Copy ignores rejection (131–134); manual creation/status/initial fetch missing state handling. Browser: table keyboard access, mobile overflow, overlay stacking, real dispatch and print.

ecommerce/BoxfulSettingsSection.tsx — active platform UI

  • P1 467–484 event checkboxes are clickable divs; switch (565–573) lacks name/role/aria-checked. All labels at 260/274/342–368/399/430 are unassociated; warehouse inputs remove outline without focus replacement.
  • P1 125–133/634–639 save has no pending/error/disabled state; context update catches persistence errors, so success can be shown despite failure. Test invokes processIncomingWebhook directly (184/209), but labels say “Recepción de Webhook en Vivo” (495) and thus do not prove an endpoint received anything. Error string rendered in same green success panel (212–213/537–540).
  • P2 51–55 populated fictional warehouse details; 579–595 says sync active/last successful from local form snapshot rather than current config; 91 generates endpoint string without verifying endpoint exists. Four strong colored actions compete (304/530/603/636); repeated card radii/shadows and backend jargon. 93–96 clipboard reports success without awaiting.
  • States: API validation loading/error/success/disabled; sync pending/log and test pending/disabled/feedback present; missing save errors, form dirty state and explicit focus/active. Browser: long select options/header/switch row on mobile; service/endpoint functionality needs independent verification.

ecommerce/BoxfulExportModal.tsx — active platform UI

  • P1 161–191 modal has no dialog/focus/Escape behavior. API key is plaintext input (259–264) with no associated label; carrier select (239) likewise. 133–137 key save has no pending/error and can claim saved despite context swallowing failures.
  • P2 161–162 glass/24px radii/custom shadow; 383–428 three equally strong colored actions. API request enabled for missing key/empty batch (385 only checks pending); no empty payload UX. 255–280 API key row never wraps; extensive fixed-height chrome leaves little JSON space on short/mobile screens.
  • States: execute loading/disabled/error/success and copy success exist; copy failure silent (117–122); response/save not live-announced; no explicit focus/active. Browser: viewport fit, nested overlay stacking and service calls.

ecommerce/analytics/StoreAnalyticsDashboard.tsx — active platform UI

  • P1 24–31/57–64: refresh lacks disabled and error/success state; repeated clicks can overlap. 46–53 unconditional Firestore live badge/copy is unrelated to sync health.
  • P2 34–47: free entrance/pulse motion and rounded card styling; header inner row does not wrap. Raw tokens throughout.
  • States: refresh icon pending only; no initial loading/error/connection-empty states supplied to children. Browser: header at 320px, truthful live indication.

ecommerce/analytics/OrdersMetricsSummary.tsx — active platform UI

  • P1 24 vs ShopifyOrdersManager:99: “Ventas Totales” here includes every unpaid/cancelled order, while orders view means paid total. 28–39/132 counts shipped/delivered and labels it “con guía” without inspecting guide existence; 113 hard-coded “Conversión activa”. Resolve metric definitions.
  • P2 58/78/98/118: repeated 24px radii and ornamental colored icon tiles, 10–11px text and slate-400 metadata. No semantic definition list/table.
  • States: zeros render; no distinction between loading/failure/true empty. Passive component receives only orders. Browser: AA/narrow metric values.

ecommerce/analytics/SalesTrendChart.tsx — active platform UI

  • P1 64/70: revenue includes every order regardless of paid/cancelled state; conflicts with paid-sales metric. Tooltip payload is ordered Bar then Area (210–226) but assumes [0] revenue and [1] count (104/112), so values are likely swapped; verify actual Recharts payload order in browser.
  • P2 94/122/176–179/226: large card/tooltip radii/shadows and area gradient against no-gradient requirement. 134–168 range selector lacks selected semantics. Chart has no author-supplied table/text alternative (172–229); no explicit empty chart state (zero grid always fabricated for date range).
  • States: active range/hover tooltip present; no load/error/empty distinction or explicit focus. Browser: screen-reader/keyboard chart support in installed Recharts, tooltip data order, AA of #94a3b8 labels and series.

ecommerce/analytics/TopProductsChart.tsx — active platform UI

  • P1 59–80 aggregates all orders, while subtitle says dispatched units (134). 100–102 sums only top five but percentage (183) can be read as share of store sales; clarify denominator. 74–76 fabricates generic name/photo/category for missing historical product.
  • P2 109/126/187: rounded-3xl card, shadow-xl tooltip, colorful bars/ornamental award tile; no table semantics or explicit chart summary though adjacent cards expose values (181–213). Header (127–140) not wrapping.
  • States: zero-sales empty state exists (143–150); no load/error. Passive component. Browser: mobile header/row truncation, AA and Recharts keyboard/table-equivalent accessibility.

toast/ToastContainer.tsx — active platform notification UI

  • P1 28: w-full plus right-4 (without a left inset or calc width) extends beyond viewport on screens narrower than max-w-sm; Browser confirm clipping/left overflow at 320px. Max-width at larger breakpoints does not prevent small-screen issue.
  • P2 26–27 + child role=alert: mixed atomic polite container/assertive child announcements; 33 free slide/fade animation. No stack height/overflow limit when many toasts arrive.
  • States: no notifications returns null; notification arrival/dismiss supported. Browser: announcement duplication/order, stacked layout, overlay z-index conflicts.

toast/ToastNotification.tsx — active platform notification UI

  • P1 89–108/123–126: auto-dismiss pauses only for mouse hover, not keyboard focus; focused actions can disappear. 110–114 dismisses even if no target id exists. “Ver en StoreManager” opens manager but does not select orders tab (StoreContext.tsx:251–254, StoreManagerModal.tsx:41).
  • P2 127–133/161/168: shadow-xl, colored glow rings, animate-bounce and animate-ping; all notifications use role=alert (126) regardless of urgency. Automatic chime on new order (82–86) has no preference here. Repeated discard/X controls consume space.
  • States: timers, hover pause, dismiss and action exist; close has aria-label (255); no focus pause/explicit focus-visible, persistent mode, or action failure feedback. Browser: live announcements, audio policy, mobile wrapping and timing usability.

Cross-cutting implementation direction (audit only)

Prioritize truthful checkout/shipping/payment and label flows, semantic controls/dialogs, then shared semantic tokens and unified flat surfaces. All audited files hard-code Tailwind palette/radius/shadow choices rather than consuming platform semantic controls. Many outline-none inputs use no replacement or a 20%-opacity ring, so browser AA/non-text contrast testing is needed even where focus classes exist. No browser or screen-reader checks were performed in this sub-audit. Test at 320/375/768px and with long Spanish labels, empty data, network failure, keyboard-only navigation, reduced motion and zoom. Decorative motion has no local reduced-motion guard in these components; verify any global stylesheet override before claiming site-wide absence.