Various fixes (#11567)
In this PR: - Remove SignUpLoading blank screen by an empty dark overlay => VerifyEffect - Add ModalContent from pages themselves instead of using it the Layout. This allow for empty dark overlay without showing an empty modal with padding
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
import { AppRouterProviders } from '@/app/components/AppRouterProviders';
|
import { AppRouterProviders } from '@/app/components/AppRouterProviders';
|
||||||
import { SettingsRoutes } from '@/app/components/SettingsRoutes';
|
import { SettingsRoutes } from '@/app/components/SettingsRoutes';
|
||||||
import { Verify } from '@/auth/components/Verify';
|
import { VerifyEffect } from '@/auth/components/Verify';
|
||||||
|
|
||||||
import { VerifyEmailEffect } from '@/auth/components/VerifyEmailEffect';
|
import { VerifyEmailEffect } from '@/auth/components/VerifyEmailEffect';
|
||||||
import indexAppPath from '@/navigation/utils/indexAppPath';
|
import indexAppPath from '@/navigation/utils/indexAppPath';
|
||||||
@ -39,7 +39,7 @@ export const useCreateAppRouter = (
|
|||||||
loader={async () => Promise.resolve(null)}
|
loader={async () => Promise.resolve(null)}
|
||||||
>
|
>
|
||||||
<Route element={<DefaultLayout />}>
|
<Route element={<DefaultLayout />}>
|
||||||
<Route path={AppPath.Verify} element={<Verify />} />
|
<Route path={AppPath.Verify} element={<VerifyEffect />} />
|
||||||
<Route path={AppPath.VerifyEmail} element={<VerifyEmailEffect />} />
|
<Route path={AppPath.VerifyEmail} element={<VerifyEmailEffect />} />
|
||||||
<Route path={AppPath.SignInUp} element={<SignInUp />} />
|
<Route path={AppPath.SignInUp} element={<SignInUp />} />
|
||||||
<Route path={AppPath.Invite} element={<SignInUp />} />
|
<Route path={AppPath.Invite} element={<SignInUp />} />
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const StyledContent = styled(Modal.Content)`
|
const StyledContent = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
`;
|
`;
|
||||||
|
|||||||
@ -10,9 +10,8 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
|||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||||
import { SignInUpLoading } from '~/pages/auth/SignInUpLoading';
|
|
||||||
|
|
||||||
export const Verify = () => {
|
export const VerifyEffect = () => {
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const loginToken = searchParams.get('loginToken');
|
const loginToken = searchParams.get('loginToken');
|
||||||
const errorMessage = searchParams.get('errorMessage');
|
const errorMessage = searchParams.get('errorMessage');
|
||||||
@ -45,5 +44,5 @@ export const Verify = () => {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [clientConfigLoaded]);
|
}, [clientConfigLoaded]);
|
||||||
|
|
||||||
return <SignInUpLoading />;
|
return <></>;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useRecoilCallback, useSetRecoilState } from 'recoil';
|
import { useRecoilCallback, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||||
import { Favorite } from '@/favorites/types/Favorite';
|
import { Favorite } from '@/favorites/types/Favorite';
|
||||||
import { FavoriteFolder } from '@/favorites/types/FavoriteFolder';
|
import { FavoriteFolder } from '@/favorites/types/FavoriteFolder';
|
||||||
import { useIsSettingsPage } from '@/navigation/hooks/useIsSettingsPage';
|
import { useIsSettingsPage } from '@/navigation/hooks/useIsSettingsPage';
|
||||||
@ -15,11 +16,15 @@ import { prefetchIsLoadedFamilyState } from '@/prefetch/states/prefetchIsLoadedF
|
|||||||
import { PrefetchKey } from '@/prefetch/types/PrefetchKey';
|
import { PrefetchKey } from '@/prefetch/types/PrefetchKey';
|
||||||
import { useShowAuthModal } from '@/ui/layout/hooks/useShowAuthModal';
|
import { useShowAuthModal } from '@/ui/layout/hooks/useShowAuthModal';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
|
||||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
|
|
||||||
export const PrefetchRunFavoriteQueriesEffect = () => {
|
export const PrefetchRunFavoriteQueriesEffect = () => {
|
||||||
const showAuthModal = useShowAuthModal();
|
const showAuthModal = useShowAuthModal();
|
||||||
const isSettingsPage = useIsSettingsPage();
|
const isSettingsPage = useIsSettingsPage();
|
||||||
|
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||||
|
const isWorkspaceActive =
|
||||||
|
currentWorkspace?.activationStatus === WorkspaceActivationStatus.ACTIVE;
|
||||||
|
|
||||||
const { objectMetadataItems } = useObjectMetadataItems();
|
const { objectMetadataItems } = useObjectMetadataItems();
|
||||||
|
|
||||||
@ -49,14 +54,14 @@ export const PrefetchRunFavoriteQueriesEffect = () => {
|
|||||||
objectNameSingular: CoreObjectNameSingular.Favorite,
|
objectNameSingular: CoreObjectNameSingular.Favorite,
|
||||||
filter: findAllFavoritesOperationSignature.variables.filter,
|
filter: findAllFavoritesOperationSignature.variables.filter,
|
||||||
recordGqlFields: findAllFavoritesOperationSignature.fields,
|
recordGqlFields: findAllFavoritesOperationSignature.fields,
|
||||||
skip: showAuthModal || isSettingsPage,
|
skip: showAuthModal || isSettingsPage || !isWorkspaceActive,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { records: favoriteFolders } = useFindManyRecords({
|
const { records: favoriteFolders } = useFindManyRecords({
|
||||||
objectNameSingular: CoreObjectNameSingular.FavoriteFolder,
|
objectNameSingular: CoreObjectNameSingular.FavoriteFolder,
|
||||||
filter: findAllFavoriteFoldersOperationSignature.variables.filter,
|
filter: findAllFavoriteFoldersOperationSignature.variables.filter,
|
||||||
recordGqlFields: findAllFavoriteFoldersOperationSignature.fields,
|
recordGqlFields: findAllFavoriteFoldersOperationSignature.fields,
|
||||||
skip: showAuthModal || isSettingsPage,
|
skip: showAuthModal || isSettingsPage || !isWorkspaceActive,
|
||||||
});
|
});
|
||||||
|
|
||||||
const setPrefetchFavoritesState = useRecoilCallback(
|
const setPrefetchFavoritesState = useRecoilCallback(
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import {
|
|||||||
useListenClickOutside,
|
useListenClickOutside,
|
||||||
} from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
} from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||||
import { useTheme } from '@emotion/react';
|
import { css, useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
@ -77,12 +77,25 @@ const StyledHeader = styled.div`
|
|||||||
padding: ${({ theme }) => theme.spacing(5)};
|
padding: ${({ theme }) => theme.spacing(5)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledContent = styled.div`
|
const StyledContent = styled.div<{
|
||||||
|
isVerticalCentered?: boolean;
|
||||||
|
isHorizontalCentered?: boolean;
|
||||||
|
}>`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex: 1 1 0%;
|
flex: 1 1 0%;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: ${({ theme }) => theme.spacing(10)};
|
padding: ${({ theme }) => theme.spacing(10)};
|
||||||
|
${({ isVerticalCentered }) =>
|
||||||
|
isVerticalCentered &&
|
||||||
|
css`
|
||||||
|
align-items: center;
|
||||||
|
`}
|
||||||
|
${({ isHorizontalCentered }) =>
|
||||||
|
isHorizontalCentered &&
|
||||||
|
css`
|
||||||
|
justify-content: center;
|
||||||
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledFooter = styled.div`
|
const StyledFooter = styled.div`
|
||||||
@ -125,12 +138,24 @@ const ModalHeader = ({ children, className }: ModalHeaderProps) => (
|
|||||||
|
|
||||||
type ModalContentProps = React.PropsWithChildren & {
|
type ModalContentProps = React.PropsWithChildren & {
|
||||||
className?: string;
|
className?: string;
|
||||||
|
isVerticalCentered?: boolean;
|
||||||
|
isHorizontalCentered?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ModalContent = ({ children, className }: ModalContentProps) => (
|
const ModalContent = ({
|
||||||
<StyledContent className={className}>{children}</StyledContent>
|
children,
|
||||||
|
className,
|
||||||
|
isVerticalCentered,
|
||||||
|
isHorizontalCentered,
|
||||||
|
}: ModalContentProps) => (
|
||||||
|
<StyledContent
|
||||||
|
className={className}
|
||||||
|
isVerticalCentered={isVerticalCentered}
|
||||||
|
isHorizontalCentered={isHorizontalCentered}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</StyledContent>
|
||||||
);
|
);
|
||||||
|
|
||||||
type ModalFooterProps = React.PropsWithChildren & {
|
type ModalFooterProps = React.PropsWithChildren & {
|
||||||
className?: string;
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import { AppPath } from '@/types/AppPath';
|
|||||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||||
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
||||||
|
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
@ -169,89 +170,91 @@ export const PasswordReset = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
isTokenValid && (
|
isTokenValid && (
|
||||||
<StyledMainContainer>
|
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||||
<AnimatedEaseIn>
|
<StyledMainContainer>
|
||||||
<Logo secondaryLogo={workspacePublicData?.logo} />
|
<AnimatedEaseIn>
|
||||||
</AnimatedEaseIn>
|
<Logo secondaryLogo={workspacePublicData?.logo} />
|
||||||
<Title animate>
|
</AnimatedEaseIn>
|
||||||
<Trans>Reset Password</Trans>
|
<Title animate>
|
||||||
</Title>
|
<Trans>Reset Password</Trans>
|
||||||
<StyledContentContainer>
|
</Title>
|
||||||
{!email ? (
|
<StyledContentContainer>
|
||||||
<SkeletonTheme
|
{!email ? (
|
||||||
baseColor={theme.background.quaternary}
|
<SkeletonTheme
|
||||||
highlightColor={theme.background.secondary}
|
baseColor={theme.background.quaternary}
|
||||||
>
|
highlightColor={theme.background.secondary}
|
||||||
<Skeleton
|
|
||||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.m}
|
|
||||||
count={2}
|
|
||||||
style={{ marginBottom: theme.spacing(2) }}
|
|
||||||
/>
|
|
||||||
</SkeletonTheme>
|
|
||||||
) : (
|
|
||||||
<StyledForm onSubmit={handleSubmit(onSubmit)}>
|
|
||||||
<StyledFullWidthMotionDiv
|
|
||||||
initial={{ opacity: 0, height: 0 }}
|
|
||||||
animate={{ opacity: 1, height: 'auto' }}
|
|
||||||
transition={{
|
|
||||||
type: 'spring',
|
|
||||||
stiffness: 800,
|
|
||||||
damping: 35,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<StyledInputContainer>
|
<Skeleton
|
||||||
<TextInputV2
|
height={SKELETON_LOADER_HEIGHT_SIZES.standard.m}
|
||||||
autoFocus
|
count={2}
|
||||||
value={email}
|
style={{ marginBottom: theme.spacing(2) }}
|
||||||
placeholder={t`Email`}
|
|
||||||
fullWidth
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
</StyledInputContainer>
|
|
||||||
</StyledFullWidthMotionDiv>
|
|
||||||
<StyledFullWidthMotionDiv
|
|
||||||
initial={{ opacity: 0, height: 0 }}
|
|
||||||
animate={{ opacity: 1, height: 'auto' }}
|
|
||||||
transition={{
|
|
||||||
type: 'spring',
|
|
||||||
stiffness: 800,
|
|
||||||
damping: 35,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Controller
|
|
||||||
name="newPassword"
|
|
||||||
control={control}
|
|
||||||
render={({
|
|
||||||
field: { onChange, onBlur, value },
|
|
||||||
fieldState: { error },
|
|
||||||
}) => (
|
|
||||||
<StyledInputContainer>
|
|
||||||
<TextInputV2
|
|
||||||
autoFocus
|
|
||||||
value={value}
|
|
||||||
type="password"
|
|
||||||
placeholder={t`New Password`}
|
|
||||||
onBlur={onBlur}
|
|
||||||
onChange={onChange}
|
|
||||||
error={error?.message}
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
</StyledInputContainer>
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
</StyledFullWidthMotionDiv>
|
</SkeletonTheme>
|
||||||
|
) : (
|
||||||
|
<StyledForm onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<StyledFullWidthMotionDiv
|
||||||
|
initial={{ opacity: 0, height: 0 }}
|
||||||
|
animate={{ opacity: 1, height: 'auto' }}
|
||||||
|
transition={{
|
||||||
|
type: 'spring',
|
||||||
|
stiffness: 800,
|
||||||
|
damping: 35,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<StyledInputContainer>
|
||||||
|
<TextInputV2
|
||||||
|
autoFocus
|
||||||
|
value={email}
|
||||||
|
placeholder={t`Email`}
|
||||||
|
fullWidth
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</StyledInputContainer>
|
||||||
|
</StyledFullWidthMotionDiv>
|
||||||
|
<StyledFullWidthMotionDiv
|
||||||
|
initial={{ opacity: 0, height: 0 }}
|
||||||
|
animate={{ opacity: 1, height: 'auto' }}
|
||||||
|
transition={{
|
||||||
|
type: 'spring',
|
||||||
|
stiffness: 800,
|
||||||
|
damping: 35,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Controller
|
||||||
|
name="newPassword"
|
||||||
|
control={control}
|
||||||
|
render={({
|
||||||
|
field: { onChange, onBlur, value },
|
||||||
|
fieldState: { error },
|
||||||
|
}) => (
|
||||||
|
<StyledInputContainer>
|
||||||
|
<TextInputV2
|
||||||
|
autoFocus
|
||||||
|
value={value}
|
||||||
|
type="password"
|
||||||
|
placeholder={t`New Password`}
|
||||||
|
onBlur={onBlur}
|
||||||
|
onChange={onChange}
|
||||||
|
error={error?.message}
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
</StyledInputContainer>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</StyledFullWidthMotionDiv>
|
||||||
|
|
||||||
<StyledMainButton
|
<StyledMainButton
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
title={t`Change Password`}
|
title={t`Change Password`}
|
||||||
type="submit"
|
type="submit"
|
||||||
fullWidth
|
fullWidth
|
||||||
disabled={isUpdatingPassword}
|
disabled={isUpdatingPassword}
|
||||||
/>
|
/>
|
||||||
</StyledForm>
|
</StyledForm>
|
||||||
)}
|
)}
|
||||||
</StyledContentContainer>
|
</StyledContentContainer>
|
||||||
</StyledMainContainer>
|
</StyledMainContainer>
|
||||||
|
</Modal.Content>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -20,11 +20,12 @@ import { DEFAULT_WORKSPACE_NAME } from '@/ui/navigation/navigation-drawer/consta
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
import { useWorkspaceFromInviteHash } from '@/auth/sign-in-up/hooks/useWorkspaceFromInviteHash';
|
import { useWorkspaceFromInviteHash } from '@/auth/sign-in-up/hooks/useWorkspaceFromInviteHash';
|
||||||
|
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||||
import { useLingui } from '@lingui/react/macro';
|
import { useLingui } from '@lingui/react/macro';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { PublicWorkspaceDataOutput } from '~/generated/graphql';
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { AnimatedEaseIn } from 'twenty-ui/utilities';
|
import { AnimatedEaseIn } from 'twenty-ui/utilities';
|
||||||
|
import { PublicWorkspaceDataOutput } from '~/generated/graphql';
|
||||||
|
|
||||||
const StandardContent = ({
|
const StandardContent = ({
|
||||||
workspacePublicData,
|
workspacePublicData,
|
||||||
@ -38,14 +39,14 @@ const StandardContent = ({
|
|||||||
title: string;
|
title: string;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||||
<AnimatedEaseIn>
|
<AnimatedEaseIn>
|
||||||
<Logo secondaryLogo={workspacePublicData?.logo} />
|
<Logo secondaryLogo={workspacePublicData?.logo} />
|
||||||
</AnimatedEaseIn>
|
</AnimatedEaseIn>
|
||||||
<Title animate>{title}</Title>
|
<Title animate>{title}</Title>
|
||||||
{signInUpForm}
|
{signInUpForm}
|
||||||
{signInUpStep !== SignInUpStep.Password && <FooterNote />}
|
{signInUpStep !== SignInUpStep.Password && <FooterNote />}
|
||||||
</>
|
</Modal.Content>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
import styled from '@emotion/styled';
|
|
||||||
import { motion } from 'framer-motion';
|
|
||||||
|
|
||||||
const StyledContentContainer = styled(motion.div)`
|
|
||||||
height: 480px;
|
|
||||||
margin-bottom: ${({ theme }) => theme.spacing(8)};
|
|
||||||
margin-top: ${({ theme }) => theme.spacing(4)};
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const SignInUpLoading = () => {
|
|
||||||
return <StyledContentContainer />;
|
|
||||||
};
|
|
||||||
@ -8,6 +8,7 @@ import { TrialCard } from '@/billing/components/TrialCard';
|
|||||||
import { useHandleCheckoutSession } from '@/billing/hooks/useHandleCheckoutSession';
|
import { useHandleCheckoutSession } from '@/billing/hooks/useHandleCheckoutSession';
|
||||||
import { isBillingPriceLicensed } from '@/billing/utils/isBillingPriceLicensed';
|
import { isBillingPriceLicensed } from '@/billing/utils/isBillingPriceLicensed';
|
||||||
import { billingState } from '@/client-config/states/billingState';
|
import { billingState } from '@/client-config/states/billingState';
|
||||||
|
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { Trans, useLingui } from '@lingui/react/macro';
|
import { Trans, useLingui } from '@lingui/react/macro';
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||||
@ -171,7 +172,7 @@ export const ChooseYourPlan = () => {
|
|||||||
?.baseProduct.name;
|
?.baseProduct.name;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Modal.Content>
|
||||||
{isDefined(baseProductPrice) && isDefined(billing) ? (
|
{isDefined(baseProductPrice) && isDefined(billing) ? (
|
||||||
<>
|
<>
|
||||||
<Title noMarginTop>
|
<Title noMarginTop>
|
||||||
@ -250,6 +251,6 @@ export const ChooseYourPlan = () => {
|
|||||||
) : (
|
) : (
|
||||||
<StyledChooseYourPlanPlaceholder />
|
<StyledChooseYourPlanPlaceholder />
|
||||||
)}
|
)}
|
||||||
</>
|
</Modal.Content>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import { PageHotkeyScope } from '@/types/PageHotkeyScope';
|
|||||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||||
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
||||||
|
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
||||||
import { Trans, useLingui } from '@lingui/react/macro';
|
import { Trans, useLingui } from '@lingui/react/macro';
|
||||||
@ -143,7 +144,7 @@ export const CreateProfile = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||||
<Title noMarginTop>
|
<Title noMarginTop>
|
||||||
<Trans>Create profile</Trans>
|
<Trans>Create profile</Trans>
|
||||||
</Title>
|
</Title>
|
||||||
@ -218,6 +219,6 @@ export const CreateProfile = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
/>
|
/>
|
||||||
</StyledButtonContainer>
|
</StyledButtonContainer>
|
||||||
</>
|
</Modal.Content>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { WorkspaceLogoUploader } from '@/settings/workspace/components/Workspace
|
|||||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||||
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
||||||
|
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||||
import { Trans, useLingui } from '@lingui/react/macro';
|
import { Trans, useLingui } from '@lingui/react/macro';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { H2Title } from 'twenty-ui/display';
|
import { H2Title } from 'twenty-ui/display';
|
||||||
@ -106,7 +107,7 @@ export const CreateWorkspace = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||||
<Title noMarginTop>
|
<Title noMarginTop>
|
||||||
<Trans>Create your workspace</Trans>
|
<Trans>Create your workspace</Trans>
|
||||||
</Title>
|
</Title>
|
||||||
@ -156,6 +157,6 @@ export const CreateWorkspace = () => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
/>
|
/>
|
||||||
</StyledButtonContainer>
|
</StyledButtonContainer>
|
||||||
</>
|
</Modal.Content>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import { PageHotkeyScope } from '@/types/PageHotkeyScope';
|
|||||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||||
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
||||||
|
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
@ -164,7 +165,7 @@ export const InviteTeam = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||||
<Title>
|
<Title>
|
||||||
<Trans>Invite your team</Trans>
|
<Trans>Invite your team</Trans>
|
||||||
</Title>
|
</Title>
|
||||||
@ -224,6 +225,6 @@ export const InviteTeam = () => {
|
|||||||
<Trans>Skip</Trans>
|
<Trans>Skip</Trans>
|
||||||
</ClickToActionLink>
|
</ClickToActionLink>
|
||||||
</StyledActionSkipLinkContainer>
|
</StyledActionSkipLinkContainer>
|
||||||
</>
|
</Modal.Content>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { SubTitle } from '@/auth/components/SubTitle';
|
|||||||
import { Title } from '@/auth/components/Title';
|
import { Title } from '@/auth/components/Title';
|
||||||
import { currentUserState } from '@/auth/states/currentUserState';
|
import { currentUserState } from '@/auth/states/currentUserState';
|
||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
|
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||||
import { useSubscriptionStatus } from '@/workspace/hooks/useSubscriptionStatus';
|
import { useSubscriptionStatus } from '@/workspace/hooks/useSubscriptionStatus';
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
@ -64,7 +65,7 @@ export const PaymentSuccess = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||||
<AnimatedEaseIn>
|
<AnimatedEaseIn>
|
||||||
<StyledCheckContainer color={color}>
|
<StyledCheckContainer color={color}>
|
||||||
<IconCheck color={color} size={24} stroke={3} />
|
<IconCheck color={color} size={24} stroke={3} />
|
||||||
@ -79,6 +80,6 @@ export const PaymentSuccess = () => {
|
|||||||
onClick={navigateWithSubscriptionCheck}
|
onClick={navigateWithSubscriptionCheck}
|
||||||
/>
|
/>
|
||||||
</StyledButtonContainer>
|
</StyledButtonContainer>
|
||||||
</>
|
</Modal.Content>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import { isMicrosoftCalendarEnabledState } from '@/client-config/states/isMicros
|
|||||||
import { isMicrosoftMessagingEnabledState } from '@/client-config/states/isMicrosoftMessagingEnabledState';
|
import { isMicrosoftMessagingEnabledState } from '@/client-config/states/isMicrosoftMessagingEnabledState';
|
||||||
import { useTriggerApisOAuth } from '@/settings/accounts/hooks/useTriggerApiOAuth';
|
import { useTriggerApisOAuth } from '@/settings/accounts/hooks/useTriggerApiOAuth';
|
||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
|
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||||
import { ConnectedAccountProvider } from 'twenty-shared/types';
|
import { ConnectedAccountProvider } from 'twenty-shared/types';
|
||||||
import { IconGoogle, IconMicrosoft } from 'twenty-ui/display';
|
import { IconGoogle, IconMicrosoft } from 'twenty-ui/display';
|
||||||
import { MainButton } from 'twenty-ui/input';
|
import { MainButton } from 'twenty-ui/input';
|
||||||
@ -104,7 +105,7 @@ export const SyncEmails = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||||
<Title noMarginTop>Emails and Calendar</Title>
|
<Title noMarginTop>Emails and Calendar</Title>
|
||||||
<SubTitle>
|
<SubTitle>
|
||||||
Sync your Emails and Calendar with Twenty. Choose your privacy settings.
|
Sync your Emails and Calendar with Twenty. Choose your privacy settings.
|
||||||
@ -147,6 +148,6 @@ export const SyncEmails = () => {
|
|||||||
Continue without sync
|
Continue without sync
|
||||||
</ClickToActionLink>
|
</ClickToActionLink>
|
||||||
</StyledActionLinkContainer>
|
</StyledActionLinkContainer>
|
||||||
</>
|
</Modal.Content>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user