Files
billing/lib/theme/theme-toggle.tsx
d61b2220c3 feat(billing): enterprise billing portal with dark/light theme (#1)
Overhaul billing.hanzo.ai with dual-mode theming (dark default matching
docs site, light via toggle) and 4 new feature panels: credits with
starter credit countdown, transaction history with filtering, promotions
with discount code validation, and support tier upsell cards.

- Expand CSS custom properties for semantic tokens (bg, text, border,
  brand, success/warning/danger) with html.light class inversion
- Add ThemeProvider context + ThemeToggle component
- Retheme all 10 existing billing components from hardcoded zinc to
  semantic token classes
- Extend Commerce client with 5 new API methods (credit grants, credit
  balance, portal overview, meters, meter events summary)
- Add CreditGrant, TransactionRecord, SupportTier types
- New CreditsPanel with progress bars and expiry countdown
- New TransactionsPanel with color-coded types and pagination
- New PromotionsPanel with discount code entry/validation
- New SupportTiersPanel with 3-tier card layout
- Expand BillingWorkspace from 7 to 11 tabs
- Wire credit/transaction/support data through billing-shell
- Add "Add Funds" preset tiles with scale animations
- Add Account link to hanzo.id in nav header

Co-authored-by: Hanzo Dev <[email protected]>
2026-02-24 01:51:30 -08:00

35 lines
1.3 KiB
TypeScript

'use client'
import { useTheme } from './theme-provider'
export function ThemeToggle() {
const { theme, toggleTheme } = useTheme()
return (
<button
type="button"
onClick={toggleTheme}
className="rounded-lg border border-border p-1.5 text-text-muted transition hover:bg-bg-elevated hover:text-text"
aria-label={`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`}
>
{theme === 'dark' ? (
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<circle cx="12" cy="12" r="5" />
<line x1="12" y1="1" x2="12" y2="3" />
<line x1="12" y1="21" x2="12" y2="23" />
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
<line x1="1" y1="12" x2="3" y2="12" />
<line x1="21" y1="12" x2="23" y2="12" />
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
</svg>
) : (
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
</svg>
)}
</button>
)
}