Fix order item names, add Select All, pay confirmation with total, close empty order
This commit is contained in:
@@ -4,6 +4,10 @@ import OrderSummary from '../components/OrderSummary'
|
||||
import useAuthStore from '../store/authStore'
|
||||
import client from '../api/client'
|
||||
|
||||
function fmtPrice(v) {
|
||||
return Number(v).toFixed(2) + ' €'
|
||||
}
|
||||
|
||||
export default function TableDetailPage() {
|
||||
const { tableId } = useParams()
|
||||
const { user } = useAuthStore()
|
||||
@@ -15,6 +19,7 @@ export default function TableDetailPage() {
|
||||
const [paying, setPaying] = useState(false)
|
||||
const [selectedIds, setSelectedIds] = useState([])
|
||||
const [confirmClose, setConfirmClose] = useState(false)
|
||||
const [confirmPay, setConfirmPay] = useState(false)
|
||||
const [error, setError] = useState('')
|
||||
|
||||
async function load() {
|
||||
@@ -28,7 +33,7 @@ export default function TableDetailPage() {
|
||||
} else {
|
||||
setOrder(null)
|
||||
}
|
||||
} catch (err) {
|
||||
} catch {
|
||||
setError('Σφάλμα φόρτωσης')
|
||||
} finally {
|
||||
setLoading(false)
|
||||
@@ -37,6 +42,9 @@ export default function TableDetailPage() {
|
||||
|
||||
useEffect(() => { load() }, [tableId])
|
||||
|
||||
const activeItems = order?.items?.filter(i => i.status === 'active') || []
|
||||
const allPaid = order && activeItems.length === 0
|
||||
|
||||
const isMyOrder = order && (
|
||||
order.opened_by === user?.id || order.waiters?.some(w => w.waiter_id === user?.id)
|
||||
)
|
||||
@@ -51,8 +59,8 @@ export default function TableDetailPage() {
|
||||
}
|
||||
|
||||
async function paySelected() {
|
||||
if (selectedIds.length === 0) return
|
||||
setPaying(true)
|
||||
setConfirmPay(false)
|
||||
try {
|
||||
await client.post(`/api/orders/${order.id}/pay`, { item_ids: selectedIds })
|
||||
setSelectedIds([])
|
||||
@@ -78,8 +86,17 @@ export default function TableDetailPage() {
|
||||
setSelectedIds(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id])
|
||||
}
|
||||
|
||||
const allPaid = order && order.items?.filter(i => i.status === 'active').length === 0
|
||||
&& order.items?.some(i => i.status === 'paid')
|
||||
function selectAll() {
|
||||
const allActive = activeItems.map(i => i.id)
|
||||
const allSelected = allActive.every(id => selectedIds.includes(id))
|
||||
setSelectedIds(allSelected ? [] : allActive)
|
||||
}
|
||||
|
||||
const selectedTotal = activeItems
|
||||
.filter(i => selectedIds.includes(i.id))
|
||||
.reduce((s, i) => s + i.unit_price * i.quantity, 0)
|
||||
|
||||
const allActiveSelected = activeItems.length > 0 && activeItems.every(i => selectedIds.includes(i.id))
|
||||
|
||||
if (loading) return <div className="page page--centered"><p style={{ color: '#94a3b8' }}>Φόρτωση…</p></div>
|
||||
|
||||
@@ -111,6 +128,14 @@ export default function TableDetailPage() {
|
||||
onToggle={toggleItem}
|
||||
/>
|
||||
|
||||
{isMyOrder && activeItems.length > 0 && (
|
||||
<div style={{ padding: '4px 12px 8px' }}>
|
||||
<button className="link-btn" onClick={selectAll} style={{ fontSize: 15 }}>
|
||||
{allActiveSelected ? '☑ Αποεπιλογή όλων' : '☐ Επιλογή όλων'}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isMyOrder && (
|
||||
<div className="action-bar">
|
||||
<button className="btn btn--accent" onClick={() => navigate(`/tables/${tableId}/add`)}>
|
||||
@@ -119,7 +144,7 @@ export default function TableDetailPage() {
|
||||
|
||||
<button
|
||||
className="btn btn--success"
|
||||
onClick={paySelected}
|
||||
onClick={() => setConfirmPay(true)}
|
||||
disabled={selectedIds.length === 0 || paying}
|
||||
>
|
||||
{paying ? '…' : `Πληρωμή (${selectedIds.length})`}
|
||||
@@ -143,6 +168,31 @@ export default function TableDetailPage() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Pay confirmation */}
|
||||
{confirmPay && (
|
||||
<div className="modal-overlay" onClick={() => setConfirmPay(false)}>
|
||||
<div className="modal-sheet" onClick={e => e.stopPropagation()}>
|
||||
<div className="modal-handle" />
|
||||
<h2 className="modal-title">Επιβεβαίωση πληρωμής</h2>
|
||||
<p style={{ color: '#94a3b8', textAlign: 'center', marginBottom: 4 }}>
|
||||
{selectedIds.length} αντικείμενο{selectedIds.length !== 1 ? 'α' : ''}
|
||||
</p>
|
||||
<p style={{ color: '#f59e0b', textAlign: 'center', fontSize: 28, fontWeight: 700, marginBottom: 24 }}>
|
||||
{fmtPrice(selectedTotal)}
|
||||
</p>
|
||||
<div style={{ display: 'flex', gap: 12 }}>
|
||||
<button className="btn btn--secondary" style={{ flex: 1 }} onClick={() => setConfirmPay(false)}>
|
||||
Άκυρο
|
||||
</button>
|
||||
<button className="btn btn--success" style={{ flex: 1 }} onClick={paySelected}>
|
||||
Πληρώθηκαν ✓
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Close confirmation */}
|
||||
{confirmClose && (
|
||||
<div className="modal-overlay" onClick={() => setConfirmClose(false)}>
|
||||
<div className="modal-sheet" onClick={e => e.stopPropagation()}>
|
||||
|
||||
Reference in New Issue
Block a user