{/* Balance hero */}
Kontostand
{CURRENT_BALANCE.toLocaleString('de-DE')}€
Verfügbares Guthaben · {DEFAULT_COMPANY.name}
{[0, 180, 340, 180, 580, 760, 440].map((v, i, a) => (
))}
{[
{ l: 'Einnahmen · Mai', v: `+${fin.income.toLocaleString('de-DE')} €`, c: t.green },
{ l: 'Ausgaben · Mai', v: `−${fin.expenses.toLocaleString('de-DE')} €`, c: t.red },
{ l: 'Netto · Mai', v: `${fin.net >= 0 ? '+' : ''}${fin.net.toLocaleString('de-DE')} €`, c: t.text },
].map((x) => (
))}
{/* KPI tiles */}
{[
{ label: 'Aktive Mieten', value: active.length, sub: 'laufend', color: t.green, icon: icons.doc, to: 'rentals' },
{ label: 'Reserviert', value: reserved.length, sub: 'geplant', color: t.orange, icon: icons.clock, to: 'rentals' },
{ label: 'Unterwegs', value: liveUtilPct + '%', sub: `${vermietet} von ${totalStock} Geräten`, color: t.accent, icon: icons.truck, to: 'equipment' },
].map((s) => go(s.to)}/>)}
{/* Equipment status */}
go('equipment')}>Equipment-Status
{[['Verfügbar', verfuegbar, t.green], ['Vermietet', vermietet, t.accent], ['In Reparatur', equipment.reduce((s, e) => s + eqStock(e, rentals).reparatur, 0), t.orange]].map(([l, v, c]) => (
))}
{[...equipment].map((e) => ({ e, u: eqUses(e, rentals), util: eqUtil(e, rentals, equipment) })).sort((a, b) => b.u - a.u || b.util - a.util).slice(0, 4).map(({ e, util }) => {
const st = eqStock(e, rentals);
return (
go('equipment', { equipmentId: e.id })} scale={0.99} hoverBg={t.cardAlt} style={{ borderRadius: 10 }}>
{e.name}
{e.cat} · {e.price} €/Tag
{util}%
);
})}
{equipment.length > 4 && (
setShowAllEq(true)} scale={0.99} hoverBg={t.cardAlt} style={{ borderRadius: 10, marginTop: 6 }}>
Alle {equipment.length} Geräte anzeigen
)}
{/* Active rentals list */}
go('rentals')}>Aktive & reservierte Mieten
{[...active, ...reserved].map((r) => {
const eq = equipment.find((e) => e.id === r.equipmentId);
const dep = depositMeta(r.depositStatus);
return (
go('rentals', { rentalId: r.id })} scale={0.99} hoverBg={t.cardAlt} style={{ borderRadius: 10 }}>
{r.tenantName}
{eq ? eq.name : r.equipmentName} · {fmtRange(r.start, r.end)}
{dep.label}
);
})}
{/* Benachrichtigungen — Aufgaben & anstehende Termine */}
Benachrichtigungen
Aufgaben & anstehende Termine
{openCount > 0 && (
{openCount} offen
)}
{/* Tab switcher */}
{[['todo', 'Zu erledigen', openCount], ['upcoming', 'Anstehend', upcomingCount]].map(([k, l, n]) => {
const sel = notifTab === k;
return (
setNotifTab(k)} scale={0.97} style={{ flex: 1 }}>
{l}
{n}
);
})}
{/* TAB: Zu erledigen */}
{notifTab === 'todo' && (
{auto.length === 0 && items.length === 0 && !adding &&
Alles erledigt ✓
}
{auto.map((a) => {
const done = !!autoDone[a.key];
return (
toggleAuto(a.key)}/>
a.rentalId ? go('rentals', { rentalId: a.rentalId }) : null} scale={0.99} style={{ flex: 1, minWidth: 0 }}>
{a.icon} {a.text}
{a.sub}
AUTO
dismissAuto(a.key)} scale={0.8}>
);
})}
{items.map((it, i) => (
toggleManual(it.id)}/>
{it.text}
removeManual(it.id)} scale={0.8}>
))}
{adding ? (
) : (
setAdding(true)} scale={0.99}>
)}
)}
{/* TAB: Anstehend */}
{notifTab === 'upcoming' && (
{[['today', 'Heute'], ['week', '7 Tage'], ['month', '30 Tage']].map(([k, l]) => {
const sel = upcRange === k;
return (
setUpcRange(k)} scale={0.96} style={{ flex: 1 }}>
{l}
);
})}
{upcoming.length === 0 &&
Keine Termine im Zeitraum.
}
{upcoming.map((ev, i) => {
const eq = equipment.find((e) => e.id === ev.equipmentId);
const isRental = !!ev.fromRental;
return (
isRental ? go('rentals', { rentalId: ev.rentalId }) : go('calendar')} scale={0.99} hoverBg={t.cardAlt} style={{ borderRadius: 10 }}>
{isRental ?
:
<>
{DE_MONTHS_SHORT[fromISO(ev.start).getMonth()]}
{fromISO(ev.start).getDate()}
>
}
{ev.title}{isRental && MIETE}
{eq ? eq.name + ' · ' : ''}{fmtRange(ev.start, ev.end)}
{isRental && (ev.startTime || ev.endTime) && (
{ev.startTime && ↑ Abholung {ev.startTime}}
{ev.endTime && ↓ Rückgabe {ev.endTime}}
)}
);
})}
)}
{/* Mini revenue chart */}
go('finance')}>Umsatzverlauf