[FEAT]: add create user logic
This commit is contained in:
parent
6ccf3ee25b
commit
dbb9ed742c
@ -1,3 +1,3 @@
|
|||||||
import createUserInfra from './infra/createUserInfra';
|
import CreateUserInfra from './infra/createUserInfra';
|
||||||
|
|
||||||
export default createUserInfra;
|
export default CreateUserInfra;
|
||||||
|
@ -4,7 +4,7 @@ import CreateProfileRepo from '../create-profile/data/repository/CreateRepositor
|
|||||||
import { HttpHandler as HttpProfileHandler } from '../create-profile/data/repository/protocols';
|
import { HttpHandler as HttpProfileHandler } from '../create-profile/data/repository/protocols';
|
||||||
import CreateUserUsecase from '../usecase/createUserUsecase';
|
import CreateUserUsecase from '../usecase/createUserUsecase';
|
||||||
|
|
||||||
class createUserInfra {
|
class CreateUserInfra {
|
||||||
private httpAccountHandler: HttpAccountHandler;
|
private httpAccountHandler: HttpAccountHandler;
|
||||||
|
|
||||||
private httpProfileHandler: HttpProfileHandler;
|
private httpProfileHandler: HttpProfileHandler;
|
||||||
@ -26,4 +26,4 @@ class createUserInfra {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default createUserInfra;
|
export default CreateUserInfra;
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import { HttpHandler as HttpProfileHandler } from './create-profile/data/repository/protocols';
|
import { HttpHandler as HttpProfileHandler } from './create-profile/data/repository/protocols';
|
||||||
import { HttpHandler as HttpAccountHandler } from './create-account/data/repository/protocols';
|
import { HttpHandler as HttpAccountHandler } from './create-account/data/repository/protocols';
|
||||||
|
import CreateUserUsecase from './usecase/createUserUsecase';
|
||||||
|
|
||||||
export default interface createUserPort {
|
export default interface createUserPort {
|
||||||
httpAccountHandler: HttpAccountHandler;
|
httpAccountHandler: HttpAccountHandler;
|
||||||
httpProfileHandler: HttpProfileHandler;
|
httpProfileHandler: HttpProfileHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type createUserReturnType = CreateUserUsecase;
|
||||||
|
@ -1,18 +1,41 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
interface ISimpleInput {
|
export type SetStateInputMethod<NameType> = (name: NameType, newValue: string) => void;
|
||||||
|
|
||||||
|
interface ISimpleInput<NameType> {
|
||||||
|
inputData: {
|
||||||
title: string;
|
title: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
className?: string;
|
className?: string;
|
||||||
|
stateHanlder: {
|
||||||
|
state: string;
|
||||||
|
setState: SetStateInputMethod<NameType>;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function SimpleInput(props: ISimpleInput) {
|
export default function SimpleInput<NameType>(props: ISimpleInput<NameType>) {
|
||||||
const { title, className } = props;
|
const { className, inputData, stateHanlder } = props;
|
||||||
|
const { name, title } = inputData;
|
||||||
|
const { setState, state } = stateHanlder;
|
||||||
|
|
||||||
|
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const { value, name: inputName } = e.target;
|
||||||
|
setState(inputName as NameType, value);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`flex flex-col ${className}`}>
|
<div className={`flex flex-col ${className}`}>
|
||||||
<label className='mb-1 text-txt-second text-xs' htmlFor={title}>
|
<label className='mb-1 text-txt-second text-xs' htmlFor={title}>
|
||||||
{title}
|
{title}
|
||||||
</label>
|
</label>
|
||||||
<input className='bg-bg-gray h-11 rounded-lg focus:outline-0 px-2 text-txt-medium' id={title} />
|
<input
|
||||||
|
value={state}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
name={name}
|
||||||
|
className='bg-bg-gray h-11 rounded-lg focus:outline-0 px-2 text-txt-medium'
|
||||||
|
id={title}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ export const staticMessages = {
|
|||||||
},
|
},
|
||||||
users: 'Users',
|
users: 'Users',
|
||||||
submit: 'Submit',
|
submit: 'Submit',
|
||||||
fistname: 'Firstname',
|
firstname: 'Firstname',
|
||||||
lastname: 'Lastname',
|
lastname: 'Lastname',
|
||||||
place_id: 'Place id',
|
place_id: 'Place id',
|
||||||
title: 'title',
|
title: 'title',
|
||||||
@ -14,7 +14,7 @@ export const staticMessages = {
|
|||||||
address: 'Address',
|
address: 'Address',
|
||||||
qrCode: 'qrCode',
|
qrCode: 'qrCode',
|
||||||
createUser: 'Create user',
|
createUser: 'Create user',
|
||||||
phoneNumber: 'Phone Number',
|
phonenumber: 'Phone Number',
|
||||||
},
|
},
|
||||||
service: {
|
service: {
|
||||||
errors: {
|
errors: {
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import StateManagementService from '~/driven/boundaries/state-management';
|
import StateManagementService from '~/driven/boundaries/state-management';
|
||||||
import {
|
import { errorHandlingStateTypes, UIErrorHandling } from './protocols/globalHelpersProtocols';
|
||||||
errorHandlingStateTypes,
|
|
||||||
UIErrorHandling,
|
|
||||||
} from './protocols/globalHelpersProtocols';
|
|
||||||
|
|
||||||
export const UIErrorHandlingFactory = <DATA_RESPONSE>({
|
export const UIErrorHandlingFactory = <DATA_RESPONSE>({
|
||||||
state,
|
state,
|
||||||
@ -18,13 +15,14 @@ export const UIErrorHandlingFactory = <DATA_RESPONSE>({
|
|||||||
state,
|
state,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const prepareStateManagementForVM = <ReturnType>(
|
export const prepareStateManagementForVM = <ReturnType>(apiUrl: string, model: () => Promise<ReturnType>) => {
|
||||||
apiUrl: string,
|
|
||||||
model: () => Promise<ReturnType>
|
|
||||||
) => {
|
|
||||||
const stateManagement = StateManagementService.swr();
|
const stateManagement = StateManagementService.swr();
|
||||||
|
|
||||||
const useGetPlacesList = () => stateManagement.useGetQuery(apiUrl, model);
|
const useGetPlacesList = () => stateManagement.useGetQuery(apiUrl, model);
|
||||||
|
|
||||||
return useGetPlacesList;
|
return useGetPlacesList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const checkPhoneNumberInput = (newValue: string) => {
|
||||||
|
return (Number.isFinite(+newValue) || newValue === '+') && newValue.length <= 12;
|
||||||
|
};
|
||||||
|
@ -1,6 +1,22 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import createAccountAdapter from '~/driven/adapters/create-account-adapter/createAccountAdapter';
|
||||||
|
import createProfileAdapter from '~/driven/adapters/create-profile-adapter/createProfileAdapter';
|
||||||
|
import CreateUserInfra from '~/business-logic/core/users/create-user';
|
||||||
import CreateUserView from '../view/CreateUserView';
|
import CreateUserView from '../view/CreateUserView';
|
||||||
|
import useCreateUserVM from '../viewmodel/CreateUserVM';
|
||||||
|
import createUserModel from '../model/createUserModel';
|
||||||
|
|
||||||
export default function CreateUser() {
|
export default function CreateUser() {
|
||||||
return <CreateUserView />;
|
// get adapters from driven layer
|
||||||
|
const createAccountDrivenAdapter = createAccountAdapter();
|
||||||
|
const createProfileDrivenAdapter = createProfileAdapter();
|
||||||
|
// pass to the logic and get the usecase
|
||||||
|
const createUserInfra = new CreateUserInfra(createAccountDrivenAdapter, createProfileDrivenAdapter);
|
||||||
|
const createUserLogic = createUserInfra.execute();
|
||||||
|
// pass the usecase to the model
|
||||||
|
const { handleSubmitForm } = createUserModel({ createUserLogic });
|
||||||
|
// pass the method to the viewmodel to call on submit
|
||||||
|
const { stateHandler, onSubmit, inputNames } = useCreateUserVM({ handleSubmitForm });
|
||||||
|
// get all of the needed information to the user to show
|
||||||
|
return <CreateUserView stateHandler={stateHandler} inputNames={inputNames} onSubmit={onSubmit} />;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
import CreateUserUsecase from '~/business-logic/core/users/create-user/usecase/createUserUsecase';
|
||||||
|
import { INewUserData } from '~/business-logic/core/users/create-user/create-account/data/dto/protocols';
|
||||||
|
import IUseCreateUserVm from '../viewmodel/protocols';
|
||||||
|
|
||||||
|
interface ICreateUserModel {
|
||||||
|
createUserLogic: CreateUserUsecase;
|
||||||
|
}
|
||||||
|
|
||||||
|
const createUserModel = (dependencies: ICreateUserModel): IUseCreateUserVm => {
|
||||||
|
const { createUserLogic } = dependencies;
|
||||||
|
|
||||||
|
const handleSubmitForm = async (newUserData: INewUserData) => {
|
||||||
|
await createUserLogic.execute(newUserData);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
handleSubmitForm,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default createUserModel;
|
@ -2,18 +2,35 @@ import React from 'react';
|
|||||||
import PrimaryButton from '~/driven/utils/components/buttons/primary-button/PrimaryButton';
|
import PrimaryButton from '~/driven/utils/components/buttons/primary-button/PrimaryButton';
|
||||||
import SimpleInput from '~/driven/utils/components/inputs/simple-input/SimpleInput';
|
import SimpleInput from '~/driven/utils/components/inputs/simple-input/SimpleInput';
|
||||||
import { staticMessages } from '~/driven/utils/constants/staticMessages';
|
import { staticMessages } from '~/driven/utils/constants/staticMessages';
|
||||||
|
import ICreateUserViewProps from './protocols';
|
||||||
|
|
||||||
export default function CreateUserView() {
|
export default function CreateUserView(props: ICreateUserViewProps) {
|
||||||
|
const { onSubmit, inputNames, stateHandler } = props;
|
||||||
|
const { inputStates, inputsSetStates } = stateHandler;
|
||||||
|
|
||||||
|
const inputs = inputNames.map((inputName) => {
|
||||||
|
const title = staticMessages.global[inputName] as string;
|
||||||
return (
|
return (
|
||||||
<div className='px-4 my-8'>
|
<SimpleInput
|
||||||
<div className='flex flex-wrap w-full gap-4'>
|
inputData={{
|
||||||
<SimpleInput title={staticMessages.global.fistname} className='mb-4 w-[48%]' />
|
title,
|
||||||
<SimpleInput title={staticMessages.global.lastname} className='mb-4 w-[48%]' />
|
name: inputName,
|
||||||
<SimpleInput title={staticMessages.global.phoneNumber} className='mb-4 w-[48%]' />
|
}}
|
||||||
</div>
|
stateHanlder={{
|
||||||
|
setState: inputsSetStates,
|
||||||
|
state: inputStates[inputName],
|
||||||
|
}}
|
||||||
|
key={inputName}
|
||||||
|
className='mb-4 w-[48%]'
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<form onSubmit={onSubmit} className='px-4 my-8'>
|
||||||
|
<div className='flex flex-wrap w-full gap-4'>{inputs}</div>
|
||||||
<div className='flex'>
|
<div className='flex'>
|
||||||
<PrimaryButton onClick={() => null} title={staticMessages.global.submit} />
|
<PrimaryButton onClick={() => null} title={staticMessages.global.submit} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
11
src/driving/application/core/create-user/view/protocols.ts
Normal file
11
src/driving/application/core/create-user/view/protocols.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { INewUserData } from '~/business-logic/core/users/create-user/create-account/data/dto/protocols';
|
||||||
|
import { SetStateInputMethod } from '~/driven/utils/components/inputs/simple-input/SimpleInput';
|
||||||
|
|
||||||
|
export default interface ICreateUserViewProps {
|
||||||
|
onSubmit: (e: React.FormEvent) => void;
|
||||||
|
stateHandler: {
|
||||||
|
inputStates: INewUserData;
|
||||||
|
inputsSetStates: SetStateInputMethod<keyof INewUserData>;
|
||||||
|
};
|
||||||
|
inputNames: (keyof INewUserData)[];
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import { checkPhoneNumberInput } from '~/driven/utils/helpers/globalHelpers';
|
||||||
|
import { INewUserData } from '~/business-logic/core/users/create-user/create-account/data/dto/protocols';
|
||||||
|
import ICreateUserViewProps from '../view/protocols';
|
||||||
|
import IUseCreateUserVm from './protocols';
|
||||||
|
|
||||||
|
const inputStateInitialValue: INewUserData = {
|
||||||
|
firstname: '',
|
||||||
|
lastname: '',
|
||||||
|
phonenumber: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
const inputNames: (keyof INewUserData)[] = ['firstname', 'lastname', 'phonenumber'];
|
||||||
|
|
||||||
|
const useCreateUserVM = (dependencies: IUseCreateUserVm): ICreateUserViewProps => {
|
||||||
|
const { handleSubmitForm } = dependencies;
|
||||||
|
const [inputsValue, setInputValues] = useState<INewUserData>(inputStateInitialValue);
|
||||||
|
|
||||||
|
const inputsSetStates = (name: keyof INewUserData, newValue: string) => {
|
||||||
|
if (name === 'phonenumber' && !checkPhoneNumberInput(newValue)) return;
|
||||||
|
setInputValues((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[name]: newValue,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmitCreateUserForm = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log('submit user', inputsValue);
|
||||||
|
handleSubmitForm(inputsValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const inputStates: INewUserData = { ...inputsValue };
|
||||||
|
|
||||||
|
return {
|
||||||
|
stateHandler: {
|
||||||
|
inputsSetStates,
|
||||||
|
inputStates,
|
||||||
|
},
|
||||||
|
onSubmit: onSubmitCreateUserForm,
|
||||||
|
inputNames,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useCreateUserVM;
|
@ -0,0 +1,5 @@
|
|||||||
|
import { INewUserData } from '~/business-logic/core/users/create-user/create-account/data/dto/protocols';
|
||||||
|
|
||||||
|
export default interface IUseCreateUserVm {
|
||||||
|
handleSubmitForm: (newUserData: INewUserData) => void;
|
||||||
|
}
|
@ -27,7 +27,7 @@ export default function UsersListView(props: IUserListProps) {
|
|||||||
});
|
});
|
||||||
}, [usersList]);
|
}, [usersList]);
|
||||||
const tableTitles: Pick<Users, 'firstname' | 'lastname'> = {
|
const tableTitles: Pick<Users, 'firstname' | 'lastname'> = {
|
||||||
firstname: staticMessages.global.fistname,
|
firstname: staticMessages.global.firstname,
|
||||||
lastname: staticMessages.global.lastname,
|
lastname: staticMessages.global.lastname,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user