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
36 changed files with 369 additions and 61 deletions
Showing only changes of commit 0fae625913 - Show all commits

View File

@ -1,2 +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

View File

@ -1,33 +1,20 @@
import Places from "../entity/placeEntity"; import Places from "../entity/placeEntity";
class PlacesModel { class PlacesModel {
private placeType: string; private placesList: Places[];
private name: string; private modelTitle = "places";
private qr: null; constructor(data: Places[]) {
this.placesList = data;
private id: string;
private parentId: string | null;
constructor(store: Places) {
const { id, name, parentId, placeType, qr } = store;
this.parentId = parentId;
this.id = id;
this.qr = qr;
this.name = name;
this.placeType = placeType;
} }
getData(): Places { getData(): Places[] {
return { return this.placesList;
id: this.id, }
name: this.name,
parentId: this.parentId, getTitle(): string {
placeType: this.placeType, return this.modelTitle;
qr: this.qr,
};
} }
} }

View File

@ -1,15 +1,19 @@
/* eslint-disable no-underscore-dangle */ /* eslint-disable no-underscore-dangle */
import { GetPlacesRO, GetPlacesResponse } from "./protocols"; import { GetPlacesRO, GetPlacesResponse } from "./protocols";
const getPlacesRO = (placeResponse: GetPlacesResponse): GetPlacesRO => ({ const getPlacesRO = (placesResponse: GetPlacesResponse): GetPlacesRO => {
id: placeResponse._id, return placesResponse.map((placeResponse) => {
placeType: placeResponse.place_type, return {
name: placeResponse.name, id: placeResponse._id,
parentId: placeResponse.place_type, placeType: placeResponse.place_type,
availableServices: placeResponse.available_services, name: placeResponse.name,
createdAt: placeResponse.createdAt, parentId: placeResponse.place_type,
updatedAt: placeResponse.updatedAt, availableServices: placeResponse.available_services,
qr: null, createdAt: placeResponse.createdAt,
}); updatedAt: placeResponse.updatedAt,
qr: null,
};
});
};
export default getPlacesRO; export default getPlacesRO;

View File

@ -8,10 +8,11 @@ export type GetPlacesResponse = {
createdAt: string; createdAt: string;
updatedAt: string; updatedAt: string;
available_services: string[]; available_services: string[];
}; }[];
export type GetPlacesRO = Places & { export type GetPlacesRO = Places[] &
availableServices: string[]; {
createdAt: string; availableServices: string[];
updatedAt: string; createdAt: string;
}; updatedAt: string;
}[];

View File

@ -1,12 +1,9 @@
import PlacesModel from "../../common/model/placesModel";
import getPlacesRepo from "../data/repository/GetPlacesRepo"; import getPlacesRepo from "../data/repository/GetPlacesRepo";
import IGetPlacesRepo from "../data/repository/IGetPlacesRepo"; import IGetPlacesRepo from "../data/repository/IGetPlacesRepo";
import GettingPlacesUsecase from "../usecase/getPlaceUsecase"; import GettingPlacesUsecase from "../usecase/getPlaceUsecase";
import { IgetPlacesInfra } from "./protocols"; import { IgetPlacesInfra, getPlacesReturnType } from "./protocols";
const getPlaces = ({ const getPlaces = ({ httpHandler }: IgetPlacesInfra): getPlacesReturnType => {
httpHandler,
}: IgetPlacesInfra): (() => Promise<PlacesModel>) => {
// get httpHandler // get httpHandler
const repository: IGetPlacesRepo = () => getPlacesRepo(httpHandler); const repository: IGetPlacesRepo = () => getPlacesRepo(httpHandler);
// connet usecase and repository // connet usecase and repository

View File

@ -1,5 +1,8 @@
import PlacesModel from "../../common/model/placesModel";
import { GetPlacesResponse } from "../data/response-object/protocols"; import { GetPlacesResponse } from "../data/response-object/protocols";
export interface IgetPlacesInfra { export interface IgetPlacesInfra {
httpHandler: () => Promise<GetPlacesResponse>; httpHandler: () => Promise<GetPlacesResponse>;
} }
export type getPlacesReturnType = () => Promise<PlacesModel>;

View File

@ -1,3 +1,5 @@
import { type IgetPlacesInfra } from "./infra/protocols"; import { getPlacesReturnType, type IgetPlacesInfra } from "./infra/protocols";
export default IgetPlacesInfra; export default IgetPlacesInfra;
export type getPlacesReturnPort = getPlacesReturnType;

View File

@ -0,0 +1,21 @@
import Users from "../../entity/entity";
class UsersModel {
private usersList: Users[];
private modelTitle = "users";
constructor(data: Users[]) {
this.usersList = data;
}
getData(): Users[] {
return this.usersList;
}
getTitle(): string {
return this.modelTitle;
}
}
export default UsersModel;

View File

@ -0,0 +1,6 @@
export default interface Users {
profileId: string;
firstname: string;
lastname: string;
accountId: string;
}

View File

@ -0,0 +1,5 @@
import UsersModel from "../../../common/data/model/usersModel";
type IGetUsersRepo = () => Promise<UsersModel>;
export default IGetUsersRepo;

View File

@ -0,0 +1,16 @@
import UsersModel from "../../../common/data/model/usersModel";
import getUsersResponseObject from "../response-object/usersRO";
import { GetUsersResponse } from "../response-object/protocols";
const getUsersRepo = async (httpHandler: () => Promise<GetUsersResponse>) => {
// call httpHandler
const usersResponse = await httpHandler();
// user response object to turn it to the data that we want
const usersData = getUsersResponseObject(usersResponse);
// make model
const usersModel = new UsersModel(usersData);
// return the model
return usersModel;
};
export default getUsersRepo;

View File

@ -0,0 +1,18 @@
export type GetUsersResponse = {
_id: string;
account_type: string;
updated_at: string;
created_at: string;
subscription_method: string;
last_login_method: string;
account_number: null | number;
balance: number;
account_id: string;
user_data: {
_id: string;
first_name: string;
last_name: string;
avatar: string;
};
__v: number;
}[];

View File

@ -0,0 +1,16 @@
/* eslint-disable no-underscore-dangle */
import Users from "../../../common/entity/entity";
import { GetUsersResponse } from "./protocols";
const getUsersResponseObject = (apiResponse: GetUsersResponse): Users[] => {
return apiResponse.map((userItem) => {
return {
profileId: userItem._id,
firstname: userItem.user_data.first_name,
lastname: userItem.user_data.last_name,
accountId: userItem.account_id,
};
});
};
export default getUsersResponseObject;

View File

@ -0,0 +1,3 @@
import getUsers from "./infra/getUsersInfra";
export default getUsers;

View File

@ -0,0 +1,15 @@
import IGetUsersRepo from "../data/repository/IGetUserRepo";
import getUsersRepo from "../data/repository/getUserRepo";
import GettingUsersUsecase from "../usecase/getUsersUsecase";
import { IgetusersInfra, getusersReturnType } from "./protocols";
const getUsers = ({ httpHandler }: IgetusersInfra): getusersReturnType => {
// get httpHandler
const repository: IGetUsersRepo = () => getUsersRepo(httpHandler);
// connet usecase and repository
const usecase = new GettingUsersUsecase(repository);
// return method to use
return () => usecase.execute();
};
export default getUsers;

View File

@ -0,0 +1,8 @@
import UsersModel from "../../common/data/model/usersModel";
import { GetUsersResponse } from "../data/response-object/protocols";
export interface IgetusersInfra {
httpHandler: () => Promise<GetUsersResponse>;
}
export type getusersReturnType = () => Promise<UsersModel>;

View File

@ -0,0 +1,21 @@
import UsersModel from "../../common/data/model/usersModel";
import IGetUsersRepo from "../data/repository/IGetUserRepo";
/**
* this usecase is responsible for calling the repo and returning the users data from the repository
*/
class GettingUsersUsecase {
private repository: IGetUsersRepo;
constructor(repository: IGetUsersRepo) {
this.repository = repository;
}
async execute(): Promise<UsersModel> {
// call usecase and return the repo
const usersData = await this.repository();
return usersData;
}
}
export default GettingUsersUsecase;

View File

@ -3,17 +3,15 @@ import IGetPlacesPort from "~/business-logic/core/places/get-places/port";
import { HTTPPovider } from "~/driven/boundaries/http-boundary/httpBoundary"; import { HTTPPovider } from "~/driven/boundaries/http-boundary/httpBoundary";
import { HttpOptionsType } from "~/driven/boundaries/http-boundary/protocols"; import { HttpOptionsType } from "~/driven/boundaries/http-boundary/protocols";
import { apiUrls } from "~/driven/utils/configs/appConfig"; import { apiUrls } from "~/driven/utils/configs/appConfig";
import { getPlacesAdapterReturnType } from "./protocols";
const getPlacesAdapter = async (): Promise<IGetPlacesPort> => { const getPlacesAdapter = (): IGetPlacesPort & getPlacesAdapterReturnType => {
// url of api // url of api
const url = apiUrls.core.places; const url = apiUrls.core.getPlaces;
// make the options of request // make the options of request
const options: HttpOptionsType = { const options: HttpOptionsType = {
url, url,
method: "GET", method: "GET",
headers: {
"Content-Type": "application/json",
},
}; };
// make the httpHandler // make the httpHandler
const httpProvider = new HTTPPovider(); const httpProvider = new HTTPPovider();
@ -24,6 +22,7 @@ const getPlacesAdapter = async (): Promise<IGetPlacesPort> => {
// return the method // return the method
return { return {
httpHandler, httpHandler,
url,
}; };
}; };

View File

@ -0,0 +1,3 @@
export type getPlacesAdapterReturnType = {
url: string;
};

View File

@ -1,14 +1,17 @@
import axios, { AxiosRequestConfig } from "axios"; import axios from "axios";
import { staticMessages } from "~/driven/utils/constants/staticMessages"; import { staticMessages } from "~/driven/utils/constants/staticMessages";
import { ApiGlobalResponseObject } from "~/driven/utils/protocols/serviceProtocols"; import { ApiGlobalResponseObject } from "~/driven/utils/protocols/serviceProtocols";
import { HttpOptionsType } from "./protocols";
export class HTTPPovider { export class HTTPPovider {
async request<R>(customOptions: AxiosRequestConfig) { async request<R>(customOptions: HttpOptionsType) {
const options: AxiosRequestConfig = { const options: HttpOptionsType = {
...customOptions, ...customOptions,
headers: { headers: {
...customOptions.headers, ...customOptions.headers,
Authorization: `Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI4NXh0WnA5eThxVDBXVDkwUFpuUkRja3N4LWw0clVyM0tHQW5JSU9DckJNIn0.eyJleHAiOjE2ODQ1NzUyNDksImlhdCI6MTY4NDQ4ODg0OSwianRpIjoiYjI3MDUwMzYtMzMwZi00MTRkLWE2Y2QtNWRiYWUzOTRkMjczIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9kaXBhbF9kZXYiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiY2RmYzY3YzQtZGJkOC00NGVhLWI0OWEtYjQ3MjZhMzNmOTAxIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiY29tZm9ydGVjaCIsInNlc3Npb25fc3RhdGUiOiJmMzBhYzJlOS04ZTAxLTQxYjItYmI2OS0yYmMyNGEwOGRjNGUiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiZGVmYXVsdC1yb2xlcy1tYXN0ZXIiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiY29tZm9ydGVjaCI6eyJyb2xlcyI6WyJ1c2VyIiwib3BlcmF0b3IiXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsInNpZCI6ImYzMGFjMmU5LThlMDEtNDFiMi1iYjY5LTJiYzI0YTA4ZGM0ZSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiKzc3Nzc3Nzc3Nzc3In0.tzM7W8szzcN1AK3XOtgUCGbHkmWd4bnqr-jvcwBICtNbl5Dty8RxK_ONFp6g5X8wI0pVPKx4qLvWkE7jXQcg1XDZW_H1V-ucZZ_a9POffDRZ5xSNcREnjfKhw3gvjK9YSSBeMf08abDexbVSJW4rbPxtmcO9WGdZN8C1k7O-_9VHz-3NBCq7vRYBNID--xVTga_MMv3mCORzHtUdx2D7B2d7YxBAjQs5x9JCl_eXuN_IHODc2HMww-s5akquzdEKGFSfASu30NpNZucbO9XyTMkAWuV-H9Xd73eq5o-tSd0jMOfY9G1it9xLAM2Gk4xmIuUA16aLnjY7_rmm3rOypw`, mode: "cors",
credentials: "include",
Authorization: `Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI4NXh0WnA5eThxVDBXVDkwUFpuUkRja3N4LWw0clVyM0tHQW5JSU9DckJNIn0.eyJleHAiOjE2ODQ2Njc2MTEsImlhdCI6MTY4NDU4MTIxMSwianRpIjoiN2VlNzQ5ZTMtMjdhOC00ZTc1LWE4MTAtOTU0MGY5NDdmNjlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9kaXBhbF9kZXYiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiY2RmYzY3YzQtZGJkOC00NGVhLWI0OWEtYjQ3MjZhMzNmOTAxIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiY29tZm9ydGVjaCIsInNlc3Npb25fc3RhdGUiOiI3YTFlZDk2OS1lNWY2LTQzZTctOThhMy05OGQ3Zjk3YWM1NDgiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiZGVmYXVsdC1yb2xlcy1tYXN0ZXIiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiY29tZm9ydGVjaCI6eyJyb2xlcyI6WyJ1c2VyIiwib3BlcmF0b3IiXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsInNpZCI6IjdhMWVkOTY5LWU1ZjYtNDNlNy05OGEzLTk4ZDdmOTdhYzU0OCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiKzc3Nzc3Nzc3Nzc3In0.qp1GetUEy2LOZWy6Aaiwf_0d0U8wBqXJQhhuSgIO4RkkEgUnwYZ5fFupkp1iTXZMpqWAsmbRp-C0Z8nYT8Hor6XjnE73XwAVVY0Jbx6HSxtcTBOqo2IT0SmVm6z-TFpgYnErHiFZZgsqP4KYkc12xlQH4SrpN-h-oXN4ZtwuOIG65ixt2yKC-8KTyZzfZGa_8llAtnthQBtxX00MdivFpRP-NU1KfCtJqHSTKn40RNs-Nt8Gi_x7vWv9OKD8h-IIp27oOCJZNyL4aa237cuPw9IWbdiDuUAOgxkPw30i9LIDPA70GvdpRKWgLq0-itcT_hpf2RguuALDafaqoGgoGQ`,
}, },
}; };
const response = await axios<ApiGlobalResponseObject<R>>(options); const response = await axios<ApiGlobalResponseObject<R>>(options);

View File

@ -0,0 +1,3 @@
import StateManagementService from "./stateManagementService";
export default StateManagementService;

View File

@ -0,0 +1,6 @@
export default abstract class StateManagementProvider {
abstract useGetQuery<DataType>(
key: string,
httpHandler: () => Promise<DataType>
): { data: DataType | undefined; isLoading: boolean; error?: string };
}

View File

@ -0,0 +1,26 @@
import StateManagementProvider from "./stateManagementProvider";
import SwrBoundary from "./swrBoundary";
export default class StateManagementService implements StateManagementProvider {
private provider: StateManagementProvider;
constructor(provider: StateManagementProvider) {
this.provider = provider;
}
static swr() {
const stateManagement = new StateManagementService(new SwrBoundary());
return stateManagement;
}
useGetQuery<DataType>(
key: string,
httpHandler: () => Promise<DataType>
): {
data: DataType | undefined;
isLoading: boolean;
error?: string | undefined;
} {
return this.provider.useGetQuery(key, httpHandler);
}
}

View File

@ -0,0 +1,15 @@
import useSwr from "swr";
import StateManagementProvider from "./stateManagementProvider";
export default class SwrBoundary implements StateManagementProvider {
useGetQuery<DataType>(
key: string,
httpHandler: () => Promise<DataType>
): {
data: DataType | undefined;
isLoading: boolean;
error?: string | undefined;
} {
return useSwr(key, httpHandler);
}
}

View File

@ -0,0 +1,13 @@
import React from "react";
import style from "./style.module.css";
export default function Loading() {
return (
<div className={style.ldsRing}>
<div />
<div />
<div />
<div />
</div>
);
}

View File

@ -0,0 +1,35 @@
.ldsRing {
display: inline-block;
position: relative;
width: 80px;
height: 80px;
}
.ldsRing div {
box-sizing: border-box;
display: block;
position: absolute;
width: 2rem;
height: 2rem;
margin: 4px;
border: 4px solid #fff;
border-radius: 50%;
animation: ldsRing 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
border-color: var(--color-primary-main) transparent transparent transparent;
}
.ldsRing div:nth-child(1) {
animation-delay: -0.45s;
}
.ldsRing div:nth-child(2) {
animation-delay: -0.3s;
}
.ldsRing div:nth-child(3) {
animation-delay: -0.15s;
}
@keyframes ldsRing {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

View File

@ -25,6 +25,7 @@ export const routesData = {
const baseApiUrl = ENVs.apiOrigin; const baseApiUrl = ENVs.apiOrigin;
export const apiUrls = { export const apiUrls = {
core: { core: {
places: `${baseApiUrl}${ENVs.apiPlaces}`, getPlaces: `${baseApiUrl}${ENVs.apiGetPlaces}`,
getUsers: `${baseApiUrl}${ENVs.apiGetUsers}`,
}, },
}; };

View File

@ -1,4 +1,5 @@
export const ENVs = { export const ENVs = {
apiOrigin: process.env.VITE_API_ORIGIN, apiOrigin: process.env.VITE_API_ORIGIN,
apiPlaces: process.env.VITE_API_PLACES, apiGetPlaces: process.env.VITE_API_PLACES,
apiGetUsers: process.env.VITE_API_USERS,
}; };

View File

@ -1,11 +1,42 @@
import React from "react"; import React from "react";
import getPlaces from "~/business-logic/core/places/get-places";
import getPlacesAdapter from "~/driven/adapters/get-places-adapter/getPlacesAdapter";
import StateManagementService from "~/driven/boundaries/state-management";
import PlacesModel from "~/business-logic/core/places/common/model/placesModel";
import PlacesListView from "../view/PlacesListView"; import PlacesListView from "../view/PlacesListView";
import usePlacesListVM from "../viewmodel/placesListVM"; import usePlacesListVM from "../viewmodel/placesListVM";
import placesListModel from "../model/placesListModel";
const prepareTheLogicForModel = () => {
const gettingPlacesDrivenAdapter = getPlacesAdapter();
const { url } = gettingPlacesDrivenAdapter;
const getingPlacesLogic = getPlaces(gettingPlacesDrivenAdapter);
return { getingPlacesLogic, url };
};
const prepareStateManagementForVM = (
apiUrl: string,
placesModel: () => Promise<PlacesModel>
) => {
const stateManagement = StateManagementService.swr();
const useGetPlacesList = () =>
stateManagement.useGetQuery(apiUrl, placesModel);
return useGetPlacesList;
};
export default function PlacessList() { export default function PlacessList() {
const { selectedRowId, setSelectedRowId } = usePlacesListVM(); const { getingPlacesLogic, url } = prepareTheLogicForModel();
const placesModel = async () => await placesListModel(getingPlacesLogic);
const useGetPlacesList = prepareStateManagementForVM(url, placesModel);
const { selectedRowId, setSelectedRowId, placesData } = usePlacesListVM({
useGetPlacesList,
});
return ( return (
<PlacesListView <PlacesListView
placesList={placesData}
selectedRowId={selectedRowId} selectedRowId={selectedRowId}
setSelectedRowId={setSelectedRowId} setSelectedRowId={setSelectedRowId}
/> />

View File

@ -0,0 +1,10 @@
import { getPlacesModel } from "./protocols";
const placesListModel: getPlacesModel = async (getPlaces) => {
// get the method for handling the logic
const places = await getPlaces();
return places;
// handling the errors
};
export default placesListModel;

View File

@ -0,0 +1,6 @@
import PlacesModel from "~/business-logic/core/places/common/model/placesModel";
import { getPlacesReturnPort } from "~/business-logic/core/places/get-places/port";
export type getPlacesModel = (
getPlaces: getPlacesReturnPort
) => Promise<PlacesModel>;

View File

@ -1,11 +1,12 @@
import React 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 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 } = props; const { selectedRowId, setSelectedRowId, placesList } = props;
console.log(placesList.data);
const rows = () => { const rows = () => {
const placesdata = [ const placesdata = [
{ {
@ -46,6 +47,13 @@ export default function UsersListView(props: IPlacesListProps) {
}); });
}; };
if (placesList.isLoading)
return (
<div className="flex justify-center items-center">
<Loading />
</div>
);
return ( return (
<table className="table-auto rounded-md w-full text-sm"> <table className="table-auto rounded-md w-full text-sm">
<thead className="text-txt-medium font-bold"> <thead className="text-txt-medium font-bold">

View File

@ -1,4 +1,11 @@
import PlacesModel from "~/business-logic/core/places/common/model/placesModel";
export interface IPlacesListProps { export interface IPlacesListProps {
placesList: {
data: PlacesModel | undefined;
isLoading: boolean;
error?: string | undefined;
};
selectedRowId: string; selectedRowId: string;
setSelectedRowId: React.Dispatch<React.SetStateAction<string>>; setSelectedRowId: React.Dispatch<React.SetStateAction<string>>;
} }

View File

@ -1,12 +1,23 @@
import { useState } from "react"; import { useState } from "react";
import PlacesModel from "~/business-logic/core/places/common/model/placesModel";
import { placesListReturnType } from "./protocols"; import { placesListReturnType } from "./protocols";
const usePlacesListVM = (): placesListReturnType => { interface IPlacesListVM {
useGetPlacesList: () => {
data: PlacesModel | undefined;
isLoading: boolean;
error?: string | undefined;
};
}
const usePlacesListVM = (dependencies: IPlacesListVM): placesListReturnType => {
const { useGetPlacesList } = dependencies;
const placesData = useGetPlacesList();
const [selectedRowId, setSelectedRowId] = useState<string>(""); const [selectedRowId, setSelectedRowId] = useState<string>("");
return { return {
selectedRowId, selectedRowId,
setSelectedRowId, setSelectedRowId,
placesData,
}; };
}; };

View File

@ -1,6 +1,12 @@
import React from "react"; import React from "react";
import PlacesModel from "~/business-logic/core/places/common/model/placesModel";
export type placesListReturnType = { export type placesListReturnType = {
selectedRowId: string; selectedRowId: string;
setSelectedRowId: React.Dispatch<React.SetStateAction<string>>; setSelectedRowId: React.Dispatch<React.SetStateAction<string>>;
placesData: {
data: PlacesModel | undefined;
isLoading: boolean;
error?: string | undefined;
};
}; };