Skip to content

Commit

Permalink
successfully update progress on goals
Browse files Browse the repository at this point in the history
  • Loading branch information
sdevalapurkar committed Oct 20, 2021
1 parent d4c0910 commit 027a351
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 22 deletions.
36 changes: 36 additions & 0 deletions api/src/paths/goal/{goalId}/updateProgress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const { getCustomError } = require("../../../helpers/errorHandler");
const { getAuthenticatedUser } = require("../../../helpers/authenticationHelpers");

async function updateGoalProgress(req, res, db) {
if (
!req.body ||
!req.body.data ||
!req.body.data.goal ||
!req.body.data.goal.id ||
!req.body.data.goal.practiceTimes
) {
return res.status(400).json(getCustomError(400));
}

const authenticatedUser = getAuthenticatedUser(req.headers);

if (!authenticatedUser) {
return res.status(401).json(getCustomError(401));
}

await db('goals').where({
user_email: authenticatedUser.email,
id: req.body.data.goal.id
}).update({
goal_practice_times: Number(req.body.data.goal.existingPracticeTimes) + Number(req.body.data.goal.practiceTimes)
});

return res.json({
type: "Goal progress updated",
attributes: {
value: req.body.data.goal.id
}
});
}

module.exports = updateGoalProgress;
5 changes: 5 additions & 0 deletions api/src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const loginUser = require("./paths/login");
const addGoal = require("./paths/goal/add");
const getGoals = require("./paths/goal/get");
const getGoal = require("./paths/goal/{goalId}/get");
const updateGoalProgress = require("./paths/goal/{goalId}/updateProgress");

