register form

This commit is contained in:
salam committed 2025-09-20 16:26:01 +02:00
1 parent 390a98e961
commit b5d090cf5e
18 files changed
+348 -45

No files matched your search

+200
View File
@@ -0,0 +1,200 @@
<?php
namespace App\Filament\Pages\Auth;
use App\Models\Konto;
use Danielebarbaro\LaravelVatEuValidator\Rules\VatNumber;
use Filament\Auth\Pages\Register as BaseRegister;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Fieldset;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Wizard;
use Filament\Schemas\Components\Wizard\Step;
use Filament\Schemas\Schema;
use Ysfkaya\FilamentPhoneInput\Forms\PhoneInput;
class Register extends BaseRegister
{
public function form(Schema $schema): Schema
{
return $schema
->components([
Wizard::make([
Step::make('Profile')
->icon('lucide-user-plus')
->description('Benutzer anlegen.')
->schema([
$this->getNameFormComponent(),
$this->getEmailFormComponent(),
$this->getPasswordFormComponent(),
$this->getPasswordConfirmationFormComponent(),
]),
Wizard\Step::make('Konto')
// ->columns(4)
->icon('lucide-key-square')
->description('Mit einem Konto verbinden.')
->schema([
$this->getKontoFormComponent(),
/** OLD */
$this->selectKontoFormComponent(),
/** NEU */
Fieldset::make('Rechnungsdaten')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->schema([
$this->getCompanyFormComponent(),
$this->getUIDFormComponent(),
$this->getPlaceFormComponent(),
$this->getPLZFormComponent(),
$this->getCountryFormComponent(),
$this->getAdresseFormComponent(),
$this->getGenderFormComponent(),
$this->getFirstNameFormComponent(),
$this->getLastNameFormComponent(),
$this->getPhoneFormComponent(),
$this->getKontoEmailFormComponent(),
])->columnSpan(4),
]),
]),
]);
}
protected function getPhoneFormComponent(): PhoneInput
{
return PhoneInput::make('phone')
->label('Telefon')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->defaultCountry('AT');
}
protected function getCountryFormComponent(): TextInput
{
return TextInput::make('country')
->label('Land')
->placeholder('Österreich')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getKontoEmailFormComponent(): TextInput
{
return TextInput::make('konto-email')
->label('E-Mail')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getPLZFormComponent(): TextInput
{
return TextInput::make('code')
->label('Postleitzahl')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getPlaceFormComponent(): TextInput
{
return TextInput::make('place')
->label('Ort')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getAdresseFormComponent(): Textarea
{
return Textarea::make('address')
->label('Adresse')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getFirstNameFormComponent(): TextInput
{
return TextInput::make('first_name')
->label('Vorname')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getLastNameFormComponent(): TextInput
{
return TextInput::make('last_name')
->label('Nachname')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getUIDFormComponent(): TextInput
{
return TextInput::make('uid_number')
->label('UID Nummer')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->rules([new VatNumber])
->required();
}
protected function getCompanyFormComponent(): TextInput
{
return TextInput::make('company')
->label('Firma')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getRoleFormComponent(): Select
{
return Select::make('role')
->options([
'gutachter' => 'Gutachter',
'super_admin' => 'Administrator',
])
->default('gutachter')
->required();
}
protected function getGenderFormComponent(): Select
{
return Select::make('gender')
->columnSpan(2)
->label('Geschlecht')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->options([
'Herr' => 'Herr',
'Frau' => 'Frau',
'Non-binary' => 'Non-binary',
])
->required();
}
protected function getKontoFormComponent(): Select
{
return Select::make('konto')
->columnSpan(4)
->label('Registriermodus')
->prefixIcon('lucide-key-square')
->prefixIconColor('primary')
->aboveLabel([
'Bitte wählen Sie ein bestehendes Konto oder erstellen Sie ein neues. Eine Registrierung bei einem bestehenden Konto muß vom Kontoinhaber bestätigt werden.',
])
->options([
'old' => 'Mit einem bestehenden Konto verbinden',
'new' => 'Ein neues Konto erstellen',
])
->live()
->required();
}
protected function selectKontoFormComponent(): Select
{
return Select::make('konto_id')
->columnSpan(4)
->label('Konto auswählen')
->visible(fn (Get $get): bool => $get('konto') == 'old')
->options(Konto::query()->pluck('company', 'id'))
->searchable()
->required();
}
}
+4
View File
@@ -30,6 +30,7 @@ class User extends Authenticatable implements FilamentUser, HasAppAuthentication
'email', 'email',
'konto_id', 'konto_id',
'password', 'password',
'role',
'super_admin', 'super_admin',
'app_verified_at', 'app_verified_at',
'first_name', 'first_name',
@@ -76,6 +77,9 @@ class User extends Authenticatable implements FilamentUser, HasAppAuthentication
{ {
static::addGlobalScope(new KontoScope); static::addGlobalScope(new KontoScope);
static::creating(function (User $user) {
$user->role = 'gutachter';
});
} }
public function getAppAuthenticationSecret(): ?string public function getAppAuthenticationSecret(): ?string
@@ -3,6 +3,7 @@
namespace App\Providers\Filament; namespace App\Providers\Filament;
use Agencetwogether\HooksHelper\HooksHelperPlugin; use Agencetwogether\HooksHelper\HooksHelperPlugin;
use App\Filament\Pages\Auth\Register;
use App\Http\Middleware\AppUserVerifiedMiddleware; use App\Http\Middleware\AppUserVerifiedMiddleware;
use Awcodes\LightSwitch\Enums\Alignment; use Awcodes\LightSwitch\Enums\Alignment;
use Awcodes\LightSwitch\LightSwitchPlugin; use Awcodes\LightSwitch\LightSwitchPlugin;
@@ -16,7 +17,6 @@ use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Pages\Dashboard; use Filament\Pages\Dashboard;
use Filament\Panel; use Filament\Panel;
use Filament\PanelProvider; use Filament\PanelProvider;
use Filament\Support\Colors\Color;
use Filament\Support\Enums\Width; use Filament\Support\Enums\Width;
use Filament\View\PanelsRenderHook; use Filament\View\PanelsRenderHook;
use Filament\Widgets\AccountWidget; use Filament\Widgets\AccountWidget;
@@ -39,15 +39,12 @@ class AdminPanelProvider extends PanelProvider
->id('admin') ->id('admin')
->path('app') ->path('app')
->login() ->login()
->registration()
->passwordReset() ->passwordReset()
->emailVerification() ->emailVerification()
->emailChangeVerification() ->emailChangeVerification()
->profile(isSimple: false) ->profile(isSimple: false)
->default() ->default()
->colors([ ->registration(Register::class)
'primary' => Color::Blue,
])
->renderHook( ->renderHook(
PanelsRenderHook::GLOBAL_SEARCH_BEFORE, PanelsRenderHook::GLOBAL_SEARCH_BEFORE,
fn (): string => auth()->user()->hasRole('konto_switch') ? Blade::render('@livewire(\'konto-switch\')') : false fn (): string => auth()->user()->hasRole('konto_switch') ? Blade::render('@livewire(\'konto-switch\')') : false
+2 -1
View File
@@ -13,6 +13,7 @@
"agencetwogether/hookshelper": "^0.0.2", "agencetwogether/hookshelper": "^0.0.2",
"awcodes/light-switch": "^2.0", "awcodes/light-switch": "^2.0",
"bezhansalleh/filament-shield": "*", "bezhansalleh/filament-shield": "*",
"danielebarbaro/laravel-vat-eu-validator": "^2.0",
"filament/filament": "^4.0", "filament/filament": "^4.0",
"laravel/framework": "^12.0", "laravel/framework": "^12.0",
"laravel/tinker": "^2.10.1", "laravel/tinker": "^2.10.1",
@@ -20,7 +21,7 @@
"mallardduck/blade-lucide-icons": "^1.23", "mallardduck/blade-lucide-icons": "^1.23",
"spatie/laravel-login-link": "^1.6", "spatie/laravel-login-link": "^1.6",
"swisnl/filament-backgrounds": "^2.0", "swisnl/filament-backgrounds": "^2.0",
"ysfkaya/filament-phone-input": "^4.0@beta" "ysfkaya/filament-phone-input": "^4.0"
}, },
"require-dev": { "require-dev": {
"fakerphp/faker": "^1.23", "fakerphp/faker": "^1.23",
Generated
+84 -4
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "86131fc6e2814af73859860025a45afe", "content-hash": "e843dbb981a84e2803fa4c750466dd27",
"packages": [ "packages": [
{ {
"name": "agencetwogether/hookshelper", "name": "agencetwogether/hookshelper",
@@ -933,6 +933,88 @@
], ],
"time": "2025-02-21T08:52:11+00:00" "time": "2025-02-21T08:52:11+00:00"
}, },
{
"name": "danielebarbaro/laravel-vat-eu-validator",
"version": "v2.0.7",
"source": {
"type": "git",
"url": "https://github.com/danielebarbaro/laravel-vat-eu-validator.git",
"reference": "d4430aecf3d7d5bb8ff4c370b06706de51a0f543"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/danielebarbaro/laravel-vat-eu-validator/zipball/d4430aecf3d7d5bb8ff4c370b06706de51a0f543",
"reference": "d4430aecf3d7d5bb8ff4c370b06706de51a0f543",
"shasum": ""
},
"require": {
"ext-openssl": "*",
"ext-soap": "*",
"illuminate/contracts": "^10.0|^11.0|^12.0",
"illuminate/support": "^10.0|^11.0|^12.0",
"php": "^8.2"
},
"require-dev": {
"driftingly/rector-laravel": "^2.0",
"friendsofphp/php-cs-fixer": "^3.59",
"orchestra/testbench": "^8.1|^9.1|^10.0",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan": "^2.1",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^10.5|^11.0",
"rector/rector": "^2.0"
},
"type": "library",
"extra": {
"laravel": {
"aliases": {
"VatValidator": "Danielebarbaro\\LaravelVatEuValidator\\Facades\\VatValidatorFacade"
},
"providers": [
"Danielebarbaro\\LaravelVatEuValidator\\VatValidatorServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Danielebarbaro\\LaravelVatEuValidator\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Daniele Barbaro",
"email": "barbaro.daniele@gmail.com",
"role": "Developer"
}
],
"description": "A simple package that validates EU VAT numbers against the central ec.europa.eu database",
"homepage": "https://github.com/danielebarbaro/laravel-vat-eu-validator",
"keywords": [
"danielebarbaro",
"laravel",
"laravel-validator",
"laravel-vat-eu-validator",
"laravel-vat-validator",
"vat",
"vat-eu-validator",
"vat-validator"
],
"support": {
"source": "https://github.com/danielebarbaro/laravel-vat-eu-validator/tree/v2.0.7"
},
"funding": [
{
"url": "https://github.com/danielebarbaro",
"type": "github"
}
],
"time": "2025-03-15T11:08:06+00:00"
},
{ {
"name": "dflydev/dot-access-data", "name": "dflydev/dot-access-data",
"version": "v3.0.3", "version": "v3.0.3",
@@ -12312,9 +12394,7 @@
], ],
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": { "stability-flags": [],
"ysfkaya/filament-phone-input": 10
},
"prefer-stable": true, "prefer-stable": true,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
@@ -21,6 +21,8 @@ return new class extends Migration
$table->string('address')->nullable(); $table->string('address')->nullable();
$table->string('place')->nullable(); $table->string('place')->nullable();
$table->string('code')->nullable(); $table->string('code')->nullable();
$table->string('country')->nullable();
$table->string('konto-email')->nullable();
$table->string('phone')->nullable(); $table->string('phone')->nullable();
$table->string('uid_number')->nullable(); $table->string('uid_number')->nullable();
$table->timestamps(); $table->timestamps();
@@ -0,0 +1,18 @@
<?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::create('users', function (Blueprint $table) {
$table->string('role')->nullable()->after('password');
});
}
};
+1 -1
View File
@@ -15,7 +15,7 @@ class KontoSeeder extends Seeder
$sql = "INSERT INTO `kontos` (`id`, `title`, `gender`, `first_name`, `last_name`, `company`, `address`, `place`, `code`, `phone`, `uid_number`) $sql = "INSERT INTO `kontos` (`id`, `title`, `gender`, `first_name`, `last_name`, `company`, `address`, `place`, `code`, `phone`, `uid_number`)
VALUES VALUES
('1', 'Architekt', 'Herr','Bruno','Kunz','Architekt Kunz','Pradlerstraße 11','Innbsruck', '6020', '0512 457328', 'ATU 234578'), ('1', 'Architekt', 'Herr','Bruno','Kunz','Architekt Kunz','Pradlerstraße 11','Innbsruck', '6020', '0512 457328', 'ATU 234578'),
('2', 'Architekt', 'Herr','Sepp','Unterlugauer','Architekt KunzUnterlugauer','Seestraße 1','Innbsruck', '6020', '0512 457328', 'ATU 234578'); ('2', 'Architekt', 'Herr','Sepp','Unterlugauer','Architekt Unterlugauer','Seestraße 1','Innbsruck', '6020', '0512 457328', 'ATU 234578');
"; ";
DB::unprepared($sql); DB::unprepared($sql);
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

+4
View File
@@ -4,3 +4,7 @@
@source '../../../../resources/views/**/*'; @source '../../../../resources/views/**/*';
@source '../../../../resources/views/filament/**/*'; @source '../../../../resources/views/filament/**/*';
@source '../../../../vendor/awcodes/light-switch/resources/**/*.blade.php'; @source '../../../../vendor/awcodes/light-switch/resources/**/*.blade.php';
.fi-simple-main {
@apply relative sm:max-w-3xl;
}
@@ -0,0 +1,3 @@
<x-filament-panels::page>
{{-- Page content --}}
</x-filament-panels::page>
+4 -12
View File
@@ -34,20 +34,12 @@
@include('layouts.nav') @include('layouts.nav')
<br> <main class="mx-auto mt-30 rounded-2xl p-10 max-w-5xl shadow-2xl bg-white/80 dark:bg-gray-900/90">
<br> @yield('content')
<div class="fi-simple-layout"> </main>
<main class="fi-simple-main fi-width-5xl shadow-2xl bg-white/80 dark:bg-gray-900/90">
<div class="bg-cover bg-position-[center_top_3.8rem]">
@yield('content') @include('layouts.footer');
</div>
</main>
@include('layouts.footer');
</div>
@filamentScripts @filamentScripts
</body> </body>
+2 -2
View File
@@ -1,6 +1,6 @@
<footer class="fixed bottom-0 z-20 p-4"> <footer class="fixed bottom-0 right-0 left-0 z-20 p-4">
<a href="https://webwerkstatt.tirol" target="_blank" <a href="https://webwerkstatt.tirol" target="_blank"
class="mx-auto cursor-pointer text-xs bg-white dark:bg-black px-2 rounded-sm opacity-70 flex"> class="w-60 mx-auto cursor-pointer text-xs bg-white dark:bg-black px-2 rounded-sm opacity-70 flex">
<span>&copy 2007-{{ date('Y') }} &middot; </span> <span>&copy 2007-{{ date('Y') }} &middot; </span>
<span class=" tracking-tight text-xs ml-1 font-bold"> <span class=" tracking-tight text-xs ml-1 font-bold">
Web<span class="text-primary-800 dark:text-primary-600 font-black">Werkstatt</span><span Web<span class="text-primary-800 dark:text-primary-600 font-black">Werkstatt</span><span
+21 -20
View File
@@ -2,8 +2,7 @@
@section('content') @section('content')
<div class="text-gray-700 dark:text-gray-200"> <div class="text-gray-700 dark:text-gray-200">
<div class="flex gap-7 leading-6">
<div class="flex gap-7">
<x-filament::section> <x-filament::section>
<x-slot name="heading"> <x-slot name="heading">
<x-title> <x-title>
@@ -12,7 +11,7 @@
</x-slot> </x-slot>
<svg xmlns="http://www.w3.org/2000/svg" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" <svg xmlns="http://www.w3.org/2000/svg" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="lucide lucide-building-icon lucide-building"> class="lucide lucide-building-icon lucide-building mx-auto">
<path d="M12 10h.01" /> <path d="M12 10h.01" />
<path d="M12 14h.01" /> <path d="M12 14h.01" />
<path d="M12 6h.01" /> <path d="M12 6h.01" />
@@ -25,17 +24,20 @@
<path d="M9 22v-3a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3" /> <path d="M9 22v-3a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3" />
<rect x="4" y="2" width="16" height="20" rx="2" /> <rect x="4" y="2" width="16" height="20" rx="2" />
</svg> </svg>
Die Nutzwertberechnung ist ein Gutachten im österreichischen Wohnungseigentumsrecht, das das Verhältnis der <p class="indent-8">
einzelnen Die Nutzwertberechnung ist ein Gutachten im österreichischen Wohnungseigentumsrecht, das das Verhältnis
Eigentumsanteile innerhalb eines Gebäudes bestimmt. <x-filament::link href="/nutzwerte" der
icon-position="after" icon="lucide-external-link"> einzelnen
Über die Nutzwertberechnung Eigentumsanteile innerhalb eines Gebäudes bestimmt. <x-filament::link href="/nutzwerte"
</x-filament::link> icon-position="after" icon="lucide-external-link">
Über die Nutzwertberechnung
</x-filament::link>
</p>
<br> <br>
<br> <br>
<svg xmlns="http://www.w3.org/2000/svg" width="32" viewBox="0 0 24 24" fill="none" <svg xmlns="http://www.w3.org/2000/svg" width="32" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="lucide lucide-school-icon lucide-school"> class="lucide lucide-school-icon lucide-school mx-auto">
<path d="M14 21v-3a2 2 0 0 0-4 0v3" /> <path d="M14 21v-3a2 2 0 0 0-4 0v3" />
<path d="M18 5v16" /> <path d="M18 5v16" />
<path d="m4 6 7.106-3.79a2 2 0 0 1 1.788 0L20 6" /> <path d="m4 6 7.106-3.79a2 2 0 0 1 1.788 0L20 6" />
@@ -44,18 +46,17 @@
<path d="M6 5v16" /> <path d="M6 5v16" />
<circle cx="12" cy="9" r="2" /> <circle cx="12" cy="9" r="2" />
</svg> </svg>
Wie Ihnen dieses Programm bei der Nutzwertberechnung zur Hand gehen kann, und Ihnen wertvolle Zeit bei der <p class="indent-8 mb-10">
Berechnung und Formatierung sparen hilft, erfahren sie hier. Wie Ihnen dieses Programm bei der Nutzwertberechnung zur Hand gehen kann, und Ihnen wertvolle Zeit bei
<br><x-filament::link href="/dieses-programm" icon-position="after" icon="lucide-external-link"> der
Über dieses Programm Berechnung und Formatierung sparen hilft, erfahren sie hier.
</x-filament::link> <br><x-filament::link href="/dieses-programm" icon-position="after" icon="lucide-external-link">
<br> Über dieses Programm
<br> </x-filament::link>
<br> </p>
<br>
<br>
@include('components.login') @include('components.login')
</x-filament::section> </x-filament::section>
<img src="images/house.jpg" class="w-82 rounded-2xl border border-gray-300" /> <img src="images/house.jpg" class="w-82 rounded-2xl border border-gray-300" />
</div> </div>
+1
View File
@@ -16,6 +16,7 @@ case "$1" in
php artisan optimize php artisan optimize
;; ;;
"3") "3")
php artisan filament:optimize-clear
php artisan route:clear php artisan route:clear
php artisan cache:clear php artisan cache:clear
php artisan icons:clear php artisan icons:clear