diff --git a/app/Filament/Pages/Auth/Register.php b/app/Filament/Pages/Auth/Register.php
new file mode 100644
index 0000000..84bb68e
--- /dev/null
+++ b/app/Filament/Pages/Auth/Register.php
@@ -0,0 +1,200 @@
+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();
+ }
+}
diff --git a/app/Models/User.php b/app/Models/User.php
index 8b4c40a..ca9d125 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -30,6 +30,7 @@ class User extends Authenticatable implements FilamentUser, HasAppAuthentication
'email',
'konto_id',
'password',
+ 'role',
'super_admin',
'app_verified_at',
'first_name',
@@ -76,6 +77,9 @@ class User extends Authenticatable implements FilamentUser, HasAppAuthentication
{
static::addGlobalScope(new KontoScope);
+ static::creating(function (User $user) {
+ $user->role = 'gutachter';
+ });
}
public function getAppAuthenticationSecret(): ?string
diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php
index 72e7b0f..4fe43ad 100644
--- a/app/Providers/Filament/AdminPanelProvider.php
+++ b/app/Providers/Filament/AdminPanelProvider.php
@@ -3,6 +3,7 @@
namespace App\Providers\Filament;
use Agencetwogether\HooksHelper\HooksHelperPlugin;
+use App\Filament\Pages\Auth\Register;
use App\Http\Middleware\AppUserVerifiedMiddleware;
use Awcodes\LightSwitch\Enums\Alignment;
use Awcodes\LightSwitch\LightSwitchPlugin;
@@ -16,7 +17,6 @@ use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Pages\Dashboard;
use Filament\Panel;
use Filament\PanelProvider;
-use Filament\Support\Colors\Color;
use Filament\Support\Enums\Width;
use Filament\View\PanelsRenderHook;
use Filament\Widgets\AccountWidget;
@@ -39,15 +39,12 @@ class AdminPanelProvider extends PanelProvider
->id('admin')
->path('app')
->login()
- ->registration()
->passwordReset()
->emailVerification()
->emailChangeVerification()
->profile(isSimple: false)
->default()
- ->colors([
- 'primary' => Color::Blue,
- ])
+ ->registration(Register::class)
->renderHook(
PanelsRenderHook::GLOBAL_SEARCH_BEFORE,
fn (): string => auth()->user()->hasRole('konto_switch') ? Blade::render('@livewire(\'konto-switch\')') : false
diff --git a/composer.json b/composer.json
index 2a86c95..c5d98b0 100644
--- a/composer.json
+++ b/composer.json
@@ -13,6 +13,7 @@
"agencetwogether/hookshelper": "^0.0.2",
"awcodes/light-switch": "^2.0",
"bezhansalleh/filament-shield": "*",
+ "danielebarbaro/laravel-vat-eu-validator": "^2.0",
"filament/filament": "^4.0",
"laravel/framework": "^12.0",
"laravel/tinker": "^2.10.1",
@@ -20,7 +21,7 @@
"mallardduck/blade-lucide-icons": "^1.23",
"spatie/laravel-login-link": "^1.6",
"swisnl/filament-backgrounds": "^2.0",
- "ysfkaya/filament-phone-input": "^4.0@beta"
+ "ysfkaya/filament-phone-input": "^4.0"
},
"require-dev": {
"fakerphp/faker": "^1.23",
diff --git a/composer.lock b/composer.lock
index 1b634ad..8e497b7 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "86131fc6e2814af73859860025a45afe",
+ "content-hash": "e843dbb981a84e2803fa4c750466dd27",
"packages": [
{
"name": "agencetwogether/hookshelper",
@@ -933,6 +933,88 @@
],
"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",
"version": "v3.0.3",
@@ -12312,9 +12394,7 @@
],
"aliases": [],
"minimum-stability": "stable",
- "stability-flags": {
- "ysfkaya/filament-phone-input": 10
- },
+ "stability-flags": [],
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
diff --git a/database/migrations/0001_01_01_000000__create_kontos_table.php b/database/migrations/0001_01_01_000000__create_kontos_table.php
index bb3ca52..f3b1088 100644
--- a/database/migrations/0001_01_01_000000__create_kontos_table.php
+++ b/database/migrations/0001_01_01_000000__create_kontos_table.php
@@ -21,6 +21,8 @@ return new class extends Migration
$table->string('address')->nullable();
$table->string('place')->nullable();
$table->string('code')->nullable();
+ $table->string('country')->nullable();
+ $table->string('konto-email')->nullable();
$table->string('phone')->nullable();
$table->string('uid_number')->nullable();
$table->timestamps();
diff --git a/database/migrations/0001_01_01_000002_add_role_to_users_table.php b/database/migrations/0001_01_01_000002_add_role_to_users_table.php
new file mode 100644
index 0000000..da17d1f
--- /dev/null
+++ b/database/migrations/0001_01_01_000002_add_role_to_users_table.php
@@ -0,0 +1,18 @@
+string('role')->nullable()->after('password');
+ });
+ }
+};
diff --git a/database/seeders/KontoSeeder.php b/database/seeders/KontoSeeder.php
index 2c9d14a..2d4fb03 100644
--- a/database/seeders/KontoSeeder.php
+++ b/database/seeders/KontoSeeder.php
@@ -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`)
VALUES
('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);
}
diff --git a/public/vendor/filament-phone-input/flags.webp b/public/vendor/filament-phone-input/flags.webp
new file mode 100644
index 0000000..e3a5c3f
Binary files /dev/null and b/public/vendor/filament-phone-input/flags.webp differ
diff --git a/public/vendor/filament-phone-input/flags@2x.webp b/public/vendor/filament-phone-input/flags@2x.webp
new file mode 100644
index 0000000..a6f669d
Binary files /dev/null and b/public/vendor/filament-phone-input/flags@2x.webp differ
diff --git a/public/vendor/filament-phone-input/globe.webp b/public/vendor/filament-phone-input/globe.webp
new file mode 100644
index 0000000..d1f2b85
Binary files /dev/null and b/public/vendor/filament-phone-input/globe.webp differ
diff --git a/public/vendor/filament-phone-input/globe@2x.webp b/public/vendor/filament-phone-input/globe@2x.webp
new file mode 100644
index 0000000..168bfa7
Binary files /dev/null and b/public/vendor/filament-phone-input/globe@2x.webp differ
diff --git a/resources/css/filament/admin/theme.css b/resources/css/filament/admin/theme.css
index 0a1b38a..10b7758 100644
--- a/resources/css/filament/admin/theme.css
+++ b/resources/css/filament/admin/theme.css
@@ -3,4 +3,8 @@
@source '../../../../app/Filament/**/*';
@source '../../../../resources/views/**/*';
@source '../../../../resources/views/filament/**/*';
-@source '../../../../vendor/awcodes/light-switch/resources/**/*.blade.php';
\ No newline at end of file
+@source '../../../../vendor/awcodes/light-switch/resources/**/*.blade.php';
+
+.fi-simple-main {
+ @apply relative sm:max-w-3xl;
+}
\ No newline at end of file
diff --git a/resources/views/filament/pages/auth/register.blade.php b/resources/views/filament/pages/auth/register.blade.php
new file mode 100644
index 0000000..bb8ed15
--- /dev/null
+++ b/resources/views/filament/pages/auth/register.blade.php
@@ -0,0 +1,3 @@
+
-
-