clean up some fields. Increase font size and contrast
This commit is contained in:
+10
-5
@@ -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; }
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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,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 %}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user