Analyze NBA player stats and performance trends to make smarter sports betting picks!
Full Website: https://main.d261zxqkub55fi.amplifyapp.com/
Recording.2025-07-07.144330.mp4
On login or registration, the client sends a request to the backend using Axios (/auth/loginUseror/auth/registerUser). If successful, a JWT is stored in the localStorage for the user. Routes that aren't the root page are protected byProtectedRoutescomponent which sends a request to the backend (auth/verifyUser) to verify if the JWT is valid or if the user even has a JWT. If valid, users can access the routes, otherwise, they'll be redirected to the root/login page. After login, the user lands on the Home page where they search for NBA players. The search triggers an API call to the backend (api/v1/getPlayer/:name) and stores the payload in thelocationstate asplayerDatawhile navigating to the/check-playerroute. Users can then view last 'N' games or head-2-head games of players in/check-playerroute. playerData is stored in thelocationstate in both the/last-n-gamesand/head-to-headroutes. In/last-n-games, users fill in information about the stat they want to check, the prop-line, and the number of games they wish to view. This triggers an API call to the backend (/api/v1/getGames/playerID?n=<>) which uses theplayerIDfromplayerDataandnfrom the number of games filled out to get the 'n' game logs of the player, and sends that payload and the other information (prop-line, stat, number of games, etc.) to thelocationstate in the/resultsroute. Similarly, in/head-to-head, users fill out the same info except they must fill out the opposing team instead of number of games. This triggers an API call to the backend (/api/v1/getHeadToHead/:player_id/:team_name) to get the game logs of the player against the chosen opposing team, and sends that payload and the other information to thelocationstate in the/resultsroute. The data is displayed as an interactive bar graph of the relevant game logs usingChart.js.
-
Thenba_apiwas used to populate the PSQL tables with the latest active players and gamelogs using Python scripts.API Routes
POST /auth/registerUser- Register a new user.POST /auth/loginUser- Login and receive a JWT.GET /auth/verifyUser- Verify JWT for protected routes.GET /dashboard- Get the logged-in user's name (protected).GET /api/v1/getPlayer/:name- Get player info by name.GET /api/v1/getGames/:player_id?n=<n>- Get last N games for a player.GET /api/v1/getHeadToHead/:player_id/:team_name- Get games vs. a specific team.GET /api/v1/playerPlayedOpponentDidNot/:playerA_id/:playerB_id/:teamA/:teamB- Find games where player A played, but played B didn'tMiddleware:
authorization.js- Checks JWT validity for protected routesvalidInfo.js- Validates registration/login input
Here's how you can get this project started up locally
Install Docker and Docker Compose (https://www.docker.com/products/docker-desktop/)
git clone https://github.com/khoamelo/PickEmOrKickEm.git
cd PickEmOrKickEm
- For the root directory .env file, add:
PGUSER=postgres
PGHOST=db
PGPASSWORD=<your_password>
PGDATABASE=<your_db_name>
PGPORT=<your_pg_port>
- For the server directory .env file, add:
PORT=<your_port>
PGUSER=postgres
PGHOST=db
PGPASSWORD=<your_password>
PGDATABASE=<your_db_name>
PGPORT=<your_pg_port>
JWT_SECRET=<your_jwt_key>
- For the client directory .env file, add:
VITE_API_URL=http://localhost:<your_port>
- In the docker-compose.yml file, add
- /app/node_modulesunderservices->client->volumes - In the Dockerfile file for the client directory, change
COPY package.*json ./toCOPY package*.json ./
docker-compose up --build
docker-compose exec server python3 /app/db/nba_api_to_db/add_active_players_db.py
docker-compose exec server python3 /app/db/nba_api_to_db/add_game_logs_db.py
docker-compose down -v
docker-compose up --build
Then repeat step 5
Once you have installed and set up everything, you will be prompted to sign in or register. If you don't have an account which you probably don't if you just installed and set up for the first time, or repopulated the DB, then register, then sign in
Once signed in, you will be prompted to enter an active NBA player name to check stats for (The matching is case-insensitive and accent-insensitive, but sensitive to punctuation such as periods and hyphens (e.g., P.J. Tucker, Shai Gilegous-Alexander, etc.))
After choosing a player, you will prompted to choose to check either of the following "Last 'N' Games" or "Head-2-Head Games." Last 'N' Games will visualize the game logs of the players last 'n' games, and Head-2-Head games will visualize the game logs of players playing against a specific team
If Last 'N' Games is chosen, you will be asked to choose a stat to check (points, rebounds, assists, points + rebounds, etc.), a prop-line that a betting site might have (SGA over 31.5 points), and the number of games you want to view
Similarly, if Head-2-Head Games is chosen, you will asked to choose a stat to check, a prop-line, and the opposing team
Once you enter in all the required fields, you will be shown a bar graph of the games you chose to visualize for the player, and whether the player hit over their prop-line (green), hit under (red), or hit exactly on the prop-line (gray). Three gauges are on top of the bar graph which gives a percentage of the player hitting over, under, or pushing the prop-line. Hovering over each bar will give you the date of the match played, the opponent and whether or not they played home or away, and the exact stat the player got.
You can also adjust the minutes played to filter out games where players played a certain amount of minutes