1
0
mirror of https://github.com/kamranahmedse/developer-roadmap.git synced 2025-09-02 22:02:39 +02:00

Add goal selection

This commit is contained in:
Kamran Ahmed
2025-05-28 16:50:16 +01:00
parent 90851f38f3
commit 53f86bb319
2 changed files with 69 additions and 54 deletions

1
.astro/types.d.ts vendored
View File

@@ -1,2 +1 @@
/// <reference types="astro/client" /> /// <reference types="astro/client" />
/// <reference path="content.d.ts" />

View File

@@ -27,20 +27,58 @@ export function UserPersonaForm(props: UserPersonaFormProps) {
onSubmit, onSubmit,
isLoading, isLoading,
} = props; } = props;
const [expertise, setExpertise] = useState( const [expertise, setExpertise] = useState(defaultValues?.expertise ?? '');
defaultValues?.expertise ?? 'no-experience',
);
const [hasInitialGoal, setHasInitialGoal] = useState(!!defaultValues?.goal); const goalOptions = [
'Finding a job',
'Learning for fun',
'Building a side project',
'Switching careers',
'Getting a promotion',
'Filling knowledge gaps',
'Other',
];
const getInitialGoalSelection = () => {
if (!defaultValues?.goal) {
return '';
}
// Check if the goal matches any predefined option
for (const option of goalOptions.slice(0, -1)) {
// Exclude 'Other'
if (defaultValues.goal.startsWith(option)) {
return option;
}
}
return 'Other';
};
const [selectedGoal, setSelectedGoal] = useState(getInitialGoalSelection());
const [goal, setGoal] = useState(defaultValues?.goal ?? ''); const [goal, setGoal] = useState(defaultValues?.goal ?? '');
const [commit, setCommit] = useState(defaultValues?.commit ?? ''); const [commit, setCommit] = useState(defaultValues?.commit ?? '');
const expertiseFieldId = useId(); const expertiseFieldId = useId();
const goalFieldId = useId(); const goalFieldId = useId();
const goalSelectId = useId();
const commitFieldId = useId(); const commitFieldId = useId();
const goalRef = useRef<HTMLTextAreaElement>(null); const goalRef = useRef<HTMLTextAreaElement>(null);
const handleGoalSelectionChange = (value: string) => {
setSelectedGoal(value);
if (value === 'Other') {
setGoal('');
setTimeout(() => {
goalRef.current?.focus();
}, 0);
} else {
setGoal(value);
}
};
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault(); e.preventDefault();
onSubmit({ expertise, goal, commit }); onSubmit({ expertise, goal, commit });
@@ -60,12 +98,11 @@ export function UserPersonaForm(props: UserPersonaFormProps) {
<SelectNative <SelectNative
id={expertiseFieldId} id={expertiseFieldId}
value={expertise} value={expertise}
defaultValue={expertise}
onChange={(e) => setExpertise(e.target.value)} onChange={(e) => setExpertise(e.target.value)}
className="h-[40px] border-gray-300 text-sm focus:border-gray-500 focus:ring-1 focus:ring-gray-500" className="h-[40px] border-gray-300 text-sm focus:border-gray-500 focus:ring-1 focus:ring-gray-500"
> >
<option value="" selected hidden> <option value="">Select your expertise</option>
Select your expertise
</option>
{[ {[
'No experience (just starting out)', 'No experience (just starting out)',
'Beginner (less than 1 year of experience)', 'Beginner (less than 1 year of experience)',
@@ -79,60 +116,39 @@ export function UserPersonaForm(props: UserPersonaFormProps) {
))} ))}
</SelectNative> </SelectNative>
</div> </div>
<div className="flex flex-col gap-3"> <div className="flex flex-col gap-3">
<label <label
className="text-sm font-medium text-gray-700" className="text-sm font-medium text-gray-700"
htmlFor={goalFieldId} htmlFor={goalSelectId}
> >
What is your goal?{' '} What is your goal?
{hasInitialGoal &&
!defaultValues?.goal &&
`Tell us more about yourself`}
</label> </label>
{!hasInitialGoal && ( <SelectNative
<div className="flex flex-row flex-wrap gap-2"> id={goalSelectId}
{[ value={selectedGoal}
'Finding a job', onChange={(e) => handleGoalSelectionChange(e.target.value)}
'Learning for fun', className="h-[40px] border-gray-300 text-sm focus:border-gray-500 focus:ring-1 focus:ring-gray-500"
'Building a side project',
'Switching careers',
'Getting a promotion',
'Filling knowledge gaps',
'Other (tell us more)',
].map((goalTemplate) => (
<button
key={goalTemplate}
className="rounded-lg border border-gray-200 bg-gray-50 px-4 py-2 text-sm text-gray-600 transition-all hover:border-gray-300 hover:border-gray-400 hover:bg-gray-100"
onClick={() => {
if (goalTemplate !== 'Other (tell us more)') {
setGoal(`${goalTemplate}.`);
}
setHasInitialGoal(true);
setTimeout(() => {
goalRef.current?.focus();
}, 0);
}}
type="button"
> >
{goalTemplate} <option value="">Select your goal</option>
</button> {goalOptions.map((goalOption) => (
<option key={goalOption} value={goalOption}>
{goalOption}
</option>
))} ))}
</div> </SelectNative>
)}
{selectedGoal === 'Other' && (
<textarea <textarea
ref={goalRef} ref={goalRef}
id={goalFieldId} id={goalFieldId}
className={cn( className="block min-h-24 w-full resize-none rounded-lg border border-gray-300 bg-white px-4 py-3 text-sm outline-none placeholder:text-gray-400 focus:border-gray-500 focus:ring-1 focus:ring-gray-500"
'block min-h-24 w-full resize-none rounded-lg border border-gray-300 bg-white px-4 py-3 text-sm outline-none placeholder:text-gray-400 focus:border-gray-500 focus:ring-1 focus:ring-gray-500', placeholder="e.g. need to find a job as soon as possible"
!hasInitialGoal && 'hidden',
)}
placeholder={`e.g. need to find a job as soon as possible`}
value={goal} value={goal}
onChange={(e) => setGoal(e.target.value)} onChange={(e) => setGoal(e.target.value)}
/> />
)}
</div> </div>
<div className="flex flex-col gap-3"> <div className="flex flex-col gap-3">