v1.37: KI-Assistent N8N-Workflow fertig eingerichtet; alle Formulare 2-spaltig mit neuem Design
- N8N: Workflow serverseitig in DB eingespielt (Webhook mp-assist, Code-Node mit Kimi-Tool-Calling, keine Credentials), E2E live verifiziert - Formulare: shared FormSection-Komponente (2 gleich breite Spalten, Wide fuer Volllbreiten-Felder), 10 Formulare umgebaut, Dialoge verbreitert - Design: Inter + Sora Fonts, Teal-Akzente, Icons in Sektionskoepfen
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import type { ReactNode } from 'react'
|
||||
import type { LucideIcon } from 'lucide-react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
/**
|
||||
* Shared Form-Layout für das Mieterportal.
|
||||
* Jede FormSection rendert ihre Felder in zwei gleich breiten Spalten
|
||||
* (mobil: eine Spalte). Elemente, die über die volle Breite laufen sollen
|
||||
* (Checkbox-Blöcke, Textareas, Uploads, Hinweistexte), in <Wide> packen.
|
||||
*/
|
||||
|
||||
export function FormSection({
|
||||
titel,
|
||||
icon: Icon,
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
titel: string
|
||||
icon?: LucideIcon
|
||||
children: ReactNode
|
||||
className?: string
|
||||
}) {
|
||||
return (
|
||||
<section
|
||||
className={cn(
|
||||
'rounded-xl border border-slate-200 bg-white p-4 shadow-sm sm:p-5',
|
||||
'dark:border-slate-700/60 dark:bg-slate-900/60',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<header className="mb-4 flex items-center gap-2.5 border-b border-slate-100 pb-3 dark:border-slate-800">
|
||||
{Icon && (
|
||||
<span className="flex h-7 w-7 items-center justify-center rounded-lg bg-teal-600/10 text-teal-700 dark:bg-teal-400/10 dark:text-teal-300">
|
||||
<Icon className="h-4 w-4" />
|
||||
</span>
|
||||
)}
|
||||
<h3 className="font-display text-[13px] font-semibold uppercase tracking-wider text-teal-800 dark:text-teal-300">
|
||||
{titel}
|
||||
</h3>
|
||||
</header>
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">{children}</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
/** Volle Breite innerhalb einer 2-spaltigen FormSection. */
|
||||
export function Wide({ children, className }: { children: ReactNode; className?: string }) {
|
||||
return <div className={cn('md:col-span-2', className)}>{children}</div>
|
||||
}
|
||||
|
||||
/** Fehlerzeile am Ende eines Formulars. */
|
||||
export function FormFehler({ fehler }: { fehler: string | null }) {
|
||||
if (!fehler) return null
|
||||
return (
|
||||
<div
|
||||
className="rounded-lg bg-red-50 px-3 py-2 text-sm text-red-700 dark:bg-red-950 dark:text-red-300"
|
||||
role="alert"
|
||||
>
|
||||
{fehler}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user