0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-06 20:40:08 -05:00

feat(console): dynamic sign in methods form (#666)

This commit is contained in:
Wang Sijie 2022-04-28 11:42:44 +08:00 committed by GitHub
parent 6738b6a088
commit 5944ff075e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 32 deletions

View file

@ -1,5 +1,5 @@
import { nanoid } from 'nanoid';
import React, { InputHTMLAttributes, ReactNode, useState } from 'react';
import React, { forwardRef, InputHTMLAttributes, ReactNode, Ref, useState } from 'react';
import Icon from './Icon';
import * as styles from './index.module.scss';
@ -8,16 +8,16 @@ type Props = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> & {
label?: ReactNode;
};
const Checkbox = ({ label, disabled, ...rest }: Props) => {
const Checkbox = ({ label, disabled, ...rest }: Props, ref: Ref<HTMLInputElement>) => {
const [id] = useState(nanoid());
return (
<div className={styles.checkbox}>
<input id={id} type="checkbox" disabled={disabled} {...rest} />
<input id={id} type="checkbox" disabled={disabled} {...rest} ref={ref} />
<Icon className={styles.icon} />
{label && <label htmlFor={id}>{label}</label>}
</div>
);
};
export default Checkbox;
export default forwardRef<HTMLInputElement, Props>(Checkbox);

View file

@ -1,5 +1,5 @@
import { SignInMethodKey } from '@logto/schemas';
import React from 'react';
import React, { useEffect, useMemo } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
@ -16,8 +16,44 @@ const signInMethods = Object.values(SignInMethodKey);
const SignInMethodsForm = () => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { register, watch, control } = useFormContext<SignInExperienceForm>();
const { register, watch, control, setValue } = useFormContext<SignInExperienceForm>();
const primaryMethod = watch('signInMethods.primary');
const enableSecondary = watch('signInMethods.enableSecondary');
const social = watch('signInMethods.social');
useEffect(() => {
if (primaryMethod) {
// When one of the sign-in methods has been primary, it should not be able to be secondary simultaneously.
setValue(`signInMethods.${primaryMethod}`, false);
}
}, [primaryMethod, setValue]);
const secondaryMethodsFields = useMemo(
() =>
signInMethods.map((method) => {
const label = (
<>
{t('sign_in_exp.sign_in_methods.methods', { context: method })}
{primaryMethod === method && (
<span className={styles.primaryTag}>
{t('sign_in_exp.sign_in_methods.methods_primary_tag')}
</span>
)}
</>
);
return (
<div key={method} className={styles.method}>
<Checkbox
label={label}
disabled={primaryMethod === method}
{...register(`signInMethods.${method}`)}
/>
</div>
);
}),
[primaryMethod, register, t]
);
return (
<>
@ -38,39 +74,39 @@ const SignInMethodsForm = () => {
)}
/>
</FormField>
{primaryMethod === SignInMethodKey.Social && (
<div className={styles.primarySocial}>
<Controller
name="socialSignInConnectorIds"
control={control}
render={({ field: { value, onChange } }) => (
<ConnectorsTransfer value={value} onChange={onChange} />
)}
/>
</div>
)}
<FormField isRequired title="admin_console.sign_in_exp.sign_in_methods.enable_secondary">
<Switch
{...register('signInMethods.enableSecondary', { required: true })}
label={t('sign_in_exp.sign_in_methods.enable_secondary_description')}
/>
{signInMethods.map((method) => (
<div key={method} className={styles.method}>
<Checkbox
label={
<>
{t('sign_in_exp.sign_in_methods.methods', { context: method })}
{primaryMethod === method && (
<span className={styles.primaryTag}>
{t('sign_in_exp.sign_in_methods.methods_primary_tag')}
</span>
)}
</>
}
disabled={primaryMethod === method}
{...register(`signInMethods.${method}`)}
/>
</div>
))}
</FormField>
<FormField title="admin_console.sign_in_exp.sign_in_methods.define_social_methods">
<Controller
name="socialSignInConnectorIds"
control={control}
render={({ field: { value, onChange } }) => (
<ConnectorsTransfer value={value} onChange={onChange} />
{enableSecondary && (
<>
{secondaryMethodsFields}
{social && (
<FormField title="admin_console.sign_in_exp.sign_in_methods.define_social_methods">
<Controller
name="socialSignInConnectorIds"
control={control}
render={({ field: { value, onChange } }) => (
<ConnectorsTransfer value={value} onChange={onChange} />
)}
/>
</FormField>
)}
/>
</FormField>
</>
)}
</>
);
};

View file

@ -13,3 +13,7 @@
.method {
margin-top: _.unit(2);
}
.primarySocial {
margin-top: _.unit(2);
}