validateDOMNesting(...): <td> cannot appear as a child of <tbody>. even the Structure is ok - reactjs

The structure is ok but I do get this error
But I dont have any <td> inside <tbody> only <td>s inside <tr>
my code is
<table className="min-w-full divide-y divide-gray-200 ">
<thead className="bg-gray-100">
<tr>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<input
onChange={(e) => {
setAllChecked(!allChecked);
setData(data.map(item => {
return {...item, isChecked: !allChecked}
}))
if (allChecked) {
setSelectedRows([])
} else if (!allChecked) {
setSelectedRows(data);
}
}}
checked={allChecked}
id="remember-me"
name="remember-me"
type="checkbox"
className="h-4 w-4 text-red-600 focus:ring-red-500 border-gray-300 rounded"
/>
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Product Name / Product id
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Product Category
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Brand
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Price
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Stock
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Status
</th>
<th scope="col" className="relative px-6 py-3">
<span className="sr-only">Action</span>
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{data.length > 0 ? <>
{data.map((product) => (
<tr
className={`${data.indexOf(product) % 2 === 0 ? 'bg-gray-50' : 'bg-white'}`}
key={product.id}>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<input
onChange={() => {
setData(data.map((item) => {
if (item.id === product.id) {
item.isChecked = !item.isChecked;
}
return item;
}));
setSelectedRows(data.filter((item) => item.isChecked));
}}
checked={product.isChecked}
id="remember-me"
name="remember-me"
type="checkbox"
className="h-4 w-4 text-red-600 focus:ring-red-500 border-gray-300 rounded"
/>
</td>
<td className="px-6 pl-2 py-4 whitespace-nowrap">
<div className="flex items-center">
<div className="ml-4">
<div
className="text-sm font-medium text-gray-900">{product.name.length > 20 ? product.name.slice(0, 20) + '...' : product.name}</div>
<div className="text-sm text-gray-500">{product.id}</div>
</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center">
<div className="ml-4">
<div
className="text-sm font-medium text-gray-900">{product.category}</div>
<div
className="text-sm text-gray-500">{product.mainProductCategory}</div>
</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm text-gray-900">{product.brand}</div>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">$ {product.price}</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{product.stock}</td>
<td className="px-6 py-4 whitespace-nowrap">
{product.isPublished ? <>
<span
className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">Published</span></>
: <>
<span
className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Not Published</span>
</>}
</td>
<td className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<span className="relative z-0 inline-flex shadow-sm rounded-md">
<button
onClick={(x) => {
changePublishedStatus(product.id, !product.isPublished)
}}
type="button"
className={`relative inline-flex items-center py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:z-10 focus:outline-none focus:ring-1 focus:ring-red-500 focus:border-red-500 ${product.isPublished ? 'px-4' : 'px-6'}`}
>
{product.isPublished ? 'Unpublish' : 'Publish'}
</button>
<button
type="button"
className="-ml-px relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:z-10 focus:outline-none focus:ring-1 focus:ring-red-500 focus:border-red-500"
>
Edit
</button>
<button
onClick={() => {
deleteProduct(product.id)
}}
type="button"
className="-ml-px relative inline-flex items-center px-4 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:z-10 focus:outline-none focus:ring-1 focus:ring-red-500 focus:border-red-500 "
>
Delete
</button>
</span>
</td>
</tr>
))}
</> : <>
<tr>
<td></td>
<td></td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<span
className="inline-flex items-center px-2.5 py-0.5 rounded-md text-sm font-medium bg-red-100 text-red-800">
No results found. Please refine your search or add Products.
</span>
</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</>}
</tbody>
</table>
how to fix this

Related

Why isn't col-span spanning the full table width

This is my table code, using React and Tailwind CSS. There is one peculiarity: when col-span turns 8, it works as expected. But when it turns 12, it breaks.
I want the table to expand to 12 cols, but it only expands to 10. If I use 11 or 12 it goes to 1, no matter what I used for colspan.
<div className={`flex flex-col lg:col-span-${order.smopen ? 8 : 12}`}>
<div className="overflow-x-auto">
<div className="align-middle inline-block min-w-full">
<div className="shadow overflow-hidden border-b border-gray-200">
<table
className={`min-w-full divide-y divide-gray-200 lg:col-span-${
order.smopen ? 8 : 12
}`}
>
<thead
className={`min-w-full divide-y divide-gray-200 lg:col-span-${
order.smopen ? 8 : 12
}`}
>
<tr>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Тема
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Дедлайн
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Статус
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Сумма
</th>
</tr>
</thead>
<tbody
className={`min-w-full divide-y divide-gray-200 lg:col-span-${
order.smopen ? 8 : 12
}`}
>
{orders.map((order, orderIdx) => (
<tr
onClick={() =>
orderDispatch({
type: "selected",
payload: {
smopen: true,
title: order.title,
dateDeadline: new Date(order.dateDeadline).toLocaleString(
"ru-RU",
{
year: "numeric",
month: "long",
day: "numeric",
}
),
status: order.status,
sum: order.sum,
},
})
}
key={order.id}
className={
orderIdx % 2 === 0
? "bg-white hover:bg-gray-100 cursor-pointer transition-all ease-in-out"
: "transition-all ease-in-out cursor-pointer bg-gray-50 hover:bg-gray-100"
}
>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
{order.title}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{new Date(order.dateDeadline).toLocaleString("ru-RU", {
year: "numeric",
month: "long",
day: "numeric",
})}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{orderTypeSwitch(order.status)}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{order.sum} ₽
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>;
How can I fix this to have my table span the whole 12 columns?

Passing function to modal in ReactJs

In an application in ReactJs, I am trying to use a modal to confirm the deletion of a user. Normally I have a delete function created in the users table that deletes a user from my database. Now I would like to pass this functionality to the modal. I am wondering how I can easily pass the delete function to the modal. That when I confirm the delete action in modal a user is deleted. I would be grateful for any guidance.
MyModal.js
import React from "react";
export default function MyModal() {
const [showModal, setShowModal] = React.useState(false);
return (
<>
<button
className="bg-red-600 text-white active:bg-pink-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={() => setShowModal(true)}
>
Delete
</button>
{showModal ? (
<>
<div className="justify-center items-center flex overflow-x-hidden overflow-y-auto fixed inset-0 z-50 outline-none focus:outline-none">
<div className="relative w-auto my-6 mx-auto max-w-3xl">
{/*content*/}
<div className="border-0 rounded-lg shadow-lg relative flex flex-col w-full bg-white outline-none focus:outline-none">
{/*header*/}
<div className="flex items-start justify-between p-5 border-b border-solid border-slate-200 rounded-t">
<h3 className="text-3xl font-semibold">Modal Title</h3>
<button
className="p-1 ml-auto bg-transparent border-0 text-black opacity-5 float-right text-3xl leading-none font-semibold outline-none focus:outline-none"
onClick={() => setShowModal(false)}
>
<span className="bg-transparent text-black opacity-5 h-6 w-6 text-2xl block outline-none focus:outline-none">
×
</span>
</button>
</div>
{/*body*/}
<div className="relative p-6 flex-auto">
<p className="my-4 text-slate-500 text-lg leading-relaxed">
Are you sure you want to delete this user?
</p>
</div>
{/*footer*/}
<div className="flex items-center justify-end p-6 border-t border-solid border-slate-200 rounded-b">
<button
className="text-blue-600 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(false)}
>
Close
</button>
<button
className="bg-red-600 text-white active:bg-emerald-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={() => setShowModal(false)}
>
Delete
</button>
</div>
</div>
</div>
</div>
<div className="opacity-25 fixed inset-0 z-40 bg-black"></div>
</>
) : null}
</>
);
}
ManageUser.js
import { useEffect, useState } from "react";
import { useAuthContext } from "../hooks/useAuthContext";
import MyModal from "../components/MyModal"
import LoadingSpinner from "../components/LoadingSpinner";
function ManageUser() {
const [users, setUser] = useState([]);
const [loading, setLoading] = useState(false)
useEffect(() => {
getData();
}, []);
async function deleteOperation(_id) {
let result = await fetch(`/api/user/${_id}`, {
method: "DELETE",
});
result = await result.json();
console.warn(result);
getData();
}
async function getData() {
setLoading(true)
let result = await fetch("/api/user/users");
result = await result.json();
setUser(result);
setLoading(false)
}
return (
<div>
<h1 className="flex justify-center py-4 text-xl font-bold">Zarządzaj użytkownikami:</h1>
<div className="flex justify-center py-2">
<div className="flex justify-between items-center h-30 max-w-[1240px] mx-auto px-4">
{ loading ? (<div className="flex justify-center items-center "><LoadingSpinner/></div>) :
<div className=" overflow-x-auto relative shadow-md sm:rounded-lg">
<table className="w-full text-sm text-center text-white">
<thead className="text-xs text-white uppercase bg-rgba(6, 18, 36, 0.945)">
<tr>
<th scope="col" className="py-3 px-6">
Nazwa
</th>
<th scope="col" className="py-3 px-6 hidden sm:table-cell">
Email
</th>
<th scope="col" className="py-3 px-6">
Admin
</th>
<th scope="col" className="py-3 px-6">
</th>
</tr>
</thead>
<tbody>
{users.map((user) => (
<tr key={user._id} user={user} className="bg-rgba(6, 18, 36, 0.945) border-b border-[#00df9a] ">
<th scope="row" className="py-4 px-6 font-medium text-white whitespace-nowrap">
{user.name}
</th>
<td className="py-4 px-6 hidden sm:table-cell">
{user.email}
</td>
<td className="py-4 px-6">
{user.isAdmin ? "Tak" : "Nie"}
</td>
<td className="py-4 px-6 text-right">
<MyModal/><button className="bg-red-500 hover:bg-[#00df9a] text-white font-semibold py-2 px-4 border border-zinc-900 rounded shadow" onClick={() => deleteOperation(user._id)}>Delete</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
}
</div>
</div>
</div>
);
}
export default ManageUser;
Is there any quick way to pass the function that I use for deleting a user to this modal?
You could just pass a property to your model component, lets call it onSubmit
export default function MyModal( { onSubmit } ) {
Within your modal you can handle the submitting with a submitHandler like
const submitHandler = () => {
setShowModal(false);
onSubmit();
}
Your delete button in the MyModal can call this submitHandler like
<button onClick={submitHandler}>
Delete
</button>
and within your ManageUser component you could pass the deleteOperation as the onSubmit function like
<MyModal onSubmit={() => deleteOperation(user.id)}/>

How to select and get all the values of rows and columns of Table in React js on Click and pass it to other Component...Help Me im stuck in this

So I have Created Custom Table Component for my data to show and i want to get all the rows value with the Heading on Click of it and pass it to any component
This is COde of my table Component
import PlaceBett from "./PlaceBett";
const MatchBetTable = ({ data }) => {
const [showPlaceBet, setShowPlaceBet] = useState(false);
const [team1Back, setTeam1Back] = useState("");
const [team1Lay, setTeam1Lay] = useState("");
const [team2Lay, setTeam2Lay] = useState("");
const [team2Back, setTeam2Back] = useState("");
const [drawLay, SetDrawLay] = useState("");
const [drawBack, SetDrawBack] = useState("");
const handleClick = () => {
setShowPlaceBet((prev) => !prev);
};
// console.log(data.values[0].val1);
console.log(data);
return (
<>
{showPlaceBet && (
<PlaceBett
data={data}
team1Back={team1Back}
team1Lay={team1Lay}
team2Back={team2Back}
team2Lay={team2Lay}
drawBack={drawBack}
drawLay={drawLay}
/>
)}
<table className="table-auto mb-4 text-black w-full ">
<thead className="bg-gray-500 md:p-5 p-1 text-sm">
<tr>
<th className="md:p-5 p-1 text-sm">{data.name}</th>
<th className="md:p-5 p-1 text-sm" colSpan="5"></th>
<th className="md:p-5 p-1 text-sm">BET DELAY-3 SEC</th>
</tr>
</thead>
<thead>
<tr
className="bg-white md:p-5 p-1 text-sm border border-table_border"
onClick={handleClick}
>
<th className="md:p-5 p-1 text-sm">MAX 50000</th>
<th className="md:p-5 p-1 text-sm" colSpan="2"></th>
<th className="md:p-5 p-1 text-sm bg-table_row-blue border border-table_border ">
BACK <p>(Back)</p>
</th>
<th className="md:p-5 p-1 text-sm text-black bg-table_row-cream border border-table_border">
LAY <p>(lay)</p>
</th>
<th className="md:p-5 p-1 text-sm" colSpan="2"></th>
</tr>
</thead>
<tbody>
<tr className="md:p-5 p-1 text-sm border border-table_border text-center">
<td className="bg-gray-300 md:p-5 p-1 text-sm">
{data.values[0].val1 === null ? "-" : data.values[0].val1}
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-blue border border-table_border">
-<p>(-)</p>
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-blue border border-table_border ">
-<p>(-)</p>
</td>
<td
dataTitle={data.values[0].odds}
className="md:p-5 p-1 text-sm bg-table_row-blue border border-table_border "
onClick={(e) => {
console.log(e.target.innerHTML);
setTeam1Back(e.target.innerHTML);
console.log("team1Back", team1Back);
}}
>
{data.values[0].odds === null ? "-" : data.values[0].odds}
</td>
{/* {!data.values.odds && (
<td className="md:p-5 p-1 text-sm bg-table_row-blue border border-table_border ">
0<p>(-)</p>
</td>
)} */}
<td className="md:p-5 p-1 text-sm bg-table_row-cream border border-table_border ">
{data.values[0].val2 === null ? 0 : data.values[0]?.val2}
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-cream border border-table_border ">
-<p>(-)</p>
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-cream border border-table_border ">
-<p>(-)</p>
</td>
</tr>
{data.values[1] && (
<tr className="md:p-5 p-1 text-sm border border-table_border text-center">
<td className="bg-gray-300 md:p-5 p-1 text-sm">
{data.values[1]?.val1}
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-blue border border-table_border ">
-<p>(-)</p>
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-blue border border-table_border ">
-<p>(-)</p>
</td>
<td
className="md:p-5 p-1 odd:bg-table_row-cream text-sm bg-table_row-blue border border-table_border"
onClick={(e) => SetDrawBack(e.target.value)}
>
{data.values[1]?.odds}
</td>
<td
className="md:p-5 p-1 text-sm bg-table_row-cream border border-table_border"
onClick={(e) => SetDrawLay(e.target.value)}
>
{data.values[1]?.val2 === null && "0"}
{data.values[1]?.val2 && data.values[1]?.val2}
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-cream border border-table_border">
-<p>(-)</p>
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-cream border border-table_border">
-<p>(-)</p>
</td>
</tr>
)}
{data?.values[2] && (
<tr className="md:p-5 p-1 text-sm border border-table_border text-center">
<td className="bg-gray-300 md:p-5 p-1 text-sm">
{data?.values[2] && data.values[2]?.val1}
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-blue border border-table_border ">
-<p>(-)</p>
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-blue border border-table_border ">
-<p>(-)</p>
</td>
<td
className="md:p-5 p-1 odd:bg-table_row-cream text-sm bg-table_row-blue border border-table_border"
onClick={(e) => setTeam2Back(e.target.value)}
>
{data?.values[2] && data.values[2]?.odds}
</td>
<td
className="md:p-5 p-1 text-sm bg-table_row-cream border border-table_border"
onClick={(e) => setTeam2Lay(e.target.value)}
>
{data.values[2]?.val2 === null && "0"}
{data.values[2]?.val2 && data.values[2]?.val2}
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-cream border border-table_border">
-<p>(-)</p>
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-cream border border-table_border">
-<p>(-)</p>
</td>
</tr>
)}
</tbody>
</table>
</>
);
};
export default MatchBetTable;
i want the values in state like i used Team1Back and Team1Lay...and pass it to the placeBet Component after clicking particular row...
Cant you do something like this?
<>
{data.values.map((bet) => (
<tr className="md:p-5 p-1 text-sm border border-table_border text-center">
<td className="bg-gray-300 md:p-5 p-1 text-sm">{bet?.val1}</td>
<td className="md:p-5 p-1 text-sm bg-table_row-blue border border-table_border ">
-<p>(-)</p>
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-blue border border-table_border ">
-<p>(-)</p>
</td>
<td
className="md:p-5 p-1 odd:bg-table_row-cream text-sm bg-table_row-blue border border-table_border"
onClick={(e) => SetDrawBack(e.target.value)}
>
{bet?.odds}
</td>
<td
className="md:p-5 p-1 text-sm bg-table_row-cream border border-table_border"
onClick={(e) => SetDrawLay(e.target.value)}
>
{bet.val2 === null && "0"}
{bet.val2 && bet?.val2}
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-cream border border-table_border">
-<p>(-)</p>
</td>
<td className="md:p-5 p-1 text-sm bg-table_row-cream border border-table_border">
-<p>(-)</p>
</td>
</tr>
))}
</>
Use .map instead of data[0], data[1]... then add onClick to row and pass whole object from map

Using pagination in NextJS from ExpressJS

I have an API in ExpressJS with an endpoint that pages users. A parameter is passed to the query in the api with the page number, and it takes care of the rest. Everything works normal on the API side.
I have been using actions in NextJS to make API requests. It has worked fine so far. This actions makes the request to the aforementioned endpoint:
export const getInactiveUsers = async (page) => {
try {
console.log(page)
const res = await _fetch(`${API}/user/inactives?page=${page}`, {
method: "GET",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
Authorization: `Bearer ${getCookie('token')}`,
}
})
const data = await res.json();
console.log('Data on action', data)
if (data.error) {
return data.error
}
return data
} catch (error) {
return console.error(error);
}
}
Make the request correctly. The problem is when it receives the page parameter for the first time. It always goes undefined.
An example of use is this table, which has access to the router, and receives the page number through the queries. Accessing from http://host.com/dashboard/waiting/number-of-page-passed-by-query
export default function WaitingHiringTable () {
const router = useRouter()
const { page } = router.query
const [people, setPeople] = useState([])
useEffect(() => {
loadUser()
}, [])
const loadUser = async () => {
const users = await getInactiveUsers(page)
if (users.error) {
console.log(users.error)
} else {
setPeople(users.data)
}
}
return (
<div className="flex flex-col mt-10">
<div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
<div className="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Name
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Email
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Phone
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Role
</th>
<th scope="col" className="relative px-6 py-3">
<span className="sr-only">Edit</span>
</th>
</tr>
</thead>
<tbody>
{
people
.map((person, personIdx) => (
<tr key={person.email} className={personIdx % 2 === 0 ? 'bg-white' : 'bg-gray-50'}>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{person.firstName} {person.lastName}</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500"><a href={`mailto:${person.email}`}>{person.email}</a></td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500"><a href={`tel:${person.phone}`}>{person.phone}</a></td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{person.role}</td>
<td className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button type="button" className="inline-flex items-center px-2.5 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Approve</button>
</td>
</tr>
))
}
</tbody>
</table>
{
people.length && (
<nav className="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6" aria-label="Pagination">
<div className="hidden sm:block">
<p className="text-sm text-gray-700">
Showing <span className="font-medium">1</span> to <span className="font-medium">{people.length}</span> of{' '}
<span className="font-medium">{people.length}</span> results
</p>
</div>
<div className="flex-1 flex justify-between sm:justify-end">
<button onClick={() => setNewPage(page - 1)}
className="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
Previous
</button>
<button onClick={() => setNewPage(page + 1)}
className="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
Next
</button>
</div>
</nav>
)
}
</div>
</div>
</div>
</div>
)
}

How to increase height of a table cell if the content overflows

I'm coding a credit log system in react using firebase realtime database. I have something like this:
and I'd like to have it so that when the content is really long it doesn't result in a scroll bar but rather causes the height of the cell to increase. I've tried doing some messing around but I'm not so proficient in tailwind. I've attached the code below.
import React, {useState, useEffect} from "react";
import PropTypes from "prop-types";
import firebase from "Firebase"
import TableDropdown from "components/Dropdowns/TableDropdown.js";
// Todo: Make this more module through adding component/variable for each cell
export default function MyCreditLog({ color }) {
const [creditData, setCreditData] = useState([]);
useEffect(() => {
let ref = firebase.database().ref("/creditlogs/"+firebase.auth().currentUser.uid)
console.log(firebase.auth().currentUser.uid)
ref.on("value", snapshot => {
const state = snapshot.val()
setCreditData(Object.values(state))
console.log(state)
})
}, [])
return (
<>
<div
className={
"relative flex flex-col min-w-0 break-words w-full mb-6 shadow-lg rounded " +
(color === "light" ? "bg-white" : "bg-blue-900 text-white")
}
>
<div className="rounded-t mb-0 px-4 py-3 border-0">
<div className="flex flex-wrap items-center">
<div className="relative w-full px-4 max-w-full flex-grow flex-1">
<h3
className={
"font-semibold text-lg " +
(color === "light" ? "text-gray-800" : "text-white")
}
>
My Credit Log
</h3>
</div>
</div>
</div>
<div className="block w-full overflow-x-auto">
{/* Projects table */}
<table className="items-center w-full bg-transparent border-collapse">
<thead>
<tr className="overflow-x-hidden">
<th
className={
"px-6 align-middle border border-solid py-3 text-xs uppercase border-l-0 border-r-0 whitespace-no-wrap font-semibold text-left " +
(color === "light"
? "bg-gray-100 text-gray-600 border-gray-200"
: "bg-blue-800 text-blue-300 border-blue-700")
}
>
Date
</th>
<th
className={
"px-6 align-middle border border-solid py-3 text-xs uppercase border-l-0 border-r-0 whitespace-no-wrap font-semibold text-left " +
(color === "light"
? "bg-gray-100 text-gray-600 border-gray-200"
: "bg-blue-800 text-blue-300 border-blue-700")
}
>
Time In
</th>
<th
className={
"px-6 align-middle border border-solid py-3 text-xs uppercase border-l-0 border-r-0 whitespace-no-wrap font-semibold text-left " +
(color === "light"
? "bg-gray-100 text-gray-600 border-gray-200"
: "bg-blue-800 text-blue-300 border-blue-700")
}
>
Time Out
</th>
<th
className={
"px-6 align-middle border border-solid py-3 text-xs uppercase border-l-0 border-r-0 whitespace-no-wrap font-semibold text-left " +
(color === "light"
? "bg-gray-100 text-gray-600 border-gray-200"
: "bg-blue-800 text-blue-300 border-blue-700")
}
>
Type
</th>
<th
className={
"px-6 align-middle border border-solid py-3 text-xs uppercase border-l-0 border-r-0 whitespace-no-wrap font-semibold text-left " +
(color === "light"
? "bg-gray-100 text-gray-600 border-gray-200"
: "bg-blue-800 text-blue-300 border-blue-700")
}
>
Description
</th>
<th
className={
"px-6 align-middle border border-solid py-3 text-xs uppercase border-l-0 border-r-0 whitespace-no-wrap font-semibold text-left " +
(color === "light"
? "bg-gray-100 text-gray-600 border-gray-200"
: "bg-blue-800 text-blue-300 border-blue-700")
}></th>
</tr>
</thead>
<tbody>
{/* loop through fetched credit data and add rows */}
{creditData.map((credit, index) => {
return (<tr key={index}>
<th className="border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-no-wrap p-4 text-left flex items-center">
{credit.date}
</th>
<td className="border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-no-wrap p-4">
{credit.timeIn}
</td>
<td className="border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-no-wrap p-4">
{credit.timeOut}
</td>
<td className="border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-no-wrap p-4">
{credit.type}
</td>
<td className="border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-no-wrap p-4">
{credit.description}
</td>
<td className="border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-no-wrap p-4 text-right">
<TableDropdown />
</td>
</tr>)
})}
</tbody>
</table>
</div>
</div>
</>
);
}
MyCreditLog.defaultProps = {
color: "light",
};
MyCreditLog.propTypes = {
color: PropTypes.oneOf(["light", "dark"]),
};
What a stupid question. I removed the "whitespace-no-wrap" class from each element and it worked perfectly.

Resources