# Sawnoff League

A competitive gaming league platform built with Symfony, Docker with FrankenPHP, and Bootstrap 5.

## Overview

Sawnoff League is a web-based platform designed to manage competitive gaming leagues. It provides functionality for:
- Managing teams and their information
- Scheduling and tracking matches
- Maintaining season standings and rankings
- Viewing match history and results

## Technology Stack

- **Backend Framework**: Symfony 7.4
- **Database**: PostgreSQL 16
- **Container**: Docker with FrankenPHP
- **Frontend**: Bootstrap 5 (CDN)
- **PHP**: 8.3
- **ORM**: Doctrine

## Features

### Core Functionality
- **Team Management**: Create and manage gaming teams
- **Season Management**: Organize competitions into seasons
- **Match Scheduling**: Schedule matches between teams
- **Standings**: Automatic calculation of team rankings based on match results
- **Responsive Design**: Mobile-friendly interface using Bootstrap 5
- **Admin Panel**: Secure admin interface for managing all league data

### Admin Features
- **User Authentication**: Secure login system for admin users
- **Season Management**: Create and manage league seasons (Winter, Spring, Summer, Autumn)
- **Team Management**: Add, edit, and delete teams
- **Round Management**: Organize matches into rounds within seasons
- **Match Management**: Schedule and manage matches with full CRUD operations
- **Dashboard**: Overview of league statistics and quick actions

### Database Schema
- **Team**: Stores team information (name, logo, timestamps)
- **Season**: Manages league seasons (name, dates, active status)
- **Round**: Organizes matches into rounds within seasons
- **GameMatch**: Tracks matches (teams, scores, status, dates, round assignment)
- **Standing**: Maintains season standings (wins, losses, draws, points)
- **User**: Admin user accounts with secure authentication

## Prerequisites

- Docker and Docker Compose (for containerized deployment)
- OR PHP 8.3+ and Composer (for local development)
- PostgreSQL 16 (if running without Docker)

## Setup Instructions

### Using Docker (Recommended)

1. **Clone the repository**
   ```bash
   git clone https://github.com/Dacso12/Sawnoff-League.git
   cd Sawnoff-League
   ```

2. **Copy environment configuration**
   ```bash
   cp .env.example .env
   ```

3. **Start the services**
   ```bash
   docker compose up -d
   ```

4. **Install dependencies**
   ```bash
   docker compose exec frankenphp composer install
   ```

5. **Run database migrations**
   ```bash
   docker compose exec frankenphp php bin/console doctrine:migrations:migrate --no-interaction
   ```

6. **Access the application**
   - Open your browser and navigate to `http://localhost:8080`

### Local Development (Without Docker)

1. **Clone the repository**
   ```bash
   git clone https://github.com/Dacso12/Sawnoff-League.git
   cd Sawnoff-League
   ```

2. **Install dependencies**
   ```bash
   composer install --ignore-platform-req=ext-redis
   ```

3. **Configure environment**
   ```bash
   cp .env.example .env
   ```
   Edit `.env` and update the `DATABASE_URL` to match your PostgreSQL configuration.

4. **Create database and run migrations**
   ```bash
   php bin/console doctrine:database:create
   php bin/console doctrine:migrations:migrate --no-interaction
   ```

5. **Start the development server**
   ```bash
   php -S 127.0.0.1:8000 -t public
   ```

6. **Access the application**
   - Open your browser and navigate to `http://localhost:8000`

## Project Structure

```
Sawnoff-League/
├── bin/                    # Console scripts
├── config/                 # Configuration files
│   ├── packages/          # Bundle configurations
│   └── routes.yaml        # Route definitions
├── migrations/            # Database migrations
├── public/                # Web root
│   └── index.php         # Front controller
├── src/
│   ├── Controller/       # Controllers
│   ├── Entity/           # Doctrine entities
│   ├── Form/             # Symfony forms
│   └── Repository/       # Database repositories
├── templates/            # Twig templates
│   ├── base.html.twig   # Base layout
│   ├── home/            # Home page templates
│   ├── teams/           # Teams page templates
│   ├── matches/         # Matches page templates
│   └── standings/       # Standings page templates
├── var/                  # Cache and logs
├── vendor/              # Composer dependencies
├── .env                 # Environment configuration
├── composer.json        # PHP dependencies
├── docker-compose.yml   # Docker services configuration
└── Dockerfile          # Docker image definition
```

## Available Pages

- **Home** (`/`) - Welcome page with current season overview and recent matches
- **Teams** (`/teams`) - List of all teams
- **Matches** (`/matches`) - Match schedules and results with season filtering
- **Standings** (`/standings`) - Current season rankings and statistics

## Development Guidelines

### Code Quality Standards
- Follow Symfony best practices
- Use PSR-12 coding standards
- Maintain proper MVC structure
- Add meaningful comments for complex logic
- Keep code clean and maintainable

### Database Operations
- Always create migrations for schema changes:
  ```bash
  php bin/console doctrine:migrations:diff
  ```
- Apply migrations:
  ```bash
  php bin/console doctrine:migrations:migrate
  ```

### Clearing Cache
```bash
php bin/console cache:clear
```

### Creating New Entities
```bash
php bin/console make:entity
```

## Admin Panel

### Access

The admin panel is accessible at `/admin-panel/login`. This URL is intentionally non-standard for security purposes and should be kept confidential in production environments.

**⚠️ IMPORTANT:** There are no links to the admin panel on the public website by design. The admin URL must be accessed directly.

### Default Credentials (Development Only)

For development and testing purposes, a default admin account is created via fixtures:

- **Email**: `admin@sawnoff.local`
- **Password**: `admin123`

**⚠️ WARNING:** Change these credentials immediately in production environments!

### Creating Admin Users

To create a new admin user, use the console command:

```bash
php bin/console app:create-admin
```

This command will prompt you for:
- Email address
- Password (minimum 6 characters)
- Password confirmation

The password will be securely hashed before being stored in the database.

### Admin Features

The admin panel provides the following functionality:

1. **Dashboard**
   - Overview of teams, seasons, and active season
   - Quick access links to all management sections

2. **Season Management**
   - Create seasons with validated types (Winter, Spring, Summer, Autumn)
   - Set start and end dates
   - Toggle active status (only one active season allowed)
   - View associated rounds and matches
   - Delete seasons (with protection for seasons with data)

3. **Team Management**
   - Create and edit teams
   - Add team logos (emoji or URL)
   - View match statistics
   - Delete teams (with protection for teams with matches)

4. **Round Management**
   - Create rounds within seasons
   - Auto-increment round numbers
   - Set optional start and end dates
   - View matches per round
   - Delete rounds (with protection for rounds with matches)

5. **Match Management**
   - Schedule matches within rounds
   - Select home and away teams (with validation)
   - Set match date and time
   - Update match status (scheduled, in progress, completed, postponed, cancelled)
   - Auto-populate season from round
   - Delete matches

### Security Features

- **Authentication Required**: All admin routes require ROLE_ADMIN
- **CSRF Protection**: All forms include CSRF tokens
- **Password Hashing**: Bcrypt algorithm for secure password storage
- **Session Management**: Remember me functionality with 1-week lifetime
- **No Public Links**: Admin panel URL not exposed on public pages
- **Robots Meta Tag**: Login page marked as noindex/nofollow

### Best Practices

- Always log out when finished with admin tasks
- Use strong, unique passwords for production admin accounts
- Regularly review and update admin user access
- Monitor admin activity through application logs
- Keep the admin URL confidential in production

## Docker Services

The `docker-compose.yml` defines two services:

1. **frankenphp**: Web server running Symfony application
   - Port: 8080 (HTTP)
   - Port: 8443 (HTTPS)

2. **db**: PostgreSQL database
   - Port: 5432
   - Database: `sawnoff_league`
   - User: `sawnoff`
   - Password: `sawnoff123`

## Environment Variables

Key environment variables (see `.env.example`):

- `APP_ENV`: Application environment (dev/prod)
- `APP_SECRET`: Secret key for Symfony
- `DATABASE_URL`: PostgreSQL connection string

## Future Enhancements

The platform is designed to be expandable for:
- User authentication and authorization
- Advanced analytics and statistics
- AI-based match predictions
- Tournament bracket systems
- Live match updates
- Player statistics tracking
- Team roster management
- Match replay and VOD integration

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Submit a pull request

## License

This project is open source and available under the MIT License.

## Support

For issues and questions, please open an issue on GitHub.