Files
WooNooW/admin-spa/src/lib/api/customers.ts
Dwindi Ramadhana 396ca25be4 feat: Page Editor v1.0 - canonical schema, SSR parity, and migration
Major improvements to WooNooW Page Editor system:

Schema & Architecture:
- Canonical section schema with unified sectionSchema.ts
- Normalized feature-grid to use items (not features)
- Standardized default values across all section types
- Schema versioning with automatic migration on read

Backend (PHP):
- Enhanced PlaceholderRenderer with typed output contracts
- Added fallback behavior for empty/invalid dynamic sources
- Added caching support for post data resolution
- New SchemaMigration class for backward compatibility
- New Features class for feature flags
- Enhanced PageSSR with full style support
- Removed controller-level special-casing for related_posts

Frontend (Admin SPA):
- Updated CanvasRenderer with schema-aware transformation
- Enhanced InspectorPanel with canonical schema metadata
- Added new section renderers

Frontend (Customer SPA):
- New section components: BentoCategoryGrid, MarqueeBanner, ProductCarousel, ShoppableImage
- Updated FeatureGridSection for items prop contract

Testing:
- Add PHP tests: SchemaMigrationTest, PlaceholderRendererTest, PageSSRTest
- Add TypeScript tests: schema-integration, feature-grid-regression
- Add parity tests for React vs SSR content matching
- Add CI script: check-schema-drift.mjs
- Add VERIFICATION_CHECKLIST.md

Documentation:
- RELEASE_NOTES-v1.0.md with full release notes
- docs/PAGE_EDITOR_SECTION_SCHEMA_V1.md
- docs/PAGE_EDITOR_SSR_COVERAGE_AUDIT.md
2026-05-30 13:02:08 +07:00

110 lines
2.2 KiB
TypeScript

import { api } from '../api';
export interface CustomerAddress {
first_name: string;
last_name: string;
company?: string;
address_1: string;
address_2?: string;
city: string;
state?: string;
postcode: string;
country: string;
phone?: string;
}
export interface CustomerStats {
total_orders: number;
total_spent: number;
}
export interface Customer {
id: number;
username: string;
email: string;
first_name: string;
last_name: string;
display_name: string;
registered: string;
role: string;
billing?: CustomerAddress;
shipping?: CustomerAddress;
stats?: CustomerStats;
}
export interface CustomerListResponse {
data: Customer[];
pagination: {
total: number;
total_pages: number;
current: number;
per_page: number;
};
}
export interface CustomerFormData {
email: string;
first_name: string;
last_name: string;
username?: string;
password?: string;
billing?: Partial<CustomerAddress>;
shipping?: Partial<CustomerAddress>;
send_email?: boolean;
}
export interface CustomerSearchResult {
id: number;
name: string;
email: string;
}
export const CustomersApi = {
/**
* List customers with pagination and filtering
*/
list: async (params?: {
page?: number;
per_page?: number;
search?: string;
role?: string;
}): Promise<CustomerListResponse> => {
return api.get('/customers', params);
},
/**
* Get single customer
*/
get: async (id: number): Promise<Customer> => {
return api.get(`/customers/${id}`);
},
/**
* Create new customer
*/
create: async (data: CustomerFormData): Promise<Customer> => {
return api.post('/customers', data);
},
/**
* Update customer
*/
update: async (id: number, data: Partial<CustomerFormData>): Promise<Customer> => {
return api.put(`/customers/${id}`, data);
},
/**
* Delete customer
*/
delete: async (id: number): Promise<void> => {
return api.del(`/customers/${id}`);
},
/**
* Search customers (for autocomplete)
*/
search: async (query: string, limit?: number): Promise<CustomerSearchResult[]> => {
return api.get('/customers/search', { q: query, limit });
},
};