From 602dc9d791e30a93e85bdfa7adf231b2c9626e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Pasteau?= <4895034+ClementPasteau@users.noreply.github.com> Date: Wed, 13 Nov 2024 10:23:02 +0100 Subject: [PATCH] Improve login & signup dialogs design (#7152) --- .../HomePage/GetStartedSection/index.js | 373 +----------------- .../HomePage/HomePageHeader.js | 4 +- newIDE/app/src/Profile/CreateAccountDialog.js | 37 +- newIDE/app/src/Profile/CreateAccountForm.js | 256 +++++++----- newIDE/app/src/Profile/LoginDialog.js | 45 +-- newIDE/app/src/Profile/LoginForm.js | 204 ++++++---- newIDE/app/src/Profile/ResponsiveDelimiter.js | 57 +++ newIDE/app/src/UI/Dialog.js | 2 +- .../Profile/CreateAccountDialog.stories.js | 7 + 9 files changed, 378 insertions(+), 607 deletions(-) create mode 100644 newIDE/app/src/Profile/ResponsiveDelimiter.js diff --git a/newIDE/app/src/MainFrame/EditorContainers/HomePage/GetStartedSection/index.js b/newIDE/app/src/MainFrame/EditorContainers/HomePage/GetStartedSection/index.js index 8d6002704a47..6ed4be3bdabf 100644 --- a/newIDE/app/src/MainFrame/EditorContainers/HomePage/GetStartedSection/index.js +++ b/newIDE/app/src/MainFrame/EditorContainers/HomePage/GetStartedSection/index.js @@ -3,60 +3,32 @@ import * as React from 'react'; import { Trans } from '@lingui/macro'; import { type I18n as I18nType } from '@lingui/core'; import Text from '../../../../UI/Text'; -import { ColumnStackLayout, LineStackLayout } from '../../../../UI/Layout'; +import { ColumnStackLayout } from '../../../../UI/Layout'; import AuthenticatedUserContext from '../../../../Profile/AuthenticatedUserContext'; import { useOnlineStatus } from '../../../../Utils/OnlineStatus'; import TreeLeaves from '../../../../UI/CustomSvgIcons/TreeLeaves'; import SectionContainer from '../SectionContainer'; -import JewelPlatform from '../../../../UI/CustomSvgIcons/JewelPlatform'; import RaisedButton from '../../../../UI/RaisedButton'; -import FlatButton from '../../../../UI/FlatButton'; import useForceUpdate from '../../../../Utils/UseForceUpdate'; -import { Column, LargeSpacer, Line } from '../../../../UI/Grid'; -import { useResponsiveWindowSize } from '../../../../UI/Responsive/ResponsiveWindowMeasurer'; +import { LargeSpacer, Line } from '../../../../UI/Grid'; import CircularProgress from '../../../../UI/CircularProgress'; -import BackgroundText from '../../../../UI/BackgroundText'; -import { - type UsernameAvailability, - type UserSurvey as UserSurveyType, -} from '../../../../Utils/GDevelopServices/User'; +import { type UserSurvey as UserSurveyType } from '../../../../Utils/GDevelopServices/User'; import UserSurvey from './UserSurvey'; import { clearUserSurveyPersistedState, hasStartedUserSurvey, } from './UserSurveyStorage'; import LinearProgress from '../../../../UI/LinearProgress'; -import CreateAccountForm from '../../../../Profile/CreateAccountForm'; -import LoginForm from '../../../../Profile/LoginForm'; import PreferencesContext from '../../../Preferences/PreferencesContext'; import RecommendationList from './RecommendationList'; import ErrorBoundary from '../../../../UI/ErrorBoundary'; import { delay } from '../../../../Utils/Delay'; -import { type AuthError } from '../../../../Utils/GDevelopServices/Authentication'; import { type SubscriptionPlanWithPricingSystems } from '../../../../Utils/GDevelopServices/Usage'; import Checkbox from '../../../../UI/Checkbox'; -import { getGetStartedSectionViewCount } from '../../../../Utils/Analytics/LocalStats'; import { sendUserSurveyCompleted } from '../../../../Utils/Analytics/EventSender'; import { type NewProjectSetup } from '../../../../ProjectCreation/NewProjectSetupDialog'; import { type ExampleShortHeader } from '../../../../Utils/GDevelopServices/Example'; -const ONE_WEEK = 7 * 24 * 3600 * 1000; -const THRESHOLD_BEFORE_ALLOWING_TO_HIDE_GET_STARTED_SECTION = 15; - -const shouldDisplayOptionToHideGetStartedSection = ({ - isAuthenticated, -}: { - isAuthenticated: boolean, -}): boolean => { - if (!isAuthenticated) return false; - - const getStartedSectionViewCount = getGetStartedSectionViewCount(); - return ( - getStartedSectionViewCount > - THRESHOLD_BEFORE_ALLOWING_TO_HIDE_GET_STARTED_SECTION - ); -}; - const styles = { icon: { width: 80, @@ -110,20 +82,10 @@ const GetStartedSection = ({ const isFillingOutSurvey = hasStartedUserSurvey(); const isOnline = useOnlineStatus(); const authenticatedUser = React.useContext(AuthenticatedUserContext); - const [ - isLoggingInUsingProvider, - setIsLoggingInUsingProvider, - ] = React.useState(false); const { profile, - onResetPassword, creatingOrLoggingInAccount, - onLogin, - onLoginWithProvider, - onCancelLoginOrSignUp, onEditProfile, - onCreateAccount, - authenticationError, loginState, } = authenticatedUser; const { @@ -131,59 +93,14 @@ const GetStartedSection = ({ setShowGetStartedSectionByDefault, } = React.useContext(PreferencesContext); const recommendationsGettingDelayPromise = React.useRef>(null); - const [error, setError] = React.useState(null); const forceUpdate = useForceUpdate(); - const { isMobile } = useResponsiveWindowSize(); const [step, setStep] = React.useState< - | 'welcome' - | 'login' - | 'register' - | 'survey' - | 'surveyFinished' - | 'recommendations' + 'survey' | 'surveyFinished' | 'recommendations' >(isFillingOutSurvey ? 'survey' : 'recommendations'); - const [email, setEmail] = React.useState(''); - const [password, setPassword] = React.useState(''); - const [username, setUsername] = React.useState(''); + const [errorSendingSurvey, setErrorSendingSurvey] = React.useState( false ); - const [ - usernameAvailability, - setUsernameAvailability, - ] = React.useState(null); - const [ - isValidatingUsername, - setIsValidatingUsername, - ] = React.useState(false); - const [getNewsletterEmail, setGetNewsletterEmail] = React.useState( - false - ); - const [ - lastVisitedAuthenticationStep, - setLastVisitedAuthenticationStep, - ] = React.useState<'login' | 'register'>('login'); - - const doLogin = () => { - if (creatingOrLoggingInAccount) return; - onLogin({ - email: email.trim(), - password, - }); - }; - - const doCreateAccount = async () => { - if (creatingOrLoggingInAccount) return; - onCreateAccount( - { - email: email.trim(), - password, - getNewsletterEmail, - username, - }, - preferences - ); - }; const onSurveyFinished = async (survey: UserSurveyType) => { try { @@ -196,40 +113,15 @@ const GetStartedSection = ({ ]); sendUserSurveyCompleted(); clearUserSurveyPersistedState(); - setStep('recommendations'); } catch (error) { console.error('An error occurred when sending survey:', error); setErrorSendingSurvey(true); - setStep('welcome'); } finally { recommendationsGettingDelayPromise.current = null; + setStep('recommendations'); } }; - const loginWithProvider = React.useCallback( - async provider => { - try { - setIsLoggingInUsingProvider(true); - await onLoginWithProvider(provider); - } finally { - setIsLoggingInUsingProvider(false); - } - }, - [onLoginWithProvider] - ); - - // Logic to store the last visited authentication step. - React.useEffect( - () => { - if (step === 'login') { - setLastVisitedAuthenticationStep('login'); - } else if (step === 'register') { - setLastVisitedAuthenticationStep('register'); - } - }, - [step] - ); - React.useEffect( () => { if (!authenticatedUser.authenticated) clearUserSurveyPersistedState(); @@ -237,24 +129,6 @@ const GetStartedSection = ({ [authenticatedUser.authenticated] ); - // Set the error when the authentication error changes. - React.useEffect( - () => { - setError(authenticationError); - }, - [authenticationError] - ); - - // Reset form when user changes authentication step. - React.useEffect( - () => { - setError(null); - setEmail(''); - setPassword(''); - }, - [lastVisitedAuthenticationStep] - ); - const shouldDisplayAnnouncements = !authenticatedUser.limits || !authenticatedUser.limits.capabilities.classrooms || @@ -284,23 +158,6 @@ const GetStartedSection = ({ > - {isLoggingInUsingProvider && ( -
- - - Cancel} - onClick={onCancelLoginOrSignUp} - /> - - -
- )} ); @@ -356,224 +213,6 @@ const GetStartedSection = ({ ); } - if (step === 'login') { - return ( - - - - - Log in to GDevelop - - - - This will synchronise your selected content wherever you go. - - -
- - {/* TODO: Add button to cancel login with providers */} -
-
-
- - - Back} - onClick={() => setStep('welcome')} - fullWidth - /> - Next} - primary - onClick={doLogin} - fullWidth - /> - - -
-
-
- ); - } - - if (step === 'register') { - return ( - - - - - Let's start by creating your GDevelop account - - - - This will synchronise your selected content wherever you go. - - -
- -
-
-
- - - Back} - onClick={() => setStep('welcome')} - fullWidth - /> - Next} - primary - onClick={doCreateAccount} - fullWidth - /> - - -
-
-
- ); - } - - if (step === 'welcome') { - const isNewUser = profile && Date.now() - profile.createdAt < ONE_WEEK; - return ( - - - - - {!profile || isNewUser ? ( - Welcome to GDevelop! - ) : profile && profile.username ? ( - Good to see you {profile.username}! - ) : ( - We have something new for you! - )} - - - - - We've made a selection of GDevelop content to help you on your - game development journey. - - - - - {profile ? ( - - Answer our questionnaire and get recommendations according to - your current objectives. - - ) : ( - Let's start by creating your account. - )} - -
- {profile ? ( - - Let's go!} - primary - onClick={() => setStep('survey')} - fullWidth - /> - - ) : ( - - Let's go!} - primary - onClick={() => setStep('register')} - fullWidth - /> - I already have an account} - onClick={() => setStep('login')} - fullWidth - /> - - )} -
-
- {shouldDisplayOptionToHideGetStartedSection({ - isAuthenticated: authenticatedUser.authenticated, - }) && ( -
- Don't show this screen on next startup} - checked={!preferences.showGetStartedSectionByDefault} - onCheck={(e, checked) => { - if (checked) onUserSurveyHidden(); - setShowGetStartedSectionByDefault(!checked); - }} - /> -
- )} -
-
- ); - } - if (step === 'surveyFinished') { return ( diff --git a/newIDE/app/src/MainFrame/EditorContainers/HomePage/HomePageHeader.js b/newIDE/app/src/MainFrame/EditorContainers/HomePage/HomePageHeader.js index 802b858b2407..dce534ecbdd2 100644 --- a/newIDE/app/src/MainFrame/EditorContainers/HomePage/HomePageHeader.js +++ b/newIDE/app/src/MainFrame/EditorContainers/HomePage/HomePageHeader.js @@ -18,6 +18,7 @@ import { useResponsiveWindowSize } from '../../../UI/Responsive/ResponsiveWindow import SaveProjectIcon from '../../SaveProjectIcon'; import Mobile from '../../../UI/CustomSvgIcons/Mobile'; import Desktop from '../../../UI/CustomSvgIcons/Desktop'; +import AuthenticatedUserContext from '../../../Profile/AuthenticatedUserContext'; const electron = optionalRequire('electron'); type Props = {| @@ -38,6 +39,7 @@ export const HomePageHeader = ({ canSave, }: Props) => { const { isMobile } = useResponsiveWindowSize(); + const { profile } = React.useContext(AuthenticatedUserContext); return ( @@ -92,7 +94,7 @@ export const HomePageHeader = ({ /> ))} - + {profile && } {isMobile ? ( diff --git a/newIDE/app/src/Profile/CreateAccountDialog.js b/newIDE/app/src/Profile/CreateAccountDialog.js index fbc00eeb05b6..d47b5bbb59dc 100644 --- a/newIDE/app/src/Profile/CreateAccountDialog.js +++ b/newIDE/app/src/Profile/CreateAccountDialog.js @@ -1,7 +1,6 @@ // @flow import React from 'react'; import { Trans } from '@lingui/macro'; -import { t } from '@lingui/macro'; import FlatButton from '../UI/FlatButton'; import Dialog, { DialogPrimaryButton } from '../UI/Dialog'; @@ -12,23 +11,21 @@ import { } from '../Utils/GDevelopServices/Authentication'; import { type UsernameAvailability } from '../Utils/GDevelopServices/User'; import LeftLoader from '../UI/LeftLoader'; -import BackgroundText from '../UI/BackgroundText'; -import { ColumnStackLayout, LineStackLayout } from '../UI/Layout'; -import { MarkdownText } from '../UI/MarkdownText'; +import { ColumnStackLayout } from '../UI/Layout'; import { isUsernameValid } from './UsernameField'; import HelpButton from '../UI/HelpButton'; import Text from '../UI/Text'; import GDevelopGLogo from '../UI/CustomSvgIcons/GDevelopGLogo'; -import { Column } from '../UI/Grid'; -import Link from '../UI/Link'; import { useResponsiveWindowSize } from '../UI/Responsive/ResponsiveWindowMeasurer'; import CreateAccountForm from './CreateAccountForm'; const getStyles = ({ isMobile }) => { return { formContainer: { - width: isMobile ? '95%' : '60%', + display: 'flex', + width: isMobile ? '95%' : '90%', marginTop: 10, + flexDirection: 'column', }, }; }; @@ -182,7 +179,7 @@ const CreateAccountDialog = ({ onRequestClose={() => { if (!createAccountInProgress) onClose(); }} - maxWidth="sm" + maxWidth="md" open flexColumnBody > @@ -194,24 +191,8 @@ const CreateAccountDialog = ({ > - Sign up for free! + Welcome to GDevelop! - - - - Already a member? - - - - Log in to your account - - - -
- - - ); diff --git a/newIDE/app/src/Profile/CreateAccountForm.js b/newIDE/app/src/Profile/CreateAccountForm.js index ffd25cfc05bc..37fc9686c376 100644 --- a/newIDE/app/src/Profile/CreateAccountForm.js +++ b/newIDE/app/src/Profile/CreateAccountForm.js @@ -1,6 +1,6 @@ // @flow import React from 'react'; -import { Trans } from '@lingui/macro'; +import { t, Trans } from '@lingui/macro'; import TextField from '../UI/TextField'; import { @@ -8,32 +8,46 @@ import { type IdentityProvider, } from '../Utils/GDevelopServices/Authentication'; import { type UsernameAvailability } from '../Utils/GDevelopServices/User'; -import { ColumnStackLayout, ResponsiveLineStackLayout } from '../UI/Layout'; +import { + ColumnStackLayout, + LineStackLayout, + ResponsiveLineStackLayout, +} from '../UI/Layout'; import { UsernameField } from './UsernameField'; import Checkbox from '../UI/Checkbox'; import Form from '../UI/Form'; import { getEmailErrorText, getPasswordErrorText } from './CreateAccountDialog'; -import { Column, Line } from '../UI/Grid'; -import Text from '../UI/Text'; +import { Column, Line, Spacer } from '../UI/Grid'; import FlatButton from '../UI/FlatButton'; import Google from '../UI/CustomSvgIcons/Google'; import Apple from '../UI/CustomSvgIcons/Apple'; import GitHub from '../UI/CustomSvgIcons/GitHub'; import AlertMessage from '../UI/AlertMessage'; import { accountsAlreadyExistsWithDifferentProviderCopy } from './LoginForm'; +import RaisedButton from '../UI/RaisedButton'; +import Text from '../UI/Text'; +import Link from '../UI/Link'; +import { useResponsiveWindowSize } from '../UI/Responsive/ResponsiveWindowMeasurer'; +import BackgroundText from '../UI/BackgroundText'; +import { MarkdownText } from '../UI/MarkdownText'; +import ResponsiveDelimiter from './ResponsiveDelimiter'; -const styles = { - identityProvidersBlock: { - display: 'flex', - flexDirection: 'column', - alignItems: 'stretch', - marginTop: 10, +const getStyles = ({ verticalDesign }) => ({ + logInContainer: { + width: '100%', + }, + panelContainer: { + width: verticalDesign ? '100%' : '90%', }, icon: { width: 16, height: 16, }, -}; + backgroundText: { + width: '100%', + textAlign: 'start', + }, +}); type Props = {| onCreateAccount: () => Promise, @@ -52,6 +66,7 @@ type Props = {| onChangeIsValidatingUsername: boolean => void, createAccountInProgress: boolean, error: ?AuthError, + onGoToLogin?: () => void, |}; const CreateAccountForm = ({ @@ -71,107 +86,148 @@ const CreateAccountForm = ({ onChangeIsValidatingUsername, createAccountInProgress, error, + onGoToLogin, }: Props) => { const accountsExistsWithOtherCredentials = error ? error.code === 'auth/account-exists-with-different-credential' : false; + const { isMobile, isLandscape } = useResponsiveWindowSize(); + + const verticalDesign = isMobile && !isLandscape; + const styles = getStyles({ verticalDesign }); + return ( -
+ {accountsExistsWithOtherCredentials && ( - + {accountsAlreadyExistsWithDifferentProviderCopy} )} - { - onChangeUsername(value); - }} - allowEmpty - onAvailabilityChecked={onChangeUsernameAvailability} - onAvailabilityCheckLoading={onChangeIsValidatingUsername} - isValidatingUsername={isValidatingUsername} - disabled={createAccountInProgress} - /> - Email} - errorText={getEmailErrorText(error)} - fullWidth - type="email" - required - onChange={(e, value) => { - onChangeEmail(value); - }} - onBlur={event => { - onChangeEmail(event.currentTarget.value.trim()); - }} - disabled={createAccountInProgress} - /> - Password} - errorText={getPasswordErrorText(error)} - type="password" - fullWidth - required - onChange={(e, value) => { - onChangePassword(value); - }} - disabled={createAccountInProgress} - /> - I want to receive the GDevelop Newsletter} - checked={optInNewsletterEmail} - onCheck={(e, value) => { - onChangeOptInNewsletterEmail(value); - }} - disabled={createAccountInProgress} - /> -
- - - Or continue with - - - - - } - onClick={() => { - onLoginWithProvider('google'); - }} - disabled={createAccountInProgress} - /> - } - onClick={() => { - onLoginWithProvider('github'); - }} - disabled={createAccountInProgress} - /> - } - onClick={() => { - onLoginWithProvider('apple'); - }} - disabled={createAccountInProgress} - /> - - -
+ + +
+ + Continue with Google} + icon={} + onClick={() => { + onLoginWithProvider('google'); + }} + disabled={createAccountInProgress} + /> + Continue with Github} + leftIcon={} + onClick={() => { + onLoginWithProvider('github'); + }} + disabled={createAccountInProgress} + /> + Continue with Apple} + leftIcon={} + onClick={() => { + onLoginWithProvider('apple'); + }} + disabled={createAccountInProgress} + /> + +
+
+ or} /> + +
+ + Email} + errorText={getEmailErrorText(error)} + fullWidth + type="email" + required + onChange={(e, value) => { + onChangeEmail(value); + }} + onBlur={event => { + onChangeEmail(event.currentTarget.value.trim()); + }} + disabled={createAccountInProgress} + /> + Password} + errorText={getPasswordErrorText(error)} + type="password" + fullWidth + required + onChange={(e, value) => { + onChangePassword(value); + }} + disabled={createAccountInProgress} + /> + { + onChangeUsername(value); + }} + allowEmpty + onAvailabilityChecked={onChangeUsernameAvailability} + onAvailabilityCheckLoading={onChangeIsValidatingUsername} + isValidatingUsername={isValidatingUsername} + disabled={createAccountInProgress} + /> + {onGoToLogin && ( +
+ + + Already a member? + + + + Log in to your account + + + +
+ )} +
+
+
+
+ + + I want to receive the GDevelop Newsletter} + checked={optInNewsletterEmail} + onCheck={(e, value) => { + onChangeOptInNewsletterEmail(value); + }} + disabled={createAccountInProgress} + /> + + + +
diff --git a/newIDE/app/src/Profile/LoginDialog.js b/newIDE/app/src/Profile/LoginDialog.js index d5f97fcb1a40..a819c8e24711 100644 --- a/newIDE/app/src/Profile/LoginDialog.js +++ b/newIDE/app/src/Profile/LoginDialog.js @@ -12,18 +12,21 @@ import { import LoginForm from './LoginForm'; import LeftLoader from '../UI/LeftLoader'; import Text from '../UI/Text'; -import { ColumnStackLayout, LineStackLayout } from '../UI/Layout'; -import { Column } from '../UI/Grid'; +import { ColumnStackLayout } from '../UI/Layout'; import HelpButton from '../UI/HelpButton'; import FlatButton from '../UI/FlatButton'; -import Link from '../UI/Link'; import GDevelopGLogo from '../UI/CustomSvgIcons/GDevelopGLogo'; import { useResponsiveWindowSize } from '../UI/Responsive/ResponsiveWindowMeasurer'; -const styles = { - formContainer: { - marginTop: 10, - }, +const getStyles = ({ isMobile }) => { + return { + formContainer: { + display: 'flex', + width: isMobile ? '95%' : '90%', + marginTop: 10, + flexDirection: 'column', + }, + }; }; type Props = {| @@ -50,6 +53,7 @@ const LoginDialog = ({ const { isMobile } = useResponsiveWindowSize(); const [email, setEmail] = React.useState(''); const [password, setPassword] = React.useState(''); + const styles = getStyles({ isMobile }); const doLogin = () => { if (loginInProgress) return; @@ -93,29 +97,7 @@ const LoginDialog = ({ Log in to your account - - - - Don't have an account yet? - - - - Create an account - - - - -
+
@@ -140,7 +123,7 @@ const LoginDialog = ({ cannotBeDismissed={loginInProgress} onRequestClose={onClose} onApply={doLogin} - maxWidth="sm" + maxWidth="md" open flexColumnBody > diff --git a/newIDE/app/src/Profile/LoginForm.js b/newIDE/app/src/Profile/LoginForm.js index e7e0781681cb..4c13d5e2fad2 100644 --- a/newIDE/app/src/Profile/LoginForm.js +++ b/newIDE/app/src/Profile/LoginForm.js @@ -10,29 +10,40 @@ import { } from '../Utils/GDevelopServices/Authentication'; import Text from '../UI/Text'; import { getEmailErrorText, getPasswordErrorText } from './CreateAccountDialog'; -import { ColumnStackLayout, ResponsiveLineStackLayout } from '../UI/Layout'; +import { + ColumnStackLayout, + LineStackLayout, + ResponsiveLineStackLayout, +} from '../UI/Layout'; import Link from '../UI/Link'; import ForgotPasswordDialog from './ForgotPasswordDialog'; import Form from '../UI/Form'; -import { Line } from '../UI/Grid'; +import { Column, Line, Spacer } from '../UI/Grid'; import FlatButton from '../UI/FlatButton'; import AlertMessage from '../UI/AlertMessage'; import Google from '../UI/CustomSvgIcons/Google'; import Apple from '../UI/CustomSvgIcons/Apple'; import GitHub from '../UI/CustomSvgIcons/GitHub'; +import { useResponsiveWindowSize } from '../UI/Responsive/ResponsiveWindowMeasurer'; +import RaisedButton from '../UI/RaisedButton'; +import ResponsiveDelimiter from './ResponsiveDelimiter'; -const styles = { - identityProvidersBlock: { - display: 'flex', - flexDirection: 'column', - alignItems: 'stretch', - marginTop: 10, +const getStyles = ({ verticalDesign }) => ({ + createAccountContainer: { + width: '100%', + }, + panelContainer: { + width: verticalDesign ? '100%' : '90%', }, icon: { width: 16, height: 16, }, -}; + backgroundText: { + width: '100%', + textAlign: 'start', + }, +}); export const accountsAlreadyExistsWithDifferentProviderCopy = ( @@ -51,6 +62,7 @@ type Props = {| onForgotPassword: (form: ForgotPasswordForm) => Promise, loginInProgress: boolean, error: ?AuthError, + onGoToCreateAccount?: () => void, |}; const LoginForm = ({ @@ -63,6 +75,7 @@ const LoginForm = ({ onForgotPassword, loginInProgress, error, + onGoToCreateAccount, }: Props) => { const [ isForgotPasswordDialogOpen, @@ -73,6 +86,10 @@ const LoginForm = ({ ? error.code === 'auth/account-exists-with-different-credential' : false; + const { isMobile, isLandscape } = useResponsiveWindowSize(); + const verticalDesign = isMobile && !isLandscape; + const styles = getStyles({ verticalDesign }); + return ( <> {accountsExistsWithOtherCredentials && ( - + {accountsAlreadyExistsWithDifferentProviderCopy} )} - Email} - errorText={getEmailErrorText(error)} - onChange={(e, value) => { - onChangeEmail(value); - }} - onBlur={event => { - onChangeEmail(event.currentTarget.value.trim()); - }} - fullWidth - type="email" - disabled={loginInProgress} - /> - Password} - errorText={getPasswordErrorText(error)} - type="password" - onChange={(e, value) => { - onChangePassword(value); - }} - fullWidth - disabled={loginInProgress} - /> + + +
+ + Continue with Google} + icon={} + onClick={() => { + onLoginWithProvider('google'); + }} + disabled={loginInProgress} + /> + Continue with Github} + leftIcon={} + onClick={() => { + onLoginWithProvider('github'); + }} + disabled={loginInProgress} + /> + Continue with Apple} + leftIcon={} + onClick={() => { + onLoginWithProvider('apple'); + }} + disabled={loginInProgress} + /> + +
+
+ or} /> + +
+ + Email} + errorText={getEmailErrorText(error)} + onChange={(e, value) => { + onChangeEmail(value); + }} + onBlur={event => { + onChangeEmail(event.currentTarget.value.trim()); + }} + fullWidth + type="email" + disabled={loginInProgress} + /> + Password} + errorText={getPasswordErrorText(error)} + type="password" + onChange={(e, value) => { + onChangePassword(value); + }} + fullWidth + disabled={loginInProgress} + /> + {onGoToCreateAccount && ( +
+ + + Don't have an account yet? + + + + Create an account + + + +
+ )} +
+
+
+
+ -
- - - Or continue with - - - - - } - onClick={() => { - onLoginWithProvider('google'); - }} - disabled={loginInProgress} - /> - } - onClick={() => { - onLoginWithProvider('github'); - }} - disabled={loginInProgress} - /> - } - onClick={() => { - onLoginWithProvider('apple'); - }} - disabled={loginInProgress} - /> - - -
{isForgotPasswordDialogOpen && ( ({ + delimiter: { + display: 'flex', + flex: 1, + borderLeft: !verticalDesign + ? `2px solid ${theme.home.separator.color}` + : 'none', + borderTop: verticalDesign + ? `2px solid ${theme.home.separator.color}` + : 'none', + }, +}); + +type Props = {| + text: React.Node, +|}; + +const ResponsiveDelimiter = ({ text }: Props) => { + const { isMobile, isLandscape } = useResponsiveWindowSize(); + + const verticalDesign = isMobile && !isLandscape; + const theme = React.useContext(GDevelopThemeContext); + const styles = getStyles({ verticalDesign, theme }); + + return !verticalDesign ? ( + +
+ + {text} + +
+ + ) : ( + + + +
+ + {text} + +
+ + + + ); +}; + +export default ResponsiveDelimiter; diff --git a/newIDE/app/src/UI/Dialog.js b/newIDE/app/src/UI/Dialog.js index 703c5141fbbd..e7da6f5b488a 100644 --- a/newIDE/app/src/UI/Dialog.js +++ b/newIDE/app/src/UI/Dialog.js @@ -299,7 +299,7 @@ const Dialog = ({ ? styles.flexBody : {}; const additionalPaddingStyle = { - paddingTop: title ? 0 : dialogTitlePadding, // Ensure the padding is here if there is no title. + paddingTop: 0, // Let the title container handle the padding, or no padding if there is no title. paddingBottom: hasActions ? 0 : dialogActionPadding, // Ensure the padding is here if there are no actions. }; const contentStyle = { diff --git a/newIDE/app/src/stories/componentStories/Profile/CreateAccountDialog.stories.js b/newIDE/app/src/stories/componentStories/Profile/CreateAccountDialog.stories.js index 51688c30a20b..330099b13f54 100644 --- a/newIDE/app/src/stories/componentStories/Profile/CreateAccountDialog.stories.js +++ b/newIDE/app/src/stories/componentStories/Profile/CreateAccountDialog.stories.js @@ -34,6 +34,13 @@ export const EmailErrorFromBackend = () => ( /> ); +export const AccountExists = () => ( + +); + export const Submitting = () => ( );