Print Fix

This commit is contained in:
2026-05-19 08:20:30 -04:00
parent da80fcffe9
commit 130130a7ed
4 changed files with 228 additions and 50 deletions

View File

@ -512,5 +512,134 @@
} }
], ],
"shippingCost": 0 "shippingCost": 0
},
{
"id": 7294,
"date": "May 14, 2026",
"customer": {
"name": "",
"contactName": "",
"address": "",
"city": "",
"province": "",
"postalCode": "",
"phone": "",
"email": ""
},
"items": [
{
"Item ID": "MDL-5H",
"Description": "Earth Drill, 5.5HP Honda Engine #GX160",
"Price": 4623.113879999999,
"quantity": 1,
"discount": 0
},
{
"Item ID": "MDL-8H2R7",
"Description": "Earth Drill, 8 HP Honda, 20:1 Trans & Roll Cage",
"Price": 6183.13014,
"quantity": 1,
"discount": 0
},
{
"Item ID": "3002-KEP",
"Description": "Nut, KEP NC, 5/16 pltd. (Nut w/Lock Washer)",
"Price": 0.7970885999999999,
"quantity": 1,
"discount": 0
},
{
"Item ID": "3000-B",
"Description": "Motor Carrier",
"Price": 189.3085425,
"quantity": 1,
"discount": 0
},
{
"Item ID": "3002",
"Description": "Bolt, 5/16 x 1-1/2 Hex NC Gr 5Zinc Plated",
"Price": 1.2335895,
"quantity": 1,
"discount": 0
},
{
"Item ID": "MDL-5B3PR7",
"Description": "Earth Drill,6HP B&S PW RC 13:1Vanguard Engine#12V3320012F",
"Price": 5091.403432499999,
"quantity": 1,
"discount": 0
},
{
"Item ID": "4034-3",
"Description": "Nut, Hex, 10-32 Pltd",
"Price": 0.49343580000000004,
"quantity": 1,
"discount": 0
},
{
"Item ID": "4018-2H",
"Description": "Clamp, Flex Shaft",
"Price": 23.153526,
"quantity": 1,
"discount": 0
},
{
"Item ID": "4018-2H",
"Description": "Clamp, Flex Shaft",
"Price": 23.153526,
"quantity": 1,
"discount": 0
},
{
"Item ID": "3000-B",
"Description": "Motor Carrier",
"Price": 189.3085425,
"quantity": 1,
"discount": 0
},
{
"Item ID": "3063-A",
"Description": "Guide Spool Assy., 8HP Honda Direct Throttle",
"Price": 22.963743,
"quantity": 1,
"discount": 0
},
{
"Item ID": "3004",
"Description": "Wheel (Includes #3006-1 Cap)",
"Price": 42.321608999999995,
"quantity": 1,
"discount": 0
},
{
"Item ID": "3000-B",
"Description": "Motor Carrier",
"Price": 189.3085425,
"quantity": 1,
"discount": 0
},
{
"Item ID": "3000-B",
"Description": "Motor Carrier",
"Price": 189.3085425,
"quantity": 1,
"discount": 0
},
{
"Item ID": "CAP",
"Description": "Cap, LITTLE BEAVER",
"Price": 39.095298,
"quantity": 1,
"discount": 0
},
{
"Item ID": "MDL-5B",
"Description": "Earth Drill, 6 HP B&S VanguardEngine #12V3320012F",
"Price": 4526.324549999999,
"quantity": 1,
"discount": 0
}
],
"shippingCost": 0
} }
] ]

View File

