From 08b23dcd6ef3bdc2d46aa665593cee7cfa36d17d Mon Sep 17 00:00:00 2001 From: HichamELBSI Date: Tue, 3 Aug 2021 09:59:56 +0200 Subject: [PATCH 1/7] DS migration : Login view (CE & EEt ) Signed-off-by: HichamELBSI --- packages/core/admin/admin/src/StrapiApp.js | 2 +- .../src/assets/images/logo_strapi_auth_v4.png | Bin 0 -> 32897 bytes .../src/components/LocaleToggle/index.js | 36 +-- .../LocaleToggle/tests/index.test.js | 217 ------------------ .../admin/admin/src/components/Theme/index.js | 4 +- .../src/layouts/UnauthenticatedLayout.js | 43 ++++ .../core/admin/admin/src/pages/App/index.js | 2 + .../AuthPage/components/Login/BaseLogin.js | 131 ++++++----- .../pages/AuthPage/components/Login/index.js | 8 +- .../src/pages/AuthPage/components/Logo/Img.js | 4 +- .../pages/AuthPage/components/Logo/index.js | 3 +- .../admin/admin/src/pages/AuthPage/index.js | 92 +++----- .../core/admin/admin/src/translations/en.json | 5 +- .../pages/AuthPage/components/Login/index.js | 85 +++---- .../components/Providers/SSOProviders.js | 98 ++++++++ packages/core/admin/index.html | 28 +-- 16 files changed, 313 insertions(+), 445 deletions(-) create mode 100644 packages/core/admin/admin/src/assets/images/logo_strapi_auth_v4.png delete mode 100644 packages/core/admin/admin/src/components/LocaleToggle/tests/index.test.js create mode 100644 packages/core/admin/admin/src/layouts/UnauthenticatedLayout.js create mode 100644 packages/core/admin/ee/admin/pages/AuthPage/components/Providers/SSOProviders.js diff --git a/packages/core/admin/admin/src/StrapiApp.js b/packages/core/admin/admin/src/StrapiApp.js index a21d0596d5..7cddb854ef 100644 --- a/packages/core/admin/admin/src/StrapiApp.js +++ b/packages/core/admin/admin/src/StrapiApp.js @@ -11,7 +11,7 @@ import { basename, createHook } from './core/utils'; import configureStore from './core/store/configureStore'; import { Plugin } from './core/apis'; import App from './pages/App'; -import AuthLogo from './assets/images/logo_strapi_auth.png'; +import AuthLogo from './assets/images/logo_strapi_auth_v4.png'; import MenuLogo from './assets/images/strapi-img.png'; import Providers from './components/Providers'; import Theme from './components/Theme'; diff --git a/packages/core/admin/admin/src/assets/images/logo_strapi_auth_v4.png b/packages/core/admin/admin/src/assets/images/logo_strapi_auth_v4.png new file mode 100644 index 0000000000000000000000000000000000000000..ff23ded75682953d881f56e2f4e476ce971cf289 GIT binary patch literal 32897 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

