Making It Reusable
Our dashboard is coming along nicely, but so far it's been hardcoded for a list of sites. We'll also want to use this "dashboard shell" for more pages. This includes showing all the user's feedback, as well as the account page. To accomplish this, let's make the dashboard components more reusable.
Dashboard Shell
- Rather than hardcoding the "My Sites" header as well as the "Add Site" button, we can remove all of that site-specific code from the
DashboardShell
and instead pass whatever React children we want. - We can also touch up the file by adding
next/link
to actually link to the pages mentioned.
components/DashboardShell.js
import React from 'react'import NextLink from 'next/link'import { Box, Button, Flex, Link, Avatar, Icon } from '@chakra-ui/core'
import { useAuth } from '@/lib/auth'
const DashboardShell = ({ children }) => { const { user } = useAuth()
return ( <Box backgroundColor="gray.100" h="100vh"> <Flex backgroundColor="white" mb={[8, 16]} w="full" borderTop="5px solid #0AF5F4" > <Flex alignItems="center" justifyContent="space-between" pt={4} pb={4} maxW="1250px" margin="0 auto" w="full" px={8} h="60px" > <Flex align="center"> <NextLink href="/" passHref> <Link> <Icon name="logo" size="24px" mr={8} /> </Link> </NextLink> <NextLink href="/sites" passHref> <Link mr={4}>Sites</Link> </NextLink> <NextLink href="/feedback" passHref> <Link>Feedback</Link> </NextLink> </Flex> <Flex justifyContent="center" alignItems="center"> {user && ( <NextLink href="/account" passHref> <Button as="a" variant="ghost" mr={2}> Account </Button> </NextLink> )} <Avatar size="sm" src={user?.photoUrl} /> </Flex> </Flex> </Flex> <Flex margin="0 auto" direction="column" maxW="1250px" px={[0, 8, 8]}> {children} </Flex> </Box> )}
export default DashboardShell
We can now create other, more focused components to forward as children.
<DashboardShell> <SiteTableHeader /> <SiteTableSkeleton /></DashboardShell>
Header
Now, it's easy for us to use the same DashboardShell
for both the sites table as well as the feedback table.
components/SiteTableHeader.js
import React from 'react'import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, Heading, Flex, Box,} from '@chakra-ui/core'
const SiteTableHeader = ({ isPaidAccount }) => ( <Box mx={4}> <Breadcrumb> <BreadcrumbItem> <BreadcrumbLink>Sites</BreadcrumbLink> </BreadcrumbItem> </Breadcrumb> <Flex justifyContent="space-between"> <Heading mb={8}>My Sites</Heading> </Flex> </Box>)
export default SiteTableHeader