Skip to content

Commit d67adc9

Browse files
Merge pull request #34 from CPSECapstone/dev-navstyling
Navbar and sidebar styling
2 parents dfe5363 + 9a5ab33 commit d67adc9

File tree

11 files changed

+229
-96
lines changed

11 files changed

+229
-96
lines changed

package-lock.json

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"bootstrap": "^4.6.0",
2929
"eslint-plugin-react": "^7.23.1",
3030
"formik": "^2.2.6",
31+
"get-video-id": "^3.2.0",
3132
"graphql": "^15.5.0",
3233
"react": "^17.0.2",
3334
"react-bootstrap": "^1.5.2",

src/App/App.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@
4141
.main {
4242
height: calc(100vh - 56px);
4343
.sidebar-container {
44-
background-color: #5884ab;
44+
background-color: ghostwhite;
4545
}
4646
.content-container {
4747
background-color: ghostwhite;
4848
}
49-
}
49+
}

src/App/App.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
12
import { Auth, Hub } from 'aws-amplify';
23
import { useState, useEffect } from 'react';
34
import { withAuthenticator } from 'aws-amplify-react';
45
import Sidebar from '../Components/Sidebar';
56
import Content from '../Components/Content';
67
import Navigation from '../Navigation/Navigation';
8+
import StudentPicture from '../assets/images/images-1.png';
9+
710
import './App.scss';
811

