diff --git a/.astro/astro/content.d.ts b/.astro/astro/content.d.ts index a5a0287..d89741c 100644 --- a/.astro/astro/content.d.ts +++ b/.astro/astro/content.d.ts @@ -307,5 +307,5 @@ declare module 'astro:content' { type AnyEntryMap = ContentEntryMap & DataEntryMap; - export type ContentConfig = typeof import("../../src/content/config.js"); + export type ContentConfig = typeof import("./../../src/content/config.js"); } diff --git a/src/data/api/authentication_api.ts b/src/data/api/authentication_api.ts new file mode 100644 index 0000000..0d71292 --- /dev/null +++ b/src/data/api/authentication_api.ts @@ -0,0 +1,11 @@ +import type { CheckTokenResponse, SignupResponse } from "../types/authentication"; + +export class AuthenticationApi { + async checkToken(token: string): Promise { + return { status: true, errorMessage: null }; + } + + async signInWithEmailAndPassword(email: string, password: string): Promise { + return { status: true, errorMessage: null }; + } +} \ No newline at end of file diff --git a/src/data/api/firebase_api.ts b/src/data/api/firebase_api.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/data/repositories/authentication_repository.ts b/src/data/repositories/authentication_repository.ts new file mode 100644 index 0000000..514fe58 --- /dev/null +++ b/src/data/repositories/authentication_repository.ts @@ -0,0 +1,25 @@ +import { AuthenticationApi } from "../api/authentication_api"; +import type { SignUpException } from "../types/authentication"; + +export class AuthenticationRepository { + api: AuthenticationApi; + + constructor() { + this.api = new AuthenticationApi(); + } + + async checkToken(token: string): Promise { + const result = await this.api.checkToken(token); + return result.status; + } + + async signInWithEmailAndPassword(email: string, password: string): Promise { + const result = await this.api.signInWithEmailAndPassword(email, password); + + if (!result.status) { + throw { + message: result.errorMessage + } as SignUpException; + } + } +} \ No newline at end of file diff --git a/src/data/types/authentication.ts b/src/data/types/authentication.ts new file mode 100644 index 0000000..28adf07 --- /dev/null +++ b/src/data/types/authentication.ts @@ -0,0 +1,13 @@ +export type CheckTokenResponse = { + status: boolean; + errorMessage: string | null; +} + +export type SignupResponse = { + status: boolean; + errorMessage: string | null; +} + +export type SignUpException = { + message: string; +} \ No newline at end of file diff --git a/src/react/pages/SignupPage.tsx b/src/react/pages/SignupPage.tsx index 55b9f05..27aaab2 100644 --- a/src/react/pages/SignupPage.tsx +++ b/src/react/pages/SignupPage.tsx @@ -4,12 +4,35 @@ import { useForm } from "@mantine/form" import { useEffect, useState } from "react"; import { notifications, showNotification } from "@mantine/notifications"; import { isEmailValid } from "../utils"; -import { useFirebaseUserInfo } from "../utils/query"; import { WebsiteConfig } from "../../config"; import { useTranslations } from "../../i18n/utils"; +import { AuthenticationRepository } from "../../data/repositories/authentication_repository"; -export const SignupPage = ({ token }: { token:string }) => { +enum SignUpPageStatus { Initial, InvalidToken, Ready, SignUpInProgress, SignUpError, SignUpComplete } + +export const SignupPage = ({ token }: { token: string }) => { const t = useTranslations("en") + const authRepository = new AuthenticationRepository(); + const [pageStatus, setPageStatus] = useState(SignUpPageStatus.Initial); + const [showPasswords, setShowPasswords] = useState(false) + + useEffect(() => { + if (pageStatus !== SignUpPageStatus.Initial) { + return; + } else if (token) { + authRepository + .checkToken(token) + .then((tokenIsValid) => { + setPageStatus(tokenIsValid + ? SignUpPageStatus.Ready + : SignUpPageStatus.InvalidToken + ); + }); + } else { + setPageStatus(SignUpPageStatus.InvalidToken); + } + }, [pageStatus, token]); + const checkErrors = () => { if (!form.isValid()) { @@ -28,9 +51,9 @@ export const SignupPage = ({ token }: { token:string }) => { confirmPassword: "", }, validate: { - email: (value) => value.length > 0? isEmailValid(value)? undefined: "The email given is invalid": "Email is required", - password: (value) => value.length > 0? undefined: "Password is required", - confirmPassword: (value, values) => value === values.password? undefined: "Passwords do not match" + email: (value) => value.length > 0 ? isEmailValid(value) ? undefined : "The email given is invalid" : "Email is required", + password: (value) => value.length > 0 ? undefined : "Password is required", + confirmPassword: (value, values) => value === values.password ? undefined : "Passwords do not match" }, validateInputOnChange: true, initialErrors: { @@ -40,82 +63,90 @@ export const SignupPage = ({ token }: { token:string }) => { } }) - const [showPasswords, setShowPasswords] = useState(false) - const [loading, setLoading] = useState(false) - - const { user, hasLoaded } = useFirebaseUserInfo() - useEffect(() => { - if(user != null && hasLoaded) { - location.href = "/app" - } - }, [user]) - if(!token) { + if (pageStatus === SignUpPageStatus.Initial) { + return
+ } else if (pageStatus === SignUpPageStatus.InvalidToken) { return Invalid token } + + return ( {/*

registration token: {token}

*/} -
{ - const requestId = notifications.show({ - loading: true, - title: "Signing up...", - message: "Please wait untils the registration is complete", - autoClose: false - }) - setLoading(true) - fetch("http://127.0.0.1/fakeAPI") - .then((userInfo) => { - notifications.update({ - id: requestId, - loading: false, - title: "Registration Completed", - message: `Welcome ${user?.displayName}`, - color: "green", - autoClose: true - }) - }).catch((error) => { - notifications.update({ - id: requestId, - loading: false, - title: `Registration error [${error.code}]`, - message: error.message, - color: "red", - autoClose: true - }) - }).finally(() => { - setLoading(false) - }) + { + const requestId = notifications.show({ + loading: true, + title: "Signing up...", + message: "Please wait untils the sign up is complete", + autoClose: false }) + + setPageStatus(SignUpPageStatus.SignUpInProgress); + + authRepository + .signInWithEmailAndPassword(data.email, data.password) + .then(() => { + notifications.update({ + id: requestId, + loading: false, + title: "Sign up Completed", + message: `Welcome ${form.values.email}`, + color: "green", + autoClose: true + }); + setPageStatus(SignUpPageStatus.SignUpComplete); + + setTimeout(() => { + location.href = "/login"; + }, 1500); + + }).catch((error) => { + notifications.update({ + id: requestId, + loading: false, + title: `Registration error [${error.code}]`, + message: error.message, + color: "red", + autoClose: true + }); + setPageStatus(SignUpPageStatus.SignUpError); + }); + }) }>

{ - WebsiteConfig.EVENT_START.toLocaleDateString("en", { - timeZone: WebsiteConfig.EVENT_TIMEZONE, - day: "numeric", - month: "long", - year: "numeric", - }) + WebsiteConfig.EVENT_START.toLocaleDateString("en", { + timeZone: WebsiteConfig.EVENT_TIMEZONE, + day: "numeric", + month: "long", + year: "numeric", + }) }

{t("info.locationName")}

- - - + + +
- setShowPasswords(e.target.checked)} checked={showPasswords} /> + setShowPasswords(e.target.checked)} checked={showPasswords} />
- +