feat: major UI overhaul with new components and enhanced UX
- Add comprehensive Company Wiki feature with complete state management - CompanyWikiManager, empty states, invite modals - Implement new Chat system with enhanced layout and components - ChatLayout, ChatSidebar, MessageThread, FileUploadInput - Create modern Login and OTP verification flows - LoginNew page, OTPVerification component - Add new Employee Forms system with enhanced controller - Introduce Figma-based design components and multiple choice inputs - Add new font assets (NeueMontreal) and robot images for onboarding - Enhance existing components with improved styling and functionality - Update build configuration and dependencies - Remove deprecated ModernLogin component
This commit is contained in:
@@ -1,47 +1,41 @@
|
||||
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';
|
||||
import { EnhancedFigmaQuestion, FigmaQuestionCard, EnhancedFigmaInput } from '../components/figma/EnhancedFigmaQuestion';
|
||||
import { FigmaInput, FigmaSelect } from '../components/figma/FigmaInput';
|
||||
import { FigmaMultipleChoice } from '../components/figma/FigmaMultipleChoice';
|
||||
|
||||
interface OnboardingData {
|
||||
// Step 1: Company Basics
|
||||
// Step 0: Company Details
|
||||
companyName: string;
|
||||
industry: string;
|
||||
size: string;
|
||||
description: string;
|
||||
yourName: string;
|
||||
|
||||
// Step 2: Mission & Vision
|
||||
// Step 1: Company Size
|
||||
companySize: string;
|
||||
|
||||
// Step 2: Mission
|
||||
mission: string;
|
||||
|
||||
// Later steps
|
||||
industry: string;
|
||||
description: 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;
|
||||
}
|
||||
|
||||
@@ -59,10 +53,11 @@ const Onboarding: React.FC = () => {
|
||||
const [isGeneratingReport, setIsGeneratingReport] = useState(false);
|
||||
const [formData, setFormData] = useState<OnboardingData>({
|
||||
companyName: org?.name || '',
|
||||
industry: '',
|
||||
size: '',
|
||||
description: '',
|
||||
yourName: '',
|
||||
companySize: '',
|
||||
mission: '',
|
||||
industry: '',
|
||||
description: '',
|
||||
vision: '',
|
||||
values: [],
|
||||
foundingYear: '',
|
||||
@@ -85,20 +80,28 @@ const Onboarding: React.FC = () => {
|
||||
|
||||
const steps = [
|
||||
{
|
||||
title: 'Company Basics',
|
||||
description: 'Tell us about your company fundamentals'
|
||||
title: 'Company Details',
|
||||
description: 'Basic information about your company'
|
||||
},
|
||||
{
|
||||
title: 'Mission & Vision',
|
||||
description: 'Define your purpose and direction'
|
||||
title: 'Company Size',
|
||||
description: 'How many people work at your company'
|
||||
},
|
||||
{
|
||||
title: 'Evolution & History',
|
||||
description: 'Share your company\'s journey'
|
||||
title: 'Mission Statement',
|
||||
description: 'What is the mission of your company'
|
||||
},
|
||||
{
|
||||
title: 'Competitive Position',
|
||||
description: 'Understand your market position'
|
||||
title: 'Vision & Values',
|
||||
description: 'Your company\'s vision and core values'
|
||||
},
|
||||
{
|
||||
title: 'Company History',
|
||||
description: 'How your company has evolved'
|
||||
},
|
||||
{
|
||||
title: 'Market Position',
|
||||
description: 'Your competitive landscape'
|
||||
},
|
||||
{
|
||||
title: 'Goals & Challenges',
|
||||
@@ -106,16 +109,11 @@ const Onboarding: React.FC = () => {
|
||||
},
|
||||
{
|
||||
title: 'Team & Culture',
|
||||
description: 'Describe your work environment'
|
||||
},
|
||||
{
|
||||
title: 'Final Review',
|
||||
description: 'Complete your company profile'
|
||||
description: 'Your work environment and culture'
|
||||
}
|
||||
];
|
||||
|
||||
const handleNext = async () => {
|
||||
// Prevent re-entry during generation
|
||||
if (isGeneratingReport) return;
|
||||
|
||||
if (step < steps.length - 1) {
|
||||
@@ -125,12 +123,11 @@ const Onboarding: React.FC = () => {
|
||||
|
||||
// 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,
|
||||
size: formData.companySize,
|
||||
description: formData.description,
|
||||
mission: formData.mission,
|
||||
vision: formData.vision,
|
||||
@@ -154,24 +151,14 @@ const Onboarding: React.FC = () => {
|
||||
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 {
|
||||
@@ -183,462 +170,160 @@ const Onboarding: React.FC = () => {
|
||||
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 updateFormData = (field: keyof OnboardingData, value: string) => {
|
||||
setFormData(prev => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
const canProceed = () => {
|
||||
switch (step) {
|
||||
case 0: // Company Details
|
||||
return formData.companyName.trim().length > 0 && formData.yourName.trim().length > 0;
|
||||
case 1: // Company Size
|
||||
return formData.companySize.length > 0;
|
||||
case 2: // Mission
|
||||
return formData.mission.trim().length > 0;
|
||||
case 3: // Vision & Values
|
||||
return formData.vision.trim().length > 0;
|
||||
case 4: // History
|
||||
return formData.evolution.trim().length > 0;
|
||||
case 5: // Market Position
|
||||
return formData.advantages.trim().length > 0;
|
||||
case 6: // Goals
|
||||
return formData.shortTermGoals.trim().length > 0;
|
||||
case 7: // Culture
|
||||
return formData.cultureDescription.trim().length > 0;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const removeFromArray = (field: 'values' | 'currentChallenges', index: number) => {
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
[field]: prev[field].filter((_, i) => i !== index)
|
||||
}));
|
||||
};
|
||||
|
||||
const renderStep = () => {
|
||||
const renderStepContent = () => {
|
||||
switch (step) {
|
||||
case 0:
|
||||
case 0: // Company Details
|
||||
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 className="self-stretch flex flex-col justify-start items-start gap-6">
|
||||
<FigmaInput
|
||||
label="Your Name"
|
||||
placeholder="John Doe"
|
||||
value={formData.yourName}
|
||||
onChange={(e) => updateFormData('yourName', e.target.value)}
|
||||
required
|
||||
/>
|
||||
<FigmaInput
|
||||
label="Company Name"
|
||||
placeholder="Doe Enterprises"
|
||||
value={formData.companyName}
|
||||
onChange={(e) => updateFormData('companyName', e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
case 1:
|
||||
case 1: // Company Size
|
||||
return (
|
||||
<FigmaMultipleChoice
|
||||
options={['1-10', '10-25', '25-50', '50-100', '100+']}
|
||||
selectedValue={formData.companySize}
|
||||
onSelect={(value) => updateFormData('companySize', value)}
|
||||
/>
|
||||
);
|
||||
|
||||
case 2: // Mission
|
||||
return (
|
||||
<FigmaQuestionCard
|
||||
question="What is the mission of your company?"
|
||||
description="Description about the question"
|
||||
>
|
||||
<EnhancedFigmaInput
|
||||
placeholder="Type your answer...."
|
||||
value={formData.mission}
|
||||
onChange={(value) => updateFormData('mission', value)}
|
||||
multiline
|
||||
rows={6}
|
||||
/>
|
||||
</FigmaQuestionCard>
|
||||
);
|
||||
|
||||
case 3: // Vision & Values
|
||||
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
|
||||
<FigmaQuestionCard
|
||||
question="What is your company's vision?"
|
||||
description="Where do you see your company in the future?"
|
||||
>
|
||||
<EnhancedFigmaInput
|
||||
placeholder="Type your answer...."
|
||||
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?"
|
||||
onChange={(value) => updateFormData('vision', value)}
|
||||
multiline
|
||||
rows={4}
|
||||
/>
|
||||
</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>
|
||||
</FigmaQuestionCard>
|
||||
</div>
|
||||
);
|
||||
|
||||
case 2:
|
||||
case 4: // History
|
||||
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>
|
||||
<FigmaQuestionCard
|
||||
question="How has your company evolved?"
|
||||
description="Tell us about your company's journey and evolution"
|
||||
>
|
||||
<EnhancedFigmaInput
|
||||
placeholder="Type your answer...."
|
||||
value={formData.evolution}
|
||||
onChange={(value) => updateFormData('evolution', value)}
|
||||
multiline
|
||||
rows={6}
|
||||
/>
|
||||
</FigmaQuestionCard>
|
||||
);
|
||||
|
||||
case 3:
|
||||
case 5: // Market Position
|
||||
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>
|
||||
<FigmaQuestionCard
|
||||
question="What are your competitive advantages?"
|
||||
description="What gives your company a competitive edge?"
|
||||
>
|
||||
<EnhancedFigmaInput
|
||||
placeholder="Type your answer...."
|
||||
value={formData.advantages}
|
||||
onChange={(value) => updateFormData('advantages', value)}
|
||||
multiline
|
||||
rows={6}
|
||||
/>
|
||||
</FigmaQuestionCard>
|
||||
);
|
||||
|
||||
case 4:
|
||||
case 6: // Goals
|
||||
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>
|
||||
<FigmaQuestionCard
|
||||
question="What are your short-term goals?"
|
||||
description="What are your priorities for the next 6-12 months?"
|
||||
>
|
||||
<EnhancedFigmaInput
|
||||
placeholder="Type your answer...."
|
||||
value={formData.shortTermGoals}
|
||||
onChange={(value) => updateFormData('shortTermGoals', value)}
|
||||
multiline
|
||||
rows={6}
|
||||
/>
|
||||
</FigmaQuestionCard>
|
||||
);
|
||||
|
||||
case 5:
|
||||
case 7: // Culture
|
||||
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>
|
||||
<FigmaQuestionCard
|
||||
question="Describe your company culture"
|
||||
description="What's it like to work at your company?"
|
||||
>
|
||||
<EnhancedFigmaInput
|
||||
placeholder="Type your answer...."
|
||||
value={formData.cultureDescription}
|
||||
onChange={(value) => updateFormData('cultureDescription', value)}
|
||||
multiline
|
||||
rows={6}
|
||||
/>
|
||||
</FigmaQuestionCard>
|
||||
);
|
||||
|
||||
default:
|
||||
@@ -646,79 +331,43 @@ const Onboarding: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const canProceed = () => {
|
||||
// Question text for each step
|
||||
const getQuestionText = () => {
|
||||
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;
|
||||
case 0: return 'Company Details';
|
||||
case 1: return `How many people work at ${formData.companyName || '[Company Name]'}?`;
|
||||
case 2: return 'What is the mission of your company?';
|
||||
case 3: return 'What is your company\'s vision?';
|
||||
case 4: return 'How has your company evolved?';
|
||||
case 5: return 'What are your competitive advantages?';
|
||||
case 6: return 'What are your short-term goals?';
|
||||
case 7: return 'Describe your company culture';
|
||||
default: return 'Onboarding';
|
||||
}
|
||||
};
|
||||
|
||||
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 className="min-h-screen bg-[--Neutrals-NeutralSlate0] flex items-center justify-center">
|
||||
<EnhancedFigmaQuestion
|
||||
question={getQuestionText()}
|
||||
currentStep={step + 1}
|
||||
totalSteps={steps.length}
|
||||
stepTitle={steps[step].title}
|
||||
onBack={handleBack}
|
||||
onNext={handleNext}
|
||||
nextDisabled={!canProceed() || isGeneratingReport}
|
||||
backDisabled={step === 0}
|
||||
showBackButton={step > 0}
|
||||
nextText={
|
||||
isGeneratingReport
|
||||
? 'Generating...'
|
||||
: step === steps.length - 1
|
||||
? 'Complete Setup'
|
||||
: 'Next'
|
||||
}
|
||||
>
|
||||
{renderStepContent()}
|
||||
</EnhancedFigmaQuestion>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user