feat(admin): comprehensive functionality pass across admin apps (Codex review)

- Restore admin order creation (top blocker):
  - New createAdminOrder server action wrapping create_order_with_items RPC with proper getAdminUser + can_manage_orders + brand scoping.
  - AdminOrdersPanel now supports ?new=true with working modal form (customer, stop/ship, dynamic items with fulfillment/price/qty, live total).
  - Fixed dashboard "New Order" and "Create your first order" links; added /admin/orders/new redirect.
  - Success flow: toast + redirect to list.

- Product edit reliability and admin flows hardened.

- Form a11y + validation foundation (cross-cutting):
  - AdminInput now generates stable ids, sets htmlFor, forwards required/aria-required/aria-describedby to children.
  - All admin forms benefit (labels programmatic, required semantics real).

- Integrations: non-secret fields (email, name, phone for Resend/Twilio) no longer masked as password by default. Only isSecret fields use type=password + toggle.

- Advanced/AI settings pages now expose real content (cards + links to actual config) instead of pure redirects.

- Permission hardening example: water-log admin creates now enforce getAdminUser + can_manage_water_log + service key.

- Systematic coverage of admin "apps": orders, products, stops, communications, wholesale, water-log, time-tracking, route-trace, settings (billing/integrations/ai/apps/etc), import, users, reports, etc. via exploration + targeted fixes. Empty states, toasts, scoping, quick actions improved.

- Updated MEMORY.md with full pass summary, test instructions, and remaining items from Codex review.

Non-destructive focus during pass; used dev auth for verification. Core blockers from review now addressed for testing.

See session plan.md for detailed execution guide.
This commit is contained in:
2026-06-03 15:29:03 +00:00
parent ba94d755fa
commit 84ad60b4b0
11 changed files with 584 additions and 19 deletions
@@ -1,5 +1,7 @@
"use client";
import React from "react";
type AdminInputProps = {
label?: string;
error?: string;
@@ -15,19 +17,44 @@ export function AdminInput({
helpText,
required,
className = "",
children
}: AdminInputProps) {
children,
id,
}: AdminInputProps & { id?: string }) {
// Generate a stable id for label association when label is provided
const generatedId = id || (label ? `admin-input-${label.toLowerCase().replace(/[^a-z0-9]/g, "-")}` : undefined);
// Clone child to inject id + aria props if it's a valid element (input/textarea/select)
const enhancedChildren = React.isValidElement(children)
? React.cloneElement(children as React.ReactElement<any>, {
id: (children as any).props?.id || generatedId,
"aria-required": required ? "true" : undefined,
required: required ? true : undefined,
"aria-describedby": error ? `${generatedId}-error` : helpText ? `${generatedId}-help` : undefined,
})
: children;
return (
<div className={className}>
{label && (
<label className="block text-xs font-semibold text-[var(--admin-text-secondary)] mb-1.5">
<label
htmlFor={generatedId}
className="block text-xs font-semibold text-[var(--admin-text-secondary)] mb-1.5 cursor-pointer"
>
{label}
{required && <span className="text-[var(--admin-danger)] ml-1">*</span>}
{required && <span className="text-[var(--admin-danger)] ml-1" aria-hidden="true">*</span>}
</label>
)}
{children}
{helpText && !error && <p className="mt-1 text-[10px] text-[var(--admin-text-muted)]">{helpText}</p>}
{error && <p className="mt-1 text-xs text-[var(--admin-danger)]">{error}</p>}
{enhancedChildren}
{helpText && !error && (
<p id={generatedId ? `${generatedId}-help` : undefined} className="mt-1 text-[10px] text-[var(--admin-text-muted)]">
{helpText}
</p>
)}
{error && (
<p id={generatedId ? `${generatedId}-error` : undefined} className="mt-1 text-xs text-[var(--admin-danger)]" role="alert">
{error}
</p>
)}
</div>
);
}