I've a map that creates edit and delete buttons.
The delete button needs to be confirmed.
So I created a modal.
console.log(additive._id) at the first delete button gives me the correct ._id
the confirm button inside the modal gives me always the last ._id of the array i map through, so it'll always delete the last item.
How can i get the correct ._id?
{additives.sort(byId).map((additive) => (
<div key={additive._id}>
<div>
<div </div>
<div>{additive.additive[0]?.label}</div>
</div>
<div className='flex justify-between items-center'>
<button
onClick={() =>
editAdditive(
additive._id,
additive.additive[0]?.value,
additive.additive[0]?.label
)
}>
Edit
</button>
<button
onClick={() => {
setShowModal(!showModal);
console.log(additive._id);
}}
>
Delete
</button>
{showModal && (
<>
<div
className='backdrop'
onClick={(e) => {
if (e.target.className === 'backdrop') {
setShowModal(false);
}
}}
>
<div className='relative w-auto my-6 mx-auto max-w-3xl'>
<div className=' rounded-lg shadow-2xl relative flex flex-col w-full bg-white outline-none focus:outline-none'>
<div className='flex items-start justify-between p-5 border-b border-solid border-slate-200 rounded-t bg-gray-600'>
<h3 className='text-3xl font-semibold text-red-500'>
Delete Additive
</h3>
</div>
<div className='relative p-6 flex-auto bg-gray-600'>
<p className='my-4 text-white text-lg leading-relaxed'>
Are you sure?
</p>
</div>
<div className='flex items-center justify-end p-6 border-t border-solid border-slate-200 rounded-b bg-gray-600'>
<button
className='text-red-500 background-transparent font-bold uppercase px-6 py-2 text-sm outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150'
type='button'
onClick={() => setShowModal(!showModal)}
>
Cancel
</button>
<button
className='bg-red-500 text-white active:bg-red-600 font-bold uppercase text-sm px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150'
type='button'
onClick={() => {
deleteAdditive(additive._id);
setShowModal(!showModal);
console.log(additive._id);
}}
>
Confirm
</button>
</div>
</div>
</div>
</div>
</>
)}
</div>
</div>
))}
store the additive id in a state and use it in the modal
const [additiveId, setAdditiveId] = useState()
<button
onClick={() => {
setShowModal(!showModal);
setAdditiveId(additive._id)
console.log(additive._id);
}}
>
Delete
</button>
<button
className='bg-red-500 text-white active:bg-red-600 font-bold uppercase text-sm px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150'
type='button'
onClick={() => {
deleteAdditive(additiveId);
setShowModal(!showModal);
console.log(additiveId);
}}
>
Confirm
</button>
Related
So i try to open modal using props from react js..., i try to console log, i found that the props is passed but the modal component is not open.. here is my try:
const [open, setOpen] = useState(false);
const openModal = () => {
setOpen(!open);
};
const handleLogin = (e) => {
e.preventDefault();
openModal();
};
<div>
{/* container */}
<div className="bg-gradient-to-r from-yellow-500 block h-screen items-center justify-center p-4 pt-32 md:flex">
{<WarnModal props={open} />}
{/* login.card */}
<div className=" bg-no-repeat bg-left bg-image flex flex-col items-center max-w-screen-lg overflow-hidden rounded-lg shadow-lg text-white w-full md:flex-row">
{/* logo */}
<div className="backdrop-blur-sm backdrop-filter flex flex-col items-center justify-center p-4 text-dark w-full md:w-1/2"> </div></div>
here is whats looks like on the modal component:
const WarnModal = ({ props }) => {
console.log("props", props);
const [open, setOpen] = useState(false);
const showModal = () => {
setOpen(props);
};
const cancelButtonRef = useRef(null);
return (
<Transition appear={true} show={open} as={Fragment}>
<Dialog
as="div"
className="relative z-10"
initialFocus={cancelButtonRef}
onClose={setOpen}
>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
</Transition.Child>
<div className="fixed inset-0 z-10 overflow-y-auto">
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg">
<div className="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div className="sm:flex sm:items-start">
<div className="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
<ExclamationTriangleIcon
className="h-6 w-6 text-red-600"
aria-hidden="true"
/>
</div>
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-gray-900"
>
Account Not Found
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-gray-500">
Please Make Sure You Have Entered The Correct Username
or Password that you used to register. Otherwise
change your password if you have forgotten it.
</p>
</div>
</div>
</div>
</div>
<div className="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
<button
type="button"
className="inline-flex w-full justify-center rounded-md border border-transparent bg-red-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 sm:ml-3 sm:w-auto sm:text-sm"
onClick={() => setOpen(false)}
>
Okay
</button>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
);
};
export default WarnModal;
can someone explained to me where did i do wrong here, i thinks the props has been pass to the component
I'm building a social media app using React, Firebase, and Tailwindcsss.
I want to add an emoji picker to the new post input and be able to add the emojis to firebase firestore.
Code:
NowPost.jsx:
const NewPost = () => {
return (
<>
<div className="bg-white rounded border border-gray-300 px-5 py-3">
<form onSubmit={handleSubmit} className="flex justify-between gap-6">
<div className="flex items-center justify-center text-white uppercase text-xl w-10 h-10 rounded-full cursor-pointer bg-green-700">
<div>{user?.displayName.charAt(0)}</div>
</div>
<input
type="text"
value={post}
onChange={(e) => setPost(e.target.value)}
className="bg-gray-200 rounded-2xl w-8/12 py-2 px-3 focus:ring-orange-500 focus:ring-1 outline-none"
placeholder="what are you thinking about?"
/>
<div>
<button
type="submit"
className="flex items-center gap-2 transition-all duration-100 bg-orange-500 hover:bg-orange-600 rounded-lg p-3 text-white"
>
Post <IoSend />
</button>
</div>
</form>
</div>
</>
);
};
how can I display my Invitee2 a bit upper in my gray bar ? And for my button how can I put it on the extrem right side of my gray bar ?
<div className="bg-gray-200 p-5 h-5 pl-2 mb-2 text-md text-primary-500 font-bold text-gray-500">
Invitee {i + 1}
<span className="float-right -mt-5">
{!!i && (
<Button primary className="rounded-md float-right mt-4" onClick={() => removeInvitee(pId)}>
- Invitee
</Button>
)}
</span>
And Button.jsx:
export default function Button({ onClick,primary,children,disabled }) {
return <button
onClick={onClick}
className={`${primary
? ' cursor-pointer rounded-md bg-primary-700 py-2 px-3 text-white hover:bg-blue-700 hover:text-white'
: 'bg-transparent text-gray border border-primary-500 hover:border-primary-100 hover:text-primary-100 transition duration-200 '}
text-primary-fg py-2 px-3 rounded-md transition-colors `}
disabled={disabled}
>{children}</button>
}
Here a picture to get the idea :
Add flex flex-row justify-between items-center in your div class
and remove the -mt-5 in span class beside float-right
check the code below
<div className="flex flex-row justify-between items-center bg-gray-200 p-5 h-5 pl-2 mb-2 text-md text-primary-500 font-bold text-gray-500">
Invitee {i + 1}
<span className="float-right">
{!!i && (
<Button primary className="rounded-md float-right mt-4" onClick={() => removeInvitee(pId)}>
- Invitee
</Button>
)}
</span>
</div>
You can use the flexbox properties to make the design you want. I had created the very similar example below , please add your functions here and replace class with className.
<script src="https://cdn.tailwindcss.com"></script>
<div class="container mx-auto py-4">
<div class="bg-gray-200 text-md flex items-center justify-between rounded-r-md">
<div class=" font-bold text-gray-500 ml-4" >Invitee 2</div>
<div class="">
<Button primary class="rounded-md bg-black text-white py-2 px-4" onclick="removeInvitee(pId)">
- Invitee
</Button>
</div>
</div>
</div>
trying to prevent default on form submission though it goes ahead and submits user input--
if I have the form onsubmit value to empty then the form prevents default.. is there solution to this?
Below is my form; on submit is empty as it prevents default when empty. though it should be going to generate as shown below...
<form className='grid' onSubmit={}>
<div className='flex'>
{/* <InputField
isRequired={true}
id='productNameField'
required={true}
className='border-solid border-2 border-gray-200 pl-3 w-full rounded-lg h-full'
type='text'
placeholder='Spotify'
label='Product Name'
onChange={onSetProductName}
/> */}
<div className=' relative '>
<label className='text-gray-700'>
Product Name
<span className='text-red-500 required-dot'>*</span>
</label>
<input
type='text'
required
className=' rounded-lg border-transparent flex-1 appearance-none border border-gray-400 w-full py-2 px-4 bg-white text-gray-700 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:ring-accent1 focus:border-transparent'
placeholder='Spotify'
onChange={onSetProductName}
/>
</div>
</div>
{/* <div className='flex pt-6'>
<InputField
id='productDescriptionField'
required={true}
className='border-solid border-2 border-gray-200 pl-3 w-full rounded-lg resize-none h-full p-1'
type='text'
placeholder='Spotify is a music service that lets you listen to music and share it with friends.'
label='Product Description'
maxRows={5}
onChange={onSetProductDescription}
multiline
/>
</div>
<div className='flex pt-6'>
<InputField
id='platformField'
required={true}
className='border-solid border-2 border-gray-200 pl-3 w-full rounded-lg h-full'
type='text'
placeholder='Instagram'
label='Platform'
onChange={onSetPlatform}
/>
</div>
<div className='flex pt-6'>
<InputField
id='audienceField'
required={true}
className='border-solid border-2 border-gray-200 pl-3 w-full rounded-lg h-full'
type='text'
placeholder='Teens'
label='Audience'
onChange={onSetAudience}
/>
</div> */}
<div className='grid'>
<div className='grid grid-cols-2 pt-6'>
{pendingCreativeAd === true ? (
<div className='grid justify-start'>
<button
type='button'
disabled={true}
className='py-2 px-4 flex justify-center items-center bg-gray-600 text-white w-full transition ease-in duration-200 text-center text-base font-semibold rounded-lg '
>
1 sec.
<LoadingIcon height={21} width={21} />
</button>
</div>
) : (
<div className='grid justify-start'>
<button
type='submit'
// onClick={generate}
className='py-2 px-4 flex justify-center items-center bg-accent1 hover:bg-blue-800 focus:bg-accent1 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none rounded-lg '
>
Generate
</button>
</div>
)}
<div className='grid justify-end'>
<button
type='button'
onClick={clearForm}
className='py-2 px-4 flex justify-center items-center bg-orange-700 hover:bg-orange-800 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:bg-orange-700 rounded-lg '
>
Clear Form
</button>
</div>
</div>
</div>
</form>
const generate = async (e) => {
e.preventDefault();
startGenAd(productName, productDescription, platform, audience);
console.log('submitting generate');
};
Just use your generate function in Form's Submit Event Instead of Button's Click Event. I think this is the easiest Approach.
set type e to
const generate = async (e: { preventDefault: () => void; }) => {
e.preventDefault();
startGenAd(productName, productDescription, platform, audience);
console.log('submitting generate');
};
I am creating a search page. You can have a search query, e.g. "Nike" and then you can click different categories or conditions.
My file structure in pages is just:
search > index.tsx
When a user changes a category or condition, the search works correctly and finds the correct results. The search query is also correct. Here is a sample query:
/search?searchQuery=nike&category=clothes
However, the page reloads, which causes UI elements to move around, expanding menu's close etc.
I need the page to research without reloading, I read that using shallow: true should avoid this behaviour but it isn't working at the moment. I am only updating the query params.
Here is my (search) index.tsx:
export default function Search() {
const [listings, setListings] = useState<null | Array<ListingObject>>(null);
const [noResultsListings, setNoResultsListings] = useState<
Array<ListingObject>
>([]);
const [loading, setLoading] = useState("idle");
const [mobileFiltersOpen, setMobileFiltersOpen] = useState(false);
const [sortBy, setSortBy] = useState("listings");
const [currentPage, setCurrentPage] = useState(0);
const [paginationData, setPaginationData] = useState<PaginationData>({
totalHits: 0,
totalPages: 0,
});
const router = useRouter();
const { query, isReady } = useRouter();
let searchClient;
if (process.env.NODE_ENV === "development") {
searchClient = algoliasearch(
process.env.NEXT_PUBLIC_ALGOLIA_TEST_APP!,
process.env.NEXT_PUBLIC_ALGOLIA_TEST_API!
);
}
useEffect(() => {
if (query && sortBy && loading === "idle" && isReady) {
console.log("Search use effect ran");
search(query, 0);
}
}, [isReady, query]);
//============================================
//When a search filter checkbox is checked/unchecked, this is called
//============================================
function handleCheck(checked: Boolean, id: string, option) {
let tempQuery = query;
if (checked) {
if (tempQuery[id]) {
tempQuery[id] += `,${option.value}`;
} else {
tempQuery[id] = `${option.value}`;
}
}
if (!checked) {
if (tempQuery[id] && tempQuery[id].toString().split(",").length > 1) {
let param = tempQuery[id].toString();
let array = param.split(",");
tempQuery[id] = array.filter((param) => param !== option.value);
} else {
delete query[id];
}
}
router.push(
{
pathname: `/search`,
query: tempQuery,
},
undefined,
{ shallow: true }
);
}
//============================================
//Where the "search" actually happens.
//============================================
async function search(query, page: number) {
if (loading === "idle") {
setListings(null);
setLoading("loading");
let listingIndex = searchClient.initIndex(sortBy);
const readyQuery = await handleSearchQuery(query);
const response = await listingIndex.search(readyQuery.searchQuery, {
numericFilters: readyQuery.filters.numericFilters,
facetFilters: readyQuery.filters.facetFilters,
page: page,
});
if (response) {
const hits = response.hits;
setPaginationData({
totalPages: response.nbPages,
totalHits: response.nbHits,
});
console.log(hits);
setListings(hits);
setLoading("idle");
}
}
}
//=========================================================
//When a user changes page, uses npm package react-paginate
//=========================================================
const handlePageClick = (data) => {
let selected = data.selected;
setCurrentPage(data.selected);
search(query, selected);
window.scrollTo(0, 0);
};
return (
<div className="flex flex-col items-center bg-white min-h-screen">
<Navbar page={"Search"} />
<div className="container">
{/* Mobile filter dialog */}
<Transition.Root show={mobileFiltersOpen} as={Fragment}>
<Dialog
as="div"
className="fixed inset-0 flex z-40 lg:hidden"
onClose={setMobileFiltersOpen}
>
<Transition.Child
as={Fragment}
enter="transition-opacity ease-linear duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity ease-linear duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Dialog.Overlay className="fixed inset-0 bg-black bg-opacity-25" />
</Transition.Child>
<Transition.Child
as={Fragment}
enter="transition ease-in-out duration-300 transform"
enterFrom="translate-x-full"
enterTo="translate-x-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="translate-x-0"
leaveTo="translate-x-full"
>
<div className="ml-auto relative max-w-xs w-full h-full bg-white shadow-xl py-4 pb-12 flex flex-col overflow-y-auto">
<div className="px-4 flex items-center justify-between">
<h2 className="text-lg font-medium text-gray-900">Filters</h2>
<button
type="button"
className="-mr-2 w-10 h-10 bg-white p-2 rounded-md flex items-center justify-center text-gray-400"
onClick={() => setMobileFiltersOpen(false)}
>
<span className="sr-only">Close menu</span>
<XIcon className="h-6 w-6" aria-hidden="true" />
</button>
</div>
{/* Filters */}
<form className="mt-4 border-t border-gray-200">
{filters.map((section) => (
<Disclosure
as="div"
key={section.id}
className="border-t border-gray-200 px-4 py-6"
>
{({ open }) => (
<>
<h3 className="-my-3 flow-root">
<Disclosure.Button className="px-2 py-3 bg-white w-full flex items-center justify-between text-gray-400 hover:text-gray-500">
<span className="font-medium text-gray-900">
{section.name}
</span>
<span className="ml-6 flex items-center">
{open ? (
<MinusSmIcon
className="h-5 w-5"
aria-hidden="true"
/>
) : (
<PlusSmIcon
className="h-5 w-5"
aria-hidden="true"
/>
)}
</span>
</Disclosure.Button>
</h3>
<Disclosure.Panel className="pt-6">
<div className="space-y-6">
{section.options.map((option, optionIdx) => (
<div
key={option.value}
className="flex items-center"
>
<input
checked={router?.query[
section.id
]?.includes(option.value)}
id={`filter-mobile-${section.id}-${optionIdx}`}
name={`${section.id}[]`}
defaultValue={option.value}
type="checkbox"
className="h-4 w-4 border-gray-300 rounded text-indigo-600 focus:ring-indigo-500"
/>
<label
htmlFor={`filter-mobile-${section.id}-${optionIdx}`}
className="ml-3 min-w-0 flex-1 text-gray-500"
>
{option.label}
</label>
</div>
))}
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
))}
</form>
</div>
</Transition.Child>
</Dialog>
</Transition.Root>
<main className="w-full mx-auto px-4 md:px-0">
{listings?.length > 0 && (
<div className="flex flex-col relative z-30 md:items-center justify-between pb-6 md:flex-row">
<div className="flex items-center mt-8">
<Menu as="div" className="relative inline-block text-left">
<Menu.Button className="group inline-flex justify-center text-sm font-medium text-gray-700 hover:text-gray-900">
{" "}
{sortOptions.find((item) => item.value === sortBy).label}
<ChevronDownIcon
className="flex-shrink-0 -mr-1 ml-1 h-5 w-5 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
</Menu.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="origin-top-right absolute left-0 md:right-0 mt-2 w-48 p-0 shadow-2xl bg-white ring-1 ring-black ring-opacity-5 focus:outline-none z-30">
<div>
{sortOptions.map((option) => (
<Menu.Item key={option.value}>
{({ active }) => (
<button
className={classNames(
sortBy === option.value
? "font-medium text-gray-900"
: "text-gray-500",
active ? "bg-gray-100" : "",
"block px-4 py-2 text-sm w-full text-left"
)}
onClick={() => {
setSortBy(option.value);
}}
>
{option.label}
</button>
)}
</Menu.Item>
))}
</div>
</Menu.Items>
</Transition>
</Menu>
<button
type="button"
className="p-2 -m-2 ml-4 sm:ml-6 text-gray-400 hover:text-gray-500 lg:hidden"
onClick={() => setMobileFiltersOpen(true)}
>
<span className="sr-only">Filters</span>
<FilterIcon className="w-5 h-5" aria-hidden="true" />
</button>
</div>
</div>
)}
<section className="flex w-full">
<div className="hidden md:grid grid-cols-1 lg:grid-cols-1 min-h-screen w-1/5 lg:pr-4">
{/* Filters */}
<form className="hidden h-full overflow-y-auto md:inline-block">
{listings?.length > 0 &&
filters.map((section) => (
<Disclosure
as="div"
key={section.id}
className="border-gray-200 py-6"
>
{({ open }) => (
<>
<h3 className="-my-3 flow-root">
<Disclosure.Button className="py-3 bg-white w-full flex items-center justify-between text-sm text-gray-400 hover:text-gray-500">
<span className="font-medium text-gray-900">
{section.name}
</span>
<span className="ml-6 flex items-center">
{open ? (
<MinusSmIcon
className="h-5 w-5"
aria-hidden="true"
/>
) : (
<PlusSmIcon
className="h-5 w-5"
aria-hidden="true"
/>
)}
</span>
</Disclosure.Button>
</h3>
<Disclosure.Panel className="pt-6">
<div className="space-y-4 px-1">
{section.options.map((option, optionIdx) => (
<div
key={option.value}
className="flex items-center"
>
<input
checked={
query[section.id] &&
query[section.id]
?.toString()
.split(",")
.includes(option.value)
? true
: false
}
id={`filter-${section.id}-${optionIdx}`}
name={`${section.id}[]`}
type="checkbox"
className="checkbox"
onChange={(e) => {
handleCheck(
e.target.checked,
section.id,
option
);
}}
/>
<label
htmlFor={`filter-${section.id}-${optionIdx}`}
className="ml-3 text-sm text-gray-600"
>
{option.label}
</label>
</div>
))}
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
))}
</form>
</div>
{/* Product grid */}
<ul
role="list"
className="h-full w-full grid grid-cols-1 py-4 gap-8 md:grid-cols-4 md:w-4/5 md:p-4 xl:gap-x-8"
>
{!listings && <SearchGridSkeleton />}
{listings?.length > 0 &&
listings.map((listing) => (
<ListingCard
key={listing.docID}
listing={listing}
type={"normal"}
/>
))}
{listings?.length === 0 && (
<div className="w-full h-full flex flex-col items-center justify-center col-span-4 relative py-8">
<h2 className="text-lg font-semibold text-center">
Oops, we found no results for "
<span className="underline text-blue-600">
{query.searchQuery}
</span>
"
</h2>
<div className="mt-16 flex flex-col justify-center items-center w-full md:w-3/4">
<h3 className="text-base font-semibold">
You may also like:
</h3>
<div className="w-full grid gap-8 mt-8 border-t pt-8 grid-cols-1 md:grid-cols-3">
{noResultsListings?.map((listing: ListingObject) => (
<ListingCard
className="col-span-1"
key={listing.docID}
type="normal"
listing={listing}
/>
))}
</div>
</div>
</div>
)}
</ul>
</section>
{listings?.length > 0 && (
<ReactPaginate
previousLabel={
<span className="flex items-center">
<ArrowNarrowLeftIcon
className="mr-3 h-5 w-5 text-gray-400"
aria-hidden="true"
/>{" "}
Previous
</span>
}
nextLabel={
<span className="flex items-center">
Next{" "}
<ArrowNarrowRightIcon
className="ml-3 h-5 w-5 text-gray-400"
aria-hidden="true"
/>
</span>
}
breakLabel={"..."}
breakClassName={"break-me"}
pageCount={paginationData.totalPages}
marginPagesDisplayed={2}
pageRangeDisplayed={10}
onPageChange={handlePageClick}
disabledClassName={"opacity-20"}
pageClassName={
"border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 border-t-2 pt-4 px-4 inline-flex items-center text-sm font-medium"
}
containerClassName={
"border-t border-gray-200 px-4 flex items-center justify-center sm:px-0 pb-8"
}
activeClassName={"border-indigo-500 text-indigo-600"}
nextClassName={
"border-t-2 border-transparent pt-4 pr-1 inline-flex items-center text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 ml-auto"
}
previousClassName={
"border-t-2 border-transparent pt-4 pr-1 inline-flex items-center text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 mr-auto"
}
initialPage={0}
/>
)}
</main>
</div>
<Footer />
</div>
);
}