feat(MED-105): update orders table to be by each separate order
This commit is contained in:
@@ -7,10 +7,11 @@ import { PageBody } from '@kit/ui/makerkit/page';
|
|||||||
import pathsConfig from '~/config/paths.config';
|
import pathsConfig from '~/config/paths.config';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
import { HomeLayoutPageHeader } from '../../_components/home-page-header';
|
import { HomeLayoutPageHeader } from '../../_components/home-page-header';
|
||||||
import OrdersTable from '../../_components/orders/orders-table';
|
|
||||||
import { withI18n } from '~/lib/i18n/with-i18n';
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
||||||
import type { IOrderLineItem } from '../../_components/orders/types';
|
|
||||||
import { getAnalysisOrders } from '~/lib/services/order.service';
|
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() {
|
export async function generateMetadata() {
|
||||||
const { t } = await createI18nServerInstance();
|
const { t } = await createI18nServerInstance();
|
||||||
@@ -29,42 +30,7 @@ async function OrdersPage() {
|
|||||||
redirect(pathsConfig.auth.signIn);
|
redirect(pathsConfig.auth.signIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
const analysisPackagesType = productTypes.find(({ metadata }) => metadata?.handle === 'analysis-packages');
|
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)
|
|
||||||
|| []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -73,8 +39,27 @@ async function OrdersPage() {
|
|||||||
description={<Trans i18nKey={'orders:description'} />}
|
description={<Trans i18nKey={'orders:description'} />}
|
||||||
/>
|
/>
|
||||||
<PageBody>
|
<PageBody>
|
||||||
<OrdersTable orderItems={analysisPackageOrders} title="orders:table.analysisPackage" />
|
{analysisOrders.map((analysisOrder) => {
|
||||||
<OrdersTable orderItems={otherOrders} title="orders:table.otherOrders" />
|
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>
|
</PageBody>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
36
app/home/(user)/_components/orders/order-block.tsx
Normal file
36
app/home/(user)/_components/orders/order-block.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
77
app/home/(user)/_components/orders/order-items-table.tsx
Normal file
77
app/home/(user)/_components/orders/order-items-table.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -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>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import { StoreOrderLineItem } from "@medusajs/types";
|
|
||||||
|
|
||||||
export interface IOrderLineItem {
|
|
||||||
item: StoreOrderLineItem;
|
|
||||||
medusaOrderId: string;
|
|
||||||
orderId: number;
|
|
||||||
orderStatus: string;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user