Skip to content

Commit

Permalink
Add getRandomWorkout logic in api and app with test; add WorkoutDetai…
Browse files Browse the repository at this point in the history
…ls view; modify Workout data model in README b00tc4mp#178
  • Loading branch information
Debi312 committed Aug 12, 2024
1 parent b2082fb commit e996a76
Show file tree
Hide file tree
Showing 32 changed files with 523 additions and 278 deletions.
Original file line number Diff line number Diff line change
@@ -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
4 changes: 3 additions & 1 deletion staff/debora-garcia/project/api/handlers/index.js
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -8,7 +9,8 @@ const routeHandler = {
errorHandler,
registerUserHandler,
authenticateUserHandler,
getUsernameHandler
getUsernameHandler,
getRandomWorkoutHandler
}

export default routeHandler
1 change: 1 addition & 0 deletions staff/debora-garcia/project/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}`))

Expand Down
34 changes: 34 additions & 0 deletions staff/debora-garcia/project/api/logic/getRandomWorkout.js
Original file line number Diff line number Diff line change
@@ -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
18 changes: 18 additions & 0 deletions staff/debora-garcia/project/api/logic/getRandomWorkout.test.js
Original file line number Diff line number Diff line change
@@ -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))
2 changes: 2 additions & 0 deletions staff/debora-garcia/project/api/logic/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"



Expand All @@ -10,6 +11,7 @@ const logic = {
authenticateUser,
getUsername,
insertWorkout,
getRandomWorkout
}

export default logic
1 change: 1 addition & 0 deletions staff/debora-garcia/project/api/test/get-randomWorkout.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
curl http://localhost:8080/workouts/emom -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmFiZTA1NjcxM2E4YmU5MmY4ZTU4NDQiLCJpYXQiOjE3MjI3OTUwMjAsImV4cCI6MTcyMzM5OTgyMH0.9JIikHMaqlttsnSqRe_YCT_1tYl9cEDfo3o6DFIePO8" -v
29 changes: 14 additions & 15 deletions staff/debora-garcia/project/app/src/App.jsx
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -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 <Routes>

<Route path="/login" element={logic.isUserLoggedIn() ? <Navigate to="/workouts" /> : <Login />} />
<Route path="/login" element={<RenderLogin />} />

<Route path="/register" element={logic.isUserLoggedIn() ? <Navigate to="/workouts" /> : <Register />} />

<Route path="/feed" element={logic.isUserLoggedIn() ? <Feed onUserLoggedOut={handleGoToLogin} /> : <Navigate to="/login" />} />

<Route path="/workouts" element={logic.isUserLoggedIn() ? <Workouts onUserLoggedOut={handleGoToLogin} /> : <Navigate to="/login" />} />

<Route path="/achievements" element={logic.isUserLoggedIn() ? <Achievements onUserLoggedOut={handleGoToLogin} /> : <Navigate to="/login" />} />
<Route path="/register" element={<RenderRegister />} />

<Route path="/*" element={<RenderHome />} />

</Routes>
}

const RenderRegister = () => (logic.isUserLoggedIn() ? <Navigate to="/workouts" /> : <Register />)
const RenderLogin = () => (logic.isUserLoggedIn() ? <Navigate to="/workouts" /> : <Login />)
const RenderHome = () => (logic.isUserLoggedIn() ? <Home /> : <Navigate to="/login" />)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import "./index.css"

export default function Button({ type, className, onClick, children }) {
return <button className={`Button ${className ? className : ""}`} onClick={onClick}>{children}</button>
return <button className={`Button ${className ? className : ""}`} type={type} onClick={onClick}>{children}</button>

}
13 changes: 8 additions & 5 deletions staff/debora-garcia/project/app/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -38,3 +37,7 @@ form {
.button-container Button:hover {
@apply bg-[#65524d];
}

main {
@apply flex flex-col justify-center items-center gap-4
}
30 changes: 30 additions & 0 deletions staff/debora-garcia/project/app/src/logic/getRandomWorkout.js
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions staff/debora-garcia/project/app/src/logic/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import isUserLoggedIn from "./isUserLoggedIn";
import loginUser from "./loginUser";
import logoutUser from "./logoutUser";
import registerUser from "./registerUser";
import getRandomWorkout from "./getRandomWorkout";

const logic = {
registerUser,
loginUser,
getUsername,
logoutUser,
isUserLoggedIn,
getRandomWorkout,

}

Expand Down
70 changes: 4 additions & 66 deletions staff/debora-garcia/project/app/src/views/Achievements.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <form>
<Header>
<Heading level="1">ACHIVEVEMENTS</Heading>
<div className="flex flex-wrap items-center space-x-4">
<div className="flex items-center justify-center w-12 h-12 bg-gray-300 rounded-full text-white text-xl font-bold">
{handlePrintInitialLetter(username)}
</div>
</div>
<Button onClick={handleLogout}>Logout</Button>
</Header>
<GoBackButton />
<Footer goToFeedClick={handleGoToFeedClick} goToWorkoutClick={handleGoToWorkoutClick} goToAchievementClick={handleGoToAchievementClick} />
</form>
return <div>
<p>Achievements</p>
</div>
}

33 changes: 33 additions & 0 deletions staff/debora-garcia/project/app/src/views/Amrap.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<div>
{workout?.workoutType && <p>{workout.workoutType}</p>}
{workout?.title && <p>{workout.title}</p>}
{workout?.duration && <p>{workout.duration}</p>}
</div>
);
}

Loading

0 comments on commit e996a76

Please sign in to comment.