Compare commits

..

3 commits

Author SHA1 Message Date
97ad0421e3 theme update
Some checks failed
linter / quality (pull_request) Has been cancelled
tests / ci (pull_request) Has been cancelled
2025-12-31 00:11:09 -06:00
c31524977a added permissions to settings 2025-12-30 23:57:45 -06:00
83f7073b18 updated permissions 2025-12-30 21:15:42 -06:00
32 changed files with 1515 additions and 914 deletions

4
.gitignore vendored
View file

@ -21,3 +21,7 @@ yarn-error.log
/.nova /.nova
/.vscode /.vscode
/.zed /.zed
/storage/debugbar
sail
docker

View file

@ -4,6 +4,7 @@ namespace App\Livewire;
use App\Models\Movie; use App\Models\Movie;
use Livewire\Component; use Livewire\Component;
use function Laravel\Prompts\select;
class MovieDetailsPanel extends Component class MovieDetailsPanel extends Component
{ {
@ -14,7 +15,19 @@ class MovieDetailsPanel extends Component
public function openPanel(int $movieId): void public function openPanel(int $movieId): void
{ {
$this->selectedMovie = Movie::find($movieId); $this->selectedMovie = Movie::where('id', $movieId)
->select(
'id',
'title',
'plot',
'poster',
'director',
'year',
'actors',
'genre',
'mpaa_rating'
)
->first();
$this->showDetails = true; $this->showDetails = true;
} }

View file

@ -33,7 +33,7 @@ class MovieList extends Component
public function getList() public function getList()
{ {
$list = MovieListModel::with('movies') $list = MovieListModel::with('movies:id,poster')
->find($this->id); ->find($this->id);
if ($list) { if ($list) {
@ -45,6 +45,12 @@ class MovieList extends Component
} }
} }
public function deleteList(): void
{
$this->list->delete();
$this->redirectRoute('lists');
}
public function filterMovies(): void public function filterMovies(): void
{ {
$this->filteredMovies = collect($this->list->movies) $this->filteredMovies = collect($this->list->movies)
@ -62,7 +68,7 @@ class MovieList extends Component
$this->getList(); $this->getList();
} }
public function updatedSettingsForm(): void public function updatedSettingsFormIsPublic(): void
{ {
$this->settingsForm->save(); $this->settingsForm->save();
} }

View file

@ -6,11 +6,33 @@ use App\Livewire\Forms\MovieListForm;
use App\Models\MovieList; use App\Models\MovieList;
use Exception; use Exception;
use Livewire\Component; use Livewire\Component;
use function Laravel\Prompts\select;
class MovieLists extends Component class MovieLists extends Component
{ {
public MovieListForm $form; public MovieListForm $form;
public $lists = []; public $lists;
public $sharedLists;
public function mount()
{
$this->lists = collect();
$this->sharedLists = collect();
$this->getLists();
}
public function getLists()
{
$user = auth()->user();
if ($user) {
$this->lists = MovieList::where('user_id', $user->id)
->select("name", "id", "is_public")
->get();
} else {
$this->redirectRoute('login');
}
}
public function addList(): void public function addList(): void
{ {
@ -32,14 +54,8 @@ class MovieLists extends Component
$this->form->reset(); $this->form->reset();
} }
public function getLists()
{
$this->lists = MovieList::all();
}
public function render() public function render()
{ {
$this->getLists();
return view('livewire.lists'); return view('livewire.lists');
} }
} }

View file

@ -3,6 +3,7 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
@ -18,4 +19,14 @@ class MovieList extends Model
{ {
return $this->belongsToMany(Movie::class); return $this->belongsToMany(Movie::class);
} }
public function owner(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
public function sharedUsers(): BelongsToMany
{
return $this->belongsToMany(User::class)->withPivot('permission')->withTimestamps();
}
} }

10
app/Models/Role.php Normal file
View file

@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
//
}

View file

@ -2,13 +2,13 @@
namespace App\Models; namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Database\Factories\UserFactory; use Database\Factories\UserFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Str; use Illuminate\Support\Facades\Context;
use Laravel\Fortify\TwoFactorAuthenticatable; use Laravel\Fortify\TwoFactorAuthenticatable;
class User extends Authenticatable class User extends Authenticatable
@ -44,6 +44,25 @@ class User extends Authenticatable
return $this->hasOne(UserProfile::class); return $this->hasOne(UserProfile::class);
} }
public function roles(): BelongsToMany
{
return $this->belongsToMany(Role::class);
}
public function hasRole(string $role): bool
{
if (Context::hasHidden('roles')) {
return in_array(strtolower($role), Context::getHidden('roles'));
}
return $this->roles->contains('name', strtolower($role));
}
public function sharedLists(): BelongsToMany
{
return $this->belongsToMany(MovieList::class)->withPivot("permission")->withTimestamps();
}
/** /**
* Get the user's initials * Get the user's initials
*/ */

