=== UPDATES === - fieldedge: Added apps, tools, main server entry, full rebuild - lightspeed: Added complete src/ directory with tools + apps - squarespace: Full rebuild — new apps, clients, tools, types modules - toast: Full rebuild — api-client, apps, tools, types - touchbistro: Full rebuild — api-client, tools, types, gitignore - servicetitan: Added 4 React UI apps (call-tracking, lead-source-analytics, performance-metrics, schedule-calendar) All servers restructured from single-file to modular architecture.
70 lines
2.8 KiB
TypeScript
70 lines
2.8 KiB
TypeScript
export const customerGridApp = {
|
|
name: 'customer-grid',
|
|
description: 'Customer directory with search and filtering',
|
|
|
|
async render(context: any, data: any) {
|
|
const { customers = [] } = data;
|
|
|
|
return `
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Customers - Squarespace</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #f5f5f5; padding: 20px; }
|
|
.container { max-width: 1400px; margin: 0 auto; }
|
|
h1 { font-size: 32px; margin-bottom: 24px; color: #1a1a1a; }
|
|
.customer-section { background: white; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); padding: 24px; }
|
|
.search-box { width: 100%; padding: 12px; border: 1px solid #e5e5e5; border-radius: 6px; margin-bottom: 20px; font-size: 14px; }
|
|
.customer-table { width: 100%; border-collapse: collapse; }
|
|
.customer-table th { text-align: left; padding: 12px; border-bottom: 2px solid #e5e5e5; font-size: 12px; color: #666; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
.customer-table td { padding: 16px 12px; border-bottom: 1px solid #f0f0f0; }
|
|
.customer-name { font-weight: 600; color: #1a1a1a; }
|
|
.customer-email { font-size: 13px; color: #666; }
|
|
.action-btn { background: #000; color: white; padding: 8px 16px; border-radius: 6px; border: none; cursor: pointer; font-size: 13px; }
|
|
.action-btn:hover { background: #333; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>👥 Customers</h1>
|
|
|
|
<div class="customer-section">
|
|
<input type="text" class="search-box" placeholder="Search customers by name or email...">
|
|
<table class="customer-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Customer</th>
|
|
<th>Email</th>
|
|
<th>Orders</th>
|
|
<th>Total Spent</th>
|
|
<th>Member Since</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
${customers.map((customer: any) => `
|
|
<tr>
|
|
<td>
|
|
<div class="customer-name">${customer.firstName || ''} ${customer.lastName || ''}</div>
|
|
</td>
|
|
<td><div class="customer-email">${customer.email}</div></td>
|
|
<td>${customer.orderCount || 0}</td>
|
|
<td>${customer.totalSpent ? `${customer.totalSpent.currency} ${customer.totalSpent.value}` : '$0.00'}</td>
|
|
<td>${new Date(customer.createdOn).toLocaleDateString()}</td>
|
|
<td><button class="action-btn" onclick="window.parent.postMessage({type:'view-customer',customerId:'${customer.id}'},'*')">View</button></td>
|
|
</tr>
|
|
`).join('')}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
`;
|
|
}
|
|
};
|