Skills Selector (#124)

* skills map in context

* using react-select

* removed sudo from package.json

* fixed lint and format issues
This commit is contained in:
dan13ram
2020-09-30 08:51:13 +05:30
committed by GitHub
parent 375c39b133
commit d5844dd8db
13 changed files with 264 additions and 22 deletions

View File

@@ -3,6 +3,8 @@ import { FlexContainer } from 'components/Container';
import { SetupContext } from 'contexts/SetupContext';
import React, { useContext } from 'react';
import { SetupSkills } from './SetupSkills';
export const SetupProfession: React.FC = () => {
const { useProgress } = useContext(SetupContext);
const numProgressSteps = 3;
@@ -10,9 +12,7 @@ export const SetupProfession: React.FC = () => {
return (
<FlexContainer flex={1}>
{currentProgress === 0 && (
<MetaHeading mb={10}>What are your superpowers?</MetaHeading>
)}
{currentProgress === 0 && <SetupSkills />}
{currentProgress === 1 && <MetaHeading mb={10}>Availability</MetaHeading>}
{currentProgress === 2 && <MetaHeading mb={10}>Memberships</MetaHeading>}
<MetaButton onClick={onNextPress}>Next Step</MetaButton>

View File

@@ -0,0 +1,22 @@
import { MetaHeading, SelectSearch } from '@metafam/ds';
import { FlexContainer } from 'components/Container';
import { SetupContext } from 'contexts/SetupContext';
import React, { useContext } from 'react';
import { SkillOption } from 'utils/skillHelpers';
export const SetupSkills: React.FC = () => {
const { skillsList, skills, setSkills } = useContext(SetupContext);
return (
<FlexContainer mb={10} align="stretch">
<MetaHeading mb={10}>What are your superpowers?</MetaHeading>
<SelectSearch
isMulti
value={skills}
onChange={(value) => setSkills(value as Array<SkillOption>)}
options={skillsList}
placeholder="ADD YOUR SKILLS"
/>
</FlexContainer>
);
};

View File

@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react';
import { CategoryOption, SkillOption } from 'utils/skillHelpers';
type SetupContextType = {
useProgress: (numProgressSteps: number) => [number, () => void];
@@ -7,6 +8,9 @@ type SetupContextType = {
setStep: React.Dispatch<React.SetStateAction<number>>;
setProgress: React.Dispatch<React.SetStateAction<number>>;
numTotalSteps: number;
skills: Array<SkillOption>;
setSkills: React.Dispatch<React.SetStateAction<Array<SkillOption>>>;
skillsList: Array<CategoryOption>;
};
export const SetupContext = React.createContext<SetupContextType>({
@@ -16,9 +20,19 @@ export const SetupContext = React.createContext<SetupContextType>({
setStep: () => undefined,
setProgress: () => undefined,
numTotalSteps: 0,
skills: [],
setSkills: () => undefined,
skillsList: [],
});
export const SetupContextProvider: React.FC = ({ children }) => {
type Props = {
skillsList: Array<CategoryOption>;
};
export const SetupContextProvider: React.FC<Props> = ({
children,
skillsList,
}) => {
const [step, setStep] = useState<number>(0);
const [progress, setProgress] = useState<number>(0.5);
const numTotalSteps = 3;
@@ -44,6 +58,8 @@ export const SetupContextProvider: React.FC = ({ children }) => {
return [currentProgress, onNextPress];
};
const [skills, setSkills] = useState<Array<SkillOption>>([]);
return (
<SetupContext.Provider
value={{
@@ -53,6 +69,9 @@ export const SetupContextProvider: React.FC = ({ children }) => {
setStep,
setProgress,
numTotalSteps,
skills,
setSkills,
skillsList,
}}
>
{children}

View File

@@ -0,0 +1,38 @@
import gql from 'fake-tag';
import { GetSkillsQuery } from './autogen/types';
import { client } from './client';
const skillsQuery = gql`
query GetSkills {
Skill(
order_by: { Player_Skills_aggregate: { count: desc }, category: asc }
) {
id
name
category
}
}
`;
export interface Skill {
id: string;
name: string;
category: string;
}
export const getSkills = async (): Promise<Skill[]> => {
const { data, error } = await client
.query<GetSkillsQuery>(skillsQuery)
.toPromise();
if (!data) {
if (error) {
throw error;
}
return [];
}
return data.Skill;
};

View File

@@ -4,16 +4,11 @@ import { SetupHeader } from 'components/Setup/SetupHeader';
import { SetupPersonality } from 'components/Setup/SetupPersonality';
import { SetupProfession } from 'components/Setup/SetupProfession';
import { SetupContext, SetupContextProvider } from 'contexts/SetupContext';
import { getSkills } from 'graphql/getSkills';
import { InferGetStaticPropsType } from 'next';
import BackgroundImage from 'public/images/profile-background.jpg';
import React, { useContext } from 'react';
export const getStaticProps = async () => {
return {
props: {
hidePageHeader: true,
},
};
};
import { parseSkills } from 'utils/skillHelpers';
const ProfileSetup: React.FC = () => {
const { step, numTotalSteps } = useContext(SetupContext);
@@ -27,8 +22,22 @@ const ProfileSetup: React.FC = () => {
);
};
const ProfileSetupWithContext: React.FC = () => (
<SetupContextProvider>
export const getStaticProps = async () => {
const skills = await getSkills();
const skillsList = parseSkills(skills);
return {
props: {
skillsList,
hidePageHeader: true,
},
};
};
export type Props = InferGetStaticPropsType<typeof getStaticProps>;
const ProfileSetupWithContext: React.FC<Props> = ({ skillsList }) => (
<SetupContextProvider skillsList={skillsList}>
<ProfileSetup />
</SetupContextProvider>
);

View File

@@ -0,0 +1,33 @@
import { Skill } from 'graphql/getSkills';
export type SkillMap = {
[category: string]: CategoryOption;
};
export type SkillOption = Skill & {
value: string;
label: string;
};
export type CategoryOption = {
label: string;
options: Array<SkillOption>;
};
export const parseSkills = (skills: Array<Skill>): Array<CategoryOption> => {
const skillsMap: SkillMap = {};
skills.map((skill) => {
if (!(skill.category in skillsMap)) {
skillsMap[skill.category] = {
label: skill.category,
options: [],
};
}
return skillsMap[skill.category].options?.push({
value: skill.id,
label: skill.name,
...skill,
});
});
return Object.values(skillsMap);
};