Skip to content

Commit

Permalink
feat: Add label admin manager, banner macro and admin middlewares (#3)
Browse files Browse the repository at this point in the history
* feat: Add label admin manager, banner macro and admin middlewares

* chore: enforce order of labels by order column for recipe relationship

* chore: regenerate composer lock file
  • Loading branch information
IronSinew authored Mar 19, 2024
1 parent 665b379 commit 4f33b86
Show file tree
Hide file tree
Showing 26 changed files with 25,823 additions and 26 deletions.
2,779 changes: 2,779 additions & 0 deletions .phpstorm.meta.php

Large diffs are not rendered by default.

21,859 changes: 21,859 additions & 0 deletions _ide_helper.php

Large diffs are not rendered by default.

193 changes: 193 additions & 0 deletions _ide_helper_models.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
<?php

// @formatter:off
// phpcs:ignoreFile
/**
* A helper file for your Eloquent Models
* Copy the phpDocs from this file to the correct Model,
* And remove them from this file, to prevent double declarations.
*
* @author Barry vd. Heuvel <[email protected]>
*/


namespace App\Models{
/**
*
*
* @property int $id
* @property string $name
* @property string $slug
* @property int $order_column
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Recipe> $recipes
* @property-read int|null $recipes_count
* @method static \Database\Factories\CategoryFactory factory($count = null, $state = [])
* @method static \Illuminate\Database\Eloquent\Builder|Category newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Category newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Category onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Category ordered(string $direction = 'asc')
* @method static \Illuminate\Database\Eloquent\Builder|Category query()
* @method static \Illuminate\Database\Eloquent\Builder|Category whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Category whereDeletedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Category whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Category whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|Category whereOrderColumn($value)
* @method static \Illuminate\Database\Eloquent\Builder|Category whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder|Category whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Category withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Category withoutTrashed()
*/
class Category extends \Eloquent implements \Spatie\EloquentSortable\Sortable {}
}

namespace App\Models{
/**
*
*
* @property int $id
* @property string $name
* @property string|null $description
* @property string $path
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Recipe> $recipes
* @property-read int|null $recipes_count
* @method static \Database\Factories\ImageFactory factory($count = null, $state = [])
* @method static \Illuminate\Database\Eloquent\Builder|Image newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Image newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Image query()
* @method static \Illuminate\Database\Eloquent\Builder|Image whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Image whereDescription($value)
* @method static \Illuminate\Database\Eloquent\Builder|Image whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Image whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|Image wherePath($value)
* @method static \Illuminate\Database\Eloquent\Builder|Image whereUpdatedAt($value)
*/
class Image extends \Eloquent {}
}

namespace App\Models{
/**
*
*
* @property int $id
* @property string $name
* @property string $slug
* @property int $order_column
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Recipe> $recipes
* @property-read int|null $recipes_count
* @method static \Database\Factories\LabelFactory factory($count = null, $state = [])
* @method static \Illuminate\Database\Eloquent\Builder|Label newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Label newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Label onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Label ordered(string $direction = 'asc')
* @method static \Illuminate\Database\Eloquent\Builder|Label query()
* @method static \Illuminate\Database\Eloquent\Builder|Label whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Label whereDeletedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Label whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Label whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|Label whereOrderColumn($value)
* @method static \Illuminate\Database\Eloquent\Builder|Label whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder|Label whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Label withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Label withoutTrashed()
*/
class Label extends \Eloquent implements \Spatie\EloquentSortable\Sortable {}
}

namespace App\Models{
/**
*
*
* @property int $id
* @property string $name
* @property string $slug
* @property string $serving
* @property string $ingredients
* @property string $instructions
* @property string|null $description
* @property int|null $published_at
* @property int $user_id
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Category> $categories
* @property-read int|null $categories_count
* @property-read \App\Models\Image|null $images
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Label> $labels
* @property-read int|null $labels_count
* @property-read \App\Models\User|null $user
* @method static \Database\Factories\RecipeFactory factory($count = null, $state = [])
* @method static \Illuminate\Database\Eloquent\Builder|Recipe newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Recipe newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Recipe onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Recipe query()
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereDeletedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereDescription($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereIngredients($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereInstructions($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe wherePublishedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereServing($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereUserId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe withTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Recipe withoutTrashed()
*/
class Recipe extends \Eloquent {}
}

namespace App\Models{
/**
*
*
* @property int $id
* @property string $name
* @property string $email
* @property \Illuminate\Support\Carbon|null $email_verified_at
* @property mixed $password
* @property string|null $remember_token
* @property int|null $current_team_id
* @property string|null $profile_photo_path
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $two_factor_secret
* @property string|null $two_factor_recovery_codes
* @property string|null $two_factor_confirmed_at
* @property \App\Enums\UserRoleEnum|null $role
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
* @property-read int|null $notifications_count
* @property-read string $profile_photo_url
* @property-read \Illuminate\Database\Eloquent\Collection<int, \Laravel\Sanctum\PersonalAccessToken> $tokens
* @property-read int|null $tokens_count
* @method static \Database\Factories\UserFactory factory($count = null, $state = [])
* @method static \Illuminate\Database\Eloquent\Builder|User newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|User newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|User query()
* @method static \Illuminate\Database\Eloquent\Builder|User whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereCurrentTeamId($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereEmail($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereEmailVerifiedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|User wherePassword($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereProfilePhotoPath($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereRememberToken($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereRole($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereTwoFactorConfirmedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereTwoFactorRecoveryCodes($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereTwoFactorSecret($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUpdatedAt($value)
*/
class User extends \Eloquent {}
}

51 changes: 51 additions & 0 deletions app/Console/Commands/AddAdminUser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace App\Console\Commands;

use App\Enums\UserRoleEnum;
use App\Models\User;
use Illuminate\Console\Command;

/** @codeCoverageIgnore */
class AddAdminUser extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:add-admin';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Add an admin user';

/**
* Execute the console command.
*/
public function handle()
{
$name = $this->ask('What is the name of the user?');
$email = $this->ask('What is the email for the user?');
$password = $this->secret('What is the password?');

$user = User::create([
'name' => $name,
'email' => $email,
'password' => bcrypt($password),
'role' => UserRoleEnum::ADMIN,
]);

if (! $user->wasRecentlyCreated) {
$this->error("Uh oh! Couldn't create the user");

return;
}

$user->forceFill(['email_verified_at' => now()])->save();
$this->info("{$user->name} has been created!");
}
}
11 changes: 11 additions & 0 deletions app/Enums/BannerTypeEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace App\Enums;

enum BannerTypeEnum: string
{
case success = 'success';
case danger = 'error';
case warning = 'warn';
case info = 'info';
}
9 changes: 9 additions & 0 deletions app/Enums/UserRoleEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace App\Enums;

enum UserRoleEnum: string
{
case ADMIN = 'admin';
case CONTRIBUTOR = 'contributor';
}
48 changes: 48 additions & 0 deletions app/Http/Controllers/Admin/LabelController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace App\Http\Controllers\Admin;

use App\Enums\BannerTypeEnum;
use App\Http\Controllers\Controller;
use App\Models\Label;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;

class LabelController extends Controller
{
public function index()
{
return Inertia::render('Admin/Label/LabelIndex')->with([
'labels' => fn () => Label::orderBy('order_column')->withCount('recipes')->get()->makeVisible('id'),
]);
}

/** @codeCoverageIgnore */
public function setNewOrder(Request $request)
{
Label::setNewOrder($request->all());

return response()->noContent();
}

public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'name' => ['required', 'max:40', 'unique:labels'],
]);

$label = Label::create($validated);

return redirect()->route('admin.labels.index')->withBanner("Successfully created {$label->name}");
}

public function destroy(Label $label)
{
$name = $label->name;
$label->delete();

return redirect()->route('admin.labels.index')
->withBanner("Deleted {$name}", BannerTypeEnum::danger);
}
}
1 change: 1 addition & 0 deletions app/Http/Middleware/HandleInertiaRequests.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public function version(Request $request): ?string
public function share(Request $request): array
{
return array_merge(parent::share($request), [
'can_access_admin_area' => $request->user()?->hasAccessToAdminArea() ?? false,
]);
}
}
25 changes: 25 additions & 0 deletions app/Http/Middleware/HasAdminAreaAccess.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;

class HasAdminAreaAccess
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (Auth::user() && Auth::user()->hasAccessToAdminArea()) {
return $next($request);
}

return redirect('/');
}
}
25 changes: 25 additions & 0 deletions app/Http/Middleware/IsAdmin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;

class IsAdmin
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (Auth::user() && Auth::user()->isAdmin()) {
return $next($request);
}

return redirect('/');
}
}
2 changes: 1 addition & 1 deletion app/Models/Recipe.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,6 @@ public function images(): BelongsTo

public function labels(): BelongsToMany
{
return $this->belongsToMany(Label::class);
return $this->belongsToMany(Label::class)->orderBy((new Label)->determineOrderColumnName());
}
}
Loading

0 comments on commit 4f33b86

Please sign in to comment.