View file

@ -0,0 +1,68 @@
<?php
namespace App\Policies;
use App\Models\MovieList;
use App\Models\User;
class MovieListPolicy
{
/**
* Create a new policy instance.
*/
public function __construct()
{
//
}
/**
* Determine if the user can view the movie list.
*
* Grants access to the list owner and any user who has been
* granted view, edit, or admin permission.
*/
public function view(User $user, MovieList $movieList): bool
{
if ($movieList->user_id === $user->id || $movieList->is_public === true) {
return true;
}
return $movieList->sharedUsers()->where("user_id", $user->id)->exists();
}
/**
* Determine if the user can update the movie list.
*
* Grants access to the list owner and any user who has been
* granted edit or admin permission.
*/
public function update(User $user, MovieList $movieList): bool
{
if ($movieList->user_id === $user->id) {
return true;
}
return $movieList->sharedUsers()
->where("user_id", $user->id)
->whereIn("permission", ["edit", "admin"])
->exists();
}
/**
* Determine if the user can delete the movie list.
*
* Grants access to the list owner and any user who has been
* granted admin permission.
*/
public function delete(User $user, MovieList $movieList): bool
{
if ($movieList->user_id === $user->id) {
return true;
}
return $movieList->sharedUsers()
->where("user_id", $user->id)
->where("permission", "admin")
->exists();
}
}

View file

@ -4,6 +4,7 @@ namespace App\Providers;
use App\Models\Interfaces\MovieDbInterface; use App\Models\Interfaces\MovieDbInterface;
use App\Services\OmdbService; use App\Services\OmdbService;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\URL; use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
@ -15,6 +16,14 @@ class AppServiceProvider extends ServiceProvider
public function register(): void public function register(): void
{ {
$this->app->bind(MovieDbInterface::class, OmdbService::class); $this->app->bind(MovieDbInterface::class, OmdbService::class);
Blade::directive('role', function ($role) {
return "<?php if(auth()->user()->hasRole({$role})) : ?>";
});
Blade::directive('endrole', function ($role) {
return "<?php endif; ?>";
});
} }
/** /**

View file

@ -19,6 +19,7 @@
"symfony/mailgun-mailer": "^7.3" "symfony/mailgun-mailer": "^7.3"
}, },
"require-dev": { "require-dev": {
"barryvdh/laravel-debugbar": "^3.16",
"fakerphp/faker": "^1.23", "fakerphp/faker": "^1.23",
"laravel/pail": "^1.2.2", "laravel/pail": "^1.2.2",
"laravel/pint": "^1.24", "laravel/pint": "^1.24",

1925
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -147,11 +147,11 @@ return [
// Features::registration(), // Features::registration(),
Features::resetPasswords(), Features::resetPasswords(),
Features::emailVerification(), Features::emailVerification(),
Features::twoFactorAuthentication([ // Features::twoFactorAuthentication([
'confirm' => true, // 'confirm' => true,
'confirmPassword' => true, // 'confirmPassword' => true,
// 'window' => 0, // // 'window' => 0,
]), // ]),
], ],
]; ];

View file

@ -4,8 +4,7 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
return new class extends Migration return new class extends Migration {
{
/** /**
* Run the migrations. * Run the migrations.
*/ */
@ -15,7 +14,7 @@ return new class extends Migration
$table->id(); $table->id();
$table->string('name'); $table->string('name');
$table->boolean('is_public')->default(false); $table->boolean('is_public')->default(false);
$table->foreignId('user_id')->constrained()->cascadeOnDelete(); $table->foreignId('user_id')->constrained()->cascadeOnDelete()->index();
$table->timestamps(); $table->timestamps();
}); });
} }

View file

@ -0,0 +1,31 @@
<?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_list_user', function (Blueprint $table) {
$table->id();
$table->foreignId("movie_list_id")->constrained()->cascadeOnDelete();
$table->foreignId("user_id")->constrained()->cascadeOnDelete();
$table->enum("permission", ["view", "edit", "admin"]);
$table->unique(["movie_list_id", "user_id"]);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('movie_list_user');
}
};

View file

