Add user roles system
This commit is contained in:
11
app/Enums/UserRole.php
Normal file
11
app/Enums/UserRole.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
enum UserRole: string
|
||||||
|
{
|
||||||
|
case ADMINISTRATOR = 'admin';
|
||||||
|
case MODERATOR = 'moderator';
|
||||||
|
case SUPPORTER = 'supporter';
|
||||||
|
case BANNED = 'banned';
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use App\Enums\UserRole;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -31,11 +32,11 @@ class UserController extends Controller
|
|||||||
|
|
||||||
switch ($validated['action']) {
|
switch ($validated['action']) {
|
||||||
case 'ban':
|
case 'ban':
|
||||||
$user->update(['is_banned' => 1]);
|
$user->addRole(UserRole::BANNED);
|
||||||
alert()->success('Banned', 'User has been banned.');
|
alert()->success('Banned', 'User has been banned.');
|
||||||
break;
|
break;
|
||||||
case 'unban':
|
case 'unban':
|
||||||
$user->update(['is_banned' => 0]);
|
$user->removeRole(UserRole::BANNED);
|
||||||
alert()->success('Unbanned', 'User has been unbanned.');
|
alert()->success('Unbanned', 'User has been unbanned.');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Auth;
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
|
use App\Enums\UserRole;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
@@ -88,10 +89,7 @@ class DiscordAuthController extends Controller
|
|||||||
|
|
||||||
// User is not in the guild
|
// User is not in the guild
|
||||||
if ($response->status() === 404) {
|
if ($response->status() === 404) {
|
||||||
$user->update([
|
$user->removeRole(UserRole::SUPPORTER);
|
||||||
'is_patreon' => false,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,21 +108,15 @@ class DiscordAuthController extends Controller
|
|||||||
$discordRoles = $response->json('roles', []);
|
$discordRoles = $response->json('roles', []);
|
||||||
$patreonRoles = config('discord.patreon_roles', []);
|
$patreonRoles = config('discord.patreon_roles', []);
|
||||||
|
|
||||||
$isPatreon = false;
|
// If intersect of array is empty, then the user doesn't have the role
|
||||||
foreach($patreonRoles as $patreonRole)
|
$hasSupporterRole = !empty(array_intersect($discordRoles, $patreonRoles));
|
||||||
{
|
|
||||||
if (in_array($patreonRole, $discordRoles, true)) {
|
if (!$hasSupporterRole) {
|
||||||
$isPatreon = true;
|
// Remove role if not found
|
||||||
break;
|
$user->removeRole(UserRole::SUPPORTER);
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only update if something actually changed
|
$user->addRole(UserRole::SUPPORTER);
|
||||||
if ($user->is_patreon !== $isPatreon) {
|
|
||||||
$user->update([
|
|
||||||
'is_patreon' => $isPatreon,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ class Kernel extends HttpKernel
|
|||||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||||
'auth.admin' => \App\Http\Middleware\IsAdmin::class,
|
'auth.admin' => \App\Http\Middleware\IsAdmin::class,
|
||||||
|
'auth.moderator' => \App\Http\Middleware\IsModerator::class,
|
||||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||||
|
|||||||
@@ -1,28 +1,14 @@
|
|||||||
<?php namespace app\Http\Middleware;
|
<?php namespace app\Http\Middleware;
|
||||||
|
|
||||||
|
use App\Enums\UserRole;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Contracts\Auth\Guard;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
class IsAdmin {
|
class IsAdmin {
|
||||||
|
|
||||||
/**
|
|
||||||
* The Guard implementation.
|
|
||||||
*
|
|
||||||
* @var Guard
|
|
||||||
*/
|
|
||||||
protected $auth;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new filter instance.
|
|
||||||
*
|
|
||||||
* @param Guard $auth
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct(Guard $auth)
|
|
||||||
{
|
|
||||||
$this->auth = $auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle an incoming request.
|
* Handle an incoming request.
|
||||||
*
|
*
|
||||||
@@ -30,15 +16,14 @@ class IsAdmin {
|
|||||||
* @param \Closure $next
|
* @param \Closure $next
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function handle($request, Closure $next)
|
public function handle(Request $request, Closure $next): Response
|
||||||
{
|
{
|
||||||
if( ! $this->auth->user()->is_admin)
|
if(Auth::check() && Auth::user()->hasRole(UserRole::ADMINISTRATOR))
|
||||||
{
|
{
|
||||||
session()->flash('error_msg','This resource is restricted to Administrators!');
|
|
||||||
return redirect()->route('home.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session()->flash('error_msg','This resource is restricted to Administrators!');
|
||||||
|
return redirect()->route('home.index');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
<?php namespace app\Http\Middleware;
|
<?php namespace app\Http\Middleware;
|
||||||
|
|
||||||
|
use App\Enums\UserRole;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Contracts\Auth\Guard;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
class IsBanned {
|
class IsBanned {
|
||||||
|
|
||||||
@@ -13,9 +16,9 @@ class IsBanned {
|
|||||||
* @param \Closure $next
|
* @param \Closure $next
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function handle($request, Closure $next)
|
public function handle(Request $request, Closure $next): Response
|
||||||
{
|
{
|
||||||
if(auth()->check() && auth()->user()->is_banned == 1)
|
if(Auth::check() && Auth::user()->hasRole(UserRole::BANNED))
|
||||||
{
|
{
|
||||||
Auth::logout();
|
Auth::logout();
|
||||||
$request->session()->invalidate();
|
$request->session()->invalidate();
|
||||||
|
|||||||
29
app/Http/Middleware/IsModerator.php
Normal file
29
app/Http/Middleware/IsModerator.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use App\Enums\UserRole;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class IsModerator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, Closure $next): Response
|
||||||
|
{
|
||||||
|
if (Auth::check() && Auth::user()->hasRole(UserRole::MODERATOR))
|
||||||
|
{
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
session()->flash('error_msg','This resource is restricted to Administrators!');
|
||||||
|
return redirect()->route('home.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
|
use App\Enums\UserRole;
|
||||||
use App\Models\Comment;
|
use App\Models\Comment;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ class AdminUserSearch extends Component
|
|||||||
public $search = '';
|
public $search = '';
|
||||||
|
|
||||||
#[Url(history: true)]
|
#[Url(history: true)]
|
||||||
public $filtered = ['true'];
|
public $discordId = '';
|
||||||
|
|
||||||
#[Url(history: true)]
|
#[Url(history: true)]
|
||||||
public $patreon = [];
|
public $patreon = [];
|
||||||
@@ -38,10 +39,10 @@ class AdminUserSearch extends Component
|
|||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
$users = User::when($this->filtered !== [], fn ($query) => $query->where('id', '>=', 10000))
|
$users = User::when($this->patreon !== [], fn ($query) => $query->whereJsonContains('roles', UserRole::SUPPORTER->value))
|
||||||
->when($this->patreon !== [], fn ($query) => $query->where('is_patreon', 1))
|
->when($this->banned !== [], fn ($query) => $query->whereJsonContains('roles', UserRole::BANNED->value))
|
||||||
->when($this->banned !== [], fn ($query) => $query->where('is_banned', 1))
|
|
||||||
->when($this->search !== '', fn ($query) => $query->where('name', 'like', '%'.$this->search.'%'))
|
->when($this->search !== '', fn ($query) => $query->where('name', 'like', '%'.$this->search.'%'))
|
||||||
|
->when($this->discordId !== '', fn ($query) => $query->where('discord_id', '=', $this->discordId))
|
||||||
->paginate(20);
|
->paginate(20);
|
||||||
|
|
||||||
return view('livewire.admin-user-search', [
|
return view('livewire.admin-user-search', [
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ class DownloadsSearch extends Component
|
|||||||
$types[] = 'FHD';
|
$types[] = 'FHD';
|
||||||
} elseif ($label === 'FHD 48fps') {
|
} elseif ($label === 'FHD 48fps') {
|
||||||
$types[] = 'FHDi';
|
$types[] = 'FHDi';
|
||||||
} elseif ($label === 'UHD' && auth()->user()->is_patreon) {
|
} elseif ($label === 'UHD' && auth()->user()->hasRole(\App\Enums\UserRole::SUPPORTER)) {
|
||||||
$types[] = 'UHD';
|
$types[] = 'UHD';
|
||||||
} elseif ($label === 'UHD 48fps' && auth()->user()->is_patreon) {
|
} elseif ($label === 'UHD 48fps' && auth()->user()->hasRole(\App\Enums\UserRole::SUPPORTER)) {
|
||||||
$types[] = 'UHDi';
|
$types[] = 'UHDi';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ class DownloadsSearch extends Component
|
|||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
if (!auth()->user()->is_patreon) {
|
if (!auth()->user()->hasRole(\App\Enums\UserRole::SUPPORTER)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
//use Illuminate\Contracts\Auth\MustVerifyEmail;
|
//use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
|
|
||||||
|
use App\Enums\UserRole;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
@@ -25,7 +27,6 @@ class User extends Authenticatable
|
|||||||
'email',
|
'email',
|
||||||
'password',
|
'password',
|
||||||
'locale',
|
'locale',
|
||||||
'is_banned',
|
|
||||||
// Discord
|
// Discord
|
||||||
'discord_id',
|
'discord_id',
|
||||||
'discord_avatar',
|
'discord_avatar',
|
||||||
@@ -54,7 +55,7 @@ class User extends Authenticatable
|
|||||||
'name' => 'string',
|
'name' => 'string',
|
||||||
'email' => 'string',
|
'email' => 'string',
|
||||||
'locale' => 'string',
|
'locale' => 'string',
|
||||||
'roles' => 'json',
|
'roles' => 'array',
|
||||||
'tag_blacklist' => 'array',
|
'tag_blacklist' => 'array',
|
||||||
// Discord
|
// Discord
|
||||||
'discord_id' => 'integer',
|
'discord_id' => 'integer',
|
||||||
@@ -119,4 +120,44 @@ class User extends Authenticatable
|
|||||||
|
|
||||||
return asset('images/default-avatar.webp');
|
return asset('images/default-avatar.webp');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if user has a specific role
|
||||||
|
*/
|
||||||
|
public function hasRole(UserRole $role): bool
|
||||||
|
{
|
||||||
|
return in_array($role->value, $this->roles ?? [], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Role to User
|
||||||
|
*/
|
||||||
|
public function addRole(UserRole $role): void
|
||||||
|
{
|
||||||
|
if ($this->hasRole($role)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all current roles
|
||||||
|
$roles = $this->roles ?? [];
|
||||||
|
|
||||||
|
// Add new role
|
||||||
|
$roles[] = $role->value;
|
||||||
|
|
||||||
|
$this->roles = $roles;
|
||||||
|
$this->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove Role from User
|
||||||
|
*/
|
||||||
|
public function removeRole(UserRole $role): void
|
||||||
|
{
|
||||||
|
if (!$this->hasRole($role)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->roles = array_diff($this->roles, [$role->value]);
|
||||||
|
$this->save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ return [
|
|||||||
'guild_id' => 802233383710228550,
|
'guild_id' => 802233383710228550,
|
||||||
|
|
||||||
'patreon_roles' => [
|
'patreon_roles' => [
|
||||||
841798154999169054, // ????
|
'841798154999169054', // ????
|
||||||
803329707650187364, // Tier-5
|
'803329707650187364', // Tier-5
|
||||||
803327903659196416, // ????
|
'803327903659196416', // ????
|
||||||
803325441942356059, // Tier-3
|
'803325441942356059', // Tier-3
|
||||||
803322725576736858, // Tier-2
|
'803322725576736858', // Tier-2
|
||||||
802270568912519198, // Tier-1
|
'802270568912519198', // Tier-1
|
||||||
802234830384267315 // admin
|
'802234830384267315' // admin
|
||||||
],
|
],
|
||||||
|
|
||||||
'discord_bot_token' => env('DISCORD_BOT_TOKEN'),
|
'discord_bot_token' => env('DISCORD_BOT_TOKEN'),
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
// Migrate supporters
|
||||||
|
DB::table('users')->where('is_patreon', 1)->update([
|
||||||
|
'roles' => DB::raw("JSON_ARRAY('supporter')")
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Migrate banned
|
||||||
|
DB::table('users')->where('is_banned', 1)->update([
|
||||||
|
'roles' => DB::raw("JSON_ARRAY('banned')")
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Migrate admins
|
||||||
|
DB::table('users')->where('is_admin', 1)->update([
|
||||||
|
'roles' => DB::raw("JSON_ARRAY('admin')")
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Drop columns
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('is_admin');
|
||||||
|
$table->dropColumn('is_patreon');
|
||||||
|
$table->dropColumn('is_banned');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
DB::table('users')->update(['roles' => null]);
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->boolean('is_admin')->default(0);
|
||||||
|
$table->boolean('is_patreon')->default(0);
|
||||||
|
$table->boolean('is_banned')->default(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
<div class="mb-4 rounded-lg bg-success-400 px-6 py-5 text-base text-success-800 mt-5" role="alert">
|
<div class="mb-4 rounded-lg bg-success-400 px-6 py-5 text-base text-success-800 mt-5" role="alert">
|
||||||
{{ $alert->text }}
|
{{ $alert->text }}
|
||||||
@auth
|
@auth
|
||||||
@if(Auth::user()->is_admin)
|
@if(Auth::user()->hasRole(\App\Enums\UserRole::ADMINISTRATOR))
|
||||||
<form method="POST" action="{{ route('admin.alert.delete', $alert->id) }}" class="float-right hover:text-success-900">
|
<form method="POST" action="{{ route('admin.alert.delete', $alert->id) }}" class="float-right hover:text-success-900">
|
||||||
@csrf
|
@csrf
|
||||||
@method('delete')
|
@method('delete')
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
<div class="mb-4 rounded-lg bg-danger-400 px-6 py-5 text-base text-danger-800 mt-5" role="alert">
|
<div class="mb-4 rounded-lg bg-danger-400 px-6 py-5 text-base text-danger-800 mt-5" role="alert">
|
||||||
{{ $alert->text }}
|
{{ $alert->text }}
|
||||||
@auth
|
@auth
|
||||||
@if(Auth::user()->is_admin)
|
@if(Auth::user()->hasRole(\App\Enums\UserRole::ADMINISTRATOR))
|
||||||
<form method="POST" action="{{ route('admin.alert.delete', $alert->id) }}" class="float-right hover:text-danger-900">
|
<form method="POST" action="{{ route('admin.alert.delete', $alert->id) }}" class="float-right hover:text-danger-900">
|
||||||
@csrf
|
@csrf
|
||||||
@method('delete')
|
@method('delete')
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
@auth
|
@auth
|
||||||
@if(Auth::user()->is_admin)
|
@if(Auth::user()->hasRole(\App\Enums\UserRole::ADMINISTRATOR))
|
||||||
<div class="relative p-5 bg-white dark:bg-neutral-700/40 rounded-lg overflow-hidden z-10">
|
<div class="relative p-5 bg-white dark:bg-neutral-700/40 rounded-lg overflow-hidden z-10">
|
||||||
<div class="float-left">
|
<div class="float-left">
|
||||||
<a data-te-toggle="modal" data-te-target="#modalUploadEpisode" class="text-xl text-gray-800 dark:text-gray-200 leading-tight cursor-pointer whitespace-nowrap">
|
<a data-te-toggle="modal" data-te-target="#modalUploadEpisode" class="text-xl text-gray-800 dark:text-gray-200 leading-tight cursor-pointer whitespace-nowrap">
|
||||||
|
|||||||
@@ -163,7 +163,7 @@
|
|||||||
<i class="fa-solid fa-gear"></i> {{ __('nav.settings') }}
|
<i class="fa-solid fa-gear"></i> {{ __('nav.settings') }}
|
||||||
</x-dropdown-link>
|
</x-dropdown-link>
|
||||||
|
|
||||||
@if (Auth::user()->is_admin)
|
@if (Auth::user()->hasRole(\App\Enums\UserRole::ADMINISTRATOR))
|
||||||
<x-dropdown-link href="{{ route('admin.upload.index') }}">
|
<x-dropdown-link href="{{ route('admin.upload.index') }}">
|
||||||
<i class="fa-solid fa-user-tie"></i> Admin
|
<i class="fa-solid fa-user-tie"></i> Admin
|
||||||
</x-dropdown-link>
|
</x-dropdown-link>
|
||||||
|
|||||||
@@ -6,12 +6,16 @@
|
|||||||
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-pink-700 dark:text-neutral-200 ">
|
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-pink-700 dark:text-neutral-200 ">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="px-6 py-3">
|
<th scope="col" class="px-6 py-3">
|
||||||
Discord-ID
|
ID
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="px-6 py-3">
|
||||||
|
Discord ID
|
||||||
<input
|
<input
|
||||||
class="w-4 h-4 ml-2 text-rose-600 bg-gray-100 border-gray-300 rounded focus:ring-rose-500 dark:focus:ring-rose-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
wire:model.live.debounce.600ms="discordId"
|
||||||
type="checkbox"
|
type="search"
|
||||||
wire:model.live="filtered"
|
id="discord-search"
|
||||||
value="true"
|
class="ml-2 w-32 h-7 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-rose-800 focus:border-rose-900 dark:bg-neutral-900 dark:border-neutral-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-rose-800 dark:focus:border-rose-900"
|
||||||
|
placeholder="Search..."
|
||||||
>
|
>
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" class="px-6 py-3">
|
<th scope="col" class="px-6 py-3">
|
||||||
@@ -59,14 +63,17 @@
|
|||||||
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||||
{{ $user->id }}
|
{{ $user->id }}
|
||||||
</th>
|
</th>
|
||||||
|
<td class="px-6 py-4">
|
||||||
|
{{ $user->discord_id ?? 'n/a' }}
|
||||||
|
</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
{{ $user->name }}
|
{{ $user->name }}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
{{ $user->is_patreon ? 'Yes' : 'No' }}
|
{{ $user->hasRole(\App\Enums\UserRole::SUPPORTER) ? 'Yes' : 'No' }}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
{{ $user->is_banned ? 'Yes' : 'No' }}
|
{{ $user->hasRole(\App\Enums\UserRole::BANNED) ? 'Yes' : 'No' }}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
{{ $user->created_at->format('Y-m-d') }}
|
{{ $user->created_at->format('Y-m-d') }}
|
||||||
@@ -78,9 +85,9 @@
|
|||||||
<form method="POST" action="{{ route('admin.user.update') }}">
|
<form method="POST" action="{{ route('admin.user.update') }}">
|
||||||
@csrf
|
@csrf
|
||||||
<input type="hidden" value="{{ $user->id }}" name="id">
|
<input type="hidden" value="{{ $user->id }}" name="id">
|
||||||
<input type="hidden" value="{{ $user->is_banned ? 'unban' : 'ban' }}" name="action">
|
<input type="hidden" value="{{ $user->hasRole(\App\Enums\UserRole::BANNED) ? 'unban' : 'ban' }}" name="action">
|
||||||
<button type="submit" class="inline-block w-full rounded bg-rose-600 pl-[4px] pr-[4px] p-[1px] text-xs font-medium uppercase leading-normal text-white transition duration-150 ease-in-out hover:bg-rose-700 focus:bg-rose-600">
|
<button type="submit" class="inline-block w-full rounded bg-rose-600 pl-[4px] pr-[4px] p-[1px] text-xs font-medium uppercase leading-normal text-white transition duration-150 ease-in-out hover:bg-rose-700 focus:bg-rose-600">
|
||||||
{{ $user->is_banned ? 'Unban' : 'Ban' }}
|
{{ $user->hasRole(\App\Enums\UserRole::BANNED) ? 'Unban' : 'Ban' }}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<button wire:click="deleteUserComments('{{ $user->id }}')" class="inline-block w-full rounded bg-red-600 pl-[4px] pr-[4px] p-[1px] text-xs font-medium uppercase leading-normal text-white transition duration-150 ease-in-out hover:bg-rose-700 focus:bg-rose-600">
|
<button wire:click="deleteUserComments('{{ $user->id }}')" class="inline-block w-full rounded bg-red-600 pl-[4px] pr-[4px] p-[1px] text-xs font-medium uppercase leading-normal text-white transition duration-150 ease-in-out hover:bg-rose-700 focus:bg-rose-600">
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
<div class="flex-grow">
|
<div class="flex-grow">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<p class="font-medium text-gray-900 dark:text-gray-100">{{ $comment->user->name }}</p>
|
<p class="font-medium text-gray-900 dark:text-gray-100">{{ $comment->user->name }}</p>
|
||||||
@if($comment->user->is_admin)
|
@if($comment->user->hasRole(\App\Enums\UserRole::ADMINISTRATOR))
|
||||||
<a data-te-toggle="tooltip" title="Admin"><i class="fa-solid fa-crown text-yellow-600"></i></a>
|
<a data-te-toggle="tooltip" title="Admin"><i class="fa-solid fa-crown text-yellow-600"></i></a>
|
||||||
@endif
|
@endif
|
||||||
@if($comment->user->is_patreon)
|
@if($comment->user->hasRole(\App\Enums\UserRole::SUPPORTER))
|
||||||
<a data-te-toggle="tooltip" title="Badge of appreciation for the horny people supporting us! :3"><i class="fa-solid fa-hand-holding-heart text-rose-600"></i></a>
|
<a data-te-toggle="tooltip" title="Badge of appreciation for the horny people supporting us! :3"><i class="fa-solid fa-hand-holding-heart text-rose-600"></i></a>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
<br>
|
<br>
|
||||||
@php $download = $episode->getDownloadByType('UHD'); @endphp
|
@php $download = $episode->getDownloadByType('UHD'); @endphp
|
||||||
@isset($download)
|
@isset($download)
|
||||||
@if (!Auth::user()->is_patreon)
|
@if (!Auth::user()->hasRole(\App\Enums\UserRole::SUPPORTER))
|
||||||
@if (config('hstream.free_downloads'))
|
@if (config('hstream.free_downloads'))
|
||||||
<p class="font-bold text-gray-800 dark:text-gray-200">
|
<p class="font-bold text-gray-800 dark:text-gray-200">
|
||||||
<i class="fa-solid fa-lock-open pr-[4px] text-yellow-600"></i> 4k
|
<i class="fa-solid fa-lock-open pr-[4px] text-yellow-600"></i> 4k
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
@if ($episode->interpolated_uhd)
|
@if ($episode->interpolated_uhd)
|
||||||
@if (!Auth::user()->is_patreon)
|
@if (!Auth::user()->hasRole(\App\Enums\UserRole::SUPPORTER))
|
||||||
@if (config('hstream.free_downloads'))
|
@if (config('hstream.free_downloads'))
|
||||||
<p class="font-bold text-gray-800 dark:text-gray-200">
|
<p class="font-bold text-gray-800 dark:text-gray-200">
|
||||||
<i class="fa-solid fa-lock-open pr-[4px] text-yellow-600"></i> 4k 48fps
|
<i class="fa-solid fa-lock-open pr-[4px] text-yellow-600"></i> 4k 48fps
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
<div class="flex-grow">
|
<div class="flex-grow">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<p class="font-medium text-gray-900 dark:text-gray-100">{{ $comment->user->name }}</p>
|
<p class="font-medium text-gray-900 dark:text-gray-100">{{ $comment->user->name }}</p>
|
||||||
@if($comment->user->is_admin)
|
@if($comment->user->hasRole(\App\Enums\UserRole::ADMINISTRATOR))
|
||||||
<a data-te-toggle="tooltip" title="Admin"><i class="fa-solid fa-crown text-yellow-600"></i></a>
|
<a data-te-toggle="tooltip" title="Admin"><i class="fa-solid fa-crown text-yellow-600"></i></a>
|
||||||
@endif
|
@endif
|
||||||
@if($comment->user->is_patreon)
|
@if($comment->user->hasRole(\App\Enums\UserRole::SUPPORTER))
|
||||||
<a data-te-toggle="tooltip" title="Badge of appreciation for the horny people supporting us! :3"><i class="fa-solid fa-hand-holding-heart text-rose-600"></i></a>
|
<a data-te-toggle="tooltip" title="Badge of appreciation for the horny people supporting us! :3"><i class="fa-solid fa-hand-holding-heart text-rose-600"></i></a>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
@include('modals.share')
|
@include('modals.share')
|
||||||
|
|
||||||
@auth
|
@auth
|
||||||
@if(Auth::user()->is_admin)
|
@if(Auth::user()->hasRole(\App\Enums\UserRole::ADMINISTRATOR))
|
||||||
@include('admin.modals.upload-episode')
|
@include('admin.modals.upload-episode')
|
||||||
@include('admin.modals.add-subtitles')
|
@include('admin.modals.add-subtitles')
|
||||||
@include('admin.modals.edit-episode')
|
@include('admin.modals.edit-episode')
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<div class="flex flex-col py-5 pl-24">
|
<div class="flex flex-col py-5 pl-24">
|
||||||
<strong class="text-slate-900 text-xl font-bold dark:text-slate-200">
|
<strong class="text-slate-900 text-xl font-bold dark:text-slate-200">
|
||||||
{{ $user->name }}
|
{{ $user->name }}
|
||||||
@if ($user->is_patreon)
|
@if ($user->hasRole(\App\Enums\UserRole::SUPPORTER))
|
||||||
<a data-te-toggle="tooltip" title="Badge of appreciation for the horny people supporting us! :3"><i
|
<a data-te-toggle="tooltip" title="Badge of appreciation for the horny people supporting us! :3"><i
|
||||||
class="fa-solid fa-hand-holding-heart text-rose-600 animate-pulse"></i></a>
|
class="fa-solid fa-hand-holding-heart text-rose-600 animate-pulse"></i></a>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
Reference in New Issue
Block a user