diff --git a/packages/web/components/Player/Section/PlayerColorDisposition.tsx b/packages/web/components/Player/Section/PlayerColorDisposition.tsx index 30fc8d04..778e602b 100644 --- a/packages/web/components/Player/Section/PlayerColorDisposition.tsx +++ b/packages/web/components/Player/Section/PlayerColorDisposition.tsx @@ -2,8 +2,10 @@ import { Link } from '@metafam/ds'; import { PlayerFragmentFragment } from 'graphql/autogen/types'; import { getPersonalityInfo } from 'graphql/getPersonalityInfo'; import { PersonalityOption } from 'graphql/types'; -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; +import { BOX_TYPE } from 'utils/boxTypes'; +import { FlexContainer } from '../../Container'; import { ProfileSection } from '../../ProfileSection'; import { ColorBar } from '../ColorBar'; @@ -20,35 +22,54 @@ export const PlayerColorDisposition: React.FC = ({ const [types, setTypes] = React.useState<{ [any: string]: PersonalityOption; }>(); + const [colorDisposition, setColorDisposition] = useState< + 0 | PersonalityOption | undefined + >(); + const [animation, setAnimation] = useState('fadeIn'); const mask = player?.color_aspect?.mask; const type = mask && types?.[mask]; - const loadTypes = async () => { - const { types: list } = await getPersonalityInfo(); - setTypes(list); - }; useEffect(() => { + const loadTypes = async () => { + const { types: list } = await getPersonalityInfo(); + setTypes(list); + }; loadTypes(); }, []); + useEffect(() => { + setAnimation('fadeOut'); + setTimeout(() => { + setColorDisposition(type); + setAnimation('fadeIn'); + }, 400); + }, [mask, type]); + return ( - {type && types && ( - - - + + + + )} ); diff --git a/packages/web/components/Player/Section/PlayerType.tsx b/packages/web/components/Player/Section/PlayerType.tsx index 1c3cfd5f..cae29d2c 100644 --- a/packages/web/components/Player/Section/PlayerType.tsx +++ b/packages/web/components/Player/Section/PlayerType.tsx @@ -1,7 +1,6 @@ import { Text } from '@metafam/ds'; import { Player_Type, PlayerFragmentFragment } from 'graphql/autogen/types'; -import { useUser } from 'lib/hooks'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { BOX_TYPE } from 'utils/boxTypes'; import { FlexContainer } from '../../Container'; @@ -18,19 +17,32 @@ export const PlayerType: React.FC = ({ isOwnProfile, onRemoveClick, }) => { - const { user } = useUser(); const [playerType, setPlayerType] = useState(); const [animation, setAnimation] = useState('fadeIn'); const type = player?.type; + const usePrevious = (value: T): T | undefined => { + const ref = useRef(); + useEffect(() => { + ref.current = value; + }); + return ref.current; + }; + const previousType = usePrevious(type); + + // todo refactor so that usePrevious won't be needed anymore + // something is retriggering useEffect when color disposition is changed, for example + // i suspect the type object's reference is changing useEffect(() => { - setAnimation('fadeOut'); - setTimeout(() => { - setPlayerType(type); - setAnimation('fadeIn'); - }, 400); - }, [user, type]); + if (previousType?.title !== type?.title) { + setAnimation('fadeOut'); + setTimeout(() => { + setPlayerType(type); + setAnimation('fadeIn'); + }, 400); + } + }, [type, previousType]); return ( = ({ isOwnProfile={isOwnProfile} boxType={BOX_TYPE.PLAYER_TYPE} > - - - {playerType?.title} - - - {playerType?.description} - - + + {playerType.title} + + + {playerType.description} + + + )} ); }; diff --git a/packages/web/components/ProfileSection.tsx b/packages/web/components/ProfileSection.tsx index 3db94e82..41df472e 100644 --- a/packages/web/components/ProfileSection.tsx +++ b/packages/web/components/ProfileSection.tsx @@ -13,6 +13,7 @@ import { useDisclosure, } from '@metafam/ds'; import BackgroundImage from 'assets/main-background.jpg'; +import { SetupPersonalityType } from 'components/Setup/SetupPersonalityType'; import { SetupPlayerType } from 'components/Setup/SetupPlayerType'; import React from 'react'; import { FaTimes } from 'react-icons/fa'; @@ -117,6 +118,8 @@ const getEditSectionBox = ( switch (boxType) { case BOX_TYPE.PLAYER_TYPE: return ; + case BOX_TYPE.PLAYER_COLOR_DISPOSITION: + return ; default: return ; } diff --git a/packages/web/components/Setup/SetupPersonalityType.tsx b/packages/web/components/Setup/SetupPersonalityType.tsx index 50383c2c..15a49c54 100644 --- a/packages/web/components/Setup/SetupPersonalityType.tsx +++ b/packages/web/components/Setup/SetupPersonalityType.tsx @@ -4,6 +4,7 @@ import { Image, MetaButton, MetaHeading, + ModalFooter, Text, useToast, } from '@metafam/ds'; @@ -12,33 +13,70 @@ import { MetaLink } from 'components/Link'; import { ColorBar } from 'components/Player/ColorBar'; import { useSetupFlow } from 'contexts/SetupContext'; import { useUpdateAboutYouMutation } from 'graphql/autogen/types'; -import { images as BaseImages } from 'graphql/queries/enums/getPersonalityInfo'; +import { + getPersonalityInfo, + images as BaseImages, +} from 'graphql/queries/enums/getPersonalityInfo'; import { PersonalityOption } from 'graphql/types'; import { useUser } from 'lib/hooks'; -import React, { useCallback, useState } from 'react'; +import React, { useEffect, useState } from 'react'; export type SetupPersonalityTypeProps = { - // keyed on a bitmask of the format 0bWUBRG - personalityTypes: { [x: number]: PersonalityOption }; - colorMask: number | undefined; - setColorMask: React.Dispatch>; + isEdit?: boolean; + onClose?: () => void; }; export const SetupPersonalityType: React.FC = ({ - personalityTypes, - colorMask, - setColorMask, + isEdit, + onClose, }) => { const { onNextPress, nextButtonLabel } = useSetupFlow(); const { user } = useUser({ redirectTo: '/' }); const toast = useToast(); const [updateAboutYouRes, updateAboutYou] = useUpdateAboutYouMutation(); const [loading, setLoading] = useState(false); + const [personalityTypes, setPersonalityTypes] = useState<{ + [x: number]: PersonalityOption; + }>([]); + const isWizard = !isEdit; - const handleNextPress = useCallback(async () => { - if (!user) return; + const [colorMask, setColorMask] = useState( + user?.player?.color_aspect?.mask, + ); + const load = () => { + const { player } = user ?? {}; + if (player) { + if (colorMask === undefined && player.color_aspect !== null) { + setColorMask(player.color_aspect?.mask); + } + } + }; + + useEffect(load, [user, colorMask]); + + useEffect(() => { + async function fetchMyAPI() { + const { + types, + // parts: personalityParts, + } = await getPersonalityInfo(); + setPersonalityTypes(types); + } + + fetchMyAPI(); + }, []); + + const handleNextPress = async () => { setLoading(true); + + save(); + + onNextPress(); + }; + + const save = async () => { + if (!user) return; if (user.player?.color_aspect?.mask !== colorMask) { const { error } = await updateAboutYou({ playerId: user.id, @@ -56,12 +94,9 @@ export const SetupPersonalityType: React.FC = ({ isClosable: true, }); setLoading(false); - return; } } - - onNextPress(); - }, [colorMask, onNextPress, toast, updateAboutYou, user]); + }; // mask should always only have at most a single bit set const toggleMaskElement = (mask = 0): void => { @@ -77,10 +112,12 @@ export const SetupPersonalityType: React.FC = ({ return ( - - Person­ality Type - - + {isWizard && ( + + Person­ality Type + + )} + Please select your personality components below. Not sure what type you are? Take @@ -108,88 +145,110 @@ export const SetupPersonalityType: React.FC = ({ wrap="wrap" id="colors" > - {Object.entries(BaseImages) - .reverse() - .map(([orig, image], idx) => { - const option = personalityTypes[parseInt(orig, 10)]; - const { mask = 0 } = option ?? {}; - const selected = ((colorMask ?? 0) & mask) > 0; + {Object.keys(personalityTypes).length && + Object.entries(BaseImages) + .reverse() + .map(([orig, image], idx) => { + const option = personalityTypes[parseInt(orig, 10)]; + const { mask = 0 } = option ?? {}; + const selected = ((colorMask ?? 0) & mask) > 0; - return ( - - ); - })} + return ( + + ); + })} - - {nextButtonLabel} - + {isEdit && ( + + + + + )} + + {isWizard && ( + + {nextButtonLabel} + + )} ); }; diff --git a/packages/web/components/Setup/SetupPlayerType.tsx b/packages/web/components/Setup/SetupPlayerType.tsx index 93134bea..c936fdbe 100644 --- a/packages/web/components/Setup/SetupPlayerType.tsx +++ b/packages/web/components/Setup/SetupPlayerType.tsx @@ -48,8 +48,6 @@ export const SetupPlayerType: React.FC = ({ isEdit, onClose }) => { }, [playerTypeChoices]); const handleNextPress = async () => { - if (!user) return; - setLoading(true); save(); diff --git a/packages/web/pages/profile/setup/personalityType.tsx b/packages/web/pages/profile/setup/personalityType.tsx index 68de7392..a8dbca3a 100644 --- a/packages/web/pages/profile/setup/personalityType.tsx +++ b/packages/web/pages/profile/setup/personalityType.tsx @@ -1,57 +1,13 @@ import { SetupPersonalityType } from 'components/Setup/SetupPersonalityType'; import { SetupProfile } from 'components/Setup/SetupProfile'; import { SetupContextProvider } from 'contexts/SetupContext'; -import { getPersonalityInfo } from 'graphql/queries/enums/getPersonalityInfo'; -import { useUser } from 'lib/hooks'; -import { InferGetStaticPropsType } from 'next'; -import React, { useEffect, useState } from 'react'; +import React from 'react'; -export const getStaticProps = async () => { - const { - types: personalityTypes, - parts: personalityParts, - } = await getPersonalityInfo(); - - return { - props: { - personalityParts, - personalityTypes, - hideTopMenu: true, - }, - }; -}; - -type Props = InferGetStaticPropsType; - -const PersonalityTypeSetup: React.FC = (props) => { - const { personalityTypes } = props; - const { user } = useUser({ redirectTo: '/' }); - const [colorMask, setColorMask] = useState( - user?.player?.color_aspect?.mask, - ); - - const load = () => { - const { player } = user ?? {}; - if (player) { - if (colorMask === undefined && player.color_aspect !== null) { - setColorMask(player.color_aspect?.mask); - } - } - }; - useEffect(load, [user, colorMask]); - - return ( - - - - - - ); -}; +const PersonalityTypeSetup: React.FC = () => ( + + + + + +); export default PersonalityTypeSetup;