party-order list ok,

This commit is contained in:
louiscklaw
2025-06-16 00:01:36 +08:00
parent 77f7211317
commit 7370316ea0
10 changed files with 135 additions and 1876 deletions

View File

@@ -25,11 +25,11 @@ export async function GET(req: NextRequest) {
const debug = { 'req.headers': flattenNextjsRequest(req) };
try {
const orders = await listPartyOrders();
const partyOrders = await listPartyOrders();
createAppLog(L_INFO, 'party-order list ok', {});
return response({ orders }, STATUS.OK);
return response({ partyOrders }, STATUS.OK);
} catch (error) {
createAppLog(L_ERROR, 'party-order list error', debug);

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
// src/actions/order.ts
// src/actions/party-order.ts
//
import { useMemo } from 'react';
import axiosInstance, { endpoints, fetcher } from 'src/lib/axios';
import type { IOrderItem } from 'src/types/party-order';
import type { IProductItem } from 'src/types/product';
import type { IPartyOrderItem } from 'src/types/party-order';
import type { SWRConfiguration } from 'swr';
import useSWR from 'swr';
import useSWR, { mutate } from 'swr';
// ----------------------------------------------------------------------
@@ -16,14 +16,14 @@ const swrOptions: SWRConfiguration = {
// ----------------------------------------------------------------------
type OrdersData = {
partyOrders: IOrderItem[];
type PartyOrdersData = {
partyOrders: IPartyOrderItem[];
};
export function useGetPartyOrders() {
const url = endpoints.partyOrder.list;
const { data, isLoading, error, isValidating, mutate } = useSWR<OrdersData>(
const { data, isLoading, error, isValidating } = useSWR<PartyOrdersData>(
url,
fetcher,
swrOptions
@@ -31,14 +31,13 @@ export function useGetPartyOrders() {
const memoizedValue = useMemo(
() => ({
orders: data?.partyOrders || [],
ordersLoading: isLoading,
ordersError: error,
ordersValidating: isValidating,
ordersEmpty: !isLoading && !isValidating && !data?.partyOrders.length,
mutate,
partyOrders: data?.partyOrders || [],
partyOrdersLoading: isLoading,
partyOrdersError: error,
partyOrdersValidating: isValidating,
partyOrdersEmpty: !isLoading && !isValidating && !data?.partyOrders.length,
}),
[data?.partyOrders, error, isLoading, isValidating, mutate]
[data?.partyOrders, error, isLoading, isValidating]
);
return memoizedValue;
@@ -46,23 +45,24 @@ export function useGetPartyOrders() {
// ----------------------------------------------------------------------
type OrderData = {
order: IOrderItem;
type PartyOrderData = {
partyOrder: IPartyOrderItem;
};
export function useGetOrder(orderId: string) {
const url = orderId ? [endpoints.order.details, { params: { orderId } }] : '';
export function useGetPartyOrder(partyOrderId: string) {
const url = partyOrderId ? [endpoints.partyOrder.details, { params: { partyOrderId } }] : '';
const { data, isLoading, error, isValidating } = useSWR<OrderData>(url, fetcher, swrOptions);
const { data, isLoading, error, isValidating } = useSWR<PartyOrderData>(url, fetcher, swrOptions);
const memoizedValue = useMemo(
() => ({
order: data?.order,
orderLoading: isLoading,
orderError: error,
orderValidating: isValidating,
partyOrder: data?.partyOrder,
partyOrderLoading: isLoading,
partyOrderError: error,
partyOrderValidating: isValidating,
mutate,
}),
[data?.order, error, isLoading, isValidating]
[data?.partyOrder, error, isLoading, isValidating]
);
return memoizedValue;
@@ -71,7 +71,7 @@ export function useGetOrder(orderId: string) {
// ----------------------------------------------------------------------
type SearchResultsData = {
results: IProductItem[];
results: IPartyOrderItem[];
};
export function useSearchProducts(query: string) {
@@ -98,129 +98,112 @@ export function useSearchProducts(query: string) {
// ----------------------------------------------------------------------
type SaveOrderData = {
name: string;
city: string;
role: string;
email: string;
state: string;
status: string;
address: string;
country: string;
zipCode: string;
company: string;
avatarUrl: string;
phoneNumber: string;
isVerified: boolean;
//
ordername: string;
password: string;
};
export async function createPartyOrder(partyOrderData: IPartyOrderItem) {
/**
* Work on server
*/
const data = { partyOrderData };
const {
data: { id },
} = await axiosInstance.post(endpoints.partyOrder.create, data);
export async function saveOrder(orderId: string, saveOrderData: SaveOrderData) {
// const url = orderId ? [endpoints.order.details, { params: { orderId } }] : '';
/**
* Work in local
*/
mutate(
endpoints.partyOrder.list,
(currentData: any) => {
const currentPartyOrders: IPartyOrderItem[] = currentData?.partyOrders;
const res = await axiosInstance.post(
//
`http://localhost:7272/api/order/saveOrder?orderId=${orderId}`,
{
data: saveOrderData,
}
const partyOrders = [...currentPartyOrders, { ...partyOrderData, id }];
return { ...currentData, partyOrders };
},
false
);
return res;
}
export async function uploadOrderImage(saveOrderData: SaveOrderData) {
console.log('uploadOrderImage ?');
// const url = orderId ? [endpoints.order.details, { params: { orderId } }] : '';
const res = await axiosInstance.get('http://localhost:7272/api/product/helloworld');
return res;
}
// ----------------------------------------------------------------------
type CreateOrderData = {
name: string;
city: string;
role: string;
email: string;
state: string;
status: string;
address: string;
country: string;
zipCode: string;
company: string;
avatarUrl: string;
phoneNumber: string;
isVerified: boolean;
//
ordername: string;
password: string;
};
export async function updatePartyOrder(partyOrderData: Partial<IPartyOrderItem>) {
/**
* Work on server
*/
const data = { partyOrderData };
await axiosInstance.put(endpoints.partyOrder.update, data);
export async function createOrder(createOrderData: CreateOrderData) {
console.log('create product ?');
// const url = productId ? [endpoints.product.details, { params: { productId } }] : '';
/**
* Work in local
*/
const res = await axiosInstance.post('http://localhost:7272/api/order/createOrder', {
data: createOrderData,
});
mutate(
endpoints.partyOrder.list,
(currentData: any) => {
const currentPartyOrders: IPartyOrderItem[] = currentData?.partyOrders;
return res;
const partyOrders = currentPartyOrders.map((partyOrder) =>
partyOrder.id === partyOrderData.id ? { ...partyOrder, ...partyOrderData } : partyOrder
);
return { ...currentData, partyOrders };
},
false
);
}
// ----------------------------------------------------------------------
type DeleteOrderResponse = {
success: boolean;
message?: string;
};
export async function deletePartyOrder(partyOrderId: string) {
/**
* Work on server
*/
const data = { partyOrderId };
await axiosInstance.patch(endpoints.partyOrder.delete, data);
export async function deletePartyOrder(orderId: string): Promise<DeleteOrderResponse> {
const url = `http://localhost:7272/api/order/deleteOrder?orderId=${orderId}`;
/**
* Work in local
*/
try {
const res = await axiosInstance.delete(url);
mutate(
endpoints.partyOrder.list,
(currentData: any) => {
const currentProducts: IPartyOrderItem[] = currentData?.partyOrders;
return {
success: true,
message: 'Order deleted successfully',
};
} catch (error) {
return {
success: false,
message: error instanceof Error ? error.message : 'Failed to delete product',
};
}
const partyOrders = currentProducts.filter((partyOrder) => partyOrder.id !== partyOrderId);
return { ...currentData, partyOrders };
},
false
);
}
// ----------------------------------------------------------------------
type ChangeStatusResponse = {
success: boolean;
message?: string;
};
// TODO: implement partyOrder changeStatus with url below
// const url = endpoints.order.changeStatus(orderId);
export async function changeStatus(partyOrderData: any, dummy: any) {
return true;
// /**
// * Work on server
// */
// const data = { partyOrderData };
// await axiosInstance.put(endpoints.partyOrder.update, data);
export async function changeStatus(
orderId: string,
newOrderStatus: string
): Promise<ChangeStatusResponse> {
const url = endpoints.order.changeStatus(orderId);
// /**
// * Work in local
// */
try {
const res = await axiosInstance.put(url, { data: { status: newOrderStatus } });
// mutate(
// endpoints.partyOrder.list,
// (currentData: any) => {
// const currentPartyOrders: IPartyOrderItem[] = currentData?.partyOrders;
return {
success: true,
message: 'status updated successfully',
};
} catch (error) {
return {
success: false,
message: error instanceof Error ? error.message : 'Failed to delete product',
};
}
// const partyOrders = currentPartyOrders.map((partyOrder) =>
// partyOrder.id === partyOrderData.id ? { ...partyOrder, ...partyOrderData } : partyOrder
// );
// return { ...currentData, partyOrders };
// },
// false
// );
}

View File

@@ -96,6 +96,8 @@ export const endpoints = {
delete: '/api/party-event/delete',
},
partyOrder: {
create: '/api/party-order/create',
delete: '/api/party-order/delete',
list: '/api/party-order/list',
profile: '/api/party-order/profile',
update: '/api/party-order/update',

View File

@@ -3,14 +3,14 @@ import type { UseSetStateReturn } from 'minimal-shared/hooks';
import { useCallback } from 'react';
import type { FiltersResultProps } from 'src/components/filters-result';
import { chipProps, FiltersBlock, FiltersResult } from 'src/components/filters-result';
import type { IOrderTableFilters } from 'src/types/party-order';
import type { IPartyOrderTableFilters } from 'src/types/party-order';
import { fDateRangeShortLabel } from 'src/utils/format-time';
// ----------------------------------------------------------------------
type Props = FiltersResultProps & {
onResetPage: () => void;
filters: UseSetStateReturn<IOrderTableFilters>;
filters: UseSetStateReturn<IPartyOrderTableFilters>;
};
export function PartyOrderTableFiltersResult({ filters, totalResults, onResetPage, sx }: Props) {

View File

@@ -20,14 +20,14 @@ import { CustomPopover } from 'src/components/custom-popover';
import { Iconify } from 'src/components/iconify';
import { Label } from 'src/components/label';
import { RouterLink } from 'src/routes/components';
import type { IOrderItem } from 'src/types/party-order';
import type { IPartyOrderItem } from 'src/types/party-order';
import { fCurrency } from 'src/utils/format-number';
import { fDate, fTime } from 'src/utils/format-time';
// ----------------------------------------------------------------------
type Props = {
row: IOrderItem;
row: IPartyOrderItem;
selected: boolean;
detailsHref: string;
onSelectRow: () => void;

View File

@@ -13,14 +13,14 @@ import { useTranslation } from 'react-i18next';
import { CustomPopover } from 'src/components/custom-popover';
import { Iconify } from 'src/components/iconify';
import type { IDatePickerControl } from 'src/types/common';
import type { IOrderTableFilters } from 'src/types/party-order';
import type { IPartyOrderTableFilters } from 'src/types/party-order';
// ----------------------------------------------------------------------
type Props = {
dateError: boolean;
onResetPage: () => void;
filters: UseSetStateReturn<IOrderTableFilters>;
filters: UseSetStateReturn<IPartyOrderTableFilters>;
};
export function PartyOrderTableToolbar({ filters, onResetPage, dateError }: Props) {

View File

@@ -12,7 +12,7 @@ import { changeStatus } from 'src/actions/party-order';
import { DashboardContent } from 'src/layouts/dashboard';
import { useTranslate } from 'src/locales';
import { paths } from 'src/routes/paths';
import type { IOrderItem } from 'src/types/party-order';
import type { IPartyOrderItem } from 'src/types/party-order';
import { OrderDetailsCustomer } from '../party-order-details-customer';
import { OrderDetailsDelivery } from '../party-order-details-delivery';
import { OrderDetailsHistory } from '../party-order-details-history';
@@ -24,7 +24,7 @@ import { OrderDetailsToolbar } from '../party-order-details-toolbar';
// ----------------------------------------------------------------------
type Props = {
order: IOrderItem;
order: IPartyOrderItem;
};
export function OrderDetailsView({ order }: Props) {

View File

@@ -36,7 +36,7 @@ import {
import { DashboardContent } from 'src/layouts/dashboard';
import { useRouter } from 'src/routes/hooks';
import { paths } from 'src/routes/paths';
import type { IOrderItem, IOrderTableFilters } from 'src/types/party-order';
import type { IPartyOrderItem, IPartyOrderTableFilters } from 'src/types/party-order';
import { fIsAfter, fIsBetween } from 'src/utils/format-time';
import { PartyOrderTableFiltersResult } from '../party-order-table-filters-result';
import { PartyOrderTableRow } from '../party-order-table-row';
@@ -50,7 +50,6 @@ const STATUS_OPTIONS = [{ value: 'all', label: 'All' }, ...PARTY_ORDER_STATUS_OP
export function PartyOrderListView() {
const { t } = useTranslation();
const router = useRouter();
const TABLE_HEAD: TableHeadCellProps[] = [
{ id: 'orderNumber', label: t('Order'), width: 88 },
@@ -62,19 +61,19 @@ export function PartyOrderListView() {
{ id: '', width: 88 },
];
const { orders, mutate, ordersLoading } = useGetPartyOrders();
const { partyOrders, partyOrdersLoading } = useGetPartyOrders();
const table = useTable({ defaultOrderBy: 'orderNumber' });
const confirmDialog = useBoolean();
const [tableData, setTableData] = useState<IOrderItem[]>([]);
const [tableData, setTableData] = useState<IPartyOrderItem[]>([]);
useEffect(() => {
setTableData(orders);
}, [orders]);
setTableData(partyOrders);
}, [partyOrders]);
const filters = useSetState<IOrderTableFilters>({
const filters = useSetState<IPartyOrderTableFilters>({
name: '',
status: 'all',
startDate: null,
@@ -107,7 +106,6 @@ export function PartyOrderListView() {
try {
await deletePartyOrder(id);
toast.success('Delete success!');
mutate();
} catch (error) {
console.error(error);
toast.error('Delete failed!');
@@ -117,7 +115,7 @@ export function PartyOrderListView() {
// setTableData(deleteRow);
// table.onUpdatePageDeleteRow(dataInPage.length);
},
[table, tableData, mutate]
[table, tableData]
);
const handleDeleteRows = useCallback(() => {
@@ -163,12 +161,9 @@ export function PartyOrderListView() {
/>
);
useEffect(() => {
mutate();
}, []);
if (!orders) return <>loading</>;
if (ordersLoading) return <>loading</>;
// TODO: remove below loading screen as mutate is not used
if (!partyOrders) return <>loading</>;
if (partyOrdersLoading) return <>loading</>;
return (
<>
@@ -324,8 +319,8 @@ export function PartyOrderListView() {
type ApplyFilterProps = {
dateError: boolean;
inputData: IOrderItem[];
filters: IOrderTableFilters;
inputData: IPartyOrderItem[];
filters: IPartyOrderTableFilters;
comparator: (a: any, b: any) => number;
};

View File

@@ -2,7 +2,7 @@ import type { IDatePickerControl, IDateValue } from './common';
// ----------------------------------------------------------------------
export type IOrderTableFilters = {
export type IPartyOrderTableFilters = {
name: string;
status: string;
endDate: IDatePickerControl;
@@ -50,7 +50,7 @@ export type IOrderProductItem = {
quantity: number;
};
export type IOrderItem = {
export type IPartyOrderItem = {
id: string;
createdAt: IDateValue;
//