leumas-private-shared
Version:
Private React JSX Package For Leumas Shared Components, Headers, Footers, Asides, Login Pages, API Key Manager and much more. Styles and everything reusable to avoid DRY code across all of our subdomains
160 lines (132 loc) • 6.44 kB
JSX
import { useTrail, animated } from 'react-spring';
import { AtomSpinner } from 'react-epic-spinners';
import {schemaToCardMapping} from '../Schemas/SchemaMapping'; // Ensure the path is correct
import {useState, useEffect} from "react"
import MultiPageForm from "../../Forms/MultiPageForm";
import {LeumasBaseStyle} from "../../styles/baseStyles"
import DefaultCard from "../../Cards/DefaultCard"
import { MdChevronLeft, MdChevronRight, MdEdit, MdDelete } from 'react-icons/md';
import { useNavigate } from 'react-router-dom';
import ToggleStatus from "./ToggleStatus"
// import {useTheme} from "../../Theme/ThemeContext"
import React from 'react';
export const ItemRenderer = ({ model, renderData, setMode, setIcon, token, baseLink = "/dashboard" }) => {
// const { theme } = useTheme();
// const bgColor = theme === 'dark' ? 'bg-black' : 'bg-white';
const [items, setItems] = useState([]);
const [isFormVisible, setIsFormVisible] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage, setItemsPerPage] = useState(3); // Adjust this number based on your preference
const lastItemIndex = currentPage * itemsPerPage;
const firstItemIndex = lastItemIndex - itemsPerPage;
const currentItems = items.slice(firstItemIndex, lastItemIndex);
const navigate = useNavigate();
const handleCardClick = (itemId) => {
navigate(`${baseLink}/${itemId}`);
};
console.log("Model " , model)
// Dynamically get the Card, Form, Tool, and Icon components based on the model
const Card = schemaToCardMapping[model]?.card;
const Form = schemaToCardMapping[model]?.form;
const Tool = schemaToCardMapping[model]?.tool;
const Icon = schemaToCardMapping[model]?.icon;
// const categoryModel = model && model.categories && model?.categories[index] ? model?.categories[index] : model;
const toggleFormVisibility = () => {
setIsFormVisible(!isFormVisible);
};
useEffect(() => {
setItems(renderData);
}, [renderData]);
useEffect(() => {
// Pass the Icon back to the parent when the model changes
setIcon(Icon);
}, [Icon, setIcon]);
const geometryBackground = "";
const depthStyle = "shadow-2xl rounded-lg";
const label3DStyle = "text-2xl shadow-3d font-bold";
const sunkenEffect = "shadow-inner border border-gray-300 rounded-lg";
const trail = useTrail(currentItems?.length || 0, {
from: { transform: 'translate3d(-100%,0,0)', opacity: 0 },
to: { transform: 'translate3d(0%,0,0)', opacity: 1 },
});
return (
<div className="p-4">
{/* Grid Section with Paginated Items */}
<div className={`${depthStyle} p-4 mb-4`}>
<h2 className={`${label3DStyle} mb-4`}>My {model || "collection(s)"}s</h2>
{currentItems && Array.isArray(currentItems) && currentItems.length > 0 ? (
<div className={`${sunkenEffect} grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 auto-rows-fr p-2`}>
{trail.map((props, index) => (
<animated.div style={props} key={currentItems[index]._id} className="relative">
<div onClick={() => handleCardClick(currentItems[index]._id)} className="cursor-pointer">
{Card
? <Card model={model} item={currentItems[index]} setMode={setMode} />
: <DefaultCard model={model} item={currentItems[index]} setMode={setMode} />
}
</div>
<div className={`absolute bottom-0 left-0 right-0 flex justify-center items-center gap-4 p-2 border rounded-b-lg `}>
<ToggleStatus />
<button
className="p-1 bg-blue-400 rounded-full hover:bg-gray-300"
onClick={() => handleEdit(currentItems[index]._id)}
aria-label="Edit Item"
>
<MdEdit size="24" />
</button>
<button
className="p-1 bg-red-200 rounded-full hover:bg-gray-300"
onClick={() => handleDelete(currentItems[index]._id)}
aria-label="Delete Item"
>
<MdDelete size="24" />
</button>
</div>
</animated.div>
))}
</div>
) : (
<div className="text-center flex items-center justify-between h-full w-full flex-col gap-4">
Sorry, we couldn't find any data in our backend
Try Creating one or pressing the fetch button once more, after selecting your type
<AtomSpinner color="red" />
</div>
)}
</div>
{/* Pagination Controls */}
<div className="flex justify-center items-center mt-4">
<button
onClick={() => setCurrentPage(currentPage - 1)}
disabled={currentPage === 1}
className="p-2 bg-red-200 rounded-full disabled:bg-red-400 mr-4"
aria-label="Previous Page"
>
<MdChevronLeft size="24" />
</button>
{/* Items count or current page indicator can go here if needed */}
<button
onClick={() => setCurrentPage(currentPage + 1)}
disabled={currentPage === Math.ceil(items.length / itemsPerPage)}
className="p-2 bg-blue-200 rounded-full disabled:bg-blue-400 ml-4"
aria-label="Next Page"
>
<MdChevronRight size="24" />
</button>
</div>
{/* MultiPageForm Area */}
<div className={`${depthStyle} p-4`}>
<h2 className={`${label3DStyle} mb-4`}>Create New</h2>
<button className={`w-full rounded-lg p-2 text-[8px] border hover:scale-105`} onClick={toggleFormVisibility} >
{isFormVisible ? "Close Form" : "Open Form"}
</button>
{isFormVisible && (
<MultiPageForm
pages={Form}
model={model}
endpoint={'LeumasAPI'}
token={token}
/>
)}
</div>
</div>
);
};