From 305bbaad2ce231ddfc39c9ff23d7af23f1990099 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Fri, 28 Oct 2022 16:03:30 +0800 Subject: [PATCH] feat(console): add social connectors on the sie page (#2251) --- .../tabs/SignUpAndSignInTab/SignInForm.tsx | 2 +- .../SignUpAndSignInTab/SocialSignInForm.tsx | 36 +++++++ .../AddButton.module.scss | 37 ++++++++ .../SocialConnectorEditBox/AddButton.tsx | 75 +++++++++++++++ .../SelectedConnectorItem.module.scss | 49 ++++++++++ .../SelectedConnectorItem.tsx | 44 +++++++++ .../SocialConnectorEditBox/index.module.scss | 12 +++ .../SocialConnectorEditBox/index.tsx | 94 +++++++++++++++++++ .../tabs/SignUpAndSignInTab/index.module.scss | 11 ++- .../tabs/SignUpAndSignInTab/index.tsx | 2 + .../translation/admin-console/sign-in-exp.ts | 12 +++ .../translation/admin-console/sign-in-exp.ts | 12 +++ .../translation/admin-console/sign-in-exp.ts | 12 +++ .../translation/admin-console/sign-in-exp.ts | 12 +++ .../translation/admin-console/sign-in-exp.ts | 12 +++ .../translation/admin-console/sign-in-exp.ts | 12 +++ 16 files changed, 428 insertions(+), 6 deletions(-) create mode 100644 packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/SocialSignInForm.tsx create mode 100644 packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.module.scss create mode 100644 packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.tsx create mode 100644 packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/SelectedConnectorItem.module.scss create mode 100644 packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/SelectedConnectorItem.tsx create mode 100644 packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/index.module.scss create mode 100644 packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/index.tsx diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/SignInForm.tsx b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/SignInForm.tsx index 5fb53a8e9..facd3f7dd 100644 --- a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/SignInForm.tsx +++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/SignInForm.tsx @@ -20,7 +20,7 @@ const SignInForm = () => { <>
{t('sign_in_exp.sign_up_and_sign_in.sign_in.title')}
-
+
{t('sign_in_exp.sign_up_and_sign_in.sign_in.description')}
{ + const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + const { control } = useFormContext(); + + return ( + <> +
+ {t('sign_in_exp.sign_up_and_sign_in.social_sign_in.title')} +
+ + +
+ {t('sign_in_exp.sign_up_and_sign_in.social_sign_in.description')} +
+ { + return ; + }} + /> +
+ + ); +}; + +export default SocialSignInForm; diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.module.scss b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.module.scss new file mode 100644 index 000000000..89722b9ab --- /dev/null +++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.module.scss @@ -0,0 +1,37 @@ +@use '@/scss/underscore' as _; + +.dropdown { + min-width: 208px; +} + +.plusIcon { + color: var(--color-text-secondary); +} + +.title { + display: flex; + align-items: center; + + .logo { + margin-right: _.unit(3); + width: 20px; + height: 20px; + + img { + width: 20px; + height: 20px; + } + } + + .name { + font: var(--font-body-medium); + } + + .icon { + width: 16px; + height: 16px; + object-fit: cover; + margin-left: _.unit(1); + color: var(--color-text-secondary); + } +} diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.tsx b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.tsx new file mode 100644 index 000000000..93003825d --- /dev/null +++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/AddButton.tsx @@ -0,0 +1,75 @@ +import Plus from '@/assets/images/plus.svg'; +import ActionMenu from '@/components/ActionMenu'; +import type { Props as ButtonProps } from '@/components/Button'; +import { DropdownItem } from '@/components/Dropdown'; +import UnnamedTrans from '@/components/UnnamedTrans'; +import ConnectorPlatformIcon from '@/icons/ConnectorPlatformIcon'; +import type { ConnectorGroup } from '@/types/connector'; + +import * as styles from './AddButton.module.scss'; + +type Props = { + options: ConnectorGroup[]; + onSelected: (signInIdentifier: string) => void; + hasSelectedConnectors: boolean; +}; + +const AddButton = ({ options, onSelected, hasSelectedConnectors }: Props) => { + if (options.length === 0) { + return null; + } + + const candidates = options.map(({ target, logo, name, connectors }) => ({ + value: target, + title: ( +
+
+ {target} +
+ + {connectors.length > 1 && + connectors + .filter(({ enabled }) => enabled) + .map(({ platform }) => ( +
+ {platform && } +
+ ))} +
+ ), + })); + + const addSocialConnectorButtonProps: ButtonProps = { + type: 'default', + size: 'medium', + title: 'sign_in_exp.sign_up_and_sign_in.social_sign_in.add_social_connector', + icon: , + }; + + const addAnotherButtonProps: ButtonProps = { + type: 'text', + size: 'small', + title: 'general.add_another', + }; + + return ( + + {candidates.map(({ value, title }) => ( + { + onSelected(value); + }} + > + {title} + + ))} + + ); +}; + +export default AddButton; diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/SelectedConnectorItem.module.scss b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/SelectedConnectorItem.module.scss new file mode 100644 index 000000000..0f036ef0e --- /dev/null +++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/SelectedConnectorItem.module.scss @@ -0,0 +1,49 @@ +@use '@/scss/underscore' as _; + +.item { + display: flex; + align-items: center; + margin: _.unit(2) 0; + + + .info { + display: flex; + align-items: center; + height: 44px; + width: 100%; + margin-right: _.unit(2); + padding: _.unit(3) _.unit(2); + background-color: var(--color-layer-2); + border-radius: 8px; + cursor: move; + color: var(--color-text); + + .draggableIcon { + color: var(--color-text-secondary); + } + + .logo { + margin: auto _.unit(3); + width: 20px; + height: 20px; + + img { + width: 20px; + height: 20px; + } + } + + .name { + font: var(--font-label-large); + } + + .icon { + width: 16px; + height: 16px; + object-fit: cover; + margin-left: _.unit(1); + color: var(--color-text-secondary); + } + } +} + diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/SelectedConnectorItem.tsx b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/SelectedConnectorItem.tsx new file mode 100644 index 000000000..acd40d1ed --- /dev/null +++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/SelectedConnectorItem.tsx @@ -0,0 +1,44 @@ +import Draggable from '@/assets/images/draggable.svg'; +import Minus from '@/assets/images/minus.svg'; +import IconButton from '@/components/IconButton'; +import UnnamedTrans from '@/components/UnnamedTrans'; +import ConnectorPlatformIcon from '@/icons/ConnectorPlatformIcon'; +import type { ConnectorGroup } from '@/types/connector'; + +import * as styles from './SelectedConnectorItem.module.scss'; + +type Props = { + data: ConnectorGroup; + onDelete: (connectorTarget: string) => void; +}; + +const SelectedConnectorItem = ({ data: { logo, target, name, connectors }, onDelete }: Props) => { + return ( +
+
+ +
+ {target} +
+ + {connectors.length > 1 && + connectors + .filter(({ enabled }) => enabled) + .map(({ platform }) => ( +
+ {platform && } +
+ ))} +
+ { + onDelete(target); + }} + > + + +
+ ); +}; + +export default SelectedConnectorItem; diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/index.module.scss b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/index.module.scss new file mode 100644 index 000000000..611b534ea --- /dev/null +++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/index.module.scss @@ -0,0 +1,12 @@ +@use '@/scss/underscore' as _; + +.setUpHint { + font: var(--font-body-medium); + color: var(--color-text-secondary); + margin-top: _.unit(2); + + a { + color: var(--color-text-link); + text-decoration: none; + } +} diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/index.tsx b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/index.tsx new file mode 100644 index 000000000..7f7b39728 --- /dev/null +++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/components/SocialConnectorEditBox/index.tsx @@ -0,0 +1,94 @@ +import { ConnectorType } from '@logto/schemas'; +import { useTranslation } from 'react-i18next'; +import { Link } from 'react-router-dom'; + +import DragDropProvider from '@/components/Transfer/DragDropProvider'; +import DraggableItem from '@/components/Transfer/DraggableItem'; +import useConnectorGroups from '@/hooks/use-connector-groups'; +import type { ConnectorGroup } from '@/types/connector'; + +import ConnectorSetupWarning from '../ConnectorSetupWarning'; +import AddButton from './AddButton'; +import SelectedConnectorItem from './SelectedConnectorItem'; +import * as styles from './index.module.scss'; + +type Props = { + value: string[]; + onChange: (value: string[]) => void; +}; + +const SocialConnectorEditBox = ({ value, onChange }: Props) => { + const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + const { data: connectorData, error } = useConnectorGroups(); + + if (!connectorData || error) { + return null; + } + + const onMoveItem = (dragIndex: number, hoverIndex: number) => { + const dragItem = value[dragIndex]; + const hoverItem = value[hoverIndex]; + + if (!dragItem || !hoverItem) { + return; + } + + onChange( + value.map((value_, index) => { + if (index === dragIndex) { + return hoverItem; + } + + if (index === hoverIndex) { + return dragItem; + } + + return value_; + }) + ); + }; + + const selectedConnectorItems = value + .map((connectorTarget) => connectorData.find(({ target }) => target === connectorTarget)) + // eslint-disable-next-line unicorn/prefer-native-coercion-functions + .filter((item): item is ConnectorGroup => Boolean(item)); + + const connectorOptions = connectorData.filter( + ({ target, type, enabled }) => + !value.includes(target) && type === ConnectorType.Social && enabled + ); + + return ( +
+ + {selectedConnectorItems.map((item, index) => ( + + { + onChange(value.filter((connectorTarget) => connectorTarget !== target)); + }} + /> + + ))} + + 0} + onSelected={(target) => { + onChange([...value, target]); + }} + /> + +
+ {t('sign_in_exp.sign_up_and_sign_in.social_sign_in.set_up_hint.not_in_list')}{' '} + + {t('sign_in_exp.sign_up_and_sign_in.social_sign_in.set_up_hint.set_up_more')} + {' '} + {t('sign_in_exp.sign_up_and_sign_in.social_sign_in.set_up_hint.go_to')} +
+
+ ); +}; + +export default SocialConnectorEditBox; diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/index.module.scss b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/index.module.scss index 946a13d28..31c0f9c5b 100644 --- a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/index.module.scss +++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/index.module.scss @@ -10,6 +10,12 @@ } } +.formFieldDescription { + font: var(--font-body-medium); + color: var(--color-text-secondary); + margin-bottom: _.unit(2); +} + .socialOnlyDescription { margin-left: _.unit(1); color: var(--color-text-secondary); @@ -20,8 +26,3 @@ margin-top: _.unit(3); } } - -.signInDescription { - font: var(--font-body-medium); - color: var(--color-text-secondary); -} diff --git a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/index.tsx b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/index.tsx index e78fc8a00..37ca2b77f 100644 --- a/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/index.tsx +++ b/packages/console/src/pages/SignInExperience/tabs/SignUpAndSignInTab/index.tsx @@ -6,6 +6,7 @@ import UnsavedChangesAlertModal from '@/components/UnsavedChangesAlertModal'; import type { SignInExperienceForm } from '../../types'; import SignInForm from './SignInForm'; import SignUpForm from './SignUpForm'; +import SocialSignInForm from './SocialSignInForm'; type Props = { defaultData: SignInExperienceForm; @@ -25,6 +26,7 @@ const SignUpAndSignInTab = ({ defaultData, isDataDirty }: Props) => { <> + ); diff --git a/packages/phrases/src/locales/en/translation/admin-console/sign-in-exp.ts b/packages/phrases/src/locales/en/translation/admin-console/sign-in-exp.ts index 5d0e323a5..3b435a6df 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/sign-in-exp.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/sign-in-exp.ts @@ -62,6 +62,18 @@ const sign_in_exp = { verification_code_auth: 'Verification code', auth_swap_tip: 'Swap to change the priority', }, + social_sign_in: { + title: 'SOCIAL SIGN IN', + social_sign_in: 'Social sign in', + description: + 'Users may need to enter required identifier when register through social accounts. This was defined by your sign up identifier.', + add_social_connector: 'Add Social Connector', + set_up_hint: { + not_in_list: 'Not in the list?', + set_up_more: 'Set up more', + go_to: 'social connectors or go to “Connectors” section.', + }, + }, }, sign_in_methods: { title: 'SIGN-IN METHODS', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/sign-in-exp.ts b/packages/phrases/src/locales/fr/translation/admin-console/sign-in-exp.ts index 5c76f1741..cce17e7b5 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/sign-in-exp.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/sign-in-exp.ts @@ -64,6 +64,18 @@ const sign_in_exp = { verification_code_auth: 'Verification code', // UNTRANSLATED auth_swap_tip: 'Swap to change the priority', // UNTRANSLATED }, + social_sign_in: { + title: 'SOCIAL SIGN IN', // UNTRANSLATED + social_sign_in: 'Social sign in', // UNTRANSLATED + description: + 'Users may need to enter required identifier when register through social accounts. This was defined by your sign up identifier.', // UNTRANSLATED + add_social_connector: 'Add Social Connector', // UNTRANSLATED + set_up_hint: { + not_in_list: 'Not in the list?', // UNTRANSLATED + set_up_more: 'Set up more', // UNTRANSLATED + go_to: 'social connectors or go to “Connectors” section.', // UNTRANSLATED + }, + }, }, sign_in_methods: { title: 'METHODES DE CONNEXION', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/sign-in-exp.ts b/packages/phrases/src/locales/ko/translation/admin-console/sign-in-exp.ts index 1d3bf579b..6b50591d1 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/sign-in-exp.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/sign-in-exp.ts @@ -59,6 +59,18 @@ const sign_in_exp = { verification_code_auth: 'Verification code', // UNTRANSLATED auth_swap_tip: 'Swap to change the priority', // UNTRANSLATED }, + social_sign_in: { + title: 'SOCIAL SIGN IN', // UNTRANSLATED + social_sign_in: 'Social sign in', // UNTRANSLATED + description: + 'Users may need to enter required identifier when register through social accounts. This was defined by your sign up identifier.', // UNTRANSLATED + add_social_connector: 'Add Social Connector', // UNTRANSLATED + set_up_hint: { + not_in_list: 'Not in the list?', // UNTRANSLATED + set_up_more: 'Set up more', // UNTRANSLATED + go_to: 'social connectors or go to “Connectors” section.', // UNTRANSLATED + }, + }, }, sign_in_methods: { title: '로그인 방법', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/sign-in-exp.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/sign-in-exp.ts index 0d295f9df..32535bb5e 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/sign-in-exp.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/sign-in-exp.ts @@ -62,6 +62,18 @@ const sign_in_exp = { verification_code_auth: 'Verification code', // UNTRANSLATED auth_swap_tip: 'Swap to change the priority', // UNTRANSLATED }, + social_sign_in: { + title: 'SOCIAL SIGN IN', // UNTRANSLATED + social_sign_in: 'Social sign in', // UNTRANSLATED + description: + 'Users may need to enter required identifier when register through social accounts. This was defined by your sign up identifier.', // UNTRANSLATED + add_social_connector: 'Add Social Connector', // UNTRANSLATED + set_up_hint: { + not_in_list: 'Not in the list?', // UNTRANSLATED + set_up_more: 'Set up more', // UNTRANSLATED + go_to: 'social connectors or go to “Connectors” section.', // UNTRANSLATED + }, + }, }, sign_in_methods: { title: 'MÉTODOS DE LOGIN', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/sign-in-exp.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/sign-in-exp.ts index 9233e80be..9e9f60fee 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/sign-in-exp.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/sign-in-exp.ts @@ -63,6 +63,18 @@ const sign_in_exp = { verification_code_auth: 'Verification code', // UNTRANSLATED auth_swap_tip: 'Swap to change the priority', // UNTRANSLATED }, + social_sign_in: { + title: 'SOCIAL SIGN IN', // UNTRANSLATED + social_sign_in: 'Social sign in', // UNTRANSLATED + description: + 'Users may need to enter required identifier when register through social accounts. This was defined by your sign up identifier.', // UNTRANSLATED + add_social_connector: 'Add Social Connector', // UNTRANSLATED + set_up_hint: { + not_in_list: 'Not in the list?', // UNTRANSLATED + set_up_more: 'Set up more', // UNTRANSLATED + go_to: 'social connectors or go to “Connectors” section.', // UNTRANSLATED + }, + }, }, sign_in_methods: { title: 'OTURUM AÇMA YÖNTEMLERİ', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/sign-in-exp.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/sign-in-exp.ts index 1184e2176..500544914 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/sign-in-exp.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/sign-in-exp.ts @@ -60,6 +60,18 @@ const sign_in_exp = { verification_code_auth: 'Verification code', // UNTRANSLATED auth_swap_tip: 'Swap to change the priority', // UNTRANSLATED }, + social_sign_in: { + title: 'SOCIAL SIGN IN', // UNTRANSLATED + social_sign_in: 'Social sign in', // UNTRANSLATED + description: + 'Users may need to enter required identifier when register through social accounts. This was defined by your sign up identifier.', // UNTRANSLATED + add_social_connector: 'Add Social Connector', // UNTRANSLATED + set_up_hint: { + not_in_list: 'Not in the list?', // UNTRANSLATED + set_up_more: 'Set up more', // UNTRANSLATED + go_to: 'social connectors or go to “Connectors” section.', // UNTRANSLATED + }, + }, }, sign_in_methods: { title: '登录方式',