From 2012e124d379c366ae0e7fd448652c90100a83d1 Mon Sep 17 00:00:00 2001 From: JUSN Date: Tue, 11 Aug 2026 23:29:53 +0200 Subject: [PATCH] App Phase 2: Antwort-Assistent als 3-Schritte-Assistent (Design-Layout) - Fortschrittsbalken + 'Schritt X von 3' - Schritt 1: Antwort-Art als Karten (Icon + Beschreibung, 'Empfohlen'-Tag fuer die vom Brief vorgeschlagenen Typen) - Schritt 2: optionale Angaben + Info-Box (Aktenzeichen/Behoerde kommen automatisch aus dem Brief), dann KI-Entwurf - Schritt 3: Entwurf pruefen/bearbeiten + PDF-Export + Teilen - alle Funktionen erhalten (generiereAntwort, sichern, PDF, Teilen); bei vorhandenem Entwurf Start direkt in Schritt 3 - warme Design-Farben durchs zentrale Theme Typecheck + 30 Tests gruen. Visuelle Pruefung (Analyse + Antwort) im Simulator steht noch aus. Co-Authored-By: Claude Opus 4.8 --- src/screens/AntwortScreen.tsx | 250 +++++++++++++++++++++++----------- 1 file changed, 167 insertions(+), 83 deletions(-) diff --git a/src/screens/AntwortScreen.tsx b/src/screens/AntwortScreen.tsx index 37005a5..020a72a 100644 --- a/src/screens/AntwortScreen.tsx +++ b/src/screens/AntwortScreen.tsx @@ -1,12 +1,15 @@ /** - * Antwort-Generator: Vorlage wählen -> KI-Entwurf -> frei bearbeiten -> - * als PDF exportieren oder als Text teilen. + * Antwort-Assistent — 3-Schritte-Assistent nach dem Claude-Design-Entwurf: + * 1. Antwort-Art wählen 2. Angaben ergänzen 3. Entwurf prüfen & exportieren + * Der KI-Entwurf (generiereAntwort) bleibt das Herzstück; nur die Führung ist + * jetzt klar in Schritte gegliedert, mit Fortschrittsbalken. */ import React, { useState } from 'react'; import { Alert, KeyboardAvoidingView, Platform, + Pressable, ScrollView, Share, StyleSheet, @@ -22,6 +25,7 @@ import { useAppStore } from '../store/useAppStore'; import { generiereAntwort } from '../services/antwort'; import { ClaudeFehler } from '../services/claudeClient'; import { GrossButton } from '../components/GrossButton'; +import { Ikone, IkonenName } from '../components/Ikone'; import { farben, schrift, abstand } from '../theme'; type Props = NativeStackScreenProps; @@ -34,10 +38,19 @@ const ALLE_TYPEN: AntwortTyp[] = [ 'rueckfrage', ]; +const TYP_INFO: Record = { + terminbestaetigung: { ikone: 'checkAn', beschreibung: 'Sie bestätigen, dass Sie zum Termin kommen.' }, + terminverschiebung: { ikone: 'kalender', beschreibung: 'Sie bitten um einen neuen Termin.' }, + widerspruch: { ikone: 'warnung', beschreibung: 'Sie sind nicht einverstanden und legen Einspruch ein.' }, + unterlagen_nachreichen: { ikone: 'dokument', beschreibung: 'Sie reichen die geforderten Unterlagen ein.' }, + rueckfrage: { ikone: 'info', beschreibung: 'Sie haben eine Frage zum Brief.' }, +}; + export function AntwortScreen({ route }: Props) { const brief = useAppStore((s) => s.briefe.find((b) => b.id === route.params.briefId)); const setzeAntwortEntwurf = useAppStore((s) => s.setzeAntwortEntwurf); + const [schritt, setSchritt] = useState<1 | 2 | 3>(brief?.antwortEntwurf?.text ? 3 : 1); const [typ, setTyp] = useState(brief?.antwortEntwurf?.typ ?? null); const [hinweise, setHinweise] = useState(''); const [betreff, setBetreff] = useState(brief?.antwortEntwurf?.betreff ?? ''); @@ -52,12 +65,16 @@ export function AntwortScreen({ route }: Props) { ); } - // Vom Brief vorgeschlagene Vorlagen zuerst, Rest danach const optionen = [ ...brief.analyse.antwort_optionen, ...ALLE_TYPEN.filter((t) => !brief.analyse.antwort_optionen.includes(t)), ]; + const typWaehlen = (t: AntwortTyp) => { + setTyp(t); + setSchritt(2); + }; + const erzeugen = async () => { if (!typ) return; setLaedt(true); @@ -66,6 +83,7 @@ export function AntwortScreen({ route }: Props) { setBetreff(entwurf.betreff); setText(entwurf.text); await setzeAntwortEntwurf(brief.id, { typ, ...entwurf }); + setSchritt(3); } catch (e) { Alert.alert( 'Fehler', @@ -76,17 +94,13 @@ export function AntwortScreen({ route }: Props) { } }; - /** Bearbeiteten Stand sichern (beim Export/Teilen automatisch). */ const sichern = async () => { - if (typ && text) { - await setzeAntwortEntwurf(brief.id, { typ, betreff, text }); - } + if (typ && text) await setzeAntwortEntwurf(brief.id, { typ, betreff, text }); }; const alsPdf = async () => { await sichern(); try { - // Einfaches, sauberes Brief-Layout für den Ausdruck const html = `