diff --git a/apps/app/components/account/email-password-form.tsx b/apps/app/components/account/email-password-form.tsx index 920ec0829..8a0dc3a33 100644 --- a/apps/app/components/account/email-password-form.tsx +++ b/apps/app/components/account/email-password-form.tsx @@ -1,11 +1,10 @@ import React, { useState } from "react"; +import { useRouter } from "next/router"; +import Link from "next/link"; + // react hook form import { useForm } from "react-hook-form"; -// services -import authenticationService from "services/authentication.service"; -// hooks -import useToast from "hooks/use-toast"; // components import { EmailResetPasswordForm } from "components/account"; // ui @@ -17,15 +16,19 @@ type EmailPasswordFormValues = { medium?: string; }; -export const EmailPasswordForm = ({ handleSignIn }: any) => { +type Props = { + onSubmit: (formData: EmailPasswordFormValues) => Promise; +}; + +export const EmailPasswordForm: React.FC = ({ onSubmit }) => { const [isResettingPassword, setIsResettingPassword] = useState(false); - const { setToastAlert } = useToast(); + const router = useRouter(); + const isSignUpPage = router.pathname === "/sign-up"; const { register, handleSubmit, - setError, formState: { errors, isSubmitting, isValid, isDirty }, } = useForm({ defaultValues: { @@ -37,31 +40,6 @@ export const EmailPasswordForm = ({ handleSignIn }: any) => { reValidateMode: "onChange", }); - const onSubmit = (formData: EmailPasswordFormValues) => { - authenticationService - .emailLogin(formData) - .then((response) => { - if (handleSignIn) handleSignIn(response); - }) - .catch((error) => { - console.log(error); - setToastAlert({ - title: "Oops!", - type: "error", - message: "Enter the correct email address and password to sign in", - }); - if (!error?.response?.data) return; - Object.keys(error.response.data).forEach((key) => { - const err = error.response.data[key]; - console.log(err); - setError(key as keyof EmailPasswordFormValues, { - type: "manual", - message: Array.isArray(err) ? err.join(", ") : err, - }); - }); - }); - }; - return ( <> {isResettingPassword ? ( @@ -82,7 +60,7 @@ export const EmailPasswordForm = ({ handleSignIn }: any) => { ) || "Email ID is not valid", }} error={errors.email} - placeholder="Enter your Email ID" + placeholder="Enter your email ID" />
@@ -100,13 +78,21 @@ export const EmailPasswordForm = ({ handleSignIn }: any) => {
- + {isSignUpPage ? ( + + + Already have an account? Sign in. + + + ) : ( + + )}
@@ -116,8 +102,21 @@ export const EmailPasswordForm = ({ handleSignIn }: any) => { disabled={!isValid && isDirty} loading={isSubmitting} > - {isSubmitting ? "Signing in..." : "Sign In"} + {isSignUpPage + ? isSubmitting + ? "Signing up..." + : "Sign Up" + : isSubmitting + ? "Signing in..." + : "Sign In"} + {!isSignUpPage && ( + + + Don{"'"}t have an account? Sign up. + + + )}
)} diff --git a/apps/app/components/workspace/create-workspace-form.tsx b/apps/app/components/workspace/create-workspace-form.tsx index 507d88ea7..42078fe91 100644 --- a/apps/app/components/workspace/create-workspace-form.tsx +++ b/apps/app/components/workspace/create-workspace-form.tsx @@ -31,16 +31,16 @@ type Props = { const restrictedUrls = [ "api", + "installations", + "404", "create-workspace", "error", - "installations", "invitations", "magic-sign-in", "onboarding", "reset-password", - "signin", + "sign-up", "workspace-member-invitation", - "404", ]; export const CreateWorkspaceForm: React.FC = ({ diff --git a/apps/app/pages/index.tsx b/apps/app/pages/index.tsx index 96d8441d7..ab2633241 100644 --- a/apps/app/pages/index.tsx +++ b/apps/app/pages/index.tsx @@ -21,6 +21,12 @@ import { import { Spinner } from "components/ui"; // icons import Logo from "public/logo.png"; +// types +type EmailPasswordFormValues = { + email: string; + password?: string; + medium?: string; +}; const HomePage: NextPage = () => { const { user, isLoading, mutateUser } = useUserAuth("sign-in"); @@ -66,7 +72,6 @@ const HomePage: NextPage = () => { throw Error("Cant find credentials"); } } catch (error: any) { - console.log(error); setToastAlert({ title: "Error signing in!", type: "error", @@ -77,19 +82,30 @@ const HomePage: NextPage = () => { } }; - const handleEmailPasswordSignIn = async (response: any) => { - try { - if (response) mutateUser(); - } catch (error: any) { - console.log(error); - setToastAlert({ - title: "Error signing in!", - type: "error", - message: - error?.error || - "Something went wrong. Please try again later or contact the support team.", - }); - } + const handlePasswordSignIn = async (formData: EmailPasswordFormValues) => { + await authenticationService + .emailLogin(formData) + .then((response) => { + try { + if (response) mutateUser(); + } catch (error: any) { + console.log(error); + setToastAlert({ + title: "Error signing in!", + type: "error", + message: + error?.error || + "Something went wrong. Please try again later or contact the support team.", + }); + } + }) + .catch(() => + setToastAlert({ + title: "Oops!", + type: "error", + message: "Enter the correct email address and password to sign in", + }) + ); }; const handleEmailCodeSignIn = async (response: any) => { @@ -114,7 +130,6 @@ const HomePage: NextPage = () => {
- {/*
Validating authentication
*/} ) : (
@@ -137,7 +152,7 @@ const HomePage: NextPage = () => {
) : ( - + )} diff --git a/apps/app/pages/sign-up.tsx b/apps/app/pages/sign-up.tsx new file mode 100644 index 000000000..eeffb53bd --- /dev/null +++ b/apps/app/pages/sign-up.tsx @@ -0,0 +1,88 @@ +import React from "react"; + +import Image from "next/image"; +import { useRouter } from "next/router"; + +// services +import authenticationService from "services/authentication.service"; +// hooks +import useUserAuth from "hooks/use-user-auth"; +import useToast from "hooks/use-toast"; +// layouts +import DefaultLayout from "layouts/default-layout"; +// components +import { EmailPasswordForm } from "components/account"; +// images +import Logo from "public/logo.png"; +// types +import type { NextPage } from "next"; +type EmailPasswordFormValues = { + email: string; + password?: string; + medium?: string; +}; + +const SignUp: NextPage = () => { + const router = useRouter(); + + const { setToastAlert } = useToast(); + + const { mutateUser } = useUserAuth("sign-in"); + + const handleSignUp = async (formData: EmailPasswordFormValues) => { + const payload = { + email: formData.email, + password: formData.password ?? "", + }; + + await authenticationService + .emailSignUp(payload) + .then(async (response) => { + setToastAlert({ + type: "success", + title: "Success!", + message: "Account created successfully.", + }); + + if (response) await mutateUser(); + router.push("/"); + }) + .catch((err) => { + if (err.status === 400) + setToastAlert({ + type: "error", + title: "Error!", + message: "An user already exists with this Email ID.", + }); + else + setToastAlert({ + type: "error", + title: "Error!", + message: "Something went wrong. Please try again later or contact the support team.", + }); + }); + }; + + return ( + +
+
+
+
+ Plane Web Logo +
+ Create a new Plane Account +
+
+ +
+ +
+
+
+
+
+ ); +}; + +export default SignUp; diff --git a/apps/app/services/api.service.ts b/apps/app/services/api.service.ts index ef198c221..361fea03e 100644 --- a/apps/app/services/api.service.ts +++ b/apps/app/services/api.service.ts @@ -7,6 +7,7 @@ const nonValidatedRoutes = [ "/magic-sign-in", "/reset-password", "/workspace-member-invitation", + "/sign-up", ]; const validateRouteCheck = (route: string): boolean => { diff --git a/apps/app/services/authentication.service.ts b/apps/app/services/authentication.service.ts index 291f255d8..f0d19da24 100644 --- a/apps/app/services/authentication.service.ts +++ b/apps/app/services/authentication.service.ts @@ -20,6 +20,18 @@ class AuthService extends APIService { }); } + async emailSignUp(data: { email: string; password: string }) { + return this.post("/api/sign-up/", data, { headers: {} }) + .then((response) => { + this.setAccessToken(response?.data?.access_token); + this.setRefreshToken(response?.data?.refresh_token); + return response?.data; + }) + .catch((error) => { + throw error?.response; + }); + } + async socialAuth(data: any) { return this.post("/api/social-auth/", data, { headers: {} }) .then((response) => {