@ -84,14 +84,14 @@ function App() {
setIsWorkOrderMode(false); setIsWorkOrderMode(false);
setTimeout(() => { setTimeout(() => {
window.print(); window.print();
}, 100); }, 300);
}; };
const handlePrintWorkOrder = () => { const handlePrintWorkOrder = () => {
setIsWorkOrderMode(true); setIsWorkOrderMode(true);
setTimeout(() => { setTimeout(() => {
window.print(); window.print();
}, 100); }, 300);
}; };
const handleSaveQuote = async () => { const handleSaveQuote = async () => {

View File

@ -53,33 +53,42 @@ export default function QuoteSummary({ items, customer, quoteId, quoteDate, ship
return ( return (
<div className="glass-card"> <div className="glass-card">
<h2>{isWorkOrderMode ? 'Work Order Summary' : 'Quote Summary'}</h2> <h2 className="no-print">{isWorkOrderMode ? 'Work Order Summary' : 'Quote Summary'}</h2>
<div className="table-container"> <div className="print-page-header">
<table>
<thead>
<tr className="print-only-block" style={{ display: 'none' }}>
<th colSpan={isWorkOrderMode ? 6 : 7} style={{ background: 'white', border: 'none', padding: '0 0 1.5rem 0' }}>
<div style={{ textAlign: 'center', marginBottom: '1.5rem' }}> <div style={{ textAlign: 'center', marginBottom: '1.5rem' }}>
<img src="/Logo.jpg" alt="Company Logo" style={{ height: '80px', marginBottom: '1rem' }} /> <img src="/Logo.jpg" alt="Company Logo" style={{ height: '60px', marginBottom: '0.5rem' }} />
<h1 style={{ fontSize: '1.8rem', color: 'black', margin: '0 0 0.5rem 0', WebkitTextFillColor: 'black', background: 'none' }}>Little Beaver Earth Augers</h1> <h1 style={{ fontSize: '1.4rem', color: 'black', margin: '0 0 0.25rem 0' }}>Little Beaver Earth Augers</h1>
<p style={{ fontSize: '1rem', color: 'black', margin: 0 }}>{isWorkOrderMode ? 'Work Order' : 'Official Quote'}</p> <p style={{ fontSize: '0.9rem', color: 'black', margin: 0 }}>{isWorkOrderMode ? 'Work Order' : 'Official Quote'}</p>
</div> </div>
<div style={{ display: 'flex', justifyContent: 'space-between', textAlign: 'left', fontWeight: 'normal' }}> <table style={{ width: '100%', borderCollapse: 'collapse', border: 'none', marginBottom: '1rem' }}>
<div> <tbody>
<h3 style={{ margin: '0 0 0.5rem 0', fontSize: '1.1rem', color: 'black' }}>Quote For:</h3> <tr>
<td style={{ textAlign: 'left', verticalAlign: 'top', border: 'none', padding: 0 }}>
<h3 style={{ margin: '0 0 0.25rem 0', fontSize: '1rem', color: 'black' }}>Quote For:</h3>
<p style={{ margin: 0, color: 'black' }}>{customer.name || 'N/A'}</p> <p style={{ margin: 0, color: 'black' }}>{customer.name || 'N/A'}</p>
{customer.contactName && <p style={{ margin: 0, color: 'black' }}><strong>Attn:</strong> {customer.contactName}</p>} {customer.contactName && <p style={{ margin: 0, color: 'black' }}><strong>Attn:</strong> {customer.contactName}</p>}
<p style={{ margin: 0, color: 'black' }}>{customer.address || 'N/A'}</p> <p style={{ margin: 0, color: 'black' }}>{customer.address || 'N/A'}</p>
<p style={{ margin: 0, color: 'black' }}>{customer.city ? `${customer.city}, ` : ''}{customer.province} {customer.postalCode}</p> <p style={{ margin: 0, color: 'black' }}>{customer.city ? `${customer.city}, ` : ''}{customer.province} {customer.postalCode}</p>
<p style={{ margin: 0, color: 'black' }}>{customer.phone || 'N/A'}</p> <p style={{ margin: 0, color: 'black' }}>{customer.phone || 'N/A'}</p>
<p style={{ margin: 0, color: 'black' }}>{customer.email || 'N/A'}</p> <p style={{ margin: 0, color: 'black' }}>{customer.email || 'N/A'}</p>
</div> </td>
<div style={{ textAlign: 'right' }}> <td style={{ textAlign: 'right', verticalAlign: 'top', border: 'none', padding: 0 }}>
<h3 style={{ margin: '0 0 0.5rem 0', fontSize: '1.1rem', color: 'black' }}>{isWorkOrderMode ? 'Work Order Details:' : 'Quote Details:'}</h3> <h3 style={{ margin: '0 0 0.25rem 0', fontSize: '1rem', color: 'black' }}>{isWorkOrderMode ? 'Work Order Details:' : 'Quote Details:'}</h3>
<p style={{ margin: 0, color: 'black' }}><strong>Date:</strong> {quoteDate}</p> <p style={{ margin: 0, color: 'black' }}><strong>Date:</strong> {quoteDate}</p>
<p style={{ margin: 0, color: 'black' }}><strong>{isWorkOrderMode ? 'Work Order #:' : 'Quote #:'}</strong> {quoteId}</p> <p style={{ margin: 0, color: 'black' }}><strong>{isWorkOrderMode ? 'Work Order #' : 'Quote #'}:</strong> {quoteId}</p>
</div> </td>
</tr>
</tbody>
</table>
</div> </div>
<div className="table-container">
<table className="print-header-table">
<thead>
<tr className="print-continuation-row">
<th colSpan={isWorkOrderMode ? 5 : 7} style={{ background: 'white', border: 'none', borderBottom: '2px solid black', padding: '0.5rem 0', fontWeight: 'normal', textAlign: 'center' }}>
<span style={{ fontSize: '0.9rem', color: 'black' }}>
{isWorkOrderMode ? 'Work Order' : 'Quote'} #{quoteId} &nbsp;|&nbsp; {quoteDate}
</span>
</th> </th>
</tr> </tr>
<tr> <tr>
@ -105,7 +114,7 @@ export default function QuoteSummary({ items, customer, quoteId, quoteDate, ship
<td>{item['Item ID']}</td> <td>{item['Item ID']}</td>
<td>{item.Description}</td> <td>{item.Description}</td>
{!isWorkOrderMode && <td> {!isWorkOrderMode && <td>
<span className="print-only-block" style={{ display: 'none' }}>{formatCurrency(price)}</span> <span className="print-only-block">{formatCurrency(price)}</span>
<div className="no-print" style={{ display: 'flex', alignItems: 'center' }}> <div className="no-print" style={{ display: 'flex', alignItems: 'center' }}>
<span style={{ marginRight: '0.25rem' }}>$</span> <span style={{ marginRight: '0.25rem' }}>$</span>
<input <input
@ -118,7 +127,7 @@ export default function QuoteSummary({ items, customer, quoteId, quoteDate, ship
</div> </div>
</td>} </td>}
{!isWorkOrderMode && <td> {!isWorkOrderMode && <td>
<span className="print-only-block" style={{ display: 'none' }}>{item.discount ? `${item.discount}%` : '-'}</span> <span className="print-only-block">{item.discount ? `${item.discount}%` : '-'}</span>
<div className="no-print" style={{ display: 'flex', alignItems: 'center' }}> <div className="no-print" style={{ display: 'flex', alignItems: 'center' }}>
<input <input
type="number" type="number"
@ -131,7 +140,7 @@ export default function QuoteSummary({ items, customer, quoteId, quoteDate, ship
</div> </div>
</td>} </td>}
<td> <td>
<span className="print-only-block" style={{ display: 'none' }}>{qty}</span> <span className="print-only-block">{qty}</span>
<div className="no-print"> <div className="no-print">
<input <input
type="number" type="number"
@ -145,7 +154,7 @@ export default function QuoteSummary({ items, customer, quoteId, quoteDate, ship
{!isWorkOrderMode && <td>{formatCurrency(finalPrice)}</td>} {!isWorkOrderMode && <td>{formatCurrency(finalPrice)}</td>}
{isWorkOrderMode && ( {isWorkOrderMode && (
<td style={{ textAlign: 'center' }}> <td style={{ textAlign: 'center' }}>
<div style={{ width: '20px', height: '20px', border: '1px solid black', margin: '0 auto' }} className="print-only-block" /> <div style={{ width: '20px', height: '20px', border: '1px solid black', margin: '0 auto' }} className="print-only-block"></div>
<div style={{ width: '20px', height: '20px', border: '1px solid #ccc', margin: '0 auto' }} className="no-print" /> <div style={{ width: '20px', height: '20px', border: '1px solid #ccc', margin: '0 auto' }} className="no-print" />
</td> </td>
)} )}
@ -182,7 +191,7 @@ export default function QuoteSummary({ items, customer, quoteId, quoteDate, ship
style={{ width: '80px', padding: '0.25rem', fontSize: '1rem', textAlign: 'right' }} style={{ width: '80px', padding: '0.25rem', fontSize: '1rem', textAlign: 'right' }}
/> />
</div> </div>
<span className="print-only-block" style={{ display: 'none' }}>{formatCurrency(shipping)}</span> <span className="print-only-block">{formatCurrency(shipping)}</span>
</div> </div>
<div className="total-row"> <div className="total-row">
<span>Tax ({(taxRate * 100).toFixed(1)}%):</span> <span>Tax ({(taxRate * 100).toFixed(1)}%):</span>

View File

@ -227,11 +227,24 @@ td {
} }
/* Print Styles */ /* Print Styles */
.print-continuation-header,
.print-continuation-row {
display: none;
}
.print-page-header {
display: none;
}
@media print { @media print {
:root { :root {
--print-size: 9pt; --print-size: 9pt;
} }
@page {
margin: 0.5in;
}
body { body {
background: white !important; background: white !important;
color: black !important; color: black !important;
@ -246,11 +259,40 @@ td {
display: block !important; display: block !important;
} }
.print-only-row {
display: table-row !important;
}
.print-page-header {
display: block !important;
}
.print-continuation-row {
display: table-row !important;
}
.print-continuation-header {
display: flex !important;
justify-content: space-between;
padding: 0.5rem 0;
margin-bottom: 0.5rem;
border-bottom: 1px solid #ccc;
font-size: 0.85rem;
color: black;
}
html, body {
height: auto !important;
min-height: auto !important;
margin: 0 !important;
padding: 0 !important;
}
.glass-card { .glass-card {
box-shadow: none !important; box-shadow: none !important;
border: none !important; border: none !important;
padding: 0 !important; padding: 0 !important;
margin-bottom: 2rem !important; margin: 0 !important;
background: transparent !important; background: transparent !important;
backdrop-filter: none !important; backdrop-filter: none !important;
-webkit-backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
@ -259,23 +301,7 @@ td {
.container { .container {
padding: 0 !important; padding: 0 !important;
max-width: 100% !important; max-width: 100% !important;
} margin: 0 !important;
.header {
margin-bottom: 1.5rem !important;
}
.header h1 {
-webkit-text-fill-color: black !important;
background: none !important;
color: black !important;
font-size: 1.8rem !important;
margin-bottom: 0.2rem !important;
}
.header p {
font-size: 1rem !important;
color: black !important;
} }
.table-container { .table-container {
@ -284,6 +310,20 @@ td {
table { table {
font-size: var(--print-size) !important; font-size: var(--print-size) !important;
page-break-inside: auto !important;
}
thead {
display: table-header-group !important;
}
tfoot {
display: table-footer-group !important;
}
tr {
page-break-inside: avoid !important;
page-break-after: auto !important;
} }
table th { table th {