some progress

This commit is contained in:
2025-08-07 23:01:58 +03:00
parent e8d7e6a1c4
commit e351803db2
14 changed files with 971 additions and 226 deletions
+12 -1
View File
@@ -3,6 +3,8 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Models\Movie;
use App\Models\Comment;
class HomeController extends Controller class HomeController extends Controller
{ {
@@ -12,6 +14,15 @@ class HomeController extends Controller
public function index() public function index()
{ {
return view('home'); $trendingMovies = Movie::orderBy('vote_average', 'desc')
->take(5)
->get();
$latestReviews = Comment::with('author')
->latest()
->take(5)
->get();
return view('home', compact('trendingMovies', 'latestReviews'));
} }
} }
+10
View File
@@ -25,4 +25,14 @@ class ShowController extends Controller
return view('show.show', compact('show', 'comments', 'seasons')); return view('show.show', compact('show', 'comments', 'seasons'));
} }
public function season(string $slug, int $seasonNumber)
{
}
public function episode(string $slug, int $seasonNumber, int $episodeNumber)
{
}
} }
+6
View File
@@ -22,6 +22,12 @@ class Comment extends Model
'tmdb_url', 'tmdb_url',
]; ];
protected $dates = [
'published_at',
'created_at',
'updated_at'
];
public function author() public function author()
{ {
return $this->hasOne(User::class, 'id', 'user_id'); return $this->hasOne(User::class, 'id', 'user_id');
+2 -1
View File
@@ -72,7 +72,8 @@ class Movie extends Model
public function director() public function director()
{ {
return $this->belongsToMany(Person::class, 'movie_cast', 'movie_id', 'person_id') return $this->belongsToMany(Person::class, 'movie_cast', 'movie_id', 'person_id')
->where('movie_cast.known_for_department', 'Directing') ->where('movie_cast.job', 'Director')
->orWhere('movie_cast.known_for_department', 'Directing')
; ;
} }
@@ -53,7 +53,7 @@ class MovieProcessingService implements ProcessingInterface
$join->on('movies.tmdb_id', '=', 'item_to_fetch_jobs.tmdb_id'); $join->on('movies.tmdb_id', '=', 'item_to_fetch_jobs.tmdb_id');
}) })
->whereRaw("FIND_IN_SET('".ItemToFetchJobs::JOB_DETAILS."', item_to_fetch_jobs.jobs)") ->whereRaw("FIND_IN_SET('".ItemToFetchJobs::JOB_DETAILS."', item_to_fetch_jobs.jobs)")
->where('item_to_fetch_jobs.type', 'movies') ->whereIn('item_to_fetch_jobs.type', ['movies', 'movie'])
->whereNull('movies.id') ->whereNull('movies.id')
->take($batch) ->take($batch)
->get(); ->get();
@@ -84,6 +84,10 @@ class MovieProcessingService implements ProcessingInterface
private function getDetails($item) private function getDetails($item)
{ {
$tmdbMovie = $this->moviesApi->getMovie($item->tmdb_id); $tmdbMovie = $this->moviesApi->getMovie($item->tmdb_id);
if (isset($tmdbMovie['status_code']) && $tmdbMovie['status_code'] == 34) {
echo "[N]";
return;
}
$tmdbMovie['tmdb_id'] = $tmdbMovie['id']; $tmdbMovie['tmdb_id'] = $tmdbMovie['id'];
Log::channel('fetch_export_items_details')->info("Processing TmdbId ".$tmdbMovie['tmdb_id']); Log::channel('fetch_export_items_details')->info("Processing TmdbId ".$tmdbMovie['tmdb_id']);
@@ -629,7 +633,8 @@ class MovieProcessingService implements ProcessingInterface
ItemToFetchJobs::create([ ItemToFetchJobs::create([
'tmdb_id' => $tmdbRecommendation['id'], 'tmdb_id' => $tmdbRecommendation['id'],
'type' => ItemToFetch::TYPE_MOVIE, 'type' => ItemToFetch::TYPE_MOVIE,
'remaining_jobs' => json_encode($jobs), 'remaining_jobs' => implode(',', $jobs),
'jobs' => implode(',', $jobs),
]); ]);
$this->getDetails($itemToFetch); $this->getDetails($itemToFetch);
@@ -694,7 +699,8 @@ class MovieProcessingService implements ProcessingInterface
ItemToFetchJobs::create([ ItemToFetchJobs::create([
'tmdb_id' => $tmdbSimilarMovie['id'], 'tmdb_id' => $tmdbSimilarMovie['id'],
'type' => ItemToFetch::TYPE_MOVIE, 'type' => ItemToFetch::TYPE_MOVIE,
'remaining_jobs' => json_encode($jobs), 'remaining_jobs' => implode(',', $jobs),
'jobs' => implode(',', $jobs),
]); ]);
$this->getDetails($itemToFetch); $this->getDetails($itemToFetch);
+38
View File
@@ -0,0 +1,38 @@
document.addEventListener('DOMContentLoaded', function() {
const themeSwitcher = document.getElementById('themeSwitcher');
const themeIcon = themeSwitcher.querySelector('.iconify');
const themeText = themeSwitcher.querySelector('.theme-text');
// Check for saved theme preference or use system preference
const savedTheme = localStorage.getItem('theme');
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (savedTheme === 'dark' || (!savedTheme && systemPrefersDark)) {
document.body.classList.add('dark-mode');
themeIcon.setAttribute('data-icon', 'mdi-weather-night');
themeText.textContent = 'Dark Mode';
} else {
document.body.classList.add('light-mode');
themeIcon.setAttribute('data-icon', 'mdi-weather-sunny');
themeText.textContent = 'Light Mode';
}
// Theme switcher click handler
themeSwitcher.addEventListener('click', function() {
if (document.body.classList.contains('dark-mode')) {
// Switch to light mode
document.body.classList.remove('dark-mode');
document.body.classList.add('light-mode');
themeIcon.setAttribute('data-icon', 'mdi-weather-sunny');
themeText.textContent = 'Light Mode';
localStorage.setItem('theme', 'light');
} else {
// Switch to dark mode
document.body.classList.remove('light-mode');
document.body.classList.add('dark-mode');
themeIcon.setAttribute('data-icon', 'mdi-weather-night');
themeText.textContent = 'Dark Mode';
localStorage.setItem('theme', 'dark');
}
});
});
+451 -7
View File
@@ -15,7 +15,290 @@ $fa-font-path: "/fonts";
@import "font-awesome/scss/font-awesome"; @import "font-awesome/scss/font-awesome";
.dark-mode{ .dark-mode{
background-color: #1a1a1a !important;
color: #e0e0e0;
.forums{
.category{
.title{
font-size: 20px;
line-height: 1;
margin-bottom: 0;
color: #e0e0e0;
small{
font-size: 14px;
font-weight: 500;
color: #a0a0a0;
}
}
}
}
.medium-info-box{
border: 1px solid #333;
border-radius: 15px;
padding: 15px;
text-align: center;
margin-top: 45px;
background: #2a2a2a;
}
.profile-page{
background: #2a2a2a;
padding: 15px 0;
margin-top: -50px;
.user-avatar{
width: 125px;
border-radius: 50%;
border: 2px solid #333;
box-shadow: 2px 2px 9px #000;
}
h1{
display: inline-block;
margin-right: 15px;
color: #e0e0e0;
}
}
.profile-page-menu{
background: rgba(42, 42, 42, 0.3);
ul{
margin: 0;
li{
padding: 5px;
a{
text-decoration: none;
color: #e0e0e0;
&:hover{
color: #fff;
}
&.active{
color: #fff;
text-decoration: underline;
}
}
}
}
}
.large-list-item{
margin: 15px 0;
border-radius: 5px;
background: #2a2a2a;
border: 1px solid #333;
box-shadow: 0px 0px 5px #000;
color: #e0e0e0;
}
header{
background: #2a2a2a;
padding-right: 1rem;
border-bottom: 1px solid #333;
}
.card{
margin-bottom: 1rem;
box-shadow: 0px 1px 2px -1px #000;
background: #2a2a2a;
border: 1px solid #333;
.card-header{
background: #2a2a2a;
border-bottom: 1px solid #333;
color: #e0e0e0;
}
.card-body{
color: #e0e0e0;
}
}
.movie-card{
border: 1px solid #333;
background: #2a2a2a;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
&:hover {
transform: translateY(-5px);
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
}
.quick-actions{
background: #333;
border-top: 1px solid #444;
li {
border-right: 1px solid #444;
a {
color: #a0a0a0;
&:hover {
background: #444;
color: #e0e0e0;
}
}
}
}
}
.user-actions{
padding: 5px;
.mark-as-seen-btn{
margin-top: 5px;
display: block;
border: 1px solid #903eb3;
padding: 7px 10px;
text-decoration: none;
color: #e0e0e0;
&:hover{
color: white;
transition: all .5s;
background: #903eb3;
}
&.seen{
color: white;
background: #903eb3;
}
}
.like-btn{
display: block;
margin-top: 5px;
padding: 7px 10px;
text-decoration: none;
border: 1px solid #16a085;
color: #e0e0e0;
&:hover{
color: white;
transition: all .5s;
background: #16a085;
}
&.liked{
color: white;
background: #16a085;
}
}
.add-to-list-btn{
display: block;
margin-top: 5px;
padding: 7px 10px;
text-decoration: none;
border: 1px solid #ff5f06;
color: #e0e0e0;
&:hover{
color: white;
transition: all .5s;
background: #ff5f06;
}
&.listed{
color: white;
background: #ff5f06;
}
}
}
.right-sidebar {
.card {
background: #2a2a2a;
border: 1px solid #333;
.card-header {
background: #333;
color: #e0e0e0;
border-bottom: 1px solid #444;
}
.card-body {
color: #e0e0e0;
}
}
.trending-movies {
.movie-item {
border-bottom: 1px solid #444;
.movie-info {
h6 {
color: #e0e0e0;
}
.rating {
color: #a0a0a0;
}
}
}
}
.quick-links {
ul {
li {
border-bottom: 1px solid #444;
a {
color: #e0e0e0;
&:hover {
color: #0d6efd;
}
}
}
}
}
}
.threads-page{
.thread-info{
background: #333;
border-radius: 15px;
padding: 15px;
color: #e0e0e0;
}
.topics-list{
.no-topics{
text-align: center;
padding: 15px;
border: 1px solid #333;
border-radius: 15px;
margin-top: 15px;
color: #e0e0e0;
}
}
}
.topic-row{
border-bottom: 1px dashed #444;
}
.navbar {
background: #2a2a2a;
border-bottom: 1px solid #333;
.navbar-brand {
color: #e0e0e0;
}
.nav-link {
color: #e0e0e0;
&:hover {
color: #fff;
}
}
}
.form-control {
background: #333;
border: 1px solid #444;
color: #e0e0e0;
&:focus {
background: #333;
border-color: #555;
color: #e0e0e0;
}
}
.btn-outline-primary {
color: #0d6efd;
border-color: #0d6efd;
&:hover {
background: #0d6efd;
color: #fff;
}
}
} }
body.light-mode{ body.light-mode{
@@ -126,16 +409,74 @@ body.light-mode{
} }
.movie-card{ .movie-card{
border: 1px solid #c3c4c5; border: 1px solid #e0e0e0;
background: #d9d9d9; background: white;
box-shadow: 0px 0px 3px 1px #ccc; box-shadow: 0 2px 4px rgba(0,0,0,0.1);
border-radius: 8px;
overflow: hidden;
transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
&:hover {
transform: translateY(-5px);
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
img {
width: 100%;
height: auto;
object-fit: cover;
border-radius: 8px 8px 0 0;
}
.quick-actions{ .quick-actions{
list-style: none; list-style: none;
padding: 2px 0px 7px 0px; padding: 0;
li{ margin: 0;
float: left; display: flex;
width: 33%; justify-content: space-between;
background: #f8f9fa;
border-top: 1px solid #e0e0e0;
li {
flex: 1;
text-align: center; text-align: center;
border-right: 1px solid #e0e0e0;
&:last-child {
border-right: none;
}
a {
color: #6c757d;
text-decoration: none;
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
padding: 8px;
transition: all 0.2s ease;
font-size: 0.85rem;
&:hover {
background: #e9ecef;
color: #495057;
}
.iconify {
font-size: 1.1rem;
}
}
// Special styling for the rating item
&:last-child a {
flex-direction: row;
justify-content: center;
gap: 4px;
.iconify {
margin-top: 0;
}
}
} }
} }
} }
@@ -305,4 +646,107 @@ body.light-mode{
.topic-row{ .topic-row{
border-bottom: 1px dashed #ccc; border-bottom: 1px dashed #ccc;
} }
.right-sidebar {
.card {
border-radius: 8px;
overflow: hidden;
margin-bottom: 1.5rem;
.card-header {
background: #f8f9fa;
padding: 1rem;
font-weight: 600;
border-bottom: 1px solid #e0e0e0;
}
.card-body {
padding: 1rem;
}
}
.trending-movies {
.movie-item {
display: flex;
align-items: center;
padding: 0.5rem 0;
border-bottom: 1px solid #e0e0e0;
&:last-child {
border-bottom: none;
}
img {
width: 50px;
height: 75px;
object-fit: cover;
border-radius: 4px;
margin-right: 1rem;
}
.movie-info {
flex: 1;
h6 {
margin: 0;
font-size: 0.9rem;
}
.rating {
font-size: 0.8rem;
color: #6c757d;
}
}
}
}
.quick-links {
ul {
list-style: none;
padding: 0;
margin: 0;
li {
padding: 0.5rem 0;
border-bottom: 1px solid #e0e0e0;
&:last-child {
border-bottom: none;
}
a {
color: #495057;
text-decoration: none;
display: flex;
align-items: center;
gap: 0.5rem;
&:hover {
color: #0d6efd;
}
.iconify {
font-size: 1.2rem;
}
}
}
}
}
}
}
.theme-switcher {
background: none;
border: none;
cursor: pointer;
padding: 0.5rem 1rem;
transition: all 0.3s ease;
&:hover {
opacity: 0.8;
}
.iconify {
font-size: 1.2rem;
}
} }
+61 -31
View File
@@ -2,42 +2,53 @@
@section('content') @section('content')
<div class="container-fluid threads-page"> <div class="container-fluid threads-page">
<div class="row">
<div class="col-md-12">
<div class="topic-name">
{{ $topic->name }}
</div>
</div>
</div>
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-md-10 forums"> <div class="col-md-10 forums">
<div class="topic-posts"> <div class="card category">
@foreach($posts as $post)
<div class="post">
<div class="card">
<div class="card-header"> <div class="card-header">
<a href="">{{ $post->author->name }}</a> | {{ $post->created_at->diffForHumans() }} <h1 class="title">
<div class="row">
<div class="col-md-12">
{{ $topic->name }} <br>
<small>Created by {{ $topic->author->name }} | {{ $topic->created_at->diffForHumans() }}</small>
</div>
</div>
</h1>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="row"> @foreach($posts as $post)
<div class="row post-row">
<div class="col-md-1"> <div class="col-md-1">
avatar <br> name <br> rank & co <div class="text-center">
<img src="{{ $post->author->avatar ?? 'https://ui-avatars.com/api/?name=' . urlencode($post->author->name) }}"
alt="{{ $post->author->name }}"
class="rounded-circle"
width="64"
height="64">
<div class="mt-2">
<small>{{ $post->author->name }}</small>
</div>
</div>
</div> </div>
<div class="col-md-11"> <div class="col-md-11">
{{ $post->content }} <div class="post-content">
{!! $post->content !!}
</div> </div>
</div> <div class="post-meta">
</div> <small>Posted {{ $post->created_at->diffForHumans() }}</small>
<div class="card-footer">
<div class="float-end"> <div class="float-end">
<a href="" class="btn btn-primary btn-sm">Reply</a> <a href="#" class="btn btn-primary btn-sm">Reply</a>
<a href="" class="btn btn-secondary btn-sm">Like</a> <a href="#" class="btn btn-secondary btn-sm">Like</a>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@if(!$loop->last)
<hr>
@endif
@endforeach @endforeach
</div> </div>
</div>
{{ $posts->links() }} {{ $posts->links() }}
<hr> <hr>
<form action="{{ route('forums.thread.topics.post.store', [$thread->category->slug, $thread->slug, $topic->slug]) }}" method="POST"> <form action="{{ route('forums.thread.topics.post.store', [$thread->category->slug, $thread->slug, $topic->slug]) }}" method="POST">
@@ -54,21 +65,40 @@
</div> </div>
<div class="col-md-2"> <div class="col-md-2">
<div class="card"> <div class="card">
<div class="user-actions"> <div class="card-header">
<ul> <h5>Forum Stats</h5>
<li> </div>
<a href=""><span class="iconify" data-icon="mdi-eye-check-outline"></span> Mark as seen</a> <div class="card-body">
<ul class="list-unstyled">
<li class="mb-2">
<span class="iconify me-1" data-icon="mdi-eye"></span>
Views: {{ $topic->views_no }}
</li> </li>
<li> <li class="mb-2">
<a href=""><span class="iconify" data-icon="mdi-thumb-up-outline"></span> Like</a> <span class="iconify me-1" data-icon="mdi-message-text"></span>
Replies: {{ $topic->replies_no }}
</li> </li>
<li> <li class="mb-2">
<a href=""><span class="iconify" data-icon="mdi-playlist-check"></span> add to list</a> <span class="iconify me-1" data-icon="mdi-clock-outline"></span>
Created: {{ $topic->created_at->diffForHumans() }}
</li> </li>
</ul> </ul>
<hr> </div>
rate </div>
<hr> <div class="card mt-3">
<div class="card-header">
<h5>Similar Topics</h5>
</div>
<div class="card-body">
<ul class="list-unstyled">
@foreach($similarTopics as $similarTopic)
<li class="mb-2">
<a href="{{ route('forums.thread.topics.show', [$thread->category->slug, $thread->slug, $similarTopic->slug]) }}">
{{ $similarTopic->name }}
</a>
</li>
@endforeach
</ul>
</div> </div>
</div> </div>
</div> </div>
+80 -21
View File
@@ -4,42 +4,101 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-md-10"> <div class="col-md-10">
<div class="card mb-4">
<div class="card"> <div class="card-body p-0">
<div class="card-body"> <img src="https://a.ltrbxd.com/sm/upload/zl/t8/nl/gy/yir-banner-1900-o.png?k=caf651e2bd" alt="" class="img-fluid w-100">
<img src="https://a.ltrbxd.com/sm/upload/zl/t8/nl/gy/yir-banner-1900-o.png?k=caf651e2bd" alt="" class="img img-fluid">
</div> </div>
</div> </div>
<div class="card"> <div class="card mb-4">
<div class="card-header"> <div class="card-header d-flex justify-content-between align-items-center">
New movies <h5 class="mb-0">New Movies</h5>
<div class="float-end"> <a href="{{ route('movie.index') }}" class="btn btn-sm btn-outline-primary">View All &rarr;</a>
<a href="">view all &rarr;</a>
</div>
</div> </div>
<div class="card-body"> <div class="card-body">
@livewire(App\Livewire\Homepage\Movies\NewMoviesComponent::class) @livewire(App\Livewire\Homepage\Movies\NewMoviesComponent::class)
</div> </div>
</div> </div>
<div class="card"> <div class="card mb-4">
<div class="card-header"> <div class="card-header d-flex justify-content-between align-items-center">
Upcoming movies <h5 class="mb-0">Upcoming Movies</h5>
<div class="float-end"> <a href="{{ route('movie.index') }}" class="btn btn-sm btn-outline-primary">View All &rarr;</a>
<a href="">view all &rarr;</a>
</div>
</div> </div>
<div class="card-body"> <div class="card-body">
@livewire(App\Livewire\Homepage\Movies\UpcomingMoviesComponent::class) @livewire(App\Livewire\Homepage\Movies\UpcomingMoviesComponent::class)
</div> </div>
</div> </div>
latest members
</div> </div>
<div class="col-md-2">
right <div class="col-md-2 right-sidebar">
<div class="card">
<div class="card-header">Trending Now</div>
<div class="card-body trending-movies">
@foreach($trendingMovies as $movie)
<div class="movie-item">
<img src="http://image.tmdb.org/t/p/w92/{{ $movie->poster_path }}" alt="{{ $movie->title }}">
<div class="movie-info">
<h6>{{ $movie->title }}</h6>
<div class="rating">
<span class="iconify" data-icon="mdi-star"></span>
{{ number_format($movie->vote_average, 1) }}
</div>
</div>
</div>
@endforeach
</div>
</div>
<div class="card">
<div class="card-header">Quick Links</div>
<div class="card-body quick-links">
<ul>
<li>
<a href="{{ route('movie.index') }}">
<span class="iconify" data-icon="mdi-movie"></span>
All Movies
</a>
</li>
<li>
<a href="{{ route('show.index') }}">
<span class="iconify" data-icon="mdi-television"></span>
TV Shows
</a>
</li>
<li>
<a href="{{ route('celebrity.index') }}">
<span class="iconify" data-icon="mdi-account-group"></span>
Celebrities
</a>
</li>
<li>
<a href="{{ route('forums.index') }}">
<span class="iconify" data-icon="mdi-forum"></span>
Forums
</a>
</li>
</ul>
</div>
</div>
<div class="card">
<div class="card-header">Latest Reviews</div>
<div class="card-body">
@foreach($latestReviews as $review)
<div class="review-item mb-3">
<div class="d-flex align-items-center mb-2">
<img src="{{ $review->author_avatar }}" alt="{{ $review->author_name }}" class="rounded-circle me-2" width="32" height="32">
<div>
<h6 class="mb-0">{{ $review->author_name }}</h6>
<small class="text-muted">{{ \Carbon\Carbon::createFromTimeString($review->published_at)->diffForHumans() }}</small>
</div>
</div>
<p class="mb-0 text-truncate">{{ $review->content }}</p>
</div>
@endforeach
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
+3
View File
@@ -37,5 +37,8 @@
</div> </div>
@livewireScripts @livewireScripts
@bukScripts @bukScripts
<script src="{{ asset('js/app.js') }}" defer></script>
<script src="{{ asset('js/theme-switcher.js') }}" defer></script>
@stack('scripts')
</body> </body>
</html> </html>
+78 -19
View File
@@ -1,43 +1,100 @@
<header class="d-flex flex-wrap justify-content-center py-3 mb-4 border-bottom"> <header class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto link-body-emphasis text-decoration-none"> <div class="container-fluid px-4">
<svg class="bi me-2" width="40" height="32"><use xlink:href="#bootstrap"></use></svg> <a href="/" class="navbar-brand d-flex align-items-center">
<span class="fs-4">Simple header</span> <span class="fs-4 fw-bold" style="font-family: 'Lobster', cursive;">MovieAddict</span>
</a> </a>
<form class="col-12 col-lg-auto mb-3 mb-lg-0 me-lg-3" role="search">
<input type="search" class="form-control form-control-dark text-bg-dark" placeholder="Search..." aria-label="Search"> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent" aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarContent">
<form class="d-flex mx-auto my-2 my-lg-0" role="search">
<div class="input-group">
<input type="search" class="form-control" placeholder="Search movies, shows, celebrities..." aria-label="Search">
<button class="btn btn-outline-primary" type="submit">
<span class="iconify" data-icon="mdi-magnify"></span>
</button>
</div>
</form> </form>
<ul class="nav nav-pills">
<li class="nav-item"><a href="/" class="nav-link">Home</a></li> <ul class="navbar-nav ms-auto">
<li class="nav-item"><a href="{{ route('movie.index') }}" class="nav-link">Movies</a></li> <li class="nav-item">
<li class="nav-item"><a href="{{ route('show.index') }}" class="nav-link">Tv Shows</a></li> <a href="/" class="nav-link d-flex align-items-center">
<li class="nav-item"><a href="{{ route('celebrity.index') }}" class="nav-link">Celebrities</a></li> <span class="iconify me-1" data-icon="mdi-home"></span>
<li class="nav-item"><a href="{{ route('forums.index') }}" class="nav-link">Forums</a></li> Home
<li class="nav-item"><a href="#" class="nav-link">Contact</a></li> </a>
</li>
<li class="nav-item">
<a href="{{ route('movie.index') }}" class="nav-link d-flex align-items-center">
<span class="iconify me-1" data-icon="mdi-movie"></span>
Movies
</a>
</li>
<li class="nav-item">
<a href="{{ route('show.index') }}" class="nav-link d-flex align-items-center">
<span class="iconify me-1" data-icon="mdi-television"></span>
TV Shows
</a>
</li>
<li class="nav-item">
<a href="{{ route('celebrity.index') }}" class="nav-link d-flex align-items-center">
<span class="iconify me-1" data-icon="mdi-account-group"></span>
Celebrities
</a>
</li>
<li class="nav-item">
<a href="{{ route('forums.index') }}" class="nav-link d-flex align-items-center">
<span class="iconify me-1" data-icon="mdi-forum"></span>
Forums
</a>
</li>
<li class="nav-item">
<button id="themeSwitcher" class="nav-link d-flex align-items-center theme-switcher">
<span class="iconify me-1" data-icon="mdi-weather-sunny"></span>
<span class="theme-text">Light Mode</span>
</button>
</li>
@guest @guest
@if (Route::has('login')) @if (Route::has('login'))
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a> <a class="nav-link d-flex align-items-center" href="{{ route('login') }}">
<span class="iconify me-1" data-icon="mdi-login"></span>
{{ __('Login') }}
</a>
</li> </li>
@endif @endif
@if (Route::has('register')) @if (Route::has('register'))
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" href="{{ route('register') }}">{{ __('Register') }}</a> <a class="btn btn-primary text-white ms-2" href="{{ route('register') }}">
<span class="iconify me-1" data-icon="mdi-account-plus"></span>
{{ __('Register') }}
</a>
</li> </li>
@endif @endif
@else @else
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre> <a id="navbarDropdown" class="nav-link dropdown-toggle d-flex align-items-center" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
<img src="{{ Auth::user()->avatar ?? 'https://ui-avatars.com/api/?name=' . urlencode(Auth::user()->name) }}" alt="{{ Auth::user()->name }}" class="rounded-circle me-2" width="32" height="32">
{{ Auth::user()->name }} {{ Auth::user()->name }}
</a> </a>
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown"> <div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<a href="{{ route('profile.list.index', Auth::user()->slug) }}" class="dropdown-item"> <a href="{{ route('profile.show', Auth::user()->slug) }}" class="dropdown-item d-flex align-items-center">
Lists <span class="iconify me-2" data-icon="mdi-account"></span>
Profile
</a> </a>
<a class="dropdown-item" href="{{ route('logout') }}" <a href="{{ route('profile.list.index', Auth::user()->slug) }}" class="dropdown-item d-flex align-items-center">
<span class="iconify me-2" data-icon="mdi-playlist-check"></span>
My Lists
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item d-flex align-items-center" href="{{ route('logout') }}"
onclick="event.preventDefault(); onclick="event.preventDefault();
document.getElementById('logout-form').submit();"> document.getElementById('logout-form').submit();">
<span class="iconify me-2" data-icon="mdi-logout"></span>
{{ __('Logout') }} {{ __('Logout') }}
</a> </a>
@@ -48,4 +105,6 @@
</li> </li>
@endguest @endguest
</ul> </ul>
</div>
</div>
</header> </header>
@@ -11,7 +11,7 @@
class="img img-fluid" class="img img-fluid"
> >
</a> </a>
<ul> <ul class="quick-actions">
<li> <li>
{{-- <span class="iconify" data-icon="mdi-check-bold"></span>--}} {{-- <span class="iconify" data-icon="mdi-check-bold"></span>--}}
<a href=""><span class="iconify" data-icon="mdi-check-outline"></span></a> <a href=""><span class="iconify" data-icon="mdi-check-outline"></span></a>
+162 -86
View File
@@ -1,175 +1,250 @@
@extends('layouts.app') @extends('layouts.app')
@section('content') @section('content')
<div class="container-fluid movie-page"> <div class="container-fluid movie-page py-4">
<div class="row justify-content-center"> <div class="row">
<div class="col-md-10"> <!-- Main Content -->
<div class="card"> <div class="col-lg-9">
<div class="card-header"> <!-- Movie Header -->
<h1 class="movie-title">{{ $movie->title }}</h1> @if($movie->release_date)(<a href="">{{ $movie->release_date->format('Y') }}</a>)@endif <div class="card mb-4">
</div>
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<div class="col-md-2"> <!-- Poster and Actions -->
<img <div class="col-md-3">
src="http://image.tmdb.org/t/p/w185/{{ $movie->poster_path }}" <div class="movie-poster mb-3">
<img src="http://image.tmdb.org/t/p/w342/{{ $movie->poster_path }}"
alt="{{ $movie->title }}" alt="{{ $movie->title }}"
title="{{ $movie->title }} @if($movie->release_date)({{ $movie->release_date->format('Y') }})@endif" class="img-fluid rounded shadow-sm"
class="img img-fluid" title="{{ $movie->title }} @if($movie->release_date)({{ $movie->release_date->format('Y') }})@endif">
> </div>
<div class="watch-provider"> <!-- Watch Providers -->
@if($movie->watchProviders->isNotEmpty())
<div class="watch-providers mb-3">
<h6 class="text-muted mb-2">Available on:</h6>
<div class="d-flex flex-wrap gap-2">
@foreach($movie->watchProviders as $watchProvider) @foreach($movie->watchProviders as $watchProvider)
<img src="http://image.tmdb.org/t/p/w45/{{ $watchProvider->logo_path }}" alt="{{ $watchProvider->provider_name }}" title="{{ $watchProvider->provider_name }}"> <img src="http://image.tmdb.org/t/p/w45/{{ $watchProvider->logo_path }}"
alt="{{ $watchProvider->provider_name }}"
title="{{ $watchProvider->provider_name }}"
class="rounded">
@endforeach @endforeach
</div> </div>
<div class="external-ids"> </div>
@endif
<!-- External Links -->
<div class="external-links mb-3">
<div class="d-flex gap-2">
@if($movie->externalIds && $movie->externalIds->tmdb_id) @if($movie->externalIds && $movie->externalIds->tmdb_id)
<a href="{{ $movie->externalIds->tmdb_id }}"><img src="{{ asset('/img/tmdb.webp') }}" alt="" width="85"></a> <a href="{{ $movie->externalIds->tmdb_id }}" class="btn btn-sm btn-outline-secondary">
<img src="{{ asset('/img/tmdb.webp') }}" alt="TMDB" height="20">
</a>
@endif @endif
@if($movie->externalIds && $movie->externalIds->imdb_id) @if($movie->externalIds && $movie->externalIds->imdb_id)
<a href="{{ $movie->externalIds->imdb_id }}"><img src="{{ asset('/img/imdb.png') }}" alt="" width="85"></a> <a href="{{ $movie->externalIds->imdb_id }}" class="btn btn-sm btn-outline-secondary">
<img src="{{ asset('/img/imdb.png') }}" alt="IMDB" height="20">
</a>
@endif @endif
</div> </div>
</div>
<!-- Trailer Button -->
@if($movie->trailer->first()) @if($movie->trailer->first())
<a href="https://www.youtube.com/watch?v={{ $movie->trailer->first()->key }}" data-toggle="lightbox" class="btn btn-sm btn-block btn-secondary">View trailer</a> <a href="https://www.youtube.com/watch?v={{ $movie->trailer->first()->key }}"
data-toggle="lightbox"
class="btn btn-primary w-100 mb-3">
<span class="iconify me-1" data-icon="mdi-play"></span>
Watch Trailer
</a>
@endif @endif
</div> </div>
<div class="col-md-10">
<span> <!-- Movie Info -->
Directed by <div class="col-md-9">
<h1 class="movie-title mb-2">
{{ $movie->title }}
@if($movie->release_date)
<span class="text-muted">({{ $movie->release_date->format('Y') }})</span>
@endif
</h1>
@if($movie->tagline)
<p class="tagline text-muted mb-3">{{ $movie->tagline }}</p>
@endif
<div class="directors mb-3">
<span class="text-muted">Directed by</span>
@foreach($movie->director as $director) @foreach($movie->director as $director)
<a href="">{{ $director->name }}</a>@if(!$loop->last), @endif <a href="#" class="text-decoration-none">{{ $director->name }}</a>@if(!$loop->last), @endif
@endforeach @endforeach
</span> </div>
<span>
<div class="tagline">{{ $movie->tagline }}</div> <div class="overview mb-4">
<div class="overview">{{ $movie->overview }}</div> <h5 class="mb-2">Overview</h5>
</span> <p class="text-muted">{{ $movie->overview }}</p>
<span> </div>
<ul class="nav nav-tabs" id="myTab" role="tablist">
<!-- Tabs -->
<div class="movie-tabs">
<ul class="nav nav-tabs" id="movieTabs" role="tablist">
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link active" id="details-tab" data-bs-toggle="tab" data-bs-target="#details-tab-pane" type="button" role="tab" aria-controls="details-tab-pane" aria-selected="true">Details</button> <button class="nav-link active" id="details-tab" data-bs-toggle="tab" data-bs-target="#details" type="button" role="tab">Details</button>
</li> </li>
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link" id="videos-tab" data-bs-toggle="tab" data-bs-target="#videos-tab-pane" type="button" role="tab" aria-controls="videos-tab-pane" aria-selected="false">Videos</button> <button class="nav-link" id="videos-tab" data-bs-toggle="tab" data-bs-target="#videos" type="button" role="tab">Videos</button>
</li> </li>
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link" id="cast-tab" data-bs-toggle="tab" data-bs-target="#cast-tab-pane" type="button" role="tab" aria-controls="cast-tab-pane" aria-selected="false">Cast</button> <button class="nav-link" id="cast-tab" data-bs-toggle="tab" data-bs-target="#cast" type="button" role="tab">Cast</button>
</li> </li>
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link" id="crew-tab" data-bs-toggle="tab" data-bs-target="#crew-tab-pane" type="button" role="tab" aria-controls="crew-tab-pane" aria-selected="false">Crew</button> <button class="nav-link" id="crew-tab" data-bs-toggle="tab" data-bs-target="#crew" type="button" role="tab">Crew</button>
</li> </li>
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link" id="releases-tab" data-bs-toggle="tab" data-bs-target="#releases-tab-pane" type="button" role="tab" aria-controls="releases-tab-pane" aria-selected="false">Releases</button> <button class="nav-link" id="releases-tab" data-bs-toggle="tab" data-bs-target="#releases" type="button" role="tab">Releases</button>
</li> </li>
</ul> </ul>
<div class="tab-content" id="myTabContent"> <div class="tab-content p-3 border border-top-0 rounded-bottom" id="movieTabsContent">
<div class="tab-pane fade show active" id="details-tab-pane" role="tabpanel" aria-labelledby="details-tab" tabindex="0"> <div class="tab-pane fade show active" id="details" role="tabpanel">
@livewire(App\Livewire\MoviePage\Tabs\Details::class, ['movie' => $movie]) @livewire(App\Livewire\MoviePage\Tabs\Details::class, ['movie' => $movie])
</div> </div>
<div class="tab-pane fade show" id="videos-tab-pane" role="tabpanel" aria-labelledby="videos-tab" tabindex="0"> <div class="tab-pane fade" id="videos" role="tabpanel">
@livewire(App\Livewire\MoviePage\Tabs\Videos::class, ['movie' => $movie]) @livewire(App\Livewire\MoviePage\Tabs\Videos::class, ['movie' => $movie])
</div> </div>
<div class="tab-pane fade" id="cast-tab-pane" role="tabpanel" aria-labelledby="cast-tab" tabindex="0"> <div class="tab-pane fade" id="cast" role="tabpanel">
@livewire(App\Livewire\MoviePage\Tabs\Cast::class, ['movie' => $movie]) @livewire(App\Livewire\MoviePage\Tabs\Cast::class, ['movie' => $movie])
</div> </div>
<div class="tab-pane fade" id="crew-tab-pane" role="tabpanel" aria-labelledby="crew-tab" tabindex="0"> <div class="tab-pane fade" id="crew" role="tabpanel">
@livewire(App\Livewire\MoviePage\Tabs\Crew::class, ['movie' => $movie]) @livewire(App\Livewire\MoviePage\Tabs\Crew::class, ['movie' => $movie])
</div> </div>
<div class="tab-pane fade" id="releases-tab-pane" role="tabpanel" aria-labelledby="releases-tab" tabindex="0"> <div class="tab-pane fade" id="releases" role="tabpanel">
@livewire(App\Livewire\MoviePage\Tabs\Releases::class, ['movie' => $movie]) @livewire(App\Livewire\MoviePage\Tabs\Releases::class, ['movie' => $movie])
</div> </div>
</div> </div>
</span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="card"> </div>
<div class="card-header">Similar</div>
<!-- Similar Movies -->
<div class="card mb-4">
<div class="card-header bg-white">
<h5 class="mb-0">Similar Movies</h5>
</div>
<div class="card-body"> <div class="card-body">
@livewire(App\Livewire\MoviePage\Similar::class, ['movie' => $movie]) @livewire(App\Livewire\MoviePage\Similar::class, ['movie' => $movie])
</div> </div>
</div> </div>
<div class="card">
<div class="card-header">Recommended</div> <!-- Recommendations -->
<div class="card mb-4">
<div class="card-header bg-white">
<h5 class="mb-0">Recommended</h5>
</div>
<div class="card-body"> <div class="card-body">
@livewire(App\Livewire\MoviePage\Recommendations::class, ['movie' => $movie]) @livewire(App\Livewire\MoviePage\Recommendations::class, ['movie' => $movie])
</div> </div>
</div> </div>
<div class="card">
<div class="card-header">Write review</div> <!-- Reviews Section -->
<div class="card mb-4">
<div class="card-header bg-white">
<h5 class="mb-0">Reviews</h5>
</div>
<div class="card-body"> <div class="card-body">
@if(Auth::check()) @if(Auth::check())
<form action="{{ route('movie.comment.store', $movie->slug) }}" method="POST"> <form action="{{ route('movie.comment.store', $movie->slug) }}" method="POST" class="mb-4">
@csrf @csrf
<div class="form-group"> <div class="form-group">
<label for="">Comment</label> <label for="content" class="form-label">Write a Review</label>
<textarea name="content" id="" cols="30" rows="3" class="form-control"></textarea> <textarea name="content" id="content" rows="3" class="form-control" placeholder="Share your thoughts about this movie..."></textarea>
@error('content') @error('content')
<div class="alert alert-danger">{{ $message }}</div> <div class="text-danger mt-1">{{ $message }}</div>
@enderror @enderror
</div> </div>
<div class="form-group"> <div class="mt-2">
<br> <button type="submit" class="btn btn-primary">
<div class="float-end"> <span class="iconify me-1" data-icon="mdi-send"></span>
<input type="submit" class="btn btn-sm btn-success" value="Post"> Post Review
</div> </button>
</div> </div>
</form> </form>
@else @else
<div class="alert alert-info"> <div class="alert alert-info">
You must be authenticated to comment! Please <a href="{{ route('login') }}">login</a> or <a href="{{ route('register') }}">register</a>. <span class="iconify me-1" data-icon="mdi-information"></span>
You must be <a href="{{ route('login') }}" class="alert-link">logged in</a> to write a review.
</div> </div>
@endif @endif
</div>
</div> <!-- Reviews List -->
<div class="reviews-list mt-4">
@foreach($comments as $comment) @foreach($comments as $comment)
<div class="card"> <div class="review-item card mb-3">
<div class="card-header"> <div class="card-body">
<div class="d-flex align-items-center mb-2">
@if($comment->author_avatar) @if($comment->author_avatar)
<img src="http://image.tmdb.org/t/p/w45/{{ $comment->author_avatar }}" alt="" width="25"> <img src="http://image.tmdb.org/t/p/w45/{{ $comment->author_avatar }}"
alt="{{ $comment->author_name }}"
class="rounded-circle me-2"
width="40"
height="40">
@else @else
// user avatar <div class="rounded-circle bg-secondary me-2" style="width: 40px; height: 40px;"></div>
@endif @endif
<div>
<h6 class="mb-0">
@if($comment->author_name) @if($comment->author_name)
{{ $comment->author_name }} {{ $comment->author_name }}
@else @else
<a href="">{{ $comment->author->name }}</a> <a href="#" class="text-decoration-none">{{ $comment->author->name }}</a>
@endif @endif
</h6>
@if($comment->tmdb_id) <small class="text-muted">
<span class="badge text-bg-success btn-tmdb"><a href="https://www.themoviedb.org/review/{{ $comment->tmdb_id }}">TMDB</a></span> {{ \Carbon\Carbon::createFromTimeString($comment->published_at)->diffForHumans() }}
@endif
<span class="rating">
{{ $comment->author_rating }}
</span>
<span class="text-muted float-end">
<small>
{{ $comment->published_at }}
</small> </small>
</span>
</div> </div>
<div class="card-body"> @if($comment->tmdb_id)
<span class="badge bg-success ms-2">
<a href="https://www.themoviedb.org/review/{{ $comment->tmdb_id }}" class="text-white text-decoration-none">TMDB</a>
</span>
@endif
</div>
<div class="review-content">
{!! $comment->content !!} {!! $comment->content !!}
</div> </div>
</div> </div>
</div>
@endforeach @endforeach
</div> </div>
<div class="col-md-2"> </div>
</div>
</div>
<!-- Sidebar -->
<div class="col-lg-3">
<div class="card"> <div class="card">
<div class="card-body">
<div class="user-actions"> <div class="user-actions">
<a href="" class="mark-as-seen-btn {{ auth()->check() ? ($movie->wasListedBy('watched', auth()->user()) ? 'seen' : '') : '' }}" data-id="{{ $movie->id }}" data-type="movie" data-list="watched"> <a href="#" class="d-block mb-3 text-decoration-none mark-as-seen-btn {{ auth()->check() ? ($movie->wasListedBy('watched', auth()->user()) ? 'seen' : '') : '' }}"
<span class="iconify" data-icon="mdi-eye-check-outline"></span> Mark as seen data-id="{{ $movie->id }}"
data-type="movie"
data-list="watched">
<span class="iconify me-1" data-icon="mdi-eye-check-outline"></span>
Mark as seen
</a> </a>
<a href="" class="like-btn {{ auth()->check() ? ($movie->wasListedBy('liked', auth()->user()) ? 'liked' : '') : '' }}" data-id="{{ $movie->id }}" data-type="movie" data-list="liked"> <a href="#" class="d-block mb-3 text-decoration-none like-btn {{ auth()->check() ? ($movie->wasListedBy('liked', auth()->user()) ? 'liked' : '') : '' }}"
<span class="iconify" data-icon="mdi-thumb-up-outline"></span> Like data-id="{{ $movie->id }}"
data-type="movie"
data-list="liked">
<span class="iconify me-1" data-icon="mdi-thumb-up-outline"></span>
Like
</a> </a>
<a href="" class="add-to-list-btn"> <a href="#" class="d-block mb-3 text-decoration-none add-to-list-btn">
<span class="iconify" data-icon="mdi-playlist-check"></span> add to list <span class="iconify me-1" data-icon="mdi-playlist-check"></span>
<span class="arrow float-end"> Add to list
&darr; <span class="float-end">
<span class="iconify" data-icon="mdi-chevron-down"></span>
</span> </span>
</a> </a>
<hr> <hr>
@@ -179,4 +254,5 @@
</div> </div>
</div> </div>
</div> </div>
</div>
@endsection @endsection
+2
View File
@@ -20,6 +20,8 @@ Route::prefix('movies')->group(function () {
Route::prefix('shows')->group(function () { Route::prefix('shows')->group(function () {
Route::get('/', [\App\Http\Controllers\ShowController::class, 'index'])->name('show.index'); Route::get('/', [\App\Http\Controllers\ShowController::class, 'index'])->name('show.index');
Route::get('/{slug}', [\App\Http\Controllers\ShowController::class, 'show'])->name('show.show'); Route::get('/{slug}', [\App\Http\Controllers\ShowController::class, 'show'])->name('show.show');
// Route::get('/{slug}/season/{seasonNumber}', [\App\Http\Controllers\ShowController::class, 'show'])->name('show.show');
// Route::get('/{slug}/season/{seasonNumber}/episode/{episodeNumber}', [\App\Http\Controllers\ShowController::class, 'show'])->name('show.show');
}); });
Route::prefix('celebrities')->group(function () { Route::prefix('celebrities')->group(function () {