@ -3,6 +3,7 @@
namespace Database\Seeders; namespace Database\Seeders;
use App\Models\User; use App\Models\User;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents; // use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
@ -16,7 +17,7 @@ class DatabaseSeeder extends Seeder
// User::factory(10)->create(); // User::factory(10)->create();
User::factory()->create([ User::factory()->create([
'name' => 'Test User', 'username' => 'testuser',
'email' => 'test@example.com', 'email' => 'test@example.com',
]); ]);
} }

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="{{ str_replace('_','-',app()->getLocale()) }}"> <html lang="{{ str_replace('_','-',app()->getLocale()) }}">
<x-head/> <x-head/>
<body class="bg-blue-600"> <body class="bg-gradient-to-br from-blue-900 via-blue-700 to-indigo-900 min-h-screen">
<div class="container mx-auto text-white"> <div class="container mx-auto text-white">
<x-header/> <x-header/>
{{ $slot }} {{ $slot }}

View file

@ -1,5 +1,5 @@
@props(['movie']) @props(['movie'])
<div class="flex flex-col bg-gray-500 w-full h-full cursor-pointer hover:bg-gray-600 transition-colors" <div class="flex flex-col bg-gray-500 w-full h-full cursor-pointer rounded-lg overflow-hidden shadow-lg hover:shadow-2xl hover:scale-105 transition-all duration-300"
wire:click="$dispatch('openMovieDetails', { movieId: {{ $movie->id }} })"> wire:click="$dispatch('openMovieDetails', { movieId: {{ $movie->id }} })">
<img class="w-full h-full object-cover" src="{{$movie->poster}}" alt="{{$movie->title}}"> <img class="w-full h-full object-cover" src="{{$movie->poster}}" alt="{{$movie->title}}">
</div> </div>

View file

@ -1,3 +1,3 @@
<div {{ $attributes->merge(['class' => 'bg-gray-700 p-5 flex flex-col gap-5 items-center rounded']) }}> <div {{ $attributes->merge(['class' => 'bg-gray-800/90 backdrop-blur-sm p-6 flex flex-col gap-5 items-center rounded-xl shadow-xl border border-gray-700/50']) }}>
{{ $slot }} {{ $slot }}
</div> </div>

View file

@ -3,7 +3,7 @@
style="mask: radial-gradient(circle at left, transparent 10px, black 11px) top left / 51% 100% no-repeat, style="mask: radial-gradient(circle at left, transparent 10px, black 11px) top left / 51% 100% no-repeat,
radial-gradient(circle at right, transparent 10px, black 11px) top right / 51% 100% no-repeat;"> radial-gradient(circle at right, transparent 10px, black 11px) top right / 51% 100% no-repeat;">
<div class="p-2 border-2 border-amber-200 m-2"> <div class="p-2 border-2 border-amber-200 m-2">
<h1 class="font-bold font-arial text-2xl text-amber-200">Movie Night</h1> <a href="/"><h1 class="font-bold font-arial text-2xl text-amber-200">Movie Night</h1></a>
</div> </div>
</div> </div>

View file

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Unauthorized'))
@section('code', '401')
@section('message', __('Unauthorized'))

View file

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Payment Required'))
@section('code', '402')
@section('message', __('Payment Required'))

View file

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Forbidden'))
@section('code', '403')
@section('message', __($exception->getMessage() ?: 'Forbidden'))

View file

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Not Found'))
@section('code', '404')
@section('message', __('Not Found'))

View file

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Page Expired'))
@section('code', '419')
@section('message', __('Page Expired'))

View file

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Too Many Requests'))
@section('code', '429')
@section('message', __('Too Many Requests'))

View file

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Server Error'))
@section('code', '500')
@section('message', __('Server Error'))

View file

@ -0,0 +1,5 @@
@extends('errors::minimal')
@section('title', __('Service Unavailable'))
@section('code', '503')
@section('message', __('Service Unavailable'))

View file

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>@yield('title')</title>
<!-- Styles -->
<style>
html, body {
background-color: #fff;
color: #636b6f;
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-weight: 100;
height: 100vh;
margin: 0;
}
.full-height {
height: 100vh;
}
.flex-center {
align-items: center;
display: flex;
justify-content: center;
}
.position-ref {
position: relative;
}
.content {
text-align: center;
}
.title {
font-size: 36px;
padding: 20px;
}
</style>
</head>
<body>
<div class="flex-center position-ref full-height">
<div class="content">
<div class="title">
@yield('message')
</div>
</div>
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

View file

