Files
the-pet-loft/apps/storefront/src/components/orders/detail/OrderLineItems.tsx
ianshaloom 5f7c3cece9 feat(orders): implement return request functionality and order timeline
- Added RequestReturnDialog component for initiating return requests.
- Enhanced OrderDetailPageView to handle return requests and display order timeline.
- Updated OrderActions to include return request button based on order status.
- Introduced OrderTimeline component to visualize order events.
- Modified order-related types and constants to support return functionality.
- Updated UI components for better styling and user experience.

This commit improves the order management system by allowing users to request returns and view the timeline of their orders.
2026-03-07 19:47:55 +03:00

92 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Image from "next/image";
import { Card, ScrollShadow } from "@heroui/react";
import { formatPrice } from "@repo/utils";
import type { OrderLineItem } from "@/lib/orders";
interface Props {
items: OrderLineItem[];
currency: string;
}
function LineItem({
item,
currency,
}: {
item: OrderLineItem;
currency: string;
}) {
return (
<div className="flex gap-3 py-3 first:pt-0 last:pb-0">
{/* Product image */}
<div className="relative h-16 w-16 shrink-0 overflow-hidden rounded-md border border-gray-100 bg-gray-50 md:h-20 md:w-20">
{item.imageUrl ? (
<Image
src={item.imageUrl}
alt={item.productName}
fill
className="object-cover"
sizes="(max-width: 768px) 64px, 80px"
/>
) : (
<div className="flex h-full w-full items-center justify-center text-2xl text-gray-300">
🐾
</div>
)}
</div>
{/* Item details */}
<div className="flex flex-1 flex-col justify-between gap-1 md:flex-row md:items-start">
<div className="space-y-0.5">
<p className="text-sm font-medium text-[#1a2e2d]">
{item.productName}
</p>
<p className="text-xs text-gray-500">
{item.variantName}
</p>
<p className="text-xs text-gray-400">SKU: {item.sku}</p>
</div>
<div className="flex items-center gap-2 text-sm md:flex-col md:items-end">
<span className="text-gray-500">
{item.quantity} × {formatPrice(item.unitPrice, currency)}
</span>
<span className="font-semibold text-[#236f6b]">
{formatPrice(item.totalPrice, currency)}
</span>
</div>
</div>
</div>
);
}
export function OrderLineItems({ items, currency }: Props) {
const scrollable = items.length > 4;
return (
<Card className="rounded-xl p-5">
<Card.Header>
<Card.Title className="text-base">
Items ({items.length})
</Card.Title>
</Card.Header>
<Card.Content className="p-0">
{scrollable ? (
<ScrollShadow className="max-h-[400px] px-4 pb-4" hideScrollBar>
<div className="divide-y divide-gray-100">
{items.map((item) => (
<LineItem key={item._id} item={item} currency={currency} />
))}
</div>
</ScrollShadow>
) : (
<div className="divide-y divide-gray-100 px-4 pb-4">
{items.map((item) => (
<LineItem key={item._id} item={item} currency={currency} />
))}
</div>
)}
</Card.Content>
</Card>
);
}