Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 97 client crud error handling #113

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
16,691 changes: 36 additions & 16,655 deletions utmap-client/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions utmap-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"@devexpress/dx-react-scheduler-material-ui": "^2.7.4",
"@material-ui/core": "^4.11.2",
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^4.0.0-alpha.57",
"@material-ui/pickers": "^3.2.10",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.3",
Expand Down
48 changes: 47 additions & 1 deletion utmap-client/src/components/pages/CalendarPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import {
IconButton,
AppBar,
Typography,
Snackbar,
} from '@material-ui/core';
import { Alert } from '@material-ui/lab';

import SingleEventPage from './SingleEventPage';
import EventFormPage from './EventFormPage';
Expand Down Expand Up @@ -139,14 +141,16 @@ function CalendarPage() {
const [sidebarEvents, setSidebarEvents] = useState([]);
const [groupedEvent, setGroupedEvent] = useState([]);
const [openGroupedList, setOpenGroupedList] = useState(false);
const [openSnackBar500, setOpenSnackBar500] = useState(false);
const [openSnackBar400, setOpenSnackBar400] = useState(false);

//Get the list of events
useEffect(() => {
getAllEvents().then(events => {
const tempEvents = events.map(convertEvent);
setEventsList(sortEvents(tempEvents));
//Note: calendarEvents has its own useEffect to update
});
}, err => handleOpenSnackBar500());
}, []);

