diff --git a/packages/backend/src/graphql/mutations/create-user.ee.ts b/packages/backend/src/graphql/mutations/create-user.ee.ts index 804daf00..4a92faa6 100644 --- a/packages/backend/src/graphql/mutations/create-user.ee.ts +++ b/packages/backend/src/graphql/mutations/create-user.ee.ts @@ -4,11 +4,12 @@ type Params = { input: { email: string; password: string; + fullName: string; }; }; const createUser = async (_parent: unknown, params: Params) => { - const { email, password } = params.input; + const { email, password, fullName } = params.input; const existingUser = await User.query().findOne({ email }); @@ -19,6 +20,7 @@ const createUser = async (_parent: unknown, params: Params) => { const user = await User.query().insert({ email, password, + fullName, role: 'user', }); diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index 7e421f6e..7e02269e 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -336,6 +336,7 @@ input DeleteStepInput { } input CreateUserInput { + fullName: String! email: String! password: String! } diff --git a/packages/web/src/components/LoginForm/index.tsx b/packages/web/src/components/LoginForm/index.tsx index 1fec7ab2..fab8fae2 100644 --- a/packages/web/src/components/LoginForm/index.tsx +++ b/packages/web/src/components/LoginForm/index.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; -import { useNavigate } from 'react-router-dom'; +import { useNavigate, Link as RouterLink } from 'react-router-dom'; import { useMutation } from '@apollo/client'; import Paper from '@mui/material/Paper'; +import Link from '@mui/material/Link'; import Typography from '@mui/material/Typography'; import LoadingButton from '@mui/lab/LoadingButton'; @@ -49,6 +50,13 @@ function renderFields(props: { loading: boolean }) { > Login + + + Don't have an Automatisch account yet?  + + Sign up + + ); }; diff --git a/packages/web/src/components/SignUpForm/index.ee.tsx b/packages/web/src/components/SignUpForm/index.ee.tsx new file mode 100644 index 00000000..eb7a55f6 --- /dev/null +++ b/packages/web/src/components/SignUpForm/index.ee.tsx @@ -0,0 +1,177 @@ +import * as React from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useMutation } from '@apollo/client'; +import Paper from '@mui/material/Paper'; +import Typography from '@mui/material/Typography'; +import LoadingButton from '@mui/lab/LoadingButton'; +import * as yup from 'yup'; + +import useAuthentication from 'hooks/useAuthentication'; +import * as URLS from 'config/urls'; +import { CREATE_USER } from 'graphql/mutations/create-user.ee'; +import Form from 'components/Form'; +import TextField from 'components/TextField'; +import { yupResolver } from '@hookform/resolvers/yup'; +import { LOGIN } from 'graphql/mutations/login'; +import useFormatMessage from 'hooks/useFormatMessage'; + +const validationSchema = yup.object().shape({ + fullName: yup.string().trim().required('signupForm.mandatoryInput'), + email: yup.string().trim().email().required('signupForm.mandatoryInput'), + password: yup.string().required('signupForm.mandatoryInput'), + confirmPassword: yup + .string() + .required('signupForm.mandatoryInput') + .oneOf([yup.ref('password')], 'signupForm.passwordMustMatch'), +}); + +const initialValues = { + fullName: '', + email: '', + password: '', + confirmPassword: '', +}; + +function SignUpForm() { + const navigate = useNavigate(); + const authentication = useAuthentication(); + const formatMessage = useFormatMessage(); + const [createUser] = useMutation(CREATE_USER); + const [login, { loading }] = useMutation(LOGIN); + + React.useEffect(() => { + if (authentication.isAuthenticated) { + navigate(URLS.DASHBOARD); + } + }, [authentication.isAuthenticated]); + + const handleSubmit = async (values: any) => { + const { fullName, email, password } = values; + await createUser({ + variables: { + input: { fullName, email, password }, + }, + }); + + const { data } = await login({ + variables: { + input: { email, password }, + }, + }); + + const { token } = data.login; + + authentication.updateToken(token); + }; + + return ( + + theme.palette.text.disabled, + pb: 2, + mb: 2, + }} + gutterBottom + > + {formatMessage('signupForm.title')} + + +
( + <> + + + + + + + + + + {formatMessage('signupForm.submit')} + + + )} + /> + + ); +} + +export default SignUpForm; diff --git a/packages/web/src/config/urls.ts b/packages/web/src/config/urls.ts index aeca5e82..062d88f4 100644 --- a/packages/web/src/config/urls.ts +++ b/packages/web/src/config/urls.ts @@ -5,6 +5,7 @@ export const EXECUTION = (executionId: string): string => `/executions/${executionId}`; export const LOGIN = '/login'; +export const SIGNUP = '/sign-up'; export const APPS = '/apps'; export const NEW_APP_CONNECTION = '/apps/new'; diff --git a/packages/web/src/graphql/mutations/create-user.ee.ts b/packages/web/src/graphql/mutations/create-user.ee.ts new file mode 100644 index 00000000..5dc9f419 --- /dev/null +++ b/packages/web/src/graphql/mutations/create-user.ee.ts @@ -0,0 +1,10 @@ +import { gql } from '@apollo/client'; + +export const CREATE_USER = gql` + mutation CreateUser($input: CreateUserInput) { + createUser(input: $input) { + email + fullName + } + } +`; diff --git a/packages/web/src/locales/en.json b/packages/web/src/locales/en.json index 0130b34f..22afbb8e 100644 --- a/packages/web/src/locales/en.json +++ b/packages/web/src/locales/en.json @@ -105,5 +105,13 @@ "webhookUrlInfo.title": "Your webhook URL", "webhookUrlInfo.description": "You'll need to configure your application with this webhook URL.", "webhookUrlInfo.helperText": "We've generated a custom webhook URL for you to send requests to. Learn more about webhooks.", - "webhookUrlInfo.copy": "Copy" -} \ No newline at end of file + "webhookUrlInfo.copy": "Copy", + "signupForm.title": "Sign up", + "signupForm.fullNameFieldLabel": "Full name", + "signupForm.emailFieldLabel": "Email", + "signupForm.passwordFieldLabel": "Password", + "signupForm.confirmPasswordFieldLabel": "Confirm password", + "signupForm.submit": "Sign up", + "signupForm.passwordMustMatch": "Passwords must match.", + "signupForm.mandatoryInput": "{inputName} is required." +} diff --git a/packages/web/src/pages/ProfileSettings/index.tsx b/packages/web/src/pages/ProfileSettings/index.tsx index 9d1aa9a0..7ec20ca5 100644 --- a/packages/web/src/pages/ProfileSettings/index.tsx +++ b/packages/web/src/pages/ProfileSettings/index.tsx @@ -158,7 +158,9 @@ function ProfileSettings() { margin="normal" type="password" error={touchedFields.password && !!errors?.password} - helperText={errors?.password?.message || ' '} + helperText={ + (touchedFields.password && errors?.password?.message) || '' + } />