fix: address Chip's review — secure auth, wire TanStack Query, fix UX issues

Must-fix:
- Exclude JWT token from Zustand persist (partialize) to prevent
  localStorage XSS exfiltration — token now lives in memory only
- Wire all pages through TanStack Query hooks (usePurchases, useProduct,
  useProducts, usePriceHistory, useCoupons, usePriceAlerts) with proper
  loading skeletons and error states
- Add mock interceptor in api.ts (VITE_MOCK_API=true) so mock data flows
  through the same fetch path — single flag to switch to live API

Should-fix:
- Wire theme toggle to DOM (dark class on <html>)
- Fix AccountLinking form inputs (controlled with value/onChange)
- Remove unused err in catch blocks (Login, Register)
- Bump remaining min-h-10 touch targets to min-h-12 (48px)

Build: 128KB initial JS, Recharts 498KB lazy chunk. 5/5 tests pass.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Frontend Frankie
2026-03-18 11:54:06 +00:00
parent 5563b5f145
commit d0185fd93d
14 changed files with 307 additions and 62 deletions
+17 -3
View File
@@ -1,12 +1,26 @@
import { useParams, Link } from 'react-router-dom'
import { mockPurchases } from '../lib/mock-data.ts'
import { usePurchase } from '../hooks/useApi.ts'
import { StoreIcon } from '../components/StoreIcon.tsx'
export function PurchaseDetail() {
const { id } = useParams<{ id: string }>()
const purchase = mockPurchases.find((p) => p.id === id)
const { data: purchase, isLoading, error } = usePurchase(id ?? '')
if (!purchase) {
if (isLoading) {
return (
<div className="animate-pulse">
<div className="h-4 w-24 rounded bg-gray-200" />
<div className="mt-4 h-20 rounded-xl bg-gray-200" />
<div className="mt-4 space-y-1">
{[1, 2, 3, 4].map((i) => (
<div key={i} className="h-12 rounded bg-gray-200" />
))}
</div>
</div>
)
}
if (error || !purchase) {
return (
<div className="py-8 text-center">
<p className="text-sm text-gray-500">Purchase not found.</p>