- Implemented the full order lifecycle, secure customer tracker, automatic acceptance emails, configurable status templates, and guest/account CRM management.
Key areas: [OrderStatusService.php](/Users/tyemeclifford/Documents/GH/fatbottomgrille/app/Services/OrderStatusService.php), [AdminController.php](/Users/tyemeclifford/Documents/GH/fatbottomgrille/app/Controllers/AdminController.php), and [Database.php](/Users/tyemeclifford/Documents/GH/fatbottomgrille/app/Core/Database.php). SQLite migration applied successfully. PHP/JS syntax, integration workflows, rendered pages, database integrity, and tracker authorization all passed. Invalid tracker tokens correctly return 403.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
<div class="admin-page-actions">
|
||||
<form class="admin-filters" action="<?= e(url('/admin/customers')) ?>" method="get">
|
||||
<input type="search" name="q" value="<?= e($query) ?>" placeholder="Search name, email, or phone">
|
||||
<select name="active">
|
||||
<option value="">All customers</option>
|
||||
<option value="1" <?= selected($activeFilter, '1') ?>>Active</option>
|
||||
<option value="0" <?= selected($activeFilter, '0') ?>>Deactivated</option>
|
||||
</select>
|
||||
<button class="button button-small" type="submit">Filter</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<section class="admin-panel">
|
||||
<div class="admin-panel-heading">
|
||||
<div><span class="eyebrow">Customer relationships</span><h2>Customer CRM</h2></div>
|
||||
<span class="count-badge"><?= count($customers) ?> shown</span>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Customer</th><th>Account</th><th>Status</th><th>Orders</th><th>Lifetime Value</th><th>Last Order</th><th></th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!$customers): ?><tr><td colspan="7" class="empty-cell">No customers match those filters.</td></tr><?php endif; ?>
|
||||
<?php foreach ($customers as $customer): ?>
|
||||
<tr>
|
||||
<td><strong><?= e($customer['full_name']) ?></strong><small><?= e($customer['email']) ?> · <?= e($customer['phone']) ?></small></td>
|
||||
<td><span class="role-badge"><?= $customer['user_id'] ? 'Has account' : 'Guest' ?></span></td>
|
||||
<td><span class="status-dot <?= $customer['active'] ? 'is-on' : '' ?>"><?= $customer['active'] ? 'Active' : 'Deactivated' ?></span></td>
|
||||
<td><?= (int) $customer['order_count'] ?></td>
|
||||
<td><?= money($customer['lifetime_value_cents']) ?></td>
|
||||
<td><?= $customer['last_order_at'] ? e(store_datetime((string) $customer['last_order_at'], 'M j, Y')) : '—' ?></td>
|
||||
<td><a class="button button-small button-ghost" href="<?= e(url('/admin/customer')) ?>?id=<?= (int) $customer['id'] ?>">Manage</a></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
Reference in New Issue
Block a user