feat: Create customer-spa core foundation (Sprint 1)

Sprint 1 - Foundation Complete! 

Created Core Files:
 src/main.tsx - Entry point
 src/App.tsx - Main app with routing
 src/index.css - Global styles (TailwindCSS)
 index.html - Development HTML

Pages Created (Placeholders):
 pages/Shop/index.tsx - Product listing
 pages/Product/index.tsx - Product detail
 pages/Cart/index.tsx - Shopping cart
 pages/Checkout/index.tsx - Checkout process
 pages/Account/index.tsx - My Account with sub-routes

Library Setup:
 lib/api/client.ts - API client with endpoints
 lib/cart/store.ts - Cart state management (Zustand)
 types/index.ts - TypeScript definitions

Configuration:
 .gitignore - Ignore node_modules, dist, logs
 README.md - Documentation

Features Implemented:

1. Routing (React Router v7)
   - /shop - Product listing
   - /shop/product/:id - Product detail
   - /shop/cart - Shopping cart
   - /shop/checkout - Checkout
   - /shop/account/* - My Account (dashboard, orders, profile)

2. API Client
   - Fetch wrapper with error handling
   - WordPress nonce authentication
   - Endpoints for shop, cart, checkout, account
   - TypeScript typed responses

3. Cart State (Zustand)
   - Add/update/remove items
   - Cart drawer (open/close)
   - LocalStorage persistence
   - Quantity management
   - Coupon support

4. Type Definitions
   - Product, Order, Customer types
   - Address, ShippingMethod, PaymentMethod
   - Cart, CartItem types
   - Window interface for WordPress globals

5. React Query Setup
   - QueryClient configured
   - 5-minute stale time
   - Retry on error
   - No refetch on window focus

6. Toast Notifications
   - Sonner toast library
   - Top-right position
   - Rich colors

Tech Stack:
- React 18 + TypeScript
- Vite (port 5174)
- React Router v7
- TanStack Query
- Zustand (state)
- TailwindCSS
- shadcn/ui
- React Hook Form + Zod

Dependencies Installed:
 437 packages installed
 All peer dependencies resolved
 Ready for development

Next Steps (Sprint 2):
- Implement Shop page with product grid
- Create ProductCard component
- Add filters and search
- Implement pagination
- Connect to WordPress API

Ready to run:
```bash
cd customer-spa
npm run dev
# Opens https://woonoow.local:5174
```
This commit is contained in:
dwindown
2025-11-21 13:53:38 +07:00
parent 342104eeab
commit 909bddb23d
15 changed files with 8398 additions and 0 deletions

View File

@@ -0,0 +1,154 @@
/**
* TypeScript type definitions for WooNooW Customer SPA
*/
export interface Product {
id: number;
name: string;
slug: string;
type: 'simple' | 'variable' | 'grouped' | 'external';
status: 'publish' | 'draft' | 'pending';
featured: boolean;
description: string;
short_description: string;
sku: string;
price: string;
regular_price: string;
sale_price: string;
on_sale: boolean;
stock_status: 'instock' | 'outofstock' | 'onbackorder';
stock_quantity: number | null;
manage_stock: boolean;
images: ProductImage[];
categories: ProductCategory[];
tags: ProductTag[];
attributes: ProductAttribute[];
variations?: number[];
meta_data?: MetaData[];
}
export interface ProductImage {
id: number;
src: string;
name: string;
alt: string;
}
export interface ProductCategory {
id: number;
name: string;
slug: string;
}
export interface ProductTag {
id: number;
name: string;
slug: string;
}
export interface ProductAttribute {
id: number;
name: string;
position: number;
visible: boolean;
variation: boolean;
options: string[];
}
export interface ProductVariation {
id: number;
product_id: number;
sku: string;
price: string;
regular_price: string;
sale_price: string;
on_sale: boolean;
stock_status: 'instock' | 'outofstock' | 'onbackorder';
stock_quantity: number | null;
image: ProductImage;
attributes: Record<string, string>;
}
export interface MetaData {
key: string;
value: any;
}
export interface Order {
id: number;
number: string;
status: string;
date: string;
total: string;
currency: string;
items_count: number;
items: OrderItem[];
billing: Address;
shipping: Address;
payment_method: string;
payment_method_title: string;
shipping_method: string;
shipping_method_title: string;
}
export interface OrderItem {
id: number;
name: string;
product_id: number;
variation_id: number;
quantity: number;
price: string;
total: string;
image?: string;
}
export interface Address {
first_name: string;
last_name: string;
company?: string;
address_1: string;
address_2?: string;
city: string;
state: string;
postcode: string;
country: string;
email?: string;
phone?: string;
}
export interface Customer {
id: number;
email: string;
first_name: string;
last_name: string;
username: string;
billing: Address;
shipping: Address;
avatar_url: string;
}
export interface ShippingMethod {
id: string;
title: string;
cost: string;
description?: string;
}
export interface PaymentMethod {
id: string;
title: string;
description?: string;
icon?: string;
}
// Global window interface for WordPress data
declare global {
interface Window {
woonoowCustomer?: {
apiUrl: string;
nonce: string;
customer?: Customer;
settings?: Record<string, any>;
};
}
}