@ -24,17 +24,44 @@
</form> </form>
</div> </div>
<ul class="w-full flex flex-col gap-5"> <div class="w-full flex flex-col gap-5">
<h2 class="text-2xl font-bold">Your Lists</h2>
@if(!$lists->isEmpty())
<ul class="w-full flex flex-col gap-3">
@foreach($lists as $list) @foreach($lists as $list)
<li class="flex py-5 justify-between text-center"> <li class="flex justify-between items-center p-4 bg-gray-700/50 rounded-lg hover:bg-gray-600/50 transition-colors">
<a class="font-bold text-2xl" href="/lists/{{$list->id}}" wire:navigate>{{$list->name}}</a> <a class="text-xl hover:text-amber-200 transition-colors" href="/lists/{{$list->id}}" wire:navigate>{{$list->name}}</a>
@if((bool)$list->is_public === true) @if((bool)$list->is_public === true)
<i class="fa fa-earth" title="Public" aria-label="Public"></i> <i class="fa fa-earth text-green-400" title="Public" aria-label="Public"></i>
@else @else
<i class="fa fa-lock" title="Private" aria-label="Private"></i> <i class="fa fa-lock text-gray-400" title="Private" aria-label="Private"></i>
@endif @endif
</li> </li>
@endforeach @endforeach
</ul> </ul>
@else
<span class="text-gray-400">No lists found.</span>
@endif
</div>
<div class="w-full flex flex-col gap-5">
<h2 class="text-2xl font-bold">Shared With You</h2>
@if(!$sharedLists->isEmpty())
<ul class="w-full flex flex-col gap-3">
@foreach($sharedLists as $list)
<li class="flex justify-between items-center p-4 bg-gray-700/50 rounded-lg hover:bg-gray-600/50 transition-colors">
<a class="text-xl hover:text-amber-200 transition-colors" href="/lists/{{$list->id}}" wire:navigate>{{$list->name}}</a>
@if((bool)$list->is_public === true)
<i class="fa fa-earth text-green-400" title="Public" aria-label="Public"></i>
@else
<i class="fa fa-lock text-gray-400" title="Private" aria-label="Private"></i>
@endif
</li>
@endforeach
</ul>
@else
<span class="text-gray-400">No lists found.</span>
@endif
</div>
</x-ui.card> </x-ui.card>
</div> </div>

View file

