diff --git a/api/controllers/workorderController.js b/api/controllers/workorderController.js
index a803e8e..4c5162d 100644
--- a/api/controllers/workorderController.js
+++ b/api/controllers/workorderController.js
@@ -1,5 +1,4 @@
const Workorder = require("../models/workorderModel");
-// const { findProfileById } = require("./profileController");
const Profile = require("../models/profileModel");
exports.createWorkorder = async ({ userId, brand, model, colour }) => {
diff --git a/api/middleware/verifyToken.js b/api/middleware/verifyToken.js
index 400779e..2a6f541 100644
--- a/api/middleware/verifyToken.js
+++ b/api/middleware/verifyToken.js
@@ -1,7 +1,6 @@
const { verifyToken } = require("../tokens/tokenService");
exports.verifyToken = async (req, res, next) => {
- console.log(req.cookies);
const { cookies } = req;
try {
if (!cookies || !cookies.token) {
diff --git a/api/routes/workorderRoutes.js b/api/routes/workorderRoutes.js
index b3b6613..2931a8d 100644
--- a/api/routes/workorderRoutes.js
+++ b/api/routes/workorderRoutes.js
@@ -2,9 +2,9 @@ const express = require("express");
const router = express.Router();
const Workorder = require("../models/workorderModel");
const { verifyToken } = require("../middleware/verifyToken");
-const { createToken } = require("../tokens/tokenService");
-const { findProfileById } = require("../controllers/profileController");
const { createWorkorder } = require("../controllers/workorderController");
+// const { createToken } = require("../tokens/tokenService");
+// const { findProfileById } = require("../controllers/profileController");
// TODO
// @route GET/workorders
diff --git a/src/App.js b/src/App.js
index 8c48c6a..ff3c84f 100644
--- a/src/App.js
+++ b/src/App.js
@@ -5,26 +5,30 @@ import MainContentSection from "./components/root/MainContentSection";
import Footer from "./components/root/Footer";
import { ImpersonatorProvider } from "./backend/authorization/ImpersonatorContext";
import { UserProvider } from "./backend/authorization/UserContext";
+import { ThemeProvider } from "@material-ui/core";
+import theme from './styles/theme'
const App = () => {
const [loginClick, setLoginClick] = useState(false);
return (
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
);
};
diff --git a/src/backend/authorization/AuthContainer.js b/src/backend/authorization/AuthContainer.js
index 45817ae..bcc8bd6 100644
--- a/src/backend/authorization/AuthContainer.js
+++ b/src/backend/authorization/AuthContainer.js
@@ -1,29 +1,54 @@
-import React, { Fragment, useContext, useCallback, useState } from "react";
+import React, { Fragment, useState } from "react";
import { Link, Switch, Route, Redirect } from "react-router-dom";
import ProfileCreate from "../../components/root/ProfileCreate";
-import Field from "../../components/root/Field";
-// import { UserContext } from "./UserContext";
-// import { ImpersonatorContext } from "./ImpersonatorContext";
-// import AuthLoginSignup from "./AuthLoginSignup";
+// import Field from "../../components/root/Field";
+import { makeStyles } from "@material-ui/core/styles";
+import TextField from "@material-ui/core/TextField";
+import Button from "@material-ui/core/Button";
+import Paper from "@material-ui/core/Paper";
+import Grid from "@material-ui/core/Grid";
-const headers = {
- Accept: "application/json",
- "Content-Type": "application/json",
-};
+const useStyles = makeStyles((theme) => ({
+ root: {
+ display: "flex",
+ flexWrap: "wrap",
+ justifyContent: "center",
+ flexGrow: 1,
+ "& > *": {
+ margin: theme.spacing(1),
+ },
+ },
+ textField: {
+ marginLEft: theme.spacing(1),
+ marginRight: theme.spacing(1),
+ // width: "50%",
+ display: "flex",
+ justifyContent: "center",
+ },
+ paper: {
+ display: "flex",
+ // width: "50%",
+ margin: "0 auto",
+ padding: 1,
+ rounded: false,
+ },
+ paperText: {
+ rounded: false,
+ padding: 1,
+ },
+ grid: {
+ maxWidth: "calc(50% - 16px)",
+ flexGrow: "50%",
+ flexBasis: "200px"
+ }
+}));
-const AuthContainer = ({loadUserProfile}) => {
- // const [currentUser, setCurrentUser] = useContext(UserContext);
+const AuthContainer = ({ loadUserProfile }) => {
+ const classes = useStyles();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [link, setLink] = useState("signup");
- // const [impersonator, setImpersonator] = useContext(ImpersonatorContext);
-
- //* const loadImpersonator = useCallback(() => {
- // setTimeout(() => {
- // setImpersonator(undefined);
- // }, [3000]);
- // }, [setImpersonator]);
const changeLink = () => {
if (link === "signup") {
@@ -33,13 +58,15 @@ const AuthContainer = ({loadUserProfile}) => {
}
};
-
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await fetch("/api/profile/login", {
method: "POST",
- headers: headers,
+ headers: {
+ Accept: "application/json",
+ "Content-Type": "application/json",
+ },
body: JSON.stringify({ email, password }),
});
const data = await response.json();
@@ -57,38 +84,57 @@ const AuthContainer = ({loadUserProfile}) => {
-
-
-
+
{/* prettier-ignore */}
-
+
);
};
diff --git a/src/components/root/ContactEditor.js b/src/components/root/ContactEditor.js
index bad2d42..9957c94 100644
--- a/src/components/root/ContactEditor.js
+++ b/src/components/root/ContactEditor.js
@@ -57,3 +57,75 @@ const ContactEditor = ({
);
export default ContactEditor;
+
+
+
+
+
+
+// import React, { Fragment } from "react";
+// import TextField from "@material-ui/core/TextField";
+// import { makeStyles } from "@material-ui/core/styles";
+
+// const useStyles = makeStyles((theme) => ({
+// root: {
+// "& > *": {
+// margin: theme.spacing(1),
+// },
+// "& .MuiTextField-root": {
+// margin: theme.spacing(1),
+// width: "25ch",
+// },
+// },
+// }));
+
+// const ContactEditor = ({
+// firstName,
+// lastName,
+// phone,
+// email,
+// password,
+// onChange,
+// }) => {
+// const classes = useStyles();
+// return (
+//
+//
+//
+//
+//
+//
+//
+// );
+// };
+// export default ContactEditor;
diff --git a/src/components/root/ExampleTable.jsx b/src/components/root/ExampleTable.jsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/components/root/Header.js b/src/components/root/Header.js
index 65d6289..2d4d58b 100644
--- a/src/components/root/Header.js
+++ b/src/components/root/Header.js
@@ -1,7 +1,19 @@
import React, { Fragment, useContext } from "react";
import { UserContext } from "../../backend/authorization/UserContext";
+import { makeStyles } from '@material-ui/core/styles';
+import Button from '@material-ui/core/Button'
+// import theme from '../../styles/theme'
+
+const useStyles = makeStyles((theme) => ({
+ root: {
+ '& > *': {
+ margin: theme.spacing(1),
+ },
+ },
+}));
function Header({ loginClick, setLoginClick }) {
+ const classes = useStyles();
const [currentUser, setCurrentUser] = useContext(UserContext);
function toggleLoginClick() {
@@ -23,9 +35,9 @@ function Header({ loginClick, setLoginClick }) {
AERO
{loginClick ? (
-
+
) : (
-
+
)}
);
@@ -33,7 +45,7 @@ function Header({ loginClick, setLoginClick }) {
content = (
AERO
-
+
);
}
diff --git a/src/components/root/MainContentSection.js b/src/components/root/MainContentSection.js
index 6bc8065..3e0a5a3 100644
--- a/src/components/root/MainContentSection.js
+++ b/src/components/root/MainContentSection.js
@@ -14,8 +14,6 @@ function MainContentSection({ loginClick }) {
const [admin, setAdmin] = useContext(ImpersonatorContext);
const [currentProfile, setCurrentProfile] = useContext(UserContext);
-
-
const loadUserProfile = useCallback(
async function () {
try {
@@ -37,12 +35,6 @@ function MainContentSection({ loginClick }) {
[setCurrentProfile]
);
- // function loadUserProfile() {
-
- // const prevWorkorders = currentProfile.workorders;
- // console.log(`prev: ${prevWorkorders} & new: ${workorders}`);
- // }
-
let content;
if (loginClick) {
if (currentProfile) {
diff --git a/src/components/root/ProfileCreate.js b/src/components/root/ProfileCreate.js
index 88cdbfa..b77d4e7 100644
--- a/src/components/root/ProfileCreate.js
+++ b/src/components/root/ProfileCreate.js
@@ -1,26 +1,77 @@
+// import ContactEditor from "./ContactEditor";
+// import { sizing } from "@material-ui/system";
import React, { useState } from "react";
-import ContactEditor from "./ContactEditor";
import { useHistory } from "react-router-dom";
+import { makeStyles } from "@material-ui/core/styles";
+import Button from "@material-ui/core/Button";
+import TextField from "@material-ui/core/TextField";
+import Paper from "@material-ui/core/Paper";
+import Grid from "@material-ui/core/Grid";
+
+const useStyles = makeStyles((theme) => ({
+ root: {
+ display: "flex",
+ flexWrap: "wrap",
+ justifyContent: "center",
+ flexGrow: 1,
+ "& > *": {
+ margin: theme.spacing(1),
+ },
+ },
+ textField: {
+ marginLEft: theme.spacing(1),
+ marginRight: theme.spacing(1),
+ width: "75%",
+ display: "flex",
+ justifyContent: "center",
+ },
+ paper: {
+ display: "flex",
+ width: "50%",
+ margin: "0 auto",
+ padding: 1,
+ rounded: false,
+ },
+ paperText: {
+ rounded: false,
+ padding: 1,
+ },
+}));
const headers = { "Content-Type": "application/json" };
function ProfileCreate({ changeLink }) {
- const [contact, setContact] = useState();
+ const classes = useStyles();
const history = useHistory();
+ const [firstName, setFirstName] = useState();
+ const [lastName, setLastName] = useState();
+ const [phone, setPhone] = useState();
+ const [email, setEmail] = useState();
+ const [password, setPassword] = useState();
- const updateContactField = (e) => {
- const contactState = { ...contact };
- contactState[e.target.name] = e.target.value;
- setContact(contactState);
- };
-
- const redirectOnSubmit = () => {
- history.push("/login");
- changeLink();
+ const updateFields = (e) => {
+ let name = e.target.name;
+ console.log(name);
+ if (name === "firstName") {
+ setFirstName(e.target.value);
+ }
+ if (name === "lastName") {
+ setLastName(e.target.value);
+ }
+ if (name === "phone") {
+ setPhone(e.target.value);
+ }
+ if (name === "email") {
+ setEmail(e.target.value);
+ }
+ if (name === "password") {
+ setPassword(e.target.value);
+ } else;
};
const addRecord = async (e) => {
e.preventDefault();
+ const contact = { firstName, lastName, phone, email, password };
try {
const response = await fetch("/api/profile/create", {
method: "POST",
@@ -31,19 +82,141 @@ function ProfileCreate({ changeLink }) {
if (!response.ok) {
throw new Error(data.message);
}
+ setFirstName("");
+ setLastName("");
+ setPhone("");
+ setEmail("");
+ setPassword("");
redirectOnSubmit();
} catch (err) {
console.log(err);
}
};
+ const redirectOnSubmit = () => {
+ history.push("/login");
+ changeLink();
+ };
+
return (
-
+
);
}
diff --git a/src/components/root/Workorder.js b/src/components/root/Workorder.js
index 3ae3eb7..141a476 100644
--- a/src/components/root/Workorder.js
+++ b/src/components/root/Workorder.js
@@ -1,12 +1,8 @@
-import React, { useContext, Fragment, useState } from "react";
-// import { UserContext } from "../../backend/authorization/UserContext";
-// import { ImpersonatorContext } from "../../backend/authorization/ImpersonatorContext";
+import React, { Fragment, useState } from "react";
import WorkorderDisplay from "./WorkorderDisplay";
import WorkorderCreate from "../admin/WorkorderCreate";
const Workorder = ({ currentProfile, loadUserProfile, admin }) => {
- // const [currentProfile] = useContext(UserContext);
- // const [admin] = useContext(ImpersonatorContext);
const [workView, setWorkView] = useState("display");
function workorderClick() {
diff --git a/src/components/root/WorkorderDisplay.js b/src/components/root/WorkorderDisplay.js
index 3e2213f..0d3ec6a 100644
--- a/src/components/root/WorkorderDisplay.js
+++ b/src/components/root/WorkorderDisplay.js
@@ -1,55 +1,360 @@
-import React, { useEffect } from "react";
-import { makeStyles } from "@material-ui/core/styles";
-import {
- Table,
- TableBody,
- TableCell,
- TableContainer,
- TableHead,
- TableRow,
-} from "@material-ui/core";
+import React from "react";
+import { lighten, makeStyles } from "@material-ui/core/styles";
+import clsx from "clsx";
+import PropTypes from "prop-types";
+import Table from "@material-ui/core/Table";
+import TableBody from "@material-ui/core/TableBody";
+import TableCell from "@material-ui/core/TableCell";
+import TableContainer from "@material-ui/core/TableContainer";
+import TableHead from "@material-ui/core/TableHead";
+import TablePagination from "@material-ui/core/TablePagination";
+import TableRow from "@material-ui/core/TableRow";
+import TableSortLabel from "@material-ui/core/TableSortLabel";
+import Toolbar from "@material-ui/core/Toolbar";
+import Typography from "@material-ui/core/Typography";
import Paper from "@material-ui/core/Paper";
+import Checkbox from "@material-ui/core/Checkbox";
+import IconButton from "@material-ui/core/IconButton";
+import Tooltip from "@material-ui/core/Tooltip";
+// import FormControlLabel from "@material-ui/core/FormControlLabel";
+// import Switch from "@material-ui/core/Switch";
+import DeleteIcon from "@material-ui/icons/Delete";
+import FilterListIcon from "@material-ui/icons/FilterList";
-const useStyles = makeStyles({
+// const useStyles = makeStyles({
+// table: {
+// minWidth: 350,
+// },
+// });
+
+function descendingComparator(a, b, orderBy) {
+ if (b[orderBy] < a[orderBy]) {
+ return -1;
+ }
+ if (b[orderBy] > a[orderBy]) {
+ return 1;
+ }
+ return 0;
+}
+
+function getComparator(order, orderBy) {
+ return order === "desc"
+ ? (a, b) => descendingComparator(a, b, orderBy)
+ : (a, b) => -descendingComparator(a, b, orderBy);
+}
+
+function stableSort(array, comparator) {
+ const stabilizedThis = array.map((el, index) => [el, index]);
+ stabilizedThis.sort((a, b) => {
+ const order = comparator(a[0], b[0]);
+ if (order !== 0) return order;
+ return a[1] - b[1];
+ });
+ return stabilizedThis.map((el) => el[0]);
+}
+
+const headCells = [
+ { id: "id", numeric: true, disablePadding: true, label: "Workorder ID" },
+ { id: "brand", numeric: false, disablePadding: false, label: "Brand" },
+ { id: "model", numeric: false, disablePadding: false, label: "Model" },
+ { id: "colour", numeric: false, disablePadding: false, label: "Colour" },
+];
+
+function EnhancedTableHead(props) {
+ const {
+ classes,
+ onSelectAllClick,
+ order,
+ orderBy,
+ numSelected,
+ rowCount,
+ onRequestSort,
+ } = props;
+ const createSortHandler = (property) => (event) => {
+ onRequestSort(event, property);
+ };
+
+ return (
+
+
+
+ 0 && numSelected < rowCount}
+ checked={rowCount > 0 && numSelected === rowCount}
+ onChange={onSelectAllClick}
+ inputProps={{ "aria-label": "select all workorders" }}
+ />
+
+ {headCells.map((headCell) => (
+
+
+ {headCell.label}
+ {orderBy === headCell.id ? (
+
+ {order === "desc" ? "sorted descending" : "sorted ascending"}
+
+ ) : null}
+
+
+ ))}
+
+
+ );
+}
+
+EnhancedTableHead.propTypes = {
+ classes: PropTypes.object.isRequired,
+ numSelected: PropTypes.number.isRequired,
+ onRequestSort: PropTypes.func.isRequired,
+ onSelectAllClick: PropTypes.func.isRequired,
+ order: PropTypes.oneOf(["asc", "desc"]).isRequired,
+ orderBy: PropTypes.string.isRequired,
+ rowCount: PropTypes.number.isRequired,
+};
+
+const useToolbarStyles = makeStyles((theme) => ({
+ root: {
+ paddingLeft: theme.spacing(2),
+ paddingRight: theme.spacing(1),
+ },
+ highlight:
+ theme.palette.type === "light"
+ ? {
+ color: theme.palette.secondary.main,
+ backgroundColor: lighten(theme.palette.secondary.light, 0.85),
+ }
+ : {
+ color: theme.palette.text.primary,
+ backgroundColor: theme.palette.secondary.dark,
+ },
+ title: {
+ flex: "1 1 100%",
+ },
+}));
+
+const EnhancedTableToolbar = (props) => {
+ const classes = useToolbarStyles();
+ const { numSelected } = props;
+
+ return (
+ 0,
+ })}
+ >
+ {numSelected > 0 ? (
+
+ {numSelected} selected
+
+ ) : (
+
+ Workorders
+
+ )}
+
+ {numSelected > 0 ? (
+
+
+
+
+
+ ) : (
+
+
+
+
+
+ )}
+
+ );
+};
+
+EnhancedTableToolbar.propTypes = {
+ numSelected: PropTypes.number.isRequired,
+};
+
+const useStyles = makeStyles((theme) => ({
+ root: {
+ width: "100%",
+ },
+ paper: {
+ width: "100%",
+ marginBottom: theme.spacing(2),
+ },
table: {
minWidth: 350,
},
-});
+ visuallyHidden: {
+ border: 0,
+ clip: "rect(0 0 0 0)",
+ height: 1,
+ margin: -1,
+ overflow: "hidden",
+ padding: 0,
+ position: "absolute",
+ top: 20,
+ width: 1,
+ },
+}));
export default function WorkorderDisplay({ currentProfile }) {
- console.log(currentProfile);
const classes = useStyles();
+ const [order, setOrder] = React.useState("asc");
+ const [orderBy, setOrderBy] = React.useState("calories");
+ const [selected, setSelected] = React.useState([]);
+ const [page, setPage] = React.useState(0);
+ const [dense, setDense] = React.useState(false);
+ const [rowsPerPage, setRowsPerPage] = React.useState(10);
const { workorders } = currentProfile;
- useEffect(() => {
- console.log('refresh');
- }, [workorders])
-
- return (
-
-
-
-
- Workorder Number
- Brand
- Model
- Colour
-
-
-
- {workorders.map((workorder) => (
-
-
- {workorder._id}
-
- {workorder.brand}
- {workorder.model}
- {workorder.colour}
-
- ))}
-
-
-
- );
+ const handleRequestSort = (event, property) => {
+ const isAsc = orderBy === property && order === "asc";
+ setOrder(isAsc ? "desc" : "asc");
+ setOrderBy(property);
+ };
+
+ const handleSelectAllClick = (event) => {
+ if (event.target.checked) {
+ const newSelecteds = workorders.map((n) => n.name);
+ setSelected(newSelecteds);
+ return;
+ }
+ setSelected([]);
+ };
+
+ const handleClick = (event, name) => {
+ const selectedIndex = selected.indexOf(name);
+ let newSelected = [];
+
+ if (selectedIndex === -1) {
+ newSelected = newSelected.concat(selected, name);
+ } else if (selectedIndex === 0) {
+ newSelected = newSelected.concat(selected.slice(1));
+ } else if (selectedIndex === selected.length - 1) {
+ newSelected = newSelected.concat(selected.slice(0, -1));
+ } else if (selectedIndex > 0) {
+ newSelected = newSelected.concat(
+ selected.slice(0, selectedIndex),
+ selected.slice(selectedIndex + 1)
+ );
+ }
+
+ setSelected(newSelected);
+ };
+
+ const handleChangePage = (event, newPage) => {
+ setPage(newPage);
+ };
+
+ const handleChangeRowsPerPage = (event) => {
+ setRowsPerPage(parseInt(event.target.value, 10));
+ setPage(0);
+ };
+
+ // const handleChangeDense = (event) => {
+ // setDense(event.target.checked);
+ // };
+
+ const isSelected = (name) => selected.indexOf(name) !== -1;
+
+ const emptyRows =
+ rowsPerPage - Math.min(rowsPerPage, workorders.length - page * rowsPerPage);
+
+ return (
+
+
+
+
+
+
+
+ {stableSort(workorders, getComparator(order, orderBy))
+ .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
+ .map((workorder, index) => {
+ const isItemSelected = isSelected(workorder._id);
+ const labelId = `enhanced-table-checkbox-${index}`;
+ return (
+
+ handleClick(event, workorder._id)
+ }
+ role="checkbox"
+ aria-checked={isItemSelected}
+ tabIndex={-1}
+ key={workorder._id}
+ selected={isItemSelected}
+ >
+
+
+
+
+ {workorder._id}
+
+ {workorder.brand}
+ {workorder.model}
+ {workorder.colour}
+
+ );
+ })}
+ {emptyRows > 0 && (
+
+
+
+ )}
+
+
+
+
+
+
+ );
}
diff --git a/src/styles/theme.jsx b/src/styles/theme.jsx
new file mode 100644
index 0000000..6d853ba
--- /dev/null
+++ b/src/styles/theme.jsx
@@ -0,0 +1,30 @@
+import { createMuiTheme } from "@material-ui/core";
+
+// import { deepPurple, amber } from "@material-ui/core/colors";
+
+const theme = createMuiTheme({
+ palette: {
+ primary: {
+ main: '#202428',
+ light: '#474c50',
+ dark: '#000000',
+ contrastText: '#a7b3bd'
+ },
+ secondary: {
+ main: '#eeeeee',
+ light: '#ffffff',
+ dark: '#bcbcbc',
+ contrastText: '#5c677d',
+ },
+ },
+ typography: {
+ fontSize: 16,
+ }
+ // overrides: {
+ // MuiPaper: {
+ // maxWidth: '500px',
+ // },
+ // },
+});
+
+export default theme;