aethex-forge/client/components/onboarding/Experience.tsx
Builder.io 0c168ce5fc Create experience component
cgen-e3faa486fa3b43b5a34fa116a43edd2f
2025-08-05 22:49:01 +00:00

221 lines
7.8 KiB
TypeScript

import { OnboardingData } from "@/pages/Onboarding";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Badge } from "@/components/ui/badge";
import { ArrowLeft, ArrowRight, Plus, X } from "lucide-react";
import { useState } from "react";
interface ExperienceProps {
data: OnboardingData;
updateData: (data: Partial<OnboardingData>) => void;
nextStep: () => void;
prevStep: () => void;
}
const experienceLevels = [
{ id: 'beginner', label: 'Beginner', description: 'New to the field' },
{ id: 'intermediate', label: 'Intermediate', description: '1-3 years experience' },
{ id: 'advanced', label: 'Advanced', description: '3-7 years experience' },
{ id: 'expert', label: 'Expert', description: '7+ years experience' },
];
const skillSuggestions = {
'game-developer': [
'Unity', 'Unreal Engine', 'C#', 'C++', 'JavaScript', 'Python', 'Blender', '3D Modeling',
'Game Design', 'Level Design', 'Animation', 'Shader Programming', 'Roblox Development'
],
'client': [
'Project Management', 'Business Strategy', 'Product Development', 'Marketing',
'Team Leadership', 'Budget Management', 'Quality Assurance', 'User Experience'
],
'member': [
'Research', 'Innovation', 'Technology Trends', 'Community Building', 'Networking',
'Content Creation', 'Documentation', 'Knowledge Sharing'
],
'customer': [
'Gaming', 'Technology Adoption', 'User Feedback', 'Beta Testing', 'Community Participation',
'Content Consumption', 'Product Evaluation'
]
};
export default function Experience({ data, updateData, nextStep, prevStep }: ExperienceProps) {
const [newSkill, setNewSkill] = useState('');
const handleLevelChange = (level: string) => {
updateData({
experience: {
...data.experience,
level
}
});
};
const handleSkillAdd = (skill: string) => {
if (skill && !data.experience.skills.includes(skill)) {
updateData({
experience: {
...data.experience,
skills: [...data.experience.skills, skill]
}
});
}
setNewSkill('');
};
const handleSkillRemove = (skillToRemove: string) => {
updateData({
experience: {
...data.experience,
skills: data.experience.skills.filter(skill => skill !== skillToRemove)
}
});
};
const handleProjectsChange = (projects: string) => {
updateData({
experience: {
...data.experience,
previousProjects: projects
}
});
};
const isValid = data.experience.level && data.experience.skills.length > 0;
const suggestions = data.userType ? skillSuggestions[data.userType] || [] : [];
return (
<div className="space-y-6">
<div className="text-center space-y-2">
<p className="text-muted-foreground">
Help us understand your background and expertise
</p>
</div>
<div className="max-w-2xl mx-auto space-y-6">
{/* Experience Level */}
<div className="space-y-3">
<Label className="text-sm font-medium">Experience Level *</Label>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{experienceLevels.map((level) => (
<button
key={level.id}
onClick={() => handleLevelChange(level.id)}
className={`p-4 rounded-lg border-2 text-left transition-all duration-200 ${
data.experience.level === level.id
? 'border-aethex-500 bg-aethex-500/10 glow-purple'
: 'border-border/50 hover:border-aethex-400/50 bg-background/50'
}`}
>
<div className="font-medium">{level.label}</div>
<div className="text-sm text-muted-foreground">{level.description}</div>
</button>
))}
</div>
</div>
{/* Skills */}
<div className="space-y-3">
<Label className="text-sm font-medium">Skills & Technologies *</Label>
{/* Current Skills */}
{data.experience.skills.length > 0 && (
<div className="flex flex-wrap gap-2">
{data.experience.skills.map((skill) => (
<Badge
key={skill}
variant="secondary"
className="bg-aethex-500/20 text-aethex-300 border-aethex-500/30 hover:bg-aethex-500/30"
>
{skill}
<X
className="h-3 w-3 ml-1 cursor-pointer hover:text-destructive"
onClick={() => handleSkillRemove(skill)}
/>
</Badge>
))}
</div>
)}
{/* Add Custom Skill */}
<div className="flex gap-2">
<input
type="text"
value={newSkill}
onChange={(e) => setNewSkill(e.target.value)}
placeholder="Add a skill..."
className="flex-1 px-3 py-2 text-sm rounded-md border border-border/50 bg-background/50 focus:border-aethex-400 focus:outline-none"
onKeyPress={(e) => e.key === 'Enter' && handleSkillAdd(newSkill)}
/>
<Button
size="sm"
onClick={() => handleSkillAdd(newSkill)}
disabled={!newSkill.trim()}
className="bg-gradient-to-r from-aethex-500 to-neon-blue"
>
<Plus className="h-4 w-4" />
</Button>
</div>
{/* Skill Suggestions */}
{suggestions.length > 0 && (
<div className="space-y-2">
<Label className="text-xs text-muted-foreground">Suggested skills:</Label>
<div className="flex flex-wrap gap-2">
{suggestions
.filter(skill => !data.experience.skills.includes(skill))
.slice(0, 8)
.map((skill) => (
<button
key={skill}
onClick={() => handleSkillAdd(skill)}
className="px-3 py-1 text-xs rounded-full border border-border/50 hover:border-aethex-400/50 hover:bg-aethex-500/10 transition-all duration-200"
>
{skill}
</button>
))}
</div>
</div>
)}
</div>
{/* Previous Projects (optional for some user types) */}
{(data.userType === 'game-developer' || data.userType === 'client') && (
<div className="space-y-2">
<Label htmlFor="projects" className="text-sm font-medium">
Previous Projects or Experience
<span className="text-muted-foreground"> (optional)</span>
</Label>
<Textarea
id="projects"
value={data.experience.previousProjects || ''}
onChange={(e) => handleProjectsChange(e.target.value)}
placeholder="Tell us about your previous projects, experiences, or achievements..."
className="bg-background/50 border-border/50 focus:border-aethex-400 min-h-[100px]"
/>
</div>
)}
</div>
<div className="flex justify-between pt-6">
<Button
variant="outline"
onClick={prevStep}
className="flex items-center space-x-2"
>
<ArrowLeft className="h-4 w-4" />
<span>Back</span>
</Button>
<Button
onClick={nextStep}
disabled={!isValid}
className="flex items-center space-x-2 bg-gradient-to-r from-aethex-500 to-neon-blue hover:from-aethex-600 hover:to-neon-blue/90"
>
<span>Continue</span>
<ArrowRight className="h-4 w-4" />
</Button>
</div>
</div>
);
}