mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-09-02 13:52:46 +02:00
Add goal selection
This commit is contained in:
1
.astro/types.d.ts
vendored
1
.astro/types.d.ts
vendored
@@ -1,2 +1 @@
|
|||||||
/// <reference types="astro/client" />
|
/// <reference types="astro/client" />
|
||||||
/// <reference path="content.d.ts" />
|
|
@@ -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',
|
<option value="">Select your goal</option>
|
||||||
'Getting a promotion',
|
{goalOptions.map((goalOption) => (
|
||||||
'Filling knowledge gaps',
|
<option key={goalOption} value={goalOption}>
|
||||||
'Other (tell us more)',
|
{goalOption}
|
||||||
].map((goalTemplate) => (
|
</option>
|
||||||
<button
|
))}
|
||||||
key={goalTemplate}
|
</SelectNative>
|
||||||
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);
|
{selectedGoal === 'Other' && (
|
||||||
setTimeout(() => {
|
<textarea
|
||||||
goalRef.current?.focus();
|
ref={goalRef}
|
||||||
}, 0);
|
id={goalFieldId}
|
||||||
}}
|
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"
|
||||||
type="button"
|
placeholder="e.g. need to find a job as soon as possible"
|
||||||
>
|
value={goal}
|
||||||
{goalTemplate}
|
onChange={(e) => setGoal(e.target.value)}
|
||||||
</button>
|
/>
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<textarea
|
|
||||||
ref={goalRef}
|
|
||||||
id={goalFieldId}
|
|
||||||
className={cn(
|
|
||||||
'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',
|
|
||||||
!hasInitialGoal && 'hidden',
|
|
||||||
)}
|
|
||||||
placeholder={`e.g. need to find a job as soon as possible`}
|
|
||||||
value={goal}
|
|
||||||
onChange={(e) => setGoal(e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
|
Reference in New Issue
Block a user