feat(MED-50): initial analysis package orders table

This commit is contained in:
2025-07-24 08:06:33 +03:00
parent 57e30911e9
commit 66760adc06
8 changed files with 164 additions and 1 deletions

View File

@@ -0,0 +1,49 @@
import { redirect } from 'next/navigation';
import { listOrders } from '~/medusa/lib/data/orders';
import { createI18nServerInstance } from '@/lib/i18n/i18n.server';
import { listProductTypes, retrieveCustomer } from '@lib/data';
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';
export async function generateMetadata() {
const { t } = await createI18nServerInstance();
return {
title: t('orders:title'),
};
}
async function OrdersPage() {
const customer = await retrieveCustomer();
const orders = await listOrders().catch(() => null);
const { productTypes } = await listProductTypes();
if (!customer || !orders || !productTypes) {
redirect(pathsConfig.auth.signIn);
}
const analysisPackagesType = productTypes.find(({ metadata }) => metadata?.handle === 'analysis-packages');
const analysisPackageOrders = orders.flatMap(({ id, items, payment_status, fulfillment_status }) => items
?.filter((item) => item.product_type_id === analysisPackagesType?.id)
.map((item) => ({ item, orderId: id, orderStatus: `${payment_status}/${fulfillment_status}` }))
|| []);
return (
<>
<HomeLayoutPageHeader
title={<Trans i18nKey={'orders:title'} />}
description={<Trans i18nKey={'orders:description'} />}
/>
<PageBody>
<OrdersTable orderItems={analysisPackageOrders} />
</PageBody>
</>
);
}
export default withI18n(OrdersPage);

View File

@@ -0,0 +1,44 @@
import {
TableCell,
TableRow,
} from '@kit/ui/table';
import { Eye } from "lucide-react";
import Link from "next/link";
import { formatDate } from "date-fns";
import { IAnalysisPackageOrder } from "./types";
export default function OrdersItem({ orderItem }: {
orderItem: IAnalysisPackageOrder,
}) {
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>
{orderItem.orderStatus && (
<TableCell className="px-6">
{orderItem.orderStatus}
</TableCell>
)}
<TableCell className="text-right px-6">
<span className="flex gap-x-1 justify-end w-[60px]">
<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>
)
}

View File

@@ -0,0 +1,46 @@
import { Trans } from '@kit/ui/trans';
import {
Table,
TableBody,
TableHead,
TableRow,
TableHeader,
} from '@kit/ui/table';
import OrdersItem from "./orders-item";
import { IAnalysisPackageOrder } from "./types";
const IS_SHOWN_ORDER_STATUS = true as boolean;
export default function OrdersTable({ orderItems }: {
orderItems: IAnalysisPackageOrder[];
}) {
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="orders:table.analysisPackage" />
</TableHead>
<TableHead className="px-6">
<Trans i18nKey="orders:table.createdAt" />
</TableHead>
{IS_SHOWN_ORDER_STATUS && (
<TableHead className="px-6">
</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

@@ -0,0 +1,7 @@
import { StoreOrderLineItem } from "@medusajs/types";
export interface IAnalysisPackageOrder {
item: StoreOrderLineItem;
orderId: string;
orderStatus: string;
}

View File

@@ -59,8 +59,8 @@ const pathsConfig = PathsSchema.parse({
selectPackage: '/select-package',
booking: '/home/booking',
orderAnalysisPackage: '/home/order-analysis-package',
myOrders: '/home/order',
// these routes are added as placeholders and can be changed when the pages are added
myOrders: '/my-orders',
analysisResults: '/home/analysis-results',
orderAnalysis: '/order-analysis',
orderHealthAnalysis: '/order-health-analysis',

View File

@@ -37,6 +37,7 @@ export const defaultI18nNamespaces = [
'booking',
'order-analysis-package',
'cart',
'orders',
];
/**

View File

@@ -0,0 +1,8 @@
{
"title": "Orders",
"description": "View your orders",
"table": {
"analysisPackage": "Analysis package",
"createdAt": "Ordered at"
}
}

View File

@@ -0,0 +1,8 @@
{
"title": "Tellimused",
"description": "Vaata oma tellimusi",
"table": {
"analysisPackage": "Analüüsi pakett",
"createdAt": "Tellitud"
}
}