edit customer page
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
/** Formats a 10-digit US phone number as "555-123-4567" for readability. Leaves anything else (extensions, international, garbage input) unchanged. */
|
||||||
|
export function formatPhone(raw: string | null | undefined): string | null {
|
||||||
|
if (!raw) return null;
|
||||||
|
const trimmed = raw.trim();
|
||||||
|
if (!trimmed) return null;
|
||||||
|
|
||||||
|
const digits = trimmed.replace(/\D/g, '');
|
||||||
|
const tenDigit = digits.length === 11 && digits.startsWith('1') ? digits.slice(1) : digits;
|
||||||
|
|
||||||
|
if (tenDigit.length === 10) {
|
||||||
|
return `${tenDigit.slice(0, 3)}-${tenDigit.slice(3, 6)}-${tenDigit.slice(6)}`;
|
||||||
|
}
|
||||||
|
return trimmed;
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Router } from 'express';
|
import { Router } from 'express';
|
||||||
import { db } from '../db.js';
|
import { db } from '../db.js';
|
||||||
|
import { formatPhone } from '../phone.js';
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
@@ -19,4 +20,41 @@ router.get('/', (req, res) => {
|
|||||||
res.render('customers/list.njk', { customers, q });
|
res.render('customers/list.njk', { customers, q });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.get('/:id/edit', (req, res) => {
|
||||||
|
const customer = db.prepare('SELECT * FROM customers WHERE id = ?').get(req.params.id);
|
||||||
|
if (!customer) return res.status(404).send('Customer not found');
|
||||||
|
res.render('customers/edit.njk', { customer });
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/:id/edit', (req, res) => {
|
||||||
|
const b = req.body as Record<string, string>;
|
||||||
|
|
||||||
|
const name = (b.name || '').trim();
|
||||||
|
if (!name) return res.status(400).send('Name is required');
|
||||||
|
|
||||||
|
const info = db
|
||||||
|
.prepare(
|
||||||
|
`UPDATE customers SET
|
||||||
|
name = ?, phone = ?, alt_phone = ?, email = ?,
|
||||||
|
address_line1 = ?, address_line2 = ?, city = ?, state = ?, zip = ?
|
||||||
|
WHERE id = ?`
|
||||||
|
)
|
||||||
|
.run(
|
||||||
|
name,
|
||||||
|
formatPhone(b.phone),
|
||||||
|
formatPhone(b.alt_phone),
|
||||||
|
b.email || null,
|
||||||
|
b.address_line1 || null,
|
||||||
|
b.address_line2 || null,
|
||||||
|
b.city || null,
|
||||||
|
b.state || null,
|
||||||
|
b.zip || null,
|
||||||
|
req.params.id
|
||||||
|
);
|
||||||
|
|
||||||
|
if (info.changes === 0) return res.status(404).send('Customer not found');
|
||||||
|
|
||||||
|
res.redirect(303, `/customers/${req.params.id}/edit`);
|
||||||
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Router } from 'express';
|
import { Router } from 'express';
|
||||||
import { db, nextOrderNumber } from '../db.js';
|
import { db, nextOrderNumber } from '../db.js';
|
||||||
import { parseCents } from '../money.js';
|
import { parseCents } from '../money.js';
|
||||||
|
import { formatPhone } from '../phone.js';
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
@@ -119,8 +120,8 @@ router.post('/orders', (req, res) => {
|
|||||||
b.new_customer_city || null,
|
b.new_customer_city || null,
|
||||||
b.new_customer_state || null,
|
b.new_customer_state || null,
|
||||||
b.new_customer_zip || null,
|
b.new_customer_zip || null,
|
||||||
b.new_customer_phone || null,
|
formatPhone(b.new_customer_phone),
|
||||||
b.new_customer_alt_phone || null,
|
formatPhone(b.new_customer_alt_phone),
|
||||||
b.new_customer_email || null
|
b.new_customer_email || null
|
||||||
);
|
);
|
||||||
customerId = Number(info.lastInsertRowid);
|
customerId = Number(info.lastInsertRowid);
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{% extends "layout.njk" %}
|
||||||
|
{% block title %}Edit {{ customer.name }} — Harding's Clocks{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="page-header">
|
||||||
|
<h1>Edit Customer</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form method="post" action="/customers/{{ customer.id }}/edit" class="stacked-form">
|
||||||
|
<fieldset>
|
||||||
|
<legend>Customer</legend>
|
||||||
|
<div class="grid-2">
|
||||||
|
<label>Name <input type="text" name="name" value="{{ customer.name }}" required></label>
|
||||||
|
<label>Phone <input type="text" name="phone" value="{{ customer.phone or '' }}"></label>
|
||||||
|
<label>Alt phone <input type="text" name="alt_phone" value="{{ customer.alt_phone or '' }}"></label>
|
||||||
|
<label>Email <input type="email" name="email" value="{{ customer.email or '' }}"></label>
|
||||||
|
<label>Address line 1 <input type="text" name="address_line1" value="{{ customer.address_line1 or '' }}"></label>
|
||||||
|
<label>Address line 2 <input type="text" name="address_line2" value="{{ customer.address_line2 or '' }}"></label>
|
||||||
|
<label>City <input type="text" name="city" value="{{ customer.city or '' }}"></label>
|
||||||
|
<label>State <input type="text" name="state" value="{{ customer.state or '' }}"></label>
|
||||||
|
<label>Zip <input type="text" name="zip" value="{{ customer.zip or '' }}"></label>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<button type="submit">Save</button>
|
||||||
|
<a class="button-link" href="/customers">Cancel</a>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for c in customers %}
|
{% for c in customers %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ c.name }}</td>
|
<td><a href="/customers/{{ c.id }}/edit">{{ c.name }}</a></td>
|
||||||
<td>{% if c.phone %}<a href="tel:{{ c.phone | tel }}">{{ c.phone }}</a>{% endif %}</td>
|
<td>{% if c.phone %}<a href="tel:{{ c.phone | tel }}">{{ c.phone }}</a>{% endif %}</td>
|
||||||
<td>{{ c.email or '' }}</td>
|
<td>{{ c.email or '' }}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|||||||
Reference in New Issue
Block a user