feat(MED-105): update orders table to be by each separate order

This commit is contained in:
2025-08-14 12:59:42 +03:00
parent 465d2e0a00
commit 4c5ec1cfac
6 changed files with 138 additions and 135 deletions

View File

@@ -7,10 +7,11 @@ import { PageBody } from '@kit/ui/makerkit/page';
import pathsConfig from '~/config/paths.config';
import { Trans } from '@kit/ui/trans';
import { HomeLayoutPageHeader } from '../../_components/home-page-header';
import OrdersTable from '../../_components/orders/orders-table';
import { withI18n } from '~/lib/i18n/with-i18n';
import type { IOrderLineItem } from '../../_components/orders/types';
import { getAnalysisOrders } from '~/lib/services/order.service';
import OrderBlock from '../../_components/orders/order-block';
import React from 'react';
import { Divider } from '@medusajs/ui';
export async function generateMetadata() {
const { t } = await createI18nServerInstance();
@@ -29,42 +30,7 @@ async function OrdersPage() {
redirect(pathsConfig.auth.signIn);
}
const analysisPackagesType = productTypes.find(({ metadata }) => metadata?.handle === 'analysis-packages');
const analysisPackageOrders: IOrderLineItem[] = medusaOrders.flatMap(({ id, items, payment_status, fulfillment_status }) => items
?.filter((item) => item.product_type_id === analysisPackagesType?.id)
.map((item) => {
const localOrder = analysisOrders.find((order) => order.medusa_order_id === id);
if (!localOrder) {
return null;
}
return {
item,
medusaOrderId: id,
orderId: localOrder?.id,
orderStatus: localOrder.status,
analysis_element_ids: localOrder.analysis_element_ids,
}
})
.filter((order) => order !== null)
|| []);
const otherOrders: IOrderLineItem[] = medusaOrders
.filter(({ items }) => items?.some((item) => item.product_type_id !== analysisPackagesType?.id))
.flatMap(({ id, items, payment_status, fulfillment_status }) => items
?.map((item) => {
const analysisOrder = analysisOrders.find((order) => order.medusa_order_id === id);
if (!analysisOrder) {
return null;
}
return {
item,
medusaOrderId: id,
orderId: analysisOrder.id,
orderStatus: analysisOrder.status,
}
})
.filter((order) => order !== null)
|| []);
const analysisPackagesType = productTypes.find(({ metadata }) => metadata?.handle === 'analysis-packages')!;
return (
<>
@@ -73,8 +39,27 @@ async function OrdersPage() {
description={<Trans i18nKey={'orders:description'} />}
/>
<PageBody>
<OrdersTable orderItems={analysisPackageOrders} title="orders:table.analysisPackage" />
<OrdersTable orderItems={otherOrders} title="orders:table.otherOrders" />
{analysisOrders.map((analysisOrder) => {
const medusaOrder = medusaOrders.find(({ id }) => id === analysisOrder.medusa_order_id);
if (!medusaOrder) {
return null;
}
const medusaOrderItems = medusaOrder.items || [];
const medusaOrderItemsAnalysisPackages = medusaOrderItems.filter((item) => item.product_type_id === analysisPackagesType?.id);
const medusaOrderItemsOther = medusaOrderItems.filter((item) => item.product_type_id !== analysisPackagesType?.id);
return (
<React.Fragment key={analysisOrder.id}>
<Divider className="my-6" />
<OrderBlock
analysisOrder={analysisOrder}
itemsAnalysisPackage={medusaOrderItemsAnalysisPackages}
itemsOther={medusaOrderItemsOther}
/>
</React.Fragment>
)
})}
</PageBody>
</>
);

View File

@@ -0,0 +1,36 @@
import { AnalysisOrder } from "~/lib/services/order.service";
import { Trans } from '@kit/ui/makerkit/trans';
import { StoreOrderLineItem } from "@medusajs/types";
import OrderItemsTable from "./order-items-table";
import Link from "next/link";
import { Eye } from "lucide-react";
export default function OrderBlock({ analysisOrder, itemsAnalysisPackage, itemsOther }: {
analysisOrder: AnalysisOrder,
itemsAnalysisPackage: StoreOrderLineItem[],
itemsOther: StoreOrderLineItem[],
}) {
return (
<div className="flex flex-col gap-4">
<h4>
<Trans i18nKey="analysis-results:orderTitle" values={{ orderNumber: analysisOrder.medusa_order_id }} />
</h4>
<div className="flex gap-2">
<h5>
<Trans i18nKey={`orders:status.${analysisOrder.status}`} />
</h5>
<Link href={`/home/order/${analysisOrder.id}`} className="flex items-center justify-between text-small-regular">
<button
className="flex gap-x-1 text-ui-fg-subtle hover:text-ui-fg-base cursor-pointer"
>
<Eye />
</button>
</Link>
</div>
<div className="flex flex-col gap-4">
<OrderItemsTable items={itemsAnalysisPackage} title="orders:table.analysisPackage" analysisOrder={analysisOrder} />
<OrderItemsTable items={itemsOther} title="orders:table.otherOrders" analysisOrder={analysisOrder} />
</div>
</div>
)
}

View File

@@ -0,0 +1,77 @@
import { Trans } from '@kit/ui/trans';
import {
Table,
TableBody,
TableHead,
TableRow,
TableHeader,
TableCell,
} from '@kit/ui/table';
import { StoreOrderLineItem } from "@medusajs/types";
import { AnalysisOrder } from '~/lib/services/order.service';
import { formatDate } from 'date-fns';
import Link from 'next/link';
import { Eye } from 'lucide-react';
export default function OrderItemsTable({ items, title, analysisOrder }: {
items: StoreOrderLineItem[];
title: string;
analysisOrder: AnalysisOrder;
}) {
if (!items || items.length === 0) {
return null;
}
return (
<Table className="rounded-lg border border-separate">
<TableHeader className="text-ui-fg-subtle txt-medium-plus">
<TableRow>
<TableHead className="px-6">
<Trans i18nKey={title} />
</TableHead>
<TableHead className="px-6">
<Trans i18nKey="orders:table.createdAt" />
</TableHead>
<TableHead className="px-6">
<Trans i18nKey="orders:table.status" />
</TableHead>
<TableHead className="px-6">
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{items
.sort((a, b) => (a.created_at ?? "") > (b.created_at ?? "") ? -1 : 1)
.map((orderItem) => (
<TableRow className="w-full" key={orderItem.id}>
<TableCell className="text-left w-[100%] px-6">
<p className="txt-medium-plus text-ui-fg-base">
{orderItem.product_title}
</p>
</TableCell>
<TableCell className="px-6 whitespace-nowrap">
{formatDate(orderItem.created_at, 'dd.MM.yyyy HH:mm')}
</TableCell>
<TableCell className="px-6 min-w-[180px]">
<Trans i18nKey={`orders:status.${analysisOrder.status}`} />
</TableCell>
<TableCell className="text-right px-6">
<span className="flex gap-x-1 justify-end w-[30px]">
<Link href={`/home/analysis-results`} className="flex items-center justify-between text-small-regular">
<button
className="flex gap-x-1 text-ui-fg-subtle hover:text-ui-fg-base cursor-pointer"
>
<Eye />
</button>
</Link>
</span>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
)
}

View File

@@ -1,43 +0,0 @@
import {
TableCell,
TableRow,
} from '@kit/ui/table';
import { Eye } from "lucide-react";
import Link from "next/link";
import { formatDate } from "date-fns";
import { IOrderLineItem } from "./types";
import { Trans } from '@kit/ui/trans';
export default function OrdersItem({ orderItem }: {
orderItem: IOrderLineItem,
}) {
return (
<TableRow className="w-full">
<TableCell className="text-left w-[100%] px-6">
<p className="txt-medium-plus text-ui-fg-base">
{orderItem.item.product_title}
</p>
</TableCell>
<TableCell className="px-6 whitespace-nowrap">
{formatDate(orderItem.item.created_at, 'dd.MM.yyyy HH:mm')}
</TableCell>
<TableCell className="px-6 whitespace-nowrap">
<Trans i18nKey={`orders:status.${orderItem.orderStatus}`} />
</TableCell>
<TableCell className="text-right px-6">
<span className="flex gap-x-1 justify-end w-[60px]">
<Link href={`/home/order/${orderItem.orderId}`} className="flex items-center justify-between text-small-regular">
<button
className="flex gap-x-1 text-ui-fg-subtle hover:text-ui-fg-base cursor-pointer"
>
<Eye />
</button>
</Link>
</span>
</TableCell>
</TableRow>
)
}

View File

@@ -1,44 +0,0 @@
import { Trans } from '@kit/ui/trans';
import {
Table,
TableBody,
TableHead,
TableRow,
TableHeader,
} from '@kit/ui/table';
import OrdersItem from "./orders-item";
import { IOrderLineItem } from "./types";
export default function OrdersTable({ orderItems, title }: {
orderItems: IOrderLineItem[];
title: string;
}) {
if (!orderItems || orderItems.length === 0) {
return null;
}
return (
<Table className="rounded-lg border border-separate">
<TableHeader className="text-ui-fg-subtle txt-medium-plus">
<TableRow>
<TableHead className="px-6">
<Trans i18nKey={title} />
</TableHead>
<TableHead className="px-6">
<Trans i18nKey="orders:table.createdAt" />
</TableHead>
<TableHead className="px-6">
<Trans i18nKey="orders:table.status" />
</TableHead>
<TableHead className="px-6">
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{orderItems
.sort((a, b) => (a.item.created_at ?? "") > (b.item.created_at ?? "") ? -1 : 1)
.map((orderItem) => (<OrdersItem key={orderItem.item.id} orderItem={orderItem} />))}
</TableBody>
</Table>
)
}

View File

@@ -1,8 +0,0 @@
import { StoreOrderLineItem } from "@medusajs/types";
export interface IOrderLineItem {
item: StoreOrderLineItem;
medusaOrderId: string;
orderId: number;
orderStatus: string;
}