Dateien nach "frontend/src" hochladen

This commit is contained in:
2026-05-26 14:49:06 +02:00
parent 75b5944d12
commit 0222778aab

View File

@@ -92,11 +92,15 @@ export default function CalendarWidget() {
const [loading, setLoading] = useState(false);
const [selected, setSelected] = useState(null); // date object
const [errors, setErrors] = useState([]);
// Load all feeds
const loadFeeds = async (feedList) => {
if (!feedList.length) { setEvents([]); return; }
setLoading(true);
setErrors([]);
const all = [];
const errs = [];
for (const f of feedList) {
try {
const res = await fetch(`/api/calendar/fetch?url=${encodeURIComponent(f.url)}`, {
@@ -106,14 +110,18 @@ export default function CalendarWidget() {
const text = await res.text();
const evs = parseIcal(text).map(e => ({ ...e, color: f.color, feedName: f.name }));
all.push(...evs);
} else {
const d = await res.json().catch(()=>({error:'Unbekannter Fehler'}));
errs.push(`${f.name}: ${d.error}`);
}
} catch {}
} catch(e) { errs.push(`${f.name}: ${e.message}`); }
}
setEvents(all);
setErrors(errs);
setLoading(false);
};
useEffect(() => { if (isOpen) loadFeeds(feeds); }, [isOpen]);
useEffect(() => { if (isOpen && feeds.length > 0) loadFeeds(feeds); }, [isOpen]);
// Calendar grid
const days = useMemo(() => {
@@ -135,15 +143,37 @@ export default function CalendarWidget() {
return (
<div style={{ ...S.card, marginBottom:10 }}>
{/* Header */}
<button onClick={()=>setIsOpen(v=>!v)} style={{ width:'100%', background:'transparent', border:'none',
display:'flex', justifyContent:'space-between', alignItems:'center', cursor:'pointer', padding:0 }}>
<div style={S.head}>KALENDER{loading?' …':''}</div>
<span style={{ color:'rgba(255,255,255,0.4)', fontSize:11, display:'inline-block',
transform:isOpen?'rotate(90deg)':'rotate(0)', transition:'transform 0.2s' }}></span>
</button>
<div style={{ display:'flex', justifyContent:'space-between', alignItems:'center' }}>
<button onClick={()=>setIsOpen(v=>!v)} style={{ flex:1, background:'transparent', border:'none',
display:'flex', justifyContent:'space-between', alignItems:'center', cursor:'pointer', padding:0 }}>
<div style={S.head}>KALENDER</div>
<span style={{ color:'rgba(255,255,255,0.4)', fontSize:11, display:'inline-block',
transform:isOpen?'rotate(90deg)':'rotate(0)', transition:'transform 0.2s' }}></span>
</button>
{isOpen && feeds.length > 0 && (
<button onClick={()=>loadFeeds(feeds)} disabled={loading}
style={{ background:'transparent', border:'none', color:'rgba(255,255,255,0.4)',
cursor:'pointer', fontSize:13, padding:'0 0 0 8px', marginLeft:8 }}
title="Neu laden">
{loading ? '⏳' : '↻'}
</button>
)}
</div>
{isOpen && (
<div style={{ marginTop:12 }}>
{/* Fehler */}
{errors.length > 0 && (
<div style={{ marginBottom:10 }}>
{errors.map((e,i) => (
<div key={i} style={{ color:'#ff6b9d', fontFamily:'monospace', fontSize:10,
background:'rgba(255,107,157,0.08)', borderRadius:6, padding:'4px 8px', marginBottom:3 }}>
{e}
</div>
))}
</div>
)}
{/* Monat Nav */}
<div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:10 }}>
<button onClick={prevMonth} style={{ background:'transparent', border:'none', color:'rgba(255,255,255,0.5)',