=== 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.
100 lines
4.3 KiB
TypeScript
100 lines
4.3 KiB
TypeScript
export const orderDashboardApp = {
|
|
name: 'order-dashboard',
|
|
description: 'Dashboard showing order overview and recent orders',
|
|
|
|
async render(context: any, data: any) {
|
|
const { orders = [], stats = {} } = data;
|
|
|
|
return `
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Order Dashboard - 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; }
|
|
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; margin-bottom: 32px; }
|
|
.stat-card { background: white; padding: 24px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); }
|
|
.stat-label { font-size: 14px; color: #666; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; }
|
|
.stat-value { font-size: 36px; font-weight: 600; color: #1a1a1a; }
|
|
.stat-change { font-size: 14px; color: #10b981; margin-top: 8px; }
|
|
.orders-section { background: white; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); padding: 24px; }
|
|
.section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
|
|
.section-title { font-size: 20px; font-weight: 600; }
|
|
.orders-table { width: 100%; border-collapse: collapse; }
|
|
.orders-table th { text-align: left; padding: 12px; border-bottom: 2px solid #e5e5e5; font-size: 12px; color: #666; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
.orders-table td { padding: 16px 12px; border-bottom: 1px solid #f0f0f0; }
|
|
.order-id { font-weight: 600; color: #1a1a1a; }
|
|
.badge { display: inline-block; padding: 4px 12px; border-radius: 12px; font-size: 12px; font-weight: 600; }
|
|
.badge-pending { background: #fef3c7; color: #92400e; }
|
|
.badge-fulfilled { background: #d1fae5; color: #065f46; }
|
|
.badge-canceled { background: #fee2e2; color: #991b1b; }
|
|
.action-btn { background: #000; color: white; padding: 8px 16px; border-radius: 6px; border: none; cursor: pointer; font-size: 14px; }
|
|
.action-btn:hover { background: #333; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>📦 Order Dashboard</h1>
|
|
|
|
<div class="stats">
|
|
<div class="stat-card">
|
|
<div class="stat-label">Total Orders</div>
|
|
<div class="stat-value">${stats.totalOrders || 0}</div>
|
|
<div class="stat-change">+${stats.ordersChange || 0}% vs last period</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-label">Total Revenue</div>
|
|
<div class="stat-value">$${stats.totalRevenue || '0.00'}</div>
|
|
<div class="stat-change">+${stats.revenueChange || 0}% vs last period</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-label">Avg Order Value</div>
|
|
<div class="stat-value">$${stats.avgOrderValue || '0.00'}</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-label">Pending Orders</div>
|
|
<div class="stat-value">${stats.pendingOrders || 0}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="orders-section">
|
|
<div class="section-header">
|
|
<div class="section-title">Recent Orders</div>
|
|
</div>
|
|
<table class="orders-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Order #</th>
|
|
<th>Customer</th>
|
|
<th>Date</th>
|
|
<th>Total</th>
|
|
<th>Status</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
${orders.map((order: any) => `
|
|
<tr>
|
|
<td><span class="order-id">#${order.orderNumber}</span></td>
|
|
<td>${order.customerEmail}</td>
|
|
<td>${new Date(order.createdOn).toLocaleDateString()}</td>
|
|
<td>${order.grandTotal.currency} ${order.grandTotal.value}</td>
|
|
<td><span class="badge badge-${order.fulfillmentStatus.toLowerCase()}">${order.fulfillmentStatus}</span></td>
|
|
<td><button class="action-btn" onclick="window.parent.postMessage({type:'view-order',orderId:'${order.id}'},'*')">View</button></td>
|
|
</tr>
|
|
`).join('')}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
`;
|
|
}
|
|
};
|