chore: stabilize apps/web (lint, build, typecheck fixes)
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 6s
Build & Deploy / 🧪 QA (push) Failing after 1m27s
Build & Deploy / 🏗️ Build (push) Failing after 1m31s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s

This commit is contained in:
2026-02-11 11:56:13 +01:00
parent 8ba81809b0
commit ecea90dc91
50 changed files with 5596 additions and 3456 deletions

View File

@@ -1,19 +1,19 @@
'use client';
"use client";
import * as React from 'react';
import { FormState } from '../types';
import { Users, Shield, Monitor, Smartphone, Globe, Lock } from 'lucide-react';
import * as React from "react";
import { FormState } from "../types";
import { Users, Shield, Monitor, Smartphone, Globe, Lock } from "lucide-react";
interface WebAppStepProps {
state: FormState;
updateState: (updates: Partial<FormState>) => void;
updateState: (_updates: Partial<FormState>) => void;
}
export function WebAppStep({ state, updateState }: WebAppStepProps) {
const toggleUserRole = (role: string) => {
const current = state.userRoles || [];
const next = current.includes(role)
? current.filter(r => r !== role)
const next = current.includes(role)
? current.filter((r) => r !== role)
: [...current, role];
updateState({ userRoles: next });
};
@@ -26,23 +26,39 @@ export function WebAppStep({ state, updateState }: WebAppStepProps) {
<h4 className="text-2xl font-bold text-slate-900 flex items-center gap-3">
<Users size={24} className="text-black" /> Zielgruppe
</h4>
<span className="px-2 py-1 bg-slate-100 text-slate-500 text-[10px] font-bold uppercase tracking-wider rounded">Fokus</span>
<span className="px-2 py-1 bg-slate-100 text-slate-500 text-[10px] font-bold uppercase tracking-wider rounded">
Fokus
</span>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{[
{ id: 'internal', label: 'Internes Tool', desc: 'Für Mitarbeiter & Prozesse.' },
{ id: 'external', label: 'Kunden-Portal', desc: 'Für Ihre Endnutzer (B2B/B2C).' },
].map(opt => (
{
id: "internal",
label: "Internes Tool",
desc: "Für Mitarbeiter & Prozesse.",
},
{
id: "external",
label: "Kunden-Portal",
desc: "Für Ihre Endnutzer (B2B/B2C).",
},
].map((opt) => (
<button
key={opt.id}
type="button"
onClick={() => updateState({ targetAudience: opt.id })}
className={`p-8 rounded-[2rem] border-2 text-left transition-all ${
state.targetAudience === opt.id ? 'border-slate-900 bg-slate-900 text-white' : 'border-slate-100 bg-white hover:border-slate-200'
state.targetAudience === opt.id
? "border-slate-900 bg-slate-900 text-white"
: "border-slate-100 bg-white hover:border-slate-200"
}`}
>
<p className="text-xl font-bold">{opt.label}</p>
<p className={`text-base mt-2 ${state.targetAudience === opt.id ? 'text-slate-200' : 'text-slate-500'}`}>{opt.desc}</p>
<p
className={`text-base mt-2 ${state.targetAudience === opt.id ? "text-slate-200" : "text-slate-500"}`}
>
{opt.desc}
</p>
</button>
))}
</div>
@@ -53,13 +69,21 @@ export function WebAppStep({ state, updateState }: WebAppStepProps) {
<h4 className="text-2xl font-bold text-slate-900">Benutzerrollen</h4>
<p className="text-lg text-slate-500">Wer wird das System nutzen?</p>
<div className="flex flex-wrap gap-4">
{['Administratoren', 'Manager', 'Standard-Nutzer', 'Gäste', 'Read-Only'].map(role => (
{[
"Administratoren",
"Manager",
"Standard-Nutzer",
"Gäste",
"Read-Only",
].map((role) => (
<button
key={role}
type="button"
onClick={() => toggleUserRole(role)}
className={`px-8 py-4 rounded-full border-2 font-bold text-base transition-all ${
(state.userRoles || []).includes(role) ? 'border-slate-900 bg-slate-900 text-white' : 'border-slate-100 bg-white hover:border-slate-200'
(state.userRoles || []).includes(role)
? "border-slate-900 bg-slate-900 text-white"
: "border-slate-100 bg-white hover:border-slate-200"
}`}
>
{role}
@@ -75,19 +99,37 @@ export function WebAppStep({ state, updateState }: WebAppStepProps) {
</h4>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{[
{ id: 'desktop', label: 'Desktop First', icon: <Monitor size={24} /> },
{ id: 'mobile', label: 'Mobile First', icon: <Smartphone size={24} /> },
{ id: 'pwa', label: 'PWA (Installierbar)', icon: <Globe size={24} /> },
].map(opt => (
{
id: "desktop",
label: "Desktop First",
icon: <Monitor size={24} />,
},
{
id: "mobile",
label: "Mobile First",
icon: <Smartphone size={24} />,
},
{
id: "pwa",
label: "PWA (Installierbar)",
icon: <Globe size={24} />,
},
].map((opt) => (
<button
key={opt.id}
type="button"
onClick={() => updateState({ platformType: opt.id })}
className={`p-8 rounded-[2rem] border-2 flex flex-col items-center gap-4 transition-all ${
state.platformType === opt.id ? 'border-slate-900 bg-slate-900 text-white' : 'border-slate-100 bg-white hover:border-slate-200'
state.platformType === opt.id
? "border-slate-900 bg-slate-900 text-white"
: "border-slate-100 bg-white hover:border-slate-200"
}`}
>
<div className={state.platformType === opt.id ? 'text-white' : 'text-black'}>
<div
className={
state.platformType === opt.id ? "text-white" : "text-black"
}
>
{opt.icon}
</div>
<span className="font-bold text-lg">{opt.label}</span>
@@ -103,19 +145,33 @@ export function WebAppStep({ state, updateState }: WebAppStepProps) {
</h4>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{[
{ id: 'standard', label: 'Standard', desc: 'Normale Nutzerdaten & Profile.' },
{ id: 'high', label: 'Sensibel', desc: 'Finanzdaten, Gesundheitsdaten oder DSGVO-kritisch.' },
].map(opt => (
{
id: "standard",
label: "Standard",
desc: "Normale Nutzerdaten & Profile.",
},
{
id: "high",
label: "Sensibel",
desc: "Finanzdaten, Gesundheitsdaten oder DSGVO-kritisch.",
},
].map((opt) => (
<button
key={opt.id}
type="button"
onClick={() => updateState({ dataSensitivity: opt.id })}
className={`p-8 rounded-[2rem] border-2 text-left transition-all ${
state.dataSensitivity === opt.id ? 'border-slate-900 bg-slate-900 text-white' : 'border-slate-100 bg-white hover:border-slate-200'
state.dataSensitivity === opt.id
? "border-slate-900 bg-slate-900 text-white"
: "border-slate-100 bg-white hover:border-slate-200"
}`}
>
<p className="text-xl font-bold">{opt.label}</p>
<p className={`text-base mt-2 ${state.dataSensitivity === opt.id ? 'text-slate-200' : 'text-slate-500'}`}>{opt.desc}</p>
<p
className={`text-base mt-2 ${state.dataSensitivity === opt.id ? "text-slate-200" : "text-slate-500"}`}
>
{opt.desc}
</p>
</button>
))}
</div>
@@ -126,9 +182,17 @@ export function WebAppStep({ state, updateState }: WebAppStepProps) {
<h4 className="text-2xl font-bold text-slate-900 flex items-center gap-3">
<Lock size={24} className="text-black" /> Authentifizierung
</h4>
<p className="text-lg text-slate-500">Wie sollen sich Nutzer anmelden?</p>
<p className="text-lg text-slate-500">
Wie sollen sich Nutzer anmelden?
</p>
<div className="flex flex-wrap gap-4">
{['E-Mail / Passwort', 'Social Login', 'SSO / SAML', '2FA / MFA', 'Magic Links'].map(method => (
{[
"E-Mail / Passwort",
"Social Login",
"SSO / SAML",
"2FA / MFA",
"Magic Links",
].map((method) => (
<div
key={method}
className="px-8 py-4 rounded-full border-2 border-white bg-white font-bold text-base text-slate-400"
@@ -137,7 +201,9 @@ export function WebAppStep({ state, updateState }: WebAppStepProps) {
</div>
))}
</div>
<p className="text-xs text-slate-400 italic">Details zur Authentifizierung besprechen wir im Erstgespräch.</p>
<p className="text-xs text-slate-400 italic">
Details zur Authentifizierung besprechen wir im Erstgespräch.
</p>
</div>
</div>
);