const db = knex({
client: "postgres",
Expand Down Expand Up @@ -68,5 +69,9 @@ app.get("/v1/goals/:goal_id", async (req, res) => {
return getGoal(req, res, db);
});

app.put("/v1/goals/:goal_id/progress", async (req, res) => {
return updateGoalProgress(req, res, db);
});

// API is listening and server is up
app.listen(PORT, () => console.log(`Server up at http:https://localhost:${PORT}`));
112 changes: 92 additions & 20 deletions app/src/components/GoalDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,32 @@ import {
import Header from "./Header";
import RegisterLogin from './RegisterLogin';
import { isAuthenticated } from '../helpers/authenticationHelper';
import { useParams } from 'react-router';
import { useParams, useHistory } from 'react-router';
import axios from "axios";
import moment from "moment";
import TrackProgressDialog from './TrackProgressDialog';
import CircularProgressWithLabel from './CircularProgressWithLabel';

function GoalDetails() {
const apiHost = process.env.REACT_APP_API_HOST || 'localhost';
const apiPort = process.env.REACT_APP_API_PORT || '5000';

const urlParams = useParams();
const history = useHistory();

const [isAuthed, setIsAuthed] = useState(isAuthenticated());
const [goalDetails, setGoalDetails] = useState(null);
const [practiceTimes, setPracticeTimes] = useState(null);
const [openTrackProgressDialog, setOpenTrackProgressDialog] = useState(false);
const [trackProgressDialogError, setTrackProgressDialogError] = useState('');

useEffect(() => {
if (openTrackProgressDialog) {
return;
}

getGoalDetails();
}, []);
}, [openTrackProgressDialog]);

const getGoalDetails = async () => {
const response = await axios.get(
Expand All @@ -42,6 +52,36 @@ function GoalDetails() {
setGoalDetails(value);
};

const handleSubmitTrackProgress = async () => {
if (!practiceTimes) {
setTrackProgressDialogError('All fields of the form are required. Please fill them out.');
return;
}

const response = await axios.put(
`http:https://${apiHost}:${apiPort}/v1/goals/${goalDetails.id}/progress`, {
data: {
goal: {
id: goalDetails.id,
practiceTimes: practiceTimes,
existingPracticeTimes: goalDetails.goal_practice_times || 0
}
}
}, {
headers: {
Authorization: `Bearer ${sessionStorage.getItem("jwt")}`
}
}
);

if (!response || !response.data) {
setTrackProgressDialogError('There was an error tracking progress towards your goal. Please try again later.');
return;
}

setOpenTrackProgressDialog(false);
};

const logoutUser = () => {
sessionStorage.removeItem('jwt');
setIsAuthed(isAuthenticated());
Expand All @@ -58,25 +98,57 @@ function GoalDetails() {
<Header logoutUser={logoutUser} />

{goalDetails && (
<Box pl="70px" pr="70px" pt={2} pb={2}>
<Box pb={2}>
<Typography variant="h5"><b>Goal:</b> {goalDetails.goal_name}</Typography>
<>
<Box pl="70px" pr="70px" pt={2} pb={2}>
<Box pb={3} display="flex" justifyContent="space-between">
<Typography variant="h5"><b>Goal:</b> {goalDetails.goal_name}</Typography>
<Button
variant="outlined"
component="label"
size="medium"
color="primary"
onClick={() => history.push('/')}
>
Return Home
</Button>
</Box>
<Typography variant="body1"><b>Times:</b> {goalDetails.goal_times}</Typography>
<Typography variant="body1"><b>Start Date:</b> {moment(goalDetails.goal_start_date).format('MMM D, YYYY')}</Typography>
<Typography variant="body1"><b>End Date:</b> {moment(goalDetails.goal_end_date).format('MMM D, YYYY')}</Typography>
<Box pb={1}>
<Typography variant="body1"><b>Progress:</b></Typography>
</Box>
<CircularProgressWithLabel
value={goalDetails.goal_practice_times ? (goalDetails.goal_practice_times * 100) / goalDetails.goal_times : 0}
/>
<Box pt={2}>
{goalDetails.goal_practice_times < goalDetails.goal_times && (
<Button
variant="outlined"
component="label"
size="medium"
color="primary"
onClick={() => setOpenTrackProgressDialog(true)}
>
Track Progress Towards Goal
</Button>
)}
{goalDetails.goal_practice_times >= goalDetails.goal_times && (
<Typography variant="h6">Congrats! You've completed this goal already.</Typography>
)}
</Box>
</Box>
<Typography variant="body1"><b>Times:</b> {goalDetails.goal_times}</Typography>
<Typography variant="body1"><b>Start Date:</b> {moment(goalDetails.goal_start_date).format('MMM D, YYYY')}</Typography>
<Typography variant="body1"><b>End Date:</b> {moment(goalDetails.goal_end_date).format('MMM D, YYYY')}</Typography>
<Box pt={2}>
<Button
variant="outlined"
component="label"
size="medium"
color="primary"
onClick={() => console.log('want to track progress')}
>
Track Progress Towards Goal
</Button>
</Box>
</Box>

<TrackProgressDialog
isOpen={openTrackProgressDialog}
handleClose={() => setOpenTrackProgressDialog(false)}
handleSubmit={() => handleSubmitTrackProgress()}
goalTimes={goalDetails.goal_times}
practiceTimes={practiceTimes}
setPracticeTimes={setPracticeTimes}
trackProgressDialogError={trackProgressDialogError}
/>
</>
)}
</>
);
Expand Down
7 changes: 6 additions & 1 deletion app/src/components/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import jwt from "jsonwebtoken";
import makeStyles from '@material-ui/core/styles/makeStyles';
import { mdiAccountCircle, mdiLogoutVariant } from '@mdi/js';
import parakeetImage from '../images/parakeet-pic.png';
import { useHistory } from 'react-router';

const useStyles = makeStyles((theme) => ({
govHeader: {
Expand Down Expand Up @@ -54,18 +55,22 @@ const useStyles = makeStyles((theme) => ({
'& a:hover': {
textDecoration: 'underline'
}
},
cursor: {
cursor: 'pointer'
}
}));

function Header(props) {
const classes = useStyles();
const history = useHistory();

return (
<AppBar position="sticky" style={{ boxShadow: 'none' }}>
<Box className={classes.govHeader}>
<Toolbar className={classes.govHeaderToolbar}>
<Box display="flex" justifyContent="space-between" width="100%">
<Box display="flex">
<Box display="flex" className={classes.cursor} onClick={() => history.push('/')}>
<picture>
<source srcSet={parakeetImage} media="(min-width: 600px)"></source>
<img src={parakeetImage} alt={'Parakeet'} height="30px" />
Expand Down
4 changes: 3 additions & 1 deletion app/src/components/Homepage.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ function Homepage() {
<TableCell>{moment(row.goal_start_date).format('MMM D, YYYY')}</TableCell>
<TableCell>{moment(row.goal_end_date).format('MMM D, YYYY')}</TableCell>
<TableCell>
<CircularProgressWithLabel value={20} />
<CircularProgressWithLabel
value={row.goal_practice_times ? (row.goal_practice_times * 100) / row.goal_times : 0}
/>
</TableCell>
<TableCell align="right">
<Box my={-1}>
Expand Down
78 changes: 78 additions & 0 deletions app/src/components/TrackProgressDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {
Dialog,
Button,
DialogTitle,
DialogContent,
DialogContentText,
TextField,
Box,
Typography
} from '@material-ui/core';
import makeStyles from '@material-ui/core/styles/makeStyles';

const useStyles = makeStyles((theme) => ({
buttonMargin: {
marginRight: '0.5rem'
},
textFieldMargin: {
marginBottom: '1rem'
}
}));

function TrackProgressDialog(props) {
const classes = useStyles();

return (
<Dialog open={props.isOpen} onClose={props.handleClose}>
<DialogTitle>Track Goal Progress</DialogTitle>
<DialogContent>
<DialogContentText>
Track progress towards your goal by entering how much you practiced.
</DialogContentText>
<Box pt={2}>
<TextField
className={classes.textFieldMargin}
type="number"
name="practice_times"
label="How many times did you practice?"
id="practice_times"
onChange={(e) => props.setPracticeTimes(e.target.value)}
variant="outlined"
value={props.practiceTimes}
fullWidth={true}
required={true}
placeholder="5"
/>
</Box>
</DialogContent>
<Box display="flex" justifyContent="flex-end" pt={1} pr={3} pb={2}>
<Button
className={classes.buttonMargin}
variant="outlined"
component="label"
size="medium"
color="primary"
onClick={props.handleClose}
>
Cancel
</Button>
<Button
variant="contained"
component="label"
size="medium"
color="primary"
onClick={props.handleSubmit}
>
Track Progress
</Button>
</Box>
{props.trackProgressDialogError && (
<Box pt={2}>
<Typography>{props.trackProgressDialogError}</Typography>
</Box>
)}
</Dialog>
);
}

export default TrackProgressDialog;

0 comments on commit 027a351

Please sign in to comment.