@ -1,18 +1,22 @@
<div class=" text-white pt-10 flex flex-col gap-5"> <div class=" text-white pt-10 flex flex-col gap-5">
<div class="flex flex-row justify-between items-center mx-2 sm:mx-0"> <div class="flex flex-row justify-between items-center mx-2 sm:mx-0">
<h1 class="text-2xl sm:text-3xl font-bold">{{$list->name}}</h1> <h1 class="text-2xl sm:text-3xl font-bold">{{$list->name}}</h1>
@can('delete', $list)
<button type="button" wire:click="toggleSettings" <button type="button" wire:click="toggleSettings"
class="hover:bg-blue-600 cursor-pointer text-white px-4 py-2 rounded"> class="hover:bg-blue-600 cursor-pointer text-white px-4 py-2 rounded">
<i class="fas fa-cog text-2xl"></i> <i class="fas fa-cog text-2xl"></i>
</button> </button>
@endcan
</div> </div>
<x-ui.card class="overflow-hidden min-h-screen"> <div>
<div class="absolute">
<livewire:search-panel :list-id="$list->id"/> <livewire:search-panel :list-id="$list->id"/>
<livewire:movie-details-panel/> <livewire:movie-details-panel/>
</div> </div>
<x-ui.card class="overflow-hidden min-h-screen">
<div class="relative w-full overflow-hidden"> <div class="relative w-full overflow-hidden">
<div class="flex transition-transform duration-300 ease-in-out" <div class="flex transition-transform duration-300 ease-in-out"
style="transform: translateX({{ $showSettings ? '-100%' : '0' }})"> style="transform: translateX({{ $showSettings ? '-100%' : '0' }})">
@ -21,21 +25,24 @@
<div class="w-full flex-shrink-0 flex flex-col gap-5"> <div class="w-full flex-shrink-0 flex flex-col gap-5">
<div class="flex flex-col-reverse sm:flex-row gap-5 sm:gap-0 justify-between w-full"> <div class="flex flex-col-reverse sm:flex-row gap-5 sm:gap-0 justify-between w-full">
<div> <div>
<input class="flex bg-white p-2 rounded sm:w-100" type="text" placeholder="Filter movies" <input class="flex bg-white p-2 rounded w-full sm:w-100" type="text"
placeholder="Filter movies"
wire:model.live="filterText" wire:model.live="filterText"
wire:keyup="filterMovies"/> wire:keyup="filterMovies"/>
</div> </div>
@can("update", $list)
<hr class="my-2 sm:my-0"/> <hr class="my-2 sm:my-0"/>
<button wire:click="$dispatch('openSearch')" <button wire:click="$dispatch('openSearch')"
class="bg-green-500 text-white p-2 rounded"> class="bg-green-500 text-white p-2 rounded">
Add Movie Add Movie
</button> </button>
@endcan
</div> </div>
@if(!$filteredMovies->isEmpty()) @if(!$filteredMovies->isEmpty())
<ul class="grid grid-cols-2 sm:grid-cols-4 gap-5"> <ul class="grid grid-cols-2 sm:grid-cols-4 gap-5">
@foreach ($filteredMovies as $movie) @foreach ($filteredMovies as $movie)
<li class="bg-gray-200"> <li>
<x-movie :movie="$movie"/> <x-movie :movie="$movie"/>
</li> </li>
@endforeach @endforeach
@ -56,23 +63,69 @@
<h2 class="text-xl font-semibold">Settings</h2> <h2 class="text-xl font-semibold">Settings</h2>
</div> </div>
<div class="flex flex-col gap-2 w-full p-5"> <div class="flex flex-col gap-2 w-full p-5 bg-gray-700">
<label for="list-name">List Name</label> <label for="list-name" class="font-bold">List Name</label>
<div class="flex flex-row"> <div class="flex flex-row">
<input type="text" wire:model.live="settingsForm.name" id="list-name" <input type="text" wire:model.live="settingsForm.name" id="list-name"
class="w-full p-2 rounded rounded-r-none bg-white"/> class="w-full p-2 rounded rounded-r-none bg-white"/>
<button class="bg-green-400 p-2 rounded-r" type="submit" wire:click="saveSettings">Save <button class="bg-green-500 p-2 rounded-r" type="submit" wire:click="saveSettings">Save
</button> </button>
</div> </div>
</div> </div>
<div <div
class="flex items-center justify-between bg-gray-700 hover:bg-gray-500 hover:opacity-85 p-5 rounded"> class="flex items-center justify-between bg-gray-700 hover:opacity-85 p-5 rounded">
<label for="is_public" class="text-white cursor-pointer">Make list public</label> <label for="is_public" class="text-white font-bold cursor-pointer">Make list public</label>
<input type="checkbox" <input type="checkbox"
id="is_public" id="is_public"
wire:model.live="settingsForm.isPublic" wire:model.live="settingsForm.isPublic"
class="w-5 h-5 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"> class="w-5 h-5 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500">
</div> </div>
<div class="p-5 flex flex-col gap-5 bg-gray-700 rounded">
<span class="font-bold">Collaborators</span>
<details class="hover:cursor-pointer bg-gray-600 p-5 rounded">
<ul class="flex flex-col gap-2 py-2">
<li><span class="font-bold">Viewer</span>: Can view the list, but cannot make any changes.</li>
<li><span class="font-bold">Editor</span>: Can add/remove movies from the list.</li>
<li><span class="font-bold">Admin</span>: Can make any changes to the list including deleting it. Can also invite other users to collaborate on this list.</li>
</ul>
</details>
<ul>
<li class="flex justify-between ">
<span>Bob</span>
<select>
<option value="view">Viewer</option>
<option value="edit">Editor</option>
<option value="admin">Admin</option>
</select>
</li>
</ul>
</div>
<div class="p-5 flex flex-col gap-3 bg-gray-700 rounded">
<span class="font-bold">Invite collaborators</span>
<span class="hover:cursor-pointer">Enter a comma separated list of emails.</span>
<textarea class="bg-white rounded text-black p-2" placeholder="user1@example.com, user2@example.com, user3@example.com"></textarea>
<button type="button" class="p-2 rounded bg-green-500">Send Invites</button>
</div>
@can('delete', $list)
<div
class="flex items-center justify-between bg-gray-700 p-5 rounded">
<label for="delete_list" class="text-white cursor-pointer">Delete List</label>
<button name="delete_list"
type="button"
class="bg-red-500 p-2 rounded font-bold"
wire:click="deleteList"
wire:confirm="Are you sure you want to delete this list?"
>
Delete List
</button>
</div>
@endcan
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,5 +0,0 @@
<x-layouts.app>
<div class="text-white text-2xl">
<livewire:movie-lists/>
</div>
</x-layouts.app>