Kanban: Modal-Scroll auf Mobile (Buttons immer sichtbar), Erstellungsdatum auf Karte
This commit is contained in:
@@ -9,7 +9,13 @@ const PRIORITIES = [
|
||||
{ id: 'high', label: 'Hoch', color: '#ff6b9d' },
|
||||
];
|
||||
const COL_COLORS = ['#4ecdc4','#60a5fa','#a78bfa','#ff6b9d','#ffe66d','#fb923c','#4ade80','#f472b6','#94a3b8'];
|
||||
const prioOf = id => PRIORITIES.find(p => p.id === id) || PRIORITIES[0];
|
||||
const fmtCardDate = s => {
|
||||
if (!s) return '';
|
||||
const d = new Date(String(s).replace(' ', 'T'));
|
||||
if (isNaN(d)) return '';
|
||||
return d.toLocaleDateString('de-DE', { day:'2-digit', month:'2-digit', year:'numeric' })
|
||||
+ ' ' + d.toLocaleTimeString('de-DE', { hour:'2-digit', minute:'2-digit' });
|
||||
};
|
||||
|
||||
// ── Karten-Modal ──────────────────────────────────────────────────────────────
|
||||
function CardModal({ card, columnId, columns, onSave, onClose, toast }) {
|
||||
@@ -64,15 +70,22 @@ function CardModal({ card, columnId, columns, onSave, onClose, toast }) {
|
||||
style={{ position:'fixed',inset:0,background:'rgba(0,0,0,0.7)',zIndex:1000,
|
||||
display:'flex',alignItems:isMob?'flex-end':'center',justifyContent:'center',padding:isMob?0:20 }}>
|
||||
<div style={{ background:'#1a1a1e',border:'1px solid rgba(255,255,255,0.12)',
|
||||
borderRadius:isMob?'16px 16px 0 0':14,padding:'22px 20px 28px',
|
||||
width:'100%',maxWidth:460 }}>
|
||||
{isMob && <div style={{ width:36,height:4,background:'rgba(255,255,255,0.15)',borderRadius:2,margin:'0 auto 16px' }}/>}
|
||||
|
||||
borderRadius:isMob?'16px 16px 0 0':14,
|
||||
width:'100%',maxWidth:460,
|
||||
display:'flex',flexDirection:'column',
|
||||
maxHeight: isMob ? '92vh' : '90vh',
|
||||
}}>
|
||||
{/* Drag-Handle + Header – immer sichtbar, nicht scrollend */}
|
||||
<div style={{ padding:'18px 20px 0', flexShrink:0 }}>
|
||||
{isMob && <div style={{ width:36,height:4,background:'rgba(255,255,255,0.15)',borderRadius:2,margin:'0 auto 14px' }}/>}
|
||||
<div style={{ display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:16 }}>
|
||||
<div style={{ ...S.head, marginBottom:0 }}>{card ? 'KARTE BEARBEITEN' : 'NEUE KARTE'}</div>
|
||||
<button onClick={onClose} style={{ background:'transparent',border:'none',color:'rgba(255,255,255,0.4)',cursor:'pointer',fontSize:18 }}>✕</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Scrollbarer Inhalt */}
|
||||
<div style={{ overflowY:'auto',padding:'0 20px',flex:1,scrollbarWidth:'thin',scrollbarColor:'rgba(255,255,255,0.08) transparent' }}>
|
||||
<input ref={titleRef} value={title} onChange={e=>setTitle(e.target.value)} onKeyDown={onKey}
|
||||
placeholder="Titel" style={{ ...S.inp, marginBottom:10 }} />
|
||||
|
||||
@@ -83,7 +96,7 @@ function CardModal({ card, columnId, columns, onSave, onClose, toast }) {
|
||||
{/* Priorität */}
|
||||
<div style={{ marginBottom:14 }}>
|
||||
<div style={{ ...S.head, marginBottom:8 }}>PRIORITÄT</div>
|
||||
<div style={{ display:'flex', gap:6 }}>
|
||||
<div style={{ display:'flex', gap:6, flexWrap:'wrap' }}>
|
||||
{PRIORITIES.map(p => (
|
||||
<button key={p.id} onClick={()=>setPrio(p.id)} style={{
|
||||
...S.btn(p.color, true),
|
||||
@@ -95,8 +108,8 @@ function CardModal({ card, columnId, columns, onSave, onClose, toast }) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Verschieben nach (nur bei Bearbeitung sinnvoll, aber auch bei Neu nützlich) */}
|
||||
<div style={{ marginBottom:18 }}>
|
||||
{/* Verschieben nach */}
|
||||
<div style={{ marginBottom:14 }}>
|
||||
<div style={{ ...S.head, marginBottom:8 }}>{card ? 'VERSCHIEBEN NACH' : 'IN SPALTE'}</div>
|
||||
{!showNewCol ? (
|
||||
<div style={{ display:'flex', gap:6, flexWrap:'wrap' }}>
|
||||
@@ -120,8 +133,11 @@ function CardModal({ card, columnId, columns, onSave, onClose, toast }) {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display:'flex', gap:8, justifyContent:'flex-end' }}>
|
||||
{/* Aktionsbuttons – immer sichtbar am unteren Rand, nicht scrollend */}
|
||||
<div style={{ padding:'14px 20px 24px', flexShrink:0, borderTop:'1px solid rgba(255,255,255,0.07)',
|
||||
display:'flex', gap:8, justifyContent:'flex-end' }}>
|
||||
<button onClick={onClose} style={S.btn('#888888', true)}>Abbrechen</button>
|
||||
<button onClick={save} disabled={!title.trim()||saving} style={S.btn('#4ecdc4', true)}>
|
||||
{saving ? '…' : card ? 'Speichern' : 'Erstellen'}
|
||||
@@ -274,6 +290,14 @@ function KanbanCard({ card, col, allCols, onEdit, onDelete, onMove, isDragging,
|
||||
{arrowBtn('→', isLastCol, ()=>onMove(card.id, allCols[colIdx+1]?.id))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Erstellungsdatum */}
|
||||
{card.created_at && (
|
||||
<div style={{ fontSize:9,fontFamily:'monospace',color:'rgba(255,255,255,0.2)',
|
||||
marginTop:6, textAlign:'right', letterSpacing:0.5 }}>
|
||||
{fmtCardDate(card.created_at)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user