Complete layout overhaul

This commit is contained in:
Frank
2026-07-04 19:08:31 +02:00
parent 05f4f2c32f
commit 5b03bd1d1c
22 changed files with 842 additions and 175 deletions
+4 -2
View File
@@ -5,14 +5,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{{ 'site.name'|trans }}{% endblock %}</title>
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{{ encore_entry_link_tags('app') }}
{% endblock %}
</head>
<body>
{% block header %}
<header>
<nav>
{% set pathinfo = app.request.pathinfo %}
<a href="/">{{ 'nav.home'|trans }}</a> |
<a href="{{ path('game_dashboard') }}">{{ 'nav.game'|trans }}</a> |
{% if app.user %}
@@ -23,6 +22,7 @@
{% endif %}
</nav>
</header>
{% endblock %}
{% block main %}
<main>
{% for label, messages in app.flashes %}
@@ -35,9 +35,11 @@
{% block body %}{% endblock %}
</main>
{% endblock %}
{% block footer %}
<footer>
<small>&copy; {{ "now"|date("Y") }} {{ 'site.name'|trans }}</small>
</footer>
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
+57 -41
View File
@@ -1,42 +1,57 @@
{% extends 'base.html.twig' %}
{% extends 'layout/site.html.twig' %}
{% block title %}Game Dashboard{% endblock %}
{% block body %}
<h1>Game Dashboard</h1>
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="mb-0">Game Dashboard</h1>
{% if is_granted('ROLE_ADMIN') %}
<a href="{{ path('game_admin_dashboard') }}" class="btn btn-outline-secondary">Go to Game Admin Dashboard</a>
{% endif %}
</div>
{% if is_granted('ROLE_ADMIN') %}
<p><a href="{{ path('game_admin_dashboard') }}">Go to Game Admin Dashboard</a></p>
{% endif %}
<div class="row g-4 mb-4">
<div class="col-md-6">
<div class="card h-100">
<div class="card-header bg-secondary text-white">Create New Session</div>
<div class="card-body">
{% if availableGames is not empty %}
<form method="post">
<select name="game_id" class="form-select mb-3">
{% for game in availableGames %}
<option value="{{ game.id }}">
{{ game.name }} ({{ game.numberOfPlayers }} players)
{% if is_granted('ROLE_ADMIN') %}
[{{ game.status.value }}]
{% endif %}
</option>
{% endfor %}
</select>
<button type="submit" name="create_session" class="btn btn-primary">Create Session</button>
</form>
{% else %}
<p class="text-muted mb-0">No games available to start.</p>
{% endif %}
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100">
<div class="card-header bg-secondary text-white">Join Session</div>
<div class="card-body">
<form method="post" class="d-flex gap-2">
<input type="text" name="invite_code" class="form-control" placeholder="Enter Invite Code" required>
<button type="submit" name="join_session" class="btn btn-primary text-nowrap">Join Session</button>
</form>
</div>
</div>
</div>
</div>
<h2>Create New Session</h2>
{% if availableGames is not empty %}
<form method="post">
<select name="game_id">
{% for game in availableGames %}
<option value="{{ game.id }}">
{{ game.name }} ({{ game.numberOfPlayers }} players)
{% if is_granted('ROLE_ADMIN') %}
[{{ game.status.value }}]
{% endif %}
</option>
{% endfor %}
</select>
<button type="submit" name="create_session">Create Session</button>
</form>
{% else %}
<p>No games available to start.</p>
{% endif %}
<h2>Join Session</h2>
<form method="post">
<input type="text" name="invite_code" placeholder="Enter Invite Code" required>
<button type="submit" name="join_session">Join Session</button>
</form>
<h2>Your Sessions</h2>
<h2 class="h4">Your Sessions</h2>
{% if sessions is not empty %}
<table>
<div class="table-responsive">
<table class="table table-striped align-middle">
<thead>
<tr>
<th>ID</th>
@@ -52,7 +67,7 @@
<tr>
<td>{{ session.id }}</td>
<td>{{ session.game.name }}</td>
<td>{{ session.status.value }}</td>
<td><span class="badge bg-info text-dark">{{ session.status.value }}</span></td>
<td>{{ session.created|date('Y-m-d H:i') }}</td>
<td>
{% set inviteCode = '' %}
@@ -65,25 +80,25 @@
{% if inviteCode %}
<code>{{ inviteCode }}</code>
{% else %}
<form method="post" style="display:inline;">
<form method="post" class="d-inline">
<input type="hidden" name="session_id" value="{{ session.id }}">
<button type="submit" name="create_invite">Generate Invite</button>
<button type="submit" name="create_invite" class="btn btn-sm btn-outline-secondary">Generate Invite</button>
</form>
{% endif %}
</td>
<td>
<a href="{{ path('game', {session: session.id}) }}">Enter Game</a>
<a href="{{ path('game', {session: session.id}) }}" class="btn btn-sm btn-primary">Enter Game</a>
{% if session.status.value == 'created' %}
{% if session.players|length >= session.game.numberOfPlayers %}
<form method="post" style="display:inline;">
<form method="post" class="d-inline">
<input type="hidden" name="session_id" value="{{ session.id }}">
<button type="submit" name="start_session">Start Session</button>
<button type="submit" name="start_session" class="btn btn-sm btn-success">Start Session</button>
</form>
{% endif %}
{% if session.timer == 0 %}
<form method="post" style="display:inline;">
<form method="post" class="d-inline">
<input type="hidden" name="session_id" value="{{ session.id }}">
<button type="submit" name="leave_session" onclick="return confirm('Are you sure you want to leave this session?')">Leave Session</button>
<button type="submit" name="leave_session" class="btn btn-sm btn-outline-danger" onclick="return confirm('Are you sure you want to leave this session?')">Leave Session</button>
</form>
{% endif %}
{% endif %}
@@ -92,7 +107,8 @@
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p>You are not part of any sessions.</p>
<p class="text-muted">You are not part of any sessions.</p>
{% endif %}
{% endblock %}
+5 -7
View File
@@ -1,11 +1,11 @@
{% extends 'base.html.twig' %}
{% extends 'layout/site.html.twig' %}
{% block title %}Game Lost - {{ session.game.name }}{% endblock %}
{% block stylesheets %}
{{ parent() }}
<style>
body {
.site-main {
background-color: #1a1a1a;
color: #e0e0e0;
}
@@ -46,10 +46,9 @@
{% endblock %}
{% block body %}
<div class="container mt-5 mb-5">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card shadow-lg">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card shadow-lg">
<div class="card-header bg-danger text-white">
<h3 class="card-title mb-0">Game Over - Time's Up!</h3>
</div>
@@ -123,5 +122,4 @@
</div>
</div>
</div>
</div>
{% endblock %}
+62 -64
View File
@@ -1,77 +1,75 @@
{% extends 'base.html.twig' %}
{% extends 'layout/site.html.twig' %}
{% block title %}Waiting for players - {{ session.game.name }}{% endblock %}
{% block body %}
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h3 class="card-title mb-0">Waiting for all players to be ready</h3>
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h3 class="card-title mb-0">Waiting for all players to be ready</h3>
</div>
<div class="card-body">
<h4>{{ session.game.name }}</h4>
<p>Welcome to the game! Please wait for all players to join and signal they are ready to start.</p>
<div class="game-info">
Please keep the following things in mind:
<ul>
<li>This game is best played in full screen mode. For windows, press F11. For Mac, press Cmd+Ctrl+F.</li>
<li>There is no need to reload the page. There is even a chance this could break the game.</li>
<li>If your internet connection is lost, you can get back in the game after internet has been fixed.</li>
</ul>
</div>
<div class="card-body">
<h4>{{ session.game.name }}</h4>
<p>Welcome to the game! Please wait for all players to join and signal they are ready to start.</p>
<div class="game-info">
Please keep the following things in mind:
<ul>
<li>This game is best played in full screen mode. For windows, press F11. For Mac, press Cmd+Ctrl+F.</li>
<li>There is no need to reload the page. There is even a chance this could break the game.</li>
<li>If your internet connection is lost, you can get back in the game after internet has been fixed.</li>
</ul>
</div>
<div class="alert alert-info">
<strong>Game Information:</strong>
<ul class="mb-0">
<li>Number of players: {{ session.game.numberOfPlayers }}</li>
<li>Current players: {{ session.players|length }} / {{ session.game.numberOfPlayers }}</li>
</ul>
</div>
<div class="alert alert-info">
<strong>Game Information:</strong>
<ul class="mb-0">
<li>Number of players: {{ session.game.numberOfPlayers }}</li>
<li>Current players: {{ session.players|length }} / {{ session.game.numberOfPlayers }}</li>
</ul>
</div>
<div class="mt-4">
<h5>Players status:</h5>
<ul class="list-group">
{% for player in session.players %}
<li class="list-group-item d-flex justify-content-between align-items-center">
{{ player.user.username }}
{% set playerReady = false %}
{% set settingName = 'ReadyAtForPlayer' ~ player.screen %}
{% for setting in session.settings %}
{% if setting.name.value == settingName and setting.player == player %}
{% set playerReady = true %}
{% endif %}
{% endfor %}
{% if playerReady %}
<span class="badge bg-success">Ready</span>
{% else %}
<span class="badge bg-secondary">Not ready</span>
<div class="mt-4">
<h5>Players status:</h5>
<ul class="list-group">
{% for player in session.players %}
<li class="list-group-item d-flex justify-content-between align-items-center">
{{ player.user.username }}
{% set playerReady = false %}
{% set settingName = 'ReadyAtForPlayer' ~ player.screen %}
{% for setting in session.settings %}
{% if setting.name.value == settingName and setting.player == player %}
{% set playerReady = true %}
{% endif %}
</li>
{% endfor %}
</ul>
{% endfor %}
{% if playerReady %}
<span class="badge bg-success">Ready</span>
{% else %}
<span class="badge bg-secondary">Not ready</span>
{% endif %}
</li>
{% endfor %}
</ul>
</div>
<hr>
<form method="post" class="mt-4">
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="toggle_ready" name="toggle_ready" onchange="this.form.submit()" {{ isReady ? 'checked' : '' }}>
<label class="form-check-label" for="toggle_ready">
<strong>I am ready to start!</strong>
</label>
</div>
<p class="text-muted small">
Note: If all players are not ready within 1 minute of you checking this, your status will be reset automatically.
</p>
</form>
<hr>
<form method="post" class="mt-4">
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="toggle_ready" name="toggle_ready" onchange="this.form.submit()" {{ isReady ? 'checked' : '' }}>
<label class="form-check-label" for="toggle_ready">
<strong>I am ready to start!</strong>
</label>
</div>
<p class="text-muted small">
Note: If all players are not ready within 1 minute of you checking this, your status will be reset automatically.
</p>
</form>
<div class="mt-3">
<a href="{{ path('game_dashboard') }}" class="btn btn-outline-secondary">Back to Dashboard</a>
</div>
<div class="mt-3">
<a href="{{ path('game_dashboard') }}" class="btn btn-outline-secondary">Back to Dashboard</a>
</div>
</div>
</div>
+12
View File
@@ -0,0 +1,12 @@
{% extends 'layout/site.html.twig' %}
{% block body %}
<div class="auth-card">
<div class="card shadow-sm">
<div class="card-body p-4 p-md-5">
<h1 class="h3 mb-4 text-center">{{ block('title') }}</h1>
{% block auth_body %}{% endblock %}
</div>
</div>
</div>
{% endblock %}
+64
View File
@@ -0,0 +1,64 @@
{% extends 'base.html.twig' %}
{% block header %}
<header class="site-header">
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container">
<a class="navbar-brand" href="{{ path('website_home') }}">
<img src="{{ asset('images/logo.png') }}" alt="{{ 'site.name'|trans }}">
{{ 'site.name'|trans }}
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#siteNav"
aria-controls="siteNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="siteNav">
<ul class="navbar-nav ms-auto align-items-lg-center gap-lg-2">
<li class="nav-item">
<a class="nav-link" href="{{ path('website_home') }}">{{ 'nav.home'|trans }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ path('game_dashboard') }}">{{ 'nav.game'|trans }}</a>
</li>
{% if app.user %}
<li class="nav-item">
<a class="nav-link" href="{{ path('app_logout') }}">{{ 'nav.logout'|trans }}</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="{{ path('app_register') }}">{{ 'nav.register'|trans }}</a>
</li>
<li class="nav-item">
<a class="btn btn-sm btn-outline-light ms-lg-2" href="{{ path('app_login') }}">{{ 'nav.login'|trans }}</a>
</li>
{% endif %}
</ul>
</div>
</div>
</nav>
</header>
{% endblock %}
{% block main %}
<main class="site-main">
<div class="container py-4">
{% for label, messages in app.flashes %}
{% for message in messages %}
<div class="alert alert-{{ label }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endfor %}
{% endfor %}
{% block body %}{% endblock %}
</div>
</main>
{% endblock %}
{% block footer %}
<footer class="site-footer py-4">
<div class="container text-center small">
&copy; {{ "now"|date("Y") }} {{ 'site.name'|trans }}
</div>
</footer>
{% endblock %}
@@ -1,10 +1,8 @@
{% extends 'base.html.twig' %}
{% extends 'layout/auth.html.twig' %}
{% block title %}Register{% endblock %}
{% block body %}
<h1>Register</h1>
{% block auth_body %}
{{ form_errors(registrationForm) }}
{{ form_start(registrationForm) }}
@@ -13,6 +11,12 @@
{{ form_row(registrationForm.plainPassword) }}
{{ form_row(registrationForm.captcha) }}
<button type="submit" class="btn">Register</button>
<div class="d-grid mt-3">
<button type="submit" class="btn btn-primary">Register</button>
</div>
{{ form_end(registrationForm) }}
<div class="mt-3 text-center">
<a href="{{ path('app_login') }}">Already have an account? Log in</a>
</div>
{% endblock %}
@@ -1,17 +1,17 @@
{% extends 'base.html.twig' %}
{% extends 'layout/auth.html.twig' %}
{% block title %}Resend verification email{% endblock %}
{% block body %}
<h1>Resend verification email</h1>
<p>Enter your email address and we will send you a new link to verify your account.</p>
{% block auth_body %}
<p class="text-muted">Enter your email address and we will send you a new link to verify your account.</p>
{{ form_errors(resendForm) }}
{{ form_start(resendForm) }}
{{ form_row(resendForm.email) }}
<button type="submit" class="btn">Resend email</button>
<div class="d-grid mt-3">
<button type="submit" class="btn btn-primary">Resend email</button>
</div>
{{ form_end(resendForm) }}
{% endblock %}
@@ -1,11 +1,11 @@
{% extends 'base.html.twig' %}
{% extends 'layout/auth.html.twig' %}
{% block title %}Password Reset Email Sent{% endblock %}
{% block body %}
{% block auth_body %}
<p>
If an account matching your email exists, then an email was just sent that contains a link that you can use to reset your password.
This link will expire in {{ resetToken.expirationMessageKey|trans(resetToken.expirationMessageData, 'ResetPasswordBundle') }}.
</p>
<p>If you don't receive an email please check your spam folder or <a href="{{ path('app_forgot_password_request') }}">try again</a>.</p>
<p class="mb-0">If you don't receive an email please check your spam folder or <a href="{{ path('app_forgot_password_request') }}">try again</a>.</p>
{% endblock %}
@@ -1,22 +1,20 @@
{% extends 'base.html.twig' %}
{% extends 'layout/auth.html.twig' %}
{% block title %}Reset your password{% endblock %}
{% block body %}
{% block auth_body %}
{% for flash_error in app.flashes('reset_password_error') %}
<div class="alert alert-danger" role="alert">{{ flash_error }}</div>
{% endfor %}
<h1>Reset your password</h1>
{{ form_start(requestForm) }}
{{ form_row(requestForm.email) }}
<div>
<small>
Enter your email address, and we will send you a
link to reset your password.
</small>
</div>
<p class="text-muted small">
Enter your email address, and we will send you a link to reset your password.
</p>
<button class="btn btn-primary">Send password reset email</button>
<div class="d-grid">
<button class="btn btn-primary">Send password reset email</button>
</div>
{{ form_end(requestForm) }}
{% endblock %}
@@ -1,12 +1,12 @@
{% extends 'base.html.twig' %}
{% extends 'layout/auth.html.twig' %}
{% block title %}Reset your password{% endblock %}
{% block body %}
<h1>Reset your password</h1>
{% block auth_body %}
{{ form_start(resetForm) }}
{{ form_row(resetForm.plainPassword) }}
<button class="btn btn-primary">Reset password</button>
<div class="d-grid mt-3">
<button class="btn btn-primary">Reset password</button>
</div>
{{ form_end(resetForm) }}
{% endblock %}
+21 -21
View File
@@ -1,8 +1,8 @@
{% extends 'base.html.twig' %}
{% extends 'layout/auth.html.twig' %}
{% block title %}Log in!{% endblock %}
{% block title %}Log in{% endblock %}
{% block body %}
{% block auth_body %}
<form method="post">
{% if error %}
<div class="alert alert-danger">
@@ -14,39 +14,39 @@
{% endif %}
{% if app.user %}
<div class="mb-3">
<div class="alert alert-info">
You are logged in as {{ app.user.userIdentifier }}, <a href="{{ path('app_logout') }}">Logout</a>
</div>
{% endif %}
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<label for="inputUsername">Username</label>
<input type="text" value="{{ last_username }}" name="username" id="inputUsername" class="form-control" autocomplete="username" required autofocus>
<label for="inputPassword">Password</label>
<input type="password" name="password" id="inputPassword" class="form-control" autocomplete="current-password" required>
<div class="mb-3">
<label for="inputUsername" class="form-label">Username</label>
<input type="text" value="{{ last_username }}" name="username" id="inputUsername" class="form-control" autocomplete="username" required autofocus>
</div>
<div class="mb-3">
<label for="inputPassword" class="form-label">Password</label>
<input type="password" name="password" id="inputPassword" class="form-control" autocomplete="current-password" required>
</div>
<input type="hidden" name="_csrf_token"
value="{{ csrf_token('authenticate') }}"
>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
{#
Uncomment this section and add a remember_me option below your firewall to activate remember me functionality.
See https://symfony.com/doc/current/security/remember_me.html
<div class="checkbox mb-3">
<label>
<input type="checkbox" name="_remember_me"> Remember me
</label>
<div class="form-check mb-3">
<input type="checkbox" class="form-check-input" id="rememberMe" name="_remember_me">
<label class="form-check-label" for="rememberMe">Remember me</label>
</div>
#}
<button class="btn btn-lg btn-primary" type="submit">
Sign in
</button>
<div class="mt-3">
<div class="d-grid">
<button class="btn btn-primary" type="submit">Sign in</button>
</div>
<div class="mt-3 text-center">
<a href="{{ path('app_forgot_password_request') }}">Forgot your password?</a>
</div>
<div class="mt-1">
<div class="mt-1 text-center">
<a href="{{ path('app_verify_resend_email') }}">Didn't receive activation email?</a>
</div>
</form>
+7 -4
View File
@@ -1,9 +1,12 @@
{% extends 'base.html.twig' %}
{% extends 'layout/site.html.twig' %}
{% block title %}{{ 'home.title'|trans({'%site%': ('site.name'|trans)}) }}{% endblock %}
{% block body %}
<h1>{{ 'home.h1'|trans({'%site%': ('site.name'|trans)}) }}</h1>
<p>{{ 'home.description'|trans }}</p>
<p><a href="{{ path('game_dashboard') }}">{{ 'link.enter_game'|trans }}</a></p>
<div class="text-center py-5">
<img src="{{ asset('images/logo.png') }}" alt="{{ 'site.name'|trans }}" height="140" class="mb-4">
<h1 class="display-5 fw-bold">{{ 'home.h1'|trans({'%site%': ('site.name'|trans)}) }}</h1>
<p class="lead col-lg-8 mx-auto text-secondary">{{ 'home.description'|trans }}</p>
<a href="{{ path('game_dashboard') }}" class="btn btn-primary btn-lg mt-3">{{ 'link.enter_game'|trans }}</a>
</div>
{% endblock %}