912
// Entry point of the Flitped App
1013
function App() {
1114
const [, setUser] = useState(null);
15+
const [fname, setFirstName] = useState('');
1216

1317
function storeToken(): void {
1418
Auth.currentSession()
@@ -22,10 +26,10 @@ function App() {
2226
})
2327
.then((authUser) => {
2428
setUser(authUser);
29+
setFirstName(authUser.attributes.given_name);
2530
})
2631
.catch(() => console.log('Not signed in'));
2732
}
28-
2933
useEffect(() => {
3034
Hub.listen('auth', ({ payload: { event, data } }) => {
3135
switch (event) {
@@ -54,6 +58,8 @@ function App() {
5458
<div className="main container-fluid">
5559
<div className="row h-100">
5660
<div className="sidebar-container col-md-2">
61+
<img src={StudentPicture} alt="" style={{ width: 180, height: 180 }} />
62+
{fname}
5763
<Sidebar />
5864
</div>
5965
<div className="content-container col-md-10">
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import PropTypes from 'prop-types';
2+
import { useState } from 'react';
3+
import { makeStyles, createStyles } from '@material-ui/core/styles';
4+
import List from '@material-ui/core/List';
5+
import ListItemIcon from '@material-ui/core/ListItemIcon';
6+
import ListItemText from '@material-ui/core/ListItemText';
7+
import Divider from '@material-ui/core/Divider';
8+
import Collapse from '@material-ui/core/Collapse';
9+
import IconExpandLess from '@material-ui/icons/ExpandLess';
10+
import IconExpandMore from '@material-ui/icons/ExpandMore';
11+
import SideBarItemComponent from './SideBarItemComponent';
12+
13+
const useStyles = makeStyles(() =>
14+
createStyles({
15+
sideBarItem: {
16+
'&.active': {
17+
color: '#2F80ED', // text
18+
'& .MuiListItemIcon-root': {
19+
color: '#2F80ED', // icon active
20+
},
21+
},
22+
},
23+
sideBarItemIcon: {
24+
color: '#AAB1BA',
25+
},
26+
})
27+
);
28+
29+
export const SideBarItemPropTypes = {
30+
name: PropTypes.string.isRequired,
31+
link: PropTypes.string,
32+
Icon: PropTypes.elementType,
33+
items: PropTypes.array,
34+
};
35+
36+
type SideBarItemPropTypes = PropTypes.InferProps<typeof SideBarItemPropTypes>;
37+
type SideBarItemPropsWithoutItems = Omit<SideBarItemPropTypes, 'items'>;
38+
39+
export type SideBarItemProps = SideBarItemPropsWithoutItems & {
40+
items?: SideBarItemProps[];
41+
};
42+
43+
function SideBarItem({ name, link, Icon, items = [] }: SideBarItemProps) {
44+
const classes = useStyles();
45+
const isExpandable = items && items.length > 0;
46+
const [open, setOpen] = useState(false);
47+
function handleClick() {
48+
setOpen(!open);
49+
}
50+
const SideBarItemRoot = (
51+
<SideBarItemComponent className={classes.sideBarItem} link={link} onClick={handleClick}>
52+
{!!Icon && (
53+
<ListItemIcon className={classes.sideBarItemIcon}>
54+
<Icon />
55+
</ListItemIcon>
56+
)}
57+
<ListItemText primary={name} inset={!Icon} />
58+
{isExpandable && !open && <IconExpandMore />}
59+
{isExpandable && open && <IconExpandLess />}
60+
</SideBarItemComponent>
61+
);
62+
63+
const SideBarItemChildren = isExpandable ? (
64+
<Collapse in={open} timeout="auto" unmountOnExit>
65+
<Divider />
66+
<List component="div" disablePadding>
67+
{items.map((item, index) => (
68+
<SideBarItem {...item} key={index} />
69+
))}
70+
</List>
71+
</Collapse>
72+
) : null;
73+
74+
return (
75+
<>
76+
{SideBarItemRoot}
77+
{SideBarItemChildren}
78+
</>
79+
);
80+
}
81+
82+
export default SideBarItem;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* eslint-disable react/no-children-prop */
2+
/* eslint-disable @typescript-eslint/no-shadow */
3+
import React, { forwardRef } from 'react';
4+
import ListItem from '@material-ui/core/ListItem';
5+
import { NavLink, NavLinkProps } from 'react-router-dom';
6+
7+
export interface SideBarItemComponentProps {
8+
className?: string;
9+
link?: string | null;
10+
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
11+
}
12+
13+
const SideBarItemComponent: React.FC<SideBarItemComponentProps> = (props) => {
14+
const { className, onClick, link, children } = props;
15+
16+
if (!link || typeof link !== 'string') {
17+
return <ListItem button className={className} children={children} onClick={onClick} />;
18+
}
19+
20+
return (
21+
<ListItem
22+
button
23+
className={className}
24+
children={children}
25+
component={forwardRef((props: NavLinkProps, ref: any) => (
26+
<NavLink exact {...props} innerRef={ref} />
27+
))}
28+
to={link}
29+
/>
30+
);
31+
};
32+
33+
export default SideBarItemComponent;

src/Components/Sidebar/Sidebar.css

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1+
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
2+
13
.sidebar {
24
display: flex;
35
flex-direction: column;
46
align-items: center;
5-
padding: 20px;
7+
padding: 22px;
68
}
79

10+
811
.sidebar .menu-container {
912
width: 80px;
1013
margin-bottom: 10px;
1114
color: ghostwhite;
1215
text-align: center;
1316
align-self: center;
17+
padding-top: 22px !important;
18+
1419
}
1520

1621
.menu-container .menu-icon {
@@ -26,4 +31,4 @@
2631
text-decoration: none;
2732
font-weight: 700;
2833
font-size: 1rem;
29-
}
34+
}

src/Components/Sidebar/Sidebar.tsx

Lines changed: 60 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,80 @@
1-
import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
2-
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3-
import {
4-
faChalkboardTeacher,
5-
faUserFriends,
6-
faComments,
7-
faMedal,
8-
faTasks,
9-
faChartLine,
10-
} from '@fortawesome/free-solid-svg-icons';
1+
import List from '@material-ui/core/List';
2+
import IconDashboard from '@material-ui/icons/Dashboard';
3+
import IconShoppingCart from '@material-ui/icons/ShoppingCart';
4+
import IconPeople from '@material-ui/icons/People';
5+
import IconBarChart from '@material-ui/icons/BarChart';
6+
import IconLibraryBooks from '@material-ui/icons/LibraryBooks';
7+
import ForumIcon from '@material-ui/icons/Forum';
8+
import SettingsIcon from '@material-ui/icons/Settings';
9+
import SideBarItem from './SideBarItem';
1110

12-
import { Link } from 'react-router-dom';
13-
14-
import './Sidebar.css';
15-
16-
type Props = { text: string; icon: IconDefinition; link: string };
17-
18-
function IconMenu({ text, icon, link }: Props) {
19-
return (
20-
<Link to={link} className="menu-container">
21-
<div className="menu-icon">
22-
<FontAwesomeIcon icon={icon} size="2x" />
23-
</div>
24-
<p className="menu-text">{text}</p>
25-
</Link>
26-
);
27-
}
28-
29-
const menus: Props[] = [
11+
const sideBarItems = [
3012
{
31-
text: 'DashBoard',
32-
icon: faChalkboardTeacher,
33-
link: '/dashboard',
13+
name: 'Classes',
14+
Icon: IconDashboard,
15+
items: [
16+
// hardcoded for now
17+
{
18+
name: 'English',
19+
items: [{ name: 'Student Progress', link: '/studentOverview/English' }],
20+
},
21+
{
22+
name: 'Math',
23+
link: '/courseHome/Math',
24+
},
25+
{
26+
name: 'Biology',
27+
link: '/courseHome/Biology',
28+
},
29+
{
30+
name: 'Integrated Science',
31+
link: '/courseHome/Integrated Science',
32+
},
33+
],
3434
},
3535
{
36-
text: 'Student',
37-
icon: faUserFriends,
38-
link: '/studentOverview/Biology',
36+
name: 'Dashboard',
37+
link: '/',
38+
Icon: IconLibraryBooks,
3939
},
4040
{
41-
text: 'Task',
42-
icon: faTasks,
41+
name: 'Task',
4342
link: '/viewTask',
43+
Icon: IconPeople,
44+
},
45+
{
46+
name: 'Marketplace',
47+
link: '/marketplace',
48+
Icon: IconShoppingCart,
4449
},
4550
{
46-
text: 'Mastery',
47-
icon: faChartLine,
48-
link: '/singleStudentMasteryOverview',
51+
name: 'Students and Groups',
52+
link: '/studentOverview/Biology',
53+
Icon: IconPeople,
4954
},
5055
{
51-
text: 'Goals',
52-
icon: faMedal,
56+
name: 'Goals',
5357
link: '/singleStudentOverview',
58+
Icon: IconBarChart,
5459
},
5560
{
56-
text: 'Submission',
57-
icon: faComments,
58-
link: './taskSubmissionOverview',
61+
name: 'Inbox',
62+
link: '/inbox',
63+
Icon: ForumIcon,
64+
},
65+
{
66+
name: 'Settings',
67+
link: '/settings',
68+
Icon: SettingsIcon,
5969
},
6070
];
61-
62-
export default function Sidebar() {
71+
function Sidebar() {
6372
return (
64-
<div className="sidebar position-fixed">
65-
{menus.map((menu) => (
66-
<IconMenu key={menu.text} text={menu.text} icon={menu.icon} link={menu.link} />
73+
<List component="nav" disablePadding>
74+
{sideBarItems.map((item, index) => (
75+
<SideBarItem {...item} key={index} />
6776
))}
68-
</div>
77+
</List>
6978
);
7079
}
80+
export default Sidebar;

0 commit comments

Comments
 (0)