diff --git a/packages/web/components/Profile/EmbeddedUrlSection.tsx b/packages/web/components/Profile/EmbeddedUrlSection.tsx index 34e2dfbb..df2c3542 100644 --- a/packages/web/components/Profile/EmbeddedUrlSection.tsx +++ b/packages/web/components/Profile/EmbeddedUrlSection.tsx @@ -87,7 +87,6 @@ const LinkPreview: React.FC = ({ url: inputUrl = '' }) => { return ( window.open(url ?? inputUrl, '_blank')} minH="18rem" w="100%" h="100%" @@ -95,9 +94,6 @@ const LinkPreview: React.FC = ({ url: inputUrl = '' }) => { backdropFilter="blur(7px)" borderWidth={0} overflow="hidden" - _hover={{ - cursor: 'pointer', - }} > = ({ {children} {boxType && ( - + = ({ p={4} _focus={{ boxShadow: 'none' }} /> - - {!modal && !modalText && ( - - )} - {modalText && modal} - + {!modal && !modalText && ( + + )} + {modalText && modal && {modalText && modal}} + {/* we should figure out how to unify modal footers (edit sections have their own, look into EditSectionBox components - they have footers with 'save' and 'cancel' buttons) */} {modalText && modal && ( diff --git a/packages/web/components/Setup/SetupAvailability.tsx b/packages/web/components/Setup/SetupAvailability.tsx index 64031bd3..d88d4277 100644 --- a/packages/web/components/Setup/SetupAvailability.tsx +++ b/packages/web/components/Setup/SetupAvailability.tsx @@ -70,7 +70,7 @@ export const SetupAvailability: React.FC = ({ What is your weekly availability for any kind of freelance work? - + đź•› diff --git a/packages/web/components/Setup/SetupPersonalityType.tsx b/packages/web/components/Setup/SetupPersonalityType.tsx index cb91b0cd..9fc2c193 100644 --- a/packages/web/components/Setup/SetupPersonalityType.tsx +++ b/packages/web/components/Setup/SetupPersonalityType.tsx @@ -5,8 +5,10 @@ import { Button, Flex, Image, + LoadingState, MetaButton, MetaHeading, + ModalBody, ModalFooter, Spinner, Text, @@ -26,7 +28,7 @@ import { PersonalityInfo, } from 'graphql/queries/enums/getPersonalityInfo'; import { useUser, useWeb3 } from 'lib/hooks'; -import React, { ReactElement, useEffect, useState } from 'react'; +import React, { ReactElement, useEffect, useMemo, useState } from 'react'; import { dispositionFor } from 'utils/playerHelpers'; export type SetupPersonalityTypeProps = { @@ -39,34 +41,37 @@ export const SetupPersonalityType: React.FC = ({ onClose, }) => { const { onNextPress, nextButtonLabel } = useSetupFlow(); - const { user } = useUser(); + const { fetching: fetchingUser, user } = useUser(); const { player } = user ?? {}; const { ceramic } = useWeb3(); const toast = useToast(); const [status, setStatus] = useState>(null); - const [colorMask, setColorMask] = useState | undefined>( - player?.profile?.colorMask, - ); + const [colorMask, setColorMask] = useState | undefined>(); const [{ types, parts }, setPersonalityInfo] = useState({ types: {}, parts: [], }); const isWizard = !isEdit; - const load = () => { - if (player) { - if (colorMask === undefined && player.profile?.colorMask != null) { - setColorMask(player.profile.colorMask); - } + useEffect(() => { + if (player?.profile?.colorMask != null) { + setColorMask(player.profile.colorMask); } - }; - useEffect(load, [player, colorMask]); + }, [colorMask, player]); + + const [fetchingInfo, setFetchingInfo] = useState(true); + + const fetching = useMemo(() => fetchingUser || fetchingInfo || !user, [ + fetchingUser, + fetchingInfo, + user, + ]); useEffect(() => { const fetchInfo = async () => setPersonalityInfo(await getPersonalityInfo()); - fetchInfo(); + fetchInfo().then(() => setFetchingInfo(false)); }, []); const handleNextPress = async () => { @@ -140,173 +145,187 @@ export const SetupPersonalityType: React.FC = ({ }); }; - return ( - - - {isWizard && ( - - Person­ality Type - - )} - - Please select your personality components below. Not sure what type - you are? - Take - - a quick exam - - or - - a longer quiz - - . - - - - {Object.keys(types).length && - Object.entries(BaseImages) - .reverse() - .map(([orig, image], idx) => { - const option = types[parseInt(orig, 10)]; - const { mask = 0 } = option ?? {}; - const selected = ((colorMask ?? 0) & mask) > 0; - - return ( - - - - ); - })} - - - - - {isEdit && onClose && ( - - - - { - await save(); - onClose(); - }} - > - {!status ? ( - 'Save Changes' - ) : ( - - - {typeof status === 'string' ? ( - {status} - ) : ( - status - )} - - )} - - - - - - - - )} - + const setup = ( + {isWizard && ( - Person­ality Type + )} + + Please select your personality components below. Not sure what type you + are? + Take + - {nextButtonLabel} - + a quick exam + + or + + a longer quiz + + . + + {fetching ? ( + + ) : ( + <> + + {Object.keys(types).length && + Object.entries(BaseImages) + .reverse() + .map(([orig, image], idx) => { + const option = types[parseInt(orig, 10)]; + const { mask = 0 } = option ?? {}; + const selected = ((colorMask ?? 0) & mask) > 0; + + return ( + + + + ); + })} + + + + {isWizard && ( + + {nextButtonLabel} + + )} + )} ); + + return isWizard ? ( + setup + ) : ( + <> + {setup}\ + {isEdit && onClose && ( + + + + + { + await save(); + onClose(); + }} + > + {!status ? ( + 'Save Changes' + ) : ( + + + {typeof status === 'string' ? ( + {status} + ) : ( + status + )} + + )} + + + + + + + + + )} + + ); }; diff --git a/packages/web/components/Setup/SetupPlayerType.tsx b/packages/web/components/Setup/SetupPlayerType.tsx index d2ae2c44..299f0827 100644 --- a/packages/web/components/Setup/SetupPlayerType.tsx +++ b/packages/web/components/Setup/SetupPlayerType.tsx @@ -6,6 +6,7 @@ import { Flex, MetaButton, MetaHeading, + ModalBody, ModalFooter, SimpleGrid, Spinner, @@ -114,7 +115,7 @@ export const SetupPlayerType: React.FC = ({ isEdit, onClose }) => { } }; - return ( + const setup = ( {isWizard && ( @@ -156,48 +157,6 @@ export const SetupPlayerType: React.FC = ({ isEdit, onClose }) => { ))} - - {isEdit && onClose && ( - - - - { - await save(); - onClose(); - }} - > - {!status ? ( - 'Save Changes' - ) : ( - - - {typeof status === 'string' ? ( - {status} - ) : ( - status - )} - - )} - - - - - - - - )} - {isWizard && ( = ({ isEdit, onClose }) => { )} ); + return isWizard ? ( + setup + ) : ( + <> + {setup} + + {isEdit && onClose && ( + + + + + { + await save(); + onClose(); + }} + > + {!status ? ( + 'Save Changes' + ) : ( + + + {typeof status === 'string' ? ( + {status} + ) : ( + status + )} + + )} + + + + + + + + + )} + + ); }; diff --git a/packages/web/components/Setup/SetupRoles.tsx b/packages/web/components/Setup/SetupRoles.tsx index 743f87e8..2415175b 100644 --- a/packages/web/components/Setup/SetupRoles.tsx +++ b/packages/web/components/Setup/SetupRoles.tsx @@ -8,6 +8,7 @@ import { LoadingState, MetaButton, MetaHeading, + ModalBody, ModalFooter, Spacer, Text, @@ -43,17 +44,18 @@ export const SetupRoles: React.FC = ({ const { fetching: fetchingUser, user } = useUser({ requestPolicy: 'network-only', }); - const [fetchingRoleChoices, setFetchingRoleChoices] = useState(false); + const [fetchingRoleChoices, setFetchingRoleChoices] = useState(true); const [roleChoices, setRoleChoices] = useState( inputRoleChoices, ); useEffect(() => { if (inputRoleChoices.length === 0 && roleChoices.length === 0) { - setFetchingRoleChoices(true); getPlayerRoles().then((s) => { setRoleChoices(s.filter(({ basic }) => basic)); setFetchingRoleChoices(false); }); + } else { + setFetchingRoleChoices(false); } }, [inputRoleChoices, roleChoices]); const fetching = useMemo(() => fetchingUser || fetchingRoleChoices, [ @@ -134,12 +136,12 @@ export const SetupRoles: React.FC = ({ const isMobile = useBreakpointValue({ base: true, md: false }); - return ( + const setup = ( {isWizard && ( @@ -147,56 +149,57 @@ export const SetupRoles: React.FC = ({ )} {fetching && } - {!fetching && roles.length === 0 ? ( - - Unlike other role-playing games, in MetaGame, anyone is free to play - multiple roles at the same time. -
- Players are required to specify their primary role, whereas any - secondary roles are optional. -
- ) : ( - - {roles.map((r, i) => { - const choice = roleChoices.find( - (roleChoice) => roleChoice.role === r, - ); - return ( - choice && ( - <> - - - {i === 0 && 'Primary Role'} - {i > 0 && roles.length === 2 && 'Secondary Role'} - {i === 1 && roles.length > 2 && 'Secondary Roles'} - {/* we still need a placeholder */} - {!isMobile && roles.length > 2 && i > 1 && ( -   - )} - + {!fetching && + (roles.length === 0 ? ( + + Unlike other role-playing games, in MetaGame, anyone is free to play + multiple roles at the same time. +
+ Players are required to specify their primary role, whereas any + secondary roles are optional. +
+ ) : ( + + {roles.map((r, i) => { + const choice = roleChoices.find( + (roleChoice) => roleChoice.role === r, + ); + return ( + choice && ( + <> + + + {i === 0 && 'Primary Role'} + {i > 0 && roles.length === 2 && 'Secondary Role'} + {i === 1 && roles.length > 2 && 'Secondary Roles'} + {/* we still need a placeholder */} + {!isMobile && roles.length > 2 && i > 1 && ( +   + )} + - - - {/* wrap after the primary */} - {i === 0 && } - - ) - ); - })} - - )} - {availableRoles.length > 0 && ( + +
+ {/* wrap after the primary */} + {i === 0 && } + + ) + ); + })} +
+ ))} + {availableRoles.length > 0 && !fetching && ( <> = ({ )} - {isEdit && onClose && ( - + {isWizard && !fetching && ( + { - await save(); - onClose(); - }} + onClick={handleNextPress} + isDisabled={roles.length < 1} + isLoading={updateRolesResult.fetching || loading} + loadingText="Saving" > - Save Changes + {nextButtonLabel} - - - )} - - {isWizard && ( - - {nextButtonLabel} - +
)} ); + return isWizard ? ( + setup + ) : ( + <> + {setup} + {isEdit && onClose && ( + + + { + await save(); + onClose(); + }} + > + Save Changes + + + + + )} + + ); }; type RoleProps = { diff --git a/packages/web/components/Setup/SetupSkills.tsx b/packages/web/components/Setup/SetupSkills.tsx index 8cf5abca..29843a6e 100644 --- a/packages/web/components/Setup/SetupSkills.tsx +++ b/packages/web/components/Setup/SetupSkills.tsx @@ -3,6 +3,7 @@ import { MetaButton, MetaHeading, MetaTheme, + ModalBody, ModalFooter, searchSelectStyles, SelectSearch, @@ -132,7 +133,7 @@ export const SetupSkills: React.FC = ({ onNextPress(); }, [save, onNextPress]); - return ( + const setup = ( {isWizard && ( @@ -151,31 +152,6 @@ export const SetupSkills: React.FC = ({ placeholder="Add Your Skills…" /> - {isEdit && onClose && ( - - { - await save(); - onClose(); - }} - > - Save Changes - - - - )} {isWizard && ( = ({ )} ); + return isWizard ? ( + setup + ) : ( + <> + {setup} + {isEdit && onClose && ( + + + { + await save(); + onClose(); + }} + > + Save Changes + + + + + )} + + ); }; diff --git a/packages/web/pages/player/[username].tsx b/packages/web/pages/player/[username].tsx index 4203d60e..b44d32ff 100644 --- a/packages/web/pages/player/[username].tsx +++ b/packages/web/pages/player/[username].tsx @@ -104,16 +104,6 @@ export const PlayerPage: React.FC = ({ export default PlayerPage; -const makeLayouts = (canEdit: boolean, layouts: Layouts): Layouts => - Object.fromEntries( - Object.entries(layouts).map(([key, items]) => [ - key, - items.map((item) => - item.i === 'hero' ? { ...item, isResizable: canEdit } : item, - ), - ]), - ); - const onRemoveBoxFromLayouts = (boxKey: string, layouts: Layouts): Layouts => Object.fromEntries( Object.entries(layouts).map(([key, items]) => [ @@ -365,11 +355,6 @@ export const Grid: React.FC = ({ const wrapperSX = useMemo(() => gridConfig.wrapper(canEdit), [canEdit]); - const displayLayouts = useMemo(() => makeLayouts(canEdit, currentLayouts), [ - canEdit, - currentLayouts, - ]); - const onRemoveBox = useCallback( (boxKey: string): void => { const layoutData = { @@ -481,10 +466,8 @@ export const Grid: React.FC = ({ )} { - handleLayoutChange(layoutItems, layouts); - }} - layouts={displayLayouts} + onLayoutChange={handleLayoutChange} + layouts={currentLayouts} breakpoints={{ lg: 1180, md: 900, sm: 0 }} cols={{ lg: 3, md: 2, sm: 1 }} rowHeight={GRID_ROW_HEIGHT}