const handleOpenEventInfo = (data) => {
Expand Down Expand Up @@ -211,6 +215,33 @@ function CalendarPage() {
setOpenDrawer(false);
};

function handleOpenSnackBar400() {
setOpenSnackBar400(true);
};

function handleCloseSnackBar400(reason) {
if (reason === 'clickaway') {
return;
}
setOpenSnackBar400(false);
};

const handleOpenSnackBar500 = () => {
setOpenSnackBar500(true);
};

const handleCloseSnackBar500 = (reason) => {
if (reason === 'clickaway') {
return;
}
setOpenSnackBar500(false);
};

const errorCallback = useCallback((err) => {
if (err >= 500) { handleOpenSnackBar500(); }
else if (err >= 400 && err < 500) { handleOpenSnackBar400(); }
},[]);

return (
<>
{/* Sidebar */}
Expand Down Expand Up @@ -285,6 +316,7 @@ function CalendarPage() {
refreshEvents={refreshEvents}
editEvent={editEvent}
event={editingEvent}
errorCallback={errorCallback}
/>
</Dialog>

Expand All @@ -295,13 +327,27 @@ function CalendarPage() {
closePopup={handleCloseEventInfo}
handleEdit={handleEditEventForm}
refreshEvents={refreshEvents}
errorCallback={errorCallback}
/>
</Dialog>

{/* Popup box for grouped event info */}
<Dialog open={openGroupedList} onClose={handleCloseGroupedList}>
<EventList eventList={groupedEvent}/>
</Dialog>

{/* Error Handling snackbars */}
<Snackbar open={openSnackBar500} autoHideDuration={4000} onClose={handleCloseSnackBar500}>
<Alert elevation={6} variant="filled" onClose={handleCloseSnackBar500} severity="error">
500 ERROR: Try again later!
</Alert>
</Snackbar>

<Snackbar open={openSnackBar400} autoHideDuration={4000} onClose={handleCloseSnackBar400}>
<Alert elevation={6} variant="filled" onClose={handleCloseSnackBar400} severity="error">
400 ERROR: Missing values! Change Form.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change the error message for 400? It's confusing (I'm not sure what "Change form" means) and it's not accurate for 404 errors. Let's say one user deletes an event and another user tries to update the same event, which will trigger a 404 error. The message should be something relevant to it.

</Alert>
</Snackbar>
</>
);
}
Expand Down
15 changes: 9 additions & 6 deletions utmap-client/src/components/pages/EventFormPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const useStyles = makeStyles(theme => ({ //CSS styles on components
}));


function EventFormPage({onClose, refreshEvents, editEvent, event}) {
function EventFormPage({onClose, refreshEvents, editEvent, event, errorCallback}) {
const isEdit = Object.keys(event).length !== 0;
const formStyle = useStyles();
const [startDate, setStartDate] = useState(isEdit ? new Date(event.startDate) : new Date());
Expand All @@ -65,8 +65,8 @@ function EventFormPage({onClose, refreshEvents, editEvent, event}) {

//Get list of buildings
useEffect(() => {
getBuildings().then(data => setBuildings(data))
}, []);
getBuildings().then(data => setBuildings(data), err => { errorCallback(err); })
}, [errorCallback]);

//This is where the form will send to server
const handleSubmit = e => {
Expand Down Expand Up @@ -95,10 +95,13 @@ function EventFormPage({onClose, refreshEvents, editEvent, event}) {
if(isEdit) {
eventForm._id = event._id;
editEvent(eventForm);
updateEvent(toBackend, event._id);
updateEvent(toBackend, event._id).then(
res => { refreshEvents(); },
err => { errorCallback(err); });
} else {
addEvent(toBackend);
refreshEvents();
addEvent(toBackend).then(
res => { refreshEvents(); },
err => { errorCallback(err); });
}
onClose();
}
Expand Down
21 changes: 20 additions & 1 deletion utmap-client/src/components/pages/MapPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import clsx from 'clsx';
import Map from '../Map.js'
import {getAllEvents} from '../../requests';
import CircularProgress from '@material-ui/core/CircularProgress';
import { Snackbar } from '@material-ui/core';
import { Alert } from '@material-ui/lab';

const useStyles = makeStyles(theme => ({
hide: {
Expand Down Expand Up @@ -46,6 +48,7 @@ function MapPage() {
const [openDrawer, setOpenDrawer] = useState(false);
const [eventsList, setEventsList] = useState([]);
const [gotEvents, setGotEvents] = useState(false);
const [openSnackBar500, setOpenSnackBar500] = React.useState(false);

const handleDrawerOpen = () => {
setOpenDrawer(true);
Expand All @@ -60,9 +63,20 @@ function MapPage() {
const tempEvents = events.map(convertEvent); //temp fix
setEventsList(sortEvents(tempEvents));
setGotEvents(true);
});
}, err => handleOpenSnackBar500());
}, []);

const handleOpenSnackBar500 = () => {
setOpenSnackBar500(true);
};

const handleCloseSnackBar500 = (event, reason) => {
if (reason === 'clickaway') {
return;
}
setOpenSnackBar500(false);
};

return (
<>
{/* Siderbar */}
Expand All @@ -83,6 +97,11 @@ function MapPage() {
{/* Map */}
{(gotEvents && <Map events={eventsList}/>) || <div className={classes.centerBox}> <CircularProgress /> </div>}

<Snackbar open={openSnackBar500} autoHideDuration={3000} onClose={handleCloseSnackBar500}>
<Alert elevation={6} variant="filled" onClose={handleCloseSnackBar500} severity="error">
500 ERROR: Try again later!
</Alert>
</Snackbar>
</>
)
}
Expand Down
19 changes: 12 additions & 7 deletions utmap-client/src/components/pages/SingleEventPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
DialogTitle,
DialogContentText,
Dialog,
Button
Button,
} from '@material-ui/core';
import AssignmentIcon from '@material-ui/icons/Assignment';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
Expand Down Expand Up @@ -60,7 +60,7 @@ const useStyles = makeStyles(theme => ({ //CSS styles on components

}));

function SingleEventPage({event, closePopup, handleEdit, refreshEvents}) {
function SingleEventPage({event, closePopup, handleEdit, refreshEvents, errorCallback}) {
const {startDate, endDate, title, description,
location, sublocation, organizer} = event;
const classes = useStyles();
Expand All @@ -79,12 +79,17 @@ function SingleEventPage({event, closePopup, handleEdit, refreshEvents}) {
const handleOpenDeletionConfirm = () => {
setOpenDeletionConfirm(true);
}

const handleDelete = (id) => {
deleteEvent(id);
refreshEvents();

async function handleDelete(id) {
try {
deleteEvent(id).then(
res => { refreshEvents(); },
err => { errorCallback(err) });
}
catch(e) {
console.log(e);
}
}

return (
<div className={classes.box}>
{/* Popup box for deletion confirmation*/}
Expand Down
52 changes: 41 additions & 11 deletions utmap-client/src/requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,57 @@ const url = `http://${host}:${port}`;

function getBuildings() {
return axios.get(`${url}/building`)
.then(res => res.data.body, err => console.log(err));
.then(res => res.data.body, err => {
if (err.response) {
return Promise.reject(err.response.status);
} else {
return Promise.reject(500)
}
})
}

function getAllEvents() {
return axios.get(`${url}/event`)
.then(res => res.data.body, err => console.log(err));
.then(res => res.data.body, err => {
if (err.response) {
return Promise.reject(err.response.status);
} else {
return Promise.reject(500)
}
})
}

function updateEvent(event, _id) {
axios.put(`${url}/event/${_id}`, event)
.catch(err => console.log(err));
async function updateEvent(event, _id) {
await axios.put(`${url}/event/${_id}`, event)
.then(res => Promise.resolve(res.status), err => {
if (err.response) {
return Promise.reject(err.response.status);
} else {
return Promise.reject(500)
}
})
}

function addEvent(event) {
axios.post(`${url}/event`, event)
.catch(err => console.log(err));
async function addEvent(event) {
await axios.post(`${url}/event`, event)
.then(res => Promise.resolve(res.status), err => {
if (err.response) {
return Promise.reject(err.response.status);
} else {
return Promise.reject(500)
}
})
}

function deleteEvent(_id) {
axios.delete(`${url}/event/${_id}`)
.catch(err => console.log(err));
async function deleteEvent(_id) {
await axios.delete(`${url}/event/${_id}`)
.then(res => Promise.resolve(res.status), err => {
if (err.response) {
return Promise.reject(err.response.status);
} else {
return Promise.reject(500)
}
})
}

export {getBuildings, getAllEvents, updateEvent, addEvent, deleteEvent}