feat: Immobilie, Versicherungen und Heim mit COPD-Verlauf
Etappe 6. Das leerstehende Haus, die Vertraege und der Gesundheitsverlauf - die drei Bereiche, in denen fuer diesen Fall das meiste Geld und das meiste Risiko liegt. Leerstands-Checkliste mit zehn Punkten, jeder mit Begruendung. Der wichtigste: den Gebaeudeversicherer ueber den Leerstand informieren - sonst droht Leistungsfreiheit, und zwar genau dann, wenn es brennt oder eine Leitung platzt. Dazu Verkehrssicherungspflicht, Frostschutz zum Oktober, Kontrollgaenge, Zaehlerstaende, Schluesselverzeichnis. Der Kuendigungsrechner nennt den spaetesten ABSENDETAG, nicht den Fristablauf: eine Kuendigung wirkt mit dem Zugang, nicht mit dem Abschicken. Drei Tage Postlaufpuffer sind einkalkuliert. Der Kuendigungs-Assistent beantwortet die Genehmigungsfrage nach § 1850 BGB nicht - er stellt sie und verlangt den Gang zum Rechtspfleger. Der Versandnachweis ist Pflichtfeld: ohne ihn kommt die Kuendigung nicht durch die Pruefung. Leistungszuschlag nach § 43c SGB XI mit Stand 01.01.2024 (15/30/50/75 Prozent nach Verweildauer, erst ab Pflegegrad 2). Die Oberflaeche zeigt, ab wann die naechste Stufe greift - das ist bares Geld und wird regelmaessig uebersehen. COPD-Schnellerfassung fuer Exazerbation, Sauerstoff, Sturz, Krankenhaus, Hilfsmittel und Impfungen, mit STIKO-Plan fuer COPD. Beschreibungen verschluesselt. Die Jahresauswertung ueber Exazerbationen und Krankenhaustage wandert in den Jahresbericht und begruendet eine Hoeherstufung. 74 Tests. Etappe: 6 Phase: Substanz
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
'use client'
|
||||
|
||||
import { useActionState } from 'react'
|
||||
import { CheckCircle2, FileWarning, Gavel, Scale, TriangleAlert } from 'lucide-react'
|
||||
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Select } from '@/components/ui/select'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import { Feld } from '@/components/feld'
|
||||
import { Rechtshinweis } from '@/components/rechtshinweis'
|
||||
import { Absendeknopf, Textbaustein, Zustandsmeldung } from '@/components/substanz-formular'
|
||||
import { kuendigungVermerken } from '@/server/actions/vertraege'
|
||||
import { formatDatum } from '@/lib/utils'
|
||||
import type { Formularzustand } from '@/lib/validierung/substanz'
|
||||
|
||||
export type AssistentDaten = {
|
||||
schreiben: string
|
||||
warnungen: string[]
|
||||
genehmigung: {
|
||||
stellen: boolean
|
||||
frage: string
|
||||
rechtsgrundlage: string
|
||||
hinweis: string
|
||||
}
|
||||
versandnachweis: {
|
||||
moeglichkeiten: string[]
|
||||
hinweis: string
|
||||
}
|
||||
plan: {
|
||||
berechenbar: boolean
|
||||
naechsterTermin: string | null
|
||||
zugangSpaetestensAm: string | null
|
||||
spaetesterAbsendetag: string | null
|
||||
tageBisAbsendetag: number | null
|
||||
verpasst: boolean
|
||||
hinweise: string[]
|
||||
}
|
||||
}
|
||||
|
||||
export function KuendigungsAssistent({
|
||||
betreuteId,
|
||||
vertragId,
|
||||
daten,
|
||||
heuteIso,
|
||||
darfSchreiben,
|
||||
}: {
|
||||
betreuteId: string
|
||||
vertragId: string
|
||||
daten: AssistentDaten
|
||||
heuteIso: string
|
||||
darfSchreiben: boolean
|
||||
}) {
|
||||
const [zustand, aktion] = useActionState<Formularzustand, FormData>(kuendigungVermerken, {})
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{daten.warnungen.length > 0 && (
|
||||
<Alert variant="warnung">
|
||||
<TriangleAlert aria-hidden="true" />
|
||||
<AlertTitle>Vor dem Absenden klären</AlertTitle>
|
||||
<AlertDescription>
|
||||
<ul className="ml-4 list-disc space-y-1.5">
|
||||
{daten.warnungen.map((warnung) => (
|
||||
<li key={warnung}>{warnung}</li>
|
||||
))}
|
||||
</ul>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<Scale className="size-5" aria-hidden="true" />
|
||||
Frist geprüft
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
Zu diesem Termin kann als Nächstes gekündigt werden — und bis wann der Brief dafür
|
||||
raus muss.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
{daten.plan.berechenbar ? (
|
||||
<dl className="grid gap-3 sm:grid-cols-3">
|
||||
<div className="rounded-md border p-3">
|
||||
<dt className="text-sm text-muted-foreground">Kündigung zum</dt>
|
||||
<dd className="text-lg font-semibold">
|
||||
{formatDatum(daten.plan.naechsterTermin)}
|
||||
</dd>
|
||||
</div>
|
||||
<div className="rounded-md border p-3">
|
||||
<dt className="text-sm text-muted-foreground">Zugang spätestens</dt>
|
||||
<dd className="text-lg font-semibold">
|
||||
{formatDatum(daten.plan.zugangSpaetestensAm)}
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
daten.plan.verpasst || (daten.plan.tageBisAbsendetag ?? 99) <= 30
|
||||
? 'rounded-md border border-ampel-rot/40 bg-ampel-rot/5 p-3'
|
||||
: 'rounded-md border p-3'
|
||||
}
|
||||
>
|
||||
<dt className="text-sm text-muted-foreground">Brief spätestens absenden</dt>
|
||||
<dd className="text-lg font-semibold">
|
||||
{formatDatum(daten.plan.spaetesterAbsendetag)}
|
||||
</dd>
|
||||
{daten.plan.tageBisAbsendetag !== null && (
|
||||
<dd className="text-sm text-muted-foreground">
|
||||
{daten.plan.tageBisAbsendetag < 0
|
||||
? `vor ${Math.abs(daten.plan.tageBisAbsendetag)} Tagen`
|
||||
: `in ${daten.plan.tageBisAbsendetag} Tagen`}
|
||||
</dd>
|
||||
)}
|
||||
</div>
|
||||
</dl>
|
||||
) : (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Ohne Laufzeitbeginn und Kündigungsfrist lässt sich der Termin nicht berechnen.
|
||||
</p>
|
||||
)}
|
||||
|
||||
<ul className="space-y-1.5 text-sm text-muted-foreground">
|
||||
{daten.plan.hinweise.map((hinweis) => (
|
||||
<li key={hinweis}>{hinweis}</li>
|
||||
))}
|
||||
</ul>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
className={
|
||||
daten.genehmigung.stellen ? 'border-ampel-orange/50 bg-ampel-orange/5' : undefined
|
||||
}
|
||||
>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<Gavel className="size-5" aria-hidden="true" />
|
||||
Genehmigungsfrage
|
||||
</CardTitle>
|
||||
<CardDescription>{daten.genehmigung.frage}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
<p className="text-sm">{daten.genehmigung.hinweis}</p>
|
||||
<Rechtshinweis rechtsgrundlage={daten.genehmigung.rechtsgrundlage} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Kündigungsschreiben</CardTitle>
|
||||
<CardDescription>
|
||||
Entwurf zum Kopieren und Bearbeiten. Die App verschickt nichts.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Textbaustein
|
||||
text={daten.schreiben}
|
||||
beschriftung="Kündigungsschreiben"
|
||||
hoehe="min-h-[36rem]"
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<FileWarning className="size-5" aria-hidden="true" />
|
||||
Versandnachweis
|
||||
</CardTitle>
|
||||
<CardDescription>{daten.versandnachweis.hinweis}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<ul className="ml-4 list-disc space-y-1 text-sm">
|
||||
{daten.versandnachweis.moeglichkeiten.map((moeglichkeit) => (
|
||||
<li key={moeglichkeit}>{moeglichkeit}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
{darfSchreiben && (
|
||||
<form action={aktion} className="space-y-4 rounded-md border p-4" noValidate>
|
||||
<input type="hidden" name="betreuteId" value={betreuteId} />
|
||||
<input type="hidden" name="vertragId" value={vertragId} />
|
||||
|
||||
<Zustandsmeldung zustand={zustand} />
|
||||
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
<Feld
|
||||
id="k-gekuendigtAm"
|
||||
beschriftung="Versandt am"
|
||||
fehler={zustand.felder?.gekuendigtAm}
|
||||
pflicht
|
||||
>
|
||||
<Input name="gekuendigtAm" type="date" defaultValue={heuteIso} required />
|
||||
</Feld>
|
||||
|
||||
<Feld
|
||||
id="k-kuendigungZum"
|
||||
beschriftung="Gekündigt zum"
|
||||
erklaerung="Der Termin aus der Berechnung oben."
|
||||
fehler={zustand.felder?.kuendigungZum}
|
||||
>
|
||||
<Input
|
||||
name="kuendigungZum"
|
||||
type="date"
|
||||
defaultValue={daten.plan.naechsterTermin ?? ''}
|
||||
/>
|
||||
</Feld>
|
||||
|
||||
<Feld
|
||||
id="k-versandart"
|
||||
beschriftung="Versandart"
|
||||
fehler={zustand.felder?.versandart}
|
||||
pflicht
|
||||
className="sm:col-span-2"
|
||||
>
|
||||
<Select name="versandart" defaultValue={daten.versandnachweis.moeglichkeiten[0]}>
|
||||
{daten.versandnachweis.moeglichkeiten.map((m) => (
|
||||
<option key={m} value={m}>
|
||||
{m}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
</Feld>
|
||||
</div>
|
||||
|
||||
<label className="flex items-start gap-2.5">
|
||||
<Checkbox name="nachweisVorhanden" className="mt-0.5" />
|
||||
<span className="text-sm">
|
||||
Der Versandnachweis liegt vor und ist als Dokument hochgeladen.
|
||||
{zustand.felder?.nachweisVorhanden && (
|
||||
<span className="mt-1 block font-medium text-destructive">
|
||||
{zustand.felder.nachweisVorhanden}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<label className="flex items-start gap-2.5">
|
||||
<Checkbox name="genehmigungGeklaert" className="mt-0.5" />
|
||||
<span className="text-sm">
|
||||
Die Genehmigungsfrage ist mit dem Rechtspfleger geklärt (§ 1850 BGB).
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<Feld id="k-bemerkung" beschriftung="Bemerkung" fehler={zustand.felder?.bemerkung}>
|
||||
<Textarea
|
||||
name="bemerkung"
|
||||
rows={2}
|
||||
maxLength={2000}
|
||||
placeholder="z. B. Einlieferungsnummer des Einschreibens"
|
||||
/>
|
||||
</Feld>
|
||||
|
||||
<Absendeknopf>
|
||||
<span className="flex items-center gap-2">
|
||||
<CheckCircle2 className="size-4" aria-hidden="true" />
|
||||
Kündigung als versandt vermerken
|
||||
</span>
|
||||
</Absendeknopf>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Setzt den Status auf „gekündigt“ und legt eine Wiedervorlage an, damit die
|
||||
Bestätigung der Gesellschaft nicht vergessen wird.
|
||||
</p>
|
||||
</form>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user