clean up some fields. Increase font size and contrast

This commit is contained in:
2026-07-11 20:08:37 -04:00
parent 23cbd6f2bf
commit eea4683c5b
9 changed files with 32 additions and 69 deletions
+10 -5
View File
@@ -6,24 +6,28 @@
/* Wood tones */ /* Wood tones */
--color-wood-dark: #4A2810; /* dark mahogany — nav, headings */ --color-wood-dark: #4A2810; /* dark mahogany — nav, headings */
--color-wood-mid: #8B5E3C; /* medium walnut — buttons, interactive */ --color-wood-mid: #6B4527; /* dark walnut — buttons, interactive (darkened for contrast) */
--color-wood-light: #B5842A; /* brass — hover states, focus rings */ --color-wood-light: #B5842A; /* brass — hover states, focus rings */
/* Text */ /* Text */
--color-text: #2C1A0E; /* near-black brown — body copy */ --color-text: #2C1A0E; /* near-black brown — body copy */
--color-text-muted: #7A5C42; /* faded oak — labels, secondary info */ --color-text-muted: #5A3D22; /* dark oak — labels, secondary info (darkened for contrast) */
--color-text-on-dark: #F2E8D5; /* parchment — text on dark backgrounds */ --color-text-on-dark: #F2E8D5; /* parchment — text on dark backgrounds */
/* Status */ /* Status */
--color-status-open: #8B5E3C; /* walnut */ --color-status-open: #6B4527; /* dark walnut */
--color-status-inprogress:#B5842A; /* brass */ --color-status-inprogress:#7A5419; /* dark brass */
--color-status-done: #5C7A42; /* muted forest green */ --color-status-done: #47602F; /* muted forest green */
--color-status-paid: #3D5C2A; /* deeper green */ --color-status-paid: #3D5C2A; /* deeper green */
--font-heading: Georgia, 'Times New Roman', serif; --font-heading: Georgia, 'Times New Roman', serif;
--font-body: system-ui, sans-serif; --font-body: system-ui, sans-serif;
} }
html {
font-size: 150%; /* Dad's eyes aren't what they used to be */
}
* { box-sizing: border-box; } * { box-sizing: border-box; }
body { body {
@@ -372,6 +376,7 @@ button.danger {
} }
@media print { @media print {
html { font-size: 100%; } /* keep the printed invoice at normal scale so it still fits one page */
.no-print { display: none !important; } .no-print { display: none !important; }
body { background: white; } body { background: white; }
.invoice { box-shadow: none; padding: 0; } .invoice { box-shadow: none; padding: 0; }
+1 -1
View File
@@ -14,7 +14,7 @@ router.get('/by-customer', (req, res) => {
const clocks = db const clocks = db
.prepare( .prepare(
`SELECT id, manufacturer, model, description `SELECT id, description, note
FROM clocks WHERE customer_id = ? ORDER BY id DESC` FROM clocks WHERE customer_id = ? ORDER BY id DESC`
) )
.all(customerId); .all(customerId);
+9 -34
View File
@@ -28,8 +28,7 @@ export function getOrderDetail(id: string | number) {
.prepare( .prepare(
`SELECT so.*, c.name AS customer_name, c.address_line1, c.address_line2, c.city, c.state, c.zip, `SELECT so.*, c.name AS customer_name, c.address_line1, c.address_line2, c.city, c.state, c.zip,
c.phone, c.alt_phone, c.email, c.phone, c.alt_phone, c.email,
cl.manufacturer, cl.model, cl.serial_number, cl.alternate_id, cl.reference, cl.description AS clock_description, cl.note AS clock_note
cl.description AS clock_description
FROM service_orders so FROM service_orders so
JOIN customers c ON c.id = so.customer_id JOIN customers c ON c.id = so.customer_id
LEFT JOIN clocks cl ON cl.id = so.clock_id LEFT JOIN clocks cl ON cl.id = so.clock_id
@@ -123,32 +122,12 @@ router.post('/orders', (req, res) => {
let clockId = b.existing_clock_id ? Number(b.existing_clock_id) : null; let clockId = b.existing_clock_id ? Number(b.existing_clock_id) : null;
if (!clockId) { if (!clockId) {
const newClockFields = [ const hasNewClock = [b.new_clock_description, b.new_clock_note].some((v) => v && v.trim());
b.new_clock_manufacturer,
b.new_clock_model,
b.new_clock_serial_number,
b.new_clock_alternate_id,
b.new_clock_reference,
b.new_clock_description,
];
const hasNewClock = newClockFields.some((v) => v && v.trim());
if (hasNewClock) { if (hasNewClock) {
const info = db const info = db
.prepare( .prepare(`INSERT INTO clocks (customer_id, description, note) VALUES (?, ?, ?)`)
`INSERT INTO clocks .run(customerId, b.new_clock_description || null, b.new_clock_note || null);
(customer_id, manufacturer, model, serial_number, alternate_id, reference, description)
VALUES (?, ?, ?, ?, ?, ?, ?)`
)
.run(
customerId,
b.new_clock_manufacturer || null,
b.new_clock_model || null,
b.new_clock_serial_number || null,
b.new_clock_alternate_id || null,
b.new_clock_reference || null,
b.new_clock_description || null
);
clockId = Number(info.lastInsertRowid); clockId = Number(info.lastInsertRowid);
} }
} }
@@ -158,17 +137,14 @@ router.post('/orders', (req, res) => {
const orderInfo = db const orderInfo = db
.prepare( .prepare(
`INSERT INTO service_orders `INSERT INTO service_orders
(order_number, customer_id, clock_id, job_type, service_rep, technician, (order_number, customer_id, clock_id, job_type, date_in, due_date, cust_po, terms)
date_in, due_date, cust_po, terms) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
) )
.run( .run(
orderNumber, orderNumber,
customerId, customerId,
clockId, clockId,
b.job_type || null, b.job_type || null,
b.service_rep || null,
b.technician || null,
b.date_in || todayStr(), b.date_in || todayStr(),
b.due_date || null, b.due_date || null,
b.cust_po || null, b.cust_po || null,
@@ -243,19 +219,18 @@ router.post('/orders/:id', (req, res) => {
db.prepare( db.prepare(
`UPDATE service_orders SET `UPDATE service_orders SET
job_type = ?, service_rep = ?, technician = ?, status = ?, job_type = ?, status = ?,
date_out = ?, due_date = ?, cust_po = ?, terms = ?, date_out = ?, due_date = ?, cust_po = ?, terms = ?, internal_note = ?,
tax = ?, shipping = ?, pickup_delivery = ?, service_call = ?, disposal = ?, amount_paid = ? tax = ?, shipping = ?, pickup_delivery = ?, service_call = ?, disposal = ?, amount_paid = ?
WHERE id = ?` WHERE id = ?`
).run( ).run(
b.job_type || null, b.job_type || null,
b.service_rep || null,
b.technician || null,
STATUSES.includes(b.status) ? b.status : 'OPEN', STATUSES.includes(b.status) ? b.status : 'OPEN',
b.date_out || null, b.date_out || null,
b.due_date || null, b.due_date || null,
b.cust_po || null, b.cust_po || null,
b.terms || null, b.terms || null,
b.internal_note || null,
parseCents(b.tax), parseCents(b.tax),
parseCents(b.shipping), parseCents(b.shipping),
parseCents(b.pickup_delivery), parseCents(b.pickup_delivery),
+2 -7
View File
@@ -15,12 +15,8 @@ CREATE TABLE customers (
CREATE TABLE clocks ( CREATE TABLE clocks (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
customer_id INTEGER NOT NULL REFERENCES customers(id), customer_id INTEGER NOT NULL REFERENCES customers(id),
manufacturer TEXT,
model TEXT,
serial_number TEXT,
alternate_id TEXT,
reference TEXT,
description TEXT, description TEXT,
note TEXT,
created_at TEXT DEFAULT (datetime('now')) created_at TEXT DEFAULT (datetime('now'))
); );
@@ -33,14 +29,13 @@ CREATE TABLE service_orders (
'31 DAY','CLEANING','ESTIMATE','FIT UP/REPLACE', '31 DAY','CLEANING','ESTIMATE','FIT UP/REPLACE',
'HOUSE CALL','MOVE CLOCK','OVERHAUL','SERVICE', 'HOUSE CALL','MOVE CLOCK','OVERHAUL','SERVICE',
'WALK IN SERVICE')), 'WALK IN SERVICE')),
service_rep TEXT,
technician TEXT,
status TEXT DEFAULT 'OPEN' CHECK (status IN ('OPEN','IN PROGRESS','DONE','PAID')), status TEXT DEFAULT 'OPEN' CHECK (status IN ('OPEN','IN PROGRESS','DONE','PAID')),
date_in TEXT DEFAULT (date('now')), date_in TEXT DEFAULT (date('now')),
date_out TEXT, date_out TEXT,
due_date TEXT, due_date TEXT,
cust_po TEXT, cust_po TEXT,
terms TEXT, terms TEXT,
internal_note TEXT, -- staff-only; never printed on the invoice
-- money summary (cents) -- money summary (cents)
tax INTEGER DEFAULT 0, tax INTEGER DEFAULT 0,
shipping INTEGER DEFAULT 0, shipping INTEGER DEFAULT 0,
+1 -1
View File
@@ -1,6 +1,6 @@
<option value="">— new clock —</option> <option value="">— new clock —</option>
{% for clock in clocks %} {% for clock in clocks %}
<option value="{{ clock.id }}"> <option value="{{ clock.id }}">
{{- clock.manufacturer or '' }} {{ clock.model or '' }}{% if clock.description %} ({{ clock.description }}){% endif -%} {{- clock.description or 'Clock #' + clock.id|string }}{% if clock.note %} ({{ clock.note }}){% endif -%}
</option> </option>
{% endfor %} {% endfor %}
+1 -5
View File
@@ -37,15 +37,11 @@
</div> </div>
<div> <div>
<h2>Clock</h2> <h2>Clock</h2>
{% if order.manufacturer or order.model %}<p>{{ order.manufacturer or '' }} {{ order.model or '' }}</p>{% endif %} {% if order.clock_description %}<p>{{ order.clock_description }}</p>{% endif %}
{% if order.serial_number %}<p>Serial: {{ order.serial_number }}</p>{% endif %}
{% if order.reference %}<p>Reference: {{ order.reference }}</p>{% endif %}
</div> </div>
<div> <div>
<h2>Order Info</h2> <h2>Order Info</h2>
<p>Job Type: {{ order.job_type or '' }}</p> <p>Job Type: {{ order.job_type or '' }}</p>
{% if order.service_rep %}<p>Rep: {{ order.service_rep }}</p>{% endif %}
{% if order.technician %}<p>Technician: {{ order.technician }}</p>{% endif %}
{% if order.cust_po %}<p>PO: {{ order.cust_po }}</p>{% endif %} {% if order.cust_po %}<p>PO: {{ order.cust_po }}</p>{% endif %}
{% if order.terms %}<p>Terms: {{ order.terms }}</p>{% endif %} {% if order.terms %}<p>Terms: {{ order.terms }}</p>{% endif %}
</div> </div>
+5 -2
View File
@@ -19,8 +19,6 @@
{% endfor %} {% endfor %}
</select> </select>
</label> </label>
<label>Service rep <input type="text" name="service_rep" value="{{ order.service_rep or '' }}"></label>
<label>Technician <input type="text" name="technician" value="{{ order.technician or '' }}"></label>
<label>Date in <input type="text" value="{{ order.date_in or '' }}" disabled></label> <label>Date in <input type="text" value="{{ order.date_in or '' }}" disabled></label>
<label>Date out <input type="date" name="date_out" value="{{ order.date_out or '' }}"></label> <label>Date out <input type="date" name="date_out" value="{{ order.date_out or '' }}"></label>
<label>Due date <input type="date" name="due_date" value="{{ order.due_date or '' }}"></label> <label>Due date <input type="date" name="due_date" value="{{ order.due_date or '' }}"></label>
@@ -28,6 +26,11 @@
<label>Terms <input type="text" name="terms" value="{{ order.terms or '' }}"></label> <label>Terms <input type="text" name="terms" value="{{ order.terms or '' }}"></label>
</div> </div>
<label>
Note <span class="hint">(internal only — never printed on the invoice)</span>
<textarea name="internal_note" rows="3">{{ order.internal_note or '' }}</textarea>
</label>
<div class="grid-2"> <div class="grid-2">
<label>Tax <input type="text" name="tax" value="{{ (order.tax / 100) | round(2) }}"></label> <label>Tax <input type="text" name="tax" value="{{ (order.tax / 100) | round(2) }}"></label>
<label>Shipping <input type="text" name="shipping" value="{{ (order.shipping / 100) | round(2) }}"></label> <label>Shipping <input type="text" name="shipping" value="{{ (order.shipping / 100) | round(2) }}"></label>
+2 -7
View File
@@ -24,14 +24,9 @@
</div> </div>
<div> <div>
<h2>Clock</h2> <h2>Clock</h2>
{% if order.manufacturer or order.model %}
<p>{{ order.manufacturer or '' }} {{ order.model or '' }}</p>
{% endif %}
{% if order.serial_number %}<p>Serial: {{ order.serial_number }}</p>{% endif %}
{% if order.alternate_id %}<p>Alt ID: {{ order.alternate_id }}</p>{% endif %}
{% if order.reference %}<p>Reference: {{ order.reference }}</p>{% endif %}
{% if order.clock_description %}<p>{{ order.clock_description }}</p>{% endif %} {% if order.clock_description %}<p>{{ order.clock_description }}</p>{% endif %}
{% if not order.manufacturer and not order.model and not order.clock_description %} {% if order.clock_note %}<p>{{ order.clock_note }}</p>{% endif %}
{% if not order.clock_description and not order.clock_note %}
<p class="empty">No clock on file.</p> <p class="empty">No clock on file.</p>
{% endif %} {% endif %}
</div> </div>
+1 -7
View File
@@ -46,12 +46,8 @@
</label> </label>
<div class="grid-2"> <div class="grid-2">
<label>Manufacturer <input type="text" name="new_clock_manufacturer"></label>
<label>Model <input type="text" name="new_clock_model"></label>
<label>Serial number <input type="text" name="new_clock_serial_number"></label>
<label>Alternate ID <input type="text" name="new_clock_alternate_id"></label>
<label>Reference <input type="text" name="new_clock_reference"></label>
<label>Description <input type="text" name="new_clock_description"></label> <label>Description <input type="text" name="new_clock_description"></label>
<label>Note <input type="text" name="new_clock_note"></label>
</div> </div>
</fieldset> </fieldset>
@@ -67,8 +63,6 @@
{% endfor %} {% endfor %}
</select> </select>
</label> </label>
<label>Service rep <input type="text" name="service_rep"></label>
<label>Technician <input type="text" name="technician"></label>
<label>Date in <input type="date" name="date_in" value="{{ today }}"></label> <label>Date in <input type="date" name="date_in" value="{{ today }}"></label>
<label>Due date <input type="date" name="due_date"></label> <label>Due date <input type="date" name="due_date"></label>
<label>Customer PO <input type="text" name="cust_po"></label> <label>Customer PO <input type="text" name="cust_po"></label>