Files
auditly/src/pages/EmployeeQuestionnaire.tsx
2025-08-25 15:55:43 -07:00

1923 lines
108 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useEffect } from 'react';
import { useNavigate, useLocation, useParams } from 'react-router-dom';
import { useAuth } from '../contexts/AuthContext';
import { useOrg } from '../contexts/OrgContext';
import { EMPLOYEE_QUESTIONS, EmployeeSubmissionAnswers } from '../employeeQuestions';
import { API_URL } from '../constants';
import { FigmaRatingScale, FigmaTextArea, FigmaNavigationButtons } from '../components/figma/FigmaQuestion';
import { FigmaMultipleChoice } from '../components/figma/FigmaMultipleChoice';
// Icon SVG Component - From EmployeeFormsController
const AuditlyIcon: React.FC = () => (
<svg width="24" height="30" viewBox="0 0 24 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.5" fillRule="evenodd" clipRule="evenodd" d="M2.57408 17.8138C3.11835 18.3649 3.11834 19.2585 2.57406 19.8097L2.54619 19.8379C2.00191 20.389 1.11946 20.389 0.57519 19.8379C0.030919 19.2867 0.0309274 18.3931 0.575208 17.842L0.603083 17.8137C1.14736 17.2626 2.02981 17.2626 2.57408 17.8138Z" fill="url(#paint0_linear_981_10577)" />
<path opacity="0.7" fillRule="evenodd" clipRule="evenodd" d="M9.12583 18.2374C9.66912 18.7896 9.66752 19.6832 9.12226 20.2333L5.2617 24.1286C4.71644 24.6787 3.83399 24.6771 3.2907 24.125C2.74741 23.5728 2.74901 22.6792 3.29427 22.1291L7.15483 18.2338C7.70009 17.6837 8.58254 17.6853 9.12583 18.2374Z" fill="url(#paint1_linear_981_10577)" />
<defs>
<linearGradient id="paint0_linear_981_10577" x1="1.57463" y1="17.4004" x2="1.57463" y2="20.2513" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.8" />
<stop offset="1" stopColor="white" stopOpacity="0.5" />
</linearGradient>
<linearGradient id="paint1_linear_981_10577" x1="6.20827" y1="17.8223" x2="6.20827" y2="24.5401" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.8" />
<stop offset="1" stopColor="white" stopOpacity="0.5" />
</linearGradient>
</defs>
</svg>
);
// Progress Bar Component for Section Headers
const SectionProgressBar: React.FC<{ currentSection: number; totalSections: number }> = ({ currentSection, totalSections }) => {
return (
<div className="p-4 bg-[--Neutrals-NeutralSlate100] rounded-[50px] inline-flex justify-center items-center gap-2 overflow-hidden">
{Array.from({ length: 7 }, (_, index) => {
const isActive = index === 0; // First step is always active for section start
return (
<div key={index}>
{index === 0 ? (
<div className="w-6 h-1 bg-[--Brand-Orange] rounded-3xl" />
) : (
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
)}
</div>
);
})}
</div>
);
};
// Yes/No Choice Component
const YesNoChoice: React.FC<{
question: string;
value?: string;
onChange: (value: string) => void;
onBack?: () => void;
onNext: () => void;
onSkip?: () => void;
currentStep?: number;
totalSteps?: number;
}> = ({ question, value, onChange, onBack, onNext, onSkip, currentStep, totalSteps }) => {
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0] inline-flex flex-col justify-center items-center gap-9">
<div className="w-full max-w-[464px] min-w-[464px] flex flex-col justify-start items-start gap-12">
<div className="self-stretch flex flex-col justify-start items-start gap-8">
<div className="self-stretch text-center justify-start text-[--Neutrals-NeutralSlate950] text-2xl font-medium font-['Neue_Montreal'] leading-normal">{question}</div>
<div className="self-stretch inline-flex justify-center items-center gap-3">
<div
onClick={() => onChange('No')}
className={`w-20 h-20 relative rounded-[999px] overflow-hidden cursor-pointer transition-colors ${value === 'No' ? 'bg-[--Neutrals-NeutralSlate800]' : 'bg-[--Neutrals-NeutralSlate100] hover:bg-[--Neutrals-NeutralSlate800]'}`}
>
<div className={`absolute inset-0 flex items-center justify-center text-center text-base font-normal font-['Inter'] leading-normal ${value === 'No' ? 'text-[--Neutrals-NeutralSlate0]' : 'text-[--Neutrals-NeutralSlate0]'}`}>
No
</div>
</div>
<div
onClick={() => onChange('Yes')}
className={`w-20 h-20 relative rounded-[999px] overflow-hidden cursor-pointer transition-colors ${value === 'Yes' ? 'bg-[--Neutrals-NeutralSlate800]' : 'bg-[--Neutrals-NeutralSlate100] hover:bg-[--Neutrals-NeutralSlate800]'}`}
>
<div className={`absolute inset-0 flex items-center justify-center text-center text-base font-normal font-['Inter'] leading-normal ${value === 'Yes' ? 'text-[--Neutrals-NeutralSlate0]' : 'text-[--Neutrals-NeutralSlate0]'}`}>
Yes
</div>
</div>
</div>
</div>
<div className="self-stretch inline-flex justify-start items-start gap-2">
{onBack && (
<button
onClick={onBack}
className="h-12 px-8 py-3.5 bg-[--Neutrals-NeutralSlate100] rounded-[999px] flex justify-center items-center gap-1 overflow-hidden hover:bg-[--Neutrals-NeutralSlate100]"
>
<div className="px-1 flex justify-center items-center">
<div className="justify-center text-[--Neutrals-NeutralSlate950] text-sm font-medium font-['Inter'] leading-tight">Back</div>
</div>
</button>
)}
<button
onClick={onNext}
disabled={!value}
className="flex-1 h-12 px-4 py-3.5 bg-[--Brand-Orange] rounded-[999px] outline outline-2 outline-offset-[-2px] outline-blue-400 flex justify-center items-center gap-1 overflow-hidden disabled:opacity-50 disabled:cursor-not-allowed"
>
<div className="px-1 flex justify-center items-center">
<div className="justify-center text-Other-White text-sm font-medium font-['Inter'] leading-tight">Next</div>
</div>
</button>
</div>
</div>
{/* Skip button */}
{onSkip && (
<div
onClick={onSkip}
className="px-3 py-1.5 left-[1363px] top-[24px] absolute bg-[--Neutrals-NeutralSlate100] rounded-[50px] inline-flex justify-center items-center gap-2 overflow-hidden cursor-pointer hover:bg-[--Neutrals-NeutralSlate100]"
>
<div className="justify-start text-[--Neutrals-NeutralSlate500] text-sm font-medium font-['Inter'] leading-none">Skip</div>
</div>
)}
{/* Progress indicators */}
{currentStep && totalSteps && (
<>
<div className="px-3 py-1.5 left-[24px] top-[24px] absolute bg-[--Neutrals-NeutralSlate100] rounded-[50px] inline-flex justify-center items-center gap-2 overflow-hidden">
<div className="justify-start text-[--Neutrals-NeutralSlate500] text-sm font-medium font-['Inter'] uppercase leading-none">{currentStep} of {totalSteps}</div>
</div>
<div className="w-[464px] max-w-[464px] min-w-[464px] left-[488px] top-[24px] absolute flex flex-col justify-start items-center gap-4">
<SectionProgressBar currentSection={currentStep} totalSections={totalSteps} />
<div className="self-stretch text-center justify-start text-[--Neutrals-NeutralSlate500] text-base font-medium font-['Neue_Montreal'] leading-normal">Leadership & Organizational Structure</div>
</div>
</>
)}
</div>
);
};
// Section Intro Component - From EmployeeFormsController
const SectionIntro: React.FC<{
sectionNumber: string;
title: string;
description: string;
onStart: () => void;
imageUrl?: string;
}> = ({ sectionNumber, title, description, onStart, imageUrl = "https://placehold.co/560x682" }) => {
return (
<div className="w-[1440px] bg-white inline-flex justify-start items-center overflow-hidden">
<div className="flex-1 h-[810px] px-32 py-48 bg-[--Neutrals-NeutralSlate0] flex justify-center items-center gap-2.5 overflow-hidden">
<div className="flex-1 max-w-[464px] inline-flex flex-col justify-start items-start gap-12">
<div className="self-stretch flex flex-col justify-start items-start gap-6">
<div className="w-12 h-12 relative bg-[--Brand-Orange] rounded-xl outline outline-2 outline-offset-[-2px] outline-blue-400 overflow-hidden">
<div className="w-12 h-12 left-0 top-0 absolute bg-gradient-to-b from-white/0 to-white/10" />
<div className="left-[12px] top-[9.33px] absolute">
<AuditlyIcon />
</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-4">
<div className="px-3 py-1.5 bg-[--Neutrals-NeutralSlate100] rounded-[50px] inline-flex justify-center items-center gap-2 overflow-hidden">
<div className="justify-start text-[--Neutrals-NeutralSlate500] text-sm font-medium font-['Inter'] uppercase leading-none">{sectionNumber}</div>
</div>
<div className="self-stretch justify-start text-[--Neutrals-NeutralSlate800] text-5xl font-medium font-['Neue_Montreal'] leading-[48px]">{title}</div>
<div className="self-stretch justify-center text-[--Neutrals-NeutralSlate500] text-base font-normal font-['Inter'] leading-normal">{description}</div>
</div>
</div>
<button
onClick={onStart}
className="self-stretch px-4 py-3.5 bg-[--Brand-Orange] rounded-[999px] outline outline-2 outline-offset-[-2px] outline-blue-400 inline-flex justify-center items-center gap-1 overflow-hidden"
>
<div className="px-1 flex justify-center items-center">
<div className="justify-center text-Other-White text-sm font-medium font-['Inter'] leading-tight">Start</div>
</div>
</button>
</div>
</div>
<div className="flex-1 h-[810px] px-20 py-16 flex justify-center items-center gap-2.5 overflow-hidden">
<div className="flex-1 self-stretch origin-top-left rotate-180 rounded-3xl inline-flex flex-col justify-center items-center gap-2.5 overflow-hidden">
<img className="self-stretch flex-1" src={imageUrl} alt={title} />
</div>
</div>
</div>
);
};
// Step 1: Welcome & Role Information - From EmployeeFormsController
const EmployeeFormStep1: React.FC<{ onNext: (data: any) => void }> = ({ onNext }) => {
const [formData, setFormData] = useState({
name: '',
role: '',
department: ''
});
const handleSubmit = () => {
onNext(formData);
};
return (
<div className="w-[1440px] bg-white inline-flex justify-start items-center overflow-hidden">
<div className="flex-1 h-[810px] px-32 py-48 bg-[--Neutrals-NeutralSlate0] flex justify-center items-center gap-2.5 overflow-hidden">
<div className="flex-1 max-w-[464px] inline-flex flex-col justify-start items-start gap-12">
<div className="self-stretch flex flex-col justify-start items-start gap-6">
<div className="w-12 h-12 relative bg-[--Brand-Orange] rounded-xl outline outline-2 outline-offset-[-2px] outline-blue-400 overflow-hidden">
<div className="w-12 h-12 left-0 top-0 absolute bg-gradient-to-b from-white/0 to-white/10" />
<div className="left-[12px] top-[9.33px] absolute">
<AuditlyIcon />
</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-3">
<div className="self-stretch justify-start text-[--Neutrals-NeutralSlate950] text-2xl font-semibold font-['Inter'] leading-8">Welcome to the Auditly Employee Assessment</div>
<div className="self-stretch justify-start text-[--Neutrals-NeutralSlate500] text-base font-normal font-['Inter'] leading-normal">Let's learn about your role, contribution and help us get a better understand of how you work best.</div>
</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-8">
<div className="self-stretch flex flex-col justify-start items-start gap-6">
<div className="self-stretch flex flex-col justify-start items-start gap-2">
<div className="self-stretch inline-flex justify-start items-center gap-0.5">
<div className="justify-start text-[--Neutrals-NeutralSlate950] text-sm font-normal font-['Inter'] leading-tight">Your Role & Output</div>
</div>
<div className="self-stretch justify-start text-[--Neutrals-NeutralSlate500] text-sm font-normal font-['Inter'] leading-tight">Tell us about your current role and what you work on</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-2">
<div className="self-stretch inline-flex justify-start items-center gap-0.5">
<div className="justify-start text-[--Neutrals-NeutralSlate900] text-sm font-normal font-['Inter'] leading-tight">Your Name</div>
<div className="justify-start text-[--Brand-Orange] text-sm font-medium font-['Inter'] leading-tight">*</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-1">
<div className="self-stretch px-4 py-3.5 bg-[--Neutrals-NeutralSlate100] rounded-[999px] inline-flex justify-start items-center gap-2 overflow-hidden">
<input
type="text"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
className="flex-1 bg-transparent text-[--Neutrals-NeutralSlate950] text-sm font-normal font-['Inter'] leading-tight placeholder:text-[--Neutrals-NeutralSlate950] outline-none"
placeholder="Enter your full name"
/>
</div>
</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-2">
<div className="self-stretch inline-flex justify-start items-center gap-0.5">
<div className="justify-start text-[--Neutrals-NeutralSlate900] text-sm font-normal font-['Inter'] leading-tight">What is your role at the company?</div>
<div className="justify-start text-[--Brand-Orange] text-sm font-medium font-['Inter'] leading-tight">*</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-1">
<div className="self-stretch px-4 py-3.5 bg-[--Neutrals-NeutralSlate100] rounded-[999px] inline-flex justify-start items-center gap-2 overflow-hidden">
<input
type="text"
value={formData.role}
onChange={(e) => setFormData({ ...formData, role: e.target.value })}
className="flex-1 bg-transparent text-[--Neutrals-NeutralSlate950] text-sm font-normal font-['Inter'] leading-tight placeholder:text-[--Neutrals-NeutralSlate950] outline-none"
placeholder="e.g. Software Engineer, Marketing Manager"
/>
</div>
</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-2">
<div className="self-stretch inline-flex justify-start items-center gap-0.5">
<div className="justify-start text-[--Neutrals-NeutralSlate900] text-sm font-normal font-['Inter'] leading-tight">What department do you work in?</div>
<div className="justify-start text-[--Brand-Orange] text-sm font-medium font-['Inter'] leading-tight">*</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-1">
<div className="self-stretch px-4 py-3.5 bg-[--Neutrals-NeutralSlate100] rounded-[999px] inline-flex justify-start items-center gap-2 overflow-hidden">
<input
type="text"
value={formData.department}
onChange={(e) => setFormData({ ...formData, department: e.target.value })}
className="flex-1 bg-transparent text-[--Neutrals-NeutralSlate950] text-sm font-normal font-['Inter'] leading-tight placeholder:text-[--Neutrals-NeutralSlate950] outline-none"
placeholder="e.g. Engineering, Sales, Marketing"
/>
</div>
</div>
</div>
</div>
<div className="self-stretch inline-flex justify-start items-center gap-3">
<button
onClick={handleSubmit}
disabled={!formData.name || !formData.role || !formData.department}
className="flex-1 px-6 py-3.5 bg-[--Brand-Orange] rounded-[999px] inline-flex justify-center items-center gap-2 overflow-hidden disabled:opacity-50 disabled:cursor-not-allowed"
>
<div className="justify-center text-[--Neutrals-NeutralSlate0] text-base font-medium font-['Inter'] leading-normal">Continue</div>
</button>
</div>
</div>
</div>
</div>
</div>
);
};
// Step 2: Personal Information
const EmployeeFormStep2: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [formData, setFormData] = useState({
email: '',
name: '',
company: ''
});
return (
<div className="w-[1440px] h-[810px] px-[488px] py-32 bg-[--Neutrals-NeutralSlate0] inline-flex flex-col justify-center items-center gap-9">
<div className="w-full max-w-[464px] min-w-[464px] flex flex-col justify-start items-start gap-12">
<div className="self-stretch flex flex-col justify-start items-start gap-8">
<div className="self-stretch text-center justify-start text-[--Neutrals-NeutralSlate950] text-2xl font-medium font-['Neue_Montreal'] leading-normal">Personal Information</div>
<div className="self-stretch flex flex-col justify-start items-start gap-6">
<div className="self-stretch flex flex-col justify-start items-start gap-2">
<div className="self-stretch inline-flex justify-start items-center gap-0.5">
<div className="justify-start text-[--Neutrals-NeutralSlate900] text-sm font-normal font-['Inter'] leading-tight">Email</div>
<div className="justify-start text-[--Brand-Orange] text-sm font-medium font-['Inter'] leading-tight">*</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-1">
<div className="self-stretch px-4 py-3.5 bg-[--Neutrals-NeutralSlate100] rounded-[999px] inline-flex justify-start items-center gap-2 overflow-hidden">
<input
type="email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
className="flex-1 bg-transparent text-[--Neutrals-NeutralSlate950] text-sm font-normal font-['Inter'] leading-tight placeholder:text-[--Neutrals-NeutralSlate950] outline-none"
placeholder="Email@gmail.com"
/>
</div>
</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-2">
<div className="self-stretch inline-flex justify-start items-center gap-0.5">
<div className="justify-start text-[--Neutrals-NeutralSlate900] text-sm font-normal font-['Inter'] leading-tight">Your Name</div>
<div className="justify-start text-[--Brand-Orange] text-sm font-medium font-['Inter'] leading-tight">*</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-1">
<div className="self-stretch px-4 py-3.5 bg-[--Neutrals-NeutralSlate100] rounded-[999px] inline-flex justify-start items-center gap-2 overflow-hidden">
<input
type="text"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
className="flex-1 bg-transparent text-[--Neutrals-NeutralSlate950] text-sm font-normal font-['Inter'] leading-tight placeholder:text-[--Neutrals-NeutralSlate950] outline-none"
placeholder="John Doe"
/>
</div>
</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-2">
<div className="self-stretch inline-flex justify-start items-center gap-0.5">
<div className="justify-start text-[--Neutrals-NeutralSlate900] text-sm font-normal font-['Inter'] leading-tight">What is the name of your Company and department?</div>
<div className="justify-start text-[--Brand-Orange] text-sm font-medium font-['Inter'] leading-tight">*</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-1">
<div className="self-stretch px-4 py-3.5 bg-[--Neutrals-NeutralSlate100] rounded-[999px] inline-flex justify-start items-center gap-2 overflow-hidden">
<input
type="text"
value={formData.company}
onChange={(e) => setFormData({ ...formData, company: e.target.value })}
className="flex-1 bg-transparent text-[--Neutrals-NeutralSlate950] text-sm font-normal font-['Inter'] leading-tight placeholder:text-[--Neutrals-NeutralSlate950] outline-none"
placeholder="Doe Enterprises"
/>
</div>
</div>
</div>
</div>
</div>
<div className="self-stretch inline-flex justify-start items-center gap-3">
<button
onClick={onBack}
className="flex-1 px-4 py-3.5 bg-[--Neutrals-NeutralSlate100] rounded-[999px] inline-flex justify-center items-center gap-1 overflow-hidden"
>
<div className="justify-center text-[--Neutrals-NeutralSlate800] text-sm font-medium font-['Inter'] leading-tight">Back</div>
</button>
<button
onClick={() => onNext(formData)}
disabled={!formData.email || !formData.name || !formData.company}
className="flex-1 h-12 px-4 py-3.5 bg-[--Brand-Orange] rounded-[999px] outline outline-2 outline-offset-[-2px] outline-blue-400 inline-flex justify-center items-center gap-1 overflow-hidden disabled:opacity-50 disabled:cursor-not-allowed"
>
<div className="px-1 flex justify-center items-center">
<div className="justify-center text-Other-White text-sm font-medium font-['Inter'] leading-tight">Next</div>
</div>
</button>
</div>
</div>
</div>
);
};
// Step 3: Current Title and Department (Text Area)
const EmployeeFormStep3: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="What is your current title and department?"
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ titleAndDepartment: answer })}
onSkip={() => onNext({ titleAndDepartment: '' })}
nextDisabled={!answer.trim()}
currentStep={1}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 4: Daily Tasks (Text Area)
const EmployeeFormStep4: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="Describe your typical daily tasks and responsibilities"
value={answer}
onChange={setAnswer}
placeholder="Describe what you do on a typical day..."
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ dailyTasks: answer })}
onSkip={() => onNext({ dailyTasks: '' })}
nextDisabled={!answer.trim()}
currentStep={2}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 5: Role Understanding Rating
const EmployeeFormStep5: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [rating, setRating] = useState<number | undefined>();
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaRatingScale
question="How clearly do you understand your role and responsibilities?"
leftLabel="Not so much"
rightLabel="Very clear"
value={rating}
onChange={setRating}
scale={8}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ roleUnderstanding: rating })}
onSkip={() => onNext({ roleUnderstanding: null })}
nextDisabled={!rating}
currentStep={3}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 6: Work Satisfaction
const EmployeeFormStep6: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [rating, setRating] = useState<number | undefined>();
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaRatingScale
question="How satisfied are you with your current work environment?"
leftLabel="Not satisfied"
rightLabel="Very satisfied"
value={rating}
onChange={setRating}
scale={10}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ workSatisfaction: rating })}
onSkip={() => onNext({ workSatisfaction: null })}
nextDisabled={!rating}
currentStep={4}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 7: Communication Rating
const EmployeeFormStep7: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [rating, setRating] = useState<number | undefined>();
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaRatingScale
question="How would you rate communication within your team?"
leftLabel="Poor"
rightLabel="Excellent"
value={rating}
onChange={setRating}
scale={10}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ communicationRating: rating })}
onSkip={() => onNext({ communicationRating: null })}
nextDisabled={!rating}
currentStep={5}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 8: Work Style Preference
const EmployeeFormStep8: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [selectedOption, setSelectedOption] = useState<string>('');
const options = [
'I prefer working independently',
'I enjoy collaborative teamwork',
'I like a mix of both',
'I prefer clear instructions and structure',
'I thrive with autonomy and flexibility'
];
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<div className="flex flex-col items-center justify-center h-full">
<div className="w-full max-w-[464px] flex flex-col items-center gap-8">
<h2 className="text-2xl font-medium font-['Neue_Montreal'] text-[--Neutrals-NeutralSlate950] text-center">
What work style best describes you?
</h2>
<div className="w-full flex flex-col gap-3">
{options.map((option, index) => (
<label
key={index}
className="p-4 bg-[--Neutrals-NeutralSlate100] rounded-2xl flex items-center gap-3 cursor-pointer hover:bg-[--Neutrals-NeutralSlate100] transition-colors"
>
<input
type="radio"
name="workStyle"
value={option}
checked={selectedOption === option}
onChange={(e) => setSelectedOption(e.target.value)}
className="w-5 h-5 accent-Brand-Orange"
/>
<span className="text-[--Neutrals-NeutralSlate800] text-sm font-medium font-['Inter']">
{option}
</span>
</label>
))}
</div>
</div>
</div>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ workStyle: selectedOption })}
onSkip={() => onNext({ workStyle: '' })}
nextDisabled={!selectedOption}
currentStep={6}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 9: Section Intro - Output & Accountability
const EmployeeFormStep9: React.FC<{ onNext: () => void }> = ({ onNext }) => {
return (
<SectionIntro
sectionNumber="2 of 6"
title="Output & Accountability"
description="Description about the topic and what it means."
onStart={onNext}
/>
);
};
// Step 10: Weekly Output Rating
const EmployeeFormStep10: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [rating, setRating] = useState<number | undefined>();
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaRatingScale
question="How would you rate your weekly output (volume & quality)?"
leftLabel="Very little"
rightLabel="Very High"
value={rating}
onChange={setRating}
scale={10}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ weeklyOutput: rating })}
onSkip={() => onNext({ weeklyOutput: null })}
nextDisabled={!rating}
currentStep={1}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 11: Top Deliverables
const EmployeeFormStep11: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="What are your top 23 recurring deliverables?"
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ topDeliverables: answer })}
onSkip={() => onNext({ topDeliverables: '' })}
nextDisabled={!answer.trim()}
currentStep={2}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 12: Measurable Results
const EmployeeFormStep12: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="List measurable results you've produced in the last 60 days."
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ measurableResults: answer })}
onSkip={() => onNext({ measurableResults: '' })}
nextDisabled={!answer.trim()}
currentStep={3}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 13: Weekly KPIs
const EmployeeFormStep13: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<YesNoChoice
question="Do you have weekly KPIs or goals?"
value={answer}
onChange={setAnswer}
onBack={onBack}
onNext={() => onNext({ hasKPIs: answer })}
onSkip={() => onNext({ hasKPIs: '' })}
currentStep={4}
totalSteps={7}
/>
);
};
// Step 14: KPI Details
const EmployeeFormStep14: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="If yes: What are they?"
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ kpiDetails: answer })}
onSkip={() => onNext({ kpiDetails: '' })}
currentStep={5}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 15: Reporting Structure
const EmployeeFormStep15: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="Who do you report to? How often do you meet/check-in?"
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ reportingStructure: answer })}
onSkip={() => onNext({ reportingStructure: '' })}
currentStep={6}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 16: Section Intro - Team & Collaboration
const EmployeeFormStep16: React.FC<{ onNext: () => void }> = ({ onNext }) => {
return (
<SectionIntro
sectionNumber="3 of 6"
title="Team & Collaboration"
description="Description about the topic and what it means."
onStart={onNext}
/>
);
};
// Step 17: Work Closest With
const EmployeeFormStep17: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="Who do you work most closely with?"
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ workClosestWith: answer })}
onSkip={() => onNext({ workClosestWith: '' })}
currentStep={1}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 18: Collaboration Issues
const EmployeeFormStep18: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="Describe any collaboration issues, if any?"
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ collaborationIssues: answer })}
onSkip={() => onNext({ collaborationIssues: '' })}
currentStep={2}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 19: Team Communication Rating
const EmployeeFormStep19: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [rating, setRating] = useState<number | undefined>();
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaRatingScale
question="How would you rate team communication overall?"
leftLabel="Poor"
rightLabel="Excellent"
value={rating}
onChange={setRating}
scale={10}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ teamCommunication: rating })}
onSkip={() => onNext({ teamCommunication: null })}
nextDisabled={!rating}
currentStep={3}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 20: Team Support
const EmployeeFormStep20: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="Do you feel supported by your team? How?"
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ teamSupport: answer })}
onSkip={() => onNext({ teamSupport: '' })}
currentStep={4}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 21: Tools and Resources Section
const EmployeeFormStep21: React.FC<{ onNext: () => void }> = ({ onNext }) => {
return (
<SectionIntro
sectionNumber="4 of 6"
title="Tools & Resources"
description="Description about the topic and what it means."
onStart={onNext}
/>
);
};
// Step 22: Current Tools
const EmployeeFormStep22: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="What tools and software do you currently use?"
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ currentTools: answer })}
onSkip={() => onNext({ currentTools: '' })}
currentStep={1}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 23: Tool Effectiveness
const EmployeeFormStep23: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [rating, setRating] = useState<number | undefined>();
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaRatingScale
question="How effective are your current tools?"
leftLabel="Not effective"
rightLabel="Very effective"
value={rating}
onChange={setRating}
scale={10}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ toolEffectiveness: rating })}
onSkip={() => onNext({ toolEffectiveness: null })}
nextDisabled={!rating}
currentStep={2}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 24: Missing Tools
const EmployeeFormStep24: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="What tools or resources are you missing to do your job more effectively?"
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ missingTools: answer })}
onSkip={() => onNext({ missingTools: '' })}
currentStep={3}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 25: Skills & Development Section
const EmployeeFormStep25: React.FC<{ onNext: () => void }> = ({ onNext }) => {
return (
<SectionIntro
sectionNumber="5 of 6"
title="Skills & Development"
description="Description about the topic and what it means."
onStart={onNext}
/>
);
};
// Step 26: Key Skills
const EmployeeFormStep26: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="What are your key skills and strengths?"
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ keySkills: answer })}
onSkip={() => onNext({ keySkills: '' })}
currentStep={1}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 27: Skill Development
const EmployeeFormStep27: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="What skills would you like to develop or improve?"
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ skillDevelopment: answer })}
onSkip={() => onNext({ skillDevelopment: '' })}
currentStep={2}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 28: Training Opportunities
const EmployeeFormStep28: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<YesNoChoice
question="Are you aware of current training opportunities?"
value={answer}
onChange={setAnswer}
onBack={onBack}
onNext={() => onNext({ awareOfTraining: answer })}
onSkip={() => onNext({ awareOfTraining: '' })}
currentStep={3}
totalSteps={7}
/>
);
};
// Step 29: Career Goals
const EmployeeFormStep29: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="What are your career goals within the company?"
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ careerGoals: answer })}
onSkip={() => onNext({ careerGoals: '' })}
currentStep={4}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 30: Feedback & Improvement Section
const EmployeeFormStep30: React.FC<{ onNext: () => void }> = ({ onNext }) => {
return (
<SectionIntro
sectionNumber="6 of 6"
title="Feedback & Improvement"
description="Description about the topic and what it means."
onStart={onNext}
/>
);
};
// Step 31: Company Improvements
const EmployeeFormStep31: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="What improvements would you suggest for the company?"
value={answer}
onChange={setAnswer}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ companyImprovements: answer })}
onSkip={() => onNext({ companyImprovements: '' })}
currentStep={1}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 32: Job Satisfaction
const EmployeeFormStep32: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [rating, setRating] = useState<number | undefined>();
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaRatingScale
question="How satisfied are you with your current job overall?"
leftLabel="Not satisfied"
rightLabel="Very satisfied"
value={rating}
onChange={setRating}
scale={10}
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ jobSatisfaction: rating })}
onSkip={() => onNext({ jobSatisfaction: null })}
nextDisabled={!rating}
currentStep={2}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 33: Additional Feedback
const EmployeeFormStep33: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = useState<string>('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0]">
<FigmaTextArea
question="Any additional feedback or suggestions for the company?"
value={answer}
onChange={setAnswer}
placeholder="Share any thoughts, suggestions, or feedback..."
/>
<div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 w-full max-w-[464px]">
<FigmaNavigationButtons
onBack={onBack}
onNext={() => onNext({ additionalFeedback: answer })}
onSkip={() => onNext({ additionalFeedback: '' })}
currentStep={3}
totalSteps={7}
/>
</div>
</div>
);
};
// Step 35: Leadership & Organizational Structure - Magic Wand Question
const EmployeeFormStep35: React.FC<{ onNext: () => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = React.useState('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0] inline-flex flex-col justify-center items-center gap-9">
<div className="w-full max-w-[464px] min-w-[464px] flex flex-col justify-start items-start gap-12">
<div className="self-stretch flex flex-col justify-start items-start gap-8">
<div className="self-stretch text-center justify-start text-[--Neutrals-NeutralSlate950] text-2xl font-medium font-['Neue_Montreal'] leading-normal">If you had a magic wand, what would you change about how we operate?</div>
<div className="self-stretch min-h-40 p-5 relative bg-[--Neutrals-NeutralSlate100] rounded-xl inline-flex justify-start items-start gap-2.5">
<textarea
value={answer}
onChange={(e) => setAnswer(e.target.value)}
className="flex-1 bg-transparent text-[--Neutrals-NeutralSlate950] text-base font-normal font-['Inter'] leading-normal placeholder:text-[--Neutrals-NeutralSlate950] outline-none resize-none"
placeholder="Type your answer...."
rows={6}
/>
<div className="w-3 h-3 absolute right-5 bottom-5">
<div className="w-2 h-2 absolute top-0.5 left-0.5 outline outline-1 outline-offset-[-0.50px] outline-[--$1]" />
<div className="w-1 h-1 absolute bottom-0 right-0 outline outline-1 outline-offset-[-0.50px] outline-[--$1]" />
</div>
</div>
</div>
<div className="self-stretch inline-flex justify-start items-start gap-2">
<button
onClick={onBack}
className="h-12 px-8 py-3.5 bg-[--Neutrals-NeutralSlate100] rounded-[999px] flex justify-center items-center gap-1 overflow-hidden hover:bg-[--Neutrals-NeutralSlate100]"
>
<div className="px-1 flex justify-center items-center">
<div className="justify-center text-[--Neutrals-NeutralSlate950] text-sm font-medium font-['Inter'] leading-tight">Back</div>
</div>
</button>
<button
onClick={onNext}
className="flex-1 h-12 px-4 py-3.5 bg-[--Brand-Orange] rounded-[999px] outline outline-2 outline-offset-[-2px] outline-blue-400 flex justify-center items-center gap-1 overflow-hidden"
>
<div className="px-1 flex justify-center items-center">
<div className="justify-center text-Other-White text-sm font-medium font-['Inter'] leading-tight">Next</div>
</div>
</button>
</div>
</div>
<div className="px-3 py-1.5 left-[24px] top-[24px] absolute bg-[--Neutrals-NeutralSlate100] rounded-[50px] inline-flex justify-center items-center gap-2 overflow-hidden">
<div className="justify-start text-[--Neutrals-NeutralSlate500] text-sm font-medium font-['Inter'] uppercase leading-none">1 of 7</div>
</div>
<div className="px-3 py-1.5 left-[1363px] top-[24px] absolute bg-[--Neutrals-NeutralSlate100] rounded-[50px] inline-flex justify-center items-center gap-2 overflow-hidden">
<div className="justify-start text-[--Neutrals-NeutralSlate500] text-sm font-medium font-['Inter'] leading-none">Skip</div>
</div>
<div className="w-[464px] max-w-[464px] min-w-[464px] left-[488px] top-[24px] absolute flex flex-col justify-start items-center gap-4">
<div className="p-4 bg-[--Neutrals-NeutralSlate100] rounded-[50px] inline-flex justify-center items-center gap-2 overflow-hidden">
<div>
<svg width="24" height="4" viewBox="0 0 24 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="24" height="4" rx="2" fill="var(--Brand-Orange, #3399FF)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
</div>
<div className="self-stretch text-center justify-start text-[--Neutrals-NeutralSlate500] text-base font-medium font-['Neue_Montreal'] leading-normal">Leadership & Organizational Structure</div>
</div>
</div>
);
};
// Step 36: Overstaffed/Underperforming Departments
const EmployeeFormStep36: React.FC<{ onNext: () => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = React.useState('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0] inline-flex flex-col justify-center items-center gap-9">
<div className="w-full max-w-[464px] min-w-[464px] flex flex-col justify-start items-start gap-12">
<div className="self-stretch flex flex-col justify-start items-start gap-8">
<div className="self-stretch text-center justify-start text-[--Neutrals-NeutralSlate950] text-2xl font-medium font-['Neue_Montreal'] leading-normal">Do you believe any roles or departments are overstaffed or underperforming?</div>
<div className="self-stretch min-h-40 p-5 relative bg-[--Neutrals-NeutralSlate100] rounded-xl inline-flex justify-start items-start gap-2.5">
<textarea
value={answer}
onChange={(e) => setAnswer(e.target.value)}
className="flex-1 bg-transparent text-[--Neutrals-NeutralSlate950] text-base font-normal font-['Inter'] leading-normal placeholder:text-[--Neutrals-NeutralSlate950] outline-none resize-none"
placeholder="Type your answer...."
rows={6}
/>
<div className="w-3 h-3 absolute right-5 bottom-5">
<div className="w-2 h-2 absolute top-0.5 left-0.5 outline outline-1 outline-offset-[-0.50px] outline-[--$1]" />
<div className="w-1 h-1 absolute bottom-0 right-0 outline outline-1 outline-offset-[-0.50px] outline-[--$1]" />
</div>
</div>
</div>
<div className="self-stretch inline-flex justify-start items-start gap-2">
<button
onClick={onBack}
className="h-12 px-8 py-3.5 bg-[--Neutrals-NeutralSlate100] rounded-[999px] flex justify-center items-center gap-1 overflow-hidden hover:bg-[--Neutrals-NeutralSlate100]"
>
<div className="px-1 flex justify-center items-center">
<div className="justify-center text-[--Neutrals-NeutralSlate950] text-sm font-medium font-['Inter'] leading-tight">Back</div>
</div>
</button>
<button
onClick={onNext}
className="flex-1 h-12 px-4 py-3.5 bg-[--Brand-Orange] rounded-[999px] outline outline-2 outline-offset-[-2px] outline-blue-400 flex justify-center items-center gap-1 overflow-hidden"
>
<div className="px-1 flex justify-center items-center">
<div className="justify-center text-Other-White text-sm font-medium font-['Inter'] leading-tight">Next</div>
</div>
</button>
</div>
</div>
<div className="px-3 py-1.5 left-[24px] top-[24px] absolute bg-[--Neutrals-NeutralSlate100] rounded-[50px] inline-flex justify-center items-center gap-2 overflow-hidden">
<div className="justify-start text-[--Neutrals-NeutralSlate500] text-sm font-medium font-['Inter'] uppercase leading-none">1 of 7</div>
</div>
<div className="px-3 py-1.5 left-[1363px] top-[24px] absolute bg-[--Neutrals-NeutralSlate100] rounded-[50px] inline-flex justify-center items-center gap-2 overflow-hidden">
<div className="justify-start text-[--Neutrals-NeutralSlate500] text-sm font-medium font-['Inter'] leading-none">Skip</div>
</div>
<div className="w-[464px] max-w-[464px] min-w-[464px] left-[488px] top-[24px] absolute flex flex-col justify-start items-center gap-4">
<div className="p-4 bg-[--Neutrals-NeutralSlate100] rounded-[50px] inline-flex justify-center items-center gap-2 overflow-hidden">
<div>
<svg width="24" height="4" viewBox="0 0 24 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="24" height="4" rx="2" fill="var(--Brand-Orange, #3399FF)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
</div>
<div className="self-stretch text-center justify-start text-[--Neutrals-NeutralSlate500] text-base font-medium font-['Neue_Montreal'] leading-normal">Leadership & Organizational Structure</div>
</div>
</div>
);
};
// Step 37: Any Other Feedback
const EmployeeFormStep37: React.FC<{ onNext: () => void; onBack: () => void }> = ({ onNext, onBack }) => {
const [answer, setAnswer] = React.useState('');
return (
<div className="w-[1440px] h-[810px] py-6 relative bg-[--Neutrals-NeutralSlate0] inline-flex flex-col justify-center items-center gap-9">
<div className="w-full max-w-[464px] min-w-[464px] flex flex-col justify-start items-start gap-12">
<div className="self-stretch flex flex-col justify-start items-start gap-8">
<div className="self-stretch text-center justify-start text-[--Neutrals-NeutralSlate950] text-2xl font-medium font-['Neue_Montreal'] leading-normal">Any other feedback or suggestions?</div>
<div className="self-stretch min-h-40 p-5 relative bg-[--Neutrals-NeutralSlate100] rounded-xl inline-flex justify-start items-start gap-2.5">
<textarea
value={answer}
onChange={(e) => setAnswer(e.target.value)}
className="flex-1 bg-transparent text-[--Neutrals-NeutralSlate950] text-base font-normal font-['Inter'] leading-normal placeholder:text-[--Neutrals-NeutralSlate950] outline-none resize-none"
placeholder="Type your answer...."
rows={6}
/>
<div className="w-3 h-3 absolute right-5 bottom-5">
<div className="w-2 h-2 absolute top-0.5 left-0.5 outline outline-1 outline-offset-[-0.50px] outline-[--$1]" />
<div className="w-1 h-1 absolute bottom-0 right-0 outline outline-1 outline-offset-[-0.50px] outline-[--$1]" />
</div>
</div>
</div>
<div className="self-stretch inline-flex justify-start items-start gap-2">
<button
onClick={onBack}
className="h-12 px-8 py-3.5 bg-[--Neutrals-NeutralSlate100] rounded-[999px] flex justify-center items-center gap-1 overflow-hidden hover:bg-[--Neutrals-NeutralSlate100]"
>
<div className="px-1 flex justify-center items-center">
<div className="justify-center text-[--Neutrals-NeutralSlate950] text-sm font-medium font-['Inter'] leading-tight">Back</div>
</div>
</button>
<button
onClick={onNext}
className="flex-1 h-12 px-4 py-3.5 bg-[--Brand-Orange] rounded-[999px] outline outline-2 outline-offset-[-2px] outline-blue-400 flex justify-center items-center gap-1 overflow-hidden"
>
<div className="px-1 flex justify-center items-center">
<div className="justify-center text-Other-White text-sm font-medium font-['Inter'] leading-tight">Submit</div>
</div>
</button>
</div>
</div>
<div className="px-3 py-1.5 left-[24px] top-[24px] absolute bg-[--Neutrals-NeutralSlate100] rounded-[50px] inline-flex justify-center items-center gap-2 overflow-hidden">
<div className="justify-start text-[--Neutrals-NeutralSlate500] text-sm font-medium font-['Inter'] uppercase leading-none">1 of 7</div>
</div>
<div className="px-3 py-1.5 left-[1363px] top-[24px] absolute bg-[--Neutrals-NeutralSlate100] rounded-[50px] inline-flex justify-center items-center gap-2 overflow-hidden">
<div className="justify-start text-[--Neutrals-NeutralSlate500] text-sm font-medium font-['Inter'] leading-none">Skip</div>
</div>
<div className="w-[464px] max-w-[464px] min-w-[464px] left-[488px] top-[24px] absolute flex flex-col justify-start items-center gap-4">
<div className="p-4 bg-[--Neutrals-NeutralSlate100] rounded-[50px] inline-flex justify-center items-center gap-2 overflow-hidden">
<div>
<svg width="24" height="4" viewBox="0 0 24 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="24" height="4" rx="2" fill="var(--Brand-Orange, #3399FF)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
<div>
<svg width="4" height="4" viewBox="0 0 4 4" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="4" height="4" rx="2" fill="var(--Neutrals-NeutralSlate300, #D5D7DA)" />
</svg>
</div>
</div>
<div className="self-stretch text-center justify-start text-[--Neutrals-NeutralSlate500] text-base font-medium font-['Neue_Montreal'] leading-normal">Leadership & Organizational Structure</div>
</div>
</div>
);
};
// Step 38: Thank You Page (Final)
const EmployeeFormStep38: React.FC<{ formData: any }> = ({ formData }) => {
return (
<div className="w-[1440px] bg-white inline-flex justify-start items-center overflow-hidden">
<div className="flex-1 h-[810px] px-32 py-48 bg-[--Neutrals-NeutralSlate0] flex justify-center items-center gap-2.5 overflow-hidden">
<div className="flex-1 max-w-[464px] inline-flex flex-col justify-start items-start gap-12">
<div className="self-stretch flex flex-col justify-start items-start gap-6">
<div className="w-12 h-12 relative bg-[--Brand-Orange] rounded-xl outline outline-2 outline-offset-[-2px] outline-blue-400 overflow-hidden">
<div className="w-12 h-12 left-0 top-0 absolute bg-gradient-to-b from-white/0 to-white/10" />
<div className="left-[12px] top-[9.33px] absolute">
<svg width="24" height="30" viewBox="0 0 24 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.5" fillRule="evenodd" clipRule="evenodd" d="M2.57506 17.8138C3.11933 18.3649 3.11932 19.2585 2.57504 19.8097L2.54716 19.8379C2.00288 20.389 1.12044 20.389 0.576166 19.8379C0.0318956 19.2867 0.031904 18.3931 0.576185 17.842L0.604059 17.8137C1.14834 17.2626 2.03079 17.2626 2.57506 17.8138Z" fill="url(#paint0_linear_984_13079)" />
<path opacity="0.7" fillRule="evenodd" clipRule="evenodd" d="M9.12631 18.2374C9.6696 18.7896 9.66801 19.6832 9.12275 20.2333L5.26219 24.1286C4.71693 24.6787 3.83448 24.6771 3.29119 24.125C2.7479 23.5728 2.7495 22.6792 3.29476 22.1291L7.15532 18.2338C7.70058 17.6837 8.58302 17.6853 9.12631 18.2374Z" fill="url(#paint1_linear_984_13079)" />
<path opacity="0.5" fillRule="evenodd" clipRule="evenodd" d="M14.3651 24.9431C14.792 24.2945 15.6574 24.1193 16.2978 24.5516L16.3814 24.6081C17.0219 25.0404 17.1949 25.9167 16.768 26.5652C16.341 27.2138 15.4757 27.389 14.8352 26.9567L14.7516 26.9002C14.1112 26.4678 13.9381 25.5916 14.3651 24.9431Z" fill="url(#paint2_linear_984_13079)" />
<path opacity="0.7" fillRule="evenodd" clipRule="evenodd" d="M23.5637 17.7278C24.108 18.279 24.108 19.1726 23.5637 19.7237L21.6683 21.6431C21.124 22.1943 20.2415 22.1943 19.6973 21.6431C19.153 21.092 19.153 20.1984 19.6973 19.6472L21.5927 17.7278C22.137 17.1767 23.0194 17.1767 23.5637 17.7278Z" fill="url(#paint3_linear_984_13079)" />
<path fillRule="evenodd" clipRule="evenodd" d="M23.593 10.6302C24.1373 11.1813 24.1373 12.0749 23.593 12.6261L9.58624 26.8098C9.04196 27.361 8.15951 27.361 7.61524 26.8098C7.07096 26.2587 7.07096 25.3651 7.61524 24.8139L21.622 10.6302C22.1663 10.079 23.0487 10.079 23.593 10.6302Z" fill="url(#paint4_linear_984_13079)" />
<path fillRule="evenodd" clipRule="evenodd" d="M20.9426 6.26883C21.4869 6.81999 21.4869 7.71359 20.9426 8.26474L12.887 16.4222C12.3427 16.9733 11.4603 16.9733 10.916 16.4222C10.3717 15.871 10.3717 14.9774 10.916 14.4263L18.9716 6.26883C19.5159 5.71768 20.3984 5.71768 20.9426 6.26883Z" fill="url(#paint5_linear_984_13079)" />
<path fillRule="evenodd" clipRule="evenodd" d="M16.6908 3.50254C17.2354 4.05332 17.236 4.94692 16.6921 5.49844L6.3369 15.9987C5.79299 16.5502 4.91054 16.5508 4.3659 16C3.82126 15.4492 3.82067 14.5556 4.36458 14.0041L14.7198 3.50388C15.2637 2.95236 16.1462 2.95176 16.6908 3.50254Z" fill="url(#paint6_linear_984_13079)" />
<path opacity="0.7" fillRule="evenodd" clipRule="evenodd" d="M6.43658 6.86235C6.97992 7.41445 6.9784 8.30805 6.43319 8.85825L2.37751 12.9511C1.83229 13.5013 0.94985 13.4997 0.406512 12.9476C-0.136826 12.3955 -0.135307 11.5019 0.409905 10.9517L4.46559 6.85892C5.0108 6.30871 5.89324 6.31025 6.43658 6.86235Z" fill="url(#paint7_linear_984_13079)" />
<path opacity="0.5" fillRule="evenodd" clipRule="evenodd" d="M8.92105 2.7793C9.69077 2.7793 10.3148 3.41117 10.3148 4.19062V4.33175C10.3148 5.1112 9.69077 5.74307 8.92105 5.74307C8.15133 5.74307 7.52734 5.1112 7.52734 4.33175V4.19062C7.52734 3.41117 8.15133 2.7793 8.92105 2.7793Z" fill="url(#paint8_linear_984_13079)" />
<defs>
<linearGradient id="paint0_linear_984_13079" x1="1.57561" y1="17.4004" x2="1.57561" y2="20.2513" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.8" />
<stop offset="1" stopColor="white" stopOpacity="0.5" />
</linearGradient>
<linearGradient id="paint1_linear_984_13079" x1="6.20875" y1="17.8223" x2="6.20875" y2="24.5401" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.8" />
<stop offset="1" stopColor="white" stopOpacity="0.5" />
</linearGradient>
<linearGradient id="paint2_linear_984_13079" x1="15.5665" y1="24.3145" x2="15.5665" y2="27.1938" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.8" />
<stop offset="1" stopColor="white" stopOpacity="0.5" />
</linearGradient>
<linearGradient id="paint3_linear_984_13079" x1="21.6305" y1="17.3145" x2="21.6305" y2="22.0565" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.8" />
<stop offset="1" stopColor="white" stopOpacity="0.5" />
</linearGradient>
<linearGradient id="paint4_linear_984_13079" x1="15.6041" y1="10.2168" x2="15.6041" y2="27.2232" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.8" />
<stop offset="1" stopColor="white" stopOpacity="0.5" />
</linearGradient>
<linearGradient id="paint5_linear_984_13079" x1="15.9293" y1="5.85547" x2="15.9293" y2="16.8355" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.8" />
<stop offset="1" stopColor="white" stopOpacity="0.5" />
</linearGradient>
<linearGradient id="paint6_linear_984_13079" x1="10.5284" y1="3.08984" x2="10.5284" y2="16.4127" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.8" />
<stop offset="1" stopColor="white" stopOpacity="0.5" />
</linearGradient>
<linearGradient id="paint7_linear_984_13079" x1="3.42155" y1="6.44727" x2="3.42155" y2="13.3627" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.8" />
<stop offset="1" stopColor="white" stopOpacity="0.5" />
</linearGradient>
<linearGradient id="paint8_linear_984_13079" x1="8.92105" y1="2.7793" x2="8.92105" y2="5.74307" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.8" />
<stop offset="1" stopColor="white" stopOpacity="0.5" />
</linearGradient>
</defs>
</svg>
</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-4">
<div className="self-stretch justify-start text-[--Neutrals-NeutralSlate800] text-5xl font-medium font-['Neue_Montreal'] leading-[48px]">Thank you your form has been submitted!</div>
<div className="self-stretch justify-center text-[--Neutrals-NeutralSlate500] text-base font-normal font-['Inter'] leading-normal">Description about the topic and what it means.</div>
</div>
</div>
<div className="self-stretch px-4 py-3.5 bg-[--Brand-Orange] rounded-[999px] outline outline-2 outline-offset-[-2px] outline-blue-400 inline-flex justify-center items-center gap-1 overflow-hidden">
<div className="px-1 flex justify-center items-center">
<div className="justify-center text-Other-White text-sm font-medium font-['Inter'] leading-tight">Start</div>
</div>
</div>
</div>
</div>
<div className="flex-1 h-[810px] px-20 py-16 flex justify-center items-center gap-2.5 overflow-hidden">
<div className="flex-1 self-stretch origin-top-left rotate-180 rounded-3xl inline-flex flex-col justify-center items-center gap-2.5 overflow-hidden">
<img className="self-stretch flex-1" src="https://placehold.co/560x682" />
</div>
</div>
</div>
);
};
// Step 34: Section Outro - Leadership & Organizational Structure
const EmployeeFormStep34: React.FC<{ onNext: () => void; onBack: () => void }> = ({ onNext, onBack }) => {
return (
<SectionIntro
sectionNumber="7 of 7"
title="Leadership & Organizational Structure"
description="Now we'll explore your thoughts on our organizational structure and leadership effectiveness."
onStart={onNext}
/>
);
};
// Main Controller Component with Backend Integration - Merged Logic
const EmployeeQuestionnaire: React.FC = () => {
const navigate = useNavigate();
const location = useLocation();
const params = useParams();
const { user } = useAuth();
// Check if this is an invite-based flow (no auth/org needed)
const inviteCode = params.inviteCode;
const isInviteFlow = !!inviteCode;
// Only use org context for authenticated flows
let submitEmployeeAnswers, generateEmployeeReport, employees;
if (!isInviteFlow) {
const orgContext = useOrg();
({ submitEmployeeAnswers, generateEmployeeReport, employees } = orgContext);
} else {
// For invite flows, we don't need these functions from org context
submitEmployeeAnswers = null;
generateEmployeeReport = null;
employees = [];
}
const [currentStep, setCurrentStep] = useState(1);
const [formData, setFormData] = useState<any>({});
const [isSubmitting, setIsSubmitting] = useState(false);
const [error, setError] = useState('');
const [inviteEmployee, setInviteEmployee] = useState<any>(null);
const [isLoadingInvite, setIsLoadingInvite] = useState(false);
// Load invite details if this is an invite flow
useEffect(() => {
if (inviteCode) {
loadInviteDetails(inviteCode);
}
}, [inviteCode]);
const loadInviteDetails = async (code: string) => {
setIsLoadingInvite(true);
try {
const response = await fetch(`${API_URL}/getInvitationStatus?code=${code}`);
if (response.ok) {
const data = await response.json();
if (data.used) {
setError('This invitation has already been used');
} else if (data.employee) {
setInviteEmployee(data.employee);
setError('');
} else {
setError('Invalid invitation data');
}
} else {
const errorData = await response.json().catch(() => ({ error: 'Unknown error' }));
setError(errorData.error || 'Invalid or expired invitation link');
}
} catch (err) {
console.error('Error loading invite details:', err);
setError('Failed to load invitation details');
} finally {
setIsLoadingInvite(false);
}
};
// Get employee info from multiple sources
const invitedEmployee = location.state?.invitedEmployee;
// Determine current employee - for invite flow, use invite employee data
let currentEmployee;
if (isInviteFlow) {
currentEmployee = inviteEmployee;
} else {
// Original auth-based logic
currentEmployee = invitedEmployee || employees.find(emp => emp.email === user?.email);
if (!currentEmployee && user?.email) {
// Try case-insensitive email matching
currentEmployee = employees.find(emp =>
emp.email?.toLowerCase() === user.email?.toLowerCase()
);
if (!currentEmployee && invitedEmployee) {
currentEmployee = employees.find(emp =>
emp.name === invitedEmployee.name || emp.id === invitedEmployee.id
);
}
}
// Demo mode fallbacks
if (!currentEmployee && user?.email === 'demo@auditly.local' && employees.length > 0) {
currentEmployee = employees[employees.length - 1];
}
if (!currentEmployee && employees.length === 1) {
currentEmployee = employees[0];
}
}
const submitViaInvite = async (answers: EmployeeSubmissionAnswers, inviteCode: string) => {
try {
// First, consume the invite to mark it as used
const consumeResponse = await fetch(`${API_URL}/consumeInvitation`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code: inviteCode })
});
if (!consumeResponse.ok) {
throw new Error('Failed to process invitation');
}
// Get orgId from the consume response
const consumeData = await consumeResponse.json();
const orgId = consumeData.orgId;
// Submit the questionnaire answers using Cloud Function
const submitResponse = await fetch(`${API_URL}/submitEmployeeAnswers`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
inviteCode: inviteCode,
answers: answers,
orgId: orgId
})
});
if (!submitResponse.ok) {
const errorData = await submitResponse.json();
throw new Error(errorData.error || 'Failed to submit questionnaire');
}
const result = await submitResponse.json();
return { success: true, reportGenerated: !!result.report };
} catch (error) {
console.error('Invite submission error:', error);
return { success: false, error: error.message };
}
};
const handleSubmit = async () => {
setIsSubmitting(true);
setError('');
try {
// Convert form data to EMPLOYEE_QUESTIONS format for backend
const answers: EmployeeSubmissionAnswers = {};
// Map form data to question IDs
if (formData.name) answers['full_name'] = formData.name;
if (formData.email) answers['email'] = formData.email;
if (formData.company) answers['company_department'] = formData.company;
if (formData.title_department) answers['title_department'] = formData.title_department;
// Add all other form data fields
Object.keys(formData).forEach(key => {
if (formData[key] && !answers[key]) {
answers[key] = formData[key];
}
});
// Submit answers - different logic for invite vs auth flow
let result;
if (isInviteFlow) {
// Direct API submission for invite flow (no auth needed)
result = await submitViaInvite(answers, inviteCode);
} else {
// Use org context for authenticated flow
if (!currentEmployee) {
// Enhanced fallback logic for authenticated users
if (employees.length > 0) {
let fallbackEmployee = employees.find(emp =>
emp.email?.toLowerCase().includes(user?.email?.toLowerCase().split('@')[0] || '')
);
if (!fallbackEmployee) {
const userDomain = user?.email?.split('@')[1];
fallbackEmployee = employees.find(emp =>
emp.email?.split('@')[1] === userDomain
) || employees[employees.length - 1];
}
const success = await submitEmployeeAnswers(fallbackEmployee.id, answers);
if (success) {
try {
const report = await generateEmployeeReport(fallbackEmployee);
console.log('Report generated successfully:', report);
} catch (reportError) {
console.error('Failed to generate report:', reportError);
}
// Navigate to completion
setCurrentStep(38); // Thank you page
return;
}
}
setError(`We couldn't match your account (${user?.email}) with an employee record. Please contact your administrator.`);
setIsSubmitting(false);
return;
}
result = await submitEmployeeAnswers(currentEmployee.id, answers);
}
if (result.success) {
// Show thank you page
setCurrentStep(38);
} else {
setError(result.message || 'Failed to submit questionnaire');
}
} catch (error) {
console.error('Submission error:', error);
setError('Failed to submit questionnaire. Please try again.');
} finally {
setIsSubmitting(false);
}
};
const handleNext = (stepData?: any) => {
if (stepData) {
const newFormData = { ...formData, ...stepData };
setFormData(newFormData);
}
if (currentStep === 37) {
// Submit form data here
handleSubmit();
} else {
setCurrentStep(currentStep + 1);
}
};
const handleBack = () => {
setCurrentStep(currentStep - 1);
};
// Early return for invite flow loading state
if (isInviteFlow && isLoadingInvite) {
return (
<div className="min-h-screen bg-[--background-primary] py-8 px-4 flex items-center justify-center">
<div className="max-w-4xl mx-auto text-center">
<div className="w-16 h-16 bg-[--accent] rounded-full flex items-center justify-center font-bold text-white text-2xl mx-auto mb-4">
A
</div>
<h1 className="text-3xl font-bold text-[--text-primary] mb-4">Loading Your Invitation...</h1>
<p className="text-[--text-secondary]">Please wait while we verify your invitation.</p>
</div>
</div>
);
}
// Early return for invite flow error state
if (isInviteFlow && error && currentStep === 1) {
return (
<div className="min-h-screen bg-[--background-primary] py-8 px-4 flex items-center justify-center">
<div className="max-w-4xl mx-auto text-center">
<div className="w-16 h-16 bg-red-500 rounded-full flex items-center justify-center font-bold text-white text-2xl mx-auto mb-4">
!
</div>
<h1 className="text-3xl font-bold text-[--text-primary] mb-4">Invitation Error</h1>
<p className="text-[--text-secondary] mb-6">{error}</p>
<button
onClick={() => window.location.href = '/'}
className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
>
Return to Homepage
</button>
</div>
</div>
);
}
const renderStep = () => {
// NOTE: Step components need to be imported from EmployeeFormsController
// For now, showing placeholder that preserves all 38 steps
switch (currentStep) {
case 1:
return <EmployeeFormStep1 onNext={handleNext} />;
case 2:
return (
<SectionIntro
sectionNumber="1 of 7"
title="Personal Information"
description="Let's start by getting to know you better. We'll ask about your role and background."
onStart={() => handleNext()}
/>
);
case 3:
return <div className="p-8 text-center"><h2>Step 3 - Personal Information Form</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 4:
return <div className="p-8 text-center"><h2>Step 4 - Email Validation</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 5:
return <div className="p-8 text-center"><h2>Step 5 - Department Details</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 6:
return <div className="p-8 text-center"><h2>Step 6 - Role Description</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 7:
return <div className="p-8 text-center"><h2>Step 7 - Experience Level</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 8:
return <div className="p-8 text-center"><h2>Step 8 - Skills Assessment</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 9:
return (
<SectionIntro
sectionNumber="2 of 7"
title="Work Environment & Culture"
description="Let's explore your work environment and team dynamics."
onStart={() => handleNext()}
/>
);
case 10:
return <div className="p-8 text-center"><h2>Step 10 - Team Dynamics</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 11:
return <div className="p-8 text-center"><h2>Step 11 - Communication Style</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 12:
return <div className="p-8 text-center"><h2>Step 12 - Work Preferences</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 13:
return <div className="p-8 text-center"><h2>Step 13 - Collaboration Rating</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 14:
return <div className="p-8 text-center"><h2>Step 14 - Remote Work</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 15:
return <div className="p-8 text-center"><h2>Step 15 - Work-Life Balance</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 16:
return (
<SectionIntro
sectionNumber="3 of 7"
title="Performance & Goals"
description="Let's discuss your performance metrics and career goals."
onStart={() => handleNext()}
/>
);
case 17:
return <div className="p-8 text-center"><h2>Step 17 - Goal Setting</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 18:
return <div className="p-8 text-center"><h2>Step 18 - Achievement Rating</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 19:
return <div className="p-8 text-center"><h2>Step 19 - Performance Metrics</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 20:
return <div className="p-8 text-center"><h2>Step 20 - Career Aspirations</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 21:
return (
<SectionIntro
sectionNumber="4 of 7"
title="Training & Development"
description="Let's explore your learning preferences and development needs."
onStart={() => handleNext()}
/>
);
case 22:
return <div className="p-8 text-center"><h2>Step 22 - Learning Style</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 23:
return <div className="p-8 text-center"><h2>Step 23 - Skill Development</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 24:
return <div className="p-8 text-center"><h2>Step 24 - Training Preferences</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 25:
return (
<SectionIntro
sectionNumber="5 of 7"
title="Feedback & Recognition"
description="Let's discuss feedback mechanisms and recognition preferences."
onStart={() => handleNext()}
/>
);
case 26:
return <div className="p-8 text-center"><h2>Step 26 - Feedback Style</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 27:
return <div className="p-8 text-center"><h2>Step 27 - Recognition Preferences</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 28:
return <div className="p-8 text-center"><h2>Step 28 - Performance Reviews</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 29:
return <div className="p-8 text-center"><h2>Step 29 - Manager Relationship</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 30:
return (
<SectionIntro
sectionNumber="6 of 7"
title="Innovation & Problem Solving"
description="Let's explore your approach to innovation and problem-solving."
onStart={() => handleNext()}
/>
);
case 31:
return <div className="p-8 text-center"><h2>Step 31 - Problem Solving</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 32:
return <div className="p-8 text-center"><h2>Step 32 - Innovation Rating</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 33:
return <div className="p-8 text-center"><h2>Step 33 - Creative Thinking</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 34:
return (
<SectionIntro
sectionNumber="7 of 7"
title="Leadership & Organizational Structure"
description="Now we'll explore your thoughts on our organizational structure and leadership effectiveness."
onStart={() => handleNext()}
/>
);
case 35:
return <div className="p-8 text-center"><h2>Step 35 - Leadership Style</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 36:
return <div className="p-8 text-center"><h2>Step 36 - Organizational Structure</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Next</button></div>;
case 37:
return <div className="p-8 text-center"><h2>Step 37 - Final Feedback</h2><button onClick={() => handleNext()} className="px-4 py-2 bg-blue-600 text-white rounded mt-4">Submit</button></div>;
case 38:
return (
<div className="w-[1440px] bg-white inline-flex justify-start items-center overflow-hidden">
<div className="flex-1 h-[810px] px-32 py-48 bg-[--Neutrals-NeutralSlate0] flex justify-center items-center gap-2.5 overflow-hidden">
<div className="flex-1 max-w-[464px] inline-flex flex-col justify-start items-start gap-12">
<div className="self-stretch flex flex-col justify-start items-start gap-6">
<div className="w-12 h-12 relative bg-[--Brand-Orange] rounded-xl outline outline-2 outline-offset-[-2px] outline-blue-400 overflow-hidden">
<div className="w-12 h-12 left-0 top-0 absolute bg-gradient-to-b from-white/0 to-white/10" />
<div className="left-[12px] top-[9.33px] absolute">
<AuditlyIcon />
</div>
</div>
<div className="self-stretch flex flex-col justify-start items-start gap-4">
<div className="self-stretch justify-start text-[--Neutrals-NeutralSlate800] text-5xl font-medium font-['Neue_Montreal'] leading-[48px]">Thank you! Your assessment has been submitted!</div>
<div className="self-stretch justify-center text-[--Neutrals-NeutralSlate500] text-base font-normal font-['Inter'] leading-normal">Your responses have been recorded and your AI-powered performance report will be generated shortly.</div>
</div>
</div>
</div>
</div>
<div className="flex-1 h-[810px] px-20 py-16 flex justify-center items-center gap-2.5 overflow-hidden">
<div className="flex-1 self-stretch origin-top-left rotate-180 rounded-3xl inline-flex flex-col justify-center items-center gap-2.5 overflow-hidden">
<img className="self-stretch flex-1" src="https://placehold.co/560x682" alt="Thank you" />
</div>
</div>
</div>
);
default:
return <div className="p-8 text-center">Form completed!</div>;
}
};
return (
<div className="min-h-screen bg-white">
{renderStep()}
{error && (
<div className="fixed bottom-4 right-4 bg-red-500 text-white p-4 rounded-lg">
{error}
</div>
)}
</div>
);
};
export default EmployeeQuestionnaire;