feat: Phase 2 - page CRUD, subscriber management, user management
This commit is contained in:
@@ -5,43 +5,128 @@ declare(strict_types=1);
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\StorePreregistrationPageRequest;
|
||||
use App\Http\Requests\Admin\UpdatePreregistrationPageRequest;
|
||||
use App\Models\PreregistrationPage;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class PageController extends Controller
|
||||
{
|
||||
public function index(): \Illuminate\View\View
|
||||
public function __construct()
|
||||
{
|
||||
return view('admin.pages.index');
|
||||
$this->authorizeResource(PreregistrationPage::class, 'page');
|
||||
}
|
||||
|
||||
public function create(): \Illuminate\View\View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$query = PreregistrationPage::query()
|
||||
->withCount('subscribers')
|
||||
->orderByDesc('start_date');
|
||||
|
||||
if (! $request->user()?->isSuperadmin()) {
|
||||
$query->where('user_id', $request->user()->id);
|
||||
} else {
|
||||
$query->with('user');
|
||||
}
|
||||
|
||||
$pages = $query->get();
|
||||
|
||||
return view('admin.pages.index', compact('pages'));
|
||||
}
|
||||
|
||||
public function create(): View
|
||||
{
|
||||
return view('admin.pages.create');
|
||||
}
|
||||
|
||||
public function store(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(StorePreregistrationPageRequest $request): RedirectResponse
|
||||
{
|
||||
return redirect()->route('admin.pages.index');
|
||||
$validated = $request->validated();
|
||||
$background = $request->file('background_image');
|
||||
$logo = $request->file('logo_image');
|
||||
unset($validated['background_image'], $validated['logo_image']);
|
||||
|
||||
$validated['slug'] = (string) Str::uuid();
|
||||
$validated['user_id'] = $request->user()->id;
|
||||
|
||||
$page = DB::transaction(function () use ($validated, $background, $logo): PreregistrationPage {
|
||||
$page = PreregistrationPage::create($validated);
|
||||
$paths = [];
|
||||
if ($background !== null) {
|
||||
$paths['background_image'] = $background->store("preregister/pages/{$page->id}", 'public');
|
||||
}
|
||||
if ($logo !== null) {
|
||||
$paths['logo_image'] = $logo->store("preregister/pages/{$page->id}", 'public');
|
||||
}
|
||||
if ($paths !== []) {
|
||||
$page->update($paths);
|
||||
}
|
||||
|
||||
return $page->fresh();
|
||||
});
|
||||
|
||||
return redirect()
|
||||
->route('admin.pages.index')
|
||||
->with('status', __('Page created. Public URL: :url', ['url' => url('/r/'.$page->slug)]));
|
||||
}
|
||||
|
||||
public function show(PreregistrationPage $page): \Illuminate\View\View
|
||||
public function show(PreregistrationPage $page): RedirectResponse
|
||||
{
|
||||
return view('admin.pages.show', compact('page'));
|
||||
return redirect()->route('admin.pages.edit', $page);
|
||||
}
|
||||
|
||||
public function edit(PreregistrationPage $page): \Illuminate\View\View
|
||||
public function edit(PreregistrationPage $page): View
|
||||
{
|
||||
return view('admin.pages.edit', compact('page'));
|
||||
}
|
||||
|
||||
public function update(Request $request, PreregistrationPage $page): \Illuminate\Http\RedirectResponse
|
||||
public function update(UpdatePreregistrationPageRequest $request, PreregistrationPage $page): RedirectResponse
|
||||
{
|
||||
return redirect()->route('admin.pages.index');
|
||||
$validated = $request->validated();
|
||||
$background = $request->file('background_image');
|
||||
$logo = $request->file('logo_image');
|
||||
unset($validated['background_image'], $validated['logo_image']);
|
||||
|
||||
DB::transaction(function () use ($validated, $background, $logo, $page): void {
|
||||
if ($background !== null) {
|
||||
if ($page->background_image !== null) {
|
||||
Storage::disk('public')->delete($page->background_image);
|
||||
}
|
||||
$validated['background_image'] = $background->store("preregister/pages/{$page->id}", 'public');
|
||||
}
|
||||
if ($logo !== null) {
|
||||
if ($page->logo_image !== null) {
|
||||
Storage::disk('public')->delete($page->logo_image);
|
||||
}
|
||||
$validated['logo_image'] = $logo->store("preregister/pages/{$page->id}", 'public');
|
||||
}
|
||||
$page->update($validated);
|
||||
});
|
||||
|
||||
return redirect()
|
||||
->route('admin.pages.index')
|
||||
->with('status', __('Page updated.'));
|
||||
}
|
||||
|
||||
public function destroy(PreregistrationPage $page): \Illuminate\Http\RedirectResponse
|
||||
public function destroy(PreregistrationPage $page): RedirectResponse
|
||||
{
|
||||
return redirect()->route('admin.pages.index');
|
||||
DB::transaction(function () use ($page): void {
|
||||
if ($page->background_image !== null) {
|
||||
Storage::disk('public')->delete($page->background_image);
|
||||
}
|
||||
if ($page->logo_image !== null) {
|
||||
Storage::disk('public')->delete($page->logo_image);
|
||||
}
|
||||
$page->delete();
|
||||
});
|
||||
|
||||
return redirect()
|
||||
->route('admin.pages.index')
|
||||
->with('status', __('Page deleted.'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,34 +5,58 @@ declare(strict_types=1);
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\IndexSubscriberRequest;
|
||||
use App\Models\PreregistrationPage;
|
||||
use Illuminate\View\View;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class SubscriberController extends Controller
|
||||
{
|
||||
public function index(PreregistrationPage $page): \Illuminate\View\View
|
||||
public function index(IndexSubscriberRequest $request, PreregistrationPage $page): View
|
||||
{
|
||||
return view('admin.subscribers.index', compact('page'));
|
||||
$search = $request->validated('search');
|
||||
$subscribers = $page->subscribers()
|
||||
->search(is_string($search) ? $search : null)
|
||||
->orderByDesc('created_at')
|
||||
->paginate(25)
|
||||
->withQueryString();
|
||||
|
||||
return view('admin.subscribers.index', compact('page', 'subscribers'));
|
||||
}
|
||||
|
||||
public function export(PreregistrationPage $page): \Symfony\Component\HttpFoundation\StreamedResponse
|
||||
public function export(IndexSubscriberRequest $request, PreregistrationPage $page): StreamedResponse
|
||||
{
|
||||
$this->authorize('view', $page);
|
||||
$search = $request->validated('search');
|
||||
$subscribers = $page->subscribers()
|
||||
->search(is_string($search) ? $search : null)
|
||||
->orderBy('created_at')
|
||||
->get();
|
||||
|
||||
$subscribers = $page->subscribers()->orderBy('created_at')->get();
|
||||
$phoneEnabled = $page->phone_enabled;
|
||||
|
||||
return response()->streamDownload(function () use ($subscribers, $page) {
|
||||
return response()->streamDownload(function () use ($subscribers, $phoneEnabled): void {
|
||||
$handle = fopen('php://output', 'w');
|
||||
fputcsv($handle, ['First Name', 'Last Name', 'Email', 'Phone', 'Registered At']);
|
||||
foreach ($subscribers as $sub) {
|
||||
fputcsv($handle, [
|
||||
$sub->first_name,
|
||||
$sub->last_name,
|
||||
$sub->email,
|
||||
$sub->phone,
|
||||
$sub->created_at->toDateTimeString(),
|
||||
]);
|
||||
$headers = ['First Name', 'Last Name', 'Email'];
|
||||
if ($phoneEnabled) {
|
||||
$headers[] = 'Phone';
|
||||
}
|
||||
$headers = array_merge($headers, ['Registered At', 'Synced to Mailwizz', 'Synced At']);
|
||||
fputcsv($handle, $headers);
|
||||
|
||||
foreach ($subscribers as $sub) {
|
||||
$row = [$sub->first_name, $sub->last_name, $sub->email];
|
||||
if ($phoneEnabled) {
|
||||
$row[] = $sub->phone ?? '';
|
||||
}
|
||||
$row[] = $sub->created_at?->toDateTimeString() ?? '';
|
||||
$row[] = $sub->synced_to_mailwizz ? 'Yes' : 'No';
|
||||
$row[] = $sub->synced_at?->toDateTimeString() ?? '';
|
||||
fputcsv($handle, $row);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
}, "subscribers-{$page->slug}.csv");
|
||||
}, 'subscribers-'.$page->slug.'.csv', [
|
||||
'Content-Type' => 'text/csv; charset=UTF-8',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,38 +5,71 @@ declare(strict_types=1);
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\StoreUserRequest;
|
||||
use App\Http\Requests\Admin\UpdateUserRequest;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function index(): \Illuminate\View\View
|
||||
public function __construct()
|
||||
{
|
||||
return view('admin.users.index');
|
||||
$this->authorizeResource(User::class, 'user', [
|
||||
'except' => ['show'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(): \Illuminate\View\View
|
||||
public function index(): View
|
||||
{
|
||||
$users = User::query()->orderBy('name')->paginate(25);
|
||||
|
||||
return view('admin.users.index', compact('users'));
|
||||
}
|
||||
|
||||
public function create(): View
|
||||
{
|
||||
return view('admin.users.create');
|
||||
}
|
||||
|
||||
public function store(Request $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(StoreUserRequest $request): RedirectResponse
|
||||
{
|
||||
return redirect()->route('admin.users.index');
|
||||
$data = $request->validated();
|
||||
$data['password'] = Hash::make($data['password']);
|
||||
User::query()->create($data);
|
||||
|
||||
return redirect()
|
||||
->route('admin.users.index')
|
||||
->with('status', __('User created.'));
|
||||
}
|
||||
|
||||
public function edit(User $user): \Illuminate\View\View
|
||||
public function edit(User $user): View
|
||||
{
|
||||
return view('admin.users.edit', compact('user'));
|
||||
}
|
||||
|
||||
public function update(Request $request, User $user): \Illuminate\Http\RedirectResponse
|
||||
public function update(UpdateUserRequest $request, User $user): RedirectResponse
|
||||
{
|
||||
return redirect()->route('admin.users.index');
|
||||
$data = $request->validated();
|
||||
if ($request->filled('password')) {
|
||||
$data['password'] = Hash::make($data['password']);
|
||||
} else {
|
||||
unset($data['password']);
|
||||
}
|
||||
$user->update($data);
|
||||
|
||||
return redirect()
|
||||
->route('admin.users.index')
|
||||
->with('status', __('User updated.'));
|
||||
}
|
||||
|
||||
public function destroy(User $user): \Illuminate\Http\RedirectResponse
|
||||
public function destroy(User $user): RedirectResponse
|
||||
{
|
||||
return redirect()->route('admin.users.index');
|
||||
$user->delete();
|
||||
|
||||
return redirect()
|
||||
->route('admin.users.index')
|
||||
->with('status', __('User deleted.'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
abstract class Controller
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
abstract class Controller extends BaseController
|
||||
{
|
||||
//
|
||||
use AuthorizesRequests;
|
||||
use ValidatesRequests;
|
||||
}
|
||||
|
||||
32
app/Http/Requests/Admin/IndexSubscriberRequest.php
Normal file
32
app/Http/Requests/Admin/IndexSubscriberRequest.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use App\Models\PreregistrationPage;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class IndexSubscriberRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
$page = $this->route('page');
|
||||
if (! $page instanceof PreregistrationPage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->user()?->can('view', $page) ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, ValidationRule|string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'search' => ['nullable', 'string', 'max:255'],
|
||||
];
|
||||
}
|
||||
}
|
||||
32
app/Http/Requests/Admin/StorePreregistrationPageRequest.php
Normal file
32
app/Http/Requests/Admin/StorePreregistrationPageRequest.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use App\Models\PreregistrationPage;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StorePreregistrationPageRequest extends FormRequest
|
||||
{
|
||||
use ValidatesPreregistrationPageInput;
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user()?->can('create', PreregistrationPage::class) ?? false;
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->preparePreregistrationPageFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, ValidationRule|string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return $this->preregistrationPageRules();
|
||||
}
|
||||
}
|
||||
32
app/Http/Requests/Admin/StoreUserRequest.php
Normal file
32
app/Http/Requests/Admin/StoreUserRequest.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class StoreUserRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user()?->can('create', User::class) ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, ValidationRule|string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', Rule::unique(User::class)],
|
||||
'password' => ['required', 'confirmed', Password::defaults()],
|
||||
'role' => ['required', Rule::in(['superadmin', 'user'])],
|
||||
];
|
||||
}
|
||||
}
|
||||
36
app/Http/Requests/Admin/UpdatePreregistrationPageRequest.php
Normal file
36
app/Http/Requests/Admin/UpdatePreregistrationPageRequest.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdatePreregistrationPageRequest extends FormRequest
|
||||
{
|
||||
use ValidatesPreregistrationPageInput;
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
$page = $this->route('page');
|
||||
if ($page === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->user()?->can('update', $page) ?? false;
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->preparePreregistrationPageFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, ValidationRule|string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return $this->preregistrationPageRules();
|
||||
}
|
||||
}
|
||||
54
app/Http/Requests/Admin/UpdateUserRequest.php
Normal file
54
app/Http/Requests/Admin/UpdateUserRequest.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class UpdateUserRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
$user = $this->route('user');
|
||||
if (! $user instanceof User) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->user()?->can('update', $user) ?? false;
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
if ($this->input('password') === '' || $this->input('password') === null) {
|
||||
$this->merge(['password' => null]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, ValidationRule|string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var User $target */
|
||||
$target = $this->route('user');
|
||||
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => [
|
||||
'required',
|
||||
'string',
|
||||
'lowercase',
|
||||
'email',
|
||||
'max:255',
|
||||
Rule::unique(User::class)->ignore($target->id),
|
||||
],
|
||||
'password' => ['nullable', 'confirmed', Password::defaults()],
|
||||
'role' => ['required', Rule::in(['superadmin', 'user'])],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
|
||||
trait ValidatesPreregistrationPageInput
|
||||
{
|
||||
/**
|
||||
* @return array<string, array<int, ValidationRule|string>>
|
||||
*/
|
||||
protected function preregistrationPageRules(): array
|
||||
{
|
||||
return [
|
||||
'title' => ['required', 'string', 'max:255'],
|
||||
'heading' => ['required', 'string', 'max:255'],
|
||||
'intro_text' => ['nullable', 'string'],
|
||||
'thank_you_message' => ['nullable', 'string'],
|
||||
'expired_message' => ['nullable', 'string'],
|
||||
'ticketshop_url' => ['nullable', 'string', 'url:http,https', 'max:255'],
|
||||
'start_date' => ['required', 'date'],
|
||||
'end_date' => ['required', 'date', 'after:start_date'],
|
||||
'phone_enabled' => ['sometimes', 'boolean'],
|
||||
'is_active' => ['sometimes', 'boolean'],
|
||||
'background_image' => ['nullable', 'image', 'mimes:jpeg,png,jpg,webp', 'max:5120'],
|
||||
'logo_image' => ['nullable', 'file', 'mimes:jpeg,png,jpg,webp,svg', 'max:2048'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function preparePreregistrationPageFields(): void
|
||||
{
|
||||
$ticketshop = $this->input('ticketshop_url');
|
||||
$ticketshopNormalized = null;
|
||||
if (is_string($ticketshop) && trim($ticketshop) !== '') {
|
||||
$ticketshopNormalized = trim($ticketshop);
|
||||
}
|
||||
|
||||
$this->merge([
|
||||
'phone_enabled' => $this->boolean('phone_enabled'),
|
||||
'is_active' => $this->boolean('is_active'),
|
||||
'ticketshop_url' => $ticketshopNormalized,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -74,6 +74,7 @@ class PreregistrationPage extends Model
|
||||
public function isActive(): bool
|
||||
{
|
||||
$now = Carbon::now();
|
||||
|
||||
return $now->gte($this->start_date) && $now->lte($this->end_date);
|
||||
}
|
||||
|
||||
@@ -86,4 +87,20 @@ class PreregistrationPage extends Model
|
||||
{
|
||||
return $query->where('is_active', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lifecycle label for admin tables: before registration opens, open window, or after end.
|
||||
*/
|
||||
public function statusKey(): string
|
||||
{
|
||||
if ($this->isBeforeStart()) {
|
||||
return 'before_start';
|
||||
}
|
||||
|
||||
if ($this->isExpired()) {
|
||||
return 'expired';
|
||||
}
|
||||
|
||||
return 'active';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
@@ -34,4 +35,19 @@ class Subscriber extends Model
|
||||
{
|
||||
return $this->belongsTo(PreregistrationPage::class);
|
||||
}
|
||||
|
||||
public function scopeSearch(Builder $query, ?string $term): Builder
|
||||
{
|
||||
if ($term === null || $term === '') {
|
||||
return $query;
|
||||
}
|
||||
|
||||
$like = '%'.$term.'%';
|
||||
|
||||
return $query->where(function (Builder $q) use ($like): void {
|
||||
$q->where('first_name', 'like', $like)
|
||||
->orWhere('last_name', 'like', $like)
|
||||
->orWhere('email', 'like', $like);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
34
app/Policies/UserPolicy.php
Normal file
34
app/Policies/UserPolicy.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class UserPolicy
|
||||
{
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return $user->isSuperadmin();
|
||||
}
|
||||
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->isSuperadmin();
|
||||
}
|
||||
|
||||
public function update(User $user, User $target): bool
|
||||
{
|
||||
return $user->isSuperadmin();
|
||||
}
|
||||
|
||||
public function delete(User $user, User $target): bool
|
||||
{
|
||||
if (! $user->isSuperadmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $user->id !== $target->id;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
@@ -19,6 +22,6 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
Paginator::useTailwind();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user