diff --git a/staff/debora-garcia/project/app/src/App.jsx b/staff/debora-garcia/project/app/src/App.jsx
index e69de29bb..22dcdf9e7 100644
--- a/staff/debora-garcia/project/app/src/App.jsx
+++ b/staff/debora-garcia/project/app/src/App.jsx
@@ -0,0 +1,14 @@
+import { Routes, Route } from "react-router-dom"
+import Login from "./views/Login";
+import Register from "./views/Register";
+import Home from "./views/Home";
+
+export default function App() {
+ console.log("App -> render")
+
+ return
+ } />
+ } />
+ } />
+
+}
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/components/Button/index.css b/staff/debora-garcia/project/app/src/components/Button/index.css
new file mode 100644
index 000000000..d884fa2ff
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/components/Button/index.css
@@ -0,0 +1,7 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+.Button {
+ @apply m-[.5rem_0] p-[.4rem] bg-white font-[1rem] rounded-[5px];
+ }
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/components/Button/index.jsx b/staff/debora-garcia/project/app/src/components/Button/index.jsx
new file mode 100644
index 000000000..70e55b70f
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/components/Button/index.jsx
@@ -0,0 +1,6 @@
+import "./index.css"
+
+export default function Button({ type, className, onClick, children }) {
+ return
+
+}
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/components/Field/index.css b/staff/debora-garcia/project/app/src/components/Field/index.css
new file mode 100644
index 000000000..67ee13ae5
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/components/Field/index.css
@@ -0,0 +1,7 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+.Field {
+ @apply p-[.3rem] bg-white text-[1rem] rounded-[5px] m-[1rem] w-[80%] ;
+ }
diff --git a/staff/debora-garcia/project/app/src/components/Field/index.jsx b/staff/debora-garcia/project/app/src/components/Field/index.jsx
new file mode 100644
index 000000000..7ebaaf273
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/components/Field/index.jsx
@@ -0,0 +1,8 @@
+import "./index.css"
+
+export default function Field({ id, type, placeholder }) {
+ return
+
+
+
+}
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/components/Heading/index.css b/staff/debora-garcia/project/app/src/components/Heading/index.css
new file mode 100644
index 000000000..5fc4c3cb8
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/components/Heading/index.css
@@ -0,0 +1,7 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+.Heading{
+ @apply text-[30px] text-[#38383b]
+}
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/components/Heading/index.jsx b/staff/debora-garcia/project/app/src/components/Heading/index.jsx
new file mode 100644
index 000000000..0eeb78d9d
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/components/Heading/index.jsx
@@ -0,0 +1,7 @@
+import "./index.css"
+
+export default function Heading({ level, children, className }) {
+ const Tag = `h${level}`
+ return {children}
+
+}
\ 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 bd6213e1d..2a3a33d0e 100644
--- a/staff/debora-garcia/project/app/src/index.css
+++ b/staff/debora-garcia/project/app/src/index.css
@@ -1,3 +1,27 @@
@tailwind base;
@tailwind components;
-@tailwind utilities;
\ No newline at end of file
+@tailwind utilities;
+
+:root {
+ --first-color: rgb(0, 0, 0);
+ --second-color: rgba(164, 151, 158, 0.776);
+ }
+
+ * {
+ font-family: "Courier New", Courier, monospace;
+ font-style: normal;
+ color: var(--first-color);
+ }
+
+ body {
+ background-color: var(--second-color);
+ margin: 0;
+ }
+
+ .registerForm{
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ }
+
+
\ 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 e69de29bb..8dc62ad8e 100644
--- a/staff/debora-garcia/project/app/src/logic/index.js
+++ b/staff/debora-garcia/project/app/src/logic/index.js
@@ -0,0 +1,9 @@
+import loginUser from "./loginUser";
+import registerUser from "./registerUser";
+
+const logic = {
+ registerUser,
+ loginUser
+}
+
+export default logic
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/logic/loginUser.js b/staff/debora-garcia/project/app/src/logic/loginUser.js
new file mode 100644
index 000000000..a76f5d9af
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/logic/loginUser.js
@@ -0,0 +1,33 @@
+import errors, { SystemError } from "com/errors"
+import validate from "com/validate"
+
+const loginUser = (username, password) => {
+ validate.username(username)
+ validate.password(password)
+
+ return fetch(`${import.meta.env.VITE_API_URL}/users/auth`, {
+ method: "POST",
+ headers: { "Content-type": "application/json" },
+ body: JSON.stringify({ username, password })
+ })
+ .catch(() => { throw new SystemError("server error") })
+ .then(response => {
+ if (response.status === 200) {
+ return response.json()
+ .catch(() => { throw new SystemError("server error") })
+ .then(token => sessionStorage.token = token)
+ }
+
+ 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 loginUser
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/logic/registerUser.js b/staff/debora-garcia/project/app/src/logic/registerUser.js
index e69de29bb..529c436ce 100644
--- a/staff/debora-garcia/project/app/src/logic/registerUser.js
+++ b/staff/debora-garcia/project/app/src/logic/registerUser.js
@@ -0,0 +1,31 @@
+import errors, { SystemError } from "com/errors"
+import validate from "com/validate"
+
+const registerUser = (name, surname, email, username, password, passwordRepeat) => {
+ validate.name(name)
+ validate.name(surname, "surname")
+ validate.email(email)
+ validate.username(username)
+ validate.password(password)
+ validate.passwordsMatch(password, passwordRepeat)
+
+ return fetch(`${import.meta.env.VITE_API_URL}/users`, {
+ method: "POST",
+ headers: { "Content-type": "application/json" },
+ body: JSON.stringify({ name, surname, email, username, password, passwordRepeat })
+ })
+ .catch(() => { throw new SystemError("server error") })
+ .then(response => {
+ if (response.status === 201) return
+
+ 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 registerUser
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/views/Home.jsx b/staff/debora-garcia/project/app/src/views/Home.jsx
new file mode 100644
index 000000000..05e8f0699
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/views/Home.jsx
@@ -0,0 +1,8 @@
+
+export default function Home() {
+ console.log("Home ->render")
+
+ return <>
+ Hola Home!
+ >
+}
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/views/Login.jsx b/staff/debora-garcia/project/app/src/views/Login.jsx
new file mode 100644
index 000000000..99d8cde72
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/views/Login.jsx
@@ -0,0 +1,46 @@
+import { useNavigate, Link } from "react-router-dom"
+
+import logic from "../logic"
+
+import Button from "../components/Button"
+import Field from "../components/Field"
+import Heading from "../components/Heading"
+
+export default function Login() {
+ console.log("Login ->render")
+ const navigate = useNavigate()
+
+
+ const handleLoginSubmit = event => {
+ event.preventDefault()
+
+ const form = event.target
+ const username = form.username.value
+ const password = form.password.value
+
+ try {
+ logic.loginUser(username, password)
+ .then(() => navigate("/home"))
+ .catch(error => {
+ console.error(error)
+ alert(error.message)
+
+ })
+
+ } catch (error) {
+ console.error(error)
+ alert(error.message)
+ }
+ }
+
+ return
+}
\ No newline at end of file
diff --git a/staff/debora-garcia/project/app/src/views/Register.jsx b/staff/debora-garcia/project/app/src/views/Register.jsx
new file mode 100644
index 000000000..05d7ccf45
--- /dev/null
+++ b/staff/debora-garcia/project/app/src/views/Register.jsx
@@ -0,0 +1,64 @@
+import { useState } from "react"
+import { useNavigate, Link } from "react-router-dom"
+
+import Button from "../components/Button"
+import Field from "../components/Field"
+import Heading from "../components/Heading"
+
+import logic from "../logic"
+
+export default function Register() {
+ console.log("Register->render")
+
+ const navigate = useNavigate()
+
+ //const [message, setMessage] = useState("")
+
+ const handleRegisterSubmit = event => {
+ event.preventDefault()
+
+ const form = event.target
+ const name = form.name.value
+ const surname = form.surname.value
+ const email = form.email.value
+ const username = form.username.value
+ const password = form.password.value
+ const passwordRepeat = form.passwordRepeat.value
+
+ try {
+ logic.registerUser(name, surname, email, username, password, passwordRepeat)
+ .then(() => navigate("/login"))
+ .catch(error => {
+ console.error(error)
+ alert(error.message)
+
+ })
+ } catch (error) {
+ console.error(error)
+
+ alert(error.message)
+ }
+
+ }
+
+ const handleLoginClick = event => {
+ event.preventDefault()
+
+ navigate("/login")
+
+ }
+
+ return
+}
diff --git a/staff/debora-garcia/project/doc/README.md b/staff/debora-garcia/project/doc/README.md
index 4b39b0ad3..2db345ebc 100644
--- a/staff/debora-garcia/project/doc/README.md
+++ b/staff/debora-garcia/project/doc/README.md
@@ -1,39 +1,42 @@
# Level Up
-Level Up allows users to generate and customize workouts, track personal bests and calculate performance metrics. Users can save workouts and interact with their fitness community.
+Level Up allows users to generate and customize workouts, track personal bests and calculate performance metrics. Users can save workouts and interact with their fitness community.
![](https://media.giphy.com/media/w7kBbAW9yrOG2Fni9R/giphy.gif?cid=790b7611608r7er4qfhmfkab26oqm779sm589ngws89in2zz&ep=v1_gifs_search&rid=giphy.gif&ct=g)
-
-
## Functional
### Use Cases
**User**
+
+- View workout results
+- Toggle like workout result
+- View wod result coments
+- Add coment to workout result
+- Delete coment from wod result
+- Get random workout
+- Share workout result
+- Edit wod result
+- View own wod results
+
+**v0.1**
+
- **Profile**
- - Edit personal information
- - Add photo/avatar
- - Modify username
- - Add optional personal data (gender, weight, age)
-- **Feed**
- - Share workouts and achievements
- - Like and comment on posts
- - View friends' shared workouts and achievements
-- **Workout**
- - Generate random workouts
- - Customize workouts
- - Save workouts with results
- - Optionally share workouts on the feed
+
+ - Edit personal information
+ - Add photo/avatar
+ - Modify username
+ - Add optional personal data (gender, weight, age)
+
- **Achievements**
- - Activity: View all recorded workouts
- - Analytics: Calculate and estimate weights and repetitions based on personal bests
+ - Activity: View all recorded workouts
+ - Analytics: Calculate and estimate weights and repetitions based on personal bests
- Add friends to circle ??
- View friends' profiles??
-
### UIUX Design
[Figma](https://www.figma.com/proto/iqaqS1n2OJgojcYrg6usIA/LEVEL-UP?page-id=0%3A1&node-id=1-2&viewport=439%2C526%2C0.37&t=ZmB9SD7AMSpINv7N-1&scaling=scale-down&content-scaling=fixed&starting-point-node-id=1%3A2)
@@ -56,51 +59,62 @@ Level Up allows users to generate and customize workouts, track personal bests a
### Data Model
**User**
+
- id (string)
- name (string)
- surname (string)
- email (string, unique)
- username (string, unique)
-- photo or avatar (string, optional)
-- gender (string, optional)
-- weight (string, optional)
-- age (string, optional) or (date, optional) ??
-- friends (list of User.id)
**Post**
+
- id (string)
- author (User.id)
- image (string,optional)
-- description/WOD/Movement (string)
-- result (string)
+- workout (Workout.id)
+- result (Result)
- date (date)
-- likes (list of User.id)
-- comments (list of Comment.id)
+- likes ([User.id)]
+- comments ([Comment.id])
+
+**Result**
+
+- id (string)
+- repetitions (number, optional)
+- time (number, optional)
+- weight (number, optional)
**Workout**
+
- id (string)
-- type (string)
-- exercises (list of Movement.id)
-- date (date)
-- description (string)
-- result (string)
-- SHARE // SAVE ?? (boolean)
+- type (string, enum: emom|amrap|for-time|benchmark)
+- exercises ([Movement.id])
+- duration (number)
+
+**Movement**
-**Movements**
- id (string)
- name (string)
- weight (number)
- repetitions (number)
-- date (date)
-**Activity**
+**v0.1**
+
+**Activity**
**Anlytics**
+
- exercises (list of Movement.id)
- - reps and weights (1RM, 2RM..)
- - percentage and weights (85%, 90%..)
+ - reps and weights (1RM, 2RM..)
+ - percentage and weights (85%, 90%..)
+ - photo or avatar (string, optional)
+**Profile**
+- gender (string, optional)
+- weight (string, optional)
+- age (date, optional)
+- friends (list of User.id)??