Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added django_email_learning/static/logo-h.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added django_service/static/src/assets/logo-h-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added django_service/static/src/assets/logo-h-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added django_service/static/src/assets/logo-v-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions frontend/course/Course.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ function Course() {
>
<Grid size={{xs: 12, md: 9}} py={2} pl={2}>
<Box p={2} sx={{ border: '1px solid', borderColor: 'grey.300', borderRadius: 1, minHeight: 300 }}>
<Button variant="outlined" startIcon={<DescriptionIcon />} sx={{ marginBottom: 2 }} onClick={() => {
<Button variant="contained" startIcon={<DescriptionIcon />} sx={{ marginBottom: 2 }} onClick={() => {
setDialogContent(<LessonForm
header="New Lesson"
initialContent={lessonCache}
Expand All @@ -98,7 +98,7 @@ function Course() {
successCallback={resetDialog}
courseId={course_id} />);
setDialogOpen(true);}}>Add a Lesson</Button>
<Button variant="outlined" startIcon={<BallotIcon />} sx={{ marginBottom: 2, marginLeft: 1 }} onClick={() => {
<Button variant="contained" startIcon={<BallotIcon />} sx={{ marginBottom: 2, marginLeft: 1 }} onClick={() => {
setDialogContent(<QuizForm
cancelCallback={() => setDialogOpen(false)}
successCallback={resetDialog}
Expand Down
8 changes: 5 additions & 3 deletions frontend/course/components/ContentTable.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { TableContainer, Table, TableHead, TableRow, TableBody, TableCell, Paper, Typography } from '@mui/material';
import { IconButton, TableContainer, Table, TableHead, TableRow, TableBody, TableCell, Paper, Typography } from '@mui/material';
import { useState, useEffect } from 'react';
import { getCookie } from '../../src/utils.js';
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
import DeleteIcon from '@mui/icons-material/Delete';

const ContentTable = ({ courseId, eventHandler, loaded = false }) => {
const [contentList, setContentList] = useState([]);
Expand Down Expand Up @@ -80,7 +80,9 @@ const ContentTable = ({ courseId, eventHandler, loaded = false }) => {
<TableCell>{formatPeriod(content.waiting_period)}</TableCell>
<TableCell>{content.type}</TableCell>
<TableCell align='right'>
<DeleteOutlineIcon sx={{ cursor: 'pointer', color: 'secondary.main' }} onClick={() => deleteContent(content.id)} />
<IconButton aria-label="delete" onClick={() => deleteContent(content.id)}>
<DeleteIcon />
</IconButton>
</TableCell>
</TableRow>
))}
Expand Down
4 changes: 2 additions & 2 deletions frontend/course/components/LessonForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,10 @@ function LessonForm({ header, initialTitle, initialContent, onContentChange, can
</Select>
</Tooltip>
<Box mt={2} textAlign="right">
<Button variant="outlined" sx={{ mr: 1, boxShadow: 'none' }} onClick={cancel}>
<Button variant="outlined" sx={{ mr: 1 }} onClick={cancel}>
Cancel
</Button>
<Button type="submit" variant="contained" color="primary" sx={{ boxShadow: 'none' }} onClick={() => {if(!lessonId) { addLesson(); } else { updateLesson(); }}}>
<Button type="submit" variant="contained" onClick={() => {if(!lessonId) { addLesson(); } else { updateLesson(); }}}>
Save Lesson
</Button>
</Box>
Expand Down
4 changes: 2 additions & 2 deletions frontend/course/components/QuestionForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const QuestionForm = ({question, index, deleteCallback}) => {
<Button variant="outlined" color="primary" sx={{ fontSize: '0.75rem', mt: 1 }} onClick={() => setAddingOption(true)} >
<RuleIcon /><Typography variant="button" sx={{ ml: 1, fontSize: '0.75rem' }}>Add Option</Typography>
</Button>
<Button variant="outlined" color="secondary" onClick={deleteCallback} sx={{ ml: 1, mt: 1, fontSize: '0.75rem' }}>
<Button variant="outlined" onClick={deleteCallback} sx={{ ml: 1, mt: 1, fontSize: '0.75rem' }}>
Delete
</Button>
</Grid>
Expand All @@ -85,7 +85,7 @@ const QuestionForm = ({question, index, deleteCallback}) => {
/>
</Grid>
<Grid size={{ xs: 3 }} sx={{ textAlign: 'left' }} alignItems={"center"}>
<Button variant="outlined" color="primary" sx={{ mt: 1, mr: 1 }} onClick={() => {
<Button variant="outlined" sx={{ mt: 1, mr: 1 }} onClick={() => {
if (optionInputRef.current) {
console.log(optionInputRef.current);
addToOptions(optionInputRef.current.value);
Expand Down
4 changes: 2 additions & 2 deletions frontend/course/components/QuizForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ const QuizForm = ({cancelCallback, successCallback, courseId, quizId }) => {
}}/>
</Grid>
<Grid size={{ xs: 12, md: 4 }} sx={{ textAlign: 'right' }}>
<Button variant="outlined" color="primary" onClick={() => {
<Button variant="outlined" onClick={() => {
addToQuestions();
}}>
Add Question
</Button>
<Button variant="outlined" sx={{ ml: 1 }} color="secondary" onClick={() => { setShowQuestionField(false); setNewQuestion(""); }}>
<Button variant="outlined" sx={{ ml: 1 }} onClick={() => { setShowQuestionField(false); setNewQuestion(""); }}>
Cancel
</Button>
</Grid>
Expand Down
19 changes: 10 additions & 9 deletions frontend/courses/Courses.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import 'vite/modulepreload-polyfill'
import { useState, useEffect } from 'react'
import { Grid, Box, Link, Button, Dialog, Paper, Switch, TableContainer, Table, TableHead, TableRow,TableBody, TableCell } from '@mui/material'
import { Grid, Box, Link, Button, IconButton, Dialog, Paper, Switch, TableContainer, Table, TableHead, TableRow,TableBody, TableCell } from '@mui/material'
import Base from '../src/components/Base.jsx'
import CourseForm from './components/CourseForm.jsx';
import FilterListIcon from '@mui/icons-material/FilterList';
import SchoolIcon from '@mui/icons-material/School';
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
import DeleteIcon from '@mui/icons-material/Delete';
import EditIcon from '@mui/icons-material/Edit';
import render from '../src/render.jsx';
import { getCookie } from '../src/utils.js';
import EnableCourseSwitchPopup from './components/EnableCourseSwitchPopup.jsx';
Expand Down Expand Up @@ -104,8 +105,8 @@ function Courses() {
organizationIdRefreshCallback={setOrganizationId}
>
<Grid size={{xs: 12, md: 9}} py={2} pl={2}>
<Box p={2} sx={{ border: '1px solid', borderColor: 'grey.300', borderRadius: 1, minHeight: 300 }}>
<Button variant="outlined" startIcon={<SchoolIcon />} sx={{ marginBottom: 2 }} onClick={() => {
<Box p={2} sx={{ border: '1px solid', borderColor: 'border.main', backgroundColor: 'background.main', borderRadius: 1, minHeight: 300 }}>
<Button variant="contained" startIcon={<SchoolIcon />} sx={{ marginBottom: 2 }} onClick={() => {
setDialogContent(<CourseForm
successCallback={handleCourseCreated}
failureCallback={handleCourseCreationFailed}
Expand Down Expand Up @@ -142,15 +143,15 @@ function Courses() {
/>
</TableCell>
<TableCell align="right">
<Button size="small" sx={{ color: 'secondary.main', }} aria-label={`Edit ${course.title}`} onClick={() => {
showEditCourseDialog(course);}}>Edit</Button>
<Button size="small" sx={{ color: 'secondary.main', }} aria-label={`Delete ${course.title}`} onClick={() => {
<IconButton onClick={() => {
showEditCourseDialog(course);}}><EditIcon fontSize="small" /></IconButton>
<IconButton aria-label={`Delete ${course.title}`} onClick={() => {
setDialogContent(<DeleteCoursePopup courseId={course.id} courseTitle={course.title} handleClose={() => setDialogOpen(false)} handleSuccess={() => {
const index = courses.findIndex(item => item.id === course.id);
setCourses(courses.filter((_, i) => i !== index));
}} />);
setDialogOpen(true);
}}><DeleteOutlineIcon fontSize="small" /></Button>
}}><DeleteIcon fontSize="small" /></IconButton>
</TableCell>
</TableRow>
))}
Expand All @@ -160,7 +161,7 @@ function Courses() {
</Box>
</Grid>
<Grid display={{xs: "none", md: "block"}} size={{ md: 3 }} p={2}>
<Box p={2} sx={{ border: '1px solid', borderColor: 'grey.300', borderRadius: 1, minHeight: 300, position: 'sticky', top: 80 }}>
<Box p={2} sx={{ border: '1px solid', borderColor: 'border.main', borderRadius: 1, minHeight: 300, position: 'sticky', top: 80, backgroundColor: 'background.main' }}>
<FilterForm onStatusChange={(params) => setQueryParameters(params)} />
</Box>
</Grid>
Expand Down
Binary file added frontend/src/assets/logo-h-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/src/assets/logo-h-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/src/assets/logo-v-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/src/assets/logo-v-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 8 additions & 3 deletions frontend/src/components/Base.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import BottomDrawer from "./BottomDrawer";
import MenuBar from "./MenuBar";
import { useState, useEffect } from "react";
import { Grid, Breadcrumbs, Typography, Link } from "@mui/material";
import { Box, GlobalStyles, Grid, Breadcrumbs, Typography, Link } from "@mui/material";
import { getCookie } from "../utils.js";


function Base({breadCrumbList, children, bottomDrawerParams, organizationIdRefreshCallback, showOrganizationSwitcher=true}) {
const [activeOrganizationId, setActiveOrganizationId] = useState(null);
const baseApiUrl = localStorage.getItem('apiBaseUrl');
const drawerWidth = 250;

useEffect(() => {
const orgId = localStorage.getItem('activeOrganizationId');
Expand Down Expand Up @@ -57,7 +58,10 @@ function Base({breadCrumbList, children, bottomDrawerParams, organizationIdRefre

return (
<>
<MenuBar activeOrganizationId={activeOrganizationId} changeOrganizationCallback={setActiveOrganizationId} showOrganizationSwitcher={showOrganizationSwitcher} />
<GlobalStyles styles={(theme) => ({ body: { margin: 0, padding: 0, backgroundColor: theme.palette.background.dark, color: theme.palette.text.primary } })} />
<MenuBar activeOrganizationId={activeOrganizationId} changeOrganizationCallback={setActiveOrganizationId} showOrganizationSwitcher={showOrganizationSwitcher} drawerWidth={drawerWidth} />
<Box component="main"
sx={{ flexGrow: 1, padding: {sm: 3, xs: 1, md: 5}, width: { md: `calc(100% - ${drawerWidth + 100}px)` }, float: { md: 'right' } }}>
<Grid container spacing={0} mt={10} px={4}>
<Grid size={{xs: 12}}>
<Breadcrumbs aria-label="breadcrumb">
Expand All @@ -66,7 +70,7 @@ function Base({breadCrumbList, children, bottomDrawerParams, organizationIdRefre
<Link key={index} underline="hover" color="inherit" href={href}>
{label}
</Link> :
<Typography key={index} sx={{ color: 'text.primary', fontSize: { xs: 12, sm: 14 } }}>
<Typography key={index} sx={{ color: 'text.primary' }}>
{label}
</Typography>
))}
Expand All @@ -79,6 +83,7 @@ function Base({breadCrumbList, children, bottomDrawerParams, organizationIdRefre
{bottomDrawerParams.children}
</BottomDrawer>}
</Grid>
</Box>
</>
);
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/ContentEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function ContentEditor({ initialContent, contentUpdateCallback }) {
<EditorContext.Provider value={{ editor }}>
{/* Material UI Toolbar */}
<Toolbar variant="dense" sx={{
backgroundColor: 'grey.50',
backgroundColor: 'background.nav',
borderBottom: '1px solid',
borderColor: 'divider'
}}>
Expand Down
114 changes: 73 additions & 41 deletions frontend/src/components/MenuBar.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { useState, useEffect } from 'react'
import { useState, useEffect, use } from 'react'
import { AppBar, Toolbar, Drawer, Box, Typography, MenuList, MenuItem, ListItemIcon, ListItemText, Button, Link, Select } from '@mui/material'
import IconButton from '@mui/material/IconButton';
import SchoolIcon from '@mui/icons-material/School';
import PeopleIcon from '@mui/icons-material/People';
import BarChartIcon from '@mui/icons-material/BarChart';
import Diversity3Icon from '@mui/icons-material/Diversity3';
import MenuIcon from '@mui/icons-material/Menu';
import logoUrl from '../assets/logo.png'
import logoHorizontalLightUrl from '../assets/logo-h-light.png'
import logoHorizontalDarkUrl from '../assets/logo-h-dark.png'
import logoVerticalLightUrl from '../assets/logo-v-light.png'
import logoVerticalDarkUrl from '../assets/logo-v-dark.png'
import { getCookie } from '../utils.js';
import { useThemeContext } from '../theme/ThemeContext.jsx';
import { useTheme, useMediaQuery } from "@mui/material";
import ThemeSwitcher from './ThemeSwitcher.jsx';

const apiBaseUrl = localStorage.getItem('apiBaseUrl');
const platformBaseUrl = localStorage.getItem('platformBaseUrl');
Expand Down Expand Up @@ -42,10 +48,17 @@ function OrganizationsSelect({organizations, activeOrganizationId, changeOrganiz
)
}

function MenuBar({activeOrganizationId, changeOrganizationCallback, showOrganizationSwitcher}) {
function MenuBar({activeOrganizationId, changeOrganizationCallback, showOrganizationSwitcher, drawerWidth}) {
const [menuOpen, setMenuOpen] = useState(false)
const [organizations, setOrganizations] = useState([])

const theme = useTheme();
const isMdUpScreen = useMediaQuery(theme.breakpoints.up('md'));

const drawerVariant = isMdUpScreen ? "permanent" : "temporary";
const logoHorizontalUrl = theme.palette.mode === 'light' ? logoHorizontalLightUrl : logoHorizontalDarkUrl;
const logoVerticalUrl = theme.palette.mode === 'light' ? logoVerticalLightUrl : logoVerticalDarkUrl;

useEffect(() => {
fetch(apiBaseUrl + '/organizations/', {
method: 'GET',
Expand Down Expand Up @@ -81,47 +94,66 @@ function MenuBar({activeOrganizationId, changeOrganizationCallback, showOrganiza
setMenuOpen(newOpen);
};

return (<AppBar sx={{boxShadow: 0, backgroundColor: 'white', borderBottom: '1px solid', borderColor: 'primary.main'}}>
<Toolbar>
<Box ml={2}>
<img src={logoUrl} alt="Logo" style={{ height: 36 }} />
</Box>
<Typography variant="body1" component="span" sx={{ flexGrow: 1, ml: 2, color: 'primary.dark' }}>
Email Learning
{
showOrganizationSwitcher && organizations.length > 0 && <OrganizationsSelect organizations={organizations} activeOrganizationId={activeOrganizationId} changeOrganizationCallback={changeOrganizationCallback} sx={{ display: { xs: 'none', md: 'inline-grid' } }} />
}
</Typography>
<Box sx={{display: { xs: 'flex', md: 'none'}, right: 0, position: "absolute" }}>
<IconButton
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={toggleMenuDrawer(true)}
color="primary"
>
<MenuIcon />
</IconButton>
</Box>
return (

// return (<AppBar sx={{boxShadow: 0, backgroundColor: 'white', borderBottom: '1px solid', borderColor: 'primary.main'}}>
// <Toolbar>
// <Box ml={2}>
// <img src={logoUrl} alt="Logo" style={{ height: 36 }} />
// </Box>
// <Typography variant="body1" component="span" sx={{ flexGrow: 1, ml: 2, color: 'primary.dark' }}>
// Email Learning
// {
// showOrganizationSwitcher && organizations.length > 0 && <OrganizationsSelect organizations={organizations} activeOrganizationId={activeOrganizationId} changeOrganizationCallback={changeOrganizationCallback} sx={{ display: { xs: 'none', md: 'inline-grid' } }} />
// }
// </Typography>
// <ThemeSwitcher />
// <Box sx={{display: { xs: 'flex', md: 'none'}, right: 0, position: "absolute" }}>
// <IconButton
// size="large"
// aria-label="account of current user"
// aria-controls="menu-appbar"
// aria-haspopup="true"
// onClick={toggleMenuDrawer(true)}
// color="primary"
// >
// <MenuIcon />
// </IconButton>
// </Box>

<Box sx={{ float: "right", display: { xs: 'none', md: 'flex' } }}>
{pages.map((page) => (
<Button
key={page.name}

href={page.href}
sx={{ color: 'black', display: 'block', textTransform: 'none' }}
>
{page.name}
</Button>
))}
// <Box sx={{ float: "right", display: { xs: 'none', md: 'flex' } }}>
// {pages.map((page) => (
// <Button
// key={page.name}
// href={page.href}
// sx={{ color: 'black', display: 'block', textTransform: 'none' }}
// >
// {page.name}
// </Button>
// ))}
// </Box>
// </Toolbar>
<Box component="nav"sx={{ width: { sm: drawerWidth }, flexShrink: { sm: 0 } }}>
<AppBar sx={{boxShadow: 0, backgroundColor: 'background.nav', borderBottom: {xs: '1px solid', md: 'none'}, borderColor: {xs: 'primary.main', md: 'none'} }}>
<Box my={1} ml={5}>
<img src={logoHorizontalUrl} alt="Logo" style={{ height: 57 }} />
</Box>
</Toolbar>
<Drawer open={menuOpen} onClose={toggleMenuDrawer(false)} display={{md: "none" }}
<Box sx={{display: { xs: 'flex'}, right: 0, position: "absolute" }}>
<ThemeSwitcher />
<Box m={1} paddingTop="7px">
<IconButton aria-controls="menu-appbar" onClick={toggleMenuDrawer(true)} sx={{ display: { xs: 'inline-block', md: 'none' }}}>
<MenuIcon />
</IconButton>
</Box>
</Box>
</AppBar>
<Drawer variant={drawerVariant} onClose={toggleMenuDrawer(false)} display={{md: "none" }} open={menuOpen} sx={{ '& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth } }}
slotProps={{ backdrop: { sx: { backgroundColor: 'rgba(251, 251, 255, 0.57)', backdropFilter: 'blur(5px)' }}, paper: { sx: { boxShadow: '2px 0px 8px rgba(0, 0, 0, 0.1)'}}}}>
<Box my={2} textAlign="center">
<img src={logoVerticalUrl} alt="Logo" style={{ width: "50%" }} />
</Box>
{
showOrganizationSwitcher && <OrganizationsSelect organizations={organizations} activeOrganizationId={activeOrganizationId} changeOrganizationCallback={changeOrganizationCallback} sx={{ m: 2 }} />
showOrganizationSwitcher && <OrganizationsSelect organizations={organizations} activeOrganizationId={activeOrganizationId} changeOrganizationCallback={changeOrganizationCallback} sx={{ m: 2 }} />
}
<MenuList>
{ pages.map((page) => (
Expand All @@ -136,7 +168,7 @@ function MenuBar({activeOrganizationId, changeOrganizationCallback, showOrganiza
)) }
</MenuList>
</Drawer>
</AppBar>)
</Box>)
}

export default MenuBar
Loading