added form login, user for frontend and backend
This commit is contained in:
parent
a5ef904c1e
commit
5488a80b91
11
app/Filament/Resources/Users/Pages/CreateUser.php
Normal file
11
app/Filament/Resources/Users/Pages/CreateUser.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Users\Pages;
|
||||
|
||||
use App\Filament\Resources\Users\UserResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateUser extends CreateRecord
|
||||
{
|
||||
protected static string $resource = UserResource::class;
|
||||
}
|
||||
19
app/Filament/Resources/Users/Pages/EditUser.php
Normal file
19
app/Filament/Resources/Users/Pages/EditUser.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Users\Pages;
|
||||
|
||||
use App\Filament\Resources\Users\UserResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditUser extends EditRecord
|
||||
{
|
||||
protected static string $resource = UserResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
19
app/Filament/Resources/Users/Pages/ListUsers.php
Normal file
19
app/Filament/Resources/Users/Pages/ListUsers.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Users\Pages;
|
||||
|
||||
use App\Filament\Resources\Users\UserResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListUsers extends ListRecords
|
||||
{
|
||||
protected static string $resource = UserResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
35
app/Filament/Resources/Users/Schemas/UserForm.php
Normal file
35
app/Filament/Resources/Users/Schemas/UserForm.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Users\Schemas;
|
||||
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class UserForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('name')
|
||||
->label('Name')
|
||||
->required(),
|
||||
TextInput::make('email')
|
||||
->label('E-Mail')
|
||||
->email()
|
||||
->required()
|
||||
->unique(ignoreRecord: true),
|
||||
TextInput::make('password')
|
||||
->label('Passwort')
|
||||
->password()
|
||||
->revealable()
|
||||
->required(fn (string $operation) => $operation === 'create')
|
||||
->dehydrateStateUsing(fn ($state) => filled($state) ? bcrypt($state) : null)
|
||||
->dehydrated(fn ($state) => filled($state))
|
||||
->minLength(8),
|
||||
Checkbox::make('is_admin')
|
||||
->label('Administrator'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
44
app/Filament/Resources/Users/Tables/UsersTable.php
Normal file
44
app/Filament/Resources/Users/Tables/UsersTable.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Users\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class UsersTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('name')
|
||||
->label('Name')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('email')
|
||||
->label('E-Mail')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
IconColumn::make('is_admin')
|
||||
->label('Administrator'),
|
||||
TextColumn::make('created_at')
|
||||
->label('Erstellt')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
54
app/Filament/Resources/Users/UserResource.php
Normal file
54
app/Filament/Resources/Users/UserResource.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Users;
|
||||
|
||||
use App\Filament\Resources\Users\Pages\CreateUser;
|
||||
use App\Filament\Resources\Users\Pages\EditUser;
|
||||
use App\Filament\Resources\Users\Pages\ListUsers;
|
||||
use App\Filament\Resources\Users\Schemas\UserForm;
|
||||
use App\Filament\Resources\Users\Tables\UsersTable;
|
||||
use App\Models\User;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class UserResource extends Resource
|
||||
{
|
||||
protected static ?string $model = User::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedUsers;
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'name';
|
||||
|
||||
protected static ?string $navigationLabel = 'Benutzer';
|
||||
|
||||
protected static ?string $modelLabel = 'Benutzer';
|
||||
|
||||
protected static ?string $pluralModelLabel = 'Benutzer';
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return UserForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return UsersTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListUsers::route('/'),
|
||||
'create' => CreateUser::route('/create'),
|
||||
'edit' => EditUser::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
37
app/Http/Controllers/LoginController.php
Normal file
37
app/Http/Controllers/LoginController.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
public function show()
|
||||
{
|
||||
return view('auth.login');
|
||||
}
|
||||
|
||||
public function login(Request $request)
|
||||
{
|
||||
$credentials = $request->validate([
|
||||
'email' => ['required', 'email'],
|
||||
'password' => ['required'],
|
||||
]);
|
||||
|
||||
if (Auth::attempt($credentials, $request->boolean('remember'))) {
|
||||
$request->session()->regenerate();
|
||||
return redirect()->intended('/');
|
||||
}
|
||||
|
||||
return back()->withErrors(['email' => 'Die eingegebenen Daten stimmen nicht überein.'])->onlyInput('email');
|
||||
}
|
||||
|
||||
public function logout(Request $request)
|
||||
{
|
||||
Auth::logout();
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
return redirect('/login');
|
||||
}
|
||||
}
|
||||
@ -2,31 +2,33 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Database\Factories\UserFactory;
|
||||
use Filament\Models\Contracts\FilamentUser;
|
||||
use Filament\Panel;
|
||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||
use Illuminate\Database\Eloquent\Attributes\Hidden;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
#[Fillable(['name', 'email', 'password'])]
|
||||
#[Fillable(['name', 'email', 'password', 'is_admin'])]
|
||||
#[Hidden(['password', 'remember_token'])]
|
||||
class User extends Authenticatable
|
||||
class User extends Authenticatable implements FilamentUser
|
||||
{
|
||||
/** @use HasFactory<UserFactory> */
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function canAccessPanel(Panel $panel): bool
|
||||
{
|
||||
return $this->is_admin;
|
||||
}
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
'is_admin' => 'boolean',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ class UserFactory extends Factory
|
||||
'email_verified_at' => now(),
|
||||
'password' => static::$password ??= Hash::make('password'),
|
||||
'remember_token' => Str::random(10),
|
||||
'is_admin' => false,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
<?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::table('users', function (Blueprint $table) {
|
||||
$table->boolean('is_admin')->default(false)->after('remember_token');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('is_admin');
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -12,6 +12,7 @@ class DatabaseSeeder extends Seeder
|
||||
public function run(): void
|
||||
{
|
||||
$this->call([
|
||||
UserSeeder::class,
|
||||
PhotoprofileSeeder::class,
|
||||
]);
|
||||
}
|
||||
|
||||
31
database/seeders/UserSeeder.php
Normal file
31
database/seeders/UserSeeder.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class UserSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
User::firstOrCreate(
|
||||
['email' => 'admin@fotobox.local'],
|
||||
[
|
||||
'name' => 'Admin',
|
||||
'password' => Hash::make('admin'),
|
||||
'is_admin' => true,
|
||||
]
|
||||
);
|
||||
|
||||
User::firstOrCreate(
|
||||
['email' => 'user@fotobox.local'],
|
||||
[
|
||||
'name' => 'User',
|
||||
'password' => Hash::make('user'),
|
||||
'is_admin' => false,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
45
resources/views/auth/login.blade.php
Normal file
45
resources/views/auth/login.blade.php
Normal file
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Fotobox – Anmelden</title>
|
||||
@if (file_exists(public_path('build/manifest.json')) || file_exists(public_path('hot')))
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
@endif
|
||||
</head>
|
||||
<body class="bg-gray-950 text-white min-h-screen flex flex-col items-center justify-center p-6">
|
||||
|
||||
<h1 class="text-3xl font-bold mb-8 tracking-wide">Fotobox</h1>
|
||||
|
||||
<form method="POST" action="{{ route('login') }}" class="w-full max-w-sm flex flex-col gap-4">
|
||||
@csrf
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<label for="email" class="text-sm text-gray-400">E-Mail</label>
|
||||
<input id="email" type="email" name="email" value="{{ old('email') }}" required autofocus
|
||||
class="rounded-xl bg-white/10 border border-white/20 px-4 py-3 text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-white/40">
|
||||
@error('email')
|
||||
<span class="text-sm text-red-400">{{ $message }}</span>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<label for="password" class="text-sm text-gray-400">Passwort</label>
|
||||
<input id="password" type="password" name="password" required
|
||||
class="rounded-xl bg-white/10 border border-white/20 px-4 py-3 text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-white/40">
|
||||
</div>
|
||||
|
||||
<label class="flex items-center gap-2 text-sm text-gray-400 cursor-pointer">
|
||||
<input type="checkbox" name="remember" class="rounded">
|
||||
Angemeldet bleiben
|
||||
</label>
|
||||
|
||||
<button type="submit"
|
||||
class="mt-2 px-10 py-4 bg-white text-gray-950 font-semibold text-lg rounded-full shadow-lg hover:bg-gray-200 active:scale-95 transition-all duration-150">
|
||||
Anmelden
|
||||
</button>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1,8 +1,16 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\LoginController;
|
||||
use App\Http\Controllers\PhotoController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::middleware('auth.basic')->group(function () {
|
||||
Route::middleware('guest')->group(function () {
|
||||
Route::get('/login', [LoginController::class, 'show'])->name('login');
|
||||
Route::post('/login', [LoginController::class, 'login']);
|
||||
});
|
||||
|
||||
Route::post('/logout', [LoginController::class, 'logout'])->name('logout')->middleware('auth');
|
||||
|
||||
Route::middleware('auth')->group(function () {
|
||||
Route::get('/', [PhotoController::class, 'index'])->name('camera');
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user