feature/create-place #8
@ -0,0 +1,45 @@
|
||||
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
|
||||
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
||||
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
|
||||
import { apiUrls } from '~/driven/utils/configs/appConfig';
|
||||
import {
|
||||
ICreatePlaceLogicMaker,
|
||||
createPlaceArguments,
|
||||
} from '~/driving/application/core/places/create-place/model/submiCreatePlace';
|
||||
|
||||
const createPlacesDto = (newPlace: createPlaceArguments) => ({
|
||||
place_type: newPlace.placeType,
|
||||
parent_id: newPlace.parentId || null,
|
||||
name: newPlace.placeName,
|
||||
});
|
||||
|
||||
const createPlaceAdapter = (
|
||||
userAdmin: AdminUserModel | null,
|
||||
updateAccessToken: (newAccessToken: string) => void,
|
||||
navigateToAuth: () => void,
|
||||
): ICreatePlaceLogicMaker => {
|
||||
const url = apiUrls.core.createPlace;
|
||||
const httpHandler = async (newPlace: createPlaceArguments) => {
|
||||
const httpProvider = new HTTPPovider(
|
||||
{
|
||||
accessToken: (userAdmin && userAdmin?.adminUserData.accessToken) || null,
|
||||
refreshToken: (userAdmin && userAdmin?.adminUserData.refreshToken) || null,
|
||||
},
|
||||
updateAccessToken,
|
||||
navigateToAuth,
|
||||
);
|
||||
const dto = createPlacesDto(newPlace);
|
||||
const options: HttpOptionsType = {
|
||||
url,
|
||||
method: 'POST',
|
||||
data: dto,
|
||||
};
|
||||
|
||||
return await httpProvider.request<string>(options);
|
||||
};
|
||||
return {
|
||||
httpHandler,
|
||||
};
|
||||
};
|
||||
|
||||
export default createPlaceAdapter;
|
@ -46,7 +46,6 @@ export class HTTPPovider {
|
||||
async request<R>(customOptions: HttpOptionsType) {
|
||||
const axiosInstance = this.handleRequestInterceptor();
|
||||
this.responseIncepter(axiosInstance);
|
||||
|
||||
const response = await axiosInstance<ApiGlobalResponseObject<R>>(customOptions);
|
||||
if (!response) throw new Error(staticMessages.service.errors[500]);
|
||||
|
||||
|
@ -40,6 +40,7 @@ export const apiUrls = {
|
||||
createUserAccount: `${baseApiUrl}${ENVs.apiCreateUserAccount}`,
|
||||
createUserProfile: `${baseApiUrl}${ENVs.apiCreateUserProfile}`,
|
||||
createMember: `${baseApiUrl}${ENVs.apiCreateMember}`,
|
||||
createPlace: `${baseApiUrl}${ENVs.apiCreatePlace}`,
|
||||
},
|
||||
generic: {
|
||||
authPhonenumber: `${ENVs.apiAuthOrigin}${ENVs.apiAuthPhonenumber}`,
|
||||
|
@ -10,4 +10,5 @@ export const ENVs = {
|
||||
apiQr: process.env.VITE_API_QR,
|
||||
apiCreateUserProfile: process.env.VITE_API_USERS_PROFILE,
|
||||
apiCreateMember: process.env.VITE_API_CREATE_MEMBER,
|
||||
apiCreatePlace: process.env.VITE_API_PLACES,
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ export const staticMessages = {
|
||||
input: 'please fill all inputs correctly',
|
||||
phonenumber: 'please fill the valid number',
|
||||
otp: 'please fill the otp fields correctly',
|
||||
inputPlace: 'place type and name of place is necessary',
|
||||
},
|
||||
users: 'Users',
|
||||
submit: 'Submit',
|
||||
@ -26,6 +27,7 @@ export const staticMessages = {
|
||||
success: {
|
||||
createUser: 'user created successfully',
|
||||
createMember: 'member created successfully',
|
||||
createPlace: 'place created successfully',
|
||||
},
|
||||
and: 'and',
|
||||
canUseFor: 'can use for',
|
||||
@ -47,7 +49,7 @@ export const staticMessages = {
|
||||
},
|
||||
service: {
|
||||
errors: {
|
||||
500: 'server not respond please try again later!',
|
||||
500: 'there is a problem with connecting to the server please try again later!',
|
||||
401: 'Authentication error!',
|
||||
},
|
||||
},
|
||||
|
@ -1,15 +1,23 @@
|
||||
import React from 'react';
|
||||
import createPlaceAdapter from '~/driven/adapters/create-place-adapter/createPlaceAdapter';
|
||||
import useGetNavigatorAndTokenUpdater from '~/driven/utils/helpers/hooks/getNavigatorAndAccessTokenUpdator';
|
||||
import CreatePlaceView from '../view/CreatePlaceView';
|
||||
import useCreatePlaceVm from '../viewmodel/createPlaceVM';
|
||||
import createPlaceModel from '../model/createPlaceModel';
|
||||
|
||||
export default function CreatePlace() {
|
||||
const { inputOptions } = createPlaceModel();
|
||||
const { formStateData, inputStateHandlers, selectBoxOptions } = useCreatePlaceVm({
|
||||
const { accessTokenUpdateHandler, notLoginAuth, userData } = useGetNavigatorAndTokenUpdater();
|
||||
const { user } = userData;
|
||||
|
||||
const createPlaceDrivenAdapter = createPlaceAdapter(user, accessTokenUpdateHandler, notLoginAuth);
|
||||
const { inputOptions, createPlace } = createPlaceModel(createPlaceDrivenAdapter);
|
||||
const { formStateData, inputStateHandlers, selectBoxOptions, handleSubmitCreatePlaceForm } = useCreatePlaceVm({
|
||||
getInputOptions: inputOptions,
|
||||
createPlaceModel: createPlace,
|
||||
});
|
||||
return (
|
||||
<CreatePlaceView
|
||||
handleSubmitCreatePlaceForm={handleSubmitCreatePlaceForm}
|
||||
inputOptions={{
|
||||
parentId: selectBoxOptions.parentIdsOptions,
|
||||
placeType: selectBoxOptions.placeTypesOptions,
|
||||
|
@ -1,9 +1,15 @@
|
||||
import { CreatePlaceType } from './protocols';
|
||||
import getValidOptionsOfSelectBox from './getValidOptionsOfSelectBox';
|
||||
import createPlaceLogicMaker, { ICreatePlaceLogicMaker } from './submiCreatePlace';
|
||||
|
||||
const createPlaceModel = (): CreatePlaceType => {
|
||||
type ICreatePlaceModel = ICreatePlaceLogicMaker;
|
||||
|
||||
const createPlaceModel = (depenedencies: ICreatePlaceModel): CreatePlaceType => {
|
||||
const { getPlacesTypeOptionsOfSelectBox, getValidParentIdsOptionsOfSelectBox } = getValidOptionsOfSelectBox;
|
||||
|
||||
const { createPlace } = createPlaceLogicMaker(depenedencies);
|
||||
return {
|
||||
createPlace,
|
||||
inputOptions: {
|
||||
getPlaceType: getPlacesTypeOptionsOfSelectBox,
|
||||
getParentIds: getValidParentIdsOptionsOfSelectBox,
|
||||
|
@ -0,0 +1,3 @@
|
||||
import createPlaceModel from './createPlaceModel';
|
||||
|
||||
export default createPlaceModel;
|
@ -1,7 +1,9 @@
|
||||
import PlacesModel from '~/business-logic/core/places/common/model/placesModel';
|
||||
import { placeTypes } from '../view/protocol';
|
||||
import { createPlaceArguments } from './submiCreatePlace';
|
||||
|
||||
export type CreatePlaceType = {
|
||||
createPlace: (placeData: createPlaceArguments) => Promise<string>;
|
||||
inputOptions: {
|
||||
getPlaceType: () => {
|
||||
value: placeTypes;
|
||||
|
@ -0,0 +1,24 @@
|
||||
import { placeTypes } from '../view/protocol';
|
||||
|
||||
export type createPlaceArguments = {
|
||||
placeType: `${placeTypes}`;
|
||||
placeName: string;
|
||||
parentId: string;
|
||||
};
|
||||
|
||||
export interface ICreatePlaceLogicMaker {
|
||||
httpHandler: (placeData: createPlaceArguments) => Promise<string>;
|
||||
}
|
||||
|
||||
const createPlaceLogicMaker = (depenedencies: ICreatePlaceLogicMaker) => {
|
||||
const { httpHandler } = depenedencies;
|
||||
|
||||
const createPlace = async (placeData: createPlaceArguments) => {
|
||||
return await httpHandler(placeData);
|
||||
};
|
||||
return {
|
||||
createPlace,
|
||||
};
|
||||
};
|
||||
|
||||
export default createPlaceLogicMaker;
|
@ -3,14 +3,23 @@ import SimpleInput from '~/driven/utils/components/inputs/simple-input/SimpleInp
|
||||
import InputBox from '~/driven/utils/components/inputs/select-box/InputBox';
|
||||
import { staticMessages } from '~/driven/utils/constants/staticMessages';
|
||||
import PrimaryButton from '~/driven/utils/components/buttons/primary-button/PrimaryButton';
|
||||
import Notification from '~/driven/utils/components/Notification/Notification';
|
||||
import { ICreatePlaceProps } from './protocol';
|
||||
|
||||
export default function CreatePlaceView(props: ICreatePlaceProps) {
|
||||
const { formStateData, inputStateHandlers, inputOptions } = props;
|
||||
const { formState } = formStateData;
|
||||
const { formStateData, inputStateHandlers, inputOptions, handleSubmitCreatePlaceForm } = props;
|
||||
const { formState, error, setError } = formStateData;
|
||||
|
||||
return (
|
||||
<form className='p-4 py-6 flex flex-wrap w-full gap-4'>
|
||||
<>
|
||||
{Boolean(error.message) && (
|
||||
<Notification
|
||||
message={error.message}
|
||||
type={error.type}
|
||||
onCloseCallback={() => setError({ message: '', type: 'error' })}
|
||||
/>
|
||||
)}
|
||||
<form onSubmit={handleSubmitCreatePlaceForm} className='p-4 py-6 flex flex-wrap w-full gap-4'>
|
||||
<SimpleInput
|
||||
inputData={{
|
||||
name: staticMessages.global.PlaceName,
|
||||
@ -47,5 +56,6 @@ export default function CreatePlaceView(props: ICreatePlaceProps) {
|
||||
<PrimaryButton onClick={() => null} title={staticMessages.global.submit} />
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -19,8 +19,19 @@ export type PlaceFormState = {
|
||||
};
|
||||
|
||||
export interface ICreatePlaceProps {
|
||||
handleSubmitCreatePlaceForm: (e: React.FormEvent) => Promise<void>;
|
||||
formStateData: {
|
||||
formState: PlaceFormState;
|
||||
error: {
|
||||
message: string;
|
||||
type: 'error' | 'success';
|
||||
};
|
||||
setError: React.Dispatch<
|
||||
React.SetStateAction<{
|
||||
message: string;
|
||||
type: 'error' | 'success';
|
||||
}>
|
||||
>;
|
||||
setFormState: React.Dispatch<React.SetStateAction<PlaceFormState>>;
|
||||
};
|
||||
inputStateHandlers: {
|
||||
|
@ -1,6 +1,9 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { AxiosError } from 'axios';
|
||||
import { staticMessages } from '~/driven/utils/constants/staticMessages';
|
||||
import useGetPlaceList from '../../common/hooks/useGetPlaceList';
|
||||
import { PlaceFormState, placeTypes } from '../view/protocol';
|
||||
import { createPlaceArguments } from '../model/submiCreatePlace';
|
||||
import { ICreatePlaceVm, initialPlaceFormState } from './protocols';
|
||||
|
||||
const onChangeInputStateHandlers = (setFormState: React.Dispatch<React.SetStateAction<PlaceFormState>>) => {
|
||||
@ -25,15 +28,41 @@ const resetParentIdOnChangePlaceType = (setFormState: React.Dispatch<React.SetSt
|
||||
};
|
||||
|
||||
const useCreatePlaceVm = (dependencies: ICreatePlaceVm) => {
|
||||
const { getInputOptions } = dependencies;
|
||||
const { getInputOptions, createPlaceModel } = dependencies;
|
||||
const { getParentIds, getPlaceType } = getInputOptions;
|
||||
const [formState, setFormState] = useState<PlaceFormState>(initialPlaceFormState);
|
||||
const [error, setError] = useState<{ message: string; type: 'error' | 'success' }>({ message: '', type: 'error' });
|
||||
|
||||
const { handleNameSetState, handleParentIdSetState, handlePlaceTypeSetState } = useMemo(
|
||||
() => onChangeInputStateHandlers(setFormState),
|
||||
[],
|
||||
);
|
||||
|
||||
const handleSubmitCreatePlaceForm = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
try {
|
||||
const { parentId, placeName, placeTypes: placeType } = formState;
|
||||
console.log(formState);
|
||||
if (!placeName || !placeName) throw new Error(staticMessages.global.errors.inputPlace);
|
||||
const newPlaceData: createPlaceArguments = {
|
||||
parentId: parentId.value,
|
||||
placeName,
|
||||
placeType,
|
||||
};
|
||||
const response = await createPlaceModel(newPlaceData);
|
||||
if (!response) throw new Error(staticMessages.service.errors[500]);
|
||||
setError({
|
||||
message: staticMessages.global.success.createPlace,
|
||||
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' });
|
||||
}
|
||||
}
|
||||
};
|
||||
useEffect(() => resetParentIdOnChangePlaceType(setFormState), [formState.placeTypes]);
|
||||
|
||||
const getPlaceList = useCallback(() => useGetPlaceList()(), []);
|
||||
@ -46,8 +75,11 @@ const useCreatePlaceVm = (dependencies: ICreatePlaceVm) => {
|
||||
}, [formState.placeTypes, places]);
|
||||
|
||||
return {
|
||||
handleSubmitCreatePlaceForm,
|
||||
formStateData: {
|
||||
formState,
|
||||
error,
|
||||
setError,
|
||||
setFormState,
|
||||
},
|
||||
inputStateHandlers: {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { CreatePlaceType } from '../model/protocols';
|
||||
import { createPlaceArguments } from '../model/submiCreatePlace';
|
||||
import { PlaceFormState, placeTypes } from '../view/protocol';
|
||||
|
||||
export const initialPlaceFormState: PlaceFormState = {
|
||||
@ -9,4 +10,5 @@ export const initialPlaceFormState: PlaceFormState = {
|
||||
|
||||
export interface ICreatePlaceVm {
|
||||
getInputOptions: CreatePlaceType['inputOptions'];
|
||||
createPlaceModel: (placeData: createPlaceArguments) => Promise<string>;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user