feat: Datum-Picker beim Bezahlt/Abgeholt markieren

This commit is contained in:
2026-06-18 01:30:21 +02:00
parent 336ad848fc
commit fa68a9083b
2 changed files with 91 additions and 10 deletions

View File

@@ -69,20 +69,24 @@ router.put('/:id', authenticate, (req, res) => {
if (!ex) return res.status(404).json({ error: 'Nicht gefunden' }); if (!ex) return res.status(404).json({ error: 'Nicht gefunden' });
const { name=ex.name, bemerkung=ex.bemerkung, status=ex.status, custom_price=ex.custom_price } = req.body; const { name=ex.name, bemerkung=ex.bemerkung, status=ex.status, custom_price=ex.custom_price } = req.body;
// Bezahlt-Status mit Datum // Bezahlt-Status mit Datum (optional überschreibbar)
let bezahlt = ex.bezahlt; let bezahlt = ex.bezahlt;
let bezahlt_am = ex.bezahlt_am; let bezahlt_am = ex.bezahlt_am;
if (req.body.bezahlt !== undefined) { if (req.body.bezahlt !== undefined) {
bezahlt = req.body.bezahlt ? 1 : 0; bezahlt = req.body.bezahlt ? 1 : 0;
bezahlt_am = req.body.bezahlt ? new Date().toISOString() : null; bezahlt_am = req.body.bezahlt
? (req.body.bezahlt_am_override || new Date().toISOString())
: null;
} }
// Abgeholt-Status mit Datum // Abgeholt-Status mit Datum (optional überschreibbar)
let abgeholt = ex.abgeholt; let abgeholt = ex.abgeholt;
let abgeholt_am = ex.abgeholt_am; let abgeholt_am = ex.abgeholt_am;
if (req.body.abgeholt !== undefined) { if (req.body.abgeholt !== undefined) {
abgeholt = req.body.abgeholt ? 1 : 0; abgeholt = req.body.abgeholt ? 1 : 0;
abgeholt_am = req.body.abgeholt ? new Date().toISOString() : null; abgeholt_am = req.body.abgeholt
? (req.body.abgeholt_am_override || new Date().toISOString())
: null;
} }
db.prepare('UPDATE orders SET name=?,bemerkung=?,status=?,custom_price=?,bezahlt=?,bezahlt_am=?,abgeholt=?,abgeholt_am=?,updated_at=CURRENT_TIMESTAMP WHERE id=? AND user_id=?') db.prepare('UPDATE orders SET name=?,bemerkung=?,status=?,custom_price=?,bezahlt=?,bezahlt_am=?,abgeholt=?,abgeholt_am=?,updated_at=CURRENT_TIMESTAMP WHERE id=? AND user_id=?')

View File

@@ -124,13 +124,44 @@ function BestellungDetail({ id, toast, onBack }) {
return 'warteliste'; return 'warteliste';
}; };
const toggleBezahlt = () => const today = () => new Date().toISOString().slice(0,10);
api(`/tools/bestellungen/${id}`,{method:'PUT',body:{bezahlt:!order.bezahlt}}) const [bezahltDate, setBezahltDate] = useState(today());
.then(u=>{setOrder(u);toast(u.bezahlt?'Als bezahlt markiert':'Bezahlung aufgehoben');}); const [abgeholtDate, setAbgeholtDate] = useState(today());
const [showBezahltPicker, setShowBezahltPicker] = useState(false);
const [showAbgeholtPicker, setShowAbgeholtPicker] = useState(false);
const toggleAbgeholt = () => function toggleBezahlt() {
api(`/tools/bestellungen/${id}`,{method:'PUT',body:{abgeholt:!order.abgeholt}}) if (!order.bezahlt) {
.then(u=>{setOrder(u);toast(u.abgeholt?'Als abgeholt markiert':'Abholung aufgehoben');}); // Noch nicht bezahlt → Datum-Picker anzeigen
setBezahltDate(today());
setShowBezahltPicker(true);
} else {
api(`/tools/bestellungen/${id}`,{method:'PUT',body:{bezahlt:false}})
.then(u=>{setOrder(u);toast('Bezahlung aufgehoben');});
}
}
function confirmBezahlt() {
const iso = new Date(bezahltDate).toISOString();
api(`/tools/bestellungen/${id}`,{method:'PUT',body:{bezahlt:true, bezahlt_am_override: iso}})
.then(u=>{setOrder(u);setShowBezahltPicker(false);toast('Als bezahlt markiert');});
}
function toggleAbgeholt() {
if (!order.abgeholt) {
setAbgeholtDate(today());
setShowAbgeholtPicker(true);
} else {
api(`/tools/bestellungen/${id}`,{method:'PUT',body:{abgeholt:false}})
.then(u=>{setOrder(u);toast('Abholung aufgehoben');});
}
}
function confirmAbgeholt() {
const iso = new Date(abgeholtDate).toISOString();
api(`/tools/bestellungen/${id}`,{method:'PUT',body:{abgeholt:true, abgeholt_am_override: iso}})
.then(u=>{setOrder(u);setShowAbgeholtPicker(false);toast('Als abgeholt markiert');});
}
const isAbgeschlossen = order && !!order.bezahlt && !!order.abgeholt; const isAbgeschlossen = order && !!order.bezahlt && !!order.abgeholt;
@@ -179,6 +210,29 @@ function BestellungDetail({ id, toast, onBack }) {
</span> </span>
)} )}
</div> </div>
{showBezahltPicker && (
<div style={{marginTop:8,padding:'10px 12px',background:'rgba(192,132,252,0.08)',
border:'1px solid rgba(192,132,252,0.25)',borderRadius:8}}>
<div style={{color:'rgba(255,255,255,0.5)',fontFamily:'monospace',fontSize:10,marginBottom:6}}>
BEZAHLT AM:
</div>
<div style={{display:'flex',gap:8,alignItems:'center'}}>
<input type="date" value={bezahltDate} onChange={e=>setBezahltDate(e.target.value)}
style={{background:'rgba(255,255,255,0.06)',border:'1px solid rgba(255,255,255,0.15)',
borderRadius:7,padding:'5px 10px',color:'#fff',fontFamily:'monospace',fontSize:12,flex:1}}/>
<button onClick={confirmBezahlt}
style={{background:BEZAHLT.bg,border:`1px solid ${BEZAHLT.color}55`,borderRadius:7,
padding:'5px 12px',color:BEZAHLT.color,fontFamily:'monospace',fontSize:11,cursor:'pointer'}}>
Bestätigen
</button>
<button onClick={()=>setShowBezahltPicker(false)}
style={{background:'rgba(255,255,255,0.05)',border:'1px solid rgba(255,255,255,0.1)',
borderRadius:7,padding:'5px 10px',color:'rgba(255,255,255,0.4)',fontFamily:'monospace',fontSize:11,cursor:'pointer'}}>
</button>
</div>
</div>
)}
{!!order.bezahlt && ( {!!order.bezahlt && (
<div style={{color:'rgba(192,132,252,0.5)',fontFamily:'monospace',fontSize:10,marginTop:5}}> <div style={{color:'rgba(192,132,252,0.5)',fontFamily:'monospace',fontSize:10,marginTop:5}}>
🔒 Bearbeitung gesperrt. 🔒 Bearbeitung gesperrt.
@@ -198,6 +252,29 @@ function BestellungDetail({ id, toast, onBack }) {
}}> }}>
{!!order.abgeholt?'📦 Abgeholt':'○ Als abgeholt markieren'} {!!order.abgeholt?'📦 Abgeholt':'○ Als abgeholt markieren'}
</button> </button>
{showAbgeholtPicker && (
<div style={{width:'100%',marginTop:8,padding:'10px 12px',background:'rgba(251,191,36,0.08)',
border:'1px solid rgba(251,191,36,0.25)',borderRadius:8}}>
<div style={{color:'rgba(255,255,255,0.5)',fontFamily:'monospace',fontSize:10,marginBottom:6}}>
ABGEHOLT AM:
</div>
<div style={{display:'flex',gap:8,alignItems:'center'}}>
<input type="date" value={abgeholtDate} onChange={e=>setAbgeholtDate(e.target.value)}
style={{background:'rgba(255,255,255,0.06)',border:'1px solid rgba(255,255,255,0.15)',
borderRadius:7,padding:'5px 10px',color:'#fff',fontFamily:'monospace',fontSize:12,flex:1}}/>
<button onClick={confirmAbgeholt}
style={{background:'rgba(251,191,36,0.15)',border:'1px solid rgba(251,191,36,0.5)',borderRadius:7,
padding:'5px 12px',color:'#fbbf24',fontFamily:'monospace',fontSize:11,cursor:'pointer'}}>
Bestätigen
</button>
<button onClick={()=>setShowAbgeholtPicker(false)}
style={{background:'rgba(255,255,255,0.05)',border:'1px solid rgba(255,255,255,0.1)',
borderRadius:7,padding:'5px 10px',color:'rgba(255,255,255,0.4)',fontFamily:'monospace',fontSize:11,cursor:'pointer'}}>
</button>
</div>
</div>
)}
{!!order.abgeholt && order.abgeholt_am && ( {!!order.abgeholt && order.abgeholt_am && (
<span style={{color:'#fbbf24',fontFamily:'monospace',fontSize:11}}> <span style={{color:'#fbbf24',fontFamily:'monospace',fontSize:11}}>
am {new Date(order.abgeholt_am).toLocaleDateString('de-DE',{day:'2-digit',month:'2-digit',year:'numeric'})} am {new Date(order.abgeholt_am).toLocaleDateString('de-DE',{day:'2-digit',month:'2-digit',year:'numeric'})}