- Add detailed report viewing with full-screen ReportDetail component for both company and employee reports - Fix company wiki to display onboarding Q&A in card format matching Figma designs - Exclude company owners from employee submission counts (owners contribute to wiki, not employee data) - Fix employee report generation to include company context (wiki + company report + employee answers) - Fix company report generation to use filtered employee submissions only - Add proper error handling for submission data format variations - Update Firebase functions to use gpt-4o model instead of deprecated gpt-4.1 - Fix UI syntax errors and improve report display functionality - Add comprehensive logging for debugging report generation flow 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
727 lines
38 KiB
TypeScript
727 lines
38 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { useOrg } from '../contexts/OrgContext';
|
|
import { Card, Button } from '../components/UiKit';
|
|
import { FigmaProgress } from '../components/figma/FigmaProgress';
|
|
import { FigmaInput } from '../components/figma/FigmaInput';
|
|
import { FigmaAlert } from '../components/figma/FigmaAlert';
|
|
|
|
interface OnboardingData {
|
|
// Step 1: Company Basics
|
|
companyName: string;
|
|
industry: string;
|
|
size: string;
|
|
description: string;
|
|
|
|
// Step 2: Mission & Vision
|
|
mission: string;
|
|
vision: string;
|
|
values: string[];
|
|
|
|
// Step 3: Company Evolution & History
|
|
foundingYear: string;
|
|
evolution: string;
|
|
majorMilestones: string;
|
|
|
|
// Step 4: Competitive Landscape
|
|
advantages: string;
|
|
vulnerabilities: string;
|
|
competitors: string;
|
|
marketPosition: string;
|
|
|
|
// Step 5: Current Challenges & Goals
|
|
currentChallenges: string[];
|
|
shortTermGoals: string;
|
|
longTermGoals: string;
|
|
keyMetrics: string;
|
|
|
|
// Step 6: Team & Culture
|
|
cultureDescription: string;
|
|
workEnvironment: string;
|
|
leadershipStyle: string;
|
|
communicationStyle: string;
|
|
|
|
// Step 7: Final Review
|
|
additionalContext: string;
|
|
}
|
|
|
|
const Onboarding: React.FC = () => {
|
|
const { org, upsertOrg, generateCompanyWiki } = useOrg();
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
if (org?.onboardingCompleted) {
|
|
navigate('/reports', { replace: true });
|
|
}
|
|
}, [org, navigate]);
|
|
|
|
const [step, setStep] = useState(0);
|
|
const [isGeneratingReport, setIsGeneratingReport] = useState(false);
|
|
const [formData, setFormData] = useState<OnboardingData>({
|
|
companyName: org?.name || '',
|
|
industry: '',
|
|
size: '',
|
|
description: '',
|
|
mission: '',
|
|
vision: '',
|
|
values: [],
|
|
foundingYear: '',
|
|
evolution: '',
|
|
majorMilestones: '',
|
|
advantages: '',
|
|
vulnerabilities: '',
|
|
competitors: '',
|
|
marketPosition: '',
|
|
currentChallenges: [],
|
|
shortTermGoals: '',
|
|
longTermGoals: '',
|
|
keyMetrics: '',
|
|
cultureDescription: '',
|
|
workEnvironment: '',
|
|
leadershipStyle: '',
|
|
communicationStyle: '',
|
|
additionalContext: ''
|
|
});
|
|
|
|
const steps = [
|
|
{
|
|
title: 'Company Basics',
|
|
description: 'Tell us about your company fundamentals'
|
|
},
|
|
{
|
|
title: 'Mission & Vision',
|
|
description: 'Define your purpose and direction'
|
|
},
|
|
{
|
|
title: 'Evolution & History',
|
|
description: 'Share your company\'s journey'
|
|
},
|
|
{
|
|
title: 'Competitive Position',
|
|
description: 'Understand your market position'
|
|
},
|
|
{
|
|
title: 'Goals & Challenges',
|
|
description: 'Current objectives and obstacles'
|
|
},
|
|
{
|
|
title: 'Team & Culture',
|
|
description: 'Describe your work environment'
|
|
},
|
|
{
|
|
title: 'Final Review',
|
|
description: 'Complete your company profile'
|
|
}
|
|
];
|
|
|
|
const handleNext = async () => {
|
|
// Prevent re-entry during generation
|
|
if (isGeneratingReport) return;
|
|
|
|
if (step < steps.length - 1) {
|
|
setStep(prev => prev + 1);
|
|
return;
|
|
}
|
|
|
|
// Final step: persist org & generate report
|
|
setIsGeneratingReport(true);
|
|
console.log('Starting onboarding completion...', { step });
|
|
try {
|
|
const newOrgData = {
|
|
name: formData.companyName,
|
|
industry: formData.industry,
|
|
size: formData.size,
|
|
description: formData.description,
|
|
mission: formData.mission,
|
|
vision: formData.vision,
|
|
values: formData.values.join(','),
|
|
foundingYear: formData.foundingYear,
|
|
evolution: formData.evolution,
|
|
majorMilestones: formData.majorMilestones,
|
|
advantages: formData.advantages,
|
|
vulnerabilities: formData.vulnerabilities,
|
|
competitors: formData.competitors,
|
|
marketPosition: formData.marketPosition,
|
|
currentChallenges: formData.currentChallenges.join(','),
|
|
shortTermGoals: formData.shortTermGoals,
|
|
longTermGoals: formData.longTermGoals,
|
|
keyMetrics: formData.keyMetrics,
|
|
cultureDescription: formData.cultureDescription,
|
|
workEnvironment: formData.workEnvironment,
|
|
leadershipStyle: formData.leadershipStyle,
|
|
communicationStyle: formData.communicationStyle,
|
|
additionalContext: formData.additionalContext,
|
|
onboardingCompleted: true
|
|
};
|
|
|
|
console.log('Saving org data...', newOrgData);
|
|
await upsertOrg(newOrgData);
|
|
console.log('Org data saved successfully');
|
|
|
|
console.log('Generating company wiki...');
|
|
await generateCompanyWiki({ ...newOrgData, orgId: org!.orgId });
|
|
console.log('Company wiki generated successfully');
|
|
|
|
// Small delay to ensure states are updated, then redirect
|
|
console.log('Redirecting to reports...');
|
|
setTimeout(() => {
|
|
console.log('Navigation executing...');
|
|
navigate('/reports', { replace: true });
|
|
console.log('Navigation called successfully');
|
|
}, 100);
|
|
} catch (error) {
|
|
console.error('Error completing onboarding:', error);
|
|
// Show detailed error to user for debugging
|
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
alert(`There was an error completing the setup: ${errorMessage}. Please check the console for more details and try again.`);
|
|
} finally {
|
|
setIsGeneratingReport(false);
|
|
}
|
|
};
|
|
|
|
const handleBack = () => {
|
|
if (step > 0) setStep(step - 1);
|
|
};
|
|
|
|
const addToArray = (field: 'values' | 'currentChallenges', value: string) => {
|
|
if (value.trim()) {
|
|
setFormData(prev => ({
|
|
...prev,
|
|
[field]: [...prev[field], value.trim()]
|
|
}));
|
|
}
|
|
};
|
|
|
|
const removeFromArray = (field: 'values' | 'currentChallenges', index: number) => {
|
|
setFormData(prev => ({
|
|
...prev,
|
|
[field]: prev[field].filter((_, i) => i !== index)
|
|
}));
|
|
};
|
|
|
|
const renderStep = () => {
|
|
switch (step) {
|
|
case 0:
|
|
return (
|
|
<div className="space-y-6">
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Company Name *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
value={formData.companyName}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, companyName: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
placeholder="Enter your company name"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Industry *
|
|
</label>
|
|
<select
|
|
value={formData.industry}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, industry: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
>
|
|
<option value="">Select industry</option>
|
|
<option value="Technology">Technology</option>
|
|
<option value="Healthcare">Healthcare</option>
|
|
<option value="Finance">Finance</option>
|
|
<option value="Manufacturing">Manufacturing</option>
|
|
<option value="Retail">Retail</option>
|
|
<option value="Professional Services">Professional Services</option>
|
|
<option value="Education">Education</option>
|
|
<option value="Media & Entertainment">Media & Entertainment</option>
|
|
<option value="Other">Other</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Company Size *
|
|
</label>
|
|
<select
|
|
value={formData.size}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, size: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
>
|
|
<option value="">Select size</option>
|
|
<option value="1-10">1-10 employees</option>
|
|
<option value="11-50">11-50 employees</option>
|
|
<option value="51-200">51-200 employees</option>
|
|
<option value="201-1000">201-1000 employees</option>
|
|
<option value="1000+">1000+ employees</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Company Description *
|
|
</label>
|
|
<textarea
|
|
value={formData.description}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, description: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={4}
|
|
placeholder="Describe what your company does, its products/services, and target market"
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
case 1:
|
|
return (
|
|
<div className="space-y-6">
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Mission Statement *
|
|
</label>
|
|
<textarea
|
|
value={formData.mission}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, mission: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={3}
|
|
placeholder="What is your company's purpose? Why does it exist?"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Vision Statement *
|
|
</label>
|
|
<textarea
|
|
value={formData.vision}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, vision: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={3}
|
|
placeholder="Where do you see your company in the future? What impact do you want to make?"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Core Values
|
|
</label>
|
|
<div className="space-y-2">
|
|
{formData.values.map((value, index) => (
|
|
<div key={index} className="flex items-center space-x-2">
|
|
<span className="flex-1 px-3 py-2 bg-[--background-tertiary] rounded-lg text-[--text-primary]">
|
|
{value}
|
|
</span>
|
|
<Button
|
|
size="sm"
|
|
variant="danger"
|
|
onClick={() => removeFromArray('values', index)}
|
|
>
|
|
Remove
|
|
</Button>
|
|
</div>
|
|
))}
|
|
<div className="flex space-x-2">
|
|
<input
|
|
type="text"
|
|
className="flex-1 px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
placeholder="Add a core value"
|
|
onKeyPress={(e) => {
|
|
if (e.key === 'Enter') {
|
|
addToArray('values', e.currentTarget.value);
|
|
e.currentTarget.value = '';
|
|
}
|
|
}}
|
|
/>
|
|
<Button
|
|
size="sm"
|
|
onClick={(e) => {
|
|
const input = (e.target as HTMLElement).parentElement?.querySelector('input');
|
|
if (input) {
|
|
addToArray('values', input.value);
|
|
input.value = '';
|
|
}
|
|
}}
|
|
>
|
|
Add
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
case 2:
|
|
return (
|
|
<div className="space-y-6">
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Founding Year
|
|
</label>
|
|
<input
|
|
type="text"
|
|
value={formData.foundingYear}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, foundingYear: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
placeholder="When was your company founded?"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Company Evolution *
|
|
</label>
|
|
<textarea
|
|
value={formData.evolution}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, evolution: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={4}
|
|
placeholder="How has your company evolved since its founding? What major changes or pivots have occurred?"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Major Milestones
|
|
</label>
|
|
<textarea
|
|
value={formData.majorMilestones}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, majorMilestones: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={4}
|
|
placeholder="List key achievements, product launches, funding rounds, or other significant milestones"
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
case 3:
|
|
return (
|
|
<div className="space-y-6">
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Competitive Advantages *
|
|
</label>
|
|
<textarea
|
|
value={formData.advantages}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, advantages: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={4}
|
|
placeholder="What gives your company a competitive edge? What are your unique strengths?"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Vulnerabilities & Weaknesses *
|
|
</label>
|
|
<textarea
|
|
value={formData.vulnerabilities}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, vulnerabilities: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={4}
|
|
placeholder="What are your company's current weaknesses or areas of vulnerability?"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Key Competitors
|
|
</label>
|
|
<textarea
|
|
value={formData.competitors}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, competitors: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={3}
|
|
placeholder="Who are your main competitors? How do you differentiate from them?"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Market Position
|
|
</label>
|
|
<textarea
|
|
value={formData.marketPosition}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, marketPosition: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={3}
|
|
placeholder="How do you position yourself in the market? What's your market share or standing?"
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
case 4:
|
|
return (
|
|
<div className="space-y-6">
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Current Challenges
|
|
</label>
|
|
<div className="space-y-2">
|
|
{formData.currentChallenges.map((challenge, index) => (
|
|
<div key={index} className="flex items-center space-x-2">
|
|
<span className="flex-1 px-3 py-2 bg-[--background-tertiary] rounded-lg text-[--text-primary]">
|
|
{challenge}
|
|
</span>
|
|
<Button
|
|
size="sm"
|
|
variant="danger"
|
|
onClick={() => removeFromArray('currentChallenges', index)}
|
|
>
|
|
Remove
|
|
</Button>
|
|
</div>
|
|
))}
|
|
<div className="flex space-x-2">
|
|
<input
|
|
type="text"
|
|
className="flex-1 px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
placeholder="Add a current challenge"
|
|
onKeyPress={(e) => {
|
|
if (e.key === 'Enter') {
|
|
addToArray('currentChallenges', e.currentTarget.value);
|
|
e.currentTarget.value = '';
|
|
}
|
|
}}
|
|
/>
|
|
<Button
|
|
size="sm"
|
|
onClick={(e) => {
|
|
const input = (e.target as HTMLElement).parentElement?.querySelector('input');
|
|
if (input) {
|
|
addToArray('currentChallenges', input.value);
|
|
input.value = '';
|
|
}
|
|
}}
|
|
>
|
|
Add
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Short-term Goals (6-12 months) *
|
|
</label>
|
|
<textarea
|
|
value={formData.shortTermGoals}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, shortTermGoals: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={4}
|
|
placeholder="What are your immediate priorities and goals for the next 6-12 months?"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Long-term Goals (1-3 years) *
|
|
</label>
|
|
<textarea
|
|
value={formData.longTermGoals}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, longTermGoals: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={4}
|
|
placeholder="What are your strategic objectives for the next 1-3 years?"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Key Metrics & Success Indicators
|
|
</label>
|
|
<textarea
|
|
value={formData.keyMetrics}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, keyMetrics: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={3}
|
|
placeholder="How do you measure success? What are your key performance indicators?"
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
case 5:
|
|
return (
|
|
<div className="space-y-6">
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Company Culture *
|
|
</label>
|
|
<textarea
|
|
value={formData.cultureDescription}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, cultureDescription: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={4}
|
|
placeholder="Describe your company culture. What's it like to work at your company?"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Work Environment *
|
|
</label>
|
|
<select
|
|
value={formData.workEnvironment}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, workEnvironment: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
>
|
|
<option value="">Select work environment</option>
|
|
<option value="Remote">Fully Remote</option>
|
|
<option value="Hybrid">Hybrid (Remote + Office)</option>
|
|
<option value="In-office">In-office</option>
|
|
<option value="Flexible">Flexible/Varies by role</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Leadership Style *
|
|
</label>
|
|
<textarea
|
|
value={formData.leadershipStyle}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, leadershipStyle: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={3}
|
|
placeholder="Describe the leadership approach and management style in your organization"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Communication Style *
|
|
</label>
|
|
<textarea
|
|
value={formData.communicationStyle}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, communicationStyle: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={3}
|
|
placeholder="How does your team communicate? What tools and processes do you use?"
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
case 6:
|
|
return (
|
|
<div className="space-y-6">
|
|
<div className="text-center mb-6">
|
|
<div className="text-4xl mb-4">📋</div>
|
|
<h3 className="text-xl font-semibold text-[--text-primary] mb-2">
|
|
Review Your Information
|
|
</h3>
|
|
<p className="text-[--text-secondary]">
|
|
Please review the information below and add any additional context
|
|
</p>
|
|
</div>
|
|
|
|
<div className="bg-[--background-tertiary] p-4 rounded-lg space-y-3">
|
|
<div><strong>Company:</strong> {formData.companyName}</div>
|
|
<div><strong>Industry:</strong> {formData.industry}</div>
|
|
<div><strong>Size:</strong> {formData.size}</div>
|
|
<div><strong>Mission:</strong> {formData.mission.substring(0, 100)}{formData.mission.length > 100 ? '...' : ''}</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-[--text-primary] mb-2">
|
|
Additional Context
|
|
</label>
|
|
<textarea
|
|
value={formData.additionalContext}
|
|
onChange={(e) => setFormData(prev => ({ ...prev, additionalContext: e.target.value }))}
|
|
className="w-full px-3 py-2 border border-[--border-color] rounded-lg bg-[--background-secondary] text-[--text-primary] focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
rows={4}
|
|
placeholder="Is there anything else important about your company that Auditly should know to provide better insights?"
|
|
/>
|
|
</div>
|
|
|
|
<div className="text-center pt-4">
|
|
<div className="text-4xl mb-4">🎉</div>
|
|
<h3 className="text-xl font-semibold text-[--text-primary]">
|
|
Ready to Complete Setup!
|
|
</h3>
|
|
<p className="text-[--text-secondary]">
|
|
{isGeneratingReport
|
|
? 'Generating your personalized company insights...'
|
|
: 'Once you complete this step, you\'ll have access to all Auditly features and your personalized company wiki will be generated.'
|
|
}
|
|
</p>
|
|
{isGeneratingReport && (
|
|
<div className="mt-4 flex items-center justify-center">
|
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"></div>
|
|
<span className="ml-3 text-[--text-secondary]">Creating your company profile...</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
default:
|
|
return null;
|
|
}
|
|
};
|
|
|
|
const canProceed = () => {
|
|
switch (step) {
|
|
case 0:
|
|
return formData.companyName.trim().length > 0 && formData.industry && formData.size && formData.description.trim().length > 0;
|
|
case 1:
|
|
return formData.mission.trim().length > 0 && formData.vision.trim().length > 0;
|
|
case 2:
|
|
return formData.evolution.trim().length > 0;
|
|
case 3:
|
|
return formData.advantages.trim().length > 0 && formData.vulnerabilities.trim().length > 0;
|
|
case 4:
|
|
return formData.shortTermGoals.trim().length > 0 && formData.longTermGoals.trim().length > 0;
|
|
case 5:
|
|
return formData.cultureDescription.trim().length > 0 && formData.workEnvironment && formData.leadershipStyle.trim().length > 0 && formData.communicationStyle.trim().length > 0;
|
|
case 6:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-[--background-primary] flex items-center justify-center p-4">
|
|
<div className="max-w-4xl w-full">
|
|
<div className="text-center mb-8">
|
|
<h1 className="text-3xl font-bold text-[--text-primary] mb-2">
|
|
Welcome to Auditly
|
|
</h1>
|
|
<p className="text-[--text-secondary]">
|
|
Let's build a comprehensive profile of your organization to provide the best insights
|
|
</p>
|
|
</div>
|
|
|
|
{/* Progress indicator */}
|
|
<div className="mb-8">
|
|
<FigmaProgress
|
|
currentStep={step + 1}
|
|
steps={steps.map((s, i) => ({ number: i + 1, title: s.title }))}
|
|
/>
|
|
</div>
|
|
|
|
<Card className="max-w-none">
|
|
<div className="mb-6">
|
|
<h2 className="text-xl font-semibold text-[--text-primary] mb-2">
|
|
{steps[step].title}
|
|
</h2>
|
|
<p className="text-[--text-secondary]">
|
|
{steps[step].description}
|
|
</p>
|
|
</div>
|
|
|
|
{renderStep()}
|
|
|
|
<div className="flex justify-between mt-8">
|
|
<Button
|
|
variant="secondary"
|
|
onClick={handleBack}
|
|
disabled={step === 0}
|
|
>
|
|
Back
|
|
</Button>
|
|
<Button
|
|
onClick={handleNext}
|
|
disabled={!canProceed() || isGeneratingReport}
|
|
>
|
|
{isGeneratingReport
|
|
? 'Generating Wiki...'
|
|
: step === steps.length - 1 ? 'Complete Setup & Generate Wiki' : 'Next'
|
|
}
|
|
</Button>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Onboarding;
|