Enhance dashboard UI and add order timeline
All checks were successful
Build Frontend / build (push) Successful in 1m12s
All checks were successful
Build Frontend / build (push) Successful in 1m12s
Refactored dashboard pages for improved layout and visual consistency using Card components, motion animations, and updated color schemes. Added an OrderTimeline component to the order details page to visualize order lifecycle. Improved customer management page with better sorting, searching, and a detailed customer dialog. Updated storefront settings page with a modernized layout and clearer sectioning.
This commit is contained in:
86
components/orders/order-timeline.tsx
Normal file
86
components/orders/order-timeline.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
"use client"
|
||||
|
||||
import { CheckCircle2, Circle, Clock, Package, Truck, Flag } from "lucide-react"
|
||||
import { motion } from "framer-motion"
|
||||
|
||||
interface OrderTimelineProps {
|
||||
status: string;
|
||||
orderDate: Date | string;
|
||||
paidAt?: Date | string;
|
||||
completedAt?: Date | string;
|
||||
}
|
||||
|
||||
const steps = [
|
||||
{ status: "unpaid", label: "Ordered", icon: Clock },
|
||||
{ status: "paid", label: "Paid", icon: CheckCircle2 },
|
||||
{ status: "acknowledged", label: "Processing", icon: Package },
|
||||
{ status: "shipped", label: "Shipped", icon: Truck },
|
||||
{ status: "completed", label: "Completed", icon: Flag },
|
||||
]
|
||||
|
||||
export default function OrderTimeline({ status, orderDate, paidAt }: OrderTimelineProps) {
|
||||
const currentStatusIndex = steps.findIndex(step =>
|
||||
step.status === status ||
|
||||
(status === "confirming" && step.status === "unpaid") ||
|
||||
(status === "acknowledged" && step.status === "paid") // Processed is after paid
|
||||
);
|
||||
|
||||
// If status is "confirming", it's basically "unpaid" for the timeline
|
||||
// If status is "acknowledged", it's "Processing"
|
||||
|
||||
const getStepStatus = (index: number) => {
|
||||
// Basic logic to determine if a step is completed, current, or pending
|
||||
let effectiveIndex = currentStatusIndex;
|
||||
if (status === "confirming") effectiveIndex = 0;
|
||||
if (status === "paid") effectiveIndex = 1;
|
||||
if (status === "acknowledged") effectiveIndex = 2;
|
||||
if (status === "shipped") effectiveIndex = 3;
|
||||
if (status === "completed") effectiveIndex = 4;
|
||||
|
||||
if (index < effectiveIndex) return "completed";
|
||||
if (index === effectiveIndex) return "current";
|
||||
return "pending";
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative flex justify-between items-center w-full px-4 py-8">
|
||||
{/* Connector Line */}
|
||||
<div className="absolute left-10 right-10 top-1/2 h-0.5 bg-muted -translate-y-1/2 z-0">
|
||||
<motion.div
|
||||
className="h-full bg-primary"
|
||||
initial={{ width: "0%" }}
|
||||
animate={{ width: `${(Math.max(0, steps.findIndex(s => s.status === status)) / (steps.length - 1)) * 100}%` }}
|
||||
transition={{ duration: 1, ease: "easeInOut" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{steps.map((step, index) => {
|
||||
const stepStatus = getStepStatus(index);
|
||||
const Icon = step.icon;
|
||||
|
||||
return (
|
||||
<div key={step.label} className="relative flex flex-col items-center z-10">
|
||||
<motion.div
|
||||
initial={{ scale: 0.8, opacity: 0 }}
|
||||
animate={{ scale: 1, opacity: 1 }}
|
||||
transition={{ delay: index * 0.1 }}
|
||||
className={`flex items-center justify-center w-10 h-10 rounded-full border-2 transition-colors duration-500 ${stepStatus === "completed"
|
||||
? "bg-primary border-primary text-primary-foreground"
|
||||
: stepStatus === "current"
|
||||
? "bg-background border-primary text-primary ring-4 ring-primary/10"
|
||||
: "bg-background border-muted text-muted-foreground"
|
||||
}`}
|
||||
>
|
||||
<Icon className="h-5 w-5" />
|
||||
</motion.div>
|
||||
<div className="absolute top-12 whitespace-nowrap text-xs font-medium tracking-tight">
|
||||
<p className={stepStatus === "pending" ? "text-muted-foreground" : "text-foreground"}>
|
||||
{step.label}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user