mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-01-15 01:17:57 -05:00
fix: bugs in EmbedUrl + SetupRoles
This commit is contained in:
committed by
Scott Stevenson
parent
10f66448ea
commit
e022573223
@@ -87,7 +87,6 @@ const LinkPreview: React.FC<LinkPreviewProps> = ({ url: inputUrl = '' }) => {
|
||||
|
||||
return (
|
||||
<LinkBox
|
||||
onClick={() => window.open(url ?? inputUrl, '_blank')}
|
||||
minH="18rem"
|
||||
w="100%"
|
||||
h="100%"
|
||||
@@ -95,9 +94,6 @@ const LinkPreview: React.FC<LinkPreviewProps> = ({ url: inputUrl = '' }) => {
|
||||
backdropFilter="blur(7px)"
|
||||
borderWidth={0}
|
||||
overflow="hidden"
|
||||
_hover={{
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
<Flex w="100%" h="100%" direction="column">
|
||||
<Box
|
||||
|
||||
@@ -131,7 +131,7 @@ export const ProfileSection: React.FC<ProfileSectionProps> = ({
|
||||
{children}
|
||||
</Box>
|
||||
{boxType && (
|
||||
<Modal {...{ isOpen, onClose }}>
|
||||
<Modal isCentered scrollBehavior="inside" {...{ isOpen, onClose }}>
|
||||
<ModalOverlay />
|
||||
<ModalContent
|
||||
maxW="80%"
|
||||
@@ -169,12 +169,11 @@ export const ProfileSection: React.FC<ProfileSectionProps> = ({
|
||||
p={4}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
/>
|
||||
<ModalBody overflowY="auto" overflowX="hidden">
|
||||
{!modal && !modalText && (
|
||||
<EditSectionBox {...{ boxType, onClose }} />
|
||||
)}
|
||||
{modalText && modal}
|
||||
</ModalBody>
|
||||
{!modal && !modalText && (
|
||||
<EditSectionBox {...{ boxType, onClose }} />
|
||||
)}
|
||||
{modalText && modal && <ModalBody>{modalText && modal}</ModalBody>}
|
||||
|
||||
{/* 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 && (
|
||||
|
||||
@@ -70,7 +70,7 @@ export const SetupAvailability: React.FC<SetupAvailabilityProps> = ({
|
||||
<Text mb={10}>
|
||||
What is your weekly availability for any kind of freelance work?
|
||||
</Text>
|
||||
<InputGroup borderColor="transparent" mb={10}>
|
||||
<InputGroup borderColor="transparent" mb={10} maxW="20rem">
|
||||
<InputLeftElement>
|
||||
<span role="img" aria-label="clock">
|
||||
🕛
|
||||
|
||||
@@ -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<SetupPersonalityTypeProps> = ({
|
||||
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<Maybe<ReactElement | string>>(null);
|
||||
const [colorMask, setColorMask] = useState<Maybe<number> | undefined>(
|
||||
player?.profile?.colorMask,
|
||||
);
|
||||
const [colorMask, setColorMask] = useState<Maybe<number> | undefined>();
|
||||
const [{ types, parts }, setPersonalityInfo] = useState<PersonalityInfo>({
|
||||
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<SetupPersonalityTypeProps> = ({
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<FlexContainer mb={8}>
|
||||
<Flex direction="column">
|
||||
{isWizard && (
|
||||
<MetaHeading mb={5} textAlign="center">
|
||||
Person­ality Type
|
||||
</MetaHeading>
|
||||
)}
|
||||
<Text mb={10} color={isWizard ? 'current' : 'white'}>
|
||||
Please select your personality components below. Not sure what type
|
||||
you are?
|
||||
<Text as="span"> Take </Text>
|
||||
<MetaLink
|
||||
href="//dysbulic.github.io/5-color-radar/#/explore/"
|
||||
isExternal
|
||||
>
|
||||
a quick exam
|
||||
</MetaLink>
|
||||
<Text as="span"> or </Text>
|
||||
<MetaLink
|
||||
href="//dysbulic.github.io/5-color-radar/#/test/"
|
||||
isExternal
|
||||
>
|
||||
a longer quiz
|
||||
</MetaLink>
|
||||
.
|
||||
</Text>
|
||||
</Flex>
|
||||
<Wrap spacing={2} justify="center" maxW="70rem">
|
||||
{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 (
|
||||
<WrapItem>
|
||||
<Button
|
||||
key={mask}
|
||||
display="flex"
|
||||
direction="row"
|
||||
justifyContent="start"
|
||||
p={6}
|
||||
m={2}
|
||||
h="auto"
|
||||
w={{ base: '100%', md: 'auto' }}
|
||||
spacing={4}
|
||||
borderRadius={8}
|
||||
cursor="pointer"
|
||||
onClick={() => toggleMaskElement(mask)}
|
||||
autoFocus={idx === 0} // Doesn't work
|
||||
ref={(input) => {
|
||||
if (idx === 0 && !input?.getAttribute('focused-once')) {
|
||||
input?.focus();
|
||||
input?.setAttribute('focused-once', 'true');
|
||||
}
|
||||
}}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
if (isWizard) handleNextPress();
|
||||
if (isEdit) save();
|
||||
e.preventDefault();
|
||||
}
|
||||
}}
|
||||
transition="background 0.25s, filter 0.5s"
|
||||
bgColor={selected ? 'purpleBoxDark' : 'purpleBoxLight'}
|
||||
_hover={{
|
||||
filter: 'hue-rotate(25deg)',
|
||||
}}
|
||||
_focus={{
|
||||
borderColor: '#FFFFFF55',
|
||||
outline: 'none',
|
||||
}}
|
||||
_active={{
|
||||
bg: selected ? 'purpleBoxDark' : 'purpleBoxLight',
|
||||
}}
|
||||
borderWidth={2}
|
||||
borderColor={selected ? 'purple.400' : 'transparent'}
|
||||
>
|
||||
<Image
|
||||
w="100%"
|
||||
maxW={16}
|
||||
h={16}
|
||||
mr={2}
|
||||
src={image}
|
||||
alt={option.name}
|
||||
filter="drop-shadow(0px 0px 3px black)"
|
||||
/>
|
||||
<FlexContainer align="stretch" ml={2}>
|
||||
<Text color="white" casing="uppercase" textAlign="left">
|
||||
{option.name}
|
||||
</Text>
|
||||
<Text
|
||||
color="blueLight"
|
||||
fontWeight="normal"
|
||||
whiteSpace="initial"
|
||||
textAlign="left"
|
||||
>
|
||||
{option.description}
|
||||
</Text>
|
||||
</FlexContainer>
|
||||
</Button>
|
||||
</WrapItem>
|
||||
);
|
||||
})}
|
||||
</Wrap>
|
||||
|
||||
<ColorBar
|
||||
mask={colorMask ?? null}
|
||||
mt={8}
|
||||
w="min(90vw, 30rem)"
|
||||
personalityInfo={{ types, parts }}
|
||||
/>
|
||||
|
||||
{isEdit && onClose && (
|
||||
<ModalFooter mt={6}>
|
||||
<Wrap justify="center" align="center" flex={1}>
|
||||
<WrapItem>
|
||||
<MetaButton
|
||||
isDisabled={!!status}
|
||||
onClick={async () => {
|
||||
await save();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
{!status ? (
|
||||
'Save Changes'
|
||||
) : (
|
||||
<Flex align="center">
|
||||
<Spinner mr={3} />
|
||||
{typeof status === 'string' ? (
|
||||
<Text>{status}</Text>
|
||||
) : (
|
||||
status
|
||||
)}
|
||||
</Flex>
|
||||
)}
|
||||
</MetaButton>
|
||||
</WrapItem>
|
||||
<WrapItem>
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={onClose}
|
||||
color="white"
|
||||
_hover={{ bg: '#FFFFFF11' }}
|
||||
_active={{ bg: '#FF000011' }}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</WrapItem>
|
||||
</Wrap>
|
||||
</ModalFooter>
|
||||
)}
|
||||
|
||||
const setup = (
|
||||
<FlexContainer mb={isWizard ? 8 : 0} spacing={isWizard ? 8 : 4}>
|
||||
{isWizard && (
|
||||
<MetaButton
|
||||
onClick={handleNextPress}
|
||||
mt={10}
|
||||
isDisabled={colorMask === undefined}
|
||||
isLoading={!!status}
|
||||
loadingText={status?.toString() ?? undefined}
|
||||
<MetaHeading textAlign="center">Person­ality Type</MetaHeading>
|
||||
)}
|
||||
<Text color={isWizard ? 'current' : 'white'}>
|
||||
Please select your personality components below. Not sure what type you
|
||||
are?
|
||||
<Text as="span"> Take </Text>
|
||||
<MetaLink
|
||||
href="//dysbulic.github.io/5-color-radar/#/explore/"
|
||||
isExternal
|
||||
>
|
||||
{nextButtonLabel}
|
||||
</MetaButton>
|
||||
a quick exam
|
||||
</MetaLink>
|
||||
<Text as="span"> or </Text>
|
||||
<MetaLink href="//dysbulic.github.io/5-color-radar/#/test/" isExternal>
|
||||
a longer quiz
|
||||
</MetaLink>
|
||||
.
|
||||
</Text>
|
||||
{fetching ? (
|
||||
<LoadingState />
|
||||
) : (
|
||||
<>
|
||||
<Wrap spacing={2} justify="center" maxW="70rem">
|
||||
{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 (
|
||||
<WrapItem>
|
||||
<Button
|
||||
key={mask}
|
||||
display="flex"
|
||||
direction="row"
|
||||
justifyContent="start"
|
||||
p={6}
|
||||
m={2}
|
||||
h="auto"
|
||||
w={{ base: '100%', md: 'auto' }}
|
||||
spacing={4}
|
||||
borderRadius={8}
|
||||
cursor="pointer"
|
||||
onClick={() => toggleMaskElement(mask)}
|
||||
autoFocus={idx === 0} // Doesn't work
|
||||
ref={(input) => {
|
||||
if (
|
||||
idx === 0 &&
|
||||
!input?.getAttribute('focused-once')
|
||||
) {
|
||||
input?.focus();
|
||||
input?.setAttribute('focused-once', 'true');
|
||||
}
|
||||
}}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
if (isWizard) handleNextPress();
|
||||
if (isEdit) save();
|
||||
e.preventDefault();
|
||||
}
|
||||
}}
|
||||
transition="background 0.25s, filter 0.5s"
|
||||
bgColor={selected ? 'purpleBoxDark' : 'purpleBoxLight'}
|
||||
_hover={{
|
||||
filter: 'hue-rotate(25deg)',
|
||||
}}
|
||||
_focus={{
|
||||
borderColor: '#FFFFFF55',
|
||||
outline: 'none',
|
||||
}}
|
||||
_active={{
|
||||
bg: selected ? 'purpleBoxDark' : 'purpleBoxLight',
|
||||
}}
|
||||
borderWidth={2}
|
||||
borderColor={selected ? 'purple.400' : 'transparent'}
|
||||
>
|
||||
<Image
|
||||
w="100%"
|
||||
maxW={16}
|
||||
h={16}
|
||||
mr={2}
|
||||
src={image}
|
||||
alt={option.name}
|
||||
filter="drop-shadow(0px 0px 3px black)"
|
||||
/>
|
||||
<FlexContainer align="stretch" ml={2}>
|
||||
<Text
|
||||
color="white"
|
||||
casing="uppercase"
|
||||
textAlign="left"
|
||||
>
|
||||
{option.name}
|
||||
</Text>
|
||||
<Text
|
||||
color="blueLight"
|
||||
fontWeight="normal"
|
||||
whiteSpace="initial"
|
||||
textAlign="left"
|
||||
>
|
||||
{option.description}
|
||||
</Text>
|
||||
</FlexContainer>
|
||||
</Button>
|
||||
</WrapItem>
|
||||
);
|
||||
})}
|
||||
</Wrap>
|
||||
|
||||
<ColorBar
|
||||
mask={colorMask ?? null}
|
||||
mt={8}
|
||||
w="min(90vw, 30rem)"
|
||||
personalityInfo={{ types, parts }}
|
||||
/>
|
||||
{isWizard && (
|
||||
<MetaButton
|
||||
onClick={handleNextPress}
|
||||
mt={10}
|
||||
isDisabled={!colorMask}
|
||||
isLoading={!!status}
|
||||
loadingText={status?.toString() ?? undefined}
|
||||
>
|
||||
{nextButtonLabel}
|
||||
</MetaButton>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</FlexContainer>
|
||||
);
|
||||
|
||||
return isWizard ? (
|
||||
setup
|
||||
) : (
|
||||
<>
|
||||
<ModalBody>{setup}</ModalBody>\
|
||||
{isEdit && onClose && (
|
||||
<FlexContainer>
|
||||
<ModalFooter py={6}>
|
||||
<Wrap justify="center" align="center" flex={1}>
|
||||
<WrapItem>
|
||||
<MetaButton
|
||||
isDisabled={!!status}
|
||||
onClick={async () => {
|
||||
await save();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
{!status ? (
|
||||
'Save Changes'
|
||||
) : (
|
||||
<Flex align="center">
|
||||
<Spinner mr={3} />
|
||||
{typeof status === 'string' ? (
|
||||
<Text>{status}</Text>
|
||||
) : (
|
||||
status
|
||||
)}
|
||||
</Flex>
|
||||
)}
|
||||
</MetaButton>
|
||||
</WrapItem>
|
||||
<WrapItem>
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={onClose}
|
||||
color="white"
|
||||
_hover={{ bg: '#FFFFFF11' }}
|
||||
_active={{ bg: '#FF000011' }}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</WrapItem>
|
||||
</Wrap>
|
||||
</ModalFooter>
|
||||
</FlexContainer>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
Flex,
|
||||
MetaButton,
|
||||
MetaHeading,
|
||||
ModalBody,
|
||||
ModalFooter,
|
||||
SimpleGrid,
|
||||
Spinner,
|
||||
@@ -114,7 +115,7 @@ export const SetupPlayerType: React.FC<Props> = ({ isEdit, onClose }) => {
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
const setup = (
|
||||
<FlexContainer mb={8}>
|
||||
{isWizard && (
|
||||
<MetaHeading mb={5} textAlign="center">
|
||||
@@ -156,48 +157,6 @@ export const SetupPlayerType: React.FC<Props> = ({ isEdit, onClose }) => {
|
||||
</FlexContainer>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
|
||||
{isEdit && onClose && (
|
||||
<ModalFooter mt={6}>
|
||||
<Wrap justify="center" align="center" flex={1}>
|
||||
<WrapItem>
|
||||
<MetaButton
|
||||
isDisabled={!!status}
|
||||
onClick={async () => {
|
||||
await save();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
{!status ? (
|
||||
'Save Changes'
|
||||
) : (
|
||||
<Flex align="center">
|
||||
<Spinner mr={3} />
|
||||
{typeof status === 'string' ? (
|
||||
<Text>{status}</Text>
|
||||
) : (
|
||||
status
|
||||
)}
|
||||
</Flex>
|
||||
)}
|
||||
</MetaButton>
|
||||
</WrapItem>
|
||||
<WrapItem>
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={onClose}
|
||||
color="white"
|
||||
_hover={{ bg: '#FFFFFF11' }}
|
||||
_active={{ bg: '#FF000011' }}
|
||||
disabled={!!status}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</WrapItem>
|
||||
</Wrap>
|
||||
</ModalFooter>
|
||||
)}
|
||||
|
||||
{isWizard && (
|
||||
<MetaButton
|
||||
onClick={handleNextPress}
|
||||
@@ -211,4 +170,54 @@ export const SetupPlayerType: React.FC<Props> = ({ isEdit, onClose }) => {
|
||||
)}
|
||||
</FlexContainer>
|
||||
);
|
||||
return isWizard ? (
|
||||
setup
|
||||
) : (
|
||||
<>
|
||||
<ModalBody>{setup}</ModalBody>
|
||||
|
||||
{isEdit && onClose && (
|
||||
<FlexContainer>
|
||||
<ModalFooter py={6}>
|
||||
<Wrap justify="center" align="center" flex={1}>
|
||||
<WrapItem>
|
||||
<MetaButton
|
||||
isDisabled={!!status}
|
||||
onClick={async () => {
|
||||
await save();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
{!status ? (
|
||||
'Save Changes'
|
||||
) : (
|
||||
<Flex align="center">
|
||||
<Spinner mr={3} />
|
||||
{typeof status === 'string' ? (
|
||||
<Text>{status}</Text>
|
||||
) : (
|
||||
status
|
||||
)}
|
||||
</Flex>
|
||||
)}
|
||||
</MetaButton>
|
||||
</WrapItem>
|
||||
<WrapItem>
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={onClose}
|
||||
color="white"
|
||||
_hover={{ bg: '#FFFFFF11' }}
|
||||
_active={{ bg: '#FF000011' }}
|
||||
disabled={!!status}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</WrapItem>
|
||||
</Wrap>
|
||||
</ModalFooter>
|
||||
</FlexContainer>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
LoadingState,
|
||||
MetaButton,
|
||||
MetaHeading,
|
||||
ModalBody,
|
||||
ModalFooter,
|
||||
Spacer,
|
||||
Text,
|
||||
@@ -43,17 +44,18 @@ export const SetupRoles: React.FC<SetupRolesProps> = ({
|
||||
const { fetching: fetchingUser, user } = useUser({
|
||||
requestPolicy: 'network-only',
|
||||
});
|
||||
const [fetchingRoleChoices, setFetchingRoleChoices] = useState(false);
|
||||
const [fetchingRoleChoices, setFetchingRoleChoices] = useState(true);
|
||||
const [roleChoices, setRoleChoices] = useState<PlayerRole[]>(
|
||||
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<SetupRolesProps> = ({
|
||||
|
||||
const isMobile = useBreakpointValue({ base: true, md: false });
|
||||
|
||||
return (
|
||||
const setup = (
|
||||
<FlexContainer
|
||||
align="center"
|
||||
mx={isWizard ? { base: 0, md: 8, lg: 16 } : 0}
|
||||
mb={8}
|
||||
color="white"
|
||||
mb={isWizard ? 'auto' : 0}
|
||||
>
|
||||
{isWizard && (
|
||||
<MetaHeading mb={{ base: 6, sm: 16 }} alignSelf="center">
|
||||
@@ -147,56 +149,57 @@ export const SetupRoles: React.FC<SetupRolesProps> = ({
|
||||
</MetaHeading>
|
||||
)}
|
||||
{fetching && <LoadingState />}
|
||||
{!fetching && roles.length === 0 ? (
|
||||
<Text mb={{ base: 6, sm: 10 }}>
|
||||
Unlike other role-playing games, in MetaGame, anyone is free to play
|
||||
multiple roles at the same time.
|
||||
<br />
|
||||
Players are required to specify their primary role, whereas any
|
||||
secondary roles are optional.
|
||||
</Text>
|
||||
) : (
|
||||
<Flex wrap="wrap" mb={{ base: 4, md: 16 }} w="100%">
|
||||
{roles.map((r, i) => {
|
||||
const choice = roleChoices.find(
|
||||
(roleChoice) => roleChoice.role === r,
|
||||
);
|
||||
return (
|
||||
choice && (
|
||||
<>
|
||||
<Box key={r} {...roleContainerStyles}>
|
||||
<Text
|
||||
color="cyan.500"
|
||||
fontWeight="bold"
|
||||
casing="uppercase"
|
||||
my="2"
|
||||
>
|
||||
{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 && (
|
||||
<span> </span>
|
||||
)}
|
||||
</Text>
|
||||
{!fetching &&
|
||||
(roles.length === 0 ? (
|
||||
<Text mb={{ base: 6, sm: 10 }}>
|
||||
Unlike other role-playing games, in MetaGame, anyone is free to play
|
||||
multiple roles at the same time.
|
||||
<br />
|
||||
Players are required to specify their primary role, whereas any
|
||||
secondary roles are optional.
|
||||
</Text>
|
||||
) : (
|
||||
<Flex wrap="wrap" mb={{ base: 4, md: 16 }} w="100%">
|
||||
{roles.map((r, i) => {
|
||||
const choice = roleChoices.find(
|
||||
(roleChoice) => roleChoice.role === r,
|
||||
);
|
||||
return (
|
||||
choice && (
|
||||
<>
|
||||
<Box key={r} {...roleContainerStyles}>
|
||||
<Text
|
||||
color="cyan.500"
|
||||
fontWeight="bold"
|
||||
casing="uppercase"
|
||||
my="2"
|
||||
>
|
||||
{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 && (
|
||||
<span> </span>
|
||||
)}
|
||||
</Text>
|
||||
|
||||
<Role
|
||||
role={choice}
|
||||
selectionIndex={i}
|
||||
numSelectedRoles={roles.length}
|
||||
onSelect={handleSelection}
|
||||
onRemove={handleRemoval}
|
||||
/>
|
||||
</Box>
|
||||
{/* wrap after the primary */}
|
||||
{i === 0 && <Box flexBasis="100%" />}
|
||||
</>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</Flex>
|
||||
)}
|
||||
{availableRoles.length > 0 && (
|
||||
<Role
|
||||
role={choice}
|
||||
selectionIndex={i}
|
||||
numSelectedRoles={roles.length}
|
||||
onSelect={handleSelection}
|
||||
onRemove={handleRemoval}
|
||||
/>
|
||||
</Box>
|
||||
{/* wrap after the primary */}
|
||||
{i === 0 && <Box flexBasis="100%" />}
|
||||
</>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</Flex>
|
||||
))}
|
||||
{availableRoles.length > 0 && !fetching && (
|
||||
<>
|
||||
<Text
|
||||
alignSelf="flex-start"
|
||||
@@ -217,44 +220,54 @@ export const SetupRoles: React.FC<SetupRolesProps> = ({
|
||||
</>
|
||||
)}
|
||||
|
||||
{isEdit && onClose && (
|
||||
<ModalFooter mt={6}>
|
||||
{isWizard && !fetching && (
|
||||
<FlexContainer pb={8}>
|
||||
<MetaButton
|
||||
mr={3}
|
||||
isLoading={loading}
|
||||
loadingText="Saving…"
|
||||
onClick={async () => {
|
||||
await save();
|
||||
onClose();
|
||||
}}
|
||||
onClick={handleNextPress}
|
||||
isDisabled={roles.length < 1}
|
||||
isLoading={updateRolesResult.fetching || loading}
|
||||
loadingText="Saving"
|
||||
>
|
||||
Save Changes
|
||||
{nextButtonLabel}
|
||||
</MetaButton>
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={onClose}
|
||||
color="white"
|
||||
_hover={{ bg: '#FFFFFF11' }}
|
||||
_active={{ bg: '#FF000011' }}
|
||||
disabled={loading}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
)}
|
||||
|
||||
{isWizard && (
|
||||
<MetaButton
|
||||
onClick={handleNextPress}
|
||||
isDisabled={roles.length < 1}
|
||||
isLoading={updateRolesResult.fetching || loading}
|
||||
loadingText="Saving"
|
||||
>
|
||||
{nextButtonLabel}
|
||||
</MetaButton>
|
||||
</FlexContainer>
|
||||
)}
|
||||
</FlexContainer>
|
||||
);
|
||||
return isWizard ? (
|
||||
setup
|
||||
) : (
|
||||
<>
|
||||
<ModalBody>{setup} </ModalBody>
|
||||
{isEdit && onClose && (
|
||||
<FlexContainer>
|
||||
<ModalFooter py={8}>
|
||||
<MetaButton
|
||||
mr={3}
|
||||
isLoading={loading}
|
||||
loadingText="Saving…"
|
||||
onClick={async () => {
|
||||
await save();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
Save Changes
|
||||
</MetaButton>
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={onClose}
|
||||
color="white"
|
||||
_hover={{ bg: '#FFFFFF11' }}
|
||||
_active={{ bg: '#FF000011' }}
|
||||
disabled={loading}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</FlexContainer>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
type RoleProps = {
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
MetaButton,
|
||||
MetaHeading,
|
||||
MetaTheme,
|
||||
ModalBody,
|
||||
ModalFooter,
|
||||
searchSelectStyles,
|
||||
SelectSearch,
|
||||
@@ -132,7 +133,7 @@ export const SetupSkills: React.FC<SetupSkillsProps> = ({
|
||||
onNextPress();
|
||||
}, [save, onNextPress]);
|
||||
|
||||
return (
|
||||
const setup = (
|
||||
<FlexContainer mb={8}>
|
||||
{isWizard && (
|
||||
<MetaHeading mb={5} textAlign="center">
|
||||
@@ -151,31 +152,6 @@ export const SetupSkills: React.FC<SetupSkillsProps> = ({
|
||||
placeholder="Add Your Skills…"
|
||||
/>
|
||||
</FlexContainer>
|
||||
{isEdit && onClose && (
|
||||
<ModalFooter mt={6}>
|
||||
<MetaButton
|
||||
mr={3}
|
||||
isLoading={loading}
|
||||
loadingText="Saving…"
|
||||
onClick={async () => {
|
||||
await save();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
Save Changes
|
||||
</MetaButton>
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={onClose}
|
||||
color="white"
|
||||
_hover={{ bg: '#FFFFFF11' }}
|
||||
_active={{ bg: '#FF000011' }}
|
||||
disabled={loading}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
)}
|
||||
|
||||
{isWizard && (
|
||||
<MetaButton
|
||||
@@ -189,4 +165,38 @@ export const SetupSkills: React.FC<SetupSkillsProps> = ({
|
||||
)}
|
||||
</FlexContainer>
|
||||
);
|
||||
return isWizard ? (
|
||||
setup
|
||||
) : (
|
||||
<>
|
||||
<ModalBody> {setup} </ModalBody>
|
||||
{isEdit && onClose && (
|
||||
<FlexContainer>
|
||||
<ModalFooter py={6}>
|
||||
<MetaButton
|
||||
mr={3}
|
||||
isLoading={loading}
|
||||
loadingText="Saving…"
|
||||
onClick={async () => {
|
||||
await save();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
Save Changes
|
||||
</MetaButton>
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={onClose}
|
||||
color="white"
|
||||
_hover={{ bg: '#FFFFFF11' }}
|
||||
_active={{ bg: '#FF000011' }}
|
||||
disabled={loading}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</FlexContainer>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -104,16 +104,6 @@ export const PlayerPage: React.FC<Props> = ({
|
||||
|
||||
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<Props> = ({
|
||||
|
||||
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<Props> = ({
|
||||
)}
|
||||
<ResponsiveGridLayout
|
||||
className="gridItems"
|
||||
onLayoutChange={(layoutItems, layouts) => {
|
||||
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}
|
||||
|
||||
Reference in New Issue
Block a user