Files
PowderCoatingLogix/src/PowderCoating.Web/design_handoff_pcl_redesign/screens_before.jsx
T
2026-04-23 21:38:24 -04:00

267 lines
16 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* "Before" screens — faithful recreations of the current Bootstrap views. */
/* =======================
DASHBOARD — BEFORE
======================= */
function DashboardBefore() {
const kpis = [
{ n: 4, label: 'Overdue Invoices', sub: '$3,240', color: '#eb3349', icon: 'bi-exclamation-circle' },
{ n: 12, label: "Today's Jobs", color: '#11998e', icon: 'bi-calendar-check-fill' },
{ n: 7, label: 'Overdue Jobs', color: '#f7971e', icon: 'bi-exclamation-triangle-fill' },
{ n: 3, label: "Today's Appointments", color: '#4facfe', icon: 'bi-calendar-event-fill' },
{ n: 8, label: 'Low Stock', color: '#a855f7', icon: 'bi-box-seam-fill' },
{ n: 2, label: 'Maintenance Due', color: '#667eea', icon: 'bi-tools' },
];
return (
<div style={{ display: 'flex', background: '#f4f5f7' }}>
<SidebarBefore />
<div style={{ flex: 1, minWidth: 0 }}>
<TopbarBefore title="Dashboard" />
<div style={{ padding: '24px 28px' }}>
{/* gradient welcome banner */}
<div style={{
background: 'linear-gradient(180deg,#1a1a2e,#16213e,#0f3460)',
borderRadius: 12, padding: '22px 26px', marginBottom: 22, color: '#fff',
display: 'flex', justifyContent: 'space-between', alignItems: 'center',
}}>
<div>
<div style={{ fontSize: 18, fontWeight: 700, marginBottom: 4 }}>Welcome Back!</div>
<div style={{ fontSize: 13, color: 'rgba(255,255,255,0.75)' }}>
Here's your shop overview for April 18, 2026 · <span style={{ opacity: 0.85 }}><i className="bi bi-rocket-takeoff" /> What's New</span>
</div>
<div style={{ fontSize: 12, color: 'rgba(255,255,255,0.6)', marginTop: 8 }}>
<i className="bi bi-lightbulb" style={{ color: 'rgba(255,220,80,0.8)' }} /> Tip: Use job templates to speed up quoting for repeat customers.
</div>
</div>
<div style={{ display: 'flex', gap: 28, textAlign: 'right' }}>
<div><div style={{ fontSize: 11, opacity: 0.75 }}>Collected April 2026</div><div style={{ fontWeight: 700, fontSize: 17 }}>$48,290</div></div>
<div><div style={{ fontSize: 11, opacity: 0.75 }}>Outstanding A/R</div><div style={{ fontWeight: 700, fontSize: 17 }}>$12,450</div></div>
<div><div style={{ fontSize: 11, opacity: 0.75 }}>Active Customers</div><div style={{ fontWeight: 700, fontSize: 17 }}>84</div></div>
</div>
</div>
{/* rainbow KPIs */}
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(6,1fr)', gap: 12, marginBottom: 22 }}>
{kpis.map((k, i) => (
<div key={i} style={{
background: '#fff', borderRadius: 10, padding: 14,
borderTop: `4px solid ${k.color}`,
boxShadow: '0 1px 3px rgba(0,0,0,0.06)',
}}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
<div>
<div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
<div style={{ fontSize: 28, fontWeight: 700, color: k.color, lineHeight: 1 }}>{k.n}</div>
{k.sub && <div style={{ fontSize: 11, color: '#6b7280' }}>{k.sub}</div>}
</div>
<div style={{ fontSize: 11, color: '#6b7280', marginTop: 4 }}>{k.label}</div>
</div>
<i className={`bi ${k.icon}`} style={{ color: k.color, opacity: 0.5, fontSize: 22 }} />
</div>
</div>
))}
</div>
{/* body cards */}
<div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr', gap: 16 }}>
<div style={{ background: '#fff', borderRadius: 10, boxShadow: '0 1px 3px rgba(0,0,0,0.06)' }}>
<div style={{ padding: '14px 18px', borderBottom: '1px solid #e5e7eb', fontWeight: 600 }}>Recent Jobs</div>
<div style={{ padding: 6 }}>
{['J-2041 · Fence gate · Rodriguez', 'J-2040 · Wheel set · D&T Auto', 'J-2039 · Patio table · Mercer', 'J-2038 · Trailer frame · Bluegrass', 'J-2037 · Bumper · Heritage'].map((r, i) => (
<div key={i} style={{ padding: '10px 12px', borderBottom: i < 4 ? '1px solid #f3f4f6' : 'none', display: 'flex', justifyContent: 'space-between', fontSize: 13, color: '#374151' }}>
<span>{r}</span>
<span style={{ background: '#fef3c7', color: '#92400e', padding: '2px 8px', borderRadius: 4, fontSize: 10.5, fontWeight: 600 }}>IN PROGRESS</span>
</div>
))}
</div>
</div>
<div style={{ background: '#fff', borderRadius: 10, boxShadow: '0 1px 3px rgba(0,0,0,0.06)' }}>
<div style={{ padding: '14px 18px', borderBottom: '1px solid #e5e7eb', fontWeight: 600 }}>A/R Aging</div>
<div style={{ padding: 18 }}>
{[['Current', 8420, '#11998e'], ['130 days', 2100, '#4facfe'], ['3160 days', 1430, '#f7971e'], ['60+ days', 500, '#eb3349']].map(([l, v, c], i) => (
<div key={i} style={{ marginBottom: 10 }}>
<div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12, marginBottom: 4 }}><span>{l}</span><span style={{ fontWeight: 600 }}>${v.toLocaleString()}</span></div>
<div style={{ height: 6, borderRadius: 99, background: '#f3f4f6', overflow: 'hidden' }}>
<div style={{ height: '100%', width: `${(v/10000)*100}%`, background: c }} />
</div>
</div>
))}
</div>
</div>
</div>
</div>
</div>
</div>
);
}
/* =======================
JOBS INDEX — BEFORE
======================= */
function JobsIndexBefore() {
const jobs = [
['J-2041', 'Fence gate — Anodized black', 'Rodriguez Metal', 'Apr 19', 'IN PROGRESS', 'HIGH', '$780'],
['J-2040', 'Wheel set (4) — Gloss white', 'D&T Auto', 'Apr 19', 'QUEUED', 'NORMAL', '$420'],
['J-2039', 'Patio table — Matte black', 'Mercer Residential', 'Apr 20', 'CURING', 'NORMAL', '$210'],
['J-2038', 'Trailer frame — Zinc primer', 'Bluegrass Trailers', 'Apr 22', 'IN PROGRESS', 'LOW', '$1,640'],
['J-2037', 'Bumper — Satin bronze', 'Heritage Restoration', 'Apr 22', 'READY FOR PICKUP', 'NORMAL', '$340'],
['J-2036', 'Railing — Hammered copper', 'Summit Builders', 'Apr 23', 'QUEUED', 'HIGH', '$980'],
];
const statusStyle = (s) => ({
'IN PROGRESS': { bg: '#fef3c7', fg: '#92400e' },
'QUEUED': { bg: '#dbeafe', fg: '#1e40af' },
'CURING': { bg: '#fee2e2', fg: '#991b1b' },
'READY FOR PICKUP': { bg: '#d1fae5', fg: '#065f46' },
}[s]);
const prioStyle = (p) => ({
'HIGH': { bg: '#fef3c7', fg: '#92400e' },
'NORMAL': { bg: '#dbeafe', fg: '#1e40af' },
'LOW': { bg: '#e5e7eb', fg: '#4b5563' },
}[p]);
return (
<div style={{ display: 'flex', background: '#f4f5f7' }}>
<SidebarBefore />
<div style={{ flex: 1, minWidth: 0 }}>
<TopbarBefore title="Jobs" />
<div style={{ padding: '24px 28px' }}>
{/* stat cards */}
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 16, marginBottom: 22 }}>
{[
['Total Jobs', '47', 'bi-briefcase', '#dbeafe', '#1e40af'],
['In Progress', '12', 'bi-hourglass-split', '#fef3c7', '#92400e'],
['Completed', '28', 'bi-check-circle', '#d1fae5', '#065f46'],
['Total Value', '$18,420', 'bi-currency-dollar', '#fee2e2', '#991b1b'],
].map(([l, v, ic, b, f], i) => (
<div key={i} style={{ background: '#fff', borderRadius: 10, padding: 18, boxShadow: '0 1px 3px rgba(0,0,0,0.06)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<div>
<div style={{ fontSize: 12, color: '#6b7280', marginBottom: 3 }}>{l}</div>
<div style={{ fontSize: 24, fontWeight: 700 }}>{v}</div>
</div>
<div style={{ width: 48, height: 48, borderRadius: '50%', background: b, color: f, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<i className={`bi ${ic}`} style={{ fontSize: 20 }} />
</div>
</div>
))}
</div>
{/* table card */}
<div style={{ background: '#fff', borderRadius: 10, boxShadow: '0 1px 3px rgba(0,0,0,0.06)' }}>
<div style={{ padding: '14px 18px', borderBottom: '1px solid #e5e7eb', display: 'flex', justifyContent: 'space-between', gap: 12 }}>
<div style={{ display: 'flex', gap: 8 }}>
<div style={{ display: 'flex', alignItems: 'center', border: '1.5px solid #9ca3af', borderRadius: 6, padding: '4px 10px', width: 320, gap: 8 }}>
<i className="bi bi-search" style={{ color: '#9ca3af' }} />
<input placeholder="Search jobs…" style={{ border: 'none', outline: 'none', flex: 1, fontSize: 13 }} />
</div>
<button style={{ background: '#4f46e5', color: '#fff', border: 'none', borderRadius: 6, padding: '0 14px', fontSize: 13, fontWeight: 500 }}><i className="bi bi-search" /></button>
<button style={{ background: '#fff', color: '#374151', border: '1.5px solid #9ca3af', borderRadius: 6, padding: '6px 12px', fontSize: 13 }}>Filters</button>
</div>
<button style={{ background: '#4f46e5', color: '#fff', border: 'none', borderRadius: 6, padding: '8px 14px', fontSize: 13, fontWeight: 500 }}><i className="bi bi-plus-lg" /> New Job</button>
</div>
<table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
<thead>
<tr>
{['Job #', 'Description', 'Customer', 'Due', 'Status', 'Priority', 'Total', ''].map((h, i) => (
<th key={i} style={{ padding: '10px 14px', textAlign: 'left', background: '#f3f4f6', color: '#6b7280', fontSize: 11, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.05em', borderBottom: '2px solid #e5e7eb' }}>{h}</th>
))}
</tr>
</thead>
<tbody>
{jobs.map((j, i) => {
const st = statusStyle(j[4]); const pr = prioStyle(j[5]);
return (
<tr key={i} style={{ borderBottom: '1px solid #f3f4f6' }}>
<td style={{ padding: '12px 14px', fontWeight: 600, color: '#4f46e5' }}>{j[0]}</td>
<td style={{ padding: '12px 14px' }}>{j[1]}</td>
<td style={{ padding: '12px 14px' }}>{j[2]}</td>
<td style={{ padding: '12px 14px' }}>{j[3]}</td>
<td style={{ padding: '12px 14px' }}><span style={{ background: st.bg, color: st.fg, padding: '4px 10px', borderRadius: 6, fontSize: 10.5, fontWeight: 600 }}>{j[4]}</span></td>
<td style={{ padding: '12px 14px' }}><span style={{ background: pr.bg, color: pr.fg, padding: '4px 10px', borderRadius: 6, fontSize: 10.5, fontWeight: 600 }}>{j[5]}</span></td>
<td style={{ padding: '12px 14px', fontWeight: 600 }}>{j[6]}</td>
<td style={{ padding: '12px 14px', color: '#6b7280' }}><i className="bi bi-three-dots" /></td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
</div>
</div>
);
}
/* =======================
JOBS BOARD — BEFORE
======================= */
function JobsBoardBefore() {
const cols = [
{ title: 'INTAKE', count: 3, tint: '#dbeafe', accent: '#1e40af', cards: [
{ id: 'J-2049', cust: 'Pine Ridge Metal', desc: 'Gate hardware set', due: 'Apr 24', prio: '#6c757d', powder: 'Gloss black' },
{ id: 'J-2048', cust: 'Highway Fabworks', desc: 'Railing brackets', due: 'Apr 25', prio: '#ffc107', powder: 'Matte white' },
{ id: 'J-2047', cust: 'Crestline Custom', desc: 'Bumper set', due: 'Apr 26', prio: '#6c757d', powder: 'Satin bronze' },
]},
{ title: 'PREP', count: 2, tint: '#fef3c7', accent: '#92400e', cards: [
{ id: 'J-2045', cust: 'Rodriguez Metal', desc: 'Fence gate', due: 'Apr 19', prio: '#dc3545', powder: 'Anodized black' },
{ id: 'J-2044', cust: 'D&T Auto', desc: 'Wheel set (4)', due: 'Apr 19', prio: '#ffc107', powder: 'Gloss white' },
]},
{ title: 'COATING', count: 3, tint: '#fee2e2', accent: '#991b1b', cards: [
{ id: 'J-2042', cust: 'Mercer', desc: 'Patio table', due: 'Apr 20', prio: '#6c757d', powder: 'Matte black' },
{ id: 'J-2041', cust: 'Bluegrass', desc: 'Trailer frame', due: 'Apr 22', prio: '#198754', powder: 'Zinc primer' },
{ id: 'J-2040', cust: 'Summit', desc: 'Railing', due: 'Apr 23', prio: '#dc3545', powder: 'Hammered copper' },
]},
{ title: 'CURING', count: 2, tint: '#e0e7ff', accent: '#3730a3', cards: [
{ id: 'J-2038', cust: 'Heritage', desc: 'Bumper', due: 'Apr 22', prio: '#6c757d', powder: 'Satin bronze' },
{ id: 'J-2037', cust: 'Parkside', desc: 'Chair set (6)', due: 'Apr 22', prio: '#ffc107', powder: 'Gloss red' },
]},
{ title: 'READY', count: 1, tint: '#d1fae5', accent: '#065f46', cards: [
{ id: 'J-2034', cust: 'Lakeside Marina', desc: 'Railing kit', due: 'Apr 18', prio: '#198754', powder: 'Matte white' },
]},
];
return (
<div style={{ display: 'flex', background: '#f4f5f7' }}>
<SidebarBefore />
<div style={{ flex: 1, minWidth: 0 }}>
<TopbarBefore title="Jobs Board" />
<div style={{ padding: '24px 28px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 14 }}>
<div style={{ display: 'flex', gap: 8 }}>
<button style={{ background: '#fff', border: '1.5px solid #9ca3af', borderRadius: 6, padding: '6px 12px', fontSize: 13 }}>All customers</button>
<button style={{ background: '#fff', border: '1.5px solid #9ca3af', borderRadius: 6, padding: '6px 12px', fontSize: 13 }}>All priorities</button>
</div>
<button style={{ background: '#4f46e5', color: '#fff', border: 'none', borderRadius: 6, padding: '8px 14px', fontSize: 13, fontWeight: 500 }}>+ New Job</button>
</div>
<div style={{ display: 'flex', gap: 10, overflow: 'hidden' }}>
{cols.map((c, i) => (
<div key={i} style={{ width: 220, background: '#e9ecef', borderRadius: 8, overflow: 'hidden', flexShrink: 0 }}>
<div style={{ padding: '10px 12px', display: 'flex', justifyContent: 'space-between', fontSize: 12, fontWeight: 600 }}>
<span style={{ background: c.tint, color: c.accent, padding: '3px 8px', borderRadius: 4, fontSize: 10.5, letterSpacing: '0.04em' }}>{c.title}</span>
<span style={{ color: '#6b7280', fontSize: 11 }}>{c.count}</span>
</div>
<div style={{ padding: '4px 8px 12px' }}>
{c.cards.map((card, j) => (
<div key={j} style={{
background: '#fff', borderRadius: 5, border: '1px solid #e5e7eb',
borderLeft: `4px solid ${card.prio}`, padding: '9px 10px', marginBottom: 7, fontSize: 12,
}}>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4 }}>
<span style={{ fontWeight: 600, color: '#4f46e5', fontSize: 11.5 }}>{card.id}</span>
<span style={{ color: '#6b7280', fontSize: 10.5 }}>{card.due}</span>
</div>
<div style={{ fontWeight: 500, marginBottom: 2, lineHeight: 1.3 }}>{card.desc}</div>
<div style={{ color: '#6b7280', fontSize: 11, marginBottom: 4 }}>{card.cust}</div>
<div style={{ color: '#6b7280', fontSize: 10.5 }}><i className="bi bi-droplet-fill" style={{ marginRight: 3 }} /> {card.powder}</div>
</div>
))}
</div>
</div>
))}
</div>
</div>
</div>
</div>
);
}
Object.assign(window, { DashboardBefore, JobsIndexBefore, JobsBoardBefore });