mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-04-02 03:00:32 -04:00
Feature/add timezone frontend (#231)
* Added tz column * Updated hasura permissions on new table * Added new dependencies for working with timezones * Added SetupTimeZone component * Bumped spacetime-informal to use their types * Extracted timezone computation into helper, added useMemo hook * Re-added spacetime types
This commit is contained in:
22
packages/@types/react-timezone-select/index.d.ts
vendored
Normal file
22
packages/@types/react-timezone-select/index.d.ts
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
declare module 'react-timezone-select' {
|
||||
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import * as React from 'react';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export, react/prefer-stateless-function
|
||||
export default class TimezoneSelect extends React.Component<SelectTimezoneProps> {}
|
||||
|
||||
export interface TimeZone {
|
||||
value: string;
|
||||
label: string;
|
||||
altName: string;
|
||||
abbrev: string;
|
||||
}
|
||||
|
||||
export interface TimezoneSelectProps extends Props {
|
||||
value?: TimeZone | string
|
||||
onBlur?: () => void
|
||||
onChange?: (timezone:TimeZone) => void
|
||||
labelStyle: 'original' | 'altName' | 'abbrev'
|
||||
}
|
||||
}
|
||||
18
packages/@types/spacetime-informal/index.d.ts
vendored
Normal file
18
packages/@types/spacetime-informal/index.d.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
declare module 'spacetime-informal' {
|
||||
export function find(tz:string): string;
|
||||
|
||||
export function display(geo:string): DisplayFormat;
|
||||
|
||||
export function version(): string;
|
||||
|
||||
export interface DisplayFormat {
|
||||
iana: string;
|
||||
standard: TimeZoneInfo;
|
||||
daylight: TimeZoneInfo;
|
||||
}
|
||||
|
||||
export interface TimeZoneInfo {
|
||||
name: string;
|
||||
abbrev: string;
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,8 @@
|
||||
"@chakra-ui/core": "next",
|
||||
"@chakra-ui/icons": "next",
|
||||
"@chakra-ui/theme": "next",
|
||||
"react-select": "^3.1.0"
|
||||
"react-select": "^3.1.0",
|
||||
"react-timezone-select": "^0.9.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.10.5",
|
||||
|
||||
@@ -83,6 +83,7 @@ export const selectStyles: Styles = {
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
export const SelectSearch: React.FC<SelectProps> = (props) => (
|
||||
<Select styles={selectStyles} {...props} />
|
||||
);
|
||||
|
||||
45
packages/design-system/src/SelectTimeZone.tsx
Normal file
45
packages/design-system/src/SelectTimeZone.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import React from 'react';
|
||||
import { Styles } from 'react-select';
|
||||
import TimezoneSelect, { TimezoneSelectProps } from 'react-timezone-select';
|
||||
|
||||
import { theme } from './theme';
|
||||
|
||||
export const selectStyles: Styles = {
|
||||
menu: (styles) => ({
|
||||
...styles,
|
||||
background: theme.colors.dark,
|
||||
}),
|
||||
input: (styles) => ({
|
||||
...styles,
|
||||
color: theme.colors.white,
|
||||
}),
|
||||
option: (styles) => ({
|
||||
...styles,
|
||||
background: theme.colors.dark,
|
||||
':hover': {
|
||||
backgroundColor: theme.colors.purpleTag,
|
||||
color: theme.colors.white,
|
||||
},
|
||||
}),
|
||||
control: (styles) => ({
|
||||
...styles,
|
||||
background: theme.colors.dark,
|
||||
border: theme.colors.dark,
|
||||
}),
|
||||
singleValue: (styles) => ({
|
||||
...styles,
|
||||
color: theme.colors.white,
|
||||
}),
|
||||
dropdownIndicator: (styles) => ({
|
||||
...styles,
|
||||
color: theme.colors.white,
|
||||
cursor: 'pointer',
|
||||
':hover': {
|
||||
color: theme.colors.blueLight,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
export const SelectTimeZone: React.FC<TimezoneSelectProps> = (props) => (
|
||||
<TimezoneSelect styles={selectStyles} {...props} />
|
||||
);
|
||||
@@ -53,3 +53,4 @@ export { MetaTag } from './MetaTag';
|
||||
export { H1, P } from './typography';
|
||||
export { ResponsiveText } from './ResponsiveText';
|
||||
export { SelectSearch, selectStyles } from './SelectSearch';
|
||||
export { SelectTimeZone } from './SelectTimeZone';
|
||||
|
||||
26
packages/web/components/Player/PlayerTimeZone.tsx
Normal file
26
packages/web/components/Player/PlayerTimeZone.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Box, HStack, Text } from '@metafam/ds';
|
||||
import { PlayerFragmentFragment } from 'graphql/autogen/types';
|
||||
import React, { useMemo } from 'react';
|
||||
import { FaGlobe } from 'react-icons/fa';
|
||||
import { getPlayerTimeZoneDisplay } from 'utils/dateHelpers';
|
||||
|
||||
type Props = {
|
||||
player: PlayerFragmentFragment;
|
||||
};
|
||||
|
||||
export const PlayerTimeZone: React.FC<Props> = ({ player }) => {
|
||||
const tzDisplay = useMemo(() => getPlayerTimeZoneDisplay(player), [player]);
|
||||
|
||||
return (
|
||||
<Box ml={1}>
|
||||
<Text fontSize="xs" color="blueLight" casing="uppercase" mb={3}>
|
||||
time zone
|
||||
</Text>
|
||||
<HStack alignItems="baseline">
|
||||
<FaGlobe color="blueLight" />
|
||||
<Text fontSize="xl" mb="1">{tzDisplay?.timeZone || '-'}</Text>
|
||||
{tzDisplay?.offset ? <Text fontSize="xs" mr={3}>{tzDisplay?.offset}</Text> : ''}
|
||||
</HStack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Box, Divider, HStack, Text } from '@metafam/ds';
|
||||
import { PlayerFragmentFragment } from 'graphql/autogen/types';
|
||||
import React from 'react';
|
||||
import { FaClock, FaGlobe } from 'react-icons/fa';
|
||||
import { FaClock } from 'react-icons/fa';
|
||||
|
||||
import { PlayerTimeZone } from '../PlayerTimeZone';
|
||||
|
||||
type Props = { player: PlayerFragmentFragment };
|
||||
export const PlayerCollab: React.FC<Props> = ({ player }) => {
|
||||
@@ -12,17 +14,7 @@ export const PlayerCollab: React.FC<Props> = ({ player }) => {
|
||||
<Divider height="3rem" color="whiteAlpha.400" orientation="vertical" />
|
||||
}
|
||||
>
|
||||
<Box>
|
||||
<Text fontSize="xs" color="blueLight" casing="uppercase" mb={3}>
|
||||
Location
|
||||
</Text>
|
||||
<HStack alignItems="baseline">
|
||||
<FaGlobe color="blueLight" />
|
||||
<Text fontSize="lg" fontFamily="mono" mb="1">
|
||||
{player.box_profile?.location || '-'}
|
||||
</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
<PlayerTimeZone player={player} />
|
||||
<Box>
|
||||
<Text fontSize="xs" color="blueLight" casing="uppercase" mb={3}>
|
||||
Availability
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from '@metafam/ds';
|
||||
import { FlexContainer } from 'components/Container';
|
||||
import { useSetupFlow } from 'contexts/SetupContext';
|
||||
import { useUpdatePlayerSkillsMutation } from 'graphql/autogen/types';
|
||||
import { useUpdateProfileMutation } from 'graphql/autogen/types';
|
||||
import { useUser } from 'lib/hooks';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
@@ -20,7 +20,6 @@ export const SetupAvailability: React.FC = () => {
|
||||
nextButtonLabel,
|
||||
availability,
|
||||
setAvailability,
|
||||
skills,
|
||||
} = useSetupFlow();
|
||||
const [invalid, setInvalid] = useState(false);
|
||||
const { user } = useUser({ redirectTo: '/' });
|
||||
@@ -31,14 +30,16 @@ export const SetupAvailability: React.FC = () => {
|
||||
setInvalid(value < 0 || value > 168);
|
||||
}, [availability]);
|
||||
|
||||
const [updateSkillsRes, updateSkills] = useUpdatePlayerSkillsMutation();
|
||||
const [updateProfileRes, updateProfile] = useUpdateProfileMutation();
|
||||
|
||||
const handleNextPress = async () => {
|
||||
if (!user) return;
|
||||
|
||||
const { error } = await updateSkills({
|
||||
availability_hours: Number(availability),
|
||||
skills: skills.map((s) => ({ skill_id: s.id })),
|
||||
const { error } = await updateProfile({
|
||||
playerId: user.id,
|
||||
input: {
|
||||
availability_hours: Number(availability)
|
||||
}
|
||||
});
|
||||
|
||||
if (error) {
|
||||
@@ -46,7 +47,7 @@ export const SetupAvailability: React.FC = () => {
|
||||
console.warn(error);
|
||||
toast({
|
||||
title: 'Error',
|
||||
description: 'Unable to update Player Skills. The octo is sad 😢',
|
||||
description: 'Unable to update availability. The octo is sad 😢',
|
||||
status: 'error',
|
||||
isClosable: true,
|
||||
});
|
||||
@@ -87,7 +88,7 @@ export const SetupAvailability: React.FC = () => {
|
||||
onClick={handleNextPress}
|
||||
mt={10}
|
||||
isDisabled={invalid}
|
||||
isLoading={updateSkillsRes.fetching}
|
||||
isLoading={updateProfileRes.fetching}
|
||||
loadingText="Saving"
|
||||
>
|
||||
{nextButtonLabel}
|
||||
|
||||
@@ -19,6 +19,8 @@ export const SetupProfile: React.FC = () => {
|
||||
setPlayerType,
|
||||
availability,
|
||||
setAvailability,
|
||||
timeZone,
|
||||
setTimeZone,
|
||||
skills,
|
||||
setSkills,
|
||||
} = useSetupFlow();
|
||||
@@ -26,35 +28,39 @@ export const SetupProfile: React.FC = () => {
|
||||
const { address } = useWeb3();
|
||||
useEffect(() => {
|
||||
if (user?.player) {
|
||||
const {player} = user;
|
||||
if (
|
||||
user.player.username &&
|
||||
user.player.username.toLowerCase() !== address?.toLowerCase() &&
|
||||
player.username &&
|
||||
player.username.toLowerCase() !== address?.toLowerCase() &&
|
||||
!username
|
||||
) {
|
||||
setUsername(user.player.username);
|
||||
setUsername(player.username);
|
||||
}
|
||||
if (user.player.availability_hours && !availability) {
|
||||
setAvailability(user.player.availability_hours.toString());
|
||||
if (player.availability_hours && !availability) {
|
||||
setAvailability(player.availability_hours.toString());
|
||||
}
|
||||
if (user.player.EnneagramType && !personalityType) {
|
||||
setPersonalityType(PersonalityTypes[user.player.EnneagramType.name]);
|
||||
if (player.EnneagramType && !personalityType) {
|
||||
setPersonalityType(PersonalityTypes[player.EnneagramType.name]);
|
||||
}
|
||||
if (user.player.playerType && !playerType) {
|
||||
setPlayerType(user.player.playerType);
|
||||
if (player.playerType && !playerType) {
|
||||
setPlayerType(player.playerType);
|
||||
}
|
||||
if (
|
||||
user.player.Player_Skills &&
|
||||
user.player.Player_Skills.length > 0 &&
|
||||
player.Player_Skills &&
|
||||
player.Player_Skills.length > 0 &&
|
||||
skills.length === 0
|
||||
) {
|
||||
setSkills(
|
||||
user.player.Player_Skills.map((s) => ({
|
||||
player.Player_Skills.map((s) => ({
|
||||
value: s.Skill.id,
|
||||
label: s.Skill.name,
|
||||
...s.Skill,
|
||||
})),
|
||||
);
|
||||
}
|
||||
if (player.tz && !timeZone) {
|
||||
setTimeZone(player.tz);
|
||||
}
|
||||
}
|
||||
}, [
|
||||
user,
|
||||
@@ -67,6 +73,8 @@ export const SetupProfile: React.FC = () => {
|
||||
setPlayerType,
|
||||
availability,
|
||||
setAvailability,
|
||||
timeZone,
|
||||
setTimeZone,
|
||||
skills,
|
||||
setSkills,
|
||||
]);
|
||||
|
||||
@@ -4,11 +4,13 @@ import {
|
||||
MetaTheme,
|
||||
SelectSearch,
|
||||
selectStyles,
|
||||
useToast,
|
||||
} from '@metafam/ds';
|
||||
import { FlexContainer } from 'components/Container';
|
||||
import { useSetupFlow } from 'contexts/SetupContext';
|
||||
import { SkillCategory_Enum } from 'graphql/autogen/types';
|
||||
import { SkillCategory_Enum, useUpdatePlayerSkillsMutation } from 'graphql/autogen/types';
|
||||
import { SkillColors } from 'graphql/types';
|
||||
import { useUser } from 'lib/hooks';
|
||||
import React from 'react';
|
||||
import { SkillOption } from 'utils/skillHelpers';
|
||||
|
||||
@@ -20,6 +22,31 @@ export const SetupSkills: React.FC = () => {
|
||||
onNextPress,
|
||||
nextButtonLabel,
|
||||
} = useSetupFlow();
|
||||
const { user } = useUser({ redirectTo: '/' });
|
||||
const toast = useToast();
|
||||
|
||||
const [updateSkillsRes, updateSkills] = useUpdatePlayerSkillsMutation();
|
||||
|
||||
const handleNextPress = async () => {
|
||||
if (!user) return;
|
||||
|
||||
const { error } = await updateSkills({
|
||||
skills: skills.map((s) => ({ skill_id: s.id })),
|
||||
});
|
||||
|
||||
if (error) {
|
||||
toast({
|
||||
title: 'Error',
|
||||
description: 'Unable to update player skills. The octo is sad 😢',
|
||||
status: 'error',
|
||||
isClosable: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
onNextPress();
|
||||
};
|
||||
|
||||
|
||||
const styles: typeof selectStyles = {
|
||||
...selectStyles,
|
||||
@@ -60,7 +87,12 @@ export const SetupSkills: React.FC = () => {
|
||||
placeholder="ADD YOUR SKILLS"
|
||||
/>
|
||||
</FlexContainer>
|
||||
<MetaButton onClick={onNextPress} mt={10}>
|
||||
<MetaButton
|
||||
onClick={handleNextPress}
|
||||
mt={10}
|
||||
isLoading={updateSkillsRes.fetching}
|
||||
loadingText="Saving"
|
||||
>
|
||||
{nextButtonLabel}
|
||||
</MetaButton>
|
||||
</FlexContainer>
|
||||
|
||||
70
packages/web/components/Setup/SetupTimeZone.tsx
Normal file
70
packages/web/components/Setup/SetupTimeZone.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
MetaButton,
|
||||
MetaHeading,
|
||||
SelectTimeZone,
|
||||
useToast,
|
||||
} from '@metafam/ds';
|
||||
import { FlexContainer } from 'components/Container';
|
||||
import { useSetupFlow } from 'contexts/SetupContext';
|
||||
import { useUpdateProfileMutation } from 'graphql/autogen/types';
|
||||
import { useUser } from 'lib/hooks';
|
||||
import React from 'react';
|
||||
|
||||
export const SetupTimeZone: React.FC = () => {
|
||||
const {
|
||||
onNextPress,
|
||||
nextButtonLabel,
|
||||
timeZone,
|
||||
setTimeZone
|
||||
} = useSetupFlow();
|
||||
const { user } = useUser({ redirectTo: '/' });
|
||||
const toast = useToast();
|
||||
|
||||
const [updateProfileRes, updateProfile] = useUpdateProfileMutation();
|
||||
|
||||
const handleNextPress = async () => {
|
||||
if (!user) return;
|
||||
|
||||
const { error } = await updateProfile({
|
||||
playerId: user.id,
|
||||
input: {
|
||||
tz: timeZone
|
||||
}
|
||||
});
|
||||
|
||||
if (error) {
|
||||
toast({
|
||||
title: 'Error',
|
||||
description: 'Unable to update time zone. The octo is sad 😢',
|
||||
status: 'error',
|
||||
isClosable: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
onNextPress();
|
||||
};
|
||||
|
||||
return (
|
||||
<FlexContainer>
|
||||
<MetaHeading mb={10} mt={-64} textAlign="center">
|
||||
Which time zone are you in?
|
||||
</MetaHeading>
|
||||
<FlexContainer w="100%" align="stretch" maxW="30rem">
|
||||
<SelectTimeZone
|
||||
value={timeZone}
|
||||
onChange={(tz) => setTimeZone(tz.value)}
|
||||
labelStyle="abbrev"
|
||||
/>
|
||||
</FlexContainer>
|
||||
<MetaButton
|
||||
onClick={handleNextPress}
|
||||
mt={10}
|
||||
isLoading={updateProfileRes.fetching}
|
||||
loadingText="Saving"
|
||||
>
|
||||
{nextButtonLabel}
|
||||
</MetaButton>
|
||||
</FlexContainer>
|
||||
);
|
||||
};
|
||||
@@ -38,6 +38,8 @@ type SetupContextType = {
|
||||
setPlayerType: React.Dispatch<React.SetStateAction<PlayerType | undefined>>;
|
||||
availability: string;
|
||||
setAvailability: React.Dispatch<React.SetStateAction<string>>;
|
||||
timeZone: string;
|
||||
setTimeZone: React.Dispatch<React.SetStateAction<string>>;
|
||||
memberships: Array<Membership> | null | undefined;
|
||||
setMemberships: React.Dispatch<
|
||||
React.SetStateAction<Array<Membership> | null | undefined>
|
||||
@@ -65,6 +67,8 @@ export const SetupContext = React.createContext<SetupContextType>({
|
||||
setPlayerType: () => undefined,
|
||||
availability: '',
|
||||
setAvailability: () => undefined,
|
||||
timeZone: '',
|
||||
setTimeZone: () => undefined,
|
||||
memberships: undefined,
|
||||
setMemberships: () => undefined,
|
||||
});
|
||||
@@ -133,6 +137,7 @@ export const SetupContextProvider: React.FC<Props> = ({
|
||||
const [personalityType, setPersonalityType] = useState<PersonalityType>();
|
||||
const [playerType, setPlayerType] = useState<PlayerType>();
|
||||
const [availability, setAvailability] = useState<string>('');
|
||||
const [timeZone, setTimeZone] = useState<string>('');
|
||||
const [memberships, setMemberships] = useState<
|
||||
Array<Membership> | null | undefined
|
||||
>();
|
||||
@@ -166,6 +171,9 @@ export const SetupContextProvider: React.FC<Props> = ({
|
||||
// availability
|
||||
availability,
|
||||
setAvailability,
|
||||
// time zone
|
||||
timeZone,
|
||||
setTimeZone,
|
||||
// memberships
|
||||
memberships,
|
||||
setMemberships,
|
||||
|
||||
@@ -8,6 +8,7 @@ export const PlayerFragment = gql`
|
||||
rank
|
||||
ethereum_address
|
||||
availability_hours
|
||||
tz
|
||||
EnneagramType {
|
||||
description
|
||||
name
|
||||
|
||||
@@ -4,7 +4,6 @@ export const UpdateAboutYouMutation = gql`
|
||||
mutation UpdateAboutYou($playerId: uuid!, $input: Player_set_input!) {
|
||||
update_Player_by_pk(pk_columns: { id: $playerId }, _set: $input) {
|
||||
enneagram
|
||||
availability_hours
|
||||
playerType {
|
||||
description
|
||||
id
|
||||
|
||||
11
packages/web/graphql/mutations/updateProfile.ts
Normal file
11
packages/web/graphql/mutations/updateProfile.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import gql from 'fake-tag';
|
||||
|
||||
export const UpdateProfileMutation = gql`
|
||||
mutation UpdateProfile($playerId: uuid!, $input: Player_set_input!) {
|
||||
update_Player_by_pk(pk_columns: { id: $playerId }, _set: $input) {
|
||||
id
|
||||
availability_hours
|
||||
tz
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -2,7 +2,6 @@ import gql from 'fake-tag';
|
||||
|
||||
export const UpdateSkillsMutation = gql`
|
||||
mutation UpdatePlayerSkills(
|
||||
$availability_hours: Int!
|
||||
$skills: [Player_Skill_insert_input!]!
|
||||
) {
|
||||
delete_Player_Skill(where: {}) {
|
||||
@@ -11,21 +10,5 @@ export const UpdateSkillsMutation = gql`
|
||||
insert_Player_Skill(objects: $skills) {
|
||||
affected_rows
|
||||
}
|
||||
update_Player(
|
||||
_set: { availability_hours: $availability_hours }
|
||||
where: {}
|
||||
) {
|
||||
returning {
|
||||
id
|
||||
availability_hours
|
||||
Player_Skills {
|
||||
Skill {
|
||||
id
|
||||
category
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
"react-dom": "^16.13.1",
|
||||
"react-icons": "^3.11.0",
|
||||
"react-is": "16.13.1",
|
||||
"spacetime": "^6.12.1",
|
||||
"spacetime-informal": "^0.5.0",
|
||||
"urql": "^1.9.7",
|
||||
"web3modal": "^1.9.0"
|
||||
}
|
||||
|
||||
36
packages/web/utils/dateHelpers.ts
Normal file
36
packages/web/utils/dateHelpers.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { PlayerFragmentFragment } from "graphql/autogen/types";
|
||||
import spacetime from 'spacetime';
|
||||
import { display } from 'spacetime-informal';
|
||||
|
||||
export interface TimeZoneDisplay {
|
||||
timeZone?: string;
|
||||
offset?: string;
|
||||
}
|
||||
|
||||
export const getPlayerTimeZoneDisplay = (player: PlayerFragmentFragment): TimeZoneDisplay => {
|
||||
let tzLabel;
|
||||
let offsetLabel;
|
||||
if (player?.tz) {
|
||||
const timeZone = spacetime.now().goto(player.tz)
|
||||
const tzDisplay = display(player.tz)
|
||||
if (tzDisplay && tzDisplay.daylight && tzDisplay.standard) {
|
||||
tzLabel = timeZone.isDST()
|
||||
? tzDisplay.daylight.abbrev
|
||||
: tzDisplay.standard.abbrev;
|
||||
const {offset} = timeZone.timezone().current;
|
||||
if (offset > 0) {
|
||||
offsetLabel = `(GMT +${offset})`;
|
||||
} else if (offset < 0) {
|
||||
offsetLabel = `(GMT ${offset})`;
|
||||
}
|
||||
} else {
|
||||
tzLabel = player.tz;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
timeZone: tzLabel,
|
||||
offset: offsetLabel
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { SetupMemberships } from 'components/Setup/SetupMemberships';
|
||||
import { SetupPersonalityType } from 'components/Setup/SetupPersonalityType';
|
||||
import { SetupPlayerType } from 'components/Setup/SetupPlayerType';
|
||||
import { SetupSkills } from 'components/Setup/SetupSkills';
|
||||
import { SetupTimeZone } from 'components/Setup/SetupTimeZone';
|
||||
import { SetupUsername } from 'components/Setup/SetupUsername';
|
||||
import React from 'react';
|
||||
|
||||
@@ -42,6 +43,10 @@ export const options = [
|
||||
label: 'Availability',
|
||||
component: <SetupAvailability />,
|
||||
},
|
||||
{
|
||||
label: 'Time Zone',
|
||||
component: <SetupTimeZone />
|
||||
},
|
||||
{
|
||||
label: 'Memberships',
|
||||
component: <SetupMemberships />,
|
||||
|
||||
@@ -33,3 +33,8 @@ export const parseSkills = (
|
||||
});
|
||||
return Object.values(skillsMap);
|
||||
};
|
||||
|
||||
export type TimeZoneOption = {
|
||||
value: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
24
yarn.lock
24
yarn.lock
@@ -25115,6 +25115,15 @@ react-textarea-autosize@^8.1.1:
|
||||
use-composed-ref "^1.0.0"
|
||||
use-latest "^1.0.0"
|
||||
|
||||
react-timezone-select@^0.9.7:
|
||||
version "0.9.8"
|
||||
resolved "https://registry.yarnpkg.com/react-timezone-select/-/react-timezone-select-0.9.8.tgz#a5d9ead1fa0b40dab1b3a77d9cdcc20354fe2ec4"
|
||||
integrity sha512-CzIOs9IwAb5hmjs5jnB1uShQvw9zJGUVeH5dIpRVy1dgVnwkasvXc2fGwnggI6nYXAmN7uOCt5kFIcQOpZmUNw==
|
||||
dependencies:
|
||||
react-select "^3.1.0"
|
||||
spacetime "^6.6.2"
|
||||
spacetime-informal "^0.3.0"
|
||||
|
||||
react-transition-group@4.4.1, react-transition-group@^4.3.0, react-transition-group@^4.4.0, react-transition-group@^4.4.1:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9"
|
||||
@@ -27104,6 +27113,21 @@ space-separated-tokens@^1.0.0, space-separated-tokens@^1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899"
|
||||
integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==
|
||||
|
||||
spacetime-informal@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/spacetime-informal/-/spacetime-informal-0.3.0.tgz#6d0feffe291697f686b737b678b59ee2dcef3297"
|
||||
integrity sha512-HtFTwtkzDl7gswCfeWPQAxvQ+Fmrdt7WqoDT0Lq2FX7RVZKZ/+zmgBOAVAuH8oVcf4uXza9NvdX9QppGRiG8oQ==
|
||||
|
||||
spacetime-informal@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/spacetime-informal/-/spacetime-informal-0.5.0.tgz#0301d45621d7207d6573d97ba0e6700dab37c667"
|
||||
integrity sha512-cdSsniJJfJJTBdeVvXtooxyXzrRfoBVjAl3usQl9DgGExB3XN3deA3MwjInnD/26C/lANf3dU54bT2YweAGrOw==
|
||||
|
||||
spacetime@^6.12.1, spacetime@^6.6.2:
|
||||
version "6.12.1"
|
||||
resolved "https://registry.yarnpkg.com/spacetime/-/spacetime-6.12.1.tgz#a0a7b583fe2646b4288bd7456bcf027337a33ba6"
|
||||
integrity sha512-mUA1xnVDX0RxF+HaAA0pOui3ePjTCkVx81DsMpSVwidQJjJgMxD39N5cKjCkOqDKKHjPmq73cF6X14b6+Oy9aA==
|
||||
|
||||
sparse-array@^1.3.1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/sparse-array/-/sparse-array-1.3.2.tgz#0e1a8b71706d356bc916fe754ff496d450ec20b0"
|
||||
|
||||
Reference in New Issue
Block a user