Files
planer/src/app/(app)/page.tsx
T
Florian WildeandClaude Opus 5 144457b9f0 fix(aufgaben): Ideen aus Aufgabenliste und Inbox heraushalten
Der Fehler fiel erst in den aufgenommenen Bildern auf: Ideen standen
mitten in der Aufgabenliste, obwohl der ganze Sinn der getrennten
Ideenseite ist, dass sie das nicht tun. Ohne Termin hätten sie dort
entweder unsichtbar unten gestanden oder mit erfundenem Termin oben.

Der Filter kennt jetzt ohneIdeen; ein ausdrücklich gewählter Typ gewinnt,
wer nach Ideen filtert, sieht sie also weiterhin.

Die Startseite filterte Ideen bisher von Hand nach dem Laden — das
erledigt jetzt dieselbe Abfrage wie überall sonst.

Ein E2E-Test hält den Fall fest.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 16:33:33 +02:00

155 lines
5.1 KiB
TypeScript

import Link from 'next/link'
import { AufgabenListe } from '@/components/aufgaben/aufgaben-liste'
import { Schnellerfassung } from '@/components/aufgaben/schnellerfassung'
import {
Card,
CardBeschreibung,
CardInhalt,
CardKopf,
CardTitel,
} from '@/components/ui/card'
import { wochenKapazitaet } from '@/lib/bereich'
import { alsDatum, alsDauer } from '@/lib/zeit'
import {
aufgabenLaden,
bereicheLaden,
projekteZurAuswahlLaden,
zaehlstaende,
} from '@/server/abfragen/aufgaben'
import { verlangeAnmeldung } from '@/server/berechtigung'
import { db } from '@/server/db'
import { jetzt } from '@/server/zeitgeber'
export default async function StartSeite() {
const benutzer = await verlangeAnmeldung('/')
const heute = jetzt()
const [alleOffenen, bereiche, projekte, zahlen, bereichsListe] = await Promise.all([
aufgabenLaden({ nurOffen: true, ohneIdeen: true }, 200),
bereicheLaden(),
projekteZurAuswahlLaden(),
zaehlstaende(),
db.bereich.findMany({
where: { aktiv: true },
orderBy: [{ reihenfolge: 'asc' }, { name: 'asc' }],
}),
])
// Was jetzt zählt: überfällig, heute oder morgen fällig.
const dran = alleOffenen.filter(
(a) => a.ueberfaellig || a.faelligkeit === 'heute' || a.faelligkeit === 'morgen',
)
const anrede = benutzer.name?.split(' ')[0] ?? benutzer.email
return (
<div className="flex flex-col gap-8">
<header>
<h1 className="text-2xl font-semibold tracking-tight">Guten Tag, {anrede}</h1>
<p className="text-gedaempft-vordergrund mt-1 text-sm">{alsDatum(heute)}</p>
</header>
<Card>
<CardKopf>
<CardTitel className="text-base">Schnell erfassen</CardTitel>
<CardBeschreibung>
Landet in der{' '}
<Link href="/inbox" className="text-betont underline underline-offset-4">
Inbox
</Link>{' '}
und wird später einsortiert.
</CardBeschreibung>
</CardKopf>
<CardInhalt>
<Schnellerfassung />
</CardInhalt>
</Card>
<section className="flex flex-col gap-3">
<div className="flex flex-wrap items-baseline justify-between gap-2">
<h2 className="text-lg font-medium">Jetzt dran</h2>
<Link
href="/aufgaben"
className="text-gedaempft-vordergrund hover:text-vordergrund text-sm"
>
Alle {zahlen.offen} offenen Aufgaben
</Link>
</div>
<AufgabenListe
aufgaben={dran}
bereiche={bereiche}
projekte={projekte}
leerText="Nichts überfällig, nichts heute fällig. Ein guter Tag."
/>
</section>
<section className="flex flex-col gap-3">
<div className="flex flex-wrap items-baseline justify-between gap-2">
<h2 className="text-lg font-medium">Deine Bereiche</h2>
<Link
href="/bereiche"
className="text-gedaempft-vordergrund hover:text-vordergrund text-sm"
>
Bereiche verwalten
</Link>
</div>
{bereichsListe.length === 0 ? (
<Card>
<CardInhalt className="text-gedaempft-vordergrund py-8 text-center text-sm">
Noch keine Bereiche angelegt.{' '}
<Link href="/bereiche" className="text-betont underline underline-offset-4">
Jetzt einrichten
</Link>
</CardInhalt>
</Card>
) : (
<ul className="grid gap-4 sm:grid-cols-2">
{bereichsListe.map((bereich) => {
const offeneHier = alleOffenen.filter((a) => a.bereich?.id === bereich.id)
return (
<li key={bereich.id}>
<Card>
<CardKopf className="flex-row items-center gap-3">
<span
aria-hidden
className="size-3 shrink-0 rounded-full ring-1 ring-black/10"
style={{ backgroundColor: bereich.farbe }}
/>
<CardTitel className="text-base">{bereich.name}</CardTitel>
</CardKopf>
<CardInhalt>
<p className="text-gedaempft-vordergrund text-sm">
{offeneHier.length === 0
? 'Nichts offen'
: `${offeneHier.length} offen`}{' '}
· {alsDauer(wochenKapazitaet(bereich))} Kapazität je Woche
</p>
</CardInhalt>
</Card>
</li>
)
})}
</ul>
)}
</section>
{zahlen.ideen > 0 && (
<Card>
<CardKopf>
<CardTitel className="text-base">
<Link href="/ideen" className="hover:underline hover:underline-offset-4">
{zahlen.ideen} Idee(n) warten
</Link>
</CardTitel>
<CardBeschreibung>
Ideen drängen sich nicht in die Aufgabenliste — bis du eine übernimmst.
</CardBeschreibung>
</CardKopf>
</Card>
)}
</div>
)
}