added discount

This commit is contained in:
2026-03-20 16:52:20 -04:00
parent 821cf379a9
commit 0b4e60970e
5 changed files with 83 additions and 26 deletions

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/png" href="/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>LB Quote Generator</title> <title>LB Quote Generator</title>
</head> </head>

BIN
public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

View File

@ -460,5 +460,27 @@
} }
], ],
"shippingCost": 0 "shippingCost": 0
},
{
"id": 2908,
"date": "March 20, 2026",
"customer": {
"name": "test",
"address": "",
"city": "",
"province": "on",
"postalCode": "",
"phone": "",
"email": ""
},
"items": [
{
"Item ID": "MDL-5H2",
"Description": "Earth Drill, 5.5HP Honda, 20:1Transmission",
"Price": 4674.3552899999995,
"quantity": 1
}
],
"shippingCost": 0
} }
] ]

View File

@ -4,21 +4,27 @@ import { Plus } from 'lucide-react';
export default function ItemSelector({ items, onAddItem }) { export default function ItemSelector({ items, onAddItem }) {
const [selectedItemIndex, setSelectedItemIndex] = useState(''); const [selectedItemIndex, setSelectedItemIndex] = useState('');
const [quantity, setQuantity] = useState(1); const [quantity, setQuantity] = useState(1);
const [discount, setDiscount] = useState('');
const handleAdd = () => { const handleAdd = () => {
if (selectedItemIndex !== '' && quantity > 0) { if (selectedItemIndex !== '' && quantity > 0) {
const selectedItem = items[selectedItemIndex]; const selectedItem = items[selectedItemIndex];
onAddItem({ ...selectedItem, quantity: parseInt(quantity, 10) }); onAddItem({
...selectedItem,
quantity: parseInt(quantity, 10),
discount: parseFloat(discount) || 0
});
setSelectedItemIndex(''); setSelectedItemIndex('');
setQuantity(1); setQuantity(1);
setDiscount('');
} }
}; };
return ( return (
<div className="glass-card no-print"> <div className="glass-card no-print">
<h2>Add Items to Quote</h2> <h2>Add Items to Quote</h2>
<div className="form-grid" style={{ alignItems: 'flex-end', gridTemplateColumns: '1fr 80px auto' }}> <div style={{ display: 'flex', flexWrap: 'wrap', gap: '1rem', alignItems: 'flex-end' }}>
<div className="form-group"> <div className="form-group" style={{ flex: '1 1 250px' }}>
<label htmlFor="itemSelect">Select Product</label> <label htmlFor="itemSelect">Select Product</label>
<select <select
id="itemSelect" id="itemSelect"
@ -33,18 +39,36 @@ export default function ItemSelector({ items, onAddItem }) {
))} ))}
</select> </select>
</div> </div>
<div className="form-group"> <div className="form-group" style={{ flex: '0 0 auto' }}>
<label htmlFor="discount">Discount (%)</label>
<input
type="number"
id="discount"
min="0"
max="100"
style={{ width: '100px' }}
value={discount}
onChange={(e) => setDiscount(e.target.value)}
placeholder="0"
/>
</div>
<div className="form-group" style={{ flex: '0 0 auto' }}>
<label htmlFor="quantity">Quantity</label> <label htmlFor="quantity">Quantity</label>
<input <input
type="number" type="number"
id="quantity" id="quantity"
min="1" min="1"
style={{ width: '80px' }} style={{ width: '100px' }}
value={quantity} value={quantity}
onChange={(e) => setQuantity(e.target.value)} onChange={(e) => setQuantity(e.target.value)}
/> />
</div> </div>
<button className="btn btn-primary" onClick={handleAdd} disabled={selectedItemIndex === ''}> <button
className="btn btn-primary"
onClick={handleAdd}
disabled={selectedItemIndex === ''}
style={{ flex: '0 0 auto', height: '44px' }}
>
<Plus size={20} /> Add <Plus size={20} /> Add
</button> </button>
</div> </div>

View File

@ -24,7 +24,11 @@ export default function QuoteSummary({ items, customer, shippingCost, onShipping
}; };
const calculateSubtotal = () => { const calculateSubtotal = () => {
return items.reduce((total, item) => total + (item.Price * item.quantity), 0); return items.reduce((total, item) => {
const itemTotal = item.Price * item.quantity;
const discountAmount = itemTotal * ((item.discount || 0) / 100);
return total + (itemTotal - discountAmount);
}, 0);
}; };
const subtotal = calculateSubtotal(); const subtotal = calculateSubtotal();
@ -55,30 +59,37 @@ export default function QuoteSummary({ items, customer, shippingCost, onShipping
<th>Item ID</th> <th>Item ID</th>
<th>Description</th> <th>Description</th>
<th>Unit Price</th> <th>Unit Price</th>
<th>Discount</th>
<th>Quantity</th> <th>Quantity</th>
<th>Total</th> <th>Total</th>
<th className="no-print">Action</th> <th className="no-print">Action</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{items.map((item, index) => ( {items.map((item, index) => {
<tr key={index}> const itemTotal = item.Price * item.quantity;
<td>{item['Item ID']}</td> const discountAmount = itemTotal * ((item.discount || 0) / 100);
<td>{item.Description}</td> const finalPrice = itemTotal - discountAmount;
<td>{formatCurrency(item.Price)}</td> return (
<td>{item.quantity}</td> <tr key={index}>
<td>{formatCurrency(item.Price * item.quantity)}</td> <td>{item['Item ID']}</td>
<td className="no-print"> <td>{item.Description}</td>
<button <td>{formatCurrency(item.Price)}</td>
className="btn btn-icon btn-danger" <td>{item.discount ? `${item.discount}%` : '-'}</td>
onClick={() => onRemoveItem(index)} <td>{item.quantity}</td>
title="Remove item" <td>{formatCurrency(finalPrice)}</td>
> <td className="no-print">
<Trash2 size={16} /> <button
</button> className="btn btn-icon btn-danger"
</td> onClick={() => onRemoveItem(index)}
</tr> title="Remove item"
))} >
<Trash2 size={16} />
</button>
</td>
</tr>
);
})}
</tbody> </tbody>
</table> </table>
</div> </div>