-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add label admin manager, banner macro and admin middlewares (#3)
* 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
Showing
26 changed files
with
25,823 additions
and
26 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 {} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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!"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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('/'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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('/'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.