login

mail@pastecode.io avatar
unknown
javascript
14 days ago
11 kB
5
Indexable
Never
import {
  Button,
  Flex,
  FormControl,
  FormLabel,
  Heading,
  Input,
  Stack,
  FormErrorMessage,
  Box,
  Text,
} from "@chakra-ui/react";
import { useState, useEffect } from "react";
import { NextPage } from "next";
import { useRouter } from "next/router";
import { FcGoogle } from "react-icons/fc";
import { FaFacebook } from "react-icons/fa";
import NextLink from "next/link";
import {
  Formik,
  Form,
  Field,
  ErrorMessage,
  FieldInputProps,
  FormikProps,
} from "formik";
import axios, { AxiosError } from "axios";
interface VALUES {
  email: string;
  password: string;
}
type FieldProps = {
  field: FieldInputProps<string>;
  form: FormikProps<VALUES>;
};
import { signIn } from "next-auth/react";
import Head from "next/head";

const LoginPage: NextPage = () => {
  const router = useRouter();
  const [error, setError] = useState(router.query.error || "");
  useEffect(() => {
    if (router.query.error) {
      setError(router.query.error);
    }
  }, [router.query]);
  const [googleSubmitting, setGoogleSubmitting] = useState(false);
  const handleClearErrors = () => {
    setError("");
    const q = Object.assign({}, router.query);
    delete q["error"];
    router.replace(
      {
        pathname: "/login",
        query: q,
      },
      undefined,
      { shallow: true }
    );
  };

  const nextURL = (router.query.next as string) || "/customer/dashboard";

  const [seconds, setSeconds] = useState(0);
  const loggedOutFlag = router.query["logged-out"];
  const [redirectInterval, setRedirectInterval] = useState<any>(null);
  useEffect(() => {
    if (!loggedOutFlag) return;
    const i = setInterval(() => {
      setSeconds((s) => {
        if (s == 8) {
          router.push("/");
          clearInterval(i);
        }
        return s + 1;
      });
    }, 1000);
    setRedirectInterval(i);
    return () => {
      clearInterval(i);
      setRedirectInterval(null);
    };
  }, [setRedirectInterval, loggedOutFlag, router]);
  const stopRedirect = () => {
    if (redirectInterval) {
      clearInterval(redirectInterval);
      setRedirectInterval(null);
    }
  };

  return <>
    <Head>
      <title>Login to Akountmate | Project management simplified.</title>
    </Head>
    <Flex
      m={0}
      p={0}
      w="100%"
      overflowX="hidden"
      minH="100vh"
      bg="accent.100"
      justifyContent={"center"}
      alignItems="center"
    >
      <Flex
        my="1em"
        mx={["0.5rem", null, "1rem"]}
        w="calc(100% - 1rem)"
        maxW="600px"
        p={["1em 1em", null, "1em 2em"]}
        h="max-content"
        flexDir={"column"}
        bg="white"
        gap="1em"
      >
        <Flex color="black" w="100%" justifyContent={"center"}>
          <img src="/landing/logo_black.svg" style={{ height: "5em" }} />
        </Flex>
        <Heading fontSize="1.4em" fontWeight={"600"}>
          Login to Akountmate
        </Heading>
        <Text color="red.600" fontWeight="500">
          {error}
        </Text>
        <Stack
          direction={["column", null, "row"]}
          minH={["3rem", null, "unset"]}
          // justifyContent="stretch"
          w="100%"
        >
          <Button
            // minW="23ch"
            // mx="auto"
            width="100%"
            // flex={["0 1", null, 1]}
            isLoading={googleSubmitting}
            onClick={() => {
              handleClearErrors();

              stopRedirect();

              setGoogleSubmitting(true);
              signIn("google", {
                redirect: true,
                callbackUrl: nextURL,
              })
                .then((resp) => {
                  if (resp?.error) {
                    // if (resp.error == "CredentialsSignin")
                    //   throw new Error(
                    //     "Invalid credentials were provided. Please try again."
                    //   );
                    console.log("ERRO", resp.error);
                    throw resp?.error;
                  }
                  // if (!resp?.ok) throw new Error("Failed to login, try again.");

                  if (router.query.next) {
                    router.push(router.query.next as string);
                    return;
                  }
                  router.push(nextURL);
                })
                .catch((er) => {
                  setError(er.message || er);
                  console.warn(er);
                })
                .finally(() => {
                  // setGoogleSubmitting(false);
                });
            }}
            leftIcon={<FcGoogle fontSize={"1.5em"} />}
          >
            Continue with Google
          </Button>
          {/* <Button
          flex="1"
          leftIcon={<FaFacebook fontSize={"1.5em"} color="#4267B2" />}
        >
          Facebook
        </Button> */}
        </Stack>
        <hr />
        <Formik
          initialValues={{
            email: "",
            password: "",
          }}
          onSubmit={(values, actions) => {
            handleClearErrors();
            stopRedirect();
            signIn("credentials", {
              email: values.email,
              password: values.password,
              redirect: false,
            })
              .then((resp) => {
                if (resp?.error) {
                  if (resp.error == "CredentialsSignin")
                    throw new Error(
                      "Invalid credentials were provided. Please try again."
                    );
                  throw resp?.error;
                }
                if (!resp?.ok) throw new Error("Failed to login, try again.");

                if (resp?.url) {
                  const u = new URL(resp.url);
                  console.log(u.searchParams.get("error"));
                }

                if (router.query.next) {
                  router.push(router.query.next as string);
                  return;
                }
                router.push("/customer/dashboard");
              })
              .catch((er) => {
                setError(er.message || er);
                console.warn(er);
              })
              .finally(() => actions.setSubmitting(false));
          }}
        >
          {(props) => (
            <Form>
              <Field name="email">
                {(props: FieldProps) => (
                  <FormControl
                    mt="1em"
                    isInvalid={
                      (props.form.errors.email && props.form.touched.email) ||
                      false
                    }
                    isRequired
                  >
                    <FormLabel fontWeight={"600"}>Your Email</FormLabel>
                    <Input
                      {...props.field}
                      variant="flushed"
                      type="email"
                      onFocus={() => {
                        stopRedirect();
                      }}
                      placeholder="example@gmail.com"
                      isDisabled={props.form.isSubmitting}
                    />
                    <FormErrorMessage>
                      {props.form.errors.email}
                    </FormErrorMessage>
                  </FormControl>
                )}
              </Field>

              <Field
                validate={(s: string) => {
                  if (s.length < 5) {
                    return "Length must be greater than or equals 5";
                  }
                  return "";
                }}
                name="password"
              >
                {(props: FieldProps) => (
                  <FormControl
                    mt="1em"
                    isInvalid={
                      (props.form.errors.password &&
                        props.form.touched.password) ||
                      false
                    }
                    isRequired
                  >
                    <FormLabel fontWeight={"600"}>Your Password</FormLabel>
                    <Input
                      {...props.field}
                      variant="flushed"
                      type="password"
                      onFocus={() => {
                        stopRedirect();
                      }}
                      placeholder="Password"
                      isDisabled={props.form.isSubmitting}
                    />
                    <FormErrorMessage>
                      {props.form.errors.password}
                    </FormErrorMessage>
                  </FormControl>
                )}
              </Field>

              <Flex
                w="100%"
                justifyContent={"space-between"}
                mt="2em"
                gap="1em"
                alignItems={["stretch", "center"]}
                flexDir={["column", "row"]}
              >
                <NextLink href="/password-email" passHref legacyBehavior>
                  <Button
                    as="a"
                    variant="link"
                    alignSelf={["flex-start", "center"]}
                    colorScheme={"accent"}
                    isDisabled={props.isSubmitting}
                  >
                    Forgot Password?
                  </Button>
                </NextLink>

                <Flex
                  flex={1}
                  justifyContent={["space-between", "flex-end"]}
                  gap="1em"
                  // alignItems="center"
                >
                  <NextLink
                    href={"/register?next=" + encodeURIComponent(nextURL)}
                    passHref
                    legacyBehavior>
                    <Button
                      as="a"
                      variant="link"
                      // px="0.5em"
                      colorScheme={"gray"}
                      isDisabled={props.isSubmitting}
                    >
                      Create a new account
                    </Button>
                  </NextLink>
                  <Button
                    borderRadius={"4px"}
                    px="2em"
                    isLoading={props.isSubmitting}
                    type="submit"
                    colorScheme={"accent"}
                  >
                    Login
                  </Button>
                </Flex>
              </Flex>
            </Form>
          )}
        </Formik>
        {redirectInterval && (
          <Text mt="1rem" fontSize="md" color="gray.400">
            Redirecting to homescreen{" "}
            {Array.from(new Array(seconds)).map((m) => ".")}
          </Text>
        )}
      </Flex>
    </Flex>
  </>;
};
export default LoginPage;
Leave a Comment