Here are the related components I used to build the Sidebar UI. Everything is displaying fine. But the loading of the content pages and how to connect the Content.jsx and SideNavBar.jsx to display perfectly is pretty much troublesome.
1. SideBarButton.jsx - this is used for the buttons of Sidebar
import React from "react";
import styled from "styled-components";
import { colors } from "../../assets/colorPalette"; // Assuming you have a file for colors
const SideBarButton = ({ onClick, icon, title }) => {
return (
<li>
<ButtonSidebar onClick={onClick}>
<Icon>{icon}</Icon>
{title}
</ButtonSidebar>
</li>
);
};
const ButtonSidebar = styled.div`
position: relative;
text-decoration: none;
display: flex;
align-items: center;
justify-content: left;
border: none;
border-top-right-radius: 15px;
border-bottom-right-radius: 15px;
font-weight: 350;
transition: all 0.2s ease-in;
color: ${colors.onSecContainer};
height: 70px;
&:hover {
background: ${colors.SurfContainer_highest};
}
&.active {
background: ${colors.secContainer};
color: ${colors.onPrimContainer};
transition: all 0.4s ease-in-out;
font-weight: 400;
}
`;
const Icon = styled.div`
margin-right: 15px;
margin-left: 20px;
height: 24px;
`
export default SideBarButton;
2. SideNavbar.jsx - This is the sidebar built with above mentioned SidebarButton component.
import React from "react";
import styled from "styled-components"; // Import styled-components only once
import SideBarButton from "./SideNavBarLinks";
import { colors } from "../../assets/colorPalette";
import dashboard from "../../assets/dashboard.svg";
import patient from "../../assets/patient.svg";
import messages from "../../assets/messages.svg";
import visits from "../../assets/visits.svg";
const SideNavbar = ({onSideNavBarClick}) => {
const handleClick = (page) => {
onSideNavbarClick(page)
}
return (
<SidebarWrapper>
<SidebarBody>
<UnorderedList>
{makeButtons.map((btn, i) => (
<SideBarButton onClick = {() => handleClick(btn.title)}
to={btn.to}
icon={btn.icon}
title={btn.title}
key={i}
/>
))}
</UnorderedList>
</SidebarBody>
</SidebarWrapper>
);
};
const makeButtons = [
{
to: "/DoctorDashboard",
icon: <img src={dashboard} alt="dashboard" />,
title: "Dashboard",
},
{
to: "/Patients",
icon: <img src={patient} alt="patient" />,
title: "Patients",
},
{
to: "/Appointments",
icon: <img src={visits} alt="appointments" />,
title: "Appointments",
},
{
to: "/Visits",
icon: <img src={messages} alt="messages" />,
title: "Visits",
},
];
const SidebarWrapper = styled.div`
position: fixed;
top: 0;
left: 0;
width: 250px;
height: 100vh;
background: ${colors.SurfContainer};
z-index: 2;
transition: transform 0.3s ease-in-out;
`;
const SidebarBody = styled.div`
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
height: 100%;
padding-top: 20px;
`;
const UnorderedList = styled.ul`
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
display:inline-block;
width: 100%;
`;
export default SideNavbar;
3. Content.jsx - this page loads the content related to the side bar buttons.
import React from 'react';
import DashboardPage from '../../pages/Doctor/DashboardPage';
import PatientsPage from '../../pages/Doctor/PatientsPage';
import VisitsPage from '../../pages/Doctor/VisitsPage';
import AppointmentsPage from '../../pages/Doctor/AppointmentsPage';
import styled from 'styled-components';
const Content = ({ selectedPage }) => {
const renderPage = () => {
switch (selectedPage) {
case 'Dashboard':
return <DashboardPage />;
case 'Patients':
return <PatientsPage />;
case 'Appointments':
return <AppointmentsPage />;
case 'Visits':
return <VisitsPage />;
default:
// Throw an error for invalid pages
throw new Error(`Invalid page: ${selectedPage}`);
}
};
return (
<ContentContainer>{renderPage()}</ContentContainer>
);
}
const ContentContainer = styled.div`
display: flex;
padding: 20px;
`
export default Content;
4. DoctorsUI.jsx - this is the final page, which is the sum of Sidebar and Content components. it is displayed correctly. But the Content pages are not loading correctly.
import React, { useState } from "react";
import styled from "styled-components";
import SideNavBar from "../../components/Doctor/SideNavbar";
import Content from "../../components/Doctor/Content";
const DoctorsUI = () => {
// State to manage the selected page
const [selectedPage, setSelectedPage] = useState("Dashboard");
// Function to handle sidebar button click
const handleSideNavClick = (page) => {
setSelectedPage(page);
};
return (
<Wrapper>
<SidebarWrapper>
{/* Pass the handleSideNavClick function to SideNavBar */}
<SideNavBar onSideNavBarClick={{handleSideNavClick}} />
</SidebarWrapper>
{/* Pass the selectedPage state to Content */}
<ContentWrapper>
<Content selectedPage={selectedPage} />
</ContentWrapper>
</Wrapper>
);
};
const Wrapper = styled.div`
display: flex;
`;
const SidebarWrapper = styled.div`
// add suitable styles for a side navigation bar wrapper
position: fixed;
top: 0;
left: 0;
width: 250px;
height: 100vh;
transition: transform 0.3s ease-in-out;
`;
const ContentWrapper = styled.div`
// add suitable styles for a content wrapper
flex: 1;
margin-left: 270px;
padding: 20px;
`;
export default DoctorsUI;
I tried everything I can as a rookie, I watched YT videos, asked GPTs, spent around 3 days and I got nothing yet I'm trying my best.
It would appear you are passing an object with a handleSideNavClick
property to SideNavBar
's onSideNavBarClick
prop, e.g. onSideNavBarClick={{ handleSideNavClick }}
.
<SideNavBar onSideNavBarClick={{ handleSideNavClick }} />
I suspect you ought to see an error in the browser console when attempting to invoke the passed onSideNavBarClick
prop, e.g. that it's not a function.
const SideNavbar = ({ onSideNavBarClick }) => {
const handleClick = (page) => {
onSideNavbarClick(page); // <-- not a function, `{ handleSideNavClick }`
};
...
};
To fix this you can just pass handleSideNavClick
as the onSideNavBarClick
value.
<SideNavBar onSideNavBarClick={handleSideNavClick} />
const SideNavbar = ({ onSideNavBarClick }) => {
const handleClick = (page) => {
onSideNavbarClick(page); // <-- a function, `handleSideNavClick`
};
...
};
or
const SideNavbar = ({ onSideNavBarClick }) => {
return (
<SidebarWrapper>
<SidebarBody>
<UnorderedList>
{makeButtons.map(({ title, ...btn}, index) => (
<SideBarButton
key={index}
onClick={() => onSideNavBarClick(title)} // <-- use directly
{...btn}
/>
))}
</UnorderedList>
</SidebarBody>
</SidebarWrapper>
);
};