import { ISchema } from '@formily/react'; import { SchemaComponent, useAPIClient, useCurrentUserContext } from '@nocobase/client'; import React, { useCallback } from 'react'; import { useAuthTranslation } from '../locale'; import { useNavigate, useSearchParams } from 'react-router-dom'; import { useForm } from '@formily/react'; import { useSignUpForms } from '../pages'; import { Authenticator } from '../authenticator'; export function useRedirect(next = '/admin') { const navigate = useNavigate(); const [searchParams] = useSearchParams(); return useCallback(() => { navigate(searchParams.get('redirect') || '/admin', { replace: true }); }, [navigate, searchParams]); } export const useSignIn = (authenticator: string) => { const form = useForm(); const api = useAPIClient(); const redirect = useRedirect(); const { refreshAsync } = useCurrentUserContext(); return { async run() { await form.submit(); await api.auth.signIn(form.values, authenticator); await refreshAsync(); redirect(); }, }; }; const passwordForm: ISchema = { type: 'object', name: 'passwordForm', 'x-component': 'FormV2', properties: { account: { type: 'string', 'x-component': 'Input', 'x-validator': `{{(value) => { if (!value) { return t("Please enter your username or email"); } if (value.includes('@')) { if (!/^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$/.test(value)) { return t("Please enter a valid email"); } } else { return /^[^@.<>"'/]{2,16}$/.test(value) || t("Please enter a valid username"); } }}}`, 'x-decorator': 'FormItem', 'x-component-props': { placeholder: '{{t("Username/Email")}}', style: {} }, }, password: { type: 'string', 'x-component': 'Password', required: true, 'x-decorator': 'FormItem', 'x-component-props': { placeholder: '{{t("Password")}}', style: {} }, }, actions: { type: 'void', 'x-component': 'div', properties: { submit: { title: '{{t("Sign in")}}', type: 'void', 'x-component': 'Action', 'x-component-props': { htmlType: 'submit', block: true, type: 'primary', useAction: `{{ useBasicSignIn }}`, style: { width: '100%' }, }, }, }, }, signUp: { type: 'void', 'x-component': 'Link', 'x-component-props': { to: '{{ signUpLink }}', }, 'x-content': '{{t("Create an account")}}', 'x-visible': '{{ allowSignUp }}', }, }, }; export const SignInForm = (props: { authenticator: Authenticator }) => { const { t } = useAuthTranslation(); const authenticator = props.authenticator; const { authType, name, options } = authenticator; const signUpPages = useSignUpForms(); const allowSignUp = !!signUpPages[authType] && options?.allowSignUp; const signUpLink = `/signup?name=${name}`; const useBasicSignIn = () => { return useSignIn(name); }; return ; };