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 034f12d0aa
commit fe5b0e87bd
14 changed files with 307 additions and 62 deletions
+13 -3
View File
@@ -8,7 +8,7 @@ import {
Legend,
ResponsiveContainer,
} from 'recharts'
import { mockProducts, getMockPriceHistory } from '../lib/mock-data.ts'
import { useProduct, usePriceHistory } from '../hooks/useApi.ts'
const storeLineColors: Record<string, string> = {
meijer: '#e31837',
@@ -18,7 +18,18 @@ const storeLineColors: Record<string, string> = {
export function ProductDetail() {
const { id } = useParams<{ id: string }>()
const product = mockProducts.find((p) => p.id === id)
const { data: product, isLoading: productLoading } = useProduct(id ?? '')
const { data: history = [], isLoading: historyLoading } = usePriceHistory(id ?? '')
if (productLoading || historyLoading) {
return (
<div className="animate-pulse">
<div className="h-4 w-20 rounded bg-gray-200" />
<div className="mt-4 h-8 w-48 rounded bg-gray-200" />
<div className="mt-6 h-52 rounded-xl bg-gray-200" />
</div>
)
}
if (!product) {
return (
@@ -31,7 +42,6 @@ export function ProductDetail() {
)
}
const history = getMockPriceHistory(product.id)
const lowestPrice = Math.min(...product.prices.map((p) => p.price))
// Reshape history for chart: { date, meijer, kroger, target }