Files
vaishnavi-ecommerce-admin-p…/src/pages/Coupons/CouponDetails.jsx
2026-03-10 14:55:59 +05:30

155 lines
5.0 KiB
JavaScript

import { useParams, Link, useNavigate } from "react-router-dom";
import {
useGetCouponByIdQuery,
useToggleCouponStatusMutation,
} from "../../features/coupons/couponAPI";
import { ArrowLeft, Percent, Calendar, Activity } from "lucide-react";
import { formatDate } from "../../utils/formatDate";
/* ---------- Status Badge ---------- */
const StatusBadge = ({ isActive }) => (
<span
className={`px-3 py-1 rounded-full text-xs font-semibold
${isActive ? "bg-green-100 text-green-700" : "bg-red-100 text-red-700"}`}
>
{isActive ? "ACTIVE" : "INACTIVE"}
</span>
);
/* ---------- Main Component ---------- */
const CouponDetails = () => {
const { id } = useParams();
const navigate = useNavigate();
const {
data: coupon,
isLoading,
isError,
} = useGetCouponByIdQuery(id, { skip: !id });
const [toggleCouponStatus, { isLoading: toggling }] =
useToggleCouponStatusMutation();
if (isLoading) {
return (
<div className="flex justify-center items-center h-64 text-gray-600">
Loading coupon details...
</div>
);
}
if (isError || !coupon) {
return (
<div className="text-center py-10 text-red-500">
Failed to load coupon details
</div>
);
}
return (
<div className="max-w-7xl mx-auto p-6 space-y-6">
{/* Back Button */}
<div className="flex items-center gap-2 text-blue-600 hover:text-blue-800">
<ArrowLeft size={18} />
<button onClick={() => navigate(-1)} className="font-medium">
Back to Coupons
</button>
</div>
{/* Header Card */}
<div className="bg-white shadow-lg rounded-2xl p-6 flex flex-col md:flex-row justify-between items-start md:items-center gap-6">
<div>
<h2 className="text-2xl font-bold text-gray-800">{coupon.code}</h2>
<p className="text-gray-500">{coupon.description}</p>
<div className="mt-2">
<StatusBadge isActive={coupon.isActive} />
</div>
</div>
<div className="text-right space-y-2">
<p className="text-2xl font-extrabold text-green-600">
{coupon.type === "PERCENTAGE"
? `${coupon.value}% OFF`
: `${coupon.value} OFF`}
</p>
<button
onClick={() => toggleCouponStatus(coupon.id)}
disabled={toggling}
className={`px-4 py-2 rounded-lg text-sm font-semibold transition
${
coupon.isActive
? "bg-red-100 text-red-700 hover:bg-red-200"
: "bg-green-100 text-green-700 hover:bg-green-200"
}`}
>
{coupon.isActive ? "Deactivate Coupon" : "Activate Coupon"}
</button>
</div>
</div>
{/* Info Cards */}
<div className="grid md:grid-cols-3 gap-6">
{/* Discount */}
<div className="bg-gradient-to-r from-purple-50 to-purple-100 p-6 rounded-2xl shadow hover:shadow-lg transition">
<h3 className="text-gray-700 font-semibold mb-2 flex items-center gap-2">
<Percent size={16} /> Discount
</h3>
<p className="text-xl font-bold text-purple-700">
{coupon.type === "PERCENTAGE"
? `${coupon.value}%`
: `${coupon.value}`}
</p>
<p className="text-gray-600 text-sm">
Min Order: {coupon.minOrderAmount}
</p>
</div>
{/* Validity */}
<div className="bg-gradient-to-r from-blue-50 to-blue-100 p-6 rounded-2xl shadow hover:shadow-lg transition">
<h3 className="text-gray-700 font-semibold mb-2 flex items-center gap-2">
<Calendar size={16} /> Validity
</h3>
<p className="text-gray-800 text-sm">
From: {formatDate(coupon.validFrom)}
</p>
<p className="text-gray-800 text-sm">
Till: {formatDate(coupon.validUntil)}
</p>
</div>
{/* Usage */}
<div className="bg-gradient-to-r from-green-50 to-green-100 p-6 rounded-2xl shadow hover:shadow-lg transition">
<h3 className="text-gray-700 font-semibold mb-2 flex items-center gap-2">
<Activity size={16} /> Usage
</h3>
<p className="text-xl font-bold text-green-700">
{coupon.usedCount}/{coupon.maxUses}
</p>
<p className="text-gray-600 text-sm">
Remaining: {coupon.remainingUses}
</p>
</div>
</div>
{/* Extra Info */}
<div className="bg-white shadow-lg rounded-2xl p-6 text-sm text-gray-600 grid md:grid-cols-2 gap-4">
<div>
<b>Created At:</b> {formatDate(coupon.createdAt)}
</div>
<div>
<b>Last Updated:</b> {formatDate(coupon.updatedAt)}
</div>
<div>
<b>Expired:</b> {coupon.isExpired ? "Yes " : "No "}
</div>
<div>
<b>Not Started:</b> {coupon.isNotStarted ? "Yes " : "No"}
</div>
</div>
</div>
);
};
export default CouponDetails;