fix(buyer/billing/comms/a11y): Codex review pass round 2

Tuxedo buyer path (subagent 2):
- src/app/tuxedo/page.tsx: remove duplicate CinematicShowcase render
- src/components/storefront/CinematicShowcase.tsx: wire up useCart, Add to Cart button, brand-aware fulfillment
- src/app/tuxedo/stops/TuxedoStopsList.tsx: improved empty state with calendar icon + CTAs
- src/app/cart/CartClient.tsx: guard against empty cart checkout; 'Cart is Empty' state

Billing reconciliation (subagent 3):
- src/actions/billing/billing-overview.ts: NEW — single source of truth
- src/app/admin/settings/billing/page.tsx: use getBillingOverview
- src/app/admin/settings/billing/BillingClientPage.tsx: rewritten to consume BillingOverview (status pill, addons state, removable flags, derived invoice amounts, usage footer)
- src/app/admin/page.tsx: use getBillingOverview (aligns dashboard with billing)
- src/components/admin/DashboardClient.tsx: 'Active Products' now reads from getBillingOverview
- supabase/migrations/203_plan_usage_active_products.sql: get_brand_plan_info counts products as active=true AND deleted_at IS NULL

Harvest Reach dedup + audience preview (manual, subagent 4 didn't complete):
- src/components/admin/CommunicationsPage.tsx: add initialTab prop
- src/app/admin/communications/compose/page.tsx: now renders with initialTab='compose' (single compose experience, no duplicate edit panel)
- src/components/admin/HarvestReach/CampaignComposerPage.tsx: always-visible audience preview panel (count + sample emails), loads via previewCampaignAudience action

Layout/content consistency + a11y sweep (subagent 5):
- src/components/layout/SiteHeader.tsx: Admin link only shows for authenticated admin users
- src/components/Providers.tsx: suppress public SiteHeader/Footer for /admin, /cart, /checkout, /wholesale, /water (fixes duplicate headers)
- src/app/contact/ContactClientPage.tsx: Phone/Email now use tel:/mailto: links; dynamic year
- src/app/blog/page.tsx, changelog, privacy-policy, roadmap, security, terms-and-conditions, waitlist: dynamic year
- src/app/admin/wholesale/WholesaleClient.tsx: proper htmlFor/id, type=email/tel, autoComplete
- src/app/admin/settings/ai/AIClient.tsx: proper htmlFor/id, required + aria-required
- src/app/admin/settings/integrations/IntegrationsClient.tsx: only mask secret fields; add required + aria-required + CredentialField.required type
- src/app/admin/water-log/headgates/HeadgatesManager.tsx: htmlFor/id, aria-required
- src/components/admin/CreateUserModal.tsx: htmlFor/id, required, aria-required, aria-describedby, autoComplete
- src/app/admin/me/AdminMeClient.tsx, products/import, sales/import, water-log/settings, login, brands, tuxedo: a11y polish (ids/required/aria)
This commit is contained in:
2026-06-03 16:39:19 +00:00
parent 03ae372509
commit 0245aa29cc
34 changed files with 1122 additions and 295 deletions
+20 -3
View File
@@ -76,7 +76,13 @@ export default function ContactClientPage() {
</svg>
</div>
<h3 className="text-lg font-bold text-[#0a0a0a] mb-3">Phone</h3>
<p className="text-[#666] leading-relaxed">support@routecommerce.com</p>
<a
href="tel:+19703235631"
className="block text-[#1a4d2e] hover:text-[#2d6a4f] font-semibold leading-relaxed"
>
(970) 323-5631
</a>
<p className="text-sm text-[#888] mt-1">Mon&ndash;Fri, 8 AM &ndash; 6 PM MT</p>
</article>
<article className="rounded-3xl bg-white border border-[#e5e5e5] p-8 text-center shadow-sm hover:shadow-lg hover:-translate-y-1 transition-all duration-300">
@@ -86,7 +92,18 @@ export default function ContactClientPage() {
</svg>
</div>
<h3 className="text-lg font-bold text-[#0a0a0a] mb-3">Email</h3>
<p className="text-[#666] leading-relaxed">hello@routecommerce.com</p>
<a
href="mailto:hello@routecommerce.com"
className="block text-[#1a4d2e] hover:text-[#2d6a4f] font-semibold leading-relaxed"
>
hello@routecommerce.com
</a>
<a
href="mailto:support@routecommerce.com"
className="block text-sm text-[#666] hover:text-[#1a4d2e] mt-1"
>
support@routecommerce.com
</a>
</article>
</div>
@@ -265,7 +282,7 @@ export default function ContactClientPage() {
<path strokeLinecap="round" strokeLinejoin="round" d="M13 10V3L4 14h7v7l9-11h-7z" />
</svg>
</div>
<span className="text-sm text-[#666]">2024 Route Commerce. All rights reserved.</span>
<span className="text-sm text-[#666]">&copy; {new Date().getFullYear()} Route Commerce. All rights reserved.</span>
</div>
<nav className="flex items-center gap-6 text-sm text-[#888]" aria-label="Footer navigation">
<Link href="/privacy-policy" className="hover:text-[#1a4d2e] transition-colors">Privacy</Link>