feat: Datum-Picker beim Bezahlt/Abgeholt markieren
This commit is contained in:
@@ -69,20 +69,24 @@ router.put('/:id', authenticate, (req, res) => {
|
||||
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;
|
||||
|
||||
// Bezahlt-Status mit Datum
|
||||
// Bezahlt-Status mit Datum (optional überschreibbar)
|
||||
let bezahlt = ex.bezahlt;
|
||||
let bezahlt_am = ex.bezahlt_am;
|
||||
if (req.body.bezahlt !== undefined) {
|
||||
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_am = ex.abgeholt_am;
|
||||
if (req.body.abgeholt !== undefined) {
|
||||
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=?')
|
||||
|
||||
@@ -124,13 +124,44 @@ function BestellungDetail({ id, toast, onBack }) {
|
||||
return 'warteliste';
|
||||
};
|
||||
|
||||
const toggleBezahlt = () =>
|
||||
api(`/tools/bestellungen/${id}`,{method:'PUT',body:{bezahlt:!order.bezahlt}})
|
||||
.then(u=>{setOrder(u);toast(u.bezahlt?'Als bezahlt markiert':'Bezahlung aufgehoben');});
|
||||
const today = () => new Date().toISOString().slice(0,10);
|
||||
const [bezahltDate, setBezahltDate] = useState(today());
|
||||
const [abgeholtDate, setAbgeholtDate] = useState(today());
|
||||
const [showBezahltPicker, setShowBezahltPicker] = useState(false);
|
||||
const [showAbgeholtPicker, setShowAbgeholtPicker] = useState(false);
|
||||
|
||||
const toggleAbgeholt = () =>
|
||||
api(`/tools/bestellungen/${id}`,{method:'PUT',body:{abgeholt:!order.abgeholt}})
|
||||
.then(u=>{setOrder(u);toast(u.abgeholt?'Als abgeholt markiert':'Abholung aufgehoben');});
|
||||
function toggleBezahlt() {
|
||||
if (!order.bezahlt) {
|
||||
// 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;
|
||||
|
||||
@@ -179,6 +210,29 @@ function BestellungDetail({ id, toast, onBack }) {
|
||||
</span>
|
||||
)}
|
||||
</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 && (
|
||||
<div style={{color:'rgba(192,132,252,0.5)',fontFamily:'monospace',fontSize:10,marginTop:5}}>
|
||||
🔒 Bearbeitung gesperrt.
|
||||
@@ -198,6 +252,29 @@ function BestellungDetail({ id, toast, onBack }) {
|
||||
}}>
|
||||
{!!order.abgeholt?'📦 Abgeholt':'○ Als abgeholt markieren'}
|
||||
</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 && (
|
||||
<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'})}
|
||||
|
||||
Reference in New Issue
Block a user