From 89d55f982bbc6ad3714cb42472f13bed0234629b Mon Sep 17 00:00:00 2001 From: averel10 Date: Fri, 17 Apr 2026 07:55:43 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20added=20new=20onboarding=20step=20(Dial?= =?UTF-8?q?ektzugeh=C3=B6rigkeit)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OnboardingViews/OnboardingFormView.tsx | 165 +++++++++++++----- 1 file changed, 125 insertions(+), 40 deletions(-) diff --git a/src/components/OnboardingViews/OnboardingFormView.tsx b/src/components/OnboardingViews/OnboardingFormView.tsx index df1281d..ddfcb6e 100644 --- a/src/components/OnboardingViews/OnboardingFormView.tsx +++ b/src/components/OnboardingViews/OnboardingFormView.tsx @@ -12,7 +12,7 @@ interface OnboardingFormViewProps { } interface ResidenceEntry { - region: string; + canton: string; years: string; } @@ -20,12 +20,37 @@ interface FormData { age?: string; participateInRaffle?: boolean; residences?: ResidenceEntry[]; + ownDialectRegion?: string; dialectQualities?: Record; listeningExperience?: string; additionalNotes?: string; } -type Step = 1 | 2 | 3; +type Step = 1 | 2 | 3 | 4; + +const AVAILABLE_CANTONS = { + ag: 'Aargau', + ar: 'Appenzell Ausserrhoden', + ai: 'Appenzell Innerrhoden', + bl: 'Basel-Landschaft', + bs: 'Basel-Stadt', + be: 'Bern', + gl: 'Glarus', + gr: 'Graubünden', + lu: 'Luzern', + nw: 'Nidwalden', + ow: 'Obwalden', + sh: 'Schaffhausen', + sz: 'Schwyz', + so: 'Solothurn', + sg: 'St. Gallen', + tg: 'Thurgau', + ur: 'Uri', + vs: 'Wallis', + zg: 'Zug', + zh: 'Zürich', + other: 'Anderer Kanton/Ausland' +}; export default function OnboardingFormView({ experimentId, onBack, userEmail }: OnboardingFormViewProps) { const router = useRouter(); @@ -39,7 +64,8 @@ export default function OnboardingFormView({ experimentId, onBack, userEmail }: const [formData, setFormData] = useState({ age: '', participateInRaffle: false, - residences: [{ region: '', years: '' }], + residences: [{ canton: '', years: '' }], + ownDialectRegion: '', dialectQualities: initializeDialectQualities() }); const [error, setError] = useState(null); @@ -84,7 +110,7 @@ export default function OnboardingFormView({ experimentId, onBack, userEmail }: const addResidence = () => { setFormData((prev) => ({ ...prev, - residences: [...(prev.residences || []), { region: '', years: '' }], + residences: [...(prev.residences || []), { canton: '', years: '' }], })); }; @@ -99,20 +125,27 @@ export default function OnboardingFormView({ experimentId, onBack, userEmail }: switch (step) { case 1: if (!formData.age) { - setError('Bitte wählen Sie eine Altersgruppe aus.'); + setError('Bitte wählen deine Altersgruppe aus.'); return false; } break; case 2: - const hasValidResidence = formData.residences?.some( - (r) => r.region && r.years - ); - if (!hasValidResidence) { - setError('Bitte fügen Sie mindestens einen Wohnort mit Jahresangabe hinzu.'); + const allResidencesValid = formData.residences?.every((r) => { + const years = parseInt(r.years); + return r.canton && r.years && years >= 1 && years <= 100; + }); + if (!allResidencesValid) { + setError('Bitte füllen alle deine Aufenthaltsorte vollständig aus und stelle sicher, dass die Jahres-Angaben zwischen 1 und 100 liegen.'); return false; } break; case 3: + if (!formData.ownDialectRegion) { + setError('Bitte wählen deine Region deines eigenen Dialekts aus.'); + return false; + } + break; + case 4: const allDialects = Object.keys(DIALECT_LABELS_WITHOUT_DE); const hasAllDialectQualities = allDialects.every( (region) => !!formData.dialectQualities?.[region] @@ -129,7 +162,7 @@ export default function OnboardingFormView({ experimentId, onBack, userEmail }: const handleNext = () => { setError(null); if (validateStep(currentStep)) { - if (currentStep < 3) { + if (currentStep < 4) { setCurrentStep((currentStep + 1) as Step); } } @@ -145,6 +178,9 @@ export default function OnboardingFormView({ experimentId, onBack, userEmail }: }; const handleSubmit = () => { + if(!validateStep(4)) { + return; + } setError(null); startTransition(async () => { @@ -161,8 +197,9 @@ export default function OnboardingFormView({ experimentId, onBack, userEmail }: const stepTitles: Record = { 1: 'Persönliche Informationen', - 2: 'Aufenthaltsorte', - 3: 'Selbsteinschätzung', + 2: 'Aufenthaltsorte in der Deutschschweiz', + 3: 'Dialektzuordnung', + 4: 'Selbsteinschätzung', }; return ( @@ -173,14 +210,14 @@ export default function OnboardingFormView({ experimentId, onBack, userEmail }:

- Schritt {currentStep} von 3 + Schritt {currentStep} von 4

-
{Math.round((currentStep / 3) * 100)}%
+
{Math.round((currentStep / 4) * 100)}%
@@ -204,7 +241,7 @@ export default function OnboardingFormView({ experimentId, onBack, userEmail }:
- handleResidenceChange(index, 'region', e.target.value) + handleResidenceChange(index, 'canton', e.target.value) } className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm" > - {Object.entries(DIALECT_LABELS_WITHOUT_DE).map( - ([key, label]) => ( - - ) + {Object.entries(AVAILABLE_CANTONS).map( + ([key, label]) => { + // Hide cantons already selected in other residence entries + const isSelectedElsewhere = formData.residences?.some( + (r, i) => i !== index && r.canton === key + ); + + if (isSelectedElsewhere) { + return null; + } + + return ( + + ); + } )}
@@ -312,7 +356,7 @@ export default function OnboardingFormView({ experimentId, onBack, userEmail }: type="button" onClick={() => removeResidence(index)} disabled={(formData.residences?.length || 0) <= 1} - className="px-3 py-2 bg-red-100 hover:bg-red-200 disabled:bg-gray-100 text-red-600 disabled:text-gray-400 font-medium rounded-lg transition-colors text-sm" + className="px-3 py-2 bg-blue-100 hover:bg-blue-200 disabled:bg-gray-100 text-blue-600 disabled:text-gray-400 font-medium rounded-lg transition-colors text-sm" > ✕ @@ -331,11 +375,52 @@ export default function OnboardingFormView({ experimentId, onBack, userEmail }:
)} - {/* Step 3: Selbsteinschätzung */} + {/* Step 3: Dialektzuordnung */} {currentStep === 3 && (

- Bewerte deine Fähigkeit, die folgenden Dialekte zu erkennen. Diese Selbsteinschätzung hilft uns, deine Kalibrierungsergebnisse besser zu interpretieren. + Zu welcher Region würdest du deinen eigenen Dialekt am ehesten zuordnen? +
+ Orientiere dich an der folgenden Karte der deutschschweizer Dialektregionen. +
+ Wenn du keinen deutschschweizer Dialekt sprichst, wähle "Ich spreche keinen deutschschweizer Dialekt" aus. +

+ +
+ Karte der deutschschweizer Dialektregionen +
+ +
+ + +
+
+ )} + + {/* Step 4: Selbsteinschätzung */} + {currentStep === 4 && ( +
+

+ Bewerte deine Fähigkeit, die folgenden deutschschweizer Dialekte zu erkennen. Diese Selbsteinschätzung hilft uns, deine Kalibrierungsergebnisse besser zu interpretieren.

    @@ -404,7 +489,7 @@ export default function OnboardingFormView({ experimentId, onBack, userEmail }: ← Zurück - {currentStep < 3 ? ( + {currentStep < 4 ? (