diff options
Diffstat (limited to 'resources')
| -rw-r--r-- | resources/sass/_navbar.scss | 5 | ||||
| -rw-r--r-- | resources/views/cinema.blade.php | 194 | ||||
| -rw-r--r-- | resources/views/cinema_show.blade.php | 206 | ||||
| -rw-r--r-- | resources/views/genre_movies.blade.php | 156 | ||||
| -rw-r--r-- | resources/views/genres.blade.php | 42 | ||||
| -rw-r--r-- | resources/views/layouts/app.blade.php | 29 |
6 files changed, 631 insertions, 1 deletions
diff --git a/resources/sass/_navbar.scss b/resources/sass/_navbar.scss index 4645fa5..7e3daa8 100644 --- a/resources/sass/_navbar.scss +++ b/resources/sass/_navbar.scss @@ -18,3 +18,8 @@ .nav-link:hover { text-decoration: underline !important; } +.nav-bar-divider { + display: inline; + padding: 0 8px; + font-size: 0.9rem; +} diff --git a/resources/views/cinema.blade.php b/resources/views/cinema.blade.php new file mode 100644 index 0000000..bc08fc8 --- /dev/null +++ b/resources/views/cinema.blade.php @@ -0,0 +1,194 @@ +@extends('layouts.app') + +@section('styles') +@include ('layouts.footer-style') + +html { + height: inherit; +} + +.movie-grid { + display: flex; + flex-wrap: wrap; + gap: 20px; + margin-top: 20px; +} + +.movie-card { + flex: 1 1 280px; + min-width: 250px; + max-width: 320px; +} + +.movie-card .poster { + width: 100%; + aspect-ratio: 2 / 3; + object-fit: cover; + background-color: #333; + border-radius: 4px 4px 0 0; +} + +.movie-card .year { + color: #868e96; + font-size: 0.85rem; +} + +.movie-card .rating { + font-size: 0.9rem; + color: #868e96; +} + +.movie-card .synopsis { + font-size: 0.875rem; + color: #6c757d; + display: -webkit-box; + -webkit-line-clamp: 4; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.movie-card h1 { + font-size: 1rem; + padding: 10px 12px 4px; + margin: 0; +} + +.movie-card h1 a { + color: inherit; + text-decoration: none; +} + +.movie-card h1 a:hover { + text-decoration: underline; +} + +.movie-card .card-body { + padding: 0 12px 12px; +} + +.no-poster { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + aspect-ratio: 2 / 3; + background-color: #495057; + color: #adb5bd; + font-size: 3rem; + border-radius: 4px 4px 0 0; +} + +.permalink:hover { + text-decoration: none; +} + +@endsection + +@section('content') +<div class="container"> + <div style="margin-top: 20px"></div> + + <div class="card"> + <h1 class="card-header"> + @if ( isset($search_query) && $search_query != '' ) + Movies matching <strong>"{{ $search_query }}"</strong> + @if ( "1" != $movies->currentPage() ) + (Page {{ $movies->currentPage() }}) + @endif + @else + Movies + @if ( "1" != $movies->currentPage() ) + (Page {{ $movies->currentPage() }}) + @endif + @endif + </h1> + <div class="card-body"> + <p class="card-text"> + @if ( isset($search_query) && $search_query != '' ) + Found {{ $count }} movies matching <strong>"{{ $search_query }}"</strong>. + @else + Browse {{ number_format($count) }} movies from the database, mentioned on Hacker News, ranked by rating or popularity. + @endif + </p> + <form class="form-inline" action="{{ route('cinema.search') }}" method="GET"> + <input name="q" class="form-control mr-sm-2" type="text" placeholder="Search movies..." aria-label="Search" value="{{ isset($search_query) ? $search_query : '' }}"> + <button class="btn btn-outline-primary my-2 my-sm-0" type="submit">Search</button> + </form> + <div class="mt-2"> + <span class="text-muted">Sort by:</span> + @foreach ([ + ['ref_count', 'Hacker News Mentions'], + ['score', 'Rating'], + ['num_votes', 'Number of Votes'], + ['num_accolades', 'Accolades'], + ['start_year', 'Release Date'], + ] as [$key, $label]) + @if ( (isset($order) ? $order : 'ref_count') == $key ) + @if ( (isset($direction) ? $direction : 'desc') == 'desc' ) + <a class="btn btn-sm btn-primary my-1" href="{{ url()->current() }}?order={{ $key }}&direction=asc">{{ $label }} ▲</a> + @else + <a class="btn btn-sm btn-primary my-1" href="{{ url()->current() }}?order={{ $key }}&direction=desc">{{ $label }} ▼</a> + @endif + @else + <a class="btn btn-sm btn-outline-secondary my-1" href="{{ url()->current() }}?order={{ $key }}&direction=desc">{{ $label }}</a> + @endif + @endforeach + </div> + </div> + </div> + + @if ( 0 != $movies->count() ) + <div class="movie-grid"> + @foreach( $movies as $movie) + <div class="card movie-card"> + <a href="{{ route('cinema.show', $movie->imdb_id) }}"> + @if ( ! empty($movie->poster_url) ) + <img class="poster" src="{{ $movie->poster_url }}" alt="{{ $movie->primary_title }} poster" loading="lazy"> + @else + <div class="no-poster">🎬</div> + @endif + </a> + <h1> + <a href="{{ route('cinema.show', $movie->imdb_id) }}"> + {{ $movie->primary_title }} + </a> + </h1> + <div class="card-body"> + <div> + @if ( ! is_null($movie->start_year) ) + <span class="year">{{ $movie->start_year }}</span> + @endif + @if ( ! is_null($movie->runtime_minutes) ) + @if ( ! is_null($movie->start_year) ) + <span class="year"> · </span> + @endif + <span class="year">{{ $movie->runtime_minutes }} min</span> + @endif + </div> + <div class="mt-1"> + @if ( ! is_null($movie->average_rating) ) + <span class="rating">⭐ {{ number_format($movie->average_rating, 1) }}</span> + @if ( ! is_null($movie->num_votes) ) + <span class="year"> ({{ number_format($movie->num_votes) }} votes)</span> + @endif + @endif + </div> + @if ( ! empty($movie->synopsis) ) + <p class="card-text synopsis mt-2"> + {{ strip_tags($movie->synopsis) }} + </p> + @endif + </div> + </div> + @endforeach + </div> + + <div style="margin-bottom: 20px"></div> + {{ $movies->appends(Request::input())->links() }} + @endif +</div> +@endsection + +@section('footer') + @include ('layouts.footer') +@endsection diff --git a/resources/views/cinema_show.blade.php b/resources/views/cinema_show.blade.php new file mode 100644 index 0000000..49c5977 --- /dev/null +++ b/resources/views/cinema_show.blade.php @@ -0,0 +1,206 @@ +@extends('layouts.app') + +@section('styles') +@include ('layouts.footer-style') + +.poster-detail { + width: 100%; + max-width: 350px; + border-radius: 4px; +} + +.year { + color: #868e96; +} + +.rating { + color: #868e96; + font-size: 0.9rem; +} + +.movie-credits { + columns: 2; + column-gap: 20px; +} + +.hn-comment { + font-size: 0.875rem; + color: #868e96; + display: -webkit-box; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; +} + +@media (max-width: 768px) { + .movie-credits { + columns: 1; + } + .poster-detail { + max-width: 200px; + margin: 0 auto; + } +} + +@endsection + +@section('content') +<div class="container"> + <div style="margin-top: 20px"></div> + + @if ( ! is_null($movie) ) + <div class="card"> + <h1 class="card-header"> + <a href="{{ route('cinema.index') }}" style="color:inherit;">← All Movies</a> + </h1> + <div class="card-body"> + <div class="row"> + <div class="col-md-3"> + @if ( ! empty($movie->poster_url) ) + <img class="poster-detail" src="{{ $movie->poster_url }}" alt="{{ $movie->primary_title }} poster"> + @else + <div class="no-poster">🎬</div> + @endif + </div> + <div class="col-md-9"> + <h3> + @if ( ! is_null($movie->wiki_article) ) + <a href="https://en.wikipedia.org/wiki/{{ $movie->wiki_article }}" target="_blank"> + {{ $movie->primary_title }} + </a> + @else + {{ $movie->primary_title }} + @endif + @if ( ! is_null($movie->original_title) && $movie->original_title != $movie->primary_title ) + <small class="text-muted">({{ $movie->original_title }})</small> + @endif + </h3> + <div class="mt-2"> + @if ( ! is_null($movie->start_year) ) + <span class="year">{{ $movie->start_year }}</span> + @endif + @if ( ! is_null($movie->runtime_minutes) ) + @if ( ! is_null($movie->start_year) ) + <span class="year"> · </span> + @endif + <span class="year">{{ $movie->runtime_minutes }} min</span> + @endif + @if ( ! is_null($movie->title_type) ) + @if ( ! is_null($movie->start_year) || ! is_null($movie->runtime_minutes) ) + <span class="year"> · </span> + @endif + <span class="badge badge-secondary">{{ $movie->title_type }}</span> + @endif + </div> + <div class="mt-1"> + @if ( ! is_null($movie->average_rating) ) + <span class="rating">⭐ {{ number_format($movie->average_rating, 1) }}</span> + @if ( ! is_null($movie->num_votes) ) + <span class="year"> ({{ number_format($movie->num_votes) }} votes)</span> + @endif + @endif + </div> + + @if ( ! empty($genres) ) + <div class="mt-2"> + @foreach( $genres as $genre ) + <a href="{{ route('cinema.genre', $genre) }}" class="badge badge-pill badge-primary" style="color: #fff;">{{ $genre }}</a> + @endforeach + </div> + @endif + + @if ( ! empty($movie->synopsis) ) + @php + $paragraphs = preg_split('/\\n\\s*\\n/', strip_tags($movie->synopsis)); + @endphp + @foreach($paragraphs as $i => $para) + @if ( trim($para) !== '' ) + <p class="card-text{{ $i === 0 ? ' mt-3' : '' }}"> + {{ trim($para) }} + </p> + @endif + @endforeach + @endif + + @if ( ! empty($directors) ) + <div class="mt-3"> + <h4>Directed by</h4> + <div class="movie-credits"> + @foreach( $directors as $person ) + <div>{{ $person->name }}</div> + @endforeach + </div> + </div> + @endif + + @if ( ! empty($actors) ) + <div class="mt-3"> + <h4>Starring</h4> + <div class="movie-credits"> + @foreach( $actors as $person ) + <div>{{ $person->name }}</div> + @endforeach + </div> + </div> + @endif + + @if ( ! is_null($movie->imdb_id) || ! is_null($movie->wiki_article) ) + <div class="mt-3"> + @if ( ! is_null($movie->wiki_article) ) + <a class="btn btn-outline-primary btn-sm mr-2" href="https://en.wikipedia.org/wiki/{{ $movie->wiki_article }}" target="_blank">View on Wikipedia</a> + @endif + @if ( ! is_null($movie->imdb_id) ) + <a class="btn btn-outline-primary btn-sm" href="https://www.imdb.com/title/{{ $movie->imdb_id }}" target="_blank">View on IMDb</a> + @endif + </div> + @endif + + @if ( ! empty($hnStories) ) + <div class="mt-3"> + <h4>Mentions on Hacker News</h4> + <ul class="list-unstyled"> + @foreach($hnStories as $story) + <li> + <a class="card-links" href="https://news.ycombinator.com/item?id={{ $story->story_id }}" target="_blank"> + @if ($story->type === 'comment' && ! empty($story->text)) + <span class="hn-comment">{{ Str::limit(strip_tags($story->text), 80) }}</span> + @else + {{ $story->title ?: 'HN Story' }} + @endif + </a> + <small class="text-muted"> + | {{ \Carbon\Carbon::createFromTimestamp($story->time)->format('Y-m-d') }} + @if ($story->score > 0) + · <span class="badge badge-pill badge-secondary">{{ $story->score }} Upvotes</span> + @endif + @if ($story->descendants > 0) + · <span class="badge badge-pill badge-secondary">{{ $story->descendants }} Comments</span> + @endif + </small> + </li> + @endforeach + </ul> + </div> + @endif + </div> + </div> + </div> + </div> + @else + <div class="card"> + <h1 class="card-header">Movie Not Found</h1> + <div class="card-body"> + <p class="card-text">The requested movie could not be found.</p> + <a href="{{ route('cinema.index') }}" class="btn btn-outline-primary">Back to Movies</a> + </div> + </div> + @endif + + <div style="margin-bottom: 20px"></div> +</div> +@endsection + +@section('footer') + @include ('layouts.footer') +@endsection diff --git a/resources/views/genre_movies.blade.php b/resources/views/genre_movies.blade.php new file mode 100644 index 0000000..a8a4585 --- /dev/null +++ b/resources/views/genre_movies.blade.php @@ -0,0 +1,156 @@ +@extends('layouts.app') + +@section('styles') +@include ('layouts.footer-style') + +html { + height: inherit; +} + +.movie-grid { + display: flex; + flex-wrap: wrap; + gap: 20px; + margin-top: 20px; +} + +.movie-card { + flex: 1 1 280px; + min-width: 250px; + max-width: 320px; +} + +.movie-card .poster { + width: 100%; + aspect-ratio: 2 / 3; + object-fit: cover; + background-color: #333; + border-radius: 4px 4px 0 0; +} + +.movie-card .year { + color: #868e96; + font-size: 0.85rem; +} + +.movie-card .rating { + font-size: 0.9rem; + color: #868e96; +} + +.movie-card .synopsis { + font-size: 0.875rem; + color: #6c757d; + display: -webkit-box; + -webkit-line-clamp: 4; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.movie-card h1 { + font-size: 1rem; + padding: 10px 12px 4px; + margin: 0; +} + +.movie-card h1 a { + color: inherit; + text-decoration: none; +} + +.movie-card h1 a:hover { + text-decoration: underline; +} + +.movie-card .card-body { + padding: 0 12px 12px; +} + +.no-poster { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + aspect-ratio: 2 / 3; + background-color: #495057; + color: #adb5bd; + font-size: 3rem; + border-radius: 4px 4px 0 0; +} + +@endsection + +@section('content') +<div class="container"> + <div style="margin-top: 20px"></div> + + <div class="card"> + <h1 class="card-header"> + Genre: <strong>{{ $genre_name }}</strong> + @if ( "1" != $movies->currentPage() ) + (Page {{ $movies->currentPage() }}) + @endif + </h1> + <div class="card-body"> + <p class="card-text"> + Browse {{ number_format($count) }} movies in the <strong>{{ $genre_name }}</strong> genre. + </p> + <a href="{{ route('cinema.genres') }}" class="btn btn-sm btn-outline-primary">All Genres</a> + </div> + </div> + + @if ( 0 != $movies->count() ) + <div class="movie-grid"> + @foreach( $movies as $movie) + <div class="card movie-card"> + <a href="{{ route('cinema.show', $movie->imdb_id) }}"> + @if ( ! empty($movie->poster_url) ) + <img class="poster" src="{{ $movie->poster_url }}" alt="{{ $movie->primary_title }} poster" loading="lazy"> + @else + <div class="no-poster">🎬</div> + @endif + </a> + <h1> + <a href="{{ route('cinema.show', $movie->imdb_id) }}"> + {{ $movie->primary_title }} + </a> + </h1> + <div class="card-body"> + <div> + @if ( ! is_null($movie->start_year) ) + <span class="year">{{ $movie->start_year }}</span> + @endif + @if ( ! is_null($movie->runtime_minutes) ) + @if ( ! is_null($movie->start_year) ) + <span class="year"> · </span> + @endif + <span class="year">{{ $movie->runtime_minutes }} min</span> + @endif + </div> + <div class="mt-1"> + @if ( ! is_null($movie->average_rating) ) + <span class="rating">⭐ {{ number_format($movie->average_rating, 1) }}</span> + @if ( ! is_null($movie->num_votes) ) + <span class="year"> ({{ number_format($movie->num_votes) }} votes)</span> + @endif + @endif + </div> + @if ( ! empty($movie->synopsis) ) + <p class="card-text synopsis mt-2"> + {{ strip_tags($movie->synopsis) }} + </p> + @endif + </div> + </div> + @endforeach + </div> + + <div style="margin-bottom: 20px"></div> + {{ $movies->appends(Request::input())->links() }} + @endif +</div> +@endsection + +@section('footer') + @include ('layouts.footer') +@endsection diff --git a/resources/views/genres.blade.php b/resources/views/genres.blade.php new file mode 100644 index 0000000..1fff8d2 --- /dev/null +++ b/resources/views/genres.blade.php @@ -0,0 +1,42 @@ +@extends('layouts.app') + +@section('styles') +@include ('layouts.footer-style') +html { + height: inherit; +} +@endsection + +@section('content') + +<div class="container"> + + <div style="margin-top: 20px"></div> + <div class="card"> + <h1 class="card-header"> + Genres + </h1> + <div class="card-body"> + <p class="card-text"> + Browse movies by genre. Each genre shows all movies that have been categorized. + </p> + </div> + </div> + <div style="margin-bottom: 20px"></div> + + <div class="text-center card"> + <div class="card-body"> + @foreach ($genres as $genre) + @if ( "" != $genre->name ) + <a href="{{ route('cinema.genre', $genre->name) }}" class="btn btn-lg btn-primary mx-1 my-1">{{ $genre->name }} ({{ $genre->count }} Movies)</a> + @endif + @endforeach + </div> + </div> + +</div> +@endsection + +@section('footer') + @include ('layouts.footer') +@endsection diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 5179be1..e3fe561 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -11,7 +11,9 @@ <link rel="me" href="https://mastodon.social/@MostDiscussed"> <title>{{ config('app.name', 'Laravel') }} - @if( ("index" != Request::route()->getName()) && ("show" != Request::route()->getName()) ) + @if( str_starts_with(Request::route()->getName(), 'cinema') ) + - Movies + @elseif( ("index" != Request::route()->getName()) && ("show" != Request::route()->getName()) ) - {{ ucwords(Request::route()->getName()) }} Articles @elseif ( "show" == Request::route()->getName() ) - {{ ucwords( $page_title) }} @@ -70,6 +72,22 @@ <style> @yield('styles') + .nav-bar-divider { + display: inline; + padding: 0 8px; + color: #fff; + opacity: 0.5; + user-select: none; + } + .btn-outline-secondary { + color: #868e96; + border-color: #868e96; + } + .btn-outline-secondary:hover { + color: #fff; + background-color: #868e96; + border-color: #868e96; + } </style> @if ( "new" == Request::route()->getName() || "popular" == Request::route()->getName() ) {!! Rumenx\Feed\Feed::link( url('feed/' . Request::route()->getName()), 'atom', 'RSS-Feed for ' . Request::route()->getName() . ' Articles'); !!} @@ -136,6 +154,15 @@ <li class="nav-item"> <a class="nav-link" href="{{ route('random') }}">{{ __('Random') }}</a> </li> + <li class="nav-item nav-bar-divider"> + <span class="nav-link" style="pointer-events: none;">|</span> + </li> + <li class="nav-item"> + <a class="nav-link" href="{{ route('cinema.index') }}">{{ __('Movies') }}</a> + </li> + <li class="nav-item"> + <a class="nav-link" href="{{ route('cinema.genres') }}">{{ __('Genres') }}</a> + </li> @else <li class="nav-item dropdown"> <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre> |
