diff --git a/src/pages/Split.module.css b/src/pages/Split.module.css index d1dc8b6..59e694c 100644 --- a/src/pages/Split.module.css +++ b/src/pages/Split.module.css @@ -15,7 +15,7 @@ gap: 2rem; } -.test { +.content { display: flex; align-items: flex-start; width: 100%; @@ -48,7 +48,7 @@ display: flex; flex-direction: column; justify-content: space-between; - gap: 1.5rem; + gap: 1rem; padding: 5%; @media (min-width: 768px) { @@ -64,7 +64,8 @@ padding-bottom: 0.5rem; } -.total { +.divider { + width: 100%; margin-top: 0.5rem; border-top: 2px solid rgba(255, 255, 255, 0.2); padding-top: 0.5rem; @@ -94,3 +95,33 @@ align-items: center; justify-content: space-between; } + +.adjustments { + margin-top: 1.5rem; + display: flex; + gap: 1rem; + flex-wrap: nowrap; +} + +.inputGroup { + flex: 1 1 0; + min-width: 200px; +} + +.inputGroup label { + display: block; + margin-bottom: 0.5rem; + font-weight: 500; +} + +.inputGroup input { + width: 100%; + padding: 0.5rem; + border: 1px solid #ddd; + border-radius: 8px; +} + +.spacerRow td { + padding: 1rem; + border: 0; +} diff --git a/src/pages/Split.tsx b/src/pages/Split.tsx index fd1c134..811318f 100644 --- a/src/pages/Split.tsx +++ b/src/pages/Split.tsx @@ -21,6 +21,8 @@ const Split = () => { const [itemAssignments, setItemAssignments] = useState< Record >({}); + const [taxPercent, setTaxPercent] = useState(0); + const [tipPercent, setTipPercent] = useState(0); // Sync assignment state with items on load useEffect(() => { @@ -38,11 +40,16 @@ const Split = () => { totals[p.id] = 0; }); + let subtotal = 0; + + // Add up assigned items items.forEach((item) => { const assignedPeople = itemAssignments[item.id] || []; if (assignedPeople.length === 0) return; const itemTotal = item.price * item.quantity; + subtotal += itemTotal; + const amountPerPerson = itemTotal / assignedPeople.length; assignedPeople.forEach((personId) => { @@ -50,6 +57,20 @@ const Split = () => { }); }); + if (subtotal > 0) { + const taxAmount = (subtotal * taxPercent) / 100; + const tipAmount = (subtotal * tipPercent) / 100; + + // Split tax/tip proportionally based on each person's share + people.forEach((p) => { + const personSubtotal = totals[p.id] || 0; + const personProportion = personSubtotal / subtotal; + const personTaxTip = (taxAmount + tipAmount) * personProportion; + + totals[p.id] = personSubtotal + personTaxTip; + }); + } + return totals; }; @@ -59,6 +80,15 @@ const Split = () => { 0, ); + // Calculate breakdown for display + const subtotal = items.reduce((sum, item) => { + const assignedPeople = itemAssignments[item.id] || []; + if (assignedPeople.length === 0) return sum; + return sum + item.price * item.quantity; + }, 0); + const taxAmount = (subtotal * taxPercent) / 100; + const tipAmount = (subtotal * tipPercent) / 100; + const openAssignModal = (item: Item) => setItemBeingAssigned(item); const closeAssignModal = () => setItemBeingAssigned(null); @@ -75,7 +105,7 @@ const Split = () => { <>
{/* Items & Assignment */} -
+
{ ))} + {/* Tax & Tip Inputs */} +
+
+ + setTaxPercent(Number(e.target.value) || 0)} + min="0" + max="100" + step="0.1" + placeholder="0" + /> +
+ +
+ + setTipPercent(Number(e.target.value) || 0)} + min="0" + max="100" + step="1" + placeholder="0" + /> +
+
+ {/* Modals */} { {/* Results */}
Results
+ + {/* Breakdown */} + {(taxPercent > 0 || tipPercent > 0) && ( + <> + + + + + + {taxPercent > 0 && ( + + + + + )} + + {tipPercent > 0 && ( + + + + + )} + + + + + + )} + + {/* Each person's total */} {people.map((person) => ( ))} + + {/* Grand total */} + {people.length > 0 && ( + + + + )} + + + +
Subtotal:${subtotal.toFixed(2)}
Tax ({taxPercent}%):${taxAmount.toFixed(2)}
Tip ({tipPercent}%):${tipAmount.toFixed(2)}
{person.name}: ${personTotals[person.id]?.toFixed(2) || "0.00"}
+
+
Total: ${grandTotal.toFixed(2)}
-
Total: ${grandTotal.toFixed(2)}