add more data

This commit is contained in:
Nông Đức Huy
2026-08-13 23:20:23 +07:00
parent 8fd23d162f
commit 57f44796ce
20 changed files with 1436 additions and 18 deletions
+23 -1
View File
@@ -1,4 +1,11 @@
import type { OffsetPaginated, PermissionGroup, RoleDetail, UserSummary } from '@sport/types';
import type {
AdminCustomer,
AdminCustomerDetail,
OffsetPaginated,
PermissionGroup,
RoleDetail,
UserSummary,
} from '@sport/types';
import type { HttpClient } from '../http-client';
@@ -44,6 +51,13 @@ export interface AdminResource {
updateUser(id: string, payload: UpdateUserPayload): Promise<UserSummary>;
resetUserPassword(id: string, password: string): Promise<{ ok: true }>;
listCustomers(params?: {
page?: number;
perPage?: number;
q?: string;
}): Promise<OffsetPaginated<AdminCustomer>>;
getCustomer(id: string): Promise<AdminCustomerDetail>;
listRoles(): Promise<RoleDetail[]>;
getRole(id: string): Promise<RoleDetail>;
listPermissions(): Promise<PermissionGroup[]>;
@@ -73,6 +87,14 @@ export function createAdminResource(http: HttpClient): AdminResource {
uncached,
),
listCustomers: (params = {}) =>
http.get<OffsetPaginated<AdminCustomer>>('/admin/customers', {
...uncached,
query: { ...params },
}),
getCustomer: (id) =>
http.get<AdminCustomerDetail>(`/admin/customers/${encodeURIComponent(id)}`, uncached),
listRoles: () => http.get<RoleDetail[]>('/admin/roles', uncached),
getRole: (id) => http.get<RoleDetail>(`/admin/roles/${encodeURIComponent(id)}`, uncached),
listPermissions: () => http.get<PermissionGroup[]>('/admin/roles/permissions', uncached),
@@ -56,6 +56,8 @@ export interface CatalogAdminResource {
images: { mediaId: string; position: number; optionValueId?: string | null }[],
): Promise<AdminProductDetail>;
setStatus(id: string, status: 'DRAFT' | 'ACTIVE' | 'ARCHIVED'): Promise<AdminProductDetail>;
/** Soft delete — the row survives for order history, see the service. */
deleteProduct(id: string): Promise<void>;
listMedia(params?: {
page?: number;
@@ -112,6 +114,7 @@ export function createCatalogAdminResource(http: HttpClient): CatalogAdminResour
{ status },
uncached,
),
deleteProduct: (id) => http.delete<void>(`/admin/products/${encodeURIComponent(id)}`, uncached),
listMedia: (params = {}) =>
http.get<OffsetPaginated<MediaAssetSummary>>('/admin/media', {
+32
View File
@@ -0,0 +1,32 @@
import type { Id, Money, Nullable } from '../primitives';
import type { CustomerAddress } from './account';
/** A shopper as the back office sees them. */
export interface AdminCustomer {
readonly id: Id;
readonly email: string;
readonly displayName: string;
readonly phone: Nullable<string>;
readonly acceptsMarketing: boolean;
readonly note: Nullable<string>;
readonly orderCount: number;
readonly addressCount: number;
/** Excludes cancelled orders — money never taken is not spend. */
readonly lifetimeSpend: Money;
readonly lastLoginAt: Nullable<string>;
readonly createdAt: string;
}
export interface AdminCustomerOrderSummary {
readonly id: Id;
readonly orderNumber: string;
readonly status: string;
readonly total: Money;
readonly placedAt: string;
}
export interface AdminCustomerDetail extends AdminCustomer {
readonly orders: readonly AdminCustomerOrderSummary[];
readonly addresses: readonly CustomerAddress[];
}
+1
View File
@@ -32,3 +32,4 @@ export * from './commerce/order';
export * from './commerce/review';
export * from './content/entry';
export * from './customers/account';
export * from './customers/admin';
+8
View File
@@ -1,6 +1,7 @@
import { z } from 'zod';
import { phoneSchema } from './common';
import { offsetPageQuerySchema } from './pagination';
/**
* The shopper's own profile.
@@ -40,3 +41,10 @@ export const wishlistItemSchema = z.object({
export type UpdateProfileInput = z.output<typeof updateProfileSchema>;
export type CustomerAddressInput = z.output<typeof customerAddressSchema>;
export type WishlistItemInput = z.output<typeof wishlistItemSchema>;
/** Back-office customer search. */
export const customerListQuerySchema = offsetPageQuerySchema.extend({
q: z.string().trim().max(120).optional(),
});
export type CustomerListQuery = z.output<typeof customerListQuerySchema>;