diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..e0a2a6b
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,14 @@
+node_modules
+npm-debug.log
+.git
+.gitignore
+README.md
+.env
+.nyc_output
+coverage
+.nyc_output
+.vscode
+.idea
+*.log
+dist
+.DS_Store
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..ba52b8f
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,50 @@
+name: CI
+
+on:
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '18'
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: npm ci
+
+ # Skipping linter for now as it is causing issues with the build
+ # - name: Run linter
+ # run: npm run lint
+
+ - name: Build application
+ run: npm run build
+
+ - name: Build Docker image
+ run: docker build -t test-track-app .
+
+ - name: Start application container
+ run: |
+ docker run -d --name test-track-container -p 8080:80 test-track-app
+ # Wait for container to start
+ sleep 10
+
+ - name: Test all routes
+ run: |
+ # Make the test script executable and run it
+ chmod +x test-routes.sh
+ ./test-routes.sh http://localhost:8080
+
+ - name: Cleanup
+ if: always()
+ run: |
+ docker stop test-track-container || true
+ docker rm test-track-container || true
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..ad182de
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,32 @@
+# Multi-stage build for React app with nginx
+FROM node:18-alpine AS builder
+
+# Set working directory
+WORKDIR /app
+
+# Copy package files
+COPY package*.json ./
+
+# Install all dependencies (including dev dependencies for build)
+RUN npm ci
+
+# Copy source code
+COPY . .
+
+# Build the application
+RUN npm run build
+
+# Production stage with nginx
+FROM nginx:alpine
+
+# Copy built assets from builder stage
+COPY --from=builder /app/dist /usr/share/nginx/html
+
+# Copy nginx configuration
+COPY nginx.conf /etc/nginx/nginx.conf
+
+# Expose port 80
+EXPOSE 80
+
+# Start nginx
+CMD ["nginx", "-g", "daemon off;"]
diff --git a/nginx.conf b/nginx.conf
new file mode 100644
index 0000000..98293ec
--- /dev/null
+++ b/nginx.conf
@@ -0,0 +1,41 @@
+events {
+ worker_connections 1024;
+}
+
+http {
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+
+ # Logging
+ access_log /var/log/nginx/access.log;
+ error_log /var/log/nginx/error.log;
+
+ # Gzip compression
+ gzip on;
+ gzip_vary on;
+ gzip_min_length 1024;
+ gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
+
+ server {
+ listen 80;
+ server_name localhost;
+ root /usr/share/nginx/html;
+ index index.html;
+
+ # Handle client-side routing
+ location / {
+ try_files $uri $uri/ /index.html;
+ }
+
+ # Cache static assets
+ location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
+ expires 1y;
+ add_header Cache-Control "public, immutable";
+ }
+
+ # Security headers
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-XSS-Protection "1; mode=block" always;
+ }
+}
diff --git a/test-routes.sh b/test-routes.sh
new file mode 100755
index 0000000..23a13c0
--- /dev/null
+++ b/test-routes.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+
+# Test script for all routes
+# Usage: ./test-routes.sh [base_url]
+# Default base_url is http://localhost:8080
+
+BASE_URL=${1:-"http://localhost:8080"}
+
+echo "Testing routes against: $BASE_URL"
+echo "================================"
+
+# Extract routes dynamically from App.tsx
+# Look for patterns and extract the path values
+routes=()
+
+# Read the file line by line and extract routes
+while IFS= read -r line; do
+ # Look for lines containing Route and path=
+ if [[ "$line" == *"