import { useEffect, useState } from 'react'; import { Link, Route, Routes, useNavigate } from 'react-router-dom'; import { op } from './analytics'; import { CartPage } from './pages/Cart'; import { CheckoutPage } from './pages/Checkout'; import { LoginPage, PRESET_GROUPS } from './pages/Login'; import { ProductPage } from './pages/Product'; import { ShopPage } from './pages/Shop'; import type { CartItem, Product, User } from './types'; const PRODUCTS: Product[] = [ { id: 'p1', name: 'Classic T-Shirt', price: 25, category: 'clothing' }, { id: 'p2', name: 'Coffee Mug', price: 15, category: 'accessories' }, { id: 'p3', name: 'Hoodie', price: 60, category: 'clothing' }, { id: 'p4', name: 'Sticker Pack', price: 10, category: 'accessories' }, { id: 'p5', name: 'Cap', price: 35, category: 'clothing' }, ]; export default function App() { const navigate = useNavigate(); const [cart, setCart] = useState([]); const [user, setUser] = useState(null); useEffect(() => { const stored = localStorage.getItem('op_testbed_user'); if (stored) { const u = JSON.parse(stored) as User; setUser(u); op.identify({ profileId: u.id, firstName: u.firstName, lastName: u.lastName, email: u.email, }); applyGroups(u); } op.ready(); }, []); function applyGroups(u: User) { op.setGroups(u.groupIds); for (const id of u.groupIds) { const meta = PRESET_GROUPS.find((g) => g.id === id); if (meta) { op.upsertGroup({ id, ...meta }); } } } function login(u: User) { localStorage.setItem('op_testbed_user', JSON.stringify(u)); setUser(u); op.identify({ profileId: u.id, firstName: u.firstName, lastName: u.lastName, email: u.email, }); applyGroups(u); op.track('user_login', { method: 'form', group_count: u.groupIds.length }); navigate('/'); } function logout() { localStorage.removeItem('op_testbed_user'); op.clear(); setUser(null); } function addToCart(product: Product) { setCart((prev) => { const existing = prev.find((i) => i.id === product.id); if (existing) { return prev.map((i) => i.id === product.id ? { ...i, qty: i.qty + 1 } : i ); } return [...prev, { ...product, qty: 1 }]; }); op.track('add_to_cart', { product_id: product.id, product_name: product.name, price: product.price, category: product.category, }); } function removeFromCart(id: string) { const item = cart.find((i) => i.id === id); if (item) { op.track('remove_from_cart', { product_id: item.id, product_name: item.name, }); } setCart((prev) => prev.filter((i) => i.id !== id)); } function startCheckout() { const total = cart.reduce((sum, i) => sum + i.price * i.qty, 0); op.track('checkout_started', { total, item_count: cart.reduce((sum, i) => sum + i.qty, 0), items: cart.map((i) => i.id), }); navigate('/checkout'); } function pay(succeed: boolean) { const total = cart.reduce((sum, i) => sum + i.price * i.qty, 0); op.track('payment_attempted', { total, success: succeed }); if (succeed) { op.revenue(total, { items: cart.map((i) => i.id), item_count: cart.reduce((sum, i) => sum + i.qty, 0), }); op.track('purchase_completed', { total }); setCart([]); navigate('/success'); } else { op.track('purchase_failed', { total, reason: 'declined' }); navigate('/error'); } } const cartCount = cart.reduce((sum, i) => sum + i.qty, 0); return (
} path="/" /> } path="/product/:id" /> } path="/login" /> } path="/cart" /> } path="/checkout" />
[OK]
Payment successful

Your order has been placed. Thanks for testing!

} path="/success" />
[ERR]
Payment failed

Card declined. Try again or go back to cart.

} path="/error" /> ); }