From 03a4b19b2aeec15984bc81e9d451c663e8e328b1 Mon Sep 17 00:00:00 2001
From: wajeht <58354193+wajeht@users.noreply.github.com>
Date: Fri, 19 Aug 2022 02:31:38 -0400
Subject: [PATCH] feat: scaffold exercise history with chart
---
package.json | 2 +-
.../api/v1/exercises/exercises.controller.js | 20 +-
.../api/v1/exercises/exercises.queries.js | 37 ++++
src/apps/api/v1/exercises/exercises.router.js | 12 ++
.../api/v1/exercises/exercises.validation.js | 27 ++-
src/apps/ui/App.vue | 18 +-
.../components/dashboard/SessionDetails.vue | 81 ++++---
.../ui/components/dashboard/VideoDetails.vue | 49 +++--
src/apps/ui/components/shared/Signup.vue | 2 +-
src/apps/ui/pages/dashboard/Block.vue | 20 ++
src/apps/ui/pages/dashboard/Community.vue | 56 ++---
src/apps/ui/pages/dashboard/Exercise.vue | 199 ++++++++++++++++++
src/apps/ui/router.vue.js | 33 ++-
13 files changed, 467 insertions(+), 89 deletions(-)
create mode 100644 src/apps/ui/pages/dashboard/Block.vue
create mode 100644 src/apps/ui/pages/dashboard/Exercise.vue
diff --git a/package.json b/package.json
index 17a7f4f9..9a8f3fd5 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
"release:alpha": "npm run release -- --prerelease alpha",
"rmds": "find . -name '.DS_Store' -delete",
"prepare": "husky install",
- "commit": "cz"
+ "commit": "git add -A && cz"
},
"bin": {
"gains": "./src/bin/gains.js"
diff --git a/src/apps/api/v1/exercises/exercises.controller.js b/src/apps/api/v1/exercises/exercises.controller.js
index c43a3115..dccb6dea 100644
--- a/src/apps/api/v1/exercises/exercises.controller.js
+++ b/src/apps/api/v1/exercises/exercises.controller.js
@@ -7,6 +7,24 @@ import * as ExercisesQueries from './exercises.queries.js';
import * as ExerciseCategoriesQueries from '../exercise-categories/exercise-categories.queries.js';
import { omit } from 'lodash-es';
+/**
+ * It gets the exercise history for a given exercise id
+ * @param req - The request object.
+ * @param res - The response object.
+ * @returns The exercise history for a specific exercise.
+ */
+export async function getExerciseHistory(req, res) {
+ const exercise_id = req.params.exercise_id;
+ const exercise = await ExercisesQueries.getExerciseHistoryByExerciseId(exercise_id);
+
+ return res.status(StatusCodes.OK).json({
+ status: 'success',
+ request_url: req.originalUrl,
+ message: 'The resource was returned successfully!',
+ data: exercise,
+ });
+}
+
/**
* It gets an exercise by its id
* @param req - The request object.
@@ -18,7 +36,7 @@ export async function getExercise(req, res) {
const exercise = await ExercisesQueries.getExerciseById(eid);
- if (!exercise.length) throw new CustomError.BadRequestError(`There are no exercise available for exercise id ${eid}!`); // prettier-ignore
+ // if (!exercise.length) throw new CustomError.BadRequestError(`There are no exercise available for exercise id ${eid}!`); // prettier-ignore
return res.status(StatusCodes.OK).json({
status: 'success',
diff --git a/src/apps/api/v1/exercises/exercises.queries.js b/src/apps/api/v1/exercises/exercises.queries.js
index d15d02d8..b9e2600d 100644
--- a/src/apps/api/v1/exercises/exercises.queries.js
+++ b/src/apps/api/v1/exercises/exercises.queries.js
@@ -19,6 +19,43 @@ export function getExerciseById(id) {
return db.select('*').from('exercises').where({ id }).andWhere({ deleted: false });
}
+/**
+ * Get all the sets for a given exercise, ordered by the date they were created.
+ * @param id - the id of the exercise you want to get the history for
+ * @returns An array of objects
+ */
+export async function getExerciseHistoryByExerciseId(id) {
+ const { rows } = await db.raw(
+ `
+ select
+ s.reps,
+ s.weight,
+ s.rpe as "rpe",
+ s.notes as "notes",
+ s.created_at as "created_at",
+ e."name" as "exercise_name",
+ ec."name" as "category_name",
+ e.id as "exercise_id",
+ ec.id as "category_id",
+ s.id as "set_id",
+ s.session_id as "session_id",
+ s.log_id as "log_id",
+ e.user_id as "user_id"
+ from
+ exercises e
+ inner join sets s on s.exercise_id = e.id
+ inner join exercise_categories ec on ec.id = e.exercise_category_id
+ where
+ e.deleted = false
+ and e.id = ?
+ order by
+ s.created_at desc
+ `,
+ [id],
+ );
+ return rows;
+}
+
/**
* Get all exercises from the database where the user_id matches the uid passed in and where the
* deleted column is false.
diff --git a/src/apps/api/v1/exercises/exercises.router.js b/src/apps/api/v1/exercises/exercises.router.js
index e6eff91f..38e1f5e3 100644
--- a/src/apps/api/v1/exercises/exercises.router.js
+++ b/src/apps/api/v1/exercises/exercises.router.js
@@ -42,6 +42,18 @@ exercises.get(
catchAsyncErrors(ExercisesController.getExercise),
);
+/**
+ * GET /api/v1/exercises/{exercise_id}/history
+ * @tags exercises
+ * @summary get history of a exercises
+ * @param {number} exercise_id.path.required - the exercise id - application/x-www-form-urlencoded
+ */
+exercises.get(
+ '/:exercise_id/history',
+ validator(ExercisesValidation.getExerciseHistory),
+ catchAsyncErrors(ExercisesController.getExerciseHistory),
+);
+
/**
* POST /api/v1/exercises
* @tags exercises
diff --git a/src/apps/api/v1/exercises/exercises.validation.js b/src/apps/api/v1/exercises/exercises.validation.js
index 6728479f..c2ac4b01 100644
--- a/src/apps/api/v1/exercises/exercises.validation.js
+++ b/src/apps/api/v1/exercises/exercises.validation.js
@@ -15,6 +15,12 @@ export const getExercise = [
.isNumeric()
.withMessage('exercise id must be an number!')
.bail()
+ .toInt()
+ .custom(async (eid) => {
+ const exercise = await ExercisesQueries.getExerciseById(eid);
+ if (exercise.length === 0) throw new Error('exercise does not exist!');
+ return true;
+ })
.toInt(),
];
@@ -47,7 +53,8 @@ export const getExercises = [
const user = await ExerciseCategoriesQueries.getExerciseCategoriesById(ecid);
if (user.length === 0) throw new Error('category_id does not exist!');
return true;
- }),
+ })
+ .toInt(),
];
export const postExercise = [
@@ -147,3 +154,21 @@ export const patchExerciseNote = [
return true;
}),
];
+
+export const getExerciseHistory = [
+ param('exercise_id')
+ .trim()
+ .notEmpty()
+ .withMessage('exercise id must not be empty!')
+ .bail()
+ .isNumeric()
+ .withMessage('exercise id must be an number!')
+ .bail()
+ .toInt()
+ .custom(async (exercise_id) => {
+ const exercise = await ExercisesQueries.getExerciseById(exercise_id);
+ if (exercise.length === 0) throw new Error('exercise does not exist!');
+ return true;
+ })
+ .toInt(),
+];
diff --git a/src/apps/ui/App.vue b/src/apps/ui/App.vue
index 6f202b85..3c942455 100644
--- a/src/apps/ui/App.vue
+++ b/src/apps/ui/App.vue
@@ -1,6 +1,10 @@
-
{{ exerciseDetails.category_name }}
+ highest max: 111 +# | +Reps | +Weight | +Rpe | +Session | +Video | +Date | +Notes | +
---|---|---|---|---|---|---|---|
+ + | +{{ s.reps }} | +{{ s.weight }} | +@{{ s.rpe }} | +
+ |
+
+ |
+ + {{ dayjs(s.created_at).format('MM/DD') }} + | +{{ s.notes }} | +