From b8b39c945d0eb28c11dcdbc598f111db61d983ad Mon Sep 17 00:00:00 2001 From: DoarMihai Date: Thu, 9 Oct 2025 00:22:54 +0300 Subject: [PATCH] progress --- .../ItemProcessing/FetchItemDataCommand.php | 1 + .../TmdbFetch/DiscoverMoviesCommand.php | 128 +++ .../TmdbFetch/DiscoverTvSeriesCommand.php | 127 +++ app/Http/Controllers/MediaListController.php | 2 +- app/Http/Controllers/MovieController.php | 11 +- app/Http/Controllers/SearchController.php | 54 + app/Service/TMDBApi/MoviesApi.php | 13 + app/Service/TMDBApi/ShowsApi.php | 12 + composer.json | 2 +- composer.lock | 14 +- ..._create_acquaintances_friendship_table.php | 0 ...acquaintances_friendships_groups_table.php | 0 ...reate_acquaintances_interactions_table.php | 0 resources/js/app.js | 15 + resources/sass/app.scss | 1009 +++++++++++++++-- resources/views/auth/login.blade.php | 88 +- resources/views/auth/register.blade.php | 106 +- resources/views/forum/index.blade.php | 17 +- resources/views/forum/thread.blade.php | 10 +- resources/views/forum/topics/show.blade.php | 34 +- resources/views/layouts/header.blade.php | 10 +- .../livewire/show-page/tabs/crew.blade.php | 48 +- resources/views/movie/show.blade.php | 246 +++- resources/views/profile/profile.blade.php | 126 +- resources/views/profile/show.blade.php | 304 ++++- resources/views/search/results.blade.php | 167 +++ resources/views/show/index.blade.php | 92 +- routes/web.php | 2 + 28 files changed, 2186 insertions(+), 452 deletions(-) create mode 100644 app/Console/Commands/TmdbFetch/DiscoverMoviesCommand.php create mode 100644 app/Console/Commands/TmdbFetch/DiscoverTvSeriesCommand.php create mode 100644 app/Http/Controllers/SearchController.php create mode 100644 database/migrations/2025_09_07_143752_create_acquaintances_friendship_table.php create mode 100644 database/migrations/2025_09_07_143752_create_acquaintances_friendships_groups_table.php create mode 100644 database/migrations/2025_09_07_143752_create_acquaintances_interactions_table.php create mode 100644 resources/views/search/results.blade.php diff --git a/app/Console/Commands/ItemProcessing/FetchItemDataCommand.php b/app/Console/Commands/ItemProcessing/FetchItemDataCommand.php index 1b19766..618e690 100644 --- a/app/Console/Commands/ItemProcessing/FetchItemDataCommand.php +++ b/app/Console/Commands/ItemProcessing/FetchItemDataCommand.php @@ -69,6 +69,7 @@ class FetchItemDataCommand extends Command $bar = $this->output->createProgressBar(count($items)); foreach ($items as $item) { + echo "Processing ".$item->tmdb_id."\n"; $this->processItem($item, $job, $type); $bar->advance(); } diff --git a/app/Console/Commands/TmdbFetch/DiscoverMoviesCommand.php b/app/Console/Commands/TmdbFetch/DiscoverMoviesCommand.php new file mode 100644 index 0000000..5571194 --- /dev/null +++ b/app/Console/Commands/TmdbFetch/DiscoverMoviesCommand.php @@ -0,0 +1,128 @@ +moviesApi = $moviesApi; + parent::__construct(); + } + + /** + * Execute the console command. + */ + public function handle() + { + $page = $this->option('page'); + $limit = $this->option('limit'); + + $this->info("Discovering movies from TMDB API (page: {$page}, limit: {$limit})"); + + $totalPages = 0; + $processedCount = 0; + + try { + for ($currentPage = $page; $currentPage < $page + $limit; $currentPage++) { + $this->info("Processing page {$currentPage}"); + + $discoverResult = $this->moviesApi->discover([ + 'page' => $currentPage, + 'sort_by' => 'popularity.desc', + 'include_adult' => false, + 'include_video' => false, + ]); + + if (empty($discoverResult) || empty($discoverResult['results'])) { + $this->error("No results found on page {$currentPage}"); + break; + } + + $totalPages = $discoverResult['total_pages']; + + if ($currentPage > $totalPages) { + $this->info("Reached the end of results (total pages: {$totalPages})"); + break; + } + + DB::beginTransaction(); + + foreach ($discoverResult['results'] as $movie) { + $this->processMovie($movie); + $processedCount++; + } + + DB::commit(); + + // Sleep to avoid rate limiting + sleep(1); + } + + $this->info("Successfully processed {$processedCount} movies"); + + } catch (\Throwable $e) { + DB::rollBack(); + $this->error("Error processing movies: " . $e->getMessage()); + $this->error($e->getTraceAsString()); + } + } + + private function processMovie(array $movie) + { + $tmdbId = $movie['id']; + + // Check if this movie is already in the queue + $existingJob = ItemToFetchJobs::where('tmdb_id', $tmdbId) + ->where('type', 'movie') + ->first(); + + if ($existingJob) { + $this->line("Movie ID {$tmdbId} already in queue, skipping"); + return; + } + + // Create ItemToFetch record if it doesn't exist + $itemToFetch = ItemToFetch::firstOrCreate( + [ + 'tmdb_id' => $tmdbId, + 'type' => ItemToFetch::TYPE_MOVIE, + ] + ); + + // Prepare jobs list + $jobs = ItemToFetchJobs::MOVIE_JOBS; + $jobs[] = ItemToFetchJobs::JOB_DETAILS; + + // Create ItemToFetchJobs record + ItemToFetchJobs::create([ + 'tmdb_id' => $tmdbId, + 'type' => ItemToFetch::TYPE_MOVIE, + 'jobs' => implode(',', $jobs), + ]); + + $this->line("Added movie ID {$tmdbId} to fetch queue"); + } +} diff --git a/app/Console/Commands/TmdbFetch/DiscoverTvSeriesCommand.php b/app/Console/Commands/TmdbFetch/DiscoverTvSeriesCommand.php new file mode 100644 index 0000000..1cd703d --- /dev/null +++ b/app/Console/Commands/TmdbFetch/DiscoverTvSeriesCommand.php @@ -0,0 +1,127 @@ +showsApi = $showsApi; + parent::__construct(); + } + + /** + * Execute the console command. + */ + public function handle() + { + $page = $this->option('page'); + $limit = $this->option('limit'); + + $this->info("Discovering TV series from TMDB API (page: {$page}, limit: {$limit})"); + + $totalPages = 0; + $processedCount = 0; + + try { + for ($currentPage = $page; $currentPage < $page + $limit; $currentPage++) { + $this->info("Processing page {$currentPage}"); + + $discoverResult = $this->showsApi->discover([ + 'page' => $currentPage, + 'sort_by' => 'popularity.desc', + 'include_adult' => false, + ]); + + if (empty($discoverResult) || empty($discoverResult['results'])) { + $this->error("No results found on page {$currentPage}"); + break; + } + + $totalPages = $discoverResult['total_pages']; + + if ($currentPage > $totalPages) { + $this->info("Reached the end of results (total pages: {$totalPages})"); + break; + } + + DB::beginTransaction(); + + foreach ($discoverResult['results'] as $show) { + $this->processShow($show); + $processedCount++; + } + + DB::commit(); + + // Sleep to avoid rate limiting + sleep(1); + } + + $this->info("Successfully processed {$processedCount} TV series"); + + } catch (\Throwable $e) { + DB::rollBack(); + $this->error("Error processing TV series: " . $e->getMessage()); + $this->error($e->getTraceAsString()); + } + } + + private function processShow(array $show) + { + $tmdbId = $show['id']; + + // Check if this show is already in the queue + $existingJob = ItemToFetchJobs::where('tmdb_id', $tmdbId) + ->where('type', ItemToFetch::TYPE_TV_SERIES) + ->first(); + + if ($existingJob) { + $this->line("TV series ID {$tmdbId} already in queue, skipping"); + return; + } + + // Create ItemToFetch record if it doesn't exist + $itemToFetch = ItemToFetch::firstOrCreate( + [ + 'tmdb_id' => $tmdbId, + 'type' => ItemToFetch::TYPE_TV_SERIES, + ] + ); + + // Prepare jobs list + $jobs = ItemToFetchJobs::SHOW_JOBS; + $jobs[] = ItemToFetchJobs::JOB_DETAILS; + + // Create ItemToFetchJobs record + ItemToFetchJobs::create([ + 'tmdb_id' => $tmdbId, + 'type' => ItemToFetch::TYPE_TV_SERIES, + 'jobs' => implode(',', $jobs), + ]); + + $this->line("Added TV series ID {$tmdbId} to fetch queue"); + } +} diff --git a/app/Http/Controllers/MediaListController.php b/app/Http/Controllers/MediaListController.php index 1d61d63..e1cbf74 100644 --- a/app/Http/Controllers/MediaListController.php +++ b/app/Http/Controllers/MediaListController.php @@ -34,7 +34,7 @@ class MediaListController extends Controller return view('profile.lists.show', compact('list', 'items', 'user')); } - public function create() + public function create(string $userSlug) { $user = Auth::user(); diff --git a/app/Http/Controllers/MovieController.php b/app/Http/Controllers/MovieController.php index f8d152e..2c440bb 100644 --- a/app/Http/Controllers/MovieController.php +++ b/app/Http/Controllers/MovieController.php @@ -4,8 +4,10 @@ namespace App\Http\Controllers; use App\Http\Requests\Movie\CommentRequest; use App\Models\Comment; +use App\Models\MediaList; use App\Models\Movie; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; class MovieController extends Controller { @@ -26,7 +28,14 @@ class MovieController extends Controller ->where('entity_type', Comment::TYPE_MOVIE) ->paginate(15); - return view('movie.show', compact('movie', 'comments')); + $userLists = []; + if (Auth::check()) { + $userLists = MediaList::whereNotIn('name', MediaList::SPECIAL_LISTS) + ->where('user_id', Auth::user()->id) + ->get(); + } + + return view('movie.show', compact('movie', 'comments', 'userLists')); } public function storeComment(CommentRequest $request, string $movieSlug) diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php new file mode 100644 index 0000000..61eb338 --- /dev/null +++ b/app/Http/Controllers/SearchController.php @@ -0,0 +1,54 @@ +input('query'); + $type = $request->input('type', 'all'); + + $movies = collect([]); + $shows = collect([]); + $people = collect([]); + + if ($query) { + // Search for movies if type is 'all' or 'movie' + if ($type === 'all' || $type === 'movie') { + $movies = Movie::where('title', 'like', "%{$query}%") + ->orWhere('overview', 'like', "%{$query}%") + ->limit(20) + ->get(); + } + + // Search for TV shows if type is 'all' or 'tv' + if ($type === 'all' || $type === 'tv') { + $shows = Show::where('name', 'like', "%{$query}%") + ->orWhere('overview', 'like', "%{$query}%") + ->limit(20) + ->get(); + } + + // Search for people if type is 'all' or 'person' + if ($type === 'all' || $type === 'person') { + $people = Person::where('name', 'like', "%{$query}%") + ->limit(20) + ->get(); + } + } + + return view('search.results', [ + 'query' => $query, + 'type' => $type, + 'movies' => $movies, + 'shows' => $shows, + 'people' => $people, + ]); + } +} diff --git a/app/Service/TMDBApi/MoviesApi.php b/app/Service/TMDBApi/MoviesApi.php index f6e2f72..cc2928c 100644 --- a/app/Service/TMDBApi/MoviesApi.php +++ b/app/Service/TMDBApi/MoviesApi.php @@ -297,4 +297,17 @@ class MoviesApi extends AbstractApiService sleep(1); return $this->get('movie/' . $movieId . '/external_ids', $parameters, $headers); } + + /** + * Discover movies based on filters. + * + * @param array $parameters + * @param array $headers + * @return mixed + */ + public function discover(array $parameters = [], array $headers = []) + { + sleep(1); + return $this->get('discover/movie', $parameters, $headers); + } } diff --git a/app/Service/TMDBApi/ShowsApi.php b/app/Service/TMDBApi/ShowsApi.php index d6be424..b8675d3 100644 --- a/app/Service/TMDBApi/ShowsApi.php +++ b/app/Service/TMDBApi/ShowsApi.php @@ -296,4 +296,16 @@ class ShowsApi extends AbstractApiService { return $this->get('tv/' . $seriesTmdbId . '/season/'.$seasonNumber); } + /** + * Discover TV shows based on filters. + * + * @param array $parameters + * @param array $headers + * @return mixed + */ + public function discover(array $parameters = [], array $headers = []) + { + sleep(1); + return $this->get('discover/tv', $parameters, $headers); + } } diff --git a/composer.json b/composer.json index a1177bf..de70948 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "laravel/tinker": "^2.9", "laravel/ui": "^4.6", "livewire/livewire": "^3.5", - "multicaret/laravel-acquaintances": "^3.6" + "multicaret/laravel-acquaintances": "^3.7" }, "require-dev": { "fakerphp/faker": "^1.23", diff --git a/composer.lock b/composer.lock index d2be980..08d659e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6d84b8d65adb605b5a8df2d31dee572e", + "content-hash": "9d587736fd8ce83beea4888793faef40", "packages": [ { "name": "blade-ui-kit/blade-ui-kit", @@ -2328,16 +2328,16 @@ }, { "name": "multicaret/laravel-acquaintances", - "version": "v3.6.1", + "version": "v3.7.3", "source": { "type": "git", "url": "https://github.com/multicaret/laravel-acquaintances.git", - "reference": "ae1c4aebe2137cc5c89072e2124e99e8843cdf64" + "reference": "58022069b29540cc37486cdf2618f30284ef447b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/multicaret/laravel-acquaintances/zipball/ae1c4aebe2137cc5c89072e2124e99e8843cdf64", - "reference": "ae1c4aebe2137cc5c89072e2124e99e8843cdf64", + "url": "https://api.github.com/repos/multicaret/laravel-acquaintances/zipball/58022069b29540cc37486cdf2618f30284ef447b", + "reference": "58022069b29540cc37486cdf2618f30284ef447b", "shasum": "" }, "require": { @@ -2392,9 +2392,9 @@ ], "support": { "issues": "https://github.com/multicaret/laravel-acquaintances/issues", - "source": "https://github.com/multicaret/laravel-acquaintances/tree/v3.6.1" + "source": "https://github.com/multicaret/laravel-acquaintances/tree/v3.7.3" }, - "time": "2024-06-08T13:48:12+00:00" + "time": "2025-08-06T12:41:26+00:00" }, { "name": "nesbot/carbon", diff --git a/database/migrations/2025_09_07_143752_create_acquaintances_friendship_table.php b/database/migrations/2025_09_07_143752_create_acquaintances_friendship_table.php new file mode 100644 index 0000000..e69de29 diff --git a/database/migrations/2025_09_07_143752_create_acquaintances_friendships_groups_table.php b/database/migrations/2025_09_07_143752_create_acquaintances_friendships_groups_table.php new file mode 100644 index 0000000..e69de29 diff --git a/database/migrations/2025_09_07_143752_create_acquaintances_interactions_table.php b/database/migrations/2025_09_07_143752_create_acquaintances_interactions_table.php new file mode 100644 index 0000000..e69de29 diff --git a/resources/js/app.js b/resources/js/app.js index acb66fa..363aa97 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -106,3 +106,18 @@ $('.remove-from-watchlist').on('click', function(e){ }); return false; }); + +$('.list-action').on('click', function(e){ + e.preventDefault(); + let url = '/lists/' + $(this).data('list') + '/' + $(this).data('id') + '/' + $(this).data('type'); + var self = this + $.ajax({ + url: url, + method: 'GET', + success: function(data){ + // Show a success message + alert('Movie ' + (data.added ? 'added to' : 'removed from') + ' list'); + } + }); + return false; +}); diff --git a/resources/sass/app.scss b/resources/sass/app.scss index 1144a52..8ef0758 100644 --- a/resources/sass/app.scss +++ b/resources/sass/app.scss @@ -18,6 +18,24 @@ $fa-font-path: "/fonts"; background-color: #1a1a1a !important; color: #e0e0e0; + .dropdown-menu { + background-color: #2a2a2a; + border-color: #444; + + .dropdown-item { + color: #e0e0e0; + + &:hover, &:focus { + background-color: #333; + color: #fff; + } + } + + .dropdown-divider { + border-color: #444; + } + } + .forums{ .category{ .title{ @@ -43,38 +61,238 @@ $fa-font-path: "/fonts"; } .profile-page{ background: #2a2a2a; - padding: 15px 0; + padding: 30px 0; margin-top: -50px; + border-bottom: 1px solid rgba(255,255,255,0.1); + .user-avatar{ - width: 125px; + width: 150px; + height: 150px; + object-fit: cover; border-radius: 50%; - border: 2px solid #333; - box-shadow: 2px 2px 9px #000; + border: 4px solid #333; + box-shadow: 0 4px 10px rgba(0,0,0,0.5); + transition: all 0.3s ease; + + &:hover { + transform: scale(1.05); + } } + + .position-relative { + .avatar-edit-overlay { + position: absolute; + bottom: 5px; + right: 5px; + opacity: 0; + transition: opacity 0.3s ease; + + .btn-light { + background-color: #333; + border-color: #444; + color: #e0e0e0; + + &:hover { + background-color: #444; + } + } + } + + &:hover .avatar-edit-overlay { + opacity: 1; + } + } + h1{ display: inline-block; margin-right: 15px; color: #e0e0e0; + font-weight: 700; + } + + .user-meta { + color: #a0a0a0; + + .iconify { + vertical-align: -0.125em; + margin-right: 4px; + } + } + + .user-stats { + background: rgba(42, 42, 42, 0.7); + border-radius: 10px; + padding: 15px; + margin-top: 15px; + box-shadow: 0 2px 5px rgba(0,0,0,0.2); + + .stat-value { + font-size: 1.5rem; + font-weight: 700; + color: #e0e0e0; + } + + .stat-label { + font-size: 0.85rem; + color: #a0a0a0; + } } } + .profile-page-menu{ - background: rgba(42, 42, 42, 0.3); - ul{ - margin: 0; - li{ - padding: 5px; - a{ - text-decoration: none; + background: #222; + box-shadow: 0 2px 5px rgba(0,0,0,0.2); + padding: 10px 0; + margin-bottom: 20px; + + .nav-pills { + .nav-link { + color: #a0a0a0; + padding: 8px 15px; + border-radius: 20px; + margin-right: 5px; + transition: all 0.3s ease; + + .iconify { + margin-right: 5px; + vertical-align: -0.125em; + } + + &:hover { + background-color: #333; color: #e0e0e0; - &:hover{ - color: #fff; + } + + &.active { + background-color: #0d6efd; + color: #fff; + } + } + } + } + + .profile-content { + .card { + background: #2a2a2a; + border: none; + border-radius: 10px; + overflow: hidden; + transition: transform 0.2s ease, box-shadow 0.2s ease; + + &:hover { + transform: translateY(-3px); + box-shadow: 0 10px 20px rgba(0,0,0,0.3) !important; + } + + .card-header { + background-color: #333; + border-bottom: 1px solid rgba(255,255,255,0.05); + padding: 15px 20px; + color: #e0e0e0; + + h5 { + font-weight: 600; + color: #e0e0e0; + + .iconify { + margin-right: 8px; + vertical-align: -0.125em; + color: #0d6efd; } - &.active{ - color: #fff; - text-decoration: underline; + } + + a { + color: #a0a0a0; + + &:hover { + color: #e0e0e0; } } } + + .card-body { + padding: 20px; + color: #e0e0e0; + + .text-muted { + color: #a0a0a0 !important; + } + + .alert-light { + background-color: #333; + color: #e0e0e0; + border-color: #444; + } + + .badge { + &.bg-light { + background-color: #444 !important; + color: #e0e0e0 !important; + } + } + + .list-group-item { + background-color: #2a2a2a; + border-color: #444; + color: #e0e0e0; + } + } + } + + .overlay-play { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0,0,0,0.5); + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transition: opacity 0.3s ease; + border-radius: 0.25rem; + + .iconify { + color: #fff; + filter: drop-shadow(0 0 3px rgba(0,0,0,0.8)); + } + } + + a:hover .overlay-play { + opacity: 1; + } + + .poster-thumbnail { + width: 60px; + height: 90px; + overflow: hidden; + + img { + width: 100%; + height: 100%; + object-fit: cover; + } + + &.more-posters { + background: #333; + border: 1px dashed #444; + color: #a0a0a0; + font-weight: 600; + } + } + + .rating-label { + width: 20px; + text-align: center; + font-weight: 600; + color: #e0e0e0; + } + + .rating-count { + width: 30px; + text-align: right; + color: #a0a0a0; } } .large-list-item{ @@ -109,7 +327,7 @@ $fa-font-path: "/fonts"; 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); @@ -118,13 +336,13 @@ $fa-font-path: "/fonts"; .quick-actions{ background: #333; border-top: 1px solid #444; - + li { border-right: 1px solid #444; - + a { color: #a0a0a0; - + &:hover { background: #444; color: #e0e0e0; @@ -135,102 +353,236 @@ $fa-font-path: "/fonts"; } .user-actions{ - padding: 5px; - .mark-as-seen-btn{ - margin-top: 5px; - display: block; - border: 1px solid #903eb3; - padding: 7px 10px; - text-decoration: none; + padding: 10px; + + .mark-as-seen-btn, .like-btn, .add-to-list-btn { + border-radius: 8px; + padding: 10px 15px; + transition: all 0.3s ease; + font-weight: 500; color: #e0e0e0; + + .badge { + background-color: rgba(255, 255, 255, 0.1); + transition: all 0.3s ease; + } + + &:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + + .badge { + background-color: rgba(255, 255, 255, 0.2); + } + } + } + + .mark-as-seen-btn{ + border: 1px solid #903eb3; + background-color: rgba(144, 62, 179, 0.1); + &: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; + background-color: rgba(22, 160, 133, 0.1); + &: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; + background-color: rgba(255, 95, 6, 0.1); + &:hover{ color: white; - transition: all .5s; background: #ff5f06; } + &.listed{ color: white; background: #ff5f06; } } + + .rating-section { + background-color: rgba(255, 255, 255, 0.05); + border-radius: 8px; + padding: 15px; + + h6 { + color: #e0e0e0; + font-weight: 600; + } + } } .right-sidebar { .card { background: #2a2a2a; border: 1px solid #333; - + border-radius: 10px; + overflow: hidden; + margin-bottom: 1.5rem; + transition: transform 0.2s ease, box-shadow 0.2s ease; + + &:hover { + transform: translateY(-3px); + box-shadow: 0 10px 20px rgba(0,0,0,0.3) !important; + } + .card-header { background: #333; color: #e0e0e0; border-bottom: 1px solid #444; + padding: 15px; + font-weight: 600; + + h5 { + display: flex; + align-items: center; + + .iconify { + margin-right: 8px; + color: #0d6efd; + } + } } - + .card-body { color: #e0e0e0; + padding: 15px; } } - + + .movie-info-list { + .list-group-item { + background-color: #2a2a2a; + border-color: #444; + padding: 12px 15px; + + .info-label { + color: #a0a0a0; + display: flex; + align-items: center; + + .iconify { + color: #0d6efd; + } + } + + .info-value { + font-weight: 500; + color: #e0e0e0; + } + } + } + .trending-movies { .movie-item { border-bottom: 1px solid #444; - + transition: background-color 0.2s ease; + + &:hover { + background-color: #333; + } + + &:last-child { + border-bottom: none; + } + + img { + width: 70px; + height: 105px; + object-fit: cover; + border-radius: 6px; + transition: transform 0.2s ease; + + &:hover { + transform: scale(1.05); + } + } + .movie-info { h6 { color: #e0e0e0; + font-size: 0.95rem; + margin-bottom: 5px; } - + .rating { color: #a0a0a0; + font-size: 0.85rem; + display: flex; + align-items: center; + + .iconify { + margin-right: 5px; + } + } + + .btn-outline-primary { + border-color: #0d6efd; + color: #0d6efd; + padding: 3px 10px; + font-size: 0.8rem; + + &:hover { + background-color: #0d6efd; + color: #fff; + } } } } } - + .quick-links { ul { + list-style: none; + padding: 0; + margin: 0; + li { border-bottom: 1px solid #444; - + + &:last-child { + border-bottom: none; + } + a { color: #e0e0e0; - + display: flex; + align-items: center; + padding: 12px 15px; + transition: all 0.2s ease; + + .iconify { + margin-right: 10px; + font-size: 1.2rem; + color: #0d6efd; + } + &:hover { color: #0d6efd; + background-color: #333; + text-decoration: none; } } } @@ -264,14 +616,14 @@ $fa-font-path: "/fonts"; .navbar { background: #2a2a2a; border-bottom: 1px solid #333; - + .navbar-brand { color: #e0e0e0; } - + .nav-link { color: #e0e0e0; - + &:hover { color: #fff; } @@ -282,7 +634,7 @@ $fa-font-path: "/fonts"; background: #333; border: 1px solid #444; color: #e0e0e0; - + &:focus { background: #333; border-color: #555; @@ -293,7 +645,7 @@ $fa-font-path: "/fonts"; .btn-outline-primary { color: #0d6efd; border-color: #0d6efd; - + &:hover { background: #0d6efd; color: #fff; @@ -306,6 +658,28 @@ body.light-mode{ } .light-mode{ + .dropdown-menu { + background-color: #fff; + border-color: #e0e0e0; + + .dropdown-item { + color: #495057; + + &:hover, &:focus { + background-color: #f8f9fa; + color: #0d6efd; + } + + .iconify { + color: #0d6efd; + } + } + + .dropdown-divider { + border-color: #e0e0e0; + } + } + .forums{ .category{ .title{ @@ -327,19 +701,74 @@ body.light-mode{ margin-top: 45px; } .profile-page{ - background: #ccc; - padding: 15px 0; + background: #f8f9fa; + padding: 30px 0; margin-top: -50px; + border-bottom: 1px solid rgba(0,0,0,0.1); + .user-avatar{ - width: 125px; + width: 150px; + height: 150px; + object-fit: cover; border-radius: 50%; - border: 2px solid #eeecec; - box-shadow: 2px 2px 9px #979696; + border: 4px solid #fff; + box-shadow: 0 4px 10px rgba(0,0,0,0.1); + transition: all 0.3s ease; + + &:hover { + transform: scale(1.05); + } } + + .position-relative { + .avatar-edit-overlay { + position: absolute; + bottom: 5px; + right: 5px; + opacity: 0; + transition: opacity 0.3s ease; + } + + &:hover .avatar-edit-overlay { + opacity: 1; + } + } + h1{ display: inline-block; margin-right: 15px; + font-weight: 700; + color: #333; } + + .user-meta { + color: #6c757d; + + .iconify { + vertical-align: -0.125em; + margin-right: 4px; + } + } + + .user-stats { + background: rgba(255,255,255,0.7); + border-radius: 10px; + padding: 15px; + margin-top: 15px; + box-shadow: 0 2px 5px rgba(0,0,0,0.05); + + .stat-value { + font-size: 1.5rem; + font-weight: 700; + color: #495057; + } + + .stat-label { + font-size: 0.85rem; + color: #6c757d; + } + } + &.pattern1{ background: url("/public/img/email-pattern.webp"); } @@ -359,21 +788,123 @@ body.light-mode{ background: url("/public/img/folk-pattern.webp"); } } + .profile-page-menu{ - background: rgba(255, 255, 255, .3); - ul{ - margin: 0; - li{ - padding: 5px; - a{ - text-decoration: none; - &:hover{} - &.active{ - color: black; - text-decoration: underline; + background: #fff; + box-shadow: 0 2px 5px rgba(0,0,0,0.05); + padding: 10px 0; + margin-bottom: 20px; + + .nav-pills { + .nav-link { + color: #495057; + padding: 8px 15px; + border-radius: 20px; + margin-right: 5px; + transition: all 0.3s ease; + + .iconify { + margin-right: 5px; + vertical-align: -0.125em; + } + + &:hover { + background-color: #f8f9fa; + } + + &.active { + background-color: #0d6efd; + color: #fff; + } + } + } + } + + .profile-content { + .card { + border: none; + border-radius: 10px; + overflow: hidden; + transition: transform 0.2s ease, box-shadow 0.2s ease; + + &:hover { + transform: translateY(-3px); + box-shadow: 0 10px 20px rgba(0,0,0,0.1) !important; + } + + .card-header { + background-color: #fff; + border-bottom: 1px solid rgba(0,0,0,0.05); + padding: 15px 20px; + + h5 { + font-weight: 600; + + .iconify { + margin-right: 8px; + vertical-align: -0.125em; + color: #0d6efd; } } } + + .card-body { + padding: 20px; + } + } + + .overlay-play { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0,0,0,0.3); + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transition: opacity 0.3s ease; + border-radius: 0.25rem; + + .iconify { + color: #fff; + filter: drop-shadow(0 0 3px rgba(0,0,0,0.5)); + } + } + + a:hover .overlay-play { + opacity: 1; + } + + .poster-thumbnail { + width: 60px; + height: 90px; + overflow: hidden; + + img { + width: 100%; + height: 100%; + object-fit: cover; + } + + &.more-posters { + background: #f8f9fa; + border: 1px dashed #dee2e6; + color: #6c757d; + font-weight: 600; + } + } + + .rating-label { + width: 20px; + text-align: center; + font-weight: 600; + } + + .rating-count { + width: 30px; + text-align: right; } } .large-list-item{ @@ -415,7 +946,7 @@ body.light-mode{ 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); @@ -436,16 +967,16 @@ body.light-mode{ justify-content: space-between; background: #f8f9fa; border-top: 1px solid #e0e0e0; - + li { flex: 1; text-align: center; border-right: 1px solid #e0e0e0; - + &:last-child { border-right: none; } - + a { color: #6c757d; text-decoration: none; @@ -456,12 +987,12 @@ body.light-mode{ padding: 8px; transition: all 0.2s ease; font-size: 0.85rem; - + &:hover { background: #e9ecef; color: #495057; } - + .iconify { font-size: 1.1rem; } @@ -472,7 +1003,7 @@ body.light-mode{ flex-direction: row; justify-content: center; gap: 4px; - + .iconify { margin-top: 0; } @@ -507,55 +1038,85 @@ body.light-mode{ } } .user-actions{ - padding: 5px; + padding: 10px; + + .mark-as-seen-btn, .like-btn, .add-to-list-btn { + border-radius: 8px; + padding: 10px 15px; + transition: all 0.3s ease; + font-weight: 500; + color: #495057; + + .badge { + background-color: rgba(0, 0, 0, 0.05); + transition: all 0.3s ease; + } + + &:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + + .badge { + background-color: rgba(0, 0, 0, 0.1); + } + } + } + .mark-as-seen-btn{ - margin-top: 5px; - display: block; border: 1px solid #903eb3; - padding: 7px 10px; - text-decoration: none; + background-color: rgba(144, 62, 179, 0.05); + &: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; + background-color: rgba(22, 160, 133, 0.05); + &: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; + background-color: rgba(255, 95, 6, 0.05); + &:hover{ color: white; - transition: all .5s; background: #ff5f06; } + &.listed{ color: white; background: #ff5f06; } } + + .rating-section { + background-color: rgba(0, 0, 0, 0.03); + border-radius: 8px; + padding: 15px; + + h6 { + color: #495057; + font-weight: 600; + } + } } @@ -649,84 +1210,153 @@ body.light-mode{ .right-sidebar { .card { - border-radius: 8px; + border-radius: 10px; overflow: hidden; margin-bottom: 1.5rem; - + border: 1px solid #e0e0e0; + transition: transform 0.2s ease, box-shadow 0.2s ease; + + &:hover { + transform: translateY(-3px); + box-shadow: 0 10px 20px rgba(0,0,0,0.1) !important; + } + .card-header { background: #f8f9fa; - padding: 1rem; + padding: 15px; font-weight: 600; border-bottom: 1px solid #e0e0e0; + + h5 { + display: flex; + align-items: center; + + .iconify { + margin-right: 8px; + color: #0d6efd; + } + } } - + .card-body { - padding: 1rem; + padding: 15px; } } - + + .movie-info-list { + .list-group-item { + padding: 12px 15px; + border-color: #e0e0e0; + + .info-label { + color: #6c757d; + display: flex; + align-items: center; + + .iconify { + color: #0d6efd; + } + } + + .info-value { + font-weight: 500; + color: #495057; + } + } + } + .trending-movies { .movie-item { - display: flex; - align-items: center; - padding: 0.5rem 0; + padding: 15px; border-bottom: 1px solid #e0e0e0; - + transition: background-color 0.2s ease; + + &:hover { + background-color: #f8f9fa; + } + &:last-child { border-bottom: none; } - + img { - width: 50px; - height: 75px; + width: 70px; + height: 105px; object-fit: cover; - border-radius: 4px; - margin-right: 1rem; + border-radius: 6px; + transition: transform 0.2s ease; + + &:hover { + transform: scale(1.05); + } } - + .movie-info { flex: 1; - + h6 { - margin: 0; - font-size: 0.9rem; + margin-bottom: 5px; + font-size: 0.95rem; + color: #495057; } - + .rating { - font-size: 0.8rem; + font-size: 0.85rem; color: #6c757d; + display: flex; + align-items: center; + margin-bottom: 10px; + + .iconify { + margin-right: 5px; + } + } + + .btn-outline-primary { + border-color: #0d6efd; + color: #0d6efd; + padding: 3px 10px; + font-size: 0.8rem; + + &:hover { + background-color: #0d6efd; + color: #fff; + } } } } } - + .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 { + padding: 12px 15px; + transition: all 0.2s ease; + + .iconify { + margin-right: 10px; + font-size: 1.2rem; color: #0d6efd; } - - .iconify { - font-size: 1.2rem; + + &:hover { + color: #0d6efd; + background-color: #f8f9fa; } } } @@ -741,12 +1371,139 @@ body.light-mode{ cursor: pointer; padding: 0.5rem 1rem; transition: all 0.3s ease; - + &:hover { opacity: 0.8; } - + .iconify { font-size: 1.2rem; } } + +/* Authentication Pages Styles */ +.auth-form-container { + margin: 2rem auto; + max-width: 550px; + + .auth-logo { + font-size: 2.5rem; + color: #0d6efd; + } + + .auth-subtitle { + color: #6c757d; + font-size: 1.1rem; + } + + .auth-card { + border-radius: 10px; + overflow: hidden; + border: none; + + .input-group-text { + background-color: #f8f9fa; + border-right: none; + + .iconify { + color: #6c757d; + font-size: 1.2rem; + } + } + + .form-control { + border-left: none; + + &:focus { + box-shadow: none; + border-color: #ced4da; + } + } + } + + .auth-footer { + .auth-bg-icons { + .auth-icon { + font-size: 1.5rem; + margin: 0 0.5rem; + color: #6c757d; + opacity: 0.5; + } + } + } +} + +/* Dark Mode Authentication Styles */ +.dark-mode { + .auth-form-container { + .auth-logo { + color: #0d6efd; + } + + .auth-subtitle { + color: #a0a0a0; + } + + .auth-card { + background: #2a2a2a; + + .card-body { + color: #e0e0e0; + } + + .input-group-text { + background-color: #333; + border-color: #444; + color: #e0e0e0; + border-right: none; + + .iconify { + color: #a0a0a0; + } + } + + .form-control { + background-color: #333; + border-color: #444; + color: #e0e0e0; + border-left: none; + + &:focus { + background-color: #333; + border-color: #444; + color: #e0e0e0; + } + + &::placeholder { + color: #6c757d; + } + } + + .form-check-label { + color: #e0e0e0; + } + + .form-check-input { + background-color: #333; + border-color: #444; + + &:checked { + background-color: #0d6efd; + border-color: #0d6efd; + } + } + } + + .auth-footer { + .auth-bg-icons { + .auth-icon { + color: #a0a0a0; + } + } + + .text-muted { + color: #a0a0a0 !important; + } + } + } +} diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index ea9ac94..8041c11 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -4,67 +4,81 @@
-
-
{{ __('Login') }}
+
+
+

MovieAddict

+

Welcome back! Log in to your account

+
-
-
- @csrf - -
- - -
- +
+
+ + @csrf +
+ +
+ + +
@error('email') - + {{ $message }} @enderror
-
- -
- - -
- +
+
+ + @if (Route::has('password.request')) + + {{ __('Forgot Password?') }} + + @endif +
+
+ + +
@error('password') - + {{ $message }} @enderror
-
-
-
+
-
-
-
-
- - - @if (Route::has('password.request')) - - {{ __('Forgot Your Password?') }} - - @endif
-
- + +
+

Don't have an account? Register now

+
+ +
+
+ +
diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php index 12cad1a..bb32f77 100644 --- a/resources/views/auth/register.blade.php +++ b/resources/views/auth/register.blade.php @@ -4,71 +4,95 @@
-
-
{{ __('Register') }}
+
+
+

MovieAddict

+

Create your account and start tracking movies

+
-
-
- @csrf - -
- - -
- +
+
+ + @csrf +
+ +
+ + +
@error('name') - + {{ $message }} @enderror
-
- -
- - -
- +
+ +
+ + +
@error('email') - + {{ $message }} @enderror
-
- -
- - -
- +
+ +
+ + +
@error('password') - + {{ $message }} @enderror
-
-
- - -
- +
+ +
+ + +
-
-
-
-
-
- + +
+

Already have an account? Log in

+
+ +
+
+ +
diff --git a/resources/views/forum/index.blade.php b/resources/views/forum/index.blade.php index 3539e7e..cc810f2 100644 --- a/resources/views/forum/index.blade.php +++ b/resources/views/forum/index.blade.php @@ -56,22 +56,7 @@
- + menu
diff --git a/resources/views/forum/thread.blade.php b/resources/views/forum/thread.blade.php index ea35b12..6178758 100644 --- a/resources/views/forum/thread.blade.php +++ b/resources/views/forum/thread.blade.php @@ -12,9 +12,11 @@ {{ $thread->name }}
- - New topic - + @if(auth()->check()) + + New topic + + @endif
@@ -50,7 +52,7 @@
{{ $topic->name }}
- Created by {{ $topic->author->name ?? 'Unknown User' }} {{ $topic->created_at ? $topic->created_at->diffForHumans() : 'N/A' }} + Created by {{ $topic->author->name ?? 'Unknown User' }} {{ $topic->created_at ? $topic->created_at->diffForHumans() : 'N/A' }}
{{ $topic->views_no }}
diff --git a/resources/views/forum/topics/show.blade.php b/resources/views/forum/topics/show.blade.php index 6e02a6b..e82be4e 100644 --- a/resources/views/forum/topics/show.blade.php +++ b/resources/views/forum/topics/show.blade.php @@ -54,18 +54,32 @@
{{ $posts->links() }} -
-
- @csrf -
- +
+
+ Reply
-
-
- -
+
+ @if(auth()->check()) +
+ + @csrf +
+ +
+
+
+ +
+
+ + @else +
+ + You must be logged in to write a review. +
+ @endif
- +
diff --git a/resources/views/layouts/header.blade.php b/resources/views/layouts/header.blade.php index a4317d5..42111c3 100644 --- a/resources/views/layouts/header.blade.php +++ b/resources/views/layouts/header.blade.php @@ -9,9 +9,15 @@