Compare commits
No commits in common. "dbb9ed742ca537d092aa4f758613a3caa199b857" and "143e3513da02ead0ff87453924e047979263dbd9" have entirely different histories.
dbb9ed742c
...
143e3513da
@ -1,5 +1,3 @@
|
|||||||
VITE_API_ORIGIN = http://176.53.196.42:6001/api/v1
|
VITE_API_ORIGIN = http://176.53.196.42:6001/api/v1
|
||||||
VITE_API_PLACES = /place
|
VITE_API_PLACES = /place
|
||||||
VITE_API_USERS = /profile
|
VITE_API_USERS = /profile
|
||||||
VITE_API_USERS_ACCOUNT = /account
|
|
||||||
VITE_API_USERS_PROFILE = /profile
|
|
@ -68,11 +68,9 @@
|
|||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"usePrettierrc": true,
|
"usePrettierrc": true,
|
||||||
"jsxSingleQuote": true,
|
"singleQuote": true
|
||||||
"singleQuote": true,
|
},
|
||||||
"endOfLine": "auto"
|
{}
|
||||||
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"jest/valid-title": "off",
|
"jest/valid-title": "off",
|
||||||
"react/button-has-type": "off",
|
"react/button-has-type": "off",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
type Places = {
|
type Places = {
|
||||||
placeType: string;
|
placeType: string;
|
||||||
name: string;
|
name: string;
|
||||||
qr: null | string;
|
qr: null;
|
||||||
id: string;
|
id: string;
|
||||||
parentId: string | null;
|
parentId: string | null;
|
||||||
};
|
};
|
||||||
|
@ -16,11 +16,6 @@ class UsersModel {
|
|||||||
getTitle(): string {
|
getTitle(): string {
|
||||||
return this.modelTitle;
|
return this.modelTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
addUser(user: Users): Users[] {
|
|
||||||
this.usersList.push(user);
|
|
||||||
return this.usersList;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default UsersModel;
|
export default UsersModel;
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import { CreateAccountDTOReturnType, INewUserData } from './protocols';
|
|
||||||
|
|
||||||
const createAccountDTO = (newUser: INewUserData): CreateAccountDTOReturnType => ({
|
|
||||||
enabled: true,
|
|
||||||
firstName: newUser.firstname,
|
|
||||||
lastName: newUser.lastname,
|
|
||||||
username: newUser.phonenumber,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default createAccountDTO;
|
|
@ -1,12 +0,0 @@
|
|||||||
export interface INewUserData {
|
|
||||||
firstname: string;
|
|
||||||
lastname: string;
|
|
||||||
phonenumber: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CreateAccountDTOReturnType = {
|
|
||||||
username: string;
|
|
||||||
firstName: string;
|
|
||||||
lastName: string;
|
|
||||||
enabled: true;
|
|
||||||
};
|
|
@ -1,8 +0,0 @@
|
|||||||
import { INewUserData } from '../dto/protocols';
|
|
||||||
import { CreateAccountROReturnType } from '../response-object/protocols';
|
|
||||||
|
|
||||||
interface ICreateAcountRepo {
|
|
||||||
execute: (newUser: INewUserData) => Promise<CreateAccountROReturnType>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ICreateAcountRepo;
|
|
@ -1,24 +0,0 @@
|
|||||||
import createAccountDTO from '../dto/createAccountDTO';
|
|
||||||
import { INewUserData } from '../dto/protocols';
|
|
||||||
import createAcountRO from '../response-object/createAcountRO';
|
|
||||||
import { CreateAccountROReturnType } from '../response-object/protocols';
|
|
||||||
import ICreateAcountRepo from './ICreateAcountRepo';
|
|
||||||
import { HttpHandler } from './protocols';
|
|
||||||
|
|
||||||
export default class CreateAccountRepo implements ICreateAcountRepo {
|
|
||||||
private httpHandler: HttpHandler;
|
|
||||||
|
|
||||||
constructor(httpHandler: HttpHandler) {
|
|
||||||
this.httpHandler = httpHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
execute: (newUser: INewUserData) => Promise<CreateAccountROReturnType> = async (newUser: INewUserData) => {
|
|
||||||
// call dto
|
|
||||||
const dto = createAccountDTO(newUser);
|
|
||||||
// call
|
|
||||||
const newAccountResponse = await this.httpHandler(dto);
|
|
||||||
// call response object
|
|
||||||
const newAccount = createAcountRO(newAccountResponse);
|
|
||||||
return newAccount;
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
import { INewUserData } from '../dto/protocols';
|
|
||||||
import { CreateAcountResponseApi } from '../response-object/protocols';
|
|
||||||
|
|
||||||
export type HttpHandler = (newUser: INewUserData) => Promise<CreateAcountResponseApi>;
|
|
@ -1,8 +0,0 @@
|
|||||||
import { CreateAccountROReturnType, CreateAcountResponseApi } from './protocols';
|
|
||||||
|
|
||||||
const createAcountRO = (apiResponse: CreateAcountResponseApi): CreateAccountROReturnType => ({
|
|
||||||
accountId: apiResponse.id,
|
|
||||||
phonenumber: apiResponse.username,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default createAcountRO;
|
|
@ -1,10 +0,0 @@
|
|||||||
export type CreateAcountResponseApi = {
|
|
||||||
nextRequestTimestamp: number;
|
|
||||||
username: string;
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CreateAccountROReturnType = {
|
|
||||||
phonenumber: string;
|
|
||||||
accountId: string;
|
|
||||||
};
|
|
@ -1,9 +0,0 @@
|
|||||||
import { CreateProfileDtoType, ICreateNewProfileData } from './protocols';
|
|
||||||
|
|
||||||
const createProfileDTO: CreateProfileDtoType = (userAccount: ICreateNewProfileData) => ({
|
|
||||||
account_id: userAccount.accountId,
|
|
||||||
first_name: userAccount.firstname,
|
|
||||||
last_name: userAccount.lastname,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default createProfileDTO;
|
|
@ -1,12 +0,0 @@
|
|||||||
import { INewUserData } from '../../../create-account/data/dto/protocols';
|
|
||||||
import { CreateAccountROReturnType } from '../../../create-account/data/response-object/protocols';
|
|
||||||
|
|
||||||
export type ICreateNewProfileData = CreateAccountROReturnType & INewUserData;
|
|
||||||
|
|
||||||
export type CreateProfileDtoReturnType = {
|
|
||||||
account_id: string;
|
|
||||||
first_name: string;
|
|
||||||
last_name: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CreateProfileDtoType = (userAccount: ICreateNewProfileData) => CreateProfileDtoReturnType;
|
|
@ -1,22 +0,0 @@
|
|||||||
/* eslint-disable no-useless-constructor */
|
|
||||||
import RepositoryHandler from '~/driven/utils/helpers/repository-handler/repositoryHandler';
|
|
||||||
import { CreateProfileDtoReturnType, ICreateNewProfileData } from '../dto/protocols';
|
|
||||||
import createProfileDTO from '../dto/createProfileDTO';
|
|
||||||
import ICreateProfileRepo from './ICreateProfileRepo';
|
|
||||||
import { HttpHandler } from './protocols';
|
|
||||||
|
|
||||||
export default class CreateProfileRepo
|
|
||||||
extends RepositoryHandler<CreateProfileDtoReturnType, string>
|
|
||||||
implements ICreateProfileRepo
|
|
||||||
{
|
|
||||||
constructor(httpHandler: HttpHandler) {
|
|
||||||
super(httpHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
async execute(accountData: ICreateNewProfileData) {
|
|
||||||
// create data in dto
|
|
||||||
const dto = createProfileDTO(accountData);
|
|
||||||
// call main http handler
|
|
||||||
return await this.httpHandler(dto);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
import { ICreateNewProfileData } from '../dto/protocols';
|
|
||||||
|
|
||||||
export default interface ICreateProfileRepo {
|
|
||||||
execute: (accountData: ICreateNewProfileData) => Promise<string>;
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
import { CreateProfileDtoReturnType } from '../dto/protocols';
|
|
||||||
|
|
||||||
export type HttpHandler = (newUser: CreateProfileDtoReturnType) => Promise<string>;
|
|
@ -1,3 +0,0 @@
|
|||||||
import CreateUserInfra from './infra/createUserInfra';
|
|
||||||
|
|
||||||
export default CreateUserInfra;
|
|
@ -1,29 +0,0 @@
|
|||||||
import CreateAccountRepo from '../create-account/data/repository/createAcountRepo';
|
|
||||||
import { HttpHandler as HttpAccountHandler } from '../create-account/data/repository/protocols';
|
|
||||||
import CreateProfileRepo from '../create-profile/data/repository/CreateRepositoryRepo';
|
|
||||||
import { HttpHandler as HttpProfileHandler } from '../create-profile/data/repository/protocols';
|
|
||||||
import CreateUserUsecase from '../usecase/createUserUsecase';
|
|
||||||
|
|
||||||
class CreateUserInfra {
|
|
||||||
private httpAccountHandler: HttpAccountHandler;
|
|
||||||
|
|
||||||
private httpProfileHandler: HttpProfileHandler;
|
|
||||||
|
|
||||||
constructor(httpAccountHandler: HttpAccountHandler, httpProfileHandler: HttpProfileHandler) {
|
|
||||||
this.httpAccountHandler = httpAccountHandler;
|
|
||||||
this.httpProfileHandler = httpProfileHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
execute() {
|
|
||||||
// make account repositroy ready
|
|
||||||
const accountRepository = new CreateAccountRepo(this.httpAccountHandler);
|
|
||||||
// make profile repository ready
|
|
||||||
const profileRepository = new CreateProfileRepo(this.httpProfileHandler);
|
|
||||||
// make usecase ready
|
|
||||||
const usecase = new CreateUserUsecase(accountRepository, profileRepository);
|
|
||||||
// return prepared method to call and create user
|
|
||||||
return usecase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default CreateUserInfra;
|
|
@ -1,10 +0,0 @@
|
|||||||
import { HttpHandler as HttpProfileHandler } from './create-profile/data/repository/protocols';
|
|
||||||
import { HttpHandler as HttpAccountHandler } from './create-account/data/repository/protocols';
|
|
||||||
import CreateUserUsecase from './usecase/createUserUsecase';
|
|
||||||
|
|
||||||
export default interface createUserPort {
|
|
||||||
httpAccountHandler: HttpAccountHandler;
|
|
||||||
httpProfileHandler: HttpProfileHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type createUserReturnType = CreateUserUsecase;
|
|
@ -1,27 +0,0 @@
|
|||||||
import { INewUserData } from '../create-account/data/dto/protocols';
|
|
||||||
import ICreateAcountRepo from '../create-account/data/repository/ICreateAcountRepo';
|
|
||||||
import ICreateProfileRepo from '../create-profile/data/repository/ICreateProfileRepo';
|
|
||||||
|
|
||||||
export default class CreateUserUsecase {
|
|
||||||
private accountRepository: ICreateAcountRepo;
|
|
||||||
|
|
||||||
private profileRepository: ICreateProfileRepo;
|
|
||||||
|
|
||||||
constructor(accountRepository: ICreateAcountRepo, profileRepository: ICreateProfileRepo) {
|
|
||||||
this.accountRepository = accountRepository;
|
|
||||||
this.profileRepository = profileRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
async execute(newUser: INewUserData) {
|
|
||||||
// create acount
|
|
||||||
const newAccountResponse = await this.accountRepository.execute(newUser);
|
|
||||||
const newProfileData = {
|
|
||||||
...newAccountResponse,
|
|
||||||
...newUser,
|
|
||||||
};
|
|
||||||
// create profile by account ID
|
|
||||||
const newProfileResponse = await this.profileRepository.execute(newProfileData);
|
|
||||||
|
|
||||||
return newProfileResponse;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
import { INewUserData } from '~/business-logic/core/users/create-user/create-account/data/dto/protocols';
|
|
||||||
import { CreateAcountResponseApi } from '~/business-logic/core/users/create-user/create-account/data/response-object/protocols';
|
|
||||||
import createUserPort from '~/business-logic/core/users/create-user/ports';
|
|
||||||
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
|
||||||
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
|
|
||||||
import { apiUrls } from '~/driven/utils/configs/appConfig';
|
|
||||||
|
|
||||||
const createAccountAdapter = (): createUserPort['httpAccountHandler'] => {
|
|
||||||
// make url
|
|
||||||
const url = apiUrls.core.createUserAccount;
|
|
||||||
// call http provider
|
|
||||||
const httpProvider = new HTTPPovider();
|
|
||||||
|
|
||||||
const httpHandler = (newUserData: INewUserData) => {
|
|
||||||
// api options
|
|
||||||
const httpOptions: HttpOptionsType = {
|
|
||||||
url,
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
data: newUserData,
|
|
||||||
};
|
|
||||||
return httpProvider.request<CreateAcountResponseApi>(httpOptions);
|
|
||||||
};
|
|
||||||
|
|
||||||
return httpHandler;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createAccountAdapter;
|
|
@ -1,29 +0,0 @@
|
|||||||
import { CreateProfileDtoReturnType } from '~/business-logic/core/users/create-user/create-profile/data/dto/protocols';
|
|
||||||
import createUserPort from '~/business-logic/core/users/create-user/ports';
|
|
||||||
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
|
||||||
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
|
|
||||||
import { apiUrls } from '~/driven/utils/configs/appConfig';
|
|
||||||
|
|
||||||
const createProfileAdapter = (): createUserPort['httpProfileHandler'] => {
|
|
||||||
// make url
|
|
||||||
const url = apiUrls.core.createUserProfile;
|
|
||||||
// call http provider
|
|
||||||
const httpProvider = new HTTPPovider();
|
|
||||||
|
|
||||||
const httpHandler = (newAccountData: CreateProfileDtoReturnType) => {
|
|
||||||
// api options
|
|
||||||
const httpOptions: HttpOptionsType = {
|
|
||||||
url,
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
data: newAccountData,
|
|
||||||
};
|
|
||||||
return httpProvider.request<string>(httpOptions);
|
|
||||||
};
|
|
||||||
|
|
||||||
return httpHandler;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createProfileAdapter;
|
|
@ -16,7 +16,8 @@ const getPlacesAdapter = (): IGetPlacesPort & getPlacesAdapterReturnType => {
|
|||||||
// make the httpHandler
|
// make the httpHandler
|
||||||
const httpProvider = new HTTPPovider();
|
const httpProvider = new HTTPPovider();
|
||||||
|
|
||||||
const httpHandler = async () => httpProvider.request<GetPlacesResponse>(options);
|
const httpHandler = async () =>
|
||||||
|
httpProvider.request<GetPlacesResponse>(options);
|
||||||
|
|
||||||
// return the method
|
// return the method
|
||||||
return {
|
return {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export default abstract class StateManagementProvider {
|
export default abstract class StateManagementProvider {
|
||||||
abstract useGetQuery<DataType>(
|
abstract useGetQuery<DataType>(
|
||||||
key: string,
|
key: string,
|
||||||
httpHandler: () => Promise<DataType>,
|
httpHandler: () => Promise<DataType>
|
||||||
): { data: DataType | undefined; isLoading: boolean; error?: string };
|
): { data: DataType | undefined; isLoading: boolean; error?: string };
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ export default class StateManagementService implements StateManagementProvider {
|
|||||||
|
|
||||||
useGetQuery<DataType>(
|
useGetQuery<DataType>(
|
||||||
key: string,
|
key: string,
|
||||||
httpHandler: () => Promise<DataType>,
|
httpHandler: () => Promise<DataType>
|
||||||
): {
|
): {
|
||||||
data: DataType | undefined;
|
data: DataType | undefined;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
|
@ -4,7 +4,7 @@ import StateManagementProvider from './stateManagementProvider';
|
|||||||
export default class SwrBoundary implements StateManagementProvider {
|
export default class SwrBoundary implements StateManagementProvider {
|
||||||
useGetQuery<DataType>(
|
useGetQuery<DataType>(
|
||||||
key: string,
|
key: string,
|
||||||
httpHandler: () => Promise<DataType>,
|
httpHandler: () => Promise<DataType>
|
||||||
): {
|
): {
|
||||||
data: DataType | undefined;
|
data: DataType | undefined;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
|
@ -1,41 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
export type SetStateInputMethod<NameType> = (name: NameType, newValue: string) => void;
|
interface ISimpleInput {
|
||||||
|
|
||||||
interface ISimpleInput<NameType> {
|
|
||||||
inputData: {
|
|
||||||
title: string;
|
title: string;
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
className?: string;
|
className?: string;
|
||||||
stateHanlder: {
|
|
||||||
state: string;
|
|
||||||
setState: SetStateInputMethod<NameType>;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function SimpleInput<NameType>(props: ISimpleInput<NameType>) {
|
export default function SimpleInput(props: ISimpleInput) {
|
||||||
const { className, inputData, stateHanlder } = props;
|
const { title, className } = 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
|
<input className='bg-bg-gray h-11 rounded-lg focus:outline-0 px-2 text-txt-medium' id={title} />
|
||||||
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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,5 @@ interface IPageTitleProps {
|
|||||||
|
|
||||||
export default function PageTitle(props: IPageTitleProps) {
|
export default function PageTitle(props: IPageTitleProps) {
|
||||||
const { title, className } = props;
|
const { title, className } = props;
|
||||||
return (
|
return <div className={`w-full shadow-sm shadow-txt-light font-semibold ${className}`}>{title}</div>;
|
||||||
<div
|
|
||||||
className={`w-full shadow-sm shadow-txt-light font-semibold ${className}`}
|
|
||||||
>
|
|
||||||
{title}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,5 @@ export const apiUrls = {
|
|||||||
core: {
|
core: {
|
||||||
getPlaces: `${baseApiUrl}${ENVs.apiGetPlaces}`,
|
getPlaces: `${baseApiUrl}${ENVs.apiGetPlaces}`,
|
||||||
getUsers: `${baseApiUrl}${ENVs.apiGetUsers}`,
|
getUsers: `${baseApiUrl}${ENVs.apiGetUsers}`,
|
||||||
createUserAccount: `${baseApiUrl}${ENVs.apiCreateUserAccount}`,
|
|
||||||
createUserProfile: `${baseApiUrl}${ENVs.apiCreateUserProfile}`,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,4 @@ export const ENVs = {
|
|||||||
apiOrigin: process.env.VITE_API_ORIGIN,
|
apiOrigin: process.env.VITE_API_ORIGIN,
|
||||||
apiGetPlaces: process.env.VITE_API_PLACES,
|
apiGetPlaces: process.env.VITE_API_PLACES,
|
||||||
apiGetUsers: process.env.VITE_API_USERS,
|
apiGetUsers: process.env.VITE_API_USERS,
|
||||||
apiCreateUserAccount: process.env.VITE_API_USERS_ACCOUNT,
|
|
||||||
apiCreateUserProfile: process.env.VITE_API_USERS_PROFILE,
|
|
||||||
};
|
};
|
||||||
|
@ -5,16 +5,15 @@ export const staticMessages = {
|
|||||||
},
|
},
|
||||||
users: 'Users',
|
users: 'Users',
|
||||||
submit: 'Submit',
|
submit: 'Submit',
|
||||||
firstname: 'Firstname',
|
fistname: 'Firstname',
|
||||||
lastname: 'Lastname',
|
lastname: 'Lastname',
|
||||||
place_id: 'Place id',
|
place_id: 'Place id',
|
||||||
title: 'title',
|
title: 'title',
|
||||||
status: 'Status',
|
status: 'Status',
|
||||||
placeType: 'Place Type',
|
|
||||||
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,5 +1,8 @@
|
|||||||
import StateManagementService from '~/driven/boundaries/state-management';
|
import StateManagementService from '~/driven/boundaries/state-management';
|
||||||
import { errorHandlingStateTypes, UIErrorHandling } from './protocols/globalHelpersProtocols';
|
import {
|
||||||
|
errorHandlingStateTypes,
|
||||||
|
UIErrorHandling,
|
||||||
|
} from './protocols/globalHelpersProtocols';
|
||||||
|
|
||||||
export const UIErrorHandlingFactory = <DATA_RESPONSE>({
|
export const UIErrorHandlingFactory = <DATA_RESPONSE>({
|
||||||
state,
|
state,
|
||||||
@ -15,14 +18,13 @@ export const UIErrorHandlingFactory = <DATA_RESPONSE>({
|
|||||||
state,
|
state,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const prepareStateManagementForVM = <ReturnType>(apiUrl: string, model: () => Promise<ReturnType>) => {
|
export const prepareStateManagementForVM = <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,9 +0,0 @@
|
|||||||
type HttpHandler<NewDataToAdd, ResponseType> = (newUser: NewDataToAdd) => Promise<ResponseType>;
|
|
||||||
|
|
||||||
export default class RepositoryHandler<NewDataToAdd, ResponseType> {
|
|
||||||
protected httpHandler: HttpHandler<NewDataToAdd, ResponseType>;
|
|
||||||
|
|
||||||
constructor(httpHandler: HttpHandler<NewDataToAdd, ResponseType>) {
|
|
||||||
this.httpHandler = httpHandler;
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,11 +9,5 @@ export default function TableRow(props: ITableRowInfra) {
|
|||||||
|
|
||||||
const { isRowSelected } = useTableRowVM({ selectedRowId, rowId });
|
const { isRowSelected } = useTableRowVM({ selectedRowId, rowId });
|
||||||
|
|
||||||
return (
|
return <TableRowView isSelected={isRowSelected} rowData={rowData} setSelectedRowId={setSelectedRowId} />;
|
||||||
<TableRowView
|
|
||||||
isSelected={isRowSelected}
|
|
||||||
rowData={rowData}
|
|
||||||
setSelectedRowId={setSelectedRowId}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export interface ITableRowInfra {
|
export interface ITableRowInfra {
|
||||||
selectedRowId: string;
|
selectedRowId: string;
|
||||||
rowData: {
|
rowData: {
|
||||||
rowItemsTitle: (string | null)[];
|
rowItemsTitle: string[];
|
||||||
rowId: string;
|
rowId: string;
|
||||||
};
|
};
|
||||||
setSelectedRowId: React.Dispatch<React.SetStateAction<string>>;
|
setSelectedRowId: React.Dispatch<React.SetStateAction<string>>;
|
||||||
|
@ -6,14 +6,7 @@ export default function TableRowView(props: ITableRowProps) {
|
|||||||
const { isSelected, setSelectedRowId, rowData } = props;
|
const { isSelected, setSelectedRowId, rowData } = props;
|
||||||
const { rowId, rowItemsTitle } = rowData;
|
const { rowId, rowItemsTitle } = rowData;
|
||||||
const columns = rowItemsTitle.map((rowItemTitle, index) => {
|
const columns = rowItemsTitle.map((rowItemTitle, index) => {
|
||||||
return (
|
return <RowItem key={rowItemTitle} hasCheckbox={index === 0} isSelected={isSelected} title={rowItemTitle} />;
|
||||||
<RowItem
|
|
||||||
key={rowItemTitle}
|
|
||||||
hasCheckbox={index === 0}
|
|
||||||
isSelected={isSelected}
|
|
||||||
title={rowItemTitle}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return <tr onClick={() => setSelectedRowId(rowId)}>{columns}</tr>;
|
return <tr onClick={() => setSelectedRowId(rowId)}>{columns}</tr>;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export interface ITableRowProps {
|
export interface ITableRowProps {
|
||||||
isSelected: boolean;
|
isSelected: boolean;
|
||||||
rowData: {
|
rowData: {
|
||||||
rowItemsTitle: (string | null)[];
|
rowItemsTitle: string[];
|
||||||
rowId: string;
|
rowId: string;
|
||||||
};
|
};
|
||||||
setSelectedRowId: React.Dispatch<React.SetStateAction<string>>;
|
setSelectedRowId: React.Dispatch<React.SetStateAction<string>>;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
interface IRowItemProp {
|
interface IRowItemProp {
|
||||||
title: string | null;
|
title: string;
|
||||||
hasCheckbox: boolean;
|
hasCheckbox: boolean;
|
||||||
isSelected: boolean;
|
isSelected: boolean;
|
||||||
}
|
}
|
||||||
@ -17,11 +17,7 @@ export default function RowItem(props: IRowItemProp) {
|
|||||||
isSelected ? 'opacity-100' : 'opacity-0'
|
isSelected ? 'opacity-100' : 'opacity-0'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span
|
<span className={`${isSelected ? 'visible' : 'hidden'} transition-all`}>✓</span>
|
||||||
className={`${isSelected ? 'visible' : 'hidden'} transition-all`}
|
|
||||||
>
|
|
||||||
✓
|
|
||||||
</span>
|
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{title}
|
{title}
|
||||||
|
@ -1,22 +1,6 @@
|
|||||||
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() {
|
||||||
// get adapters from driven layer
|
return <CreateUserView />;
|
||||||
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} />;
|
|
||||||
}
|
}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
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,35 +2,18 @@ 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(props: ICreateUserViewProps) {
|
export default function CreateUserView() {
|
||||||
const { onSubmit, inputNames, stateHandler } = props;
|
|
||||||
const { inputStates, inputsSetStates } = stateHandler;
|
|
||||||
|
|
||||||
const inputs = inputNames.map((inputName) => {
|
|
||||||
const title = staticMessages.global[inputName] as string;
|
|
||||||
return (
|
return (
|
||||||
<SimpleInput
|
<div className='px-4 my-8'>
|
||||||
inputData={{
|
<div className='flex flex-wrap w-full gap-4'>
|
||||||
title,
|
<SimpleInput title={staticMessages.global.fistname} className='mb-4 w-[48%]' />
|
||||||
name: inputName,
|
<SimpleInput title={staticMessages.global.lastname} className='mb-4 w-[48%]' />
|
||||||
}}
|
<SimpleInput title={staticMessages.global.phoneNumber} className='mb-4 w-[48%]' />
|
||||||
stateHanlder={{
|
</div>
|
||||||
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>
|
||||||
</form>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
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)[];
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
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;
|
|
@ -1,5 +0,0 @@
|
|||||||
import { INewUserData } from '~/business-logic/core/users/create-user/create-account/data/dto/protocols';
|
|
||||||
|
|
||||||
export default interface IUseCreateUserVm {
|
|
||||||
handleSubmitForm: (newUserData: INewUserData) => void;
|
|
||||||
}
|
|
@ -1,19 +1,39 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React from 'react';
|
||||||
import { staticMessages } from '~/driven/utils/constants/staticMessages';
|
import { staticMessages } from '~/driven/utils/constants/staticMessages';
|
||||||
import Loading from '~/driven/utils/components/loading/Loading';
|
import Loading from '~/driven/utils/components/loading/Loading';
|
||||||
import Places from '~/business-logic/core/places/common/entity/placeEntity';
|
|
||||||
import TableRow from '../../common/table-row';
|
import TableRow from '../../common/table-row';
|
||||||
import { IPlacesListProps } from './protocols';
|
import { IPlacesListProps } from './protocols';
|
||||||
|
|
||||||
export default function UsersListView(props: IPlacesListProps) {
|
export default function UsersListView(props: IPlacesListProps) {
|
||||||
const { selectedRowId, setSelectedRowId, placesList } = props;
|
const { selectedRowId, setSelectedRowId, placesList } = props;
|
||||||
|
console.log(placesList.data);
|
||||||
|
const rows = () => {
|
||||||
|
const placesdata = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
place_id: '6440020b89366fdcaf15a8c2',
|
||||||
|
title: 'flat demoplace ',
|
||||||
|
status: 'demo',
|
||||||
|
address: 'demoplace',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
place_id: '6440020b89366fdcaf15asdfa',
|
||||||
|
title: 'flat demoplace second ',
|
||||||
|
status: 'demo second',
|
||||||
|
address: 'demoplace second',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const rows = useMemo(() => {
|
return placesdata.map((places) => {
|
||||||
if (!placesList.data) return null;
|
|
||||||
|
|
||||||
return placesList.data.getData().map((places) => {
|
|
||||||
const rowData = {
|
const rowData = {
|
||||||
rowItemsTitle: [places.name, places.placeType, places.qr],
|
rowItemsTitle: [
|
||||||
|
places.id,
|
||||||
|
places.title,
|
||||||
|
places.status,
|
||||||
|
places.address,
|
||||||
|
'',
|
||||||
|
],
|
||||||
rowId: places.id,
|
rowId: places.id,
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
@ -25,36 +45,27 @@ export default function UsersListView(props: IPlacesListProps) {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}, [placesList]);
|
};
|
||||||
|
|
||||||
if (placesList.isLoading)
|
if (placesList.isLoading)
|
||||||
return (
|
return (
|
||||||
<div className='flex justify-center items-center'>
|
<div className="flex justify-center items-center">
|
||||||
<Loading />
|
<Loading />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
const tableTitles: Pick<Places, 'name' | 'placeType' | 'qr'> = {
|
|
||||||
name: staticMessages.global.title,
|
|
||||||
placeType: staticMessages.global.placeType,
|
|
||||||
qr: staticMessages.global.qrCode,
|
|
||||||
};
|
|
||||||
|
|
||||||
const titles = Object.keys(tableTitles).map((titleKey) => {
|
|
||||||
const key = titleKey as keyof typeof tableTitles;
|
|
||||||
|
|
||||||
const title = tableTitles[key];
|
|
||||||
return (
|
return (
|
||||||
<th key={key} className='py-3'>
|
<table className="table-auto rounded-md w-full text-sm">
|
||||||
{title}
|
<thead className="text-txt-medium font-bold">
|
||||||
</th>
|
<tr>
|
||||||
);
|
<th className="py-3">{staticMessages.global.place_id}</th>
|
||||||
});
|
<th className="py-3">{staticMessages.global.title}</th>
|
||||||
return (
|
<th className="py-3">{staticMessages.global.status}</th>
|
||||||
<table className='table-auto rounded-md w-full text-sm h-fit'>
|
<th className="py-3">{staticMessages.global.address}</th>
|
||||||
<thead className='text-txt-medium font-bold'>
|
<th className="py-3">{staticMessages.global.qrCode}</th>
|
||||||
<tr>{titles}</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>{rows}</tbody>
|
<tbody>{rows()}</tbody>
|
||||||
</table>
|
</table>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,29 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
import React from 'react';
|
||||||
import React, { useMemo } from 'react';
|
|
||||||
import { staticMessages } from '~/driven/utils/constants/staticMessages';
|
import { staticMessages } from '~/driven/utils/constants/staticMessages';
|
||||||
import Users from '~/business-logic/core/users/common/entity/entity';
|
|
||||||
import Loading from '~/driven/utils/components/loading/Loading';
|
|
||||||
import TableRow from '../../common/table-row';
|
import TableRow from '../../common/table-row';
|
||||||
import { IUserListProps } from './protocols';
|
import { IUserListProps } from './protocols';
|
||||||
|
|
||||||
export default function UsersListView(props: IUserListProps) {
|
export default function UsersListView(props: IUserListProps) {
|
||||||
const { selectedRowId, setSelectedRowId, usersList } = props;
|
const { selectedRowId, setSelectedRowId, usersList } = props;
|
||||||
const rows = useMemo(() => {
|
console.log(usersList.data);
|
||||||
if (!usersList.data) return null;
|
const rows = () => {
|
||||||
|
const userdata = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
firstname: 'behnam',
|
||||||
|
lastname: 'rahimpour',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
firstname: 'Salar',
|
||||||
|
lastname: 'Sali',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return usersList.data.getData().map((user) => {
|
return userdata.map((user) => {
|
||||||
const rowData = {
|
const rowData = {
|
||||||
rowItemsTitle: [user.firstname, user.lastname],
|
rowItemsTitle: [user.firstname, user.lastname],
|
||||||
rowId: user.accountId,
|
rowId: user.id,
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<TableRow
|
<TableRow
|
||||||
@ -25,36 +34,17 @@ export default function UsersListView(props: IUserListProps) {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}, [usersList]);
|
|
||||||
const tableTitles: Pick<Users, 'firstname' | 'lastname'> = {
|
|
||||||
firstname: staticMessages.global.firstname,
|
|
||||||
lastname: staticMessages.global.lastname,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const titles = Object.keys(tableTitles).map((titleKey) => {
|
|
||||||
const key = titleKey as keyof typeof tableTitles;
|
|
||||||
|
|
||||||
const title = tableTitles[key];
|
|
||||||
return (
|
return (
|
||||||
<th key={key} className='py-3'>
|
<table className="table-auto rounded-md w-full text-sm">
|
||||||
{title}
|
<thead className="text-txt-medium font-bold">
|
||||||
</th>
|
<tr>
|
||||||
);
|
<th className="py-3">{staticMessages.global.fistname}</th>
|
||||||
});
|
<th className="py-3">{staticMessages.global.lastname}</th>
|
||||||
|
</tr>
|
||||||
if (usersList.isLoading)
|
|
||||||
return (
|
|
||||||
<div className='flex justify-center items-center'>
|
|
||||||
<Loading />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<table className='table-auto rounded-md w-full text-sm h-fit'>
|
|
||||||
<thead className='text-txt-medium font-bold'>
|
|
||||||
<tr>{titles}</tr>
|
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>{rows}</tbody>
|
<tbody>{rows()}</tbody>
|
||||||
</table>
|
</table>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,7 @@ export default function Sidebar() {
|
|||||||
key={key}
|
key={key}
|
||||||
to={routesData[key].path}
|
to={routesData[key].path}
|
||||||
className={`flex text-white mb-6 text-sm w-full py-2 pl-2 rounded-lg ${
|
className={`flex text-white mb-6 text-sm w-full py-2 pl-2 rounded-lg ${
|
||||||
isCurrentPage.pathname === routesData[key].path
|
isCurrentPage.pathname === routesData[key].path ? 'bg-primary-300' : ''
|
||||||
? 'bg-primary-300'
|
|
||||||
: ''
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<img src={routesData[key].icon} alt='page icon' className='mr-2' />
|
<img src={routesData[key].icon} alt='page icon' className='mr-2' />
|
||||||
|
@ -6,10 +6,7 @@ import CreateUser from '~/driving/application/core/create-user';
|
|||||||
export default function CreateUserPage() {
|
export default function CreateUserPage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageTitle
|
<PageTitle className='px-4 py-5' title={staticMessages.global.createUser} />
|
||||||
className='px-4 py-5'
|
|
||||||
title={staticMessages.global.createUser}
|
|
||||||
/>
|
|
||||||
<CreateUser />
|
<CreateUser />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -11,11 +11,7 @@ export default function index() {
|
|||||||
<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'>
|
<div className='w-full flex flex-row-reverse items-center py-2'>
|
||||||
<PrimaryButton
|
<PrimaryButton className='text-sm' title={staticMessages.global.submit} onClick={() => null} />
|
||||||
className='text-sm'
|
|
||||||
title={staticMessages.global.submit}
|
|
||||||
onClick={() => null}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<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 />
|
||||||
|
@ -4,7 +4,7 @@ import Sidebar from '~/driving/application/support/sidebar';
|
|||||||
|
|
||||||
export default function MainPageLayout() {
|
export default function MainPageLayout() {
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-nowrap min-h-screen'>
|
<div className='flex flex-nowrap 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-fit'>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user