A modern web application for tracking Magic: The Gathering competitive pod league performance and statistics. View leaderboards, analyze win rates, and explore deck statistics with a dark, mystical MTG-themed UI.
- Pod Leaderboards - Player standings ranked by points with podium display and player cards
- Win Rate Analytics - Interactive charts with trend tracking over time
- Deck Statistics - Deck win rates and performance metrics filtered by pod
- Game History - Timeline view of recorded matches
- Game Entry - Admin interface for recording new game results
- Player & Pod Filtering - Filter data by pod, player, and player count
- Authentication - Protected admin routes with Supabase Auth
- Real-time Updates - Live data synchronization via Supabase
- Automated Backups - Daily database backups to Supabase Storage via GitHub Actions
- Offline Support - Mock data fallback for development without database
- Responsive Design - Mobile-first with adaptive navigation
- Dark Theme - Mystical purple and blue MTG-inspired aesthetic
- React 18.3 - UI framework
- TypeScript 5.8 - Type safety
- Vite 5.4 - Build tool with hot reload
- TanStack Query 5.8 - Server state management
- Tailwind CSS 3.4 - Utility-first styling
- shadcn/ui - Component library with Radix UI primitives
- Recharts 2.15 - Data visualization
- Supabase - PostgreSQL database with real-time capabilities
- React Hook Form - Form state management
- Zod - Schema validation
- GitHub Actions - CI pipeline and automated daily database backups
- Vitest - Unit testing
- ESLint - Code linting
- Prettier - Code formatting
- Husky - Pre-commit hooks
- Docker - Containerization (dev and production)
- Node.js 20+ and npm
- Supabase account (optional - app works with mock data)
# Clone the repository
git clone https://github.com/stousignant/mtg-pod-hub.git
cd mtg-pod-hub
# Install dependencies
npm install
# Copy environment template
cp .env.example .env
# Edit .env with your Supabase credentials (optional)
# App works with mock data if Supabase is not configured
# Start development server
npm run devVisit http://localhost:8080
npm run dev # Start dev server with hot reload
npm run build # Production build
npm run preview # Preview production build
npm run lint # Run ESLint
npm run format # Format code with Prettier
npm run format:check # Check code formatting
npm run test # Run tests once
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverageStart with Docker Compose:
docker-compose upApp will be available at http://localhost:8080 with hot reload.
Stop containers:
docker-compose downmtg-pod-hub/
├── src/
│ ├── components/ # React components
│ │ ├── ui/ # shadcn/ui primitives
│ │ └── ... # Feature components
│ ├── pages/ # Route components
│ ├── hooks/ # Custom React hooks
│ ├── lib/ # Utilities & Supabase client
│ ├── data/ # Mock data & TypeScript interfaces
│ ├── constants/ # Centralized configuration
│ └── test/ # Test utilities
├── .github/workflows/ # CI and backup pipelines
├── scripts/ # Automation scripts (DB backup)
├── migrations/ # SQL migration files
├── public/ # Static assets
└── ...config files
This project enforces code quality through:
- Pre-commit hooks - Automatic linting and formatting on commit
- CI/CD pipeline - Automated tests, linting, and builds on push
- Zero magic numbers - All constants centralized in
src/constants/config.ts - Type safety - TypeScript throughout with defined interfaces
Aggregated view of player performance by pod:
player_name- Player display nameavatar_url- Player avatar URLpod_name- Pod identifierwins,draws,losses- Game resultspoints- Calculated scorewin_rate- Percentage of games won
Deck performance metrics:
deck_name- Deck identifiercommander_name- Commander card nameowner_name- Deck ownergames_played- Total gameswins- Total winswin_rate- Win percentage
npm run build
# Deploy the dist/ directorySet environment variables in your hosting platform:
VITE_SUPABASE_URLVITE_SUPABASE_ANON_KEY
Build production image:
docker build -t mtg-pod-hub:latest .Run production container:
docker run -p 80:80 \
-e VITE_SUPABASE_URL=your_url \
-e VITE_SUPABASE_ANON_KEY=your_key \
mtg-pod-hub:latestProduction image includes:
- Multi-stage build for optimized size
- Nginx server with gzip compression
- Security headers configured
- Health check endpoint at
/health
Automated daily backups run via GitHub Actions at 3 AM UTC. The workflow:
- Dumps all table data using
pg_dump - Compares against the previous backup checksum
- Uploads to a private Supabase Storage bucket if changes are detected
- Retains the last 30 backups
Backups can also be triggered manually via workflow_dispatch in the Actions tab.
| Secret | Description |
|---|---|
SUPABASE_PROJECT_REF |
Project reference ID |
SUPABASE_URL |
Project API URL |
SUPABASE_SERVICE_ROLE_KEY |
Service role key (Project Settings → API) |
SUPABASE_DB_PASSWORD |
Database password (Project Settings → Database) |
SUPABASE_POOLER_HOST |
Session mode pooler host (Project Settings → Database) |
- Create a private
backupsbucket in Supabase Storage - Add the secrets above to your GitHub repository
- The workflow runs automatically, or trigger manually from the Actions tab
Create a .env file based on .env.example:
VITE_SUPABASE_URL=your_supabase_project_url
VITE_SUPABASE_ANON_KEY=your_supabase_anon_keyNote: App works offline with mock data if Supabase is not configured.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests and linting (
npm run test && npm run lint) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project uses Conventional Commits:
feat:- New featurefix:- Bug fixchore:- Maintenancedocs:- Documentationtest:- Testsrefactor:- Code refactoring
Run the test suite:
npm run test # Run once
npm run test:watch # Watch mode
npm run test:coverage # With coverage reportCoverage reports are generated in the coverage/ directory.
This project is licensed under the MIT License.