lots of progress
This commit is contained in:
@@ -45,18 +45,9 @@ class FetchItemDataCommand extends Command
|
|||||||
|
|
||||||
private function getBatch(string $type, int $batch, string $job)
|
private function getBatch(string $type, int $batch, string $job)
|
||||||
{
|
{
|
||||||
return ItemToFetch::has('jobs')
|
return ItemToFetch::whereHas('jobs', function($query) use ($job){
|
||||||
->with([
|
return $query->where('jobs', '<>', null)->whereRaw('FIND_IN_SET(?, jobs)', [$job]);
|
||||||
// 'jobs' => fn ($jobs) => dd($jobs->first()->remaining_jobs) /*array_search($job, $jobs->first()->remaining_jobs, true)*/,
|
})->with(['jobs'])
|
||||||
'jobs' => function ($jobs) use ($job) {
|
|
||||||
$remainingJobs = $jobs->first()->remaining_jobs;
|
|
||||||
if (is_string($remainingJobs)) {
|
|
||||||
$remainingJobs = json_decode($jobs->first()->remaining_jobs, true);
|
|
||||||
}
|
|
||||||
return array_search($job, $remainingJobs, true);
|
|
||||||
},
|
|
||||||
|
|
||||||
])
|
|
||||||
->where('type', $type)
|
->where('type', $type)
|
||||||
->take($batch)
|
->take($batch)
|
||||||
->get();
|
->get();
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ class FetchUpcomingMoviesCommand extends Command
|
|||||||
$oldUpcomingIds = UpcomingMovie::all()->pluck('movie_id');
|
$oldUpcomingIds = UpcomingMovie::all()->pluck('movie_id');
|
||||||
|
|
||||||
foreach ($upcomingMovies['results'] as $upcomingMovie) {
|
foreach ($upcomingMovies['results'] as $upcomingMovie) {
|
||||||
|
echo ".";
|
||||||
$movie = $this->process($upcomingMovie);
|
$movie = $this->process($upcomingMovie);
|
||||||
|
|
||||||
if ($movie) {
|
if ($movie) {
|
||||||
@@ -69,11 +70,13 @@ class FetchUpcomingMoviesCommand extends Command
|
|||||||
if (!empty($newUpcomingIds)) {
|
if (!empty($newUpcomingIds)) {
|
||||||
UpcomingMovie::whereIn('id', $oldUpcomingIds)->delete();
|
UpcomingMovie::whereIn('id', $oldUpcomingIds)->delete();
|
||||||
UpcomingMovie::insert($newUpcomingIds);
|
UpcomingMovie::insert($newUpcomingIds);
|
||||||
|
echo "+";
|
||||||
}
|
}
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
|
dump($e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -86,14 +89,14 @@ class FetchUpcomingMoviesCommand extends Command
|
|||||||
return $movie;
|
return $movie;
|
||||||
}
|
}
|
||||||
|
|
||||||
$itemToFetch = ItemToFetch::where('tmdb_id', $upcomingMovie['id'])->where('type', $type)->first();
|
$itemToFetch = ItemToFetch::where('tmdb_id', $upcomingMovie['id'])->where('type', ItemToFetch::TYPE_MOVIE)->first();
|
||||||
|
|
||||||
if ($itemToFetch) {
|
if ($itemToFetch) {
|
||||||
$this->movieProcessingService->process($itemToFetch, ItemToFetchJobs::JOB_DETAILS);
|
$this->movieProcessingService->process($itemToFetch, ItemToFetchJobs::JOB_DETAILS);
|
||||||
return Movie::where('tmdb_id', $upcomingMovie['id'])->first();
|
return Movie::where('tmdb_id', $upcomingMovie['id'])->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemToFetch::create([
|
$itemToFetch = ItemToFetch::create([
|
||||||
'tmdb_id' => $upcomingMovie['id'],
|
'tmdb_id' => $upcomingMovie['id'],
|
||||||
'type' => ItemToFetch::TYPE_MOVIE,
|
'type' => ItemToFetch::TYPE_MOVIE,
|
||||||
]);
|
]);
|
||||||
@@ -107,6 +110,7 @@ class FetchUpcomingMoviesCommand extends Command
|
|||||||
'remaining_jobs' => json_encode($jobs),
|
'remaining_jobs' => json_encode($jobs),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return null;
|
$this->movieProcessingService->process($itemToFetch, ItemToFetchJobs::JOB_DETAILS);
|
||||||
|
return Movie::where('tmdb_id', $upcomingMovie['id'])->first();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,13 +88,11 @@ class FetchExportItemsCommand extends Command
|
|||||||
'type' => $type,
|
'type' => $type,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// $jobs = ItemToFetchJobs::JOBS;
|
|
||||||
// $jobs[] = "Details";
|
|
||||||
|
|
||||||
ItemToFetchJobs::create([
|
ItemToFetchJobs::create([
|
||||||
'tmdb_id' => $decodedLine['id'],
|
'tmdb_id' => $decodedLine['id'],
|
||||||
'type' => $type,
|
'type' => $type,
|
||||||
'remaining_jobs' => json_encode($jobs),
|
'remaining_jobs' => json_encode($jobs),
|
||||||
|
'jobs' => implode(',', $jobs),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Http\Controllers\Auth;
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\MediaList;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
@@ -64,11 +65,27 @@ class RegisterController extends Controller
|
|||||||
*/
|
*/
|
||||||
protected function create(array $data)
|
protected function create(array $data)
|
||||||
{
|
{
|
||||||
return User::create([
|
$user = User::create([
|
||||||
'name' => $data['name'],
|
'name' => $data['name'],
|
||||||
'slug' => Str::slug($data['name']),
|
'slug' => Str::slug($data['name']),
|
||||||
'email' => $data['email'],
|
'email' => $data['email'],
|
||||||
'password' => Hash::make($data['password']),
|
'password' => Hash::make($data['password']),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->createMediaList('Watchlist', $user);
|
||||||
|
$this->createMediaList('Collection', $user);
|
||||||
|
$this->createMediaList('Watched', $user);
|
||||||
|
$this->createMediaList('Liked', $user);
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createMediaList(string $name, $user)
|
||||||
|
{
|
||||||
|
return MediaList::create([
|
||||||
|
'name' => $name,
|
||||||
|
'slug' => Str::slug($name),
|
||||||
|
'user_id' => $user->id,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\MediaListRequest;
|
||||||
|
use App\Models\MediaList;
|
||||||
|
use App\Models\MediaListItem;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class MediaListController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$lists = MediaList::whereNotIn('name', MediaList::SPECIAL_LISTS)
|
||||||
|
->where('user_id', Auth::user()->id)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
return view('profile.lists.index', compact('lists'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show(string $userSlug, string $listSlug)
|
||||||
|
{
|
||||||
|
$user = User::where('slug', $userSlug)->first();
|
||||||
|
$list = MediaList::where('user_id', $user->id)->where('slug', $listSlug)->first();
|
||||||
|
$items = MediaListItem::where('media_list_id', $list->id)->paginate(15);
|
||||||
|
|
||||||
|
return view('profile.lists.show', compact('list', 'items'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
return view('profile.lists.create');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(MediaListRequest $request)
|
||||||
|
{
|
||||||
|
$slug = Str::slug($request->get('name'));
|
||||||
|
|
||||||
|
$mediaList = MediaList::create([
|
||||||
|
'description' => $request->get('description'),
|
||||||
|
'name' => $request->get('name'),
|
||||||
|
'slug' => $slug,
|
||||||
|
'user_id' => Auth::user()->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->route('profile.list.show', [Auth::user()->slug, $slug]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Movie;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class MovieController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$movies = Movie::orderBy('release_date', 'ASC')->paginate(60);
|
||||||
|
|
||||||
|
return view('movie.index', compact('movies'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show(string $slug)
|
||||||
|
{
|
||||||
|
$movie = Movie::with('director', 'watchProviders')
|
||||||
|
->where('slug', $slug)
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
return view('movie.show', compact('movie'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class MediaListRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => 'required|min:2|max:255',
|
||||||
|
'description' => 'sometimes|nullable',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,12 +2,20 @@
|
|||||||
|
|
||||||
namespace App\Livewire\Homepage\Movies;
|
namespace App\Livewire\Homepage\Movies;
|
||||||
|
|
||||||
|
use App\Models\Movie;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class NewMoviesComponent extends Component
|
class NewMoviesComponent extends Component
|
||||||
{
|
{
|
||||||
|
public $newMovies;
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.homepage.movies.new-movies-component');
|
return view('livewire.homepage.movies.new-movies-component');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$this->newMovies = Movie::orderBy('created_at', 'desc')->take(6)->get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,23 @@
|
|||||||
|
|
||||||
namespace App\Livewire\Homepage\Movies;
|
namespace App\Livewire\Homepage\Movies;
|
||||||
|
|
||||||
|
use App\Models\Movie;
|
||||||
|
use App\Models\UpcomingMovie;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class UpcomingMoviesComponent extends Component
|
class UpcomingMoviesComponent extends Component
|
||||||
{
|
{
|
||||||
|
public $upcomingMovies;
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.homepage.movies.upcoming-movies-component');
|
return view('livewire.homepage.movies.upcoming-movies-component');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$this->upcomingMovies = Movie::whereIn('id', UpcomingMovie::orderBy('id', 'desc')->get()->pluck('movie_id'))
|
||||||
|
->take(6)
|
||||||
|
->get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\MoviePage\Tabs;
|
||||||
|
|
||||||
|
use App\Models\Movie;
|
||||||
|
use App\Models\Person;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class Cast extends Component
|
||||||
|
{
|
||||||
|
public $movie;
|
||||||
|
public $peopleByDepartment;
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.movie-page.tabs.cast');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$this->movie = Movie::with('castList')->where('id', $this->movie->id)->first();
|
||||||
|
|
||||||
|
$peopleByDepartment = [];
|
||||||
|
|
||||||
|
foreach ($this->movie->castList as $castMember) {
|
||||||
|
if (!isset($peopleByDepartment[$castMember->pivot->known_for_department])) {
|
||||||
|
$peopleByDepartment[$castMember->pivot->known_for_department] = [];
|
||||||
|
}
|
||||||
|
$peopleByDepartment[$castMember->pivot->known_for_department][] = [
|
||||||
|
Person::find($castMember->pivot->person_id),
|
||||||
|
$castMember->pivot->character,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$this->peopleByDepartment = $peopleByDepartment;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\MoviePage\Tabs;
|
||||||
|
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class Crew extends Component
|
||||||
|
{
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.movie-page.tabs.crew');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\MoviePage\Tabs;
|
||||||
|
|
||||||
|
use App\Models\Movie;
|
||||||
|
use App\Models\MovieAlternativeTitle;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class Details extends Component
|
||||||
|
{
|
||||||
|
public $movie;
|
||||||
|
public $productionCompanies;
|
||||||
|
public $productionCountries;
|
||||||
|
public $alternativeTitles;
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.movie-page.tabs.details');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$this->alternativeTitles = MovieAlternativeTitle::where('movie_id', $this->movie->id)->get();
|
||||||
|
$movie = Movie::with('productionCompanies', 'productionCountries')->find($this->movie->id);
|
||||||
|
|
||||||
|
$this->productionCompanies = $movie->productionCompanies;
|
||||||
|
$this->productionCountries = $movie->productionCountries;
|
||||||
|
|
||||||
|
// $this->productionCompanies = Movie::
|
||||||
|
// alt titles
|
||||||
|
// prod company
|
||||||
|
// prod country
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\MoviePage\Tabs;
|
||||||
|
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class Releases extends Component
|
||||||
|
{
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.movie-page.tabs.releases');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -76,6 +76,7 @@ class ItemToFetchJobs extends Model
|
|||||||
'item_id',
|
'item_id',
|
||||||
'type',
|
'type',
|
||||||
'remaining_jobs',
|
'remaining_jobs',
|
||||||
|
'jobs',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected function casts(): array
|
protected function casts(): array
|
||||||
|
|||||||
@@ -6,6 +6,18 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
|
|
||||||
class MediaList extends Model
|
class MediaList extends Model
|
||||||
{
|
{
|
||||||
|
public const WATCHLIST = 'Watchlist';
|
||||||
|
public const COLLECTION = 'Collection';
|
||||||
|
public const WATCHED = 'Watched';
|
||||||
|
public const LIKED = 'Liked';
|
||||||
|
|
||||||
|
public const SPECIAL_LISTS = [
|
||||||
|
self::WATCHLIST,
|
||||||
|
self::COLLECTION,
|
||||||
|
self::WATCHED,
|
||||||
|
self::LIKED,
|
||||||
|
];
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'description',
|
'description',
|
||||||
'favorites_count',
|
'favorites_count',
|
||||||
@@ -15,6 +27,8 @@ class MediaList extends Model
|
|||||||
'iso_3166_1',
|
'iso_3166_1',
|
||||||
'list_type',
|
'list_type',
|
||||||
'name',
|
'name',
|
||||||
|
'slug',
|
||||||
'poster_path',
|
'poster_path',
|
||||||
|
'user_id',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-1
@@ -28,6 +28,17 @@ class Movie extends Model
|
|||||||
'vote_count',
|
'vote_count',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'release_date' => 'date'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function director()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(Person::class, 'movie_cast', 'movie_id', 'person_id')
|
||||||
|
->where('movie_cast.known_for_department', 'Directing')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
public function collections()
|
public function collections()
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(MovieCollection::class, 'movies_in_collection', 'movie_id', 'collection_id');
|
return $this->belongsToMany(MovieCollection::class, 'movies_in_collection', 'movie_id', 'collection_id');
|
||||||
@@ -40,7 +51,7 @@ class Movie extends Model
|
|||||||
|
|
||||||
public function castList()
|
public function castList()
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(Person::class, 'movie_cast', 'movie_id', 'person_id');
|
return $this->belongsToMany(Person::class, 'movie_cast', 'movie_id', 'person_id')->withPivot('known_for_department', 'character', 'order');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function crewList()
|
public function crewList()
|
||||||
@@ -72,4 +83,14 @@ class Movie extends Model
|
|||||||
{
|
{
|
||||||
return $this->belongsToMany(Video::class, 'movie_videos', 'movie_id', 'video_id');
|
return $this->belongsToMany(Video::class, 'movie_videos', 'movie_id', 'video_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function productionCompanies()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(ProductionCompany::class, 'movie_production_companies', 'movie_id', 'production_company_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function productionCountries()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(ProductionCountry::class, 'movie_production_countries', 'movie_id', 'production_country_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Pagination\Paginator;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
class AppServiceProvider extends ServiceProvider
|
class AppServiceProvider extends ServiceProvider
|
||||||
@@ -19,6 +20,6 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
*/
|
*/
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
//
|
Paginator::useBootstrapFour();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ use App\Models\MovieCollection;
|
|||||||
use App\Models\MovieRecommendation;
|
use App\Models\MovieRecommendation;
|
||||||
use App\Models\MovieSimilar;
|
use App\Models\MovieSimilar;
|
||||||
use App\Models\Person;
|
use App\Models\Person;
|
||||||
|
use App\Models\ProductionCompany;
|
||||||
|
use App\Models\ProductionCountry;
|
||||||
use App\Models\ReleaseDate;
|
use App\Models\ReleaseDate;
|
||||||
use App\Models\Translation;
|
use App\Models\Translation;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@@ -79,6 +81,14 @@ class MovieProcessingService implements ProcessingInterface
|
|||||||
$this->processMovieGenres($movieId->id, $tmdbMovie['genres']);
|
$this->processMovieGenres($movieId->id, $tmdbMovie['genres']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!empty($tmdbMovie['production_companies'])) {
|
||||||
|
$this->processProductionCompanies($movieId->id, $tmdbMovie['production_companies']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($tmdbMovie['production_countries'])) {
|
||||||
|
$this->processProductionCountries($movieId->id, $tmdbMovie['production_countries']);
|
||||||
|
}
|
||||||
|
|
||||||
$this->removeElementFromRemainingJobs($tmdbMovie['id'], 'Details');
|
$this->removeElementFromRemainingJobs($tmdbMovie['id'], 'Details');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,9 +122,11 @@ class MovieProcessingService implements ProcessingInterface
|
|||||||
|
|
||||||
private function getCredits($item)
|
private function getCredits($item)
|
||||||
{
|
{
|
||||||
|
echo "Credits for TMDBID ".$item->tmdb_id." \n";
|
||||||
$tmdbCredits = $this->moviesApi->getCredits($item->tmdb_id);
|
$tmdbCredits = $this->moviesApi->getCredits($item->tmdb_id);
|
||||||
|
|
||||||
if (empty($tmdbCredits)) {
|
if (empty($tmdbCredits)) {
|
||||||
|
echo "Empty for ".$item->tmdb_id." \n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,10 +713,16 @@ class MovieProcessingService implements ProcessingInterface
|
|||||||
{
|
{
|
||||||
$itemToFetchJobs = ItemToFetchJobs::where('tmdb_id', $tmdbId)->first();
|
$itemToFetchJobs = ItemToFetchJobs::where('tmdb_id', $tmdbId)->first();
|
||||||
|
|
||||||
$remainingJobs = $itemToFetchJobs->remaining_jobs;
|
if (!$itemToFetchJobs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$remainingJobs = $itemToFetchJobs->jobs;
|
||||||
|
|
||||||
if (is_string($remainingJobs)) {
|
if (is_string($remainingJobs)) {
|
||||||
$remainingJobs = json_decode($remainingJobs, true);
|
$remainingJobs = explode(',', $remainingJobs);
|
||||||
|
} else {
|
||||||
|
dd($remainingJobs, $tmdbId);
|
||||||
}
|
}
|
||||||
|
|
||||||
$remainingJobKey = array_search($job, $remainingJobs);
|
$remainingJobKey = array_search($job, $remainingJobs);
|
||||||
@@ -715,13 +733,14 @@ class MovieProcessingService implements ProcessingInterface
|
|||||||
$itemToFetchJobs->delete();
|
$itemToFetchJobs->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
$itemToFetchJobs->remaining_jobs = $remainingJobs;
|
// $itemToFetchJobs->remaining_jobs = $remainingJobs;
|
||||||
|
$itemToFetchJobs->jobs = implode(',', $remainingJobs);
|
||||||
$itemToFetchJobs->save();
|
$itemToFetchJobs->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processCast($movie, array $castList)
|
private function processCast($movie, array $castList)
|
||||||
{
|
{
|
||||||
if (empty($castList)) {
|
if (empty($castList) || $movie === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -753,15 +772,12 @@ class MovieProcessingService implements ProcessingInterface
|
|||||||
'place_of_birth' => $tmdbPerson['place_of_birth'],
|
'place_of_birth' => $tmdbPerson['place_of_birth'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$person = Person::create($personData);
|
$person = Person::create($personData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($movie->whereHas('castList', function ($query) use ($person) {
|
if (!$movie->whereHas('castList', function ($query) use ($person) {
|
||||||
$query->where('tmdb_id', '=', $person->tmdb_id);
|
$query->where('person_id', '=', $person->id);
|
||||||
})->exists()) {
|
})->exists()) {
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
$movie->castList()->attach($person, [
|
$movie->castList()->attach($person, [
|
||||||
'known_for_department' => $castPerson['known_for_department'],
|
'known_for_department' => $castPerson['known_for_department'],
|
||||||
'character' => $castPerson['character'],
|
'character' => $castPerson['character'],
|
||||||
@@ -825,6 +841,56 @@ class MovieProcessingService implements ProcessingInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function processProductionCompanies(int $movieId, array $productionCompanies)
|
||||||
|
{
|
||||||
|
$movie = Movie::find($movieId);
|
||||||
|
|
||||||
|
foreach ($productionCompanies as $productionCompany) {
|
||||||
|
$existingProductionCompany = ProductionCompany::where('tmdb_id', $productionCompany['id'])->first();
|
||||||
|
|
||||||
|
if (!$existingProductionCompany) {
|
||||||
|
$existingProductionCompany = ProductionCompany::create([
|
||||||
|
'tmdb_id' => $productionCompany['id'],
|
||||||
|
'logo_path' => $productionCompany['logo_path'],
|
||||||
|
'name' => $productionCompany['name'],
|
||||||
|
'origin_country' => $productionCompany['origin_country'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($movie->whereHas('productionCompanies', function ($query) use ($existingProductionCompany) {
|
||||||
|
$query->where('production_company_id', '=', $existingProductionCompany->id);
|
||||||
|
})->exists()) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
$movie->productionCompanies()->attach($existingProductionCompany);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processProductionCountries(int $movieId, array $productionCountries)
|
||||||
|
{
|
||||||
|
$movie = Movie::find($movieId);
|
||||||
|
|
||||||
|
foreach ($productionCountries as $productionCountry) {
|
||||||
|
$existingProductionCountry = ProductionCountry::where('iso_3166', $productionCountry['iso_3166_1'])->first();
|
||||||
|
|
||||||
|
if (!$existingProductionCountry) {
|
||||||
|
$existingProductionCountry = ProductionCountry::create([
|
||||||
|
'iso_3166' => $productionCountry['iso_3166_1'],
|
||||||
|
'name' => $productionCountry['name'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($movie->whereHas('productionCountries', function ($query) use ($existingProductionCountry) {
|
||||||
|
$query->where('production_country_id', '=', $existingProductionCountry->id);
|
||||||
|
})->exists()) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
$movie->productionCountries()->attach($existingProductionCountry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function createJob($tmdbId)
|
private function createJob($tmdbId)
|
||||||
{
|
{
|
||||||
$itemToFetch = ItemToFetch::where('tmdb_id', $tmdbId)->where('type', ItemToFetch::TYPE_MOVIE)->first();
|
$itemToFetch = ItemToFetch::where('tmdb_id', $tmdbId)->where('type', ItemToFetch::TYPE_MOVIE)->first();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ return new class extends Migration
|
|||||||
$table->timestamp('email_verified_at')->nullable();
|
$table->timestamp('email_verified_at')->nullable();
|
||||||
$table->string('password');
|
$table->string('password');
|
||||||
$table->boolean('is_dummy_account')->default(0);
|
$table->boolean('is_dummy_account')->default(0);
|
||||||
|
$table->string('profile_photo')->nullable();
|
||||||
$table->rememberToken();
|
$table->rememberToken();
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ return new class extends Migration
|
|||||||
$table->bigInteger('item_id')->nullable(true);
|
$table->bigInteger('item_id')->nullable(true);
|
||||||
$table->string('type')->nullable(false);
|
$table->string('type')->nullable(false);
|
||||||
$table->json('remaining_jobs')->default(null);
|
$table->json('remaining_jobs')->default(null);
|
||||||
|
$table->set('jobs', \App\Models\ItemToFetchJobs::JOBS)->default(null);
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,13 +15,16 @@ return new class extends Migration
|
|||||||
$table->id();
|
$table->id();
|
||||||
$table->text('description')->nullable();
|
$table->text('description')->nullable();
|
||||||
$table->integer('favorites_count')->default(0);
|
$table->integer('favorites_count')->default(0);
|
||||||
$table->unsignedBigInteger('tmdb_id');
|
$table->unsignedBigInteger('tmdb_id')->nullable();
|
||||||
$table->integer('item_count')->default(0);
|
$table->integer('item_count')->default(0);
|
||||||
$table->string('iso_639_1', 2);
|
$table->string('iso_639_1', 2)->nullable();
|
||||||
$table->string('iso_3166_1', 2);
|
$table->string('iso_3166_1', 2)->nullable();
|
||||||
$table->string('list_type', 15);
|
$table->string('list_type', 15)->nullable();
|
||||||
$table->string('name', 550);
|
$table->string('name', 550);
|
||||||
|
$table->string('slug', 550);
|
||||||
$table->string('poster_path', 550)->nullable();
|
$table->string('poster_path', 550)->nullable();
|
||||||
|
$table->unsignedBigInteger('user_id')->nullable();
|
||||||
|
$table->boolean('public')->default(true);
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('movie_production_companies', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('movie_id');
|
||||||
|
$table->unsignedBigInteger('production_company_id');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('movie_production_companies');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('movie_production_countries', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('movie_id');
|
||||||
|
$table->unsignedBigInteger('production_country_id');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('movie_production_countries');
|
||||||
|
}
|
||||||
|
};
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 243 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 200 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 150 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
@@ -6,3 +6,68 @@
|
|||||||
|
|
||||||
// Bootstrap
|
// Bootstrap
|
||||||
@import 'bootstrap/scss/bootstrap';
|
@import 'bootstrap/scss/bootstrap';
|
||||||
|
|
||||||
|
.dark-mode{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
body.light-mode{
|
||||||
|
background-color: #d9d9d9 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.light-mode{
|
||||||
|
header{
|
||||||
|
background: white;
|
||||||
|
padding-right: 1rem;
|
||||||
|
}
|
||||||
|
.card{
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
box-shadow: 0px 1px 2px -1px #918f8f;
|
||||||
|
.card-header{
|
||||||
|
background: white;
|
||||||
|
border-bottom: 1px dashed #d9d9d9;
|
||||||
|
}
|
||||||
|
.card-body{}
|
||||||
|
}
|
||||||
|
|
||||||
|
.movie-card{
|
||||||
|
border: 1px solid #c3c4c5;
|
||||||
|
background: #d9d9d9;
|
||||||
|
box-shadow: 0px 0px 3px 1px #ccc;
|
||||||
|
.quick-actions{
|
||||||
|
list-style: none;
|
||||||
|
padding: 2px 0px 7px 0px;
|
||||||
|
li{
|
||||||
|
float: left;
|
||||||
|
width: 33%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.movie-page{
|
||||||
|
.card{
|
||||||
|
.card-header{
|
||||||
|
h1{
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 1.7em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tagline{
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.cast-list{
|
||||||
|
.department{
|
||||||
|
.persons{
|
||||||
|
.person{
|
||||||
|
img{
|
||||||
|
max-width: 45px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,25 +1,45 @@
|
|||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="container">
|
<div class="container-fluid">
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-md-8">
|
<div class="col-md-10">
|
||||||
@livewire(App\Livewire\Homepage\Movies\LatestTrailersComponent::class)
|
|
||||||
@livewire(App\Livewire\Homepage\Movies\NewMoviesComponent::class)
|
|
||||||
@livewire(App\Livewire\Homepage\Movies\UpcomingMoviesComponent::class)
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">{{ __('Dashboard') }}</div>
|
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@if (session('status'))
|
<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 class="alert alert-success" role="alert">
|
</div>
|
||||||
{{ session('status') }}
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
|
||||||
|
|
||||||
{{ __('You are logged in!') }}
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
New movies
|
||||||
|
<div class="float-end">
|
||||||
|
<a href="">view all →</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
@livewire(App\Livewire\Homepage\Movies\NewMoviesComponent::class)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
Upcoming movies
|
||||||
|
<div class="float-end">
|
||||||
|
<a href="">view all →</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
@livewire(App\Livewire\Homepage\Movies\UpcomingMoviesComponent::class)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
latest members
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
right
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,66 +12,18 @@
|
|||||||
<!-- Fonts -->
|
<!-- Fonts -->
|
||||||
<link rel="dns-prefetch" href="//fonts.bunny.net">
|
<link rel="dns-prefetch" href="//fonts.bunny.net">
|
||||||
<link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">
|
<link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">
|
||||||
|
<script src="//code.iconify.design/1/1.0.6/iconify.min.js"></script>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Lobster&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
@vite(['resources/sass/app.scss', 'resources/js/app.js'])
|
@vite(['resources/sass/app.scss', 'resources/js/app.js'])
|
||||||
@livewireStyles
|
@livewireStyles
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="light-mode">
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
|
@include('layouts.header')
|
||||||
<div class="container">
|
|
||||||
<a class="navbar-brand" href="{{ url('/') }}">
|
|
||||||
{{ config('app.name', 'Laravel') }}
|
|
||||||
</a>
|
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
|
||||||
<!-- Left Side Of Navbar -->
|
|
||||||
<ul class="navbar-nav me-auto">
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!-- Right Side Of Navbar -->
|
|
||||||
<ul class="navbar-nav ms-auto">
|
|
||||||
<!-- Authentication Links -->
|
|
||||||
@guest
|
|
||||||
@if (Route::has('login'))
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (Route::has('register'))
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@else
|
|
||||||
<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>
|
|
||||||
{{ Auth::user()->name }}
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
|
|
||||||
<a class="dropdown-item" href="{{ route('logout') }}"
|
|
||||||
onclick="event.preventDefault();
|
|
||||||
document.getElementById('logout-form').submit();">
|
|
||||||
{{ __('Logout') }}
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
|
|
||||||
@csrf
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
@endguest
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<main class="py-4">
|
<main class="py-4">
|
||||||
@yield('content')
|
@yield('content')
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<header class="d-flex flex-wrap justify-content-center py-3 mb-4 border-bottom">
|
||||||
|
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto link-body-emphasis text-decoration-none">
|
||||||
|
<svg class="bi me-2" width="40" height="32"><use xlink:href="#bootstrap"></use></svg>
|
||||||
|
<span class="fs-4">Simple header</span>
|
||||||
|
</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">
|
||||||
|
</form>
|
||||||
|
<ul class="nav nav-pills">
|
||||||
|
<li class="nav-item"><a href="#" class="nav-link">Home</a></li>
|
||||||
|
<li class="nav-item"><a href="{{ route('movie.index') }}" class="nav-link">Movies</a></li>
|
||||||
|
<li class="nav-item"><a href="#" class="nav-link">Tv Shows</a></li>
|
||||||
|
<li class="nav-item"><a href="#" class="nav-link">Celebrities</a></li>
|
||||||
|
<li class="nav-item"><a href="#" class="nav-link">Contact</a></li>
|
||||||
|
@guest
|
||||||
|
@if (Route::has('login'))
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
|
||||||
|
</li>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if (Route::has('register'))
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link active" href="{{ route('register') }}">{{ __('Register') }}</a>
|
||||||
|
</li>
|
||||||
|
@endif
|
||||||
|
@else
|
||||||
|
<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>
|
||||||
|
{{ Auth::user()->name }}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
|
||||||
|
<a href="{{ route('profile.list.index', Auth::user()->slug) }}" class="dropdown-item">
|
||||||
|
Lists
|
||||||
|
</a>
|
||||||
|
<a class="dropdown-item" href="{{ route('logout') }}"
|
||||||
|
onclick="event.preventDefault();
|
||||||
|
document.getElementById('logout-form').submit();">
|
||||||
|
{{ __('Logout') }}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
|
||||||
|
@csrf
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
@endguest
|
||||||
|
</ul>
|
||||||
|
</header>
|
||||||
@@ -1,3 +1,32 @@
|
|||||||
<div>
|
<div>
|
||||||
{{-- If you look to others for fulfillment, you will never truly be fulfilled. --}}
|
<div class="row">
|
||||||
|
@foreach($newMovies as $newMovie)
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="movie-card">
|
||||||
|
<a href="{{ route('movie.show', $newMovie->slug) }}" title="{{ $newMovie->title }}">
|
||||||
|
<img
|
||||||
|
src="http://image.tmdb.org/t/p/w185/{{ $newMovie->poster_path }}"
|
||||||
|
alt="{{ $newMovie->title }}"
|
||||||
|
title="{{ $newMovie->title }} ({{ $newMovie->release_date->format('Y') }})"
|
||||||
|
class="img img-fluid"
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
<ul class="quick-actions">
|
||||||
|
<li>
|
||||||
|
{{-- <span class="iconify" data-icon="mdi-check-bold"></span>--}}
|
||||||
|
<a href=""><span class="iconify" data-icon="mdi-check-outline"></span></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href=""><span class="iconify" data-icon="mdi-image-multiple"></span></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="">
|
||||||
|
{{ $newMovie->vote_average }} <span class="iconify" data-icon="mdi-star"></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,3 +1,32 @@
|
|||||||
<div>
|
<div>
|
||||||
{{-- In work, do what you enjoy. --}}
|
<div class="row">
|
||||||
|
@foreach($upcomingMovies as $upcomingMovie)
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="movie-card">
|
||||||
|
<a href="{{ route('movie.show', $upcomingMovie->slug) }}" title="{{ $upcomingMovie->title }}">
|
||||||
|
<img
|
||||||
|
src="http://image.tmdb.org/t/p/w154/{{ $upcomingMovie->poster_path }}"
|
||||||
|
alt="{{ $upcomingMovie->title }}"
|
||||||
|
title="{{ $upcomingMovie->title }} ({{ $upcomingMovie->release_date->format('Y') }})"
|
||||||
|
class="img img-fluid"
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
{{-- <span class="iconify" data-icon="mdi-check-bold"></span>--}}
|
||||||
|
<a href=""><span class="iconify" data-icon="mdi-check-outline"></span></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href=""><span class="iconify" data-icon="mdi-image-multiple"></span></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="">
|
||||||
|
{{ $upcomingMovie->vote_average }} <span class="iconify" data-icon="mdi-star"></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<div>
|
||||||
|
<div class="cast-list">
|
||||||
|
@foreach($peopleByDepartment as $department => $personInfo)
|
||||||
|
<div class="department">
|
||||||
|
{{ $department }}
|
||||||
|
<hr>
|
||||||
|
<div class="persons">
|
||||||
|
<div class="row">
|
||||||
|
@foreach($personInfo as [$person, $character])
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="person">
|
||||||
|
@if($person->profile_path == null)
|
||||||
|
@if($person->gender == 2)
|
||||||
|
<img src="/img/no_avatar_male.png" alt="" class="img img-fluid float-start">
|
||||||
|
@else
|
||||||
|
<img src="/img/no_avatar_female.png" alt="" class="img img-fluid float-start">
|
||||||
|
@endif
|
||||||
|
@else
|
||||||
|
<img src="http://image.tmdb.org/t/p/w185/{{ $person->profile_path }}" alt="" class="img img-fluid float-start">
|
||||||
|
@endif
|
||||||
|
<a href="">{{ $person->name }}</a> <br>
|
||||||
|
{{ $character }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<div>
|
||||||
|
{{-- A good traveler has no fixed plans and is not intent upon arriving. --}}
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<div>
|
||||||
|
<div class="element">
|
||||||
|
<div class="title">
|
||||||
|
Studio
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="element">
|
||||||
|
<div class="title">
|
||||||
|
Country
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
@foreach($productionCountries as $productionCountry)
|
||||||
|
{{ $productionCountry->name }}
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="element">
|
||||||
|
<div class="title">
|
||||||
|
Language
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
{{ $movie->original_language }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="element">
|
||||||
|
<div class="title">
|
||||||
|
Alternative titles
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<ul>
|
||||||
|
@foreach($alternativeTitles as $alternativeTitle)
|
||||||
|
<li>
|
||||||
|
{{ $alternativeTitle->title }}
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<div>
|
||||||
|
{{-- Success is as dangerous as failure. --}}
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container-fluid movie-page">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Movies</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
@foreach($movies as $movie)
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="movie-card">
|
||||||
|
<a href="{{ route('movie.show', $movie->slug) }}" title="{{ $movie->title }}">
|
||||||
|
<img
|
||||||
|
src="http://image.tmdb.org/t/p/w185/{{ $movie->poster_path }}"
|
||||||
|
alt="{{ $movie->title }}"
|
||||||
|
title="{{ $movie->title }} @if($movie->release_date) ({{ $movie->release_date->format('Y') }})" @endif
|
||||||
|
class="img img-fluid"
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
<ul class="quick-actions">
|
||||||
|
<li>
|
||||||
|
{{-- <span class="iconify" data-icon="mdi-check-bold"></span>--}}
|
||||||
|
<a href=""><span class="iconify" data-icon="mdi-check-outline"></span></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href=""><span class="iconify" data-icon="mdi-image-multiple"></span></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="">
|
||||||
|
{{ $movie->vote_average }} <span class="iconify" data-icon="mdi-star"></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ $movies->links() }}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="card">
|
||||||
|
menu
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container-fluid movie-page">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h1 class="movie-title">{{ $movie->title }}</h1> (<a href="">{{ $movie->release_date->format('Y') }}</a>)
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<img
|
||||||
|
src="http://image.tmdb.org/t/p/w185/{{ $movie->poster_path }}"
|
||||||
|
alt="{{ $movie->title }}"
|
||||||
|
title="{{ $movie->title }} ({{ $movie->release_date->format('Y') }})"
|
||||||
|
class="img img-fluid"
|
||||||
|
>
|
||||||
|
|
||||||
|
<div class="watch-provider">
|
||||||
|
@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 }}">
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
|
||||||
|
view trailer /
|
||||||
|
external ids
|
||||||
|
</div>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<span>
|
||||||
|
Directed by
|
||||||
|
@foreach($movie->director as $director)
|
||||||
|
<a href="">{{ $director->name }}</a>@if(!$loop->last), @endif
|
||||||
|
@endforeach
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<div class="tagline">{{ $movie->tagline }}</div>
|
||||||
|
<div class="overview">{{ $movie->overview }}</div>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
||||||
|
<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>
|
||||||
|
</li>
|
||||||
|
<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>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#contact-tab-pane" type="button" role="tab" aria-controls="contact-tab-pane" aria-selected="false">Crew</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#contact-tab-pane" type="button" role="tab" aria-controls="contact-tab-pane" aria-selected="false">Releases</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="tab-content" id="myTabContent">
|
||||||
|
<div class="tab-pane fade show active" id="details-tab-pane" role="tabpanel" aria-labelledby="details-tab" tabindex="0">
|
||||||
|
@livewire(App\Livewire\MoviePage\Tabs\Details::class, ['movie' => $movie])
|
||||||
|
</div>
|
||||||
|
<div class="tab-pane fade" id="cast-tab-pane" role="tabpanel" aria-labelledby="cast-tab" tabindex="0">
|
||||||
|
@livewire(App\Livewire\MoviePage\Tabs\Cast::class, ['movie' => $movie])
|
||||||
|
</div>
|
||||||
|
<div class="tab-pane fade" id="contact-tab-pane" role="tabpanel" aria-labelledby="contact-tab" tabindex="0">...</div>
|
||||||
|
<div class="tab-pane fade" id="disabled-tab-pane" role="tabpanel" aria-labelledby="disabled-tab" tabindex="0">...</div>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Similar</div>
|
||||||
|
<div class="card-body"></div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Recommended</div>
|
||||||
|
<div class="card-body"></div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Write review</div>
|
||||||
|
<div class="card-body"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="card">
|
||||||
|
<div class="user-actions">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href=""><span class="iconify" data-icon="mdi-eye-check-outline"></span> Mark as seen</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href=""><span class="iconify" data-icon="mdi-thumb-up-outline"></span> Like</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href=""><span class="iconify" data-icon="mdi-playlist-check"></span> add to list</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<hr>
|
||||||
|
rate
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
@extends('profile.profile')
|
||||||
|
|
||||||
|
@section('page_content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<form action="{{ route('profile.list.store', auth()->user()->slug) }}" method="POST">
|
||||||
|
@csrf
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">New list</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="">Name</label>
|
||||||
|
<input type="text" class="form-control" name="name">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="">Description</label>
|
||||||
|
<textarea name="description" id="" cols="30" rows="10" class="form-control"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for=""><input type="checkbox" checked> Public</label>
|
||||||
|
</div>
|
||||||
|
<div class="float-end">
|
||||||
|
<input type="submit" class="btn btn-primary" value="Save!">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
@extends('profile.profile')
|
||||||
|
|
||||||
|
@section('page_content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
@if($lists->count())
|
||||||
|
lists
|
||||||
|
@else
|
||||||
|
<div class="medium-info-box">
|
||||||
|
No lists yet. <a href="{{ route('profile.list.create', auth()->user()->slug) }}">Start one?</a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="profile-nav">
|
||||||
|
avatar/name/etc <br>
|
||||||
|
<div class="menu-nav">
|
||||||
|
<ul class="list-inline">
|
||||||
|
<li class="float-start"><a href="">Profile</a></li>
|
||||||
|
<li class="float-start"><a href="">History</a></li>
|
||||||
|
<li class="float-start"><a href="">Watchlist</a></li>
|
||||||
|
<li class="float-start"><a href="">Collection</a></li>
|
||||||
|
<li class="float-start"><a href="">Ratings</a></li>
|
||||||
|
<li class="float-start"><a href="">Reviews</a></li>
|
||||||
|
<li class="float-start"><a href="">Likes</a></li>
|
||||||
|
<li class="float-start"><a href="">Network</a></li>
|
||||||
|
<li class="float-start"><a href="">Stats</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@yield('page_content')
|
||||||
|
@endsection
|
||||||
@@ -9,3 +9,17 @@ use Illuminate\Support\Facades\Route;
|
|||||||
Auth::routes();
|
Auth::routes();
|
||||||
|
|
||||||
Route::get('/', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
|
Route::get('/', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
|
||||||
|
|
||||||
|
|
||||||
|
Route::prefix('movies')->group(function () {
|
||||||
|
Route::get('/', [\App\Http\Controllers\MovieController::class, 'index'])->name('movie.index');
|
||||||
|
Route::get('/{slug}', [\App\Http\Controllers\MovieController::class, 'show'])->name('movie.show');
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::prefix('profile/{slug}')->group(function () {
|
||||||
|
Route::get('/lists', [\App\Http\Controllers\MediaListController::class, 'index'])->name('profile.list.index');
|
||||||
|
Route::get('/lists/create', [\App\Http\Controllers\MediaListController::class, 'create'])->name('profile.list.create');
|
||||||
|
Route::post('/lists/store', [\App\Http\Controllers\MediaListController::class, 'store'])->name('profile.list.store');
|
||||||
|
Route::get('/lists/view/{slug}', [\App\Http\Controllers\MediaListController::class, 'show'])->name('profile.list.show');
|
||||||
|
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user