Files
RasadDam_Frontend/src/Pages/Products.tsx

267 lines
8.9 KiB
TypeScript
Raw Normal View History

2026-01-19 13:08:58 +03:30
import { motion } from "framer-motion";
import { useApiRequest } from "../utils/useApiRequest";
import sabos from "../assets/images/products/saboos.png";
import jo from "../assets/images/products/jo.png";
import soya from "../assets/images/products/soya.png";
import zorat from "../assets/images/products/zorat.png";
import goosfandi from "../assets/images/products/constantre-goosfandi.png";
import parvari from "../assets/images/products/constantre-parvari.png";
import porTolid from "../assets/images/products/constantre-gave-shiri-por-tolid.png";
import shiriMotevaset from "../assets/images/products/constantre-gave-shiri-motevaset.png";
import defaultImage from "../assets/images/products/default.png";
import Button from "../components/Button/Button";
import { PencilIcon, TrashIcon } from "@heroicons/react/24/outline";
import { Grid } from "../components/Grid/Grid";
import { useModalStore } from "../context/zustand-store/appStore";
import { AddProduct } from "../partials/feed-input/AddProduct";
import { getAbleToSee } from "../utils/getAbleToSee";
import { DeleteProduct } from "../partials/feed-input/DeleteProduct";
interface Category {
id: number;
name: string;
}
interface Product {
id: number;
create_date: string;
modify_date: string;
creator_info: string;
modifier_info: string;
trash: boolean;
name: string;
product_id: number;
type: string;
img: string;
created_by: number;
modified_by: number;
category: Category;
image: string;
}
export default function Products() {
const { openModal } = useModalStore();
const { data: productsData, refetch } = useApiRequest({
api: "/product/web/api/v1/product/",
method: "get",
params: { page: 1, page_size: 100 },
queryKey: ["products"],
});
const getProductImage = (name: string) => {
switch (name) {
case "سبوس":
return sabos;
case "جو":
return jo;
case "سویا":
return soya;
case "ذرت":
return zorat;
case "کنسانتره گوسفندی":
return goosfandi;
case "کنسانتره گاو شیری پر تولید":
return porTolid;
case "کنسانتره پرواری":
return parvari;
case "کنسانتره گاو شیری متوسط":
return shiriMotevaset;
default:
return defaultImage;
}
};
const container = {
hidden: { opacity: 0 },
show: {
opacity: 1,
transition: {
staggerChildren: 0.1,
},
},
};
const item = {
hidden: { y: 20, opacity: 0 },
show: {
y: 0,
opacity: 1,
transition: {
duration: 0.3,
ease: "easeOut",
},
},
};
return (
<motion.div
className="p-1 md:p-4 w-full"
initial="hidden"
animate="show"
variants={container}
>
<Grid>
<Button
className="mb-2"
size="small"
page="feed_input_products"
access="Post-Product"
variant="submit"
onClick={() => {
openModal({
title: "ایجاد محصول",
content: <AddProduct getData={refetch} />,
});
}}
>
ایجاد محصول
</Button>
</Grid>
<motion.div className=" hidden md:grid grid-cols-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-3 2xl:grid-cols-4 lg:mx-30 xl:mx-40 2xl:mx-70 gap-4 justify-items-center">
{productsData?.results?.map((product: Product) => (
<motion.div
key={product.id}
className="bg-white dark:bg-dark-600 rounded-lg shadow-md overflow-hidden flex flex-col max-w-60 w-full"
variants={item}
initial="hidden"
animate="show"
>
<div className="h-50 bg-gray-100 dark:bg-dark-700">
<img
src={
product?.img && product.img !== "empty"
? `${product.img}?t=${product.modify_date || Date.now()}`
: getProductImage(product.name)
}
alt={product.name}
className="w-full h-full object-cover dark:opacity-60"
key={`${product.id}-${product.modify_date}`}
/>
</div>
<div className="p-3 flex flex-col gap-1 text-sm text-gray-500 dark:text-dark-200">
<p className="font-extrabold">{product.name}</p>
<p>کد محصول: {product.product_id}</p>
<p
className={`text-xs p-1 px-2 rounded-lg w-12 text-center ${
product.type === "gov"
? "text-gray-600 bg-gray1-100"
: "text-gray-100 bg-gray-400"
}`}
>
{product.type === "gov" ? "دولتی" : "آزاد"}
</p>
</div>
<div className="flex justify-between items-center gap-2 px-2 pb-3 mt-auto">
<Button
page="feed_input_products"
access="Edit-Product"
onClick={() => {
openModal({
title: "ویرایش محصول",
content: <AddProduct getData={refetch} item={product} />,
});
}}
size="small"
fullWidth
className="bg-primary-500 dark:bg-dark-500 hover:bg-primary-400 dark:hover:bg-dark-400 text-white px-3 w-full rounded-lg text-sm"
>
ویرایش
</Button>
<Button
onClick={() => {
openModal({
title: "آیا از حذف محصول اطمینان دارید؟",
content: <DeleteProduct getData={refetch} item={product} />,
});
}}
page="feed_input_products"
access="Delete-Product"
size="small"
fullWidth
className="bg-white dark:bg-dark-600 text-primary-600 border w-full px-3 rounded-lg hover:bg-red-100 dark:hover:bg-dark-500 text-sm"
>
حذف
</Button>
</div>
</motion.div>
))}
</motion.div>
{/* mobile */}
<motion.div className="grid md:hidden grid-cols-1 gap-2 justify-items-center">
{productsData?.results?.map((product: Product) => (
<motion.div
key={product.id}
className="bg-white dark:bg-dark-600 rounded-lg shadow-sm border border-gray-300 overflow-hidden flex justify-between items-center p-2 w-full"
variants={item}
initial="hidden"
animate="show"
>
<div className="h-15 bg-transparent w-1/6 dark:bg-dark-700">
<img
src={
product?.img && product.img !== "empty"
? `${product.img}?t=${product.modify_date || Date.now()}`
: getProductImage(product.name)
}
alt={product.name}
className="w-15 h-full object-cover rounded-xl dark:opacity-80"
key={`${product.id}-${product.modify_date}`}
/>
</div>
<div className="p-3 flex flex-col text-xs text-gray-500 dark:text-dark-200 w-3/6">
<p className="font-extrabold">{product.name}</p>
<p>کد محصول: {product.product_id}</p>
</div>
<p
className={`text-xs p-1 px-2 rounded-lg max-w-12 text-center w-1/6 ${
product.type === "gov"
? "text-gray-600 bg-gray1-100"
: "text-gray-100 bg-gray-400"
}`}
>
{product.type === "gov" ? "دولتی" : "آزاد"}
</p>
<div className="flex justify-between items-end flex-col gap-4 w-1/6">
<button
className={`${getAbleToSee(
"feed_input_products",
"Edit-Product"
)} rounded-full text-primary-600 text-sm`}
onClick={() => {
openModal({
title: "ویرایش محصول",
content: <AddProduct getData={refetch} item={product} />,
});
}}
>
<PencilIcon className="w-5" />
</button>
<button
onClick={() => {
openModal({
title: "آیا از حذف محصول اطمینان دارید؟",
content: <DeleteProduct getData={refetch} item={product} />,
});
}}
className={`${getAbleToSee(
"feed_input_products",
"Delete-Product"
)} text-red-400 rounded-lg text-sm`}
>
<TrashIcon className="w-5" />
</button>
</div>
</motion.div>
))}
</motion.div>
</motion.div>
);
}