How can I insert row div for every 3rd entry in props?

Viewed 24

I've got a set of dashboards that display in bootstrap cards on a front page and I would like to wrap them in a div with the class row for every 3rd entry. I was thinking about marking my dashboard component with the DB id from props and use a modulus function, but that will cause problems if an ID is deleted

Dashboard component:

export type DashboardProps = {
  id: number
  title: string
  description: string
}

const Dashboard: React.FC<{ dashboard: DashboardProps }> = ({ dashboard }) => {
  return (
    <>
      <div className="col-sm-12 col-lg-4">
        <div className="card bg-light h-100">
          <div className="card-header">
            {dashboard.title}
          </div>
          <div className="card-body d-flex flex-column">
            <p className="card-text">
              {dashboard.description}
            </p>
            <a className="btn btn-info text-center mt-auto" 
                onClick={() =>
                  Router.push("/dashboard/[id]", `/dashboard/${dashboard.id}`)
                }
            >Go to dashboard</a>
          </div>
        </div>
      </div>
    </>
  )
}

export default Dashboard

Index page:

type Props = {
  dashboards: DashboardProps[]
}

export const getServerSideProps: GetServerSideProps = async () => {
  const dashboards = await prisma.dashboard.findMany({
    orderBy: { id: "asc", },
  })

  return {
    props: JSON.parse(JSON.stringify({ dashboards })),
  }
}

const Index: React.FC<Props> = (props) => {
  const { data: session, status } = useSession()

  if (status === "loading") {
    return (
      <Spinner />
    )
  }

  if (!session) {
    return (
      <Layout>
        <AccessDenied />
      </Layout>
    )
  }

  return (
    <Layout>
      <h1>Dashboards</h1>
        {props.dashboards.map((dashboard) => (
          <Dashboard dashboard={dashboard} />
        ))}
    </Layout>
  )
}

export default Index

I could also potentially wrap them in a single div with class row, but I would need to enforce a top/bottom margin so the cards don't stack right on top of each other. Any tips to get me rolling on this would be greatly appreciated!

1 Answers

.map provides index, you this to find every 3rd element.

//...
{
  props.dashboards.map((dashboard, index) =>
    (index + 1) % 3 === 0 ? (
      <div>
        <Dashboard key={dashboard.id} dashboard={dashboard} />
      </div>
    ) : (
      <Dashboard key={dashboard.id} dashboard={dashboard} />
    )
  )
}

Related