feature/get-places-api #2

Merged
behnam merged 26 commits from feature/get-places-api into develop 2023-05-23 09:23:56 +00:00
12 changed files with 90 additions and 19 deletions
Showing only changes of commit 8b0687d945 - Show all commits

View File

@ -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

View File

@ -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;

View File

@ -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}`,

View File

@ -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,
};

View File

@ -22,6 +22,7 @@ export const staticMessages = {
enterOtpCode: 'Enter your Otp Code',
success: {
createUser: 'user created successfully',
createMember: 'member created successfully',
},
},
service: {

View File

@ -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' });

View File

@ -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} />;

View File

@ -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} />;

View File

@ -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>
);
}

View File

@ -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>
</>

View File

@ -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>

View File

@ -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 />;
}