UNPKG

leumas-universal-crud-react

Version:

Leumas Universal CRUD to a dynamic Endpoint, Setup your own Dynamic Endpoint and Use Leumas API to send to your MONGO clusters

159 lines (130 loc) 6.35 kB
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 DefaultCard from "leumas-react-cards" import { MdChevronLeft, MdChevronRight, MdEdit, MdDelete } from 'react-icons/md'; import { useNavigate } from 'react-router-dom'; import ToggleStatus from "./ToggleStatus" import {useTheme} from "../../Theme/ThemeContext" 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 ${bgColor}`}> <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> ); };