-
- Executive Summary
- {companyReport.executiveSummary}
-
-
-
{companyReport.overview.totalEmployees}
-
Employees
-
-
-
{companyReport.overview?.departmentBreakdown?.length || 0}
-
Departments
-
-
-
{companyReport.organizationalStrengths?.length || 0}
-
Strength Areas
-
-
-
{companyReport.organizationalRisks?.length || 0}
-
Risks
-
-
- {(Array.isArray(companyReport.gradingOverview) && companyReport.gradingOverview.length > 0) && (
-
- ({
- label: g.category || g.department || g.subject || 'Metric',
- value: g.value ?? g.averageScore ?? 0
- }))}
- />
-
- )}
-
-
-
-
- Strengths
-
- {(companyReport.organizationalStrengths || []).map((s: any, i) => • {s.area || s} )}
-
-
-
- Risks
-
- {(companyReport.organizationalRisks || []).map((r, i) => • {r} )}
-
-
-
- Forward Plan
-
-
Goals
-
- {(companyReport.operatingPlan?.nextQuarterGoals || companyReport.forwardOperatingPlan?.quarterlyGoals || []).map((g: string, i: number) => {g} )}
-
-
Resource Needs
-
- {(companyReport.operatingPlan?.resourceNeeds || companyReport.forwardOperatingPlan?.resourceNeeds || []).map((g: string, i: number) => {g} )}
-
-
Risk Mitigation
-
- {(companyReport.operatingPlan?.riskMitigation || companyReport.forwardOperatingPlan?.riskMitigation || []).map((g: string, i: number) => {g} )}
-
-
-
-
+
+ {error && (
+
+ {error}
)}
- {/* Company Profile - Q&A Format from Onboarding */}
-
-
Company Profile
-
- {org?.mission && (
-
-
-
-
Question:
-
What is your company's mission?
-
-
-
Answer:
-
{org.mission}
-
-
-
- )}
- {org?.vision && (
-
-
-
-
Question:
-
What is your company's vision?
-
-
-
Answer:
-
{org.vision}
-
-
-
- )}
- {org?.evolution && (
-
-
-
-
Question:
-
How has your company evolved over time?
-
-
-
Answer:
-
{org.evolution}
-
-
-
- )}
- {org?.advantages && (
-
-
-
-
Question:
-
What are your competitive advantages?
-
-
-
Answer:
-
{org.advantages}
-
-
-
- )}
- {org?.vulnerabilities && (
-
-
-
-
Question:
-
What are your key vulnerabilities?
-
-
-
Answer:
-
{org.vulnerabilities}
-
-
-
- )}
- {org?.shortTermGoals && (
-
-
-
-
Question:
-
What are your short-term goals?
-
-
-
Answer:
-
{org.shortTermGoals}
-
-
-
- )}
- {org?.longTermGoals && (
-
-
-
-
Question:
-
What are your long-term goals?
-
-
-
Answer:
-
{org.longTermGoals}
-
-
-
- )}
- {org?.cultureDescription && (
-
-
-
-
Question:
-
How would you describe your company culture?
-
-
-
Answer:
-
{org.cultureDescription}
-
-
-
- )}
- {org?.workEnvironment && (
-
-
-
-
Question:
-
What is your work environment like?
-
-
-
Answer:
-
{org.workEnvironment}
-
-
-
- )}
- {org?.additionalContext && (
-
-
-
-
Question:
-
Any additional context about your company?
-
-
-
Answer:
-
{org.additionalContext}
-
-
-
- )}
-
-
-
- {org?.description && (
-
- About
- {org.description}
-
- )}
+
);
};
-export default CompanyWiki;
+export default CompanyWiki;
\ No newline at end of file
diff --git a/pages/EmployeeFormNew.tsx b/pages/EmployeeFormNew.tsx
new file mode 100644
index 0000000..0f4a30a
--- /dev/null
+++ b/pages/EmployeeFormNew.tsx
@@ -0,0 +1,101 @@
+import React, { useState } from 'react';
+
+const EmployeeFormNew: React.FC = () => {
+ const [currentStep, setCurrentStep] = useState(1);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Welcome to the Auditly Employee Assessment
+
Let's learn about your role, contribution and help us get a better understand of how you work best.
+
+
+
+
+
+
+
Tell us about your current role and what you work on
+
+
+
+
+
What is your role at the company?
+
*
+
+
+
+
+
+
What department do you work in?
+
*
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default EmployeeFormNew;
\ No newline at end of file
diff --git a/pages/EmployeeFormsController.tsx b/pages/EmployeeFormsController.tsx
new file mode 100644
index 0000000..ec137fe
--- /dev/null
+++ b/pages/EmployeeFormsController.tsx
@@ -0,0 +1,1595 @@
+import React, { useState } from 'react';
+import { useParams } from 'react-router-dom';
+import { FigmaRatingScale, FigmaTextArea, FigmaNavigationButtons } from '../components/figma/FigmaQuestion';
+import { FigmaMultipleChoice } from '../components/figma/FigmaMultipleChoice';
+
+// Icon SVG Component
+const AuditlyIcon: React.FC = () => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+);
+
+// Progress Bar Component for Section Headers
+const SectionProgressBar: React.FC<{ currentSection: number; totalSections: number }> = ({ currentSection, totalSections }) => {
+ return (
+
+ {Array.from({ length: 7 }, (_, index) => {
+ const isActive = index === 0; // First step is always active for section start
+ return (
+
+ {index === 0 ? (
+
+ ) : (
+
+
+
+ )}
+
+ );
+ })}
+
+ );
+};
+
+// 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 (
+
+
+
+
{question}
+
+
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-NeutralSlate200'}`}
+ >
+
+ No
+
+
+
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-NeutralSlate200'}`}
+ >
+
+ Yes
+
+
+
+
+
+ {onBack && (
+
+
+
+ )}
+
+
+
+
+
+
+ {/* Skip button */}
+ {onSkip && (
+
+ )}
+
+ {/* Progress indicators */}
+ {currentStep && totalSteps && (
+ <>
+
+
{currentStep} of {totalSteps}
+
+
+
+
Leadership & Organizational Structure
+
+ >
+ )}
+
+ );
+};
+
+// Section Intro Component
+const SectionIntro: React.FC<{
+ sectionNumber: string;
+ title: string;
+ description: string;
+ onStart: () => void;
+ imageUrl?: string;
+}> = ({ sectionNumber, title, description, onStart, imageUrl = "https://placehold.co/560x682" }) => {
+ return (
+
+
+
+
+
+
+
+
{title}
+
{description}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+// Step 1: Welcome & Role Information (Light)
+const EmployeeFormStep1: React.FC<{ onNext: (data: any) => void }> = ({ onNext }) => {
+ const [formData, setFormData] = useState({
+ name: '',
+ role: '',
+ department: ''
+ });
+
+ const handleSubmit = () => {
+ onNext(formData);
+ };
+
+ return (
+
+
+
+
+
+
+
Welcome to the Auditly Employee Assessment
+
Let's learn about your role, contribution and help us get a better understand of how you work best.
+
+
+
+
+
+
+
Tell us about your current role and what you work on
+
+
+
+
+
+ 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-NeutralSlate500 outline-none"
+ placeholder="Enter your full name"
+ />
+
+
+
+
+
+
What is your role at the company?
+
*
+
+
+
+ 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-NeutralSlate500 outline-none"
+ placeholder="e.g. Software Engineer, Marketing Manager"
+ />
+
+
+
+
+
+
What department do you work in?
+
*
+
+
+
+ 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-NeutralSlate500 outline-none"
+ placeholder="e.g. Engineering, Sales, Marketing"
+ />
+
+
+
+
+
+
+
+
+
+ );
+};
+
+// Step 2: Personal Information
+const EmployeeFormStep2: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [formData, setFormData] = useState({
+ email: '',
+ name: '',
+ company: ''
+ });
+
+ return (
+
+
+
+
Personal Information
+
+
+
+
+
+ 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-NeutralSlate500 outline-none"
+ placeholder="Email@gmail.com"
+ />
+
+
+
+
+
+
+
+ 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-NeutralSlate500 outline-none"
+ placeholder="John Doe"
+ />
+
+
+
+
+
+
What is the name of your Company and department?
+
*
+
+
+
+ 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-NeutralSlate500 outline-none"
+ placeholder="Doe Enterprises"
+ />
+
+
+
+
+
+
+
+ Back
+
+
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"
+ >
+
+
+
+
+
+ );
+};
+
+// Step 3: Current Title and Department (Text Area)
+const EmployeeFormStep3: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState
('');
+
+ return (
+
+
+
+ onNext({ titleAndDepartment: answer })}
+ onSkip={() => onNext({ titleAndDepartment: '' })}
+ nextDisabled={!answer.trim()}
+ currentStep={1}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 4: Daily Tasks (Text Area)
+const EmployeeFormStep4: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+
+
+
+ onNext({ dailyTasks: answer })}
+ onSkip={() => onNext({ dailyTasks: '' })}
+ nextDisabled={!answer.trim()}
+ currentStep={2}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 5: Role Understanding Rating
+const EmployeeFormStep5: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [rating, setRating] = useState();
+
+ return (
+
+
+
+ onNext({ roleUnderstanding: rating })}
+ onSkip={() => onNext({ roleUnderstanding: null })}
+ nextDisabled={!rating}
+ currentStep={3}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 6: Work Satisfaction
+const EmployeeFormStep6: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [rating, setRating] = useState();
+
+ return (
+
+
+
+ onNext({ workSatisfaction: rating })}
+ onSkip={() => onNext({ workSatisfaction: null })}
+ nextDisabled={!rating}
+ currentStep={4}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 7: Communication Rating
+const EmployeeFormStep7: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [rating, setRating] = useState();
+
+ return (
+
+
+
+ onNext({ communicationRating: rating })}
+ onSkip={() => onNext({ communicationRating: null })}
+ nextDisabled={!rating}
+ currentStep={5}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 8: Work Style Preference
+const EmployeeFormStep8: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [selectedOption, setSelectedOption] = useState('');
+
+ 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 (
+
+
+
+
+ What work style best describes you?
+
+
+ {options.map((option, index) => (
+
+ setSelectedOption(e.target.value)}
+ className="w-5 h-5 accent-Brand-Orange"
+ />
+
+ {option}
+
+
+ ))}
+
+
+
+
+ onNext({ workStyle: selectedOption })}
+ onSkip={() => onNext({ workStyle: '' })}
+ nextDisabled={!selectedOption}
+ currentStep={6}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 9: Section Intro - Output & Accountability
+const EmployeeFormStep9: React.FC<{ onNext: () => void }> = ({ onNext }) => {
+ return (
+
+ );
+};
+
+// Step 10: Weekly Output Rating
+const EmployeeFormStep10: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [rating, setRating] = useState();
+
+ return (
+
+
+
+ onNext({ weeklyOutput: rating })}
+ onSkip={() => onNext({ weeklyOutput: null })}
+ nextDisabled={!rating}
+ currentStep={1}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 11: Top Deliverables
+const EmployeeFormStep11: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+
+
+
+ onNext({ topDeliverables: answer })}
+ onSkip={() => onNext({ topDeliverables: '' })}
+ nextDisabled={!answer.trim()}
+ currentStep={2}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 12: Measurable Results
+const EmployeeFormStep12: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+
+
+
+ onNext({ measurableResults: answer })}
+ onSkip={() => onNext({ measurableResults: '' })}
+ nextDisabled={!answer.trim()}
+ currentStep={3}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 13: Weekly KPIs
+const EmployeeFormStep13: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+ 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('');
+
+ return (
+
+
+
+ onNext({ kpiDetails: answer })}
+ onSkip={() => onNext({ kpiDetails: '' })}
+ currentStep={5}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 15: Reporting Structure
+const EmployeeFormStep15: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+
+
+
+ onNext({ reportingStructure: answer })}
+ onSkip={() => onNext({ reportingStructure: '' })}
+ currentStep={6}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 16: Section Intro - Team & Collaboration
+const EmployeeFormStep16: React.FC<{ onNext: () => void }> = ({ onNext }) => {
+ return (
+
+ );
+};
+
+// Step 17: Work Closest With
+const EmployeeFormStep17: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+
+
+
+ onNext({ workClosestWith: answer })}
+ onSkip={() => onNext({ workClosestWith: '' })}
+ currentStep={1}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 18: Collaboration Issues
+const EmployeeFormStep18: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+
+
+
+ onNext({ collaborationIssues: answer })}
+ onSkip={() => onNext({ collaborationIssues: '' })}
+ currentStep={2}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 19: Team Communication Rating
+const EmployeeFormStep19: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [rating, setRating] = useState();
+
+ return (
+
+
+
+ onNext({ teamCommunication: rating })}
+ onSkip={() => onNext({ teamCommunication: null })}
+ nextDisabled={!rating}
+ currentStep={3}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 20: Team Support
+const EmployeeFormStep20: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+
+
+
+ onNext({ teamSupport: answer })}
+ onSkip={() => onNext({ teamSupport: '' })}
+ currentStep={4}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 21: Tools and Resources Section
+const EmployeeFormStep21: React.FC<{ onNext: () => void }> = ({ onNext }) => {
+ return (
+
+ );
+};
+
+// Step 22: Current Tools
+const EmployeeFormStep22: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+
+
+
+ onNext({ currentTools: answer })}
+ onSkip={() => onNext({ currentTools: '' })}
+ currentStep={1}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 23: Tool Effectiveness
+const EmployeeFormStep23: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [rating, setRating] = useState();
+
+ return (
+
+
+
+ onNext({ toolEffectiveness: rating })}
+ onSkip={() => onNext({ toolEffectiveness: null })}
+ nextDisabled={!rating}
+ currentStep={2}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 24: Missing Tools
+const EmployeeFormStep24: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+
+
+
+ onNext({ missingTools: answer })}
+ onSkip={() => onNext({ missingTools: '' })}
+ currentStep={3}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 25: Skills & Development Section
+const EmployeeFormStep25: React.FC<{ onNext: () => void }> = ({ onNext }) => {
+ return (
+
+ );
+};
+
+// Step 26: Key Skills
+const EmployeeFormStep26: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+
+
+
+ onNext({ keySkills: answer })}
+ onSkip={() => onNext({ keySkills: '' })}
+ currentStep={1}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 27: Skill Development
+const EmployeeFormStep27: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+
+
+
+ onNext({ skillDevelopment: answer })}
+ onSkip={() => onNext({ skillDevelopment: '' })}
+ currentStep={2}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 28: Training Opportunities
+const EmployeeFormStep28: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+ 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('');
+
+ return (
+
+
+
+ onNext({ careerGoals: answer })}
+ onSkip={() => onNext({ careerGoals: '' })}
+ currentStep={4}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 30: Feedback & Improvement Section
+const EmployeeFormStep30: React.FC<{ onNext: () => void }> = ({ onNext }) => {
+ return (
+
+ );
+};
+
+// Step 31: Company Improvements
+const EmployeeFormStep31: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+
+
+
+ onNext({ companyImprovements: answer })}
+ onSkip={() => onNext({ companyImprovements: '' })}
+ currentStep={1}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 32: Job Satisfaction
+const EmployeeFormStep32: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [rating, setRating] = useState();
+
+ return (
+
+
+
+ onNext({ jobSatisfaction: rating })}
+ onSkip={() => onNext({ jobSatisfaction: null })}
+ nextDisabled={!rating}
+ currentStep={2}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 33: Additional Feedback
+const EmployeeFormStep33: React.FC<{ onNext: (data: any) => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = useState('');
+
+ return (
+
+
+
+ onNext({ additionalFeedback: answer })}
+ onSkip={() => onNext({ additionalFeedback: '' })}
+ currentStep={3}
+ totalSteps={7}
+ />
+
+
+ );
+};
+
+// Step 35: Leadership & Organizational Structure - Magic Wand Question
+const EmployeeFormStep35: React.FC<{ onNext: () => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = React.useState('');
+
+ return (
+
+
+
+
If you had a magic wand, what would you change about how we operate?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Leadership & Organizational Structure
+
+
+ );
+};
+
+// Step 36: Overstaffed/Underperforming Departments
+const EmployeeFormStep36: React.FC<{ onNext: () => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = React.useState('');
+
+ return (
+
+
+
+
Do you believe any roles or departments are overstaffed or underperforming?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Leadership & Organizational Structure
+
+
+ );
+};
+
+// Step 37: Any Other Feedback
+const EmployeeFormStep37: React.FC<{ onNext: () => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ const [answer, setAnswer] = React.useState('');
+
+ return (
+
+
+
+
Any other feedback or suggestions?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Leadership & Organizational Structure
+
+
+ );
+};
+
+// Step 38: Thank You Page (Final)
+const EmployeeFormStep38: React.FC<{ formData: any }> = ({ formData }) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Thank you your form has been submitted!
+
Description about the topic and what it means.
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+// Step 34: Section Outro - Leadership & Organizational Structure
+const EmployeeFormStep34: React.FC<{ onNext: () => void; onBack: () => void }> = ({ onNext, onBack }) => {
+ return (
+
+ );
+};
+
+// Main Controller Component
+const EmployeeFormsController: React.FC = () => {
+ const { inviteCode } = useParams();
+ const [currentStep, setCurrentStep] = useState(1);
+ const [formData, setFormData] = useState({});
+
+ const handleNext = (stepData?: any) => {
+ if (stepData) {
+ const newFormData = { ...formData, ...stepData };
+ setFormData(newFormData);
+ }
+
+ if (currentStep === 37) {
+ // Submit form data here
+ console.log('Submitting form data:', formData);
+ // TODO: Submit to backend
+ }
+
+ setCurrentStep(currentStep + 1);
+ };
+
+ const handleBack = () => {
+ setCurrentStep(currentStep - 1);
+ };
+
+ const handleSkip = () => {
+ setCurrentStep(currentStep + 1);
+ };
+
+ const renderStep = () => {
+ switch (currentStep) {
+ case 1:
+ return ;
+ case 2:
+ return ;
+ case 3:
+ return ;
+ case 4:
+ return ;
+ case 5:
+ return ;
+ case 6:
+ return ;
+ case 7:
+ return ;
+ case 8:
+ return ;
+ case 9:
+ return handleNext()} />;
+ case 10:
+ return ;
+ case 11:
+ return ;
+ case 12:
+ return ;
+ case 13:
+ return ;
+ case 14:
+ return ;
+ case 15:
+ return ;
+ case 16:
+ return handleNext()} />;
+ case 17:
+ return ;
+ case 18:
+ return ;
+ case 19:
+ return ;
+ case 20:
+ return ;
+ case 21:
+ return handleNext()} />;
+ case 22:
+ return ;
+ case 23:
+ return ;
+ case 24:
+ return ;
+ case 25:
+ return handleNext()} />;
+ case 26:
+ return ;
+ case 27:
+ return ;
+ case 28:
+ return ;
+ case 29:
+ return ;
+ case 30:
+ return handleNext()} />;
+ case 31:
+ return ;
+ case 32:
+ return ;
+ case 33:
+ return ;
+ case 34:
+ return ;
+ case 35:
+ return ;
+ case 36:
+ return ;
+ case 37:
+ return ;
+ case 38:
+ return ;
+ default:
+ return Form completed!
;
+ }
+ };
+
+ return (
+
+ {renderStep()}
+
+ );
+};
+
+export default EmployeeFormsController;
\ No newline at end of file
diff --git a/pages/HelpNew.tsx b/pages/HelpNew.tsx
new file mode 100644
index 0000000..3265e90
--- /dev/null
+++ b/pages/HelpNew.tsx
@@ -0,0 +1,133 @@
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { useAuth } from '../contexts/AuthContext';
+import Sidebar from '../components/figma/Sidebar';
+
+interface FAQItem {
+ question: string;
+ answer: string;
+ isOpen: boolean;
+}
+
+const HelpNew: React.FC = () => {
+ const { user } = useAuth();
+ const navigate = useNavigate();
+
+ const [faqItems, setFaqItems] = useState([
+ {
+ question: "What is the process for submitting a support ticket?",
+ answer: "Team members will undergo evaluations every three months, focusing on their performance, teamwork, and communication skills. Role advancements will be considered at these intervals.",
+ isOpen: true
+ },
+ {
+ question: "How can I reset my password?",
+ answer: "To reset your password, click on the 'Forgot Password' link on the login page and follow the instructions sent to your email address.",
+ isOpen: false
+ },
+ {
+ question: "What are the criteria for performance reviews?",
+ answer: "Performance reviews are based on multiple factors including goal achievement, collaboration, innovation, and adherence to company values. Reviews are conducted quarterly with detailed feedback sessions.",
+ isOpen: false
+ },
+ {
+ question: "How can I access the company's training resources?",
+ answer: "Training resources are available through our internal learning portal. You can access them from the main dashboard under the 'Learning & Development' section.",
+ isOpen: false
+ },
+ {
+ question: "What should I do if I encounter a technical issue?",
+ answer: "For technical issues, first check our troubleshooting guide. If the issue persists, contact our IT support team through the help desk or email support@company.com.",
+ isOpen: false
+ },
+ {
+ question: "How do I provide feedback on team projects?",
+ answer: "Feedback can be provided through our project management system or during regular team meetings. We encourage constructive feedback that helps improve project outcomes.",
+ isOpen: false
+ }
+ ]);
+
+ const toggleFAQ = (index: number) => {
+ setFaqItems(prev => prev.map((item, i) => ({
+ ...item,
+ isOpen: i === index ? !item.isOpen : item.isOpen
+ })));
+ };
+
+ const handleContactUs = () => {
+ // In a real app, this would open a contact form or support chat
+ alert('Contact functionality would be implemented here');
+ };
+
+ if (!user) {
+ navigate('/login');
+ return null;
+ }
+
+ return (
+
+
+
+
+
Help & Support
+
+ {faqItems.map((item, index) => (
+
+
toggleFAQ(index)}
+ className="self-stretch px-3 py-2 inline-flex justify-start items-center gap-2 cursor-pointer"
+ >
+
+ {item.question}
+
+
+ {item.isOpen ? (
+
+
+
+ ) : (
+
+
+
+ )}
+
+
+
+ {item.isOpen && (
+
+ )}
+
+ ))}
+
+
+
+
Still have questions?
+
We are available for 24/7
+
+
+
+
+
+
+ );
+};
+
+export default HelpNew;
\ No newline at end of file
diff --git a/pages/Login.tsx b/pages/Login.tsx
index 8d0b90f..c907d47 100644
--- a/pages/Login.tsx
+++ b/pages/Login.tsx
@@ -1,266 +1,403 @@
import React, { useState, useEffect } from 'react';
import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { useAuth } from '../contexts/AuthContext';
-import { useOrg } from '../contexts/OrgContext';
-import { Card, Button } from '../components/UiKit';
+import { Button } from '../components/UiKit';
-const Login: React.FC = () => {
+type AuthStep = 'email' | 'otp' | 'password-fallback';
+
+const ModernLogin: React.FC = () => {
const navigate = useNavigate();
const location = useLocation();
const { inviteCode: routeInviteCode } = useParams<{ inviteCode: string }>();
- const [email, setEmail] = useState('demo@auditly.com');
- const [password, setPassword] = useState('demo123');
+
+ // Auth state
+ const { signInWithGoogle, signInWithEmail, signUpWithEmail, user, loading, sendOTP: authSendOTP, verifyOTP: authVerifyOTP } = useAuth();
+
+ // Form state
+ const [step, setStep] = useState('email');
+ const [email, setEmail] = useState('');
+ const [otp, setOtp] = useState('');
+ const [password, setPassword] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState('');
const [inviteCode, setInviteCode] = useState(null);
- const { signInWithGoogle, signInWithEmail, signUpWithEmail, user, loading } = useAuth();
- const { consumeInvite, org } = useOrg();
+ const [resendCooldown, setResendCooldown] = useState(0);
+ const [demoOTP, setDemoOTP] = useState(null);
+ // Extract invite code from URL
useEffect(() => {
- // Check for invite code in route params first, then fallback to query params
if (routeInviteCode) {
- console.log('Invite code from route params:', routeInviteCode);
setInviteCode(routeInviteCode);
- // Clear demo credentials for invite flow
- setEmail('');
- setPassword('');
} else {
- // Extract query params from hash-based URL
const hashSearch = location.hash.includes('?') ? location.hash.split('?')[1] : '';
const searchParams = new URLSearchParams(hashSearch);
const queryInvite = searchParams.get('invite');
if (queryInvite) {
- console.log('Invite code from query params:', queryInvite);
setInviteCode(queryInvite);
- // Clear demo credentials for invite flow
- setEmail('');
- setPassword('');
}
}
}, [routeInviteCode, location]);
- const handleSuccessfulLogin = async () => {
- if (inviteCode) {
- // Invite flow - redirect to org selection with invite code
- navigate(`/org-selection?invite=${inviteCode}`, { replace: true });
- } else {
- // Regular login - redirect to org selection to choose/create org
- navigate('/org-selection', { replace: true });
- }
- };
-
+ // Handle successful authentication
useEffect(() => {
if (user && !loading) {
- handleSuccessfulLogin();
- }
- }, [user, loading]);
-
- const handleEmailLogin = async (e: React.FormEvent) => {
- e.preventDefault();
- setIsLoading(true);
- setError('');
- try {
if (inviteCode) {
- // For invites, try to create account first since they're new users
- console.log('Invite flow: attempting to create account for', email);
- await signUpWithEmail(email, password, email.split('@')[0]);
+ navigate(`/org-selection?invite=${inviteCode}`, { replace: true });
} else {
- // Regular login
- await signInWithEmail(email, password);
- }
- // Success will be handled by the useEffect hook
- } catch (error) {
- console.error('Auth failed:', error);
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
-
- if (inviteCode) {
- // For invite flow, if account creation failed, try login instead
- if (errorMessage.includes('User already exists') || errorMessage.includes('already-exists')) {
- try {
- console.log('Account exists, trying login instead...');
- await signInWithEmail(email, password);
- } catch (loginError) {
- console.error('Login also failed:', loginError);
- setError(`Account exists but password is incorrect. Please check your password or contact your administrator.`);
- setIsLoading(false);
- }
- } else {
- setError(`Failed to create account: ${errorMessage}. Please try a different email or contact your administrator.`);
- setIsLoading(false);
- }
- } else {
- // Regular login flow - try signup if user not found
- if (errorMessage.includes('User not found')) {
- try {
- console.log('User not found, attempting sign-up...');
- await signUpWithEmail(email, password, email.split('@')[0]);
- // Success will be handled by the useEffect hook
- } catch (signUpError) {
- console.error('Sign-up also failed:', signUpError);
- setError(`Failed to create account: ${signUpError instanceof Error ? signUpError.message : 'Unknown error'}`);
- setIsLoading(false);
- }
- } else {
- setError(`Login failed: ${errorMessage}`);
- setIsLoading(false);
- }
+ navigate('/org-selection', { replace: true });
}
}
- };
+ }, [user, loading, navigate, inviteCode]);
- const handleGoogleLogin = async () => {
- setIsLoading(true);
- setError('');
+ // Resend cooldown timer
+ useEffect(() => {
+ if (resendCooldown > 0) {
+ const timer = setTimeout(() => setResendCooldown(resendCooldown - 1), 1000);
+ return () => clearTimeout(timer);
+ }
+ }, [resendCooldown]);
+
+ const sendOTP = async (emailAddress: string) => {
try {
- await signInWithGoogle();
- // Success will be handled by the useEffect hook
- } catch (error) {
- console.error('Google login failed:', error);
- setError(`Google login failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
+ setIsLoading(true);
+ setError('');
+ setDemoOTP(null);
+
+ // Call auth context method
+ const response = await authSendOTP(emailAddress, inviteCode || undefined);
+
+ // If OTP is returned in response (demo mode), display it
+ if (response.otp) {
+ setDemoOTP(response.otp);
+ }
+
+ setStep('otp');
+ setResendCooldown(60); // 60 second cooldown
+
+ } catch (err) {
+ console.error('OTP send error:', err);
+ setError(err instanceof Error ? err.message : 'Failed to send verification code. Please try again.');
+ } finally {
+ setIsLoading(false);
+ }
+ }; const verifyOTP = async () => {
+ try {
+ setIsLoading(true);
+ setError('');
+
+ // Call auth context method
+ await authVerifyOTP(email, otp, inviteCode || undefined);
+
+ // Success - user will be set in auth context and useEffect will handle navigation
+
+ } catch (err) {
+ console.error('OTP verification error:', err);
+ setError(err instanceof Error ? err.message : 'Invalid verification code. Please try again.');
+ } finally {
setIsLoading(false);
}
};
- return (
-
-
-
-
- A
-
-
Welcome to Auditly
-
- {inviteCode ? 'Complete your profile to join the team survey' : 'Sign in to your account'}
-
- {inviteCode && (
-
-
- � Employee Survey Invitation
- No account needed! Just create a password to secure your responses and start the questionnaire.
-
-
- )}
- {error && (
-
- )}
-
+ const handleEmailSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ if (!email.trim()) return;
-