GAgx0naE`tH)giFz+U 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 Gp#KBUZ*!Rd literal 0 HcmV?d00001 diff --git a/packages/core/admin/admin/src/components/LocaleToggle/index.js b/packages/core/admin/admin/src/components/LocaleToggle/index.js index 49c4505ac3..23cfe81c7a 100644 --- a/packages/core/admin/admin/src/components/LocaleToggle/index.js +++ b/packages/core/admin/admin/src/components/LocaleToggle/index.js @@ -4,42 +4,22 @@ * */ -import React, { useState } from 'react'; +import React from 'react'; import { useIntl } from 'react-intl'; -import { ButtonDropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap'; +import { SimpleMenu, MenuItem } from '@strapi/parts'; import useLocalesProvider from '../LocalesProvider/useLocalesProvider'; -import Wrapper from './Wrapper'; const LocaleToggle = () => { const { changeLocale, localeNames } = useLocalesProvider(); - - const [isOpen, setIsOpen] = useState(false); - const toggle = () => setIsOpen(prev => !prev); const { locale } = useIntl(); return ( - - - - {localeNames[locale]} - - - - {Object.keys(localeNames).map(lang => { - return ( - changeLocale(lang)} - className={`localeToggleItem ${locale === lang ? 'localeToggleItemActive' : ''}`} - > - {localeNames[lang]} - - ); - })} - - - + + {Object.keys(localeNames).map(lang => ( + changeLocale(lang)} key={lang}>{localeNames[lang]} + ))} + ); }; -export default LocaleToggle; +export default LocaleToggle; \ No newline at end of file diff --git a/packages/core/admin/admin/src/components/LocaleToggle/tests/index.test.js b/packages/core/admin/admin/src/components/LocaleToggle/tests/index.test.js deleted file mode 100644 index 1fe55951ca..0000000000 --- a/packages/core/admin/admin/src/components/LocaleToggle/tests/index.test.js +++ /dev/null @@ -1,217 +0,0 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import LanguageProvider from '../../LanguageProvider'; -import en from '../../../translations/en.json'; -import LocaleToggle from '../index'; - -const messages = { en }; -const localeNames = { en: 'English' }; - -describe('', () => { - it('should not crash', () => { - const App = ( - - - - ); - - const { container } = render(App); - expect(container.firstChild).toMatchInlineSnapshot(` - .c0 { - -webkit-font-smoothing: antialiased; - } - - .c0 > div { - height: 6rem; - line-height: 5.8rem; - z-index: 999; - } - - .c0 > div > button { - width: 100%; - padding: 0 30px; - background: transparent; - border: none; - border-radius: 0; - color: #333740; - font-weight: 500; - text-align: right; - cursor: pointer; - -webkit-transition: background 0.2s ease-out; - transition: background 0.2s ease-out; - } - - .c0 > div > button:hover, - .c0 > div > button:focus, - .c0 > div > button:active { - color: #333740; - background-color: #fafafb !important; - } - - .c0 > div > button > i, - .c0 > div > button > svg { - margin-left: 10px; - -webkit-transition: -webkit-transform 0.3s ease-out; - -webkit-transition: transform 0.3s ease-out; - transition: transform 0.3s ease-out; - } - - .c0 > div > button > i[alt='true'], - .c0 > div > button > svg[alt='true'] { - -webkit-transform: rotateX(180deg); - -ms-transform: rotateX(180deg); - transform: rotateX(180deg); - } - - .c0 .localeDropdownContent { - -webkit-font-smoothing: antialiased; - } - - .c0 .localeDropdownContent span { - color: #333740; - font-size: 13px; - font-family: Lato; - font-weight: 500; - -webkit-letter-spacing: 0.5; - -moz-letter-spacing: 0.5; - -ms-letter-spacing: 0.5; - letter-spacing: 0.5; - vertical-align: baseline; - } - - .c0 .localeDropdownMenu { - min-width: 90px !important; - max-height: 162px !important; - overflow: auto !important; - margin: 0 !important; - padding: 0; - line-height: 1.8rem; - border: none !important; - border-top-left-radius: 0 !important; - border-top-right-radius: 0 !important; - box-shadow: 0 1px 4px 0px rgba(40,42,49,0.05); - } - - .c0 .localeDropdownMenu:before { - content: ''; - position: absolute; - top: -3px; - left: -1px; - width: calc(100% + 1px); - height: 3px; - box-shadow: 0 1px 2px 0 rgba(40,42,49,0.16); - } - - .c0 .localeDropdownMenu > button { - height: 40px; - padding: 0px 15px; - line-height: 40px; - color: #f75b1d; - font-size: 13px; - font-weight: 500; - -webkit-letter-spacing: 0.5; - -moz-letter-spacing: 0.5; - -ms-letter-spacing: 0.5; - letter-spacing: 0.5; - } - - .c0 .localeDropdownMenu > button:hover, - .c0 .localeDropdownMenu > button:focus, - .c0 .localeDropdownMenu > button:active { - background-color: #fafafb !important; - border-radius: 0px; - cursor: pointer; - } - - .c0 .localeDropdownMenu > button:first-child { - line-height: 50px; - margin-bottom: 4px; - } - - .c0 .localeDropdownMenu > button:first-child:hover, - .c0 .localeDropdownMenu > button:first-child:active { - color: #333740; - } - - .c0 .localeDropdownMenu > button:not(:first-child) { - height: 36px; - line-height: 36px; - } - - .c0 .localeDropdownMenu > button:not(:first-child) > i, - .c0 .localeDropdownMenu > button:not(:first-child) > svg { - margin-left: 10px; - } - - .c0 .localeDropdownMenuNotLogged { - background: transparent !important; - box-shadow: none !important; - border: 1px solid #e3e9f3 !important; - border-top: 0px !important; - } - - .c0 .localeDropdownMenuNotLogged button { - padding-left: 17px; - } - - .c0 .localeDropdownMenuNotLogged button:hover { - background-color: #f7f8f8 !important; - } - - .c0 .localeDropdownMenuNotLogged:before { - box-shadow: none !important; - } - - .c0 .localeToggleItem img { - max-height: 13.37px; - margin-left: 9px; - } - - .c0 .localeToggleItem:active { - color: black; - } - - .c0 .localeToggleItem:hover { - background-color: #fafafb !important; - } - - .c0 .localeToggleItemActive { - color: #333740 !important; - } - -

- `); - }); -}); diff --git a/packages/core/admin/admin/src/components/Theme/index.js b/packages/core/admin/admin/src/components/Theme/index.js index 313ccf3762..92e479b9ec 100644 --- a/packages/core/admin/admin/src/components/Theme/index.js +++ b/packages/core/admin/admin/src/components/Theme/index.js @@ -1,12 +1,12 @@ import React from 'react'; import { ThemeProvider } from 'styled-components'; import PropTypes from 'prop-types'; -import GlobalStyle from '../GlobalStyle'; +// import GlobalStyle from '../GlobalStyle'; import Fonts from '../Fonts'; const Theme = ({ children, theme }) => ( - + {/* */} {children} diff --git a/packages/core/admin/admin/src/layouts/UnauthenticatedLayout.js b/packages/core/admin/admin/src/layouts/UnauthenticatedLayout.js new file mode 100644 index 0000000000..d4f53b4c0a --- /dev/null +++ b/packages/core/admin/admin/src/layouts/UnauthenticatedLayout.js @@ -0,0 +1,43 @@ +import React from 'react'; +import styled from 'styled-components'; +import PropTypes from 'prop-types'; +import { Box, Row } from '@strapi/parts'; +import LocaleToggle from '../components/LocaleToggle'; + +const Wrapper = styled(Box)` + margin: 0 auto; + width: 552px; +`; + +export const Column = styled(Row)` + flex-direction: column; +`; + +const UnauthenticatedLayout = ({ children }) => { + return ( +
+ + + + + + + + {children} + + +
+ ); +}; + +UnauthenticatedLayout.propTypes = { + children: PropTypes.node.isRequired, +}; + +export default UnauthenticatedLayout; diff --git a/packages/core/admin/admin/src/pages/App/index.js b/packages/core/admin/admin/src/pages/App/index.js index d1216617c5..40e4c2e2c2 100644 --- a/packages/core/admin/admin/src/pages/App/index.js +++ b/packages/core/admin/admin/src/pages/App/index.js @@ -13,6 +13,7 @@ import { useNotification, TrackingContext, } from '@strapi/helper-plugin'; +import { SkipToContent } from '@strapi/parts'; import PrivateRoute from '../../components/PrivateRoute'; import { createRoute, makeUniqueRoutes } from '../../utils'; import AuthPage from '../AuthPage'; @@ -105,6 +106,7 @@ function App() { return ( }> + Skip to content {authRoutes} diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js b/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js index cf45d1cf1f..a96742faa7 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js @@ -1,84 +1,97 @@ import React from 'react'; -import { Checkbox } from '@buffetjs/core'; -import { useIntl } from 'react-intl'; -import { get } from 'lodash'; +import { Box, Stack, H1, Text, Subtitle, Button, Checkbox, TextInput, Main } from '@strapi/parts'; import PropTypes from 'prop-types'; -import { BaselineAlignment } from '@strapi/helper-plugin'; +import styled from 'styled-components'; +import { useIntl } from 'react-intl'; +import { Formik } from 'formik'; -import Button from '../../../../components/FullWidthButton'; -import AuthLink from '../AuthLink'; -import Box from '../Box'; -import Input from '../Input'; -import Logo from '../Logo'; -import Section from '../Section'; +import { Column } from '../../../../layouts/UnauthenticatedLayout'; +import { useConfigurations } from '../../../../hooks'; -const Login = ({ children, formErrors, modifiedData, onChange, onSubmit, requestError }) => { +const AuthButton = styled(Button)` + display: inline-block; + width: 100%; +`; + +const Login = ({ onSubmit, schema }) => { + const { authLogo } = useConfigurations(); const { formatMessage } = useIntl(); return ( - <> -
- -
-
- - -
- + + {({ handleSubmit, values, errors, handleChange }) => ( + + + strapi-app-logo + +

{formatMessage({ id: 'Auth.form.welcome.title' })}

+
+ + + {formatMessage({ id: 'Auth.form.welcome.subtitle' })} + + + {errors.errorMessage && {errors.errorMessage}} +
+ + + - { + handleChange({ target: { value: checked, name: 'rememberMe' } }); + }} + value={values.rememberMe} name="rememberMe" - onChange={onChange} - value={modifiedData.rememberMe} - /> - - - - - {children} -
-
-
- - + > + {formatMessage({ id: 'Auth.form.rememberMe.label' })} + + + {formatMessage({ id: 'Auth.form.button.login' })} + + + + )} + + ); }; Login.defaultProps = { - children: null, - onSubmit: e => e.preventDefault(), - requestError: null, + onSubmit: () => {}, }; Login.propTypes = { - children: PropTypes.node, - formErrors: PropTypes.object.isRequired, - modifiedData: PropTypes.object.isRequired, - onChange: PropTypes.func.isRequired, onSubmit: PropTypes.func, - requestError: PropTypes.object, + schema: PropTypes.shape({ + type: PropTypes.string.isRequired, + }).isRequired, }; export default Login; diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Login/index.js b/packages/core/admin/admin/src/pages/AuthPage/components/Login/index.js index 7ca153d3de..2bfc7100c3 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Login/index.js +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Login/index.js @@ -1,10 +1,14 @@ import React from 'react'; import PropTypes from 'prop-types'; - import BaseLogin from './BaseLogin'; +import UnauthenticatedLayout from '../../../../layouts/UnauthenticatedLayout'; const Login = loginProps => { - return ; + return ( + + + + ); }; Login.defaultProps = { diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Logo/Img.js b/packages/core/admin/admin/src/pages/AuthPage/components/Logo/Img.js index a12578ffcc..036367f1b3 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Logo/Img.js +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Logo/Img.js @@ -1,7 +1,7 @@ import styled from 'styled-components'; const Img = styled.img` - height: 40px; + height: 36px; `; -export default Img; +export { Img }; diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Logo/index.js b/packages/core/admin/admin/src/pages/AuthPage/components/Logo/index.js index 359f707cdc..dcd198cde9 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Logo/index.js +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Logo/index.js @@ -1,11 +1,10 @@ import React from 'react'; import { useConfigurations } from '../../../../hooks'; -import Img from './Img'; const Logo = () => { const { authLogo } = useConfigurations(); - return strapi; + return strapi; }; export default Logo; diff --git a/packages/core/admin/admin/src/pages/AuthPage/index.js b/packages/core/admin/admin/src/pages/AuthPage/index.js index b249afcf4e..59500df575 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/index.js +++ b/packages/core/admin/admin/src/pages/AuthPage/index.js @@ -1,16 +1,11 @@ import React, { useEffect, useReducer } from 'react'; import axios from 'axios'; -import { camelCase, get, omit, upperFirst } from 'lodash'; +import { camelCase, get, omit } from 'lodash'; import { Redirect, useRouteMatch, useHistory } from 'react-router-dom'; -import { BaselineAlignment, auth, useNotification, useQuery } from '@strapi/helper-plugin'; -import { Padded } from '@buffetjs/core'; +import { auth, useNotification, useQuery } from '@strapi/helper-plugin'; import PropTypes from 'prop-types'; import forms from 'ee_else_ce/pages/AuthPage/utils/forms'; import useLocalesProvider from '../../components/LocalesProvider/useLocalesProvider'; -import NavTopRightWrapper from '../../components/NavTopRightWrapper'; -import PageTitle from '../../components/PageTitle'; -import LocaleToggle from '../../components/LocaleToggle'; -import checkFormValidity from '../../utils/checkFormValidity'; import formatAPIErrors from '../../utils/formatAPIErrors'; import init from './init'; import { initialState, reducer } from './reducer'; @@ -95,40 +90,24 @@ const AuthPage = ({ hasAdmin, setHasAdmin }) => { }); }; - const handleSubmit = async e => { - e.preventDefault(); + const handleSubmit = async (e, { setSubmitting, setErrors }) => { + const body = omit(e, fieldsToOmit); + const requestURL = `/admin/${endPoint}`; - dispatch({ - type: 'SET_ERRORS', - errors: {}, - }); + if (authType === 'login') { + await loginRequest(body, requestURL, { setSubmitting, setErrors }); + } - const errors = await checkFormValidity(modifiedData, schema); + if (authType === 'register' || authType === 'register-admin') { + await registerRequest(body, requestURL); + } - dispatch({ - type: 'SET_ERRORS', - errors: errors || {}, - }); + if (authType === 'forgot-password') { + await forgotPasswordRequest(body, requestURL); + } - if (!errors) { - const body = omit(modifiedData, fieldsToOmit); - const requestURL = `/admin/${endPoint}`; - - if (authType === 'login') { - await loginRequest(body, requestURL); - } - - if (authType === 'register' || authType === 'register-admin') { - await registerRequest(body, requestURL); - } - - if (authType === 'forgot-password') { - await forgotPasswordRequest(body, requestURL); - } - - if (authType === 'reset-password') { - await resetPasswordRequest(body, requestURL); - } + if (authType === 'reset-password') { + await resetPasswordRequest(body, requestURL); } }; @@ -152,7 +131,7 @@ const AuthPage = ({ hasAdmin, setHasAdmin }) => { } }; - const loginRequest = async (body, requestURL) => { + const loginRequest = async (body, requestURL, { setSubmitting, setErrors }) => { try { const { data: { @@ -175,8 +154,8 @@ const AuthPage = ({ hasAdmin, setHasAdmin }) => { push('/'); } catch (err) { if (err.response) { + setSubmitting(false); const errorMessage = get(err, ['response', 'data', 'message'], 'Something went wrong'); - const errorStatus = get(err, ['response', 'data', 'statusCode'], 400); if (camelCase(errorMessage).toLowerCase() === 'usernotactive') { push('/auth/oops'); @@ -188,11 +167,7 @@ const AuthPage = ({ hasAdmin, setHasAdmin }) => { return; } - dispatch({ - type: 'SET_REQUEST_ERROR', - errorMessage, - errorStatus, - }); + setErrors({ errorMessage }); } } }; @@ -288,24 +263,17 @@ const AuthPage = ({ hasAdmin, setHasAdmin }) => { } return ( - - - - - - - - - + ); }; diff --git a/packages/core/admin/admin/src/translations/en.json b/packages/core/admin/admin/src/translations/en.json index 23ba3901e7..05d76dbe62 100644 --- a/packages/core/admin/admin/src/translations/en.json +++ b/packages/core/admin/admin/src/translations/en.json @@ -3,7 +3,7 @@ "Auth.components.Oops.text": "Your account has been suspended", "Auth.form.button.forgot-password": "Send Email", "Auth.form.button.go-home": "GO BACK HOME", - "Auth.form.button.login": "Log in", + "Auth.form.button.login": "Login", "Auth.form.button.login.providers.error": "We cannot connect you through the selected provider.", "Auth.form.button.login.providers.see-more": "See more", "Auth.form.button.login.strapi": "LOG IN VIA STRAPI", @@ -38,10 +38,13 @@ "Auth.form.rememberMe.label": "Remember me", "Auth.form.username.label": "Username", "Auth.form.username.placeholder": "Kai Doe", + "Auth.form.welcome.subtitle": "Log in to your Strapi account", + "Auth.form.welcome.title": "Welcome back!", "Auth.link.forgot-password": "Forgot your password?", "Auth.link.ready": "Ready to sign in?", "Auth.link.signin": "Sign in", "Auth.link.signin.account": "Already have an account?", + "Auth.login.sso.divider": "Or login with", "Auth.privacy-policy-agreement.policy": "privacy policy", "Auth.privacy-policy-agreement.terms": "terms", "Content Manager": "Content Manager", diff --git a/packages/core/admin/ee/admin/pages/AuthPage/components/Login/index.js b/packages/core/admin/ee/admin/pages/AuthPage/components/Login/index.js index cc9ce8020e..fefca630df 100644 --- a/packages/core/admin/ee/admin/pages/AuthPage/components/Login/index.js +++ b/packages/core/admin/ee/admin/pages/AuthPage/components/Login/index.js @@ -1,73 +1,48 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { useTheme } from 'styled-components'; -import { Link } from 'react-router-dom'; +import styled from 'styled-components'; +import { Stack, Row, Divider, TableLabel, Box } from '@strapi/parts'; import { useIntl } from 'react-intl'; -import { Flex, Padded, Separator } from '@buffetjs/core'; -import { LoadingIndicator, Tooltip } from '@buffetjs/styles'; -import { Dots } from '@buffetjs/icons'; -import { BaselineAlignment } from '@strapi/helper-plugin'; import BaseLogin from '../../../../../../admin/src/pages/AuthPage/components/Login/BaseLogin'; -import ProviderButton from '../../../../components/ProviderButton'; -import { - ProviderButtonWrapper, - ProviderLink, -} from '../../../../components/ProviderButton/ProviderButtonStyles'; import { useAuthProviders } from '../../../../hooks'; +import UnauthenticatedLayout from '../../../../../../admin/src/layouts/UnauthenticatedLayout'; +import SSOProviders from '../Providers/SSOProviders'; + +const DividerFull = styled(Divider)` + flex: 1; +`; const Login = loginProps => { const ssoEnabled = strapi.features.isEnabled(strapi.features.SSO); - - const theme = useTheme(); const { isLoading, data: providers } = useAuthProviders({ ssoEnabled }); const { formatMessage } = useIntl(); if (!ssoEnabled || (!isLoading && providers.length === 0)) { - return ; + return ( + + + + ); } return ( - - - - - - {isLoading ? ( - - ) : ( - - {providers.slice(0, 2).map((provider, index) => ( - - - - ))} - {providers.length > 2 && ( - - - - - - - - - )} - - )} - - + + + + + + + + + {formatMessage({ id: 'Auth.login.sso.divider' })} + + + + + + + + ); }; diff --git a/packages/core/admin/ee/admin/pages/AuthPage/components/Providers/SSOProviders.js b/packages/core/admin/ee/admin/pages/AuthPage/components/Providers/SSOProviders.js new file mode 100644 index 0000000000..6730817f51 --- /dev/null +++ b/packages/core/admin/ee/admin/pages/AuthPage/components/Providers/SSOProviders.js @@ -0,0 +1,98 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Text, Row, Grid, GridItem } from '@strapi/parts'; +import styled from 'styled-components'; +import { Link } from 'react-router-dom'; + +const SSOButton = styled.a` + width: ${136 / 16}rem; + display: flex; + justify-content: center; + align-items: center; + height: ${48 / 16}rem; + border: 1px solid ${({ theme }) => theme.colors.neutral150}; + border-radius: ${({ theme }) => theme.borderRadius}; + text-decoration: none; +`; + +const SSOProvidersWrapper = styled(Row)` + & a:not(:first-child):not(:last-child) { + margin: 0 ${({ theme }) => theme.spaces[2]}; + } + & a:first-child { + margin-right: ${({ theme }) => theme.spaces[2]}; + } + & a:last-child { + margin-left: ${({ theme }) => theme.spaces[2]}; + } +`; + +const SSOProviderButton = ({ provider }) => { + return ( + + {provider.icon ? ( + {provider.displayName} + ) : ( + {provider.displayName} + )} + + ); +}; + +SSOProviderButton.propTypes = { + provider: PropTypes.shape({ + icon: PropTypes.string, + displayName: PropTypes.string.isRequired, + uid: PropTypes.string.isRequired, + }).isRequired, +}; + +const SSOProviders = ({ providers, displayAllProviders }) => { + if (displayAllProviders) { + return ( + + {providers.map(provider => ( + + + + ))} + + ); + } + + if (providers.length > 2 && !displayAllProviders) { + return ( + + {providers.slice(0, 2).map(provider => ( + + + + ))} + + + ••• + + + + ); + } + + return ( + + {providers.map(provider => ( + + ))} + + ); +}; + +SSOProviders.defaultProps = { + displayAllProviders: true, +}; + +SSOProviders.propTypes = { + providers: PropTypes.arrayOf(PropTypes.object).isRequired, + displayAllProviders: PropTypes.bool, +}; + +export default SSOProviders; diff --git a/packages/core/admin/index.html b/packages/core/admin/index.html index ff86160ebd..b6d254f0e7 100644 --- a/packages/core/admin/index.html +++ b/packages/core/admin/index.html @@ -1,16 +1,16 @@ - + - - - - - - - Strapi Admin - - - -
- - + + + + + + + Strapi Admin + + + +
+ + From 18d1825f760b7833eda4692865ea817b098ae727 Mon Sep 17 00:00:00 2001 From: HichamELBSI Date: Fri, 6 Aug 2021 12:29:49 +0200 Subject: [PATCH 2/7] Add formik focus component Signed-off-by: HichamELBSI --- .../AuthPage/components/Login/BaseLogin.js | 10 +++-- .../components/Login/FormikFocusError.js | 40 +++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 packages/core/admin/admin/src/pages/AuthPage/components/Login/FormikFocusError.js diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js b/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js index a96742faa7..f90b2152a1 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js @@ -3,10 +3,11 @@ import { Box, Stack, H1, Text, Subtitle, Button, Checkbox, TextInput, Main } fro import PropTypes from 'prop-types'; import styled from 'styled-components'; import { useIntl } from 'react-intl'; -import { Formik } from 'formik'; +import { Formik, Form } from 'formik'; import { Column } from '../../../../layouts/UnauthenticatedLayout'; import { useConfigurations } from '../../../../hooks'; +import FormikFocusError from './FormikFocusError'; const AuthButton = styled(Button)` display: inline-block; @@ -29,8 +30,9 @@ const Login = ({ onSubmit, schema }) => { validationSchema={schema} validateOnChange={false} > - {({ handleSubmit, values, errors, handleChange }) => ( -
+ {({ values, errors, handleChange }) => ( + + strapi-app-logo @@ -76,7 +78,7 @@ const Login = ({ onSubmit, schema }) => { {formatMessage({ id: 'Auth.form.button.login' })} - + )} diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Login/FormikFocusError.js b/packages/core/admin/admin/src/pages/AuthPage/components/Login/FormikFocusError.js new file mode 100644 index 0000000000..83f30ee847 --- /dev/null +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Login/FormikFocusError.js @@ -0,0 +1,40 @@ +import { useEffect } from 'react'; +import { useFormikContext, getIn } from 'formik'; + +const FormikFocusError = () => { + const { isSubmitting, isValidating, errors, touched } = useFormikContext(); + + useEffect(() => { + if (isSubmitting && !isValidating) { + const errorNames = Object.keys(touched).reduce((prev, key) => { + if (getIn(errors, key)) { + prev.push(key); + } + + return prev; + }, []); + + if (errorNames.length && typeof document !== 'undefined') { + let errorEl; + + errorNames.forEach(errorKey => { + const selector = `[name="${errorKey}"]`; + + if (!errorEl) { + errorEl = document.querySelector(selector); + } + }); + + setTimeout(() => { + if (errorEl) { + errorEl.focus(); + } + }, 100); + } + } + }, [errors, isSubmitting, isValidating, touched]); + + return null; +}; + +export default FormikFocusError; From 34eb7985787440b714753c9315d4a91a0f6786de Mon Sep 17 00:00:00 2001 From: HichamELBSI Date: Fri, 6 Aug 2021 13:27:06 +0200 Subject: [PATCH 3/7] Remove document useless check Signed-off-by: HichamELBSI --- .../pages/AuthPage/components/Login/FormikFocusError.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Login/FormikFocusError.js b/packages/core/admin/admin/src/pages/AuthPage/components/Login/FormikFocusError.js index 83f30ee847..7a4eea21ac 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Login/FormikFocusError.js +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Login/FormikFocusError.js @@ -14,7 +14,7 @@ const FormikFocusError = () => { return prev; }, []); - if (errorNames.length && typeof document !== 'undefined') { + if (errorNames.length) { let errorEl; errorNames.forEach(errorKey => { @@ -25,11 +25,7 @@ const FormikFocusError = () => { } }); - setTimeout(() => { - if (errorEl) { - errorEl.focus(); - } - }, 100); + errorEl.focus(); } } }, [errors, isSubmitting, isValidating, touched]); From 073bea95c84d258b7071a0263220cb817bd85a1b Mon Sep 17 00:00:00 2001 From: HichamELBSI Date: Fri, 6 Aug 2021 14:43:58 +0200 Subject: [PATCH 4/7] Fix PR feedback Signed-off-by: HichamELBSI --- .../admin/admin/src/components/Theme/index.js | 4 +- .../core/admin/admin/src/pages/App/index.js | 4 +- .../AuthPage/components/Login/BaseLogin.js | 7 ++-- .../Login/{FormikFocusError.js => Form.js} | 10 ++--- .../components/Providers/SSOProviders.js | 39 +++++++++++++------ 5 files changed, 40 insertions(+), 24 deletions(-) rename packages/core/admin/admin/src/pages/AuthPage/components/Login/{FormikFocusError.js => Form.js} (76%) diff --git a/packages/core/admin/admin/src/components/Theme/index.js b/packages/core/admin/admin/src/components/Theme/index.js index 92e479b9ec..313ccf3762 100644 --- a/packages/core/admin/admin/src/components/Theme/index.js +++ b/packages/core/admin/admin/src/components/Theme/index.js @@ -1,12 +1,12 @@ import React from 'react'; import { ThemeProvider } from 'styled-components'; import PropTypes from 'prop-types'; -// import GlobalStyle from '../GlobalStyle'; +import GlobalStyle from '../GlobalStyle'; import Fonts from '../Fonts'; const Theme = ({ children, theme }) => ( - {/* */} + {children} diff --git a/packages/core/admin/admin/src/pages/App/index.js b/packages/core/admin/admin/src/pages/App/index.js index 40e4c2e2c2..1ffa600906 100644 --- a/packages/core/admin/admin/src/pages/App/index.js +++ b/packages/core/admin/admin/src/pages/App/index.js @@ -14,6 +14,7 @@ import { TrackingContext, } from '@strapi/helper-plugin'; import { SkipToContent } from '@strapi/parts'; +import { useIntl } from 'react-intl'; import PrivateRoute from '../../components/PrivateRoute'; import { createRoute, makeUniqueRoutes } from '../../utils'; import AuthPage from '../AuthPage'; @@ -27,6 +28,7 @@ const AuthenticatedApp = lazy(() => function App() { const toggleNotification = useNotification(); + const { formatMessage } = useIntl(); const [{ isLoading, hasAdmin, uuid }, setState] = useState({ isLoading: true, hasAdmin: false }); const authRoutes = useMemo(() => { @@ -106,7 +108,7 @@ function App() { return ( }> - Skip to content + {formatMessage({ id: 'skipToContent' })} {authRoutes} diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js b/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js index f90b2152a1..a6b4d59641 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js @@ -3,11 +3,11 @@ import { Box, Stack, H1, Text, Subtitle, Button, Checkbox, TextInput, Main } fro import PropTypes from 'prop-types'; import styled from 'styled-components'; import { useIntl } from 'react-intl'; -import { Formik, Form } from 'formik'; +import { Formik } from 'formik'; import { Column } from '../../../../layouts/UnauthenticatedLayout'; import { useConfigurations } from '../../../../hooks'; -import FormikFocusError from './FormikFocusError'; +import Form from './Form'; const AuthButton = styled(Button)` display: inline-block; @@ -32,9 +32,8 @@ const Login = ({ onSubmit, schema }) => { > {({ values, errors, handleChange }) => (
- - strapi-app-logo +

{formatMessage({ id: 'Auth.form.welcome.title' })}

diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Login/FormikFocusError.js b/packages/core/admin/admin/src/pages/AuthPage/components/Login/Form.js similarity index 76% rename from packages/core/admin/admin/src/pages/AuthPage/components/Login/FormikFocusError.js rename to packages/core/admin/admin/src/pages/AuthPage/components/Login/Form.js index 7a4eea21ac..97fa4fc2ac 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Login/FormikFocusError.js +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Login/Form.js @@ -1,7 +1,7 @@ -import { useEffect } from 'react'; -import { useFormikContext, getIn } from 'formik'; +import React, { useEffect } from 'react'; +import { Form, useFormikContext, getIn } from 'formik'; -const FormikFocusError = () => { +const FormWithFocus = props => { const { isSubmitting, isValidating, errors, touched } = useFormikContext(); useEffect(() => { @@ -30,7 +30,7 @@ const FormikFocusError = () => { } }, [errors, isSubmitting, isValidating, touched]); - return null; + return ; }; -export default FormikFocusError; +export default FormWithFocus; diff --git a/packages/core/admin/ee/admin/pages/AuthPage/components/Providers/SSOProviders.js b/packages/core/admin/ee/admin/pages/AuthPage/components/Providers/SSOProviders.js index 6730817f51..4c9620694e 100644 --- a/packages/core/admin/ee/admin/pages/AuthPage/components/Providers/SSOProviders.js +++ b/packages/core/admin/ee/admin/pages/AuthPage/components/Providers/SSOProviders.js @@ -1,7 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Text, Row, Grid, GridItem } from '@strapi/parts'; +import { Text, Row, Grid, GridItem, Tooltip } from '@strapi/parts'; import styled from 'styled-components'; +import { useIntl } from 'react-intl'; import { Link } from 'react-router-dom'; const SSOButton = styled.a` @@ -12,7 +13,11 @@ const SSOButton = styled.a` height: ${48 / 16}rem; border: 1px solid ${({ theme }) => theme.colors.neutral150}; border-radius: ${({ theme }) => theme.borderRadius}; - text-decoration: none; + text-decoration: inherit; + &:link { + text-decoration: none; + } + color: ${({ theme }) => theme.colors.neutral600}; `; const SSOProvidersWrapper = styled(Row)` @@ -29,13 +34,15 @@ const SSOProvidersWrapper = styled(Row)` const SSOProviderButton = ({ provider }) => { return ( - - {provider.icon ? ( - {provider.displayName} - ) : ( - {provider.displayName} - )} - + + + {provider.icon ? ( + + ) : ( + {provider.displayName} + )} + + ); }; @@ -48,6 +55,8 @@ SSOProviderButton.propTypes = { }; const SSOProviders = ({ providers, displayAllProviders }) => { + const { formatMessage } = useIntl(); + if (displayAllProviders) { return ( @@ -69,9 +78,15 @@ const SSOProviders = ({ providers, displayAllProviders }) => { ))} - - ••• - + + + ••• + + ); From c79afa3f443fb7c72467568e608a2dde0c8fb2ed Mon Sep 17 00:00:00 2001 From: HichamELBSI Date: Fri, 6 Aug 2021 17:59:43 +0200 Subject: [PATCH 5/7] Fix design feedback Signed-off-by: HichamELBSI --- .../AuthPage/components/Login/BaseLogin.js | 44 +++++++++++++++++-- .../core/admin/admin/src/translations/en.json | 4 +- .../lib/src/testUtils/commonTrads.json | 2 +- test/config/front/testUtils/commonTrads.json | 2 +- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js b/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js index a6b4d59641..f186dffce5 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js @@ -1,5 +1,17 @@ -import React from 'react'; -import { Box, Stack, H1, Text, Subtitle, Button, Checkbox, TextInput, Main } from '@strapi/parts'; +import React, { useState } from 'react'; +import { Show, Hide } from '@strapi/icons'; +import { + Box, + Stack, + H1, + Text, + Subtitle, + Button, + Checkbox, + TextInput, + Main, + FieldAction, +} from '@strapi/parts'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import { useIntl } from 'react-intl'; @@ -13,8 +25,18 @@ const AuthButton = styled(Button)` display: inline-block; width: 100%; `; +const FieldActionWrapper = styled(FieldAction)` + svg { + height: 16px; + width: 16px; + path { + fill: ${({ theme }) => theme.colors.neutral600}; + } + } +`; const Login = ({ onSubmit, schema }) => { + const [passwordShown, setPasswordShown] = useState(false); const { authLogo } = useConfigurations(); const { formatMessage } = useIntl(); @@ -61,7 +83,23 @@ const Login = ({ onSubmit, schema }) => { value={values.password} label={formatMessage({ id: 'Auth.form.password.label' })} name="password" - type="password" + type={passwordShown ? 'text' : 'password'} + endAction={ + // eslint-disable-next-line react/jsx-wrap-multilines + { + e.preventDefault(); + setPasswordShown(prev => !prev); + }} + label={formatMessage({ + id: passwordShown + ? 'Auth.form.password.show-password' + : 'Auth.form.password.hide-password', + })} + > + {passwordShown ? : } + + } required /> Date: Tue, 10 Aug 2021 16:59:50 +0200 Subject: [PATCH 6/7] Fix form UI + add tmp logout button Signed-off-by: HichamELBSI --- .../admin/admin/src/components/LeftMenu/index.js | 13 +++++++++++++ .../pages/AuthPage/components/Login/BaseLogin.js | 5 +---- packages/core/admin/package.json | 4 ++-- yarn.lock | 16 ++++++++-------- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/packages/core/admin/admin/src/components/LeftMenu/index.js b/packages/core/admin/admin/src/components/LeftMenu/index.js index c4a2170a6e..f96797d1ea 100644 --- a/packages/core/admin/admin/src/components/LeftMenu/index.js +++ b/packages/core/admin/admin/src/components/LeftMenu/index.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import get from 'lodash/get'; +import { useHistory } from 'react-router-dom'; import { MainNav, NavBrand, @@ -12,6 +13,7 @@ import { NavUser, NavCondense, Divider, + Button, } from '@strapi/parts'; import ContentIcon from '@strapi/icons/ContentIcon'; import { auth, usePersistentState } from '@strapi/helper-plugin'; @@ -19,6 +21,7 @@ import useConfigurations from '../../hooks/useConfigurations'; const LeftMenu = ({ generalSectionLinks, pluginsSectionLinks }) => { const { menuLogo } = useConfigurations(); + const { push } = useHistory(); const [condensed, setCondensed] = usePersistentState('navbar-condensed', false); const userInfo = auth.getUserInfo(); @@ -63,6 +66,16 @@ const LeftMenu = ({ generalSectionLinks, pluginsSectionLinks }) => { ))} + {/* This is temporary */} + ) : null} diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js b/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js index f186dffce5..1c569edd27 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js @@ -87,10 +87,7 @@ const Login = ({ onSubmit, schema }) => { endAction={ // eslint-disable-next-line react/jsx-wrap-multilines { - e.preventDefault(); - setPasswordShown(prev => !prev); - }} + onClick={() => setPasswordShown(prev => !prev)} label={formatMessage({ id: passwordShown ? 'Auth.form.password.show-password' diff --git a/packages/core/admin/package.json b/packages/core/admin/package.json index 03cdc38911..c560c8c6a9 100644 --- a/packages/core/admin/package.json +++ b/packages/core/admin/package.json @@ -41,8 +41,8 @@ "@strapi/babel-plugin-switch-ee-ce": "1.0.0", "@strapi/helper-plugin": "3.6.6", "@strapi/utils": "3.6.6", - "@strapi/icons": "0.0.1-alpha.5", - "@strapi/parts": "0.0.1-alpha.5", + "@strapi/icons": "0.0.1-alpha.6", + "@strapi/parts": "0.0.1-alpha.6", "axios": "^0.21.1", "babel-loader": "8.2.2", "babel-plugin-styled-components": "1.12.0", diff --git a/yarn.lock b/yarn.lock index d85e671d6d..b158bdf6dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3490,15 +3490,15 @@ tslib "^2.0.0" upath "2.0.1" -"@strapi/icons@0.0.1-alpha.5": - version "0.0.1-alpha.5" - resolved "https://registry.yarnpkg.com/@strapi/icons/-/icons-0.0.1-alpha.5.tgz#04f2d62a516e8da6b14f0b1bacc040b10c5f44db" - integrity sha512-PCTQXIkBxfV/qWQZPrbABEdkLSYO7w4+RWVHA7eNlSkcKPP/b5Q/ZEW+56GZ/o9DLexivsGdZaC/aVUzK7G7IA== +"@strapi/icons@0.0.1-alpha.6": + version "0.0.1-alpha.6" + resolved "https://registry.yarnpkg.com/@strapi/icons/-/icons-0.0.1-alpha.6.tgz#d714c4f0f44d5a53b813989f0c890af62278ce1b" + integrity sha512-QB5ghVyTh+vWlFAbDMmZGS//0+mZLWnB0ejxZfHjvT/d3ByVDycxsugLpk+jwALmD7pPdcqK66+3vR9o97Pl1g== -"@strapi/parts@0.0.1-alpha.5": - version "0.0.1-alpha.5" - resolved "https://registry.yarnpkg.com/@strapi/parts/-/parts-0.0.1-alpha.5.tgz#6abddbcf4ee58da506065aa49f736b0b51e9cbfa" - integrity sha512-Vb55oaD0G9N9OzsVM4SB3WG30w4Mo3oDITq9lCvwQT9uR0xKuN+GwYK1XdlBTItLcjnJOpRJ3vSoI7sgI1L8rQ== +"@strapi/parts@0.0.1-alpha.6": + version "0.0.1-alpha.6" + resolved "https://registry.yarnpkg.com/@strapi/parts/-/parts-0.0.1-alpha.6.tgz#7259e26edb7b4195352713a73f23d54dfefc79c8" + integrity sha512-4RhcguoPf41tJ6TbrHrUffOMEmWIJGgT9dxgqy5aFLZFHXnO1x1463Sw5hVSqdT+D05SiJLcBCO3zY+NhpEsDQ== dependencies: compute-scroll-into-view "^1.0.17" prop-types "^15.7.2" From 2adfa6db2600c200348aa829876a7893940dd7bf Mon Sep 17 00:00:00 2001 From: HichamELBSI Date: Thu, 12 Aug 2021 13:43:56 +0200 Subject: [PATCH 7/7] Fix PR feedback Signed-off-by: HichamELBSI --- .../admin/src/layouts/UnauthenticatedLayout.js | 2 +- .../pages/AuthPage/components/Login/BaseLogin.js | 16 +++++++++++----- .../src/pages/AuthPage/components/Login/Form.js | 7 +++++++ .../src/pages/AuthPage/components/Logo/Img.js | 7 ------- .../src/pages/AuthPage/components/Logo/index.js | 7 ++++++- .../core/admin/admin/src/pages/AuthPage/index.js | 1 + 6 files changed, 26 insertions(+), 14 deletions(-) delete mode 100644 packages/core/admin/admin/src/pages/AuthPage/components/Logo/Img.js diff --git a/packages/core/admin/admin/src/layouts/UnauthenticatedLayout.js b/packages/core/admin/admin/src/layouts/UnauthenticatedLayout.js index d4f53b4c0a..6d99c91460 100644 --- a/packages/core/admin/admin/src/layouts/UnauthenticatedLayout.js +++ b/packages/core/admin/admin/src/layouts/UnauthenticatedLayout.js @@ -16,7 +16,7 @@ export const Column = styled(Row)` const UnauthenticatedLayout = ({ children }) => { return (
- + diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js b/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js index 1c569edd27..6e65046efb 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Login/BaseLogin.js @@ -18,8 +18,8 @@ import { useIntl } from 'react-intl'; import { Formik } from 'formik'; import { Column } from '../../../../layouts/UnauthenticatedLayout'; -import { useConfigurations } from '../../../../hooks'; import Form from './Form'; +import Logo from '../Logo'; const AuthButton = styled(Button)` display: inline-block; @@ -37,7 +37,6 @@ const FieldActionWrapper = styled(FieldAction)` const Login = ({ onSubmit, schema }) => { const [passwordShown, setPasswordShown] = useState(false); - const { authLogo } = useConfigurations(); const { formatMessage } = useIntl(); return ( @@ -55,7 +54,7 @@ const Login = ({ onSubmit, schema }) => { {({ values, errors, handleChange }) => ( - +

{formatMessage({ id: 'Auth.form.welcome.title' })}

@@ -64,7 +63,11 @@ const Login = ({ onSubmit, schema }) => { {formatMessage({ id: 'Auth.form.welcome.subtitle' })} - {errors.errorMessage && {errors.errorMessage}} + {errors.errorMessage && ( + + {errors.errorMessage} + + )}
@@ -87,7 +90,10 @@ const Login = ({ onSubmit, schema }) => { endAction={ // eslint-disable-next-line react/jsx-wrap-multilines setPasswordShown(prev => !prev)} + onClick={e => { + e.stopPropagation(); + setPasswordShown(prev => !prev); + }} label={formatMessage({ id: passwordShown ? 'Auth.form.password.show-password' diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Login/Form.js b/packages/core/admin/admin/src/pages/AuthPage/components/Login/Form.js index 97fa4fc2ac..ee273000cb 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Login/Form.js +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Login/Form.js @@ -28,6 +28,13 @@ const FormWithFocus = props => { errorEl.focus(); } } + if (!isSubmitting && !isValidating && Object.keys(errors).length) { + const el = document.getElementById('global-form-error'); + + if (el) { + el.focus(); + } + } }, [errors, isSubmitting, isValidating, touched]); return ; diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Logo/Img.js b/packages/core/admin/admin/src/pages/AuthPage/components/Logo/Img.js deleted file mode 100644 index 036367f1b3..0000000000 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Logo/Img.js +++ /dev/null @@ -1,7 +0,0 @@ -import styled from 'styled-components'; - -const Img = styled.img` - height: 36px; -`; - -export { Img }; diff --git a/packages/core/admin/admin/src/pages/AuthPage/components/Logo/index.js b/packages/core/admin/admin/src/pages/AuthPage/components/Logo/index.js index dcd198cde9..ca2f2edb37 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/components/Logo/index.js +++ b/packages/core/admin/admin/src/pages/AuthPage/components/Logo/index.js @@ -1,10 +1,15 @@ import React from 'react'; +import styled from 'styled-components'; import { useConfigurations } from '../../../../hooks'; +const Img = styled.img` + height: 72px; +`; + const Logo = () => { const { authLogo } = useConfigurations(); - return strapi; + return ; }; export default Logo; diff --git a/packages/core/admin/admin/src/pages/AuthPage/index.js b/packages/core/admin/admin/src/pages/AuthPage/index.js index 59500df575..d368e1d48f 100644 --- a/packages/core/admin/admin/src/pages/AuthPage/index.js +++ b/packages/core/admin/admin/src/pages/AuthPage/index.js @@ -91,6 +91,7 @@ const AuthPage = ({ hasAdmin, setHasAdmin }) => { }; const handleSubmit = async (e, { setSubmitting, setErrors }) => { + setSubmitting(true); const body = omit(e, fieldsToOmit); const requestURL = `/admin/${endPoint}`;