Roadmap to becoming a developer in 2022
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

221 lines
5.7 KiB

import { useEffect, useState } from 'react';
import { Stepper } from '../Stepper';
import { Step0, type ValidTeamType } from './Step0';
import { Step1, type ValidTeamSize } from './Step1';
import { Step2 } from './Step2';
import { httpGet } from '../../lib/http';
import { getUrlParams, setUrlParams } from '../../lib/browser';
import { pageProgressMessage } from '../../stores/page';
import type { TeamResourceConfig } from './RoadmapSelector';
import { Step3 } from './Step3';
import { Step4 } from './Step4';
import { useToast } from '../../hooks/use-toast';
export interface TeamDocument {
_id?: string;
name: string;
avatar?: string;
creatorId: string;
links: {
website?: string;
github?: string;
linkedIn?: string;
};
type: ValidTeamType;
personalProgressOnly?: boolean;
canMemberSendInvite: boolean;
teamSize?: ValidTeamSize;
createdAt: Date;
updatedAt: Date;
}
export function CreateTeamForm() {
// Can't use hook `useParams` because it runs asynchronously
const { s: queryStepIndex, t: teamId } = getUrlParams();
const toast = useToast();
const [team, setTeam] = useState<TeamDocument>();
const [loadingTeam, setLoadingTeam] = useState(!!teamId && !team?._id);
const [stepIndex, setStepIndex] = useState(0);
async function loadTeam(
teamIdToFetch: string,
requiredStepIndex: number | string,
) {
const { response, error } = await httpGet<TeamDocument>(
`${import.meta.env.PUBLIC_API_URL}/v1-get-team/${teamIdToFetch}`,
);
if (error || !response) {
toast.error(error?.message || 'Error loading team');
window.location.href = '/account';
return;
}
const requiredStepIndexNumber = parseInt(requiredStepIndex as string, 10);
const completedSteps = Array(requiredStepIndexNumber)
.fill(1)
.map((_, counter) => counter);
setTeam(response);
setSelectedTeamType(response.type);
setCompletedSteps(completedSteps);
setStepIndex(requiredStepIndexNumber);
await loadTeamResourceConfig(teamIdToFetch);
}
const [teamResourceConfig, setTeamResourceConfig] =
useState<TeamResourceConfig>([]);
async function loadTeamResourceConfig(teamId: string) {
const { error, response } = await httpGet<TeamResourceConfig>(
`${import.meta.env.PUBLIC_API_URL}/v1-get-team-resource-config/${teamId}`,
);
if (error || !Array.isArray(response)) {
console.error(error);
return;
}
setTeamResourceConfig(response);
}
useEffect(() => {
if (!teamId || !queryStepIndex || team) {
return;
}
pageProgressMessage.set('Fetching team');
setLoadingTeam(true);
loadTeam(teamId, queryStepIndex).finally(() => {
setLoadingTeam(false);
pageProgressMessage.set('');
});
// fetch team and move to step
}, [teamId, queryStepIndex]);
const [selectedTeamType, setSelectedTeamType] = useState<ValidTeamType>(
team?.type || 'company',
);
const [completedSteps, setCompletedSteps] = useState([0]);
if (loadingTeam) {
return null;
}
let stepForm = null;
if (stepIndex === 0) {
stepForm = (
<Step0
team={team}
selectedTeamType={selectedTeamType}
setSelectedTeamType={setSelectedTeamType}
onStepComplete={() => {
if (team?._id) {
setUrlParams({ t: team._id, s: '1' });
}
setCompletedSteps([0]);
setStepIndex(1);
}}
/>
);
} else if (stepIndex === 1) {
stepForm = (
<Step1
team={team}
onBack={() => {
if (team?._id) {
setUrlParams({ t: team._id, s: '0' });
}
setStepIndex(0);
}}
onStepComplete={(team: TeamDocument) => {
const createdTeamId = team._id!;
setUrlParams({ t: createdTeamId, s: '2' });
setCompletedSteps([0, 1]);
setStepIndex(2);
setTeam(team);
}}
selectedTeamType={selectedTeamType}
/>
);
} else if (stepIndex === 2) {
stepForm = (
<Step2
team={team!}
teamResourceConfig={teamResourceConfig}
setTeamResourceConfig={setTeamResourceConfig}
onBack={() => {
if (team) {
setUrlParams({ t: team._id!, s: '1' });
}
setStepIndex(1);
}}
onNext={() => {
setUrlParams({ t: teamId!, s: '3' });
setCompletedSteps([0, 1, 2]);
setStepIndex(3);
}}
/>
);
} else if (stepIndex === 3) {
stepForm = (
<Step3
team={team}
onBack={() => {
if (team) {
setUrlParams({ t: team._id!, s: '2' });
}
setStepIndex(2);
}}
onNext={() => {
if (team) {
setUrlParams({ t: team._id!, s: '4' });
}
setCompletedSteps([0, 1, 2, 3]);
setStepIndex(4);
}}
/>
);
} else if (stepIndex === 4) {
stepForm = <Step4 team={team!} />;
}
return (
<div className={'mx-auto max-w-[700px] py-1 md:py-6'}>
<div
className={
'mb-3 flex flex-col items-start border-b pb-3 md:mb-8 md:items-center md:border-b-0 md:pb-0'
}
>
<h1 className={'text-xl font-bold md:text-4xl'}>Create Team</h1>
<p className={'mt-1 text-sm text-gray-500 md:mt-2 md:text-base'}>
Complete the steps below to create your team
</p>
</div>
<div className="mb-8 mt-8 hidden w-full sm:flex">
<Stepper
activeIndex={stepIndex}
completeSteps={completedSteps}
steps={[
{ label: 'Type' },
{ label: 'Details' },
{ label: 'Skills' },
{ label: 'Members' },
]}
/>
</div>
{stepForm}
</div>
);
}