This is a Gym Tracker application built with FastAPI for the backend and Expo/React Native for the frontend. The application allows users to track their workouts, manage exercises, and view statistics. It works on both mobile devices and web browsers.
- User authentication (registration, login, logout)
- Add Exercises
- Start a workout where you can add your previously added exercises
- Add sets to exercises, where you specify the weight, repetitions and how good the set was
- checkmark = set done
- plus = set was easy
- minus = set was hard
- H = needed help
- You can add a note to the exercise and the workout
- Your workout time is tracked
- Calendar allows you to see your workouts on a specific date and the content of the workout
- Profile page shows your statistics and gyms nearby using the Google Maps API
A test user with demo data is available for quick testing:
-
Username:
test -
Password:
test -
If not already provided, create a
.envfile in the root directory of the project (next todocker-compose.yaml) with the following content:AUTH_SECRET_KEY=your_strong_secret_key_here GOOGLE_MAPS_API_KEY=your_google_maps_api_key_here
There are two main ways to run this project:
1. Using Docker:
-
Ensure you have Docker and Docker Compose installed.
-
From the root directory of the project, run:
docker-compose up --build
-
The frontend will be accessible at
http://localhost:8081. -
The backend API Documentation will be accessible at
http://localhost:8000/docs.
2. Local Development Setup: Frontend (Expo/React Native):
-
Navigate to the frontend directory:
cd app -
Install dependencies:
npm install
-
Start the development server:
npm start
-
If needed regenerate the Frotend Api with Open Api Generator:
npx @openapitools/openapi-generator-cli generate -i http://localhost:8000/openapi.json -g typescript-fetch -o api --additional- properties=useSingleRequestParameter=false,useTags=true,exportModels=true --type-mappings date=string
Backend (FastAPI):
-
Navigate to the backend directory:
cd api -
Create a virtual environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install dependencies:
pip install -e . -
Run the development server:
fastapi dev main.py
-
The frontend will be accessible at
http://localhost:8081. -
The backend API Documentation will be accessible at
http://localhost:8000/docs.
- Directory Structure: Organization of project folders.
- File Structure: Division of program code into files.
- Comments: Commenting of (complex) functions or code sections, use of (phpDoc, or similar).
- Formatting: Formatting of backend and frontend code.
- Code Organization: Subdivision of program code into functions/sections.
- Programming Techniques: Efficiency in programming, e.g., recursion, concepts, design patterns.
- Understandability: Clarity of code, e.g., good naming of variables (also formatting, commenting, ...).
- Login: Registration and login functionality present.
- IO (DB): Data is read from/written to files or databases.
- Use of External APIs: External APIs (third-party code) integrated and used in the program.
- Validation: User inputs are validated and checked for errors.
- Security: Basic protection against web attacks (SQL Injection, XSS), encryption, validation.
- Dynamics: The website is dynamically built and adapted (where it makes sense).
- Use Cases Considered: Use cases that also reflect unusual user behavior.
- Error Messages: Error and success messages are present and do not disclose sensitive information.
- Bugs Present: Program functions can be tested without errors. (This is an outcome, the goal is to minimize bugs).
- Browser Compatibility: All current modern browsers (i.e., Edge, Firefox, Chrome, possibly Safari).
- Page Structure: Clear page layout, possibly responsive design.
- Usability: Functions are clear to the user, link depth of the page, navigation aids, help, easy to learn, ...
- Help Texts: Texts to help the user are present (constraints, options, tooltips, descriptions).
-
Directory Structure:
- The project is clearly separated into a
backend(FastAPI) and afrontend(Expo/React Native) application, each with its own logical subdirectories. - Backend (
apifolder):entities/: Contains Pydantic/SQLModel data models (e.g.,gym.py,user.py).routers/: Contains FastAPI routers for different API endpoints (e.g.,users_router.py,statistics_router.py,misc_router.py).- Root files like
main.py,database_setup.py,auth_setup.pyfor core application logic.
- Frontend (
appfolder):api/: Contains auto-generated API client code from OpenAPI.app/: Contains Expo Router specific files for navigation and screen layouts (e.g.,(tabs)/_layout.tsx).assets/: For static assets like fonts and images.components/: Reusable React Native components (e.g.,Profile.tsx,ActiveWorkout.tsx,generic/MyButton.tsx).context/: React Context for managing global state like API instances and authentication (e.g.,ApiContext.tsx).
- The project is clearly separated into a
-
File Structure:
- Code is modularized into files based on functionality.
- Backend: Routers handle specific API paths, entities define data structures, and setup files manage database and authentication configurations.
- Example: User-related routes are in
api/routers/users_router.py, while workout-related routes are inapi/routers/workouts_router.py.
- Example: User-related routes are in
- Frontend: Screens are typically in the
app/directory, reusable UI elements are incomponents/, and global state management is incontext/.- Example: The user profile display and logic is in
app/components/Profile.tsx. API client models are inapp/api/models/.
- Example: The user profile display and logic is in
-
Comments:
- Comments are being used everywhere.
-
Formatting:
- Frontend code is formatted using Prettier and ESLint, ensuring consistent style and error checking.
- Backend code is formatted using Black, which is a popular Python code formatter.
-
Code Organization:
-
Backend: FastAPI's router system naturally organizes code by API resource. Dependency injection is used for database sessions and current user.
-
Frontend: React components are used for UI elements, with props for data passing and state management via
useStateanduseEffect.react-hook-formis used for form management.
-
-
Programming Techniques:
- Asynchronous Operations:
async/awaitis used extensively in both backend (FastAPI async routes,httpxcalls) and frontend (API calls,expo-location). - State Management (Frontend): React Hooks (
useState,useEffect,useContext) are used for managing component state and side effects.ApiContextprovides a centralized way to manage API instances and authentication status. - Form Management (Frontend):
react-hook-formis used for handling forms, validation, and field arrays (e.g., inActiveWorkout.tsxandExecution.tsx). - Dependency Injection (Backend): FastAPI's
Dependssystem is used for managing dependencies like database sessions and authenticated users. - ORM/Data Mapping (Backend): SQLModel is used as an ORM to interact with the database, defining models that map to database tables.
- Asynchronous Operations:
-
Login:
- Registration and login functionality is implemented.
- Frontend:
Login.tsxcomponent handles user input, andApiContext.tsxcontainsloginandsignupmethods that call the backend. SecureStore (mobile) and Cookies with HTTP-Only Tokens (web) are used for token/session management. - Backend:
api/routers/users_router.pydefines/token(login) and/users/(POST for registration) endpoints. Password hashing and JWT/OAuth2 Bearer tokens are used.
-
IO (DB):
- Data is read from and written to a SQLite database (
database.db) using SQLModel. - Backend Example (
api/routers/statistics_router.py): - Workouts, exercises, sets, and user data are persisted in the database.
- Data is read from and written to a SQLite database (
-
Use of External APIs:
- The Google Maps Places API is used to find nearby gyms.
- Backend (
api/routers/misc_router.py): MakesPOSTrequests tohttps://places.googleapis.com/v1/places:searchNearbyusinghttpx. - Frontend (
app/components/Profile.tsx): Calls the backend endpoint which in turn calls the Google API. It also usesexpo-locationto get the user's current GPS coordinates. This works on both mobile and web but requires user permission for location access.
-
Validation:
-
Backend: Pydantic models (via SQLModel) automatically validate incoming request data types and constraints for API endpoints.FastAPI automatically returns detailed validation errors if input doesn't match the model.
-
Frontend:
react-hook-formis used for form validation. Empty Exercise names are not allowed and Reps and Weight must be numbers for example.
-
-
Security:
- Authentication: OAuth2 Password Bearer flow with JWT tokens is used for user authentication in the backend.
- Password Hashing: Passwords are hashed before being stored (handled by
auth_setup.py'sget_password_hash). - Input Validation: Pydantic models on the backend provide a first line of defense against malformed data and potential injection attacks by ensuring data types.
- API Key Management: The
GOOGLE_MAPS_API_KEYis loaded from an.envfile in the backend - CORS: The backend (
main.py) configures CORS to restrict which origins can access the API. - Token Expiration: JWT tokens have an expiration time, and refresh tokens are used to maintain user sessions.
- Secure Storage: On the frontend, Expo SecureStore is used to securely store tokens on mobile devices. For web, HTTP-Only cookies are used to prevent XSS attacks.
-
Dynamics:
- The frontend is built with React Native and Expo, making it inherently dynamic.
- UI components render based on application state (e.g.,
currentUser,statistics,gymsinProfile.tsx). - Data is fetched from the backend API and displayed, lists are rendered using
FlatList. - Navigation is handled by Expo Router, allowing users to move between different screens without reloading the app.
-
Use Cases Considered:
- Error States: Error messages are displayed to the user if API calls fail or permissions are denied (e.g.,
gymsError,locationErrorinProfile.tsx). - Empty States: Messages are shown when no data is available (e.g., "No Gyms nearby", "No exercises found.").
- Default Values: Default values are provided for form inputs and initial states (e.g.,
defaultLocationinProfile.tsx, initialSetCreatevalues inExecution.tsx).
- Error States: Error messages are displayed to the user if API calls fail or permissions are denied (e.g.,
-
Error Messages:
-
Backend: FastAPI uses
HTTPExceptionto return structured error responses with status codes and details. -
Frontend: Error states are managed and displayed to the user.
console.erroris used for logging more detailed errors.
-
-
Browser Compatibility:
- The frontend is built with Expo for Web (
npx expo export --platform web). Expo aims to provide good compatibility with modern web browsers (Chrome, Firefox, Edge, Safari) by using standard web technologies and polyfills where necessary.
- The frontend is built with Expo for Web (
-
Page Structure:
- The application uses a tab-based navigation (
app/(tabs)/_layout.tsx) for main sections. - Screens are structured using React Native's
Viewcomponents and styled with Tailwind CSS (nativewind), allowing for clear and potentially responsive layouts. ScrollViewis used for content that might exceed screen height.- The use of Tailwind CSS facilitates responsive design principles.
- The application uses a tab-based navigation (
-
Usability:
- Navigation is clear through bottom tabs.
- Buttons (
MyButton) have descriptive text (e.g., "Logout", "Add Set", "Finish"). - Interactive elements like
TouchableOpacityprovide visual feedback on press. - Modals (
ExerciseListModal,ConfirmDeleteModal) are used for focused interactions. - The application flow for common tasks like starting a workout, adding exercises, and viewing history seems logical.
-
Help Texts:
placeholderattributes inMyTextInputcomponents guide user input.- Descriptive text is used for empty states or to provide context