diff --git a/staff/debora-garcia/project/api/handlers/getRandomWorkoutHandler.js b/staff/debora-garcia/project/api/handlers/getRandomWorkoutHandler.js
new file mode 100644
index 000000000..bfe90a05a
--- /dev/null
+++ b/staff/debora-garcia/project/api/handlers/getRandomWorkoutHandler.js
@@ -0,0 +1,32 @@
+import "dotenv/config"
+import logic from "../logic/index.js"
+import jwt from "../utils/jsonwebtoken-promised.js"
+import { CredentialsError } from "com/errors.js"
+
+const { JWT_SECRET } = process.env
+const getRandomWorkoutHandler = (req, res, next) => {
+ try {
+ const token = req.headers.authorization.slice(7)
+
+ jwt.verify(token, JWT_SECRET)
+ .then(payload => {
+ const { sub: userId } = payload
+ const { workoutType } = req.params
+
+ try {
+ logic.getRandomWorkout(userId, workoutType)
+ .then(randomWorkout => res.json(randomWorkout))
+ .catch(error => next(error))
+ } catch (error) {
+ next(error)
+ }
+
+ })
+ .catch(error => next(new CredentialsError(error.message)))
+
+ } catch (error) {
+ next(error)
+ }
+}
+
+export default getRandomWorkoutHandler
\ No newline at end of file
diff --git a/staff/debora-garcia/project/api/handlers/index.js b/staff/debora-garcia/project/api/handlers/index.js
index 1a1398bcd..9cfb51903 100644
--- a/staff/debora-garcia/project/api/handlers/index.js
+++ b/staff/debora-garcia/project/api/handlers/index.js
@@ -1,5 +1,6 @@
import authenticateUserHandler from "./authenticateUserHandler.js";
import errorHandler from "./errorHandler.js";
+import getRandomWorkoutHandler from "./getRandomWorkoutHandler.js";
import getUsernameHandler from "./getUsernameHandler.js";
import registerUserHandler from "./registerUserHandler.js";
@@ -8,7 +9,8 @@ const routeHandler = {
errorHandler,
registerUserHandler,
authenticateUserHandler,
- getUsernameHandler
+ getUsernameHandler,
+ getRandomWorkoutHandler
}
export default routeHandler
\ No newline at end of file
diff --git a/staff/debora-garcia/project/api/index.js b/staff/debora-garcia/project/api/index.js
index 086e6ca3b..1c735a2d3 100644
--- a/staff/debora-garcia/project/api/index.js
+++ b/staff/debora-garcia/project/api/index.js
@@ -24,6 +24,7 @@ mongoose.connect(MONGODB_URL)
api.post("/users", jsonBodyParser, routeHandler.registerUserHandler)
api.post("/users/auth", jsonBodyParser, routeHandler.authenticateUserHandler)
api.get("/users/:targetUserId", routeHandler.getUsernameHandler)
+ api.get("/workouts/:workoutType", routeHandler.getRandomWorkoutHandler)
api.use(errorHandler)
api.listen(PORT, () => console.log(`API running on PORT ${PORT}`))
diff --git a/staff/debora-garcia/project/api/logic/getRandomWorkout.js b/staff/debora-garcia/project/api/logic/getRandomWorkout.js
new file mode 100644
index 000000000..99e8533f4
--- /dev/null
+++ b/staff/debora-garcia/project/api/logic/getRandomWorkout.js
@@ -0,0 +1,34 @@
+import { User, Workout } from "../data/index.js"
+import { SystemError, NotFoundError } from "com/errors.js"
+import validate from "com/validate.js"
+
+const getRandomWorkout = (userId, workoutType) => {
+ validate.id(userId, "userId")
+ validate.type(workoutType, "workoutType")
+
+ return User.findById(userId).lean()
+ .catch(error => { throw new SystemError(error.message) })
+ .then(user => {
+ if (!user) throw new NotFoundError("user not found")
+
+ return Workout.find({ workoutType }).select("-__v").populate("movements").lean()
+ .catch(error => { throw new SystemError(error.message) })
+ .then(workouts => {
+ if (!workouts) throw new NotFoundError("workouts not found")
+
+ const randomNumber = Math.floor(Math.random() * workouts.length)
+
+ const randomWorkout = workouts[randomNumber]
+
+ if (!randomWorkout) throw new NotFoundError("workout not found")
+
+ randomWorkout.id = randomWorkout._id.toString()
+
+ delete randomWorkout._id
+
+ return randomWorkout
+ })
+
+ })
+}
+export default getRandomWorkout
diff --git a/staff/debora-garcia/project/api/logic/getRandomWorkout.test.js b/staff/debora-garcia/project/api/logic/getRandomWorkout.test.js
new file mode 100644
index 000000000..8a7b27715
--- /dev/null
+++ b/staff/debora-garcia/project/api/logic/getRandomWorkout.test.js
@@ -0,0 +1,18 @@
+import "dotenv/config"
+import mongoose from "mongoose"
+
+import getRandomWorkout from "./getRandomWorkout.js"
+const { MONGODB_URL } = process.env
+
+mongoose.connect(MONGODB_URL)
+ .then(() => {
+ try {
+ getRandomWorkout("66b0b8ff337c2b614a26583b", "emom")
+ .then(randomWorkout => console.log(randomWorkout))
+ .catch(error => console.error(error))
+
+ } catch (error) {
+ console.error(error)
+ }
+ })
+ .catch(error => console.error(error))
diff --git a/staff/debora-garcia/project/api/logic/index.js b/staff/debora-garcia/project/api/logic/index.js
index ffb745143..88957cce1 100644
--- a/staff/debora-garcia/project/api/logic/index.js
+++ b/staff/debora-garcia/project/api/logic/index.js
@@ -2,6 +2,7 @@ import registerUser from "./registerUser.js"
import authenticateUser from "./authenticateUser.js"
import getUsername from "./getUsername.js"
import insertWorkout from "./insertWorkout.js"
+import getRandomWorkout from "./getRandomWorkout.js"
@@ -10,6 +11,7 @@ const logic = {
authenticateUser,
getUsername,
insertWorkout,
+ getRandomWorkout
}
export default logic
\ No newline at end of file
diff --git a/staff/debora-garcia/project/api/test/get-randomWorkout.sh b/staff/debora-garcia/project/api/test/get-randomWorkout.sh
new file mode 100755
index 000000000..ccb0867e0
--- /dev/null
+++ b/staff/debora-garcia/project/api/test/get-randomWorkout.sh
@@ -0,0 +1 @@
+curl http://localhost:8080/workouts/emom -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmFiZTA1NjcxM2E4YmU5MmY4ZTU4NDQiLCJpYXQiOjE3MjI3OTUwMjAsImV4cCI6MTcyMzM5OTgyMH0.9JIikHMaqlttsnSqRe_YCT_1tYl9cEDfo3o6DFIePO8" -v
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/App.jsx b/staff/debora-garcia/project/app/src/App.jsx
index 40781664d..463d7f393 100644
--- a/staff/debora-garcia/project/app/src/App.jsx
+++ b/staff/debora-garcia/project/app/src/App.jsx
@@ -1,4 +1,4 @@
-import { Routes, Route, useNavigate, Navigate } from "react-router-dom"
+import { Routes, Route, Navigate } from "react-router-dom"
import logic from "./logic";
@@ -7,28 +7,27 @@ import Register from "./views/Register";
import Workouts from "./views/Workouts";
import Achievements from "./views/Achievements";
import Feed from "./views/Feed";
+import Amrap from "./views/Amrap";
+import Emom from "./views/Emom";
+import ForTime from "./views/ForTime";
+import Benchmark from "./views/Benchmark";
+import Home from "./views/Home";
+//TODO hacer una pagina de home
export default function App() {
console.log("App -> render")
- const navigate = useNavigate()
- const handleGoToLogin = () => navigate("/login")
- const handleGoToRegister = () => navigate("/register")
- const handleGoToFeed = () => navigate("/feed")
- const handleGoToWorkouts = () => navigate("/workouts")
- const handleGoToAchievements = () => navigate("/achievements")
return
- : } />
+ } />
- : } />
-
- : } />
-
- : } />
-
- : } />
+ } />
+ } />
+
}
+const RenderRegister = () => (logic.isUserLoggedIn() ? : )
+const RenderLogin = () => (logic.isUserLoggedIn() ? : )
+const RenderHome = () => (logic.isUserLoggedIn() ? : )
diff --git a/staff/debora-garcia/project/app/src/components/Button/index.jsx b/staff/debora-garcia/project/app/src/components/Button/index.jsx
index 70e55b70f..47925354b 100644
--- a/staff/debora-garcia/project/app/src/components/Button/index.jsx
+++ b/staff/debora-garcia/project/app/src/components/Button/index.jsx
@@ -1,6 +1,6 @@
import "./index.css"
export default function Button({ type, className, onClick, children }) {
- return
+ return
}
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/index.css b/staff/debora-garcia/project/app/src/index.css
index 3540b6286..6a1c69f6e 100644
--- a/staff/debora-garcia/project/app/src/index.css
+++ b/staff/debora-garcia/project/app/src/index.css
@@ -15,14 +15,13 @@
}
body {
- background-color: var(--second-color);
- margin: 0;
+ @apply flex min-h-screen w-full flex-col bg-[--second-color] justify-center;
}
-
-form {
- @apply flex flex-col justify-center min-h-[100vh];
+.Main {
+ @apply flex w-full flex-grow flex-col items-center justify-center;
}
+
.registerForm {
@apply flex flex-col items-center;
}
@@ -38,3 +37,7 @@ form {
.button-container Button:hover {
@apply bg-[#65524d];
}
+
+main {
+ @apply flex flex-col justify-center items-center gap-4
+}
diff --git a/staff/debora-garcia/project/app/src/logic/getRandomWorkout.js b/staff/debora-garcia/project/app/src/logic/getRandomWorkout.js
new file mode 100644
index 000000000..dd572149e
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/logic/getRandomWorkout.js
@@ -0,0 +1,30 @@
+import errors, { SystemError } from "com/errors"
+import validate from "com/validate"
+
+const getRandomWorkout = (workoutType) => {
+ validate.type(workoutType, "workoutType")
+ return fetch(`${import.meta.env.VITE_API_URL}/workouts/${workoutType}`, {
+ method: "GET",
+ headers: {
+ Authorization: `Bearer ${sessionStorage.token}`
+ }
+ })
+ .catch(() => { throw new SystemError("server error") })
+ .then(response => {
+ if (response.status === 200) {
+ return response.json()
+ .catch(() => { throw new SystemError("server error") })
+ .then(workoutRandom => workoutRandom)
+ }
+ return response.json()
+ .catch(() => { throw new SystemError("server error") })
+ .then(body => {
+ const { error, message } = body
+ const constructor = errors[error]
+ throw new constructor(message)
+ })
+ })
+}
+
+
+export default getRandomWorkout
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/logic/index.js b/staff/debora-garcia/project/app/src/logic/index.js
index c23133f8c..aa187be0b 100644
--- a/staff/debora-garcia/project/app/src/logic/index.js
+++ b/staff/debora-garcia/project/app/src/logic/index.js
@@ -3,6 +3,7 @@ import isUserLoggedIn from "./isUserLoggedIn";
import loginUser from "./loginUser";
import logoutUser from "./logoutUser";
import registerUser from "./registerUser";
+import getRandomWorkout from "./getRandomWorkout";
const logic = {
registerUser,
@@ -10,6 +11,7 @@ const logic = {
getUsername,
logoutUser,
isUserLoggedIn,
+ getRandomWorkout,
}
diff --git a/staff/debora-garcia/project/app/src/views/Achievements.jsx b/staff/debora-garcia/project/app/src/views/Achievements.jsx
index e695eca3e..858ab5ccc 100644
--- a/staff/debora-garcia/project/app/src/views/Achievements.jsx
+++ b/staff/debora-garcia/project/app/src/views/Achievements.jsx
@@ -2,74 +2,12 @@ import { useNavigate, Link } from "react-router-dom"
import { useState, useEffect } from "react"
import logic from "../logic"
-import Footer from "./components/Footer"
-import Header from "./components/Header"
-import Heading from "../components/Heading"
import Button from "../components/Button"
-import GoBackButton from "../components/GoBackButton"
-export default function Achievements({ onUserLoggedOut }) {
+export default function Achievements() {
console.log("Achievements ->render")
-
- const [username, setUsername] = useState("")
- const navigate = useNavigate()
- const [message, setMessage] = useState(null)
-
- useEffect(() => {
- console.log("Home -> useEffect")
- try {
- logic.getUsername()
- .then((username) => {
- console.log("Home -> setUsername")
-
- setUsername(username)
- })
- .catch(error => {
- console.error(error)
-
- setMessage(error.message)
- })
- } catch (error) {
- console.error(error)
-
- alert(error.message)
- }
- }, [])
-
- const handleGoToFeedClick = () => {
- navigate("/feed")
- }
-
- const handleGoToWorkoutClick = () => {
- navigate("/workouts")
- }
-
- const handleGoToAchievementClick = () => {
- navigate("/achievements")
- }
- const handleLogout = () => {
- logic.logoutUser()
- //navigate("/login")
- onUserLoggedOut()
-
- }
-
- const handlePrintInitialLetter = (username) => {
- return username.charAt(0).toUpperCase()
- }
-
- return
+ return
}
diff --git a/staff/debora-garcia/project/app/src/views/Amrap.jsx b/staff/debora-garcia/project/app/src/views/Amrap.jsx
new file mode 100644
index 000000000..9a4aee108
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/views/Amrap.jsx
@@ -0,0 +1,33 @@
+import { useNavigate, Link, Routes, Route, useParams } from "react-router-dom"
+import { useState, useEffect, } from "react"
+import logic from "../logic"
+
+import Button from "../components/Button"
+
+export default function Amrap() {
+ const { amrap } = useParams()
+ const [workout, setWorkout] = useState({})
+
+ useEffect(() => {
+ console.log("Benchmark ->render")
+ try {
+ logic.getRandomWorkout(amrap)
+ .then((amrapkWorkout) => {
+ setWorkout(amrapkWorkout)
+ console.log(amrapkWorkout)
+ })
+ .catch(error => alert(error.message))
+ } catch (error) {
+ alert(error.message)
+ }
+ }, [])
+
+ return (
+
+ {workout?.workoutType &&
{workout.workoutType}
}
+ {workout?.title &&
{workout.title}
}
+ {workout?.duration &&
{workout.duration}
}
+
+ );
+}
+
diff --git a/staff/debora-garcia/project/app/src/views/Benchmark.jsx b/staff/debora-garcia/project/app/src/views/Benchmark.jsx
new file mode 100644
index 000000000..47a465436
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/views/Benchmark.jsx
@@ -0,0 +1,32 @@
+import { useNavigate, Link, Routes, Route, useParams } from "react-router-dom"
+import { useState, useEffect } from "react"
+import logic from "../logic"
+
+import Button from "../components/Button"
+
+export default function Benchmark() {
+ const { benchmark } = useParams()
+ const [workout, setWorkout] = useState({})
+
+ useEffect(() => {
+ console.log("Benchmark ->render")
+ try {
+ logic.getRandomWorkout(benchmark)
+ .then((benchmarkWorkout) => {
+ setWorkout(benchmarkWorkout)
+ console.log(benchmarkWorkout)
+ })
+ .catch(error => alert(error.message))
+ } catch (error) {
+ alert(error.message)
+ }
+ }, [])
+
+ return (
+
+ {workout?.workoutType &&
{workout.workoutType}
}
+ {workout?.title &&
{workout.title}
}
+ {workout?.duration &&
{workout.duration}
}
+
+ );
+}
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/views/Emom.jsx b/staff/debora-garcia/project/app/src/views/Emom.jsx
new file mode 100644
index 000000000..870465a07
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/views/Emom.jsx
@@ -0,0 +1,38 @@
+import { Route, Routes, useNavigate, useParams } from "react-router-dom"
+import { useState, useEffect } from "react"
+import logic from "../logic"
+
+import Button from "../components/Button"
+
+export default function Emom() {
+ const { emom } = useParams()
+ const [workout, setWorkout] = useState({})
+
+ const generateRandomWorkout = () => {
+ console.log("Emom -> generateRandomWorkout")
+ try {
+ logic.getRandomWorkout(emom)
+ .then((emomWorkout) => {
+ setWorkout(emomWorkout)
+ console.log(emomWorkout)
+ })
+ .catch(error => alert(error.message))
+ } catch (error) {
+ alert(error.message)
+ }
+ }
+
+ useEffect(() => {
+ console.log("Emom -> useEffect")
+ generateRandomWorkout()
+ }, [emom])// workout?
+
+ return (
+
+ {workout?.workoutType &&
{workout.workoutType}
}
+ {workout?.title &&
{workout.title}
}
+ {workout?.duration &&
{workout.duration}
}
+
+
+ )
+}
diff --git a/staff/debora-garcia/project/app/src/views/Feed.jsx b/staff/debora-garcia/project/app/src/views/Feed.jsx
index e0fe519b8..6b6002a86 100644
--- a/staff/debora-garcia/project/app/src/views/Feed.jsx
+++ b/staff/debora-garcia/project/app/src/views/Feed.jsx
@@ -2,72 +2,13 @@ import { useNavigate, Link } from "react-router-dom"
import { useState, useEffect } from "react"
import logic from "../logic"
-import Footer from "./components/Footer"
-import Header from "./components/Header"
-import Heading from "../components/Heading"
import Button from "../components/Button"
import GoBackButton from "../components/GoBackButton"
-export default function Feed({ onUserLoggedOut }) {
+export default function Feed() {
console.log("Feed ->render")
- const [username, setUsername] = useState("")
- const navigate = useNavigate()
- const [message, setMessage] = useState(null)
-
- useEffect(() => {
- console.log("Home -> useEffect")
- try {
- logic.getUsername()
- .then((username) => {
- console.log("Home -> setUsername")
-
- setUsername(username)
- })
- .catch(error => {
- console.error(error)
-
- setMessage(error.message)
- })
- } catch (error) {
- console.error(error)
-
- alert(error.message)
- }
- }, [])
-
- const handleGoToFeedClick = () => {
- navigate("/feed")
- }
-
- const handleGoToWorkoutClick = () => {
- navigate("/workouts")
- }
-
- const handleGoToAchievementClick = () => {
- navigate("/achievements")
- }
- const handleLogout = () => {
- logic.logoutUser()
- //navigate("/login")
- onUserLoggedOut()
-
- }
-
- const handlePrintInitialLetter = (username) => {
- return username.charAt(0).toUpperCase()
- }
- return