267 lines
9.0 KiB
TypeScript
267 lines
9.0 KiB
TypeScript
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/LiveStock/feed-input/AddProduct";
|
||
import { getAbleToSee } from "../../utils/getAbleToSee";
|
||
import { DeleteProduct } from "../../partials/LiveStock/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>
|
||
);
|
||
}
|