Reputation: 349
I'm building a dashboard of sorts as part of a project to learn React and NextJS. I'm stuck on an issue that I have found no solution to online. Any help is appreciated!
So I have a page called 'departments.js', which shows a table like the one in the image below.
I get the data to fill in the rows and columns from 2 hardcoded JSON stringa:
const data = [
{ name: "Customer Service", num: '56', dept:'custserv' },
{ name: "Human Resources", num: '21', dept:'hr' },
{ name: "Quality Assurance", num: '13', dept:'qa' },
{ name: "Marketing", num: '30', dept:'mark' },
{ name: "Research and Development", num: '17', dept:'rnd' },
{ name: "Operations", num: '49', dept:'ops' },
{ name: "Sales", num: '37', dept:'sales' },
{ name: "Distribution", num: '26', dept:'dist' },
{ name: "IT", num: '12', dept:'it' },
]
const column = [
{ heading: 'Department', value: 'name' },
{ heading: 'No. of Employees', value: 'num' },
{ heading: 'Actions', value: 'dept' },
];
The dept
field in the JSON string should store the name of the js file for that department.
What I want to achieve is - when the user clicks the View Department button in the marketing row, the app navigates to /mark.js
.
I have a separate component for the table:
Table.js
const Table = ({ data, column }) => {
return (
<table>
<thead>
<tr>
{column.map((item, index) => <TableHeadItem item={item} />)}
</tr>
</thead>
<tbody>
{data.map((item, index) => <TableRow item={item} column={column} />)}
</tbody>
</table>
)
}
const TableHeadItem = ({ item }) => <th>{item.heading}</th>
const TableRow = ({ item, column }) => (
<tr>
{column.map((columnItem, index) => {
if(columnItem.value.includes('.')) {
const itemSplit = columnItem.value.split('.')
return <td>{item[itemSplit[0]][itemSplit[1]]}</td>
}
return <td>{item[`${columnItem.value}`]}</td>
})}
</tr>
)
export default Table
Here is how I build the table in the departments.js
file:
return(
<div className={styles.tableCont}>
<Table data={data} column={column} /> {/* data and column JSONs*/}
</div>
)
I tried declaring a function to build the button for each row with the dept
from the data JSON, but I'm not able to do it. Please advise on how to go about this.
My failed attempt
const viewDeptBtn = (dept) => {
return (
<button className={styles.viewDeptBtn} onClick={() => router.push('/'+dept)}>
View Department
</button>
)
}
const column = [
{ heading: 'Department', value: 'name' },
{ heading: 'No. of Employees', value: 'num' },
{ heading: 'Actions', value: viewDeptBtn('dept') },
];
Upvotes: 0
Views: 560
Reputation: 17374
If your data is shaped like this:
const data = [
{ name: "Customer Service", num: '56', dept:'custserv' },
{ name: "Human Resources", num: '21', dept:'hr' },
{ name: "Quality Assurance", num: '13', dept:'qa' },
{ name: "Marketing", num: '30', dept:'mark' },
{ name: "Research and Development", num: '17', dept:'rnd' },
{ name: "Operations", num: '49', dept:'ops' },
{ name: "Sales", num: '37', dept:'sales' },
{ name: "Distribution", num: '26', dept:'dist' },
{ name: "IT", num: '12', dept:'it' },
]
Then to produce the table rows you'd just have to do the following:
const Button = ({ dept }) => (
<button onClick={() => router.push(`/${dept}`)}>View Department</button>
);
const TableRow = ({ item }) => (
<tr>
<td>{item.name}</td>
<td>{item.num}</td>
<td>
<Button dept={item.dept} />
</td>
</tr>
);
const TableHeadItem = ({ item }) => <th>{item.heading}</th>;
export default function Table({data, column}) {
return (
<table>
<thead>
<tr>
{column.map((item, index) => (
<TableHeadItem item={item} key={index} />
))}
</tr>
</thead>
<tbody>
{data.map((item) => (
<TableRow item={item} key={item.num} />
))}
</tbody>
</table>
);
}
Upvotes: 1