Files
app/src/lib/mock-data.ts
T
Frontend Frankie 5fbf0f5c5c feat: add core PWA screens (auth, dashboard, purchases, products, alerts, settings)
Build all 8 primary screens for CAR-33 on top of the Phase 1 scaffold:
- Auth: login, register, forgot password with JWT flow and mock fallback
- Dashboard: triggered alerts banner, spending stats, price trend sparklines (Recharts), recent purchases
- Purchase History: store filter chips, paginated list with item previews
- Purchase Detail: receipt view with line items linking to product pages
- Products: search with instant filter, store price comparison badges
- Product Detail: 90-day price history chart (Recharts), store comparison table
- Store Comparison: ranked store cards with savings banner
- Price Alerts: triggered/watching sections, create form, progress bars, delete
- Coupons: expiration warnings, copy-to-clipboard coupon codes
- Account Linking: connect Meijer/Kroger/Target with status indicators
- Settings: profile, connected stores, notification toggles, theme switcher, sign out

Also adds:
- Mock data layer (src/lib/mock-data.ts) for demo/screenshot use
- StoreIcon component with store brand colors
- Code-split Recharts chunk (initial JS: 117KB, Recharts lazy: 498KB)
- All 48px+ touch targets, mobile-first Tailwind layout

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-17 12:24:31 +00:00

191 lines
8.6 KiB
TypeScript

import type { Purchase, Product, PriceHistory, Coupon, PriceAlert, User } from '../types/api.ts'
export const mockUser: User = {
id: 'u1',
email: 'sam@example.com',
name: 'Sam Johnson',
connectedStores: ['meijer', 'kroger'],
}
export const mockPurchases: Purchase[] = [
{
id: 'p1',
storeId: 'meijer',
storeName: 'Meijer',
date: '2026-03-15',
total: 47.23,
items: [
{ id: 'i1', productId: 'prod1', name: 'Whole Milk (1 gal)', quantity: 1, price: 3.49, unitPrice: 3.49 },
{ id: 'i2', productId: 'prod2', name: 'Bananas (bunch)', quantity: 1, price: 1.29, unitPrice: 1.29 },
{ id: 'i3', productId: 'prod3', name: 'Chicken Breast (2 lb)', quantity: 1, price: 9.98, unitPrice: 4.99 },
{ id: 'i4', productId: 'prod4', name: 'Cheddar Cheese (8 oz)', quantity: 2, price: 7.58, unitPrice: 3.79 },
{ id: 'i5', productId: 'prod5', name: 'Sourdough Bread', quantity: 1, price: 4.29, unitPrice: 4.29 },
{ id: 'i6', productId: 'prod6', name: 'Baby Spinach (5 oz)', quantity: 1, price: 3.99, unitPrice: 3.99 },
{ id: 'i7', productId: 'prod7', name: 'Greek Yogurt (32 oz)', quantity: 1, price: 5.49, unitPrice: 5.49 },
{ id: 'i8', productId: 'prod8', name: 'Pasta Sauce', quantity: 1, price: 3.79, unitPrice: 3.79 },
{ id: 'i9', productId: 'prod9', name: 'Spaghetti (16 oz)', quantity: 1, price: 1.89, unitPrice: 1.89 },
{ id: 'i10', productId: 'prod10', name: 'Eggs (dozen)', quantity: 1, price: 5.44, unitPrice: 5.44 },
],
},
{
id: 'p2',
storeId: 'kroger',
storeName: 'Kroger',
date: '2026-03-12',
total: 32.87,
items: [
{ id: 'i11', productId: 'prod1', name: 'Whole Milk (1 gal)', quantity: 1, price: 3.29, unitPrice: 3.29 },
{ id: 'i12', productId: 'prod10', name: 'Eggs (dozen)', quantity: 1, price: 5.29, unitPrice: 5.29 },
{ id: 'i13', productId: 'prod11', name: 'Orange Juice (52 oz)', quantity: 1, price: 4.49, unitPrice: 4.49 },
{ id: 'i14', productId: 'prod12', name: 'Ground Beef (1 lb)', quantity: 2, price: 11.98, unitPrice: 5.99 },
{ id: 'i15', productId: 'prod2', name: 'Bananas (bunch)', quantity: 1, price: 0.99, unitPrice: 0.99 },
{ id: 'i16', productId: 'prod13', name: 'Tortilla Chips', quantity: 1, price: 3.49, unitPrice: 3.49 },
{ id: 'i17', productId: 'prod14', name: 'Salsa (16 oz)', quantity: 1, price: 3.34, unitPrice: 3.34 },
],
},
{
id: 'p3',
storeId: 'meijer',
storeName: 'Meijer',
date: '2026-03-08',
total: 61.45,
items: [
{ id: 'i18', productId: 'prod3', name: 'Chicken Breast (2 lb)', quantity: 2, price: 19.96, unitPrice: 4.99 },
{ id: 'i19', productId: 'prod15', name: 'Rice (5 lb)', quantity: 1, price: 6.99, unitPrice: 6.99 },
{ id: 'i20', productId: 'prod6', name: 'Baby Spinach (5 oz)', quantity: 2, price: 7.98, unitPrice: 3.99 },
{ id: 'i21', productId: 'prod16', name: 'Olive Oil (16 oz)', quantity: 1, price: 8.99, unitPrice: 8.99 },
{ id: 'i22', productId: 'prod5', name: 'Sourdough Bread', quantity: 1, price: 4.29, unitPrice: 4.29 },
{ id: 'i23', productId: 'prod17', name: 'Butter (1 lb)', quantity: 1, price: 4.79, unitPrice: 4.79 },
{ id: 'i24', productId: 'prod18', name: 'Avocados (3 ct)', quantity: 1, price: 4.99, unitPrice: 4.99 },
{ id: 'i25', productId: 'prod19', name: 'Cereal (Family Size)', quantity: 1, price: 3.46, unitPrice: 3.46 },
],
},
{
id: 'p4',
storeId: 'target',
storeName: 'Target',
date: '2026-03-05',
total: 28.76,
items: [
{ id: 'i26', productId: 'prod20', name: 'Paper Towels (6 pk)', quantity: 1, price: 12.99, unitPrice: 12.99 },
{ id: 'i27', productId: 'prod21', name: 'Dish Soap', quantity: 1, price: 3.49, unitPrice: 3.49 },
{ id: 'i28', productId: 'prod22', name: 'Trash Bags (45 ct)', quantity: 1, price: 8.79, unitPrice: 8.79 },
{ id: 'i29', productId: 'prod23', name: 'Hand Soap (2 pk)', quantity: 1, price: 3.49, unitPrice: 3.49 },
],
},
]
export const mockProducts: Product[] = [
{
id: 'prod1',
name: 'Whole Milk (1 gal)',
brand: 'Store Brand',
category: 'Dairy',
prices: [
{ storeId: 'meijer', storeName: 'Meijer', price: 3.49, lastUpdated: '2026-03-15' },
{ storeId: 'kroger', storeName: 'Kroger', price: 3.29, lastUpdated: '2026-03-14' },
{ storeId: 'target', storeName: 'Target', price: 3.59, lastUpdated: '2026-03-13' },
],
},
{
id: 'prod10',
name: 'Eggs (dozen)',
brand: 'Store Brand',
category: 'Dairy',
prices: [
{ storeId: 'meijer', storeName: 'Meijer', price: 5.44, lastUpdated: '2026-03-15' },
{ storeId: 'kroger', storeName: 'Kroger', price: 5.29, lastUpdated: '2026-03-14' },
{ storeId: 'target', storeName: 'Target', price: 5.69, lastUpdated: '2026-03-13' },
],
},
{
id: 'prod3',
name: 'Chicken Breast (2 lb)',
brand: 'Store Brand',
category: 'Meat',
prices: [
{ storeId: 'meijer', storeName: 'Meijer', price: 9.98, lastUpdated: '2026-03-15' },
{ storeId: 'kroger', storeName: 'Kroger', price: 10.49, lastUpdated: '2026-03-14' },
{ storeId: 'target', storeName: 'Target', price: 10.99, lastUpdated: '2026-03-13' },
],
},
{
id: 'prod2',
name: 'Bananas (bunch)',
brand: 'Dole',
category: 'Produce',
prices: [
{ storeId: 'meijer', storeName: 'Meijer', price: 1.29, lastUpdated: '2026-03-15' },
{ storeId: 'kroger', storeName: 'Kroger', price: 0.99, lastUpdated: '2026-03-14' },
{ storeId: 'target', storeName: 'Target', price: 1.19, lastUpdated: '2026-03-13' },
],
},
{
id: 'prod5',
name: 'Sourdough Bread',
brand: 'Artisan Hearth',
category: 'Bakery',
prices: [
{ storeId: 'meijer', storeName: 'Meijer', price: 4.29, lastUpdated: '2026-03-15' },
{ storeId: 'kroger', storeName: 'Kroger', price: 4.49, lastUpdated: '2026-03-14' },
],
},
{
id: 'prod6',
name: 'Baby Spinach (5 oz)',
brand: 'Organic Girl',
category: 'Produce',
prices: [
{ storeId: 'meijer', storeName: 'Meijer', price: 3.99, lastUpdated: '2026-03-15' },
{ storeId: 'kroger', storeName: 'Kroger', price: 3.79, lastUpdated: '2026-03-14' },
{ storeId: 'target', storeName: 'Target', price: 4.19, lastUpdated: '2026-03-13' },
],
},
]
export function getMockPriceHistory(productId: string): PriceHistory[] {
const basePrice = productId === 'prod1' ? 3.29
: productId === 'prod10' ? 3.49
: productId === 'prod3' ? 8.99
: productId === 'prod2' ? 0.89
: 3.99
const stores = ['meijer', 'kroger', 'target']
const history: PriceHistory[] = []
for (let i = 90; i >= 0; i -= 7) {
const date = new Date(2026, 2, 17)
date.setDate(date.getDate() - i)
const dateStr = date.toISOString().split('T')[0]
for (const store of stores) {
const storeOffset = store === 'meijer' ? 0.10 : store === 'target' ? 0.20 : 0
// simulate price variation over time
const spike = (i > 30 && i < 50) ? 0.80 : 0
const drift = (90 - i) * 0.005
history.push({
date: dateStr,
price: Math.round((basePrice + storeOffset + spike + drift) * 100) / 100,
storeId: store,
})
}
}
return history
}
export const mockCoupons: Coupon[] = [
{ id: 'c1', productId: 'prod1', storeName: 'Kroger', description: '$0.50 off Whole Milk (1 gal)', discount: '$0.50', expiresAt: '2026-03-31', code: 'MILK50' },
{ id: 'c2', storeName: 'Meijer', description: '10% off Meat Department', discount: '10%', expiresAt: '2026-03-22' },
{ id: 'c3', productId: 'prod6', storeName: 'Kroger', description: 'Buy 2 Get 1 Free — Baby Spinach', discount: 'B2G1', expiresAt: '2026-04-05' },
{ id: 'c4', storeName: 'Target', description: '$5 off $40+ Grocery Purchase', discount: '$5.00', expiresAt: '2026-03-28', code: 'SAVE5' },
{ id: 'c5', productId: 'prod10', storeName: 'Meijer', description: '$1 off Eggs (dozen)', discount: '$1.00', expiresAt: '2026-03-25' },
]
export const mockAlerts: PriceAlert[] = [
{ id: 'a1', productId: 'prod10', productName: 'Eggs (dozen)', targetPrice: 4.99, currentPrice: 5.29, triggered: false },
{ id: 'a2', productId: 'prod2', productName: 'Bananas (bunch)', targetPrice: 1.09, currentPrice: 0.99, triggered: true },
{ id: 'a3', productId: 'prod3', productName: 'Chicken Breast (2 lb)', targetPrice: 9.50, currentPrice: 9.98, triggered: false },
{ id: 'a4', productId: 'prod1', productName: 'Whole Milk (1 gal)', targetPrice: 3.39, currentPrice: 3.29, triggered: true },
]