-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #108 from leepeuker/movies-page
Movies page
- Loading branch information
Showing
8 changed files
with
264 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
function toggleSearchOptions () { | ||
let searchOptions = document.getElementById('searchOptions') | ||
|
||
if (searchOptions.style.display === 'none') { | ||
searchOptions.style.display = 'block' | ||
|
||
return | ||
} | ||
|
||
searchOptions.style.display = 'none' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Movary\HttpController; | ||
|
||
use Movary\Application\Movie; | ||
use Movary\Application\User\Service\UserPageAuthorizationChecker; | ||
use Movary\ValueObject\Http\Request; | ||
use Movary\ValueObject\Http\Response; | ||
use Movary\ValueObject\Http\StatusCode; | ||
use Twig\Environment; | ||
|
||
class MoviesController | ||
{ | ||
private const DEFAULT_LIMIT = 24; | ||
|
||
private const DEFAULT_SORT_BY = 'title'; | ||
|
||
private const DEFAULT_SORT_ORDER = 'DESC'; | ||
|
||
public function __construct( | ||
private readonly Environment $twig, | ||
private readonly Movie\Api $movieApi, | ||
private readonly UserPageAuthorizationChecker $userPageAuthorizationChecker, | ||
) { | ||
} | ||
|
||
public function renderPage(Request $request) : Response | ||
{ | ||
$userId = $this->userPageAuthorizationChecker->findUserIdIfCurrentVisitorIsAllowedToSeeUser((string)$request->getRouteParameters()['username']); | ||
if ($userId === null) { | ||
return Response::createNotFound(); | ||
} | ||
|
||
$searchTerm = $request->getGetParameters()['s'] ?? null; | ||
$page = $request->getGetParameters()['p'] ?? 1; | ||
$limit = $request->getGetParameters()['pp'] ?? self::DEFAULT_LIMIT; | ||
$sortBy = $request->getGetParameters()['sb'] ?? self::DEFAULT_SORT_BY; | ||
$sortOrder = $request->getGetParameters()['so'] ?? self::DEFAULT_SORT_ORDER; | ||
|
||
$uniqueMovies = $this->movieApi->fetchUniqueMoviesPaginated($userId, (int)$limit, (int)$page, $searchTerm, $sortBy, $sortOrder); | ||
$historyCount = $this->movieApi->fetchUniqueMoviesCount($userId, $searchTerm); | ||
|
||
$maxPage = (int)ceil($historyCount / $limit); | ||
|
||
$paginationElements = [ | ||
'previous' => $page > 1 ? $page - 1 : null, | ||
'next' => $page < $maxPage ? $page + 1 : null, | ||
'currentPage' => $page, | ||
'maxPage' => $maxPage, | ||
]; | ||
|
||
return Response::create( | ||
StatusCode::createOk(), | ||
$this->twig->render('page/movies.html.twig', [ | ||
'users' => $this->userPageAuthorizationChecker->fetchAllVisibleUsernamesForCurrentVisitor(), | ||
'movies' => $uniqueMovies, | ||
'paginationElements' => $paginationElements, | ||
'searchTerm' => $searchTerm, | ||
'perPage' => $limit, | ||
'sortBy' => $sortBy, | ||
'sortOrder' => $sortOrder, | ||
]), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
{% extends 'base.html.twig' %} | ||
{% import 'makro/tmdb.html.twig' as tmdb %} | ||
|
||
{% block title %} | ||
History | ||
{% endblock %} | ||
|
||
{% block stylesheets %} | ||
<link href="/css/app.css" rel="stylesheet"> | ||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css"> | ||
{% endblock %} | ||
|
||
{% block scripts %} | ||
<script src="/js/userSelect.js"></script> | ||
<script src="/js/movies.js"></script> | ||
{% endblock %} | ||
|
||
{% block body %} | ||
<main role="main" class="container"> | ||
{{ include('component/navbar.html.twig') }} | ||
|
||
<div style="text-align: center"> | ||
{{ include('component/user-select.html.twig') }} | ||
|
||
<form action="/{{ routeUsername }}/movies" method="GET"> | ||
<div class="input-group mb-3"> | ||
<input type="text" class="form-control" name="s" placeholder="Search" value="{{ (searchTerm is null) ? '' : searchTerm }}"> | ||
<button class="btn btn-primary" type="button" onclick="toggleSearchOptions()" style="background-color: #aab0b3;border-color: #aab0b3"><i | ||
class="bi bi-chevron-down"></i></button> | ||
<button class="btn btn-primary" type="submit"><i class="bi bi-search"></i></button> | ||
</div> | ||
<div style="display: none;border: #aab0b3 1px;margin-top:1em;margin-bottom:1em" id="searchOptions"> | ||
<div class="input-group mb-3"> | ||
<span class="input-group-text">Per page</span> | ||
<select class="form-control" name="pp" id="per-page"> | ||
<option value="24" {{ perPage == 24 ? 'selected' }}>24</option> | ||
<option value="48" {{ perPage == 48 ? 'selected' }}>48</option> | ||
<option value="72" {{ perPage == 72 ? 'selected' }}>72</option> | ||
<option value="96" {{ perPage == 96 ? 'selected' }}>96</option> | ||
</select> | ||
</div> | ||
<div class="input-group mb-3"> | ||
<span class="input-group-text">Sort by</span> | ||
<select class="form-control" name="sb" id="sort-by"> | ||
<option value="title" {{ sortBy == 'title' ? 'selected' }}>Title</option> | ||
<option value="releaseDate" {{ sortBy == 'releaseDate' ? 'selected' }}>Release date</option> | ||
<option value="rating" {{ sortBy == 'rating' ? 'selected' }}>Rating</option> | ||
<option value="runtime" {{ sortBy == 'runtime' ? 'selected' }}>Runtime</option> | ||
</select> | ||
</div> | ||
<div class="input-group mb-3"> | ||
<span class="input-group-text">Sort order</span> | ||
<select class="form-control" name="so" id="sort-order"> | ||
<option value="desc" {{ sortOrder == 'desc' ? 'selected' }}>Desc</option> | ||
<option value="asc" {{ sortOrder == 'asc' ? 'selected' }}>Asc</option> | ||
</select> | ||
</div> | ||
</div> | ||
</form> | ||
|
||
<div class="row row-cols-3 row-cols-md-3 row-cols-lg-6"> | ||
{% for movie in movies %} | ||
<div class="col" style="padding-bottom: 1rem;cursor: pointer" onclick="window.location='/{{ routeUsername }}/movie/{{ movie.id }}'"> | ||
<div class="card h-100 position-relative"> | ||
<img src="{{ tmdb.generatePosterImageUrl(movie.tmdb_poster_path) }}" class="card-img-top" alt="..."> | ||
|
||
{% if movie.userRating is not null %} | ||
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-warning text-dark" style="font-size: 0.8rem"> | ||
{{ movie.userRating }} | ||
</span> | ||
{% endif %} | ||
</div> | ||
</div> | ||
{% endfor %} | ||
</div> | ||
|
||
<ul class="pagination justify-content-center"> | ||
{% if paginationElements.previous is null %} | ||
<li class="page-item disabled"><p class="page-link"><span aria-hidden="true">«</span></p></li> | ||
<li class="page-item disabled"><p class="page-link"><span aria-hidden="true">‹</span></p></li> | ||
{% else %} | ||
<li class="page-item"> | ||
<a class="page-link" href="/{{ routeUsername }}/history?{{ (searchTerm is null) ? '' : "s=#{searchTerm}&" }}p=1"> | ||
<span aria-hidden="true">«</span> | ||
</a> | ||
</li> | ||
<li class="page-item"> | ||
<a class="page-link" href="/{{ routeUsername }}/history?{{ (searchTerm is null) ? '' : "s=#{searchTerm}&" }}p={{ paginationElements.previous }}"> | ||
<span aria-hidden="true">‹</span> | ||
</a> | ||
</li> | ||
{% endif %} | ||
<li class="page-item active"> | ||
<p class="page-link">{{ paginationElements.currentPage }} of {{ paginationElements.maxPage }}</p> | ||
</li> | ||
{% if paginationElements.next is null %} | ||
<li class="page-item disabled"><p class="page-link"><span aria-hidden="true">›</span></p></li> | ||
<li class="page-item disabled"><p class="page-link"><span aria-hidden="true">»</span></p></li> | ||
{% else %} | ||
<li class="page-item"> | ||
<a class="page-link" href="/{{ routeUsername }}/history?{{ (searchTerm is null) ? '' : "s=#{searchTerm}&" }}p={{ paginationElements.next }}"> | ||
<span aria-hidden="true">›</span> | ||
</a> | ||
</li> | ||
<li class="page-item"> | ||
<a class="page-link" href="/{{ routeUsername }}/history?{{ (searchTerm is null) ? '' : "s=#{searchTerm}&" }}p={{ paginationElements.maxPage }}"> | ||
<span aria-hidden="true">»</span> | ||
</a> | ||
</li> | ||
{% endif %} | ||
</ul> | ||
|
||
</div> | ||
</main> | ||
{% endblock %} |