From 8b0687d9458807f109acb2193abcd40dd9995f61 Mon Sep 17 00:00:00 2001 From: behnamrhp <behnamrahimpour74@gmail.com> Date: Mon, 22 May 2023 22:32:14 +0300 Subject: [PATCH] [FEAT]: log out implemented --- .env.development | 1 + .../boundaries/http-boundary/httpBoundary.ts | 4 +- src/driven/utils/configs/appConfig.ts | 1 + src/driven/utils/constants/envs.ts | 1 + src/driven/utils/constants/staticMessages.ts | 1 + .../create-user/viewmodel/CreateUserVM.ts | 2 - .../core/places-list/infra/PlacesList.tsx | 10 ++- .../core/users-list/infra/UsersList.tsx | 9 ++- .../support/sidebar/view/Sidebar.tsx | 14 ++++- src/driving/main/pages/index.tsx | 62 +++++++++++++++++-- .../main/pages/layouts/MainPageLayout.tsx | 3 +- .../main/pages/layouts/UserLoginLayout.tsx | 1 - 12 files changed, 90 insertions(+), 19 deletions(-) diff --git a/.env.development b/.env.development index ff1bac7..233e901 100644 --- a/.env.development +++ b/.env.development @@ -3,6 +3,7 @@ VITE_API_AUTH_ORIGIN = https://auth.dev.dipal.ru/api/v1/auth VITE_API_AUTH_PHONENUMBER = /start-challenge VITE_API_AUTH_LOGIN = /login VITE_API_AUTH_REFRESH = /refresh-token +VITE_API_CREATE_MEMBER = /user_place/members VITE_API_PLACES = /place VITE_API_USERS = /profile VITE_API_USERS_ACCOUNT = /account diff --git a/src/driven/boundaries/http-boundary/httpBoundary.ts b/src/driven/boundaries/http-boundary/httpBoundary.ts index 47a236c..3f65647 100644 --- a/src/driven/boundaries/http-boundary/httpBoundary.ts +++ b/src/driven/boundaries/http-boundary/httpBoundary.ts @@ -7,8 +7,8 @@ import { apiUrls } from '~/driven/utils/configs/appConfig'; import { HttpOptionsType } from './protocols'; interface IUserTokens { - accessToken: string | null; - refreshToken: string | null; + accessToken: string | null | undefined; + refreshToken: string | null | undefined; } export class HTTPPovider { private userTokens: IUserTokens; diff --git a/src/driven/utils/configs/appConfig.ts b/src/driven/utils/configs/appConfig.ts index 2b4d4f8..93bd570 100644 --- a/src/driven/utils/configs/appConfig.ts +++ b/src/driven/utils/configs/appConfig.ts @@ -32,6 +32,7 @@ export const apiUrls = { getUsers: `${baseApiUrl}${ENVs.apiGetUsers}`, createUserAccount: `${baseApiUrl}${ENVs.apiCreateUserAccount}`, createUserProfile: `${baseApiUrl}${ENVs.apiCreateUserProfile}`, + createMember: `${baseApiUrl}${ENVs.apiCreateMember}`, }, generic: { authPhonenumber: `${ENVs.apiAuthOrigin}${ENVs.apiAuthPhonenumber}`, diff --git a/src/driven/utils/constants/envs.ts b/src/driven/utils/constants/envs.ts index e347844..102978c 100644 --- a/src/driven/utils/constants/envs.ts +++ b/src/driven/utils/constants/envs.ts @@ -8,4 +8,5 @@ export const ENVs = { apiGetUsers: process.env.VITE_API_USERS, apiCreateUserAccount: process.env.VITE_API_USERS_ACCOUNT, apiCreateUserProfile: process.env.VITE_API_USERS_PROFILE, + apiCreateMember: process.env.VITE_API_CREATE_MEMBER, }; diff --git a/src/driven/utils/constants/staticMessages.ts b/src/driven/utils/constants/staticMessages.ts index c841036..3acc2a0 100644 --- a/src/driven/utils/constants/staticMessages.ts +++ b/src/driven/utils/constants/staticMessages.ts @@ -22,6 +22,7 @@ export const staticMessages = { enterOtpCode: 'Enter your Otp Code', success: { createUser: 'user created successfully', + createMember: 'member created successfully', }, }, service: { diff --git a/src/driving/application/core/create-user/viewmodel/CreateUserVM.ts b/src/driving/application/core/create-user/viewmodel/CreateUserVM.ts index 2fd76be..f2e7785 100644 --- a/src/driving/application/core/create-user/viewmodel/CreateUserVM.ts +++ b/src/driving/application/core/create-user/viewmodel/CreateUserVM.ts @@ -34,9 +34,7 @@ const useCreateUserVM = (dependencies: IUseCreateUserVm): ICreateUserViewProps = await handleSubmitForm(inputsValue); setError({ message: staticMessages.global.success.createUser, type: 'success' }); } catch (errorExc) { - console.log('herere', errorExc); if (errorExc instanceof AxiosError) { - console.log('herere', errorExc); setError({ message: errorExc.response?.data?.description, type: 'error' }); } else if (errorExc instanceof Error) { setError({ message: errorExc.message, type: 'error' }); diff --git a/src/driving/application/core/places-list/infra/PlacesList.tsx b/src/driving/application/core/places-list/infra/PlacesList.tsx index 3b46a98..b3d0422 100644 --- a/src/driving/application/core/places-list/infra/PlacesList.tsx +++ b/src/driving/application/core/places-list/infra/PlacesList.tsx @@ -19,12 +19,18 @@ const prepareTheLogicForModel = () => { return { getingPlacesLogic, url }; }; -export default function PlacessList() { +export interface IPlacesListProps { + selectedRowId: string; + setSelectedRowId: React.Dispatch<React.SetStateAction<string>>; +} + +export default function PlacessList(props: IPlacesListProps) { + const { selectedRowId, setSelectedRowId } = props; const { getingPlacesLogic, url } = prepareTheLogicForModel(); const placesModel = async () => await placesListModel(getingPlacesLogic); const useGetPlacesList = prepareStateManagementForVM<PlacesModel>(url, placesModel); - const { selectedRowId, setSelectedRowId, placesData } = usePlacesListVM({ + const { placesData } = usePlacesListVM({ useGetPlacesList, }); return <PlacesListView placesList={placesData} selectedRowId={selectedRowId} setSelectedRowId={setSelectedRowId} />; diff --git a/src/driving/application/core/users-list/infra/UsersList.tsx b/src/driving/application/core/users-list/infra/UsersList.tsx index 669731f..5b71f59 100644 --- a/src/driving/application/core/users-list/infra/UsersList.tsx +++ b/src/driving/application/core/users-list/infra/UsersList.tsx @@ -19,11 +19,16 @@ const usePrepareTheLogicForModel = () => { return { getingusersLogic, url }; }; -export default function UsersList() { +export interface IUsersListProps { + selectedRowId: string; + setSelectedRowId: React.Dispatch<React.SetStateAction<string>>; +} +export default function UsersList(props: IUsersListProps) { + const { selectedRowId, setSelectedRowId } = props; const { getingusersLogic, url } = usePrepareTheLogicForModel(); const usersModel = async () => await usersListModel(getingusersLogic); const useGetusersList = prepareStateManagementForVM<UsersModel>(url, usersModel); - const { selectedRowId, setSelectedRowId, usersData } = useUsersListVM({ + const { usersData } = useUsersListVM({ useGetusersList, }); return <UsersListView usersList={usersData} selectedRowId={selectedRowId} setSelectedRowId={setSelectedRowId} />; diff --git a/src/driving/application/support/sidebar/view/Sidebar.tsx b/src/driving/application/support/sidebar/view/Sidebar.tsx index 726c54e..f3af15d 100644 --- a/src/driving/application/support/sidebar/view/Sidebar.tsx +++ b/src/driving/application/support/sidebar/view/Sidebar.tsx @@ -1,11 +1,14 @@ import React from 'react'; -import { Link, useLocation } from 'react-router-dom'; +import { Link, useLocation, useNavigate } from 'react-router-dom'; import { routesData } from '~/driven/utils/configs/appConfig'; import { icons } from '~/driven/utils/constants/assertUrls'; +import { useUser } from '~/driven/utils/helpers/contexts/userContext'; +import { navigateToAuth } from '~/driven/utils/helpers/globalHelpers'; export default function Sidebar() { const isCurrentPage = useLocation(); - + const userCTX = useUser(); + const navigator = useNavigate(); const pages = Object.keys(routesData).map((routeKey) => { const key = routeKey as keyof typeof routesData; return ( @@ -27,7 +30,12 @@ export default function Sidebar() { <div className='logo'> <img src={icons.logo} alt='logo icon' /> </div> - <div className='mt-14 flex flex-col items-baseline'>{pages}</div> + <div className='mt-14 flex flex-col items-baseline'> + {pages} + <div className='mt-auto text-white px-3 absolute bottom-5'> + <button onClick={() => navigateToAuth(userCTX, navigator)}>Log out</button> + </div> + </div> </aside> ); } diff --git a/src/driving/main/pages/index.tsx b/src/driving/main/pages/index.tsx index a0baa8e..2d51079 100644 --- a/src/driving/main/pages/index.tsx +++ b/src/driving/main/pages/index.tsx @@ -1,21 +1,73 @@ -import React from 'react'; +import { AxiosError } from 'axios'; +import React, { useState } from 'react'; +import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary'; +import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols'; +import Notification from '~/driven/utils/components/Notification/Notification'; import PrimaryButton from '~/driven/utils/components/buttons/primary-button/PrimaryButton'; import PageTitle from '~/driven/utils/components/page-title/pageTitle'; +import { apiUrls } from '~/driven/utils/configs/appConfig'; import { staticMessages } from '~/driven/utils/constants/staticMessages'; +import useGetNavigatorAndTokenUpdater from '~/driven/utils/helpers/hooks/getNavigatorAndAccessTokenUpdator'; import PlacesList from '~/driving/application/core/places-list'; import UsersList from '~/driving/application/core/users-list'; export default function index() { + const [selectedUserRowId, setSelectedUserRowId] = useState<string>(''); + const [selectedPlaceRowId, setSelectedPlaceRowId] = useState<string>(''); + const { accessTokenUpdateHandler, notLoginAuth, userData } = useGetNavigatorAndTokenUpdater(); + const [error, setError] = useState<{ message: string; type: 'error' | 'success' }>({ message: '', type: 'error' }); + + const onSubmitMember = async (e: React.FormEvent) => { + e.preventDefault(); + try { + const url = apiUrls.core.createMember; + const data = { + place_id: selectedPlaceRowId, + account_id: selectedUserRowId, + }; + + const options: HttpOptionsType = { + url, + data, + headers: { + 'Content-Type': 'application/json', + }, + method: 'POST', + }; + + const userTokens = { + accessToken: userData.user?.adminUserData.accessToken || null, + refreshToken: userData.user?.adminUserData.refreshToken || null, + }; + const httpProvider = new HTTPPovider(userTokens, accessTokenUpdateHandler, notLoginAuth); + + await httpProvider.request(options); + setError({ message: staticMessages.global.success.createMember, type: 'success' }); + } catch (errorExc) { + if (errorExc instanceof AxiosError) { + setError({ message: errorExc.response?.data?.description, type: 'error' }); + } else if (errorExc instanceof Error) { + setError({ message: errorExc.message, type: 'error' }); + } + } + }; return ( <> + {Boolean(error.message) && ( + <Notification + message={error.message} + type={error.type} + onCloseCallback={() => setError({ message: '', type: 'error' })} + /> + )} <PageTitle className='px-4 py-5' title={staticMessages.global.users} /> <div className='container mx-auto px-4'> - <div className='w-full flex flex-row-reverse items-center py-2 sticky top-0'> + <form onSubmit={onSubmitMember} className='w-full flex flex-row-reverse items-center py-2 sticky top-0'> <PrimaryButton className='text-sm' title={staticMessages.global.submit} onClick={() => null} /> - </div> + </form> <div className='md:grid-cols-2 gap-x-4 grid grid-cols-1 mx-auto'> - <UsersList /> - <PlacesList /> + <UsersList selectedRowId={selectedUserRowId} setSelectedRowId={setSelectedUserRowId} /> + <PlacesList selectedRowId={selectedPlaceRowId} setSelectedRowId={setSelectedPlaceRowId} /> </div> </div> </> diff --git a/src/driving/main/pages/layouts/MainPageLayout.tsx b/src/driving/main/pages/layouts/MainPageLayout.tsx index bc004c9..9447647 100644 --- a/src/driving/main/pages/layouts/MainPageLayout.tsx +++ b/src/driving/main/pages/layouts/MainPageLayout.tsx @@ -11,7 +11,6 @@ import Sidebar from '~/driving/application/support/sidebar'; */ export default function MainPageLayout() { const { user, setUser } = useUser(); - console.log('hi'); useEffect(() => { const storage = StorageService.localStorage<AdminUserModel>(); const currentUser = storage.getData(appConfig.adminUserStorageKey); @@ -22,7 +21,7 @@ export default function MainPageLayout() { return ( <div className='flex flex-nowrap min-h-screen'> <Sidebar /> - <main className='dipal-panel w-full text-black bg-white h-fit'> + <main className='dipal-panel w-full text-black bg-white h-screen overflow-auto'> <Outlet /> </main> </div> diff --git a/src/driving/main/pages/layouts/UserLoginLayout.tsx b/src/driving/main/pages/layouts/UserLoginLayout.tsx index 33683f2..dfeee28 100644 --- a/src/driving/main/pages/layouts/UserLoginLayout.tsx +++ b/src/driving/main/pages/layouts/UserLoginLayout.tsx @@ -5,7 +5,6 @@ import { useUser } from '~/driven/utils/helpers/contexts/userContext'; export default function UserLoginLayout() { const { user } = useUser(); - console.log('hhhh'); if (user && user.adminUserData.accessToken) return <Navigate to={routes.usersList} replace />; return <Outlet />; }