feature/get-places-api #2
@ -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_PHONENUMBER = /start-challenge
|
||||||
VITE_API_AUTH_LOGIN = /login
|
VITE_API_AUTH_LOGIN = /login
|
||||||
VITE_API_AUTH_REFRESH = /refresh-token
|
VITE_API_AUTH_REFRESH = /refresh-token
|
||||||
|
VITE_API_CREATE_MEMBER = /user_place/members
|
||||||
VITE_API_PLACES = /place
|
VITE_API_PLACES = /place
|
||||||
VITE_API_USERS = /profile
|
VITE_API_USERS = /profile
|
||||||
VITE_API_USERS_ACCOUNT = /account
|
VITE_API_USERS_ACCOUNT = /account
|
||||||
|
@ -7,8 +7,8 @@ import { apiUrls } from '~/driven/utils/configs/appConfig';
|
|||||||
import { HttpOptionsType } from './protocols';
|
import { HttpOptionsType } from './protocols';
|
||||||
|
|
||||||
interface IUserTokens {
|
interface IUserTokens {
|
||||||
accessToken: string | null;
|
accessToken: string | null | undefined;
|
||||||
refreshToken: string | null;
|
refreshToken: string | null | undefined;
|
||||||
}
|
}
|
||||||
export class HTTPPovider {
|
export class HTTPPovider {
|
||||||
private userTokens: IUserTokens;
|
private userTokens: IUserTokens;
|
||||||
|
@ -32,6 +32,7 @@ export const apiUrls = {
|
|||||||
getUsers: `${baseApiUrl}${ENVs.apiGetUsers}`,
|
getUsers: `${baseApiUrl}${ENVs.apiGetUsers}`,
|
||||||
createUserAccount: `${baseApiUrl}${ENVs.apiCreateUserAccount}`,
|
createUserAccount: `${baseApiUrl}${ENVs.apiCreateUserAccount}`,
|
||||||
createUserProfile: `${baseApiUrl}${ENVs.apiCreateUserProfile}`,
|
createUserProfile: `${baseApiUrl}${ENVs.apiCreateUserProfile}`,
|
||||||
|
createMember: `${baseApiUrl}${ENVs.apiCreateMember}`,
|
||||||
},
|
},
|
||||||
generic: {
|
generic: {
|
||||||
authPhonenumber: `${ENVs.apiAuthOrigin}${ENVs.apiAuthPhonenumber}`,
|
authPhonenumber: `${ENVs.apiAuthOrigin}${ENVs.apiAuthPhonenumber}`,
|
||||||
|
@ -8,4 +8,5 @@ export const ENVs = {
|
|||||||
apiGetUsers: process.env.VITE_API_USERS,
|
apiGetUsers: process.env.VITE_API_USERS,
|
||||||
apiCreateUserAccount: process.env.VITE_API_USERS_ACCOUNT,
|
apiCreateUserAccount: process.env.VITE_API_USERS_ACCOUNT,
|
||||||
apiCreateUserProfile: process.env.VITE_API_USERS_PROFILE,
|
apiCreateUserProfile: process.env.VITE_API_USERS_PROFILE,
|
||||||
|
apiCreateMember: process.env.VITE_API_CREATE_MEMBER,
|
||||||
};
|
};
|
||||||
|
@ -22,6 +22,7 @@ export const staticMessages = {
|
|||||||
enterOtpCode: 'Enter your Otp Code',
|
enterOtpCode: 'Enter your Otp Code',
|
||||||
success: {
|
success: {
|
||||||
createUser: 'user created successfully',
|
createUser: 'user created successfully',
|
||||||
|
createMember: 'member created successfully',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
service: {
|
service: {
|
||||||
|
@ -34,9 +34,7 @@ const useCreateUserVM = (dependencies: IUseCreateUserVm): ICreateUserViewProps =
|
|||||||
await handleSubmitForm(inputsValue);
|
await handleSubmitForm(inputsValue);
|
||||||
setError({ message: staticMessages.global.success.createUser, type: 'success' });
|
setError({ message: staticMessages.global.success.createUser, type: 'success' });
|
||||||
} catch (errorExc) {
|
} catch (errorExc) {
|
||||||
console.log('herere', errorExc);
|
|
||||||
if (errorExc instanceof AxiosError) {
|
if (errorExc instanceof AxiosError) {
|
||||||
console.log('herere', errorExc);
|
|
||||||
setError({ message: errorExc.response?.data?.description, type: 'error' });
|
setError({ message: errorExc.response?.data?.description, type: 'error' });
|
||||||
} else if (errorExc instanceof Error) {
|
} else if (errorExc instanceof Error) {
|
||||||
setError({ message: errorExc.message, type: 'error' });
|
setError({ message: errorExc.message, type: 'error' });
|
||||||
|
@ -19,12 +19,18 @@ const prepareTheLogicForModel = () => {
|
|||||||
return { getingPlacesLogic, url };
|
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 { getingPlacesLogic, url } = prepareTheLogicForModel();
|
||||||
const placesModel = async () => await placesListModel(getingPlacesLogic);
|
const placesModel = async () => await placesListModel(getingPlacesLogic);
|
||||||
|
|
||||||
const useGetPlacesList = prepareStateManagementForVM<PlacesModel>(url, placesModel);
|
const useGetPlacesList = prepareStateManagementForVM<PlacesModel>(url, placesModel);
|
||||||
const { selectedRowId, setSelectedRowId, placesData } = usePlacesListVM({
|
const { placesData } = usePlacesListVM({
|
||||||
useGetPlacesList,
|
useGetPlacesList,
|
||||||
});
|
});
|
||||||
return <PlacesListView placesList={placesData} selectedRowId={selectedRowId} setSelectedRowId={setSelectedRowId} />;
|
return <PlacesListView placesList={placesData} selectedRowId={selectedRowId} setSelectedRowId={setSelectedRowId} />;
|
||||||
|
@ -19,11 +19,16 @@ const usePrepareTheLogicForModel = () => {
|
|||||||
return { getingusersLogic, url };
|
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 { getingusersLogic, url } = usePrepareTheLogicForModel();
|
||||||
const usersModel = async () => await usersListModel(getingusersLogic);
|
const usersModel = async () => await usersListModel(getingusersLogic);
|
||||||
const useGetusersList = prepareStateManagementForVM<UsersModel>(url, usersModel);
|
const useGetusersList = prepareStateManagementForVM<UsersModel>(url, usersModel);
|
||||||
const { selectedRowId, setSelectedRowId, usersData } = useUsersListVM({
|
const { usersData } = useUsersListVM({
|
||||||
useGetusersList,
|
useGetusersList,
|
||||||
});
|
});
|
||||||
return <UsersListView usersList={usersData} selectedRowId={selectedRowId} setSelectedRowId={setSelectedRowId} />;
|
return <UsersListView usersList={usersData} selectedRowId={selectedRowId} setSelectedRowId={setSelectedRowId} />;
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
import React from 'react';
|
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 { routesData } from '~/driven/utils/configs/appConfig';
|
||||||
import { icons } from '~/driven/utils/constants/assertUrls';
|
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() {
|
export default function Sidebar() {
|
||||||
const isCurrentPage = useLocation();
|
const isCurrentPage = useLocation();
|
||||||
|
const userCTX = useUser();
|
||||||
|
const navigator = useNavigate();
|
||||||
const pages = Object.keys(routesData).map((routeKey) => {
|
const pages = Object.keys(routesData).map((routeKey) => {
|
||||||
const key = routeKey as keyof typeof routesData;
|
const key = routeKey as keyof typeof routesData;
|
||||||
return (
|
return (
|
||||||
@ -27,7 +30,12 @@ export default function Sidebar() {
|
|||||||
<div className='logo'>
|
<div className='logo'>
|
||||||
<img src={icons.logo} alt='logo icon' />
|
<img src={icons.logo} alt='logo icon' />
|
||||||
</div>
|
</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>
|
</aside>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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 PrimaryButton from '~/driven/utils/components/buttons/primary-button/PrimaryButton';
|
||||||
import PageTitle from '~/driven/utils/components/page-title/pageTitle';
|
import PageTitle from '~/driven/utils/components/page-title/pageTitle';
|
||||||
|
import { apiUrls } from '~/driven/utils/configs/appConfig';
|
||||||
import { staticMessages } from '~/driven/utils/constants/staticMessages';
|
import { staticMessages } from '~/driven/utils/constants/staticMessages';
|
||||||
|
import useGetNavigatorAndTokenUpdater from '~/driven/utils/helpers/hooks/getNavigatorAndAccessTokenUpdator';
|
||||||
import PlacesList from '~/driving/application/core/places-list';
|
import PlacesList from '~/driving/application/core/places-list';
|
||||||
import UsersList from '~/driving/application/core/users-list';
|
import UsersList from '~/driving/application/core/users-list';
|
||||||
|
|
||||||
export default function index() {
|
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 (
|
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} />
|
<PageTitle className='px-4 py-5' title={staticMessages.global.users} />
|
||||||
<div className='container mx-auto px-4'>
|
<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} />
|
<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'>
|
<div className='md:grid-cols-2 gap-x-4 grid grid-cols-1 mx-auto'>
|
||||||
<UsersList />
|
<UsersList selectedRowId={selectedUserRowId} setSelectedRowId={setSelectedUserRowId} />
|
||||||
<PlacesList />
|
<PlacesList selectedRowId={selectedPlaceRowId} setSelectedRowId={setSelectedPlaceRowId} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
@ -11,7 +11,6 @@ import Sidebar from '~/driving/application/support/sidebar';
|
|||||||
*/
|
*/
|
||||||
export default function MainPageLayout() {
|
export default function MainPageLayout() {
|
||||||
const { user, setUser } = useUser();
|
const { user, setUser } = useUser();
|
||||||
console.log('hi');
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const storage = StorageService.localStorage<AdminUserModel>();
|
const storage = StorageService.localStorage<AdminUserModel>();
|
||||||
const currentUser = storage.getData(appConfig.adminUserStorageKey);
|
const currentUser = storage.getData(appConfig.adminUserStorageKey);
|
||||||
@ -22,7 +21,7 @@ export default function MainPageLayout() {
|
|||||||
return (
|
return (
|
||||||
<div className='flex flex-nowrap min-h-screen'>
|
<div className='flex flex-nowrap min-h-screen'>
|
||||||
<Sidebar />
|
<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 />
|
<Outlet />
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,7 +5,6 @@ import { useUser } from '~/driven/utils/helpers/contexts/userContext';
|
|||||||
|
|
||||||
export default function UserLoginLayout() {
|
export default function UserLoginLayout() {
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
console.log('hhhh');
|
|
||||||
if (user && user.adminUserData.accessToken) return <Navigate to={routes.usersList} replace />;
|
if (user && user.adminUserData.accessToken) return <Navigate to={routes.usersList} replace />;
|
||||||
return <Outlet />;
|
return <Outlet />;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user