From 343547bfe48470c5739457b3cd19c55ca202e414 Mon Sep 17 00:00:00 2001 From: MarioBatalha Date: Mon, 31 Mar 2025 01:37:40 +0100 Subject: [PATCH 1/8] =?UTF-8?q?=E2=9C=A8=20feat:=20sign=20in=20call=20endp?= =?UTF-8?q?oint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- constants/global.ts | 2 + views/sign-in/sign-in-button.tsx | 133 ++++++++++++++++++------------- 2 files changed, 78 insertions(+), 57 deletions(-) create mode 100644 constants/global.ts diff --git a/constants/global.ts b/constants/global.ts new file mode 100644 index 0000000..267d2fb --- /dev/null +++ b/constants/global.ts @@ -0,0 +1,2 @@ +export const BASE_URL = + 'https://apiauthmemezfun-staging.up.railway.app/api/v1/auth/'; diff --git a/views/sign-in/sign-in-button.tsx b/views/sign-in/sign-in-button.tsx index 1a0219c..f383248 100644 --- a/views/sign-in/sign-in-button.tsx +++ b/views/sign-in/sign-in-button.tsx @@ -1,18 +1,22 @@ import { Button, Div } from '@stylin.js/elements'; +import { useRouter } from 'next/router'; import { FC } from 'react'; import { useFormContext } from 'react-hook-form'; import DialogCountdown from '@/components/dialog/dialog-countdown'; import { LoaderSVG } from '@/components/svg'; import { useConnectModal } from '@/components/wallet-button/wallet-button.hook'; +import { RoutesEnum } from '@/constants'; +import { BASE_URL } from '@/constants/global'; import { useDialog } from '@/hooks/use-dialog'; import { SignInFormProps } from './sign-in.types'; const SignInButton: FC = () => { - const { setValue, trigger } = useFormContext(); + const { setValue, trigger, getValues } = useFormContext(); const { dialog, handleClose } = useDialog(); const handleOpenConnectModal = useConnectModal(); + const { push } = useRouter(); const handleCreateProfile = () => { return new Promise((resolve, reject) => { @@ -34,65 +38,80 @@ const SignInButton: FC = () => { fieldsToValidate = ['username', 'password']; const isValid = await trigger(fieldsToValidate); - if (isValid) { - await dialog.promise(handleCreateProfile(), { - success: () => ({ - title: 'Sign-in successful', - button: ( - - ), - ghostButton: ( - - ), - message: 'Now connect your wallet do see all the function', - }), - loading: () => ({ - Icon: , - title: 'Signing...', - message: 'Please wait...', - }), - error: (e) => ({ - title: 'Oops! You can not sign in!', - button: { label: 'Try again', onClick: handleClose }, - message: ( - e.message || - 'Make sure you fill every field correctly and try again.' - ).replace('Invariant failed: ', ''), - ghostButton: { - label: 'Do not want to try again!', - onClick: handleClose, - }, + try { + fetch(`${BASE_URL}/sign-in`, { + method: 'POST', + body: JSON.stringify({ + username: `${getValues('username')}`, + password: `${getValues('password')}`, }), + }).then((res) => { + if (res.ok) { + if (isValid) { + dialog.promise(handleCreateProfile(), { + success: () => ({ + title: 'Sign-in successful', + button: ( + + ), + ghostButton: ( + + ), + message: 'Now connect your wallet do see all the function', + }), + loading: () => ({ + Icon: , + title: 'Signing...', + message: 'Please wait...', + }), + error: (e) => ({ + title: 'Oops! You can not sign in!', + button: { label: 'Try again', onClick: handleClose }, + message: ( + e.message || + 'Make sure you fill every field correctly and try again.' + ).replace('Invariant failed: ', ''), + ghostButton: { + label: 'Do not want to try again!', + onClick: handleClose, + }, + }), + }); + } + push(RoutesEnum.Profile); + } + if (!isValid) return; }); + } catch (error) { + console.error('Error _> ', error); } - if (!isValid) return; }; return ( From 9b29747ab5582d63ce654f4b94e20bbc9eb18733 Mon Sep 17 00:00:00 2001 From: MarioBatalha Date: Mon, 31 Mar 2025 20:48:00 +0100 Subject: [PATCH 2/8] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20sign=20in?= =?UTF-8?q?=20call=20endpoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 3 +- components/profile/menu-list.tsx | 13 +- constants/global.ts | 2 +- views/sign-in/sign-in-button.tsx | 190 ++++++++++++++------------- views/sign-in/sign-in-validations.ts | 2 +- 5 files changed, 117 insertions(+), 93 deletions(-) diff --git a/.env b/.env index 572274e..7498483 100644 --- a/.env +++ b/.env @@ -1 +1,2 @@ -NEXT_PUBLIC_NETWORK=testnet \ No newline at end of file +NEXT_PUBLIC_NETWORK=testnet +BASE_URL=https://apiauthmemezfun-staging.up.railway.app/api/v1/auth \ No newline at end of file diff --git a/components/profile/menu-list.tsx b/components/profile/menu-list.tsx index 7798888..51b0492 100644 --- a/components/profile/menu-list.tsx +++ b/components/profile/menu-list.tsx @@ -1,8 +1,12 @@ import { useDisconnectWallet } from '@mysten/dapp-kit'; import { Div } from '@stylin.js/elements'; +import { useRouter } from 'next/router'; import { not } from 'ramda'; import { FC, useState } from 'react'; +import { RoutesEnum } from '@/constants'; +import { BASE_URL } from '@/constants/global'; + import { DocIDSVG, ExplorerSVG, @@ -23,6 +27,13 @@ const MenuList: FC = () => { const [isAccountMenuOpen, setIsAccountMenuOpen] = useState(false); const [isExplorerMenuOpen, setIsExplorerMenuOpen] = useState(false); const { mutate: disconnectWallet } = useDisconnectWallet(); + const { push } = useRouter(); + + const handleDisconnectWallet = () => { + disconnectWallet(); + fetch(`${BASE_URL}/sign-out`).then((res) => res.json()); + push(RoutesEnum.Home); + }; return (
@@ -58,7 +69,7 @@ const MenuList: FC = () => { Icon={LogoutSVG} title="Disconnect" color="#E85965" - onClick={() => disconnectWallet()} + onClick={handleDisconnectWallet} />
); diff --git a/constants/global.ts b/constants/global.ts index 267d2fb..09eca03 100644 --- a/constants/global.ts +++ b/constants/global.ts @@ -1,2 +1,2 @@ export const BASE_URL = - 'https://apiauthmemezfun-staging.up.railway.app/api/v1/auth/'; + 'https://apiauthmemezfun-staging.up.railway.app/api/v1/auth'; diff --git a/views/sign-in/sign-in-button.tsx b/views/sign-in/sign-in-button.tsx index f383248..7bf93c7 100644 --- a/views/sign-in/sign-in-button.tsx +++ b/views/sign-in/sign-in-button.tsx @@ -1,6 +1,6 @@ -import { Button, Div } from '@stylin.js/elements'; +import { Button, Div, P } from '@stylin.js/elements'; import { useRouter } from 'next/router'; -import { FC } from 'react'; +import { FC, useState } from 'react'; import { useFormContext } from 'react-hook-form'; import DialogCountdown from '@/components/dialog/dialog-countdown'; @@ -13,109 +13,121 @@ import { useDialog } from '@/hooks/use-dialog'; import { SignInFormProps } from './sign-in.types'; const SignInButton: FC = () => { - const { setValue, trigger, getValues } = useFormContext(); + const [isError, setIsError] = useState({ status: false, message: '' }); + const { trigger, getValues } = useFormContext(); const { dialog, handleClose } = useDialog(); const handleOpenConnectModal = useConnectModal(); const { push } = useRouter(); - const handleCreateProfile = () => { - return new Promise((resolve, reject) => { - setTimeout(() => { - const isSuccess = Math.random() > 0.5; - if (isSuccess) { - setValue('success', true); - resolve('success'); - return; - } - reject('Error'); - }, 1000); - }); - }; - - const handleSignIn = async () => { + const handleCreateProfile = async () => { let fieldsToValidate: (keyof SignInFormProps)[] = []; fieldsToValidate = ['username', 'password']; const isValid = await trigger(fieldsToValidate); + const username = getValues('username'); + const password = getValues('password'); + + console.log('Base URL _>', BASE_URL); try { - fetch(`${BASE_URL}/sign-in`, { - method: 'POST', - body: JSON.stringify({ - username: `${getValues('username')}`, - password: `${getValues('password')}`, - }), - }).then((res) => { - if (res.ok) { - if (isValid) { - dialog.promise(handleCreateProfile(), { - success: () => ({ - title: 'Sign-in successful', - button: ( - - ), - ghostButton: ( - - ), - message: 'Now connect your wallet do see all the function', - }), - loading: () => ({ - Icon: , - title: 'Signing...', - message: 'Please wait...', - }), - error: (e) => ({ - title: 'Oops! You can not sign in!', - button: { label: 'Try again', onClick: handleClose }, - message: ( - e.message || - 'Make sure you fill every field correctly and try again.' - ).replace('Invariant failed: ', ''), - ghostButton: { - label: 'Do not want to try again!', - onClick: handleClose, - }, - }), - }); + const requestBody = { + username, + password, + }; + if (isValid) { + fetch(`${BASE_URL}/sign-in`, { + method: 'POST', + mode: 'cors', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(requestBody), + }).then((res) => { + console.log('Res _> ', res); + if (res.ok) { + push(RoutesEnum.Profile); } - push(RoutesEnum.Profile); - } - if (!isValid) return; - }); + }); + } + if (!isValid) return; } catch (error) { - console.error('Error _> ', error); + setIsError({ status: true, message: 'User does not exist' }); + console.log('Error _> ', error); } }; + const handleSignIn = async () => { + dialog.promise(handleCreateProfile(), { + success: () => ({ + title: 'Sign-in successful', + button: ( + + ), + ghostButton: ( + + ), + message: 'Now connect your wallet do see all the function', + }), + loading: () => ({ + Icon: , + title: 'Signing...', + message: 'Please wait...', + }), + error: (e) => ({ + title: 'Oops! You can not sign in!', + button: { label: 'Try again', onClick: handleClose }, + message: ( + e.message || 'Make sure you fill every field correctly and try again.' + ).replace('Invariant failed: ', ''), + ghostButton: { + label: 'Do not want to try again!', + onClick: handleClose, + }, + }), + }); + }; + return ( -
+
+ {isError.status && ( +

+ {isError.message} +

+ )}
- - +
+ + +
{ - const [isError, setIsError] = useState({ status: false, message: '' }); - const { trigger, getValues } = useFormContext(); + const { set: setCookie } = useCookie(MEMEZ_FUN_TOKEN_AUTH); + const { getValues, handleSubmit } = useFormContext(); const { dialog, handleClose } = useDialog(); const handleOpenConnectModal = useConnectModal(); - const { push } = useRouter(); const handleCreateProfile = async () => { - let fieldsToValidate: (keyof SignInFormProps)[] = []; - - fieldsToValidate = ['username', 'password']; - const isValid = await trigger(fieldsToValidate); - const username = getValues('username'); - const password = getValues('password'); - - try { - const requestBody = { - username, - password, - }; - if (isValid) { - fetch(`${BASE_URL}/sign-in`, { - method: 'POST', - mode: 'cors', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(requestBody), - }).then((res) => { - if (res.ok) { - push(RoutesEnum.Profile); - } - }); + const { username, password } = getValues(); + const body = JSON.stringify({ + username, + password, + }); + return await fetch(`${process.env.NEXT_PUBLIC_AUTH_URL}/sign-in`, { + method: 'POST', + mode: 'cors', + headers: { + 'Content-Type': 'application/json', + }, + body, + }).then(async (res) => { + const response = await res.json(); + if (!res.ok) { + throw new Error(`${response.error}: ${response.message}`); } - if (!isValid) return; - } catch (error) { - setIsError({ status: true, message: 'User does not exist' }); - console.log('Error _> ', error); - } + setCookie(response.accessToken); + return; + }); }; - const handleSignIn = async () => { + const handleSignIn = () => { dialog.promise(handleCreateProfile(), { success: () => ({ title: 'Sign-in successful', @@ -120,11 +107,6 @@ const SignInButton: FC = () => { flexDirection="column" justifyContent="center" > - {isError.status && ( -

- {isError.message} -

- )}