Compare commits

...

2 Commits

Author SHA1 Message Date
0c53a578e2 wip 2026-04-29 15:27:21 +03:00
35db26c385 wip 2026-04-15 20:11:19 +03:00
12 changed files with 210 additions and 118 deletions

View File

@ -9,12 +9,13 @@ import type {
AuthUserResponse,
ChangeOrderStatusApiRequest,
CreateOrderApiRequest,
GetManagersParams,
GetOrdersParams,
LoginRequest,
Logout200,
ManagerListItemResponse,
OrderApiResponse,
RegisterManagerRequest,
UpdateOrderApiRequest
PageManagerListItemResponse,
PageOrderApiResponse,
RegisterManagerRequest
} from './models';
import { apiInstance } from './client';
@ -22,43 +23,62 @@ import type { BodyType } from './client';
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
/**
* Who can call: only MANAGER from active session, and only for orders assigned to this manager.
* @summary Edit order
*/
export const editOrder = (
export const getOrderById = (
orderId: string,
updateOrderApiRequest: BodyType<UpdateOrderApiRequest>,
options?: SecondParameter<typeof apiInstance<OrderApiResponse>>,) => {
return apiInstance<OrderApiResponse>(
{url: `/api/orders/${orderId}`, method: 'GET'
},
options);
}
export const updateOrder = (
orderId: string,
createOrderApiRequest: BodyType<CreateOrderApiRequest>,
options?: SecondParameter<typeof apiInstance<OrderApiResponse>>,) => {
return apiInstance<OrderApiResponse>(
{url: `/api/orders/${orderId}`, method: 'PUT',
headers: {'Content-Type': 'application/json', },
data: updateOrderApiRequest
data: createOrderApiRequest
},
options);
}
/**
* Who can call: MANAGER or SENIOR_MANAGER from active session. SENIOR_MANAGER sees all orders, MANAGER sees only assigned orders.
* @summary Get orders list
*/
export const getOrders = (
options?: SecondParameter<typeof apiInstance<OrderApiResponse[]>>,) => {
return apiInstance<OrderApiResponse[]>(
{url: `/api/orders`, method: 'GET'
},
options);
}
/**
* Who can call: anonymous buyer (no manager session required).
* @summary Create order
*/
export const createOrder = (
createOrderApiRequest: BodyType<CreateOrderApiRequest>,
export const deleteOrder = (
orderId: string,
options?: SecondParameter<typeof apiInstance<void>>,) => {
return apiInstance<void>(
{url: `/api/orders/${orderId}`, method: 'DELETE'
},
options);
}
export const assignManager = (
orderId: string,
assignManagerApiRequest: BodyType<AssignManagerApiRequest>,
options?: SecondParameter<typeof apiInstance<OrderApiResponse>>,) => {
return apiInstance<OrderApiResponse>(
{url: `/api/orders/${orderId}/manager`, method: 'PUT',
headers: {'Content-Type': 'application/json', },
data: assignManagerApiRequest
},
options);
}
export const getOrders = (
params?: GetOrdersParams,
options?: SecondParameter<typeof apiInstance<PageOrderApiResponse>>,) => {
return apiInstance<PageOrderApiResponse>(
{url: `/api/orders`, method: 'GET',
params
},
options);
}
export const createOrder = (
createOrderApiRequest: BodyType<CreateOrderApiRequest>,
options?: SecondParameter<typeof apiInstance<OrderApiResponse>>,) => {
return apiInstance<OrderApiResponse>(
{url: `/api/orders`, method: 'POST',
headers: {'Content-Type': 'application/json', },
data: createOrderApiRequest
@ -66,26 +86,6 @@ export const createOrder = (
options);
}
/**
* Who can call: only SENIOR_MANAGER from active session.
* @summary Assign manager to order
*/
export const assignManager = (
orderId: string,
assignManagerApiRequest: BodyType<AssignManagerApiRequest>,
options?: SecondParameter<typeof apiInstance<OrderApiResponse>>,) => {
return apiInstance<OrderApiResponse>(
{url: `/api/orders/${orderId}/manager`, method: 'POST',
headers: {'Content-Type': 'application/json', },
data: assignManagerApiRequest
},
options);
}
/**
* Who can call: currently open endpoint. Intended for MANAGER/SENIOR_MANAGER account bootstrap only.
* @summary Register manager account
*/
export const register = (
registerManagerRequest: BodyType<RegisterManagerRequest>,
options?: SecondParameter<typeof apiInstance<AuthUserResponse>>,) => {
@ -97,23 +97,15 @@ export const register = (
options);
}
/**
* Who can call: any authenticated session.
* @summary Logout current user
*/
export const logout = (
options?: SecondParameter<typeof apiInstance<Logout200>>,) => {
return apiInstance<Logout200>(
options?: SecondParameter<typeof apiInstance<void>>,) => {
return apiInstance<void>(
{url: `/api/auth/logout`, method: 'POST'
},
options);
}
/**
* Who can call: MANAGER or SENIOR_MANAGER with valid login/password. On success user is stored in HTTP session.
* @summary Login manager
*/
export const login = (
loginRequest: BodyType<LoginRequest>,
options?: SecondParameter<typeof apiInstance<AuthUserResponse>>,) => {
@ -125,10 +117,6 @@ export const login = (
options);
}
/**
* Who can call: only MANAGER from active session, and only for orders assigned to this manager.
* @summary Change order status
*/
export const changeStatus = (
orderId: string,
changeOrderStatusApiRequest: BodyType<ChangeOrderStatusApiRequest>,
@ -141,23 +129,16 @@ export const changeStatus = (
options);
}
/**
* Who can call: only SENIOR_MANAGER from active session. Returns users with role MANAGER only.
* @summary Get all managers
*/
export const getManagers = (
options?: SecondParameter<typeof apiInstance<ManagerListItemResponse[]>>,) => {
return apiInstance<ManagerListItemResponse[]>(
{url: `/api/managers`, method: 'GET'
params?: GetManagersParams,
options?: SecondParameter<typeof apiInstance<PageManagerListItemResponse>>,) => {
return apiInstance<PageManagerListItemResponse>(
{url: `/api/managers`, method: 'GET',
params
},
options);
}
/**
* Who can call: any authenticated session.
* @summary Get current session user
*/
export const me = (
options?: SecondParameter<typeof apiInstance<AuthUserResponse>>,) => {
@ -167,10 +148,12 @@ export const me = (
options);
}
export type EditOrderResult = NonNullable<Awaited<ReturnType<typeof editOrder>>>
export type GetOrderByIdResult = NonNullable<Awaited<ReturnType<typeof getOrderById>>>
export type UpdateOrderResult = NonNullable<Awaited<ReturnType<typeof updateOrder>>>
export type DeleteOrderResult = NonNullable<Awaited<ReturnType<typeof deleteOrder>>>
export type AssignManagerResult = NonNullable<Awaited<ReturnType<typeof assignManager>>>
export type GetOrdersResult = NonNullable<Awaited<ReturnType<typeof getOrders>>>
export type CreateOrderResult = NonNullable<Awaited<ReturnType<typeof createOrder>>>
export type AssignManagerResult = NonNullable<Awaited<ReturnType<typeof assignManager>>>
export type RegisterResult = NonNullable<Awaited<ReturnType<typeof register>>>
export type LogoutResult = NonNullable<Awaited<ReturnType<typeof logout>>>
export type LoginResult = NonNullable<Awaited<ReturnType<typeof login>>>

View File

@ -0,0 +1,11 @@
/**
* Generated by orval v8.7.0 🍺
* Do not edit manually.
* OpenAPI definition
* OpenAPI spec version: v0
*/
export type GetManagersParams = {
page?: number;
size?: number;
};

View File

@ -5,4 +5,7 @@
* OpenAPI spec version: v0
*/
export type Logout200 = {[key: string]: string};
export type GetOrdersParams = {
page?: number;
size?: number;
};

View File

@ -9,16 +9,16 @@ import type { OrderItemApiResponse } from './OrderItemApiResponse';
import type { OrderManagerDto } from './OrderManagerDto';
export interface OrderApiResponse {
id?: string;
customerId?: string;
customerName?: string;
customerEmail?: string;
customerPhoneNumber?: string;
id: string;
customerId: string;
customerName: string;
customerEmail: string;
customerPhoneNumber: string;
managerId?: string;
manager?: OrderManagerDto;
status?: OrderApiResponseStatus;
createdAt?: string;
updatedAt?: string;
totalAmount?: number;
items?: OrderItemApiResponse[];
status: OrderApiResponseStatus;
createdAt: string;
updatedAt: string;
totalAmount: number;
items: OrderItemApiResponse[];
}

View File

@ -6,10 +6,10 @@
*/
export interface OrderItemApiResponse {
id?: string;
productId?: string;
productName?: string;
quantity?: number;
unitPrice?: number;
lineTotal?: number;
id: string;
productId: string;
productName: string;
quantity: number;
unitPrice: number;
lineTotal: number;
}

View File

@ -0,0 +1,23 @@
/**
* Generated by orval v8.7.0 🍺
* Do not edit manually.
* OpenAPI definition
* OpenAPI spec version: v0
*/
import type { ManagerListItemResponse } from './ManagerListItemResponse';
import type { PageableObject } from './PageableObject';
import type { SortObject } from './SortObject';
export interface PageManagerListItemResponse {
totalPages?: number;
totalElements?: number;
size?: number;
content?: ManagerListItemResponse[];
number?: number;
sort?: SortObject;
first?: boolean;
last?: boolean;
numberOfElements?: number;
pageable?: PageableObject;
empty?: boolean;
}

View File

@ -0,0 +1,23 @@
/**
* Generated by orval v8.7.0 🍺
* Do not edit manually.
* OpenAPI definition
* OpenAPI spec version: v0
*/
import type { OrderApiResponse } from './OrderApiResponse';
import type { PageableObject } from './PageableObject';
import type { SortObject } from './SortObject';
export interface PageOrderApiResponse {
totalPages?: number;
totalElements?: number;
size?: number;
content?: OrderApiResponse[];
number?: number;
sort?: SortObject;
first?: boolean;
last?: boolean;
numberOfElements?: number;
pageable?: PageableObject;
empty?: boolean;
}

View File

@ -0,0 +1,16 @@
/**
* Generated by orval v8.7.0 🍺
* Do not edit manually.
* OpenAPI definition
* OpenAPI spec version: v0
*/
import type { SortObject } from './SortObject';
export interface PageableObject {
offset?: number;
sort?: SortObject;
pageNumber?: number;
pageSize?: number;
paged?: boolean;
unpaged?: boolean;
}

View File

@ -0,0 +1,12 @@
/**
* Generated by orval v8.7.0 🍺
* Do not edit manually.
* OpenAPI definition
* OpenAPI spec version: v0
*/
export interface SortObject {
empty?: boolean;
sorted?: boolean;
unsorted?: boolean;
}

View File

@ -1,18 +0,0 @@
/**
* Generated by orval v8.7.0 🍺
* Do not edit manually.
* OpenAPI definition
* OpenAPI spec version: v0
*/
import type { CreateOrderItemApiRequest } from './CreateOrderItemApiRequest';
export interface UpdateOrderApiRequest {
/** @minLength 1 */
customerName: string;
/** @minLength 1 */
phoneNumber: string;
/** @minLength 1 */
email: string;
/** @minItems 1 */
items: CreateOrderItemApiRequest[];
}

View File

@ -12,14 +12,18 @@ export * from './ChangeOrderStatusApiRequest';
export * from './ChangeOrderStatusApiRequestStatus';
export * from './CreateOrderApiRequest';
export * from './CreateOrderItemApiRequest';
export * from './GetManagersParams';
export * from './GetOrdersParams';
export * from './LoginRequest';
export * from './Logout200';
export * from './ManagerDto';
export * from './ManagerListItemResponse';
export * from './OrderApiResponse';
export * from './OrderApiResponseStatus';
export * from './OrderItemApiResponse';
export * from './OrderManagerDto';
export * from './PageableObject';
export * from './PageManagerListItemResponse';
export * from './PageOrderApiResponse';
export * from './RegisterManagerRequest';
export * from './RegisterManagerRequestRole';
export * from './UpdateOrderApiRequest';
export * from './SortObject';

View File

@ -3,8 +3,12 @@ import { assignManager, changeStatus, getManagers, getOrders } from "~/api/api";
import {
AuthUserResponseRole,
ChangeOrderStatusApiRequestStatus,
type GetManagersParams,
type GetOrdersParams,
type ManagerListItemResponse,
type OrderApiResponse,
type PageManagerListItemResponse,
type PageOrderApiResponse,
} from "~/api/models";
import type { RootStore } from "./RootStore";
@ -70,7 +74,7 @@ export class OrdersStore {
this.isLoading = true;
this.error = "";
try {
const data = await getOrders();
const data = await this.fetchAllOrders();
runInAction(() => {
this.orders = data;
});
@ -110,7 +114,7 @@ export class OrdersStore {
this.managers = [];
});
} catch {
// error state is already set by called actions
}
}
@ -118,7 +122,7 @@ export class OrdersStore {
this.isManagersLoading = true;
this.error = "";
try {
const data = await getManagers();
const data = await this.fetchAllManagers();
runInAction(() => {
this.managers = data;
});
@ -204,4 +208,35 @@ export class OrdersStore {
private shouldRefetchByNotification(type: string) {
return type === "NEW_ORDER_CREATED" || type === "ORDER_ASSIGNED" || type === "ORDER_STATUS_CHANGED";
}
private async fetchAllOrders() {
return this.fetchAllPages<OrderApiResponse, GetOrdersParams, PageOrderApiResponse>((params) => getOrders(params));
}
private async fetchAllManagers() {
return this.fetchAllPages<ManagerListItemResponse, GetManagersParams, PageManagerListItemResponse>((params) =>
getManagers(params),
);
}
private async fetchAllPages<TItem, TParams extends { page?: number; size?: number }, TPage extends {
content?: TItem[];
last?: boolean;
}>(loader: (params: TParams) => Promise<TPage>, size = 100) {
let page = 0;
const items: TItem[] = [];
while (true) {
const response = await loader({ page, size } as TParams);
items.push(...(response.content ?? []));
if (response.last ?? true) {
break;
}
page += 1;
}
return items;
}
}