UserResource
Die UserResource verwaltet alle Benutzer der Plattform (Administratoren, Auftraggeber, Sprachmittler).
Konfiguration
File: UserResource.php
| Eigenschaft | Wert |
|---|---|
| Model | App\Models\User |
| Navigation Group | Benutzerverwaltung |
| Navigation Label | Benutzer |
| Navigation Icon | heroicon-o-users |
| Navigation Sort | 1 |
State Machine
Form-Struktur
Das Formular passt sich dynamisch an die Benutzerrolle an.
Basisfelder (alle Rollen)
| Feld | Typ | Validierung |
|---|---|---|
| role | Select | required, in:admin,requester,interpreter |
| state | Select | required |
| salutation | Select | nullable |
| first_name | TextInput | required, max:255 |
| last_name | TextInput | required, max:255 |
| TextInput | required, email, unique | |
| phone | TextInput | nullable, tel |
| password | TextInput | required (create), min:8 |
Auftraggeber-spezifische Felder
Sichtbar wenn role === 'requester':
Organisation
| Feld | Typ | Beschreibung |
|---|---|---|
| organization_name | TextInput | Name der Organisation |
| organization_type | Select | government, healthcare, school, social_services, legal, other |
| billing_email | TextInput | Rechnungs-E-Mail |
Rechnungsadresse
| Feld | Typ |
|---|---|
| billing_street | TextInput |
| billing_house_number | TextInput |
| billing_postal_code | TextInput |
| billing_city | TextInput |
Sprachmittler-spezifische Felder
Sichtbar wenn role === 'interpreter':
Adresse
| Feld | Typ | Validierung |
|---|---|---|
| street | TextInput | required |
| house_number | TextInput | required |
| postal_code | TextInput | required |
| city | TextInput | required |
Arbeitseinstellungen
| Feld | Typ | Beschreibung |
|---|---|---|
| max_distance | TextInput | 10-100 km |
| available_for_selection | Toggle | Für Auswahl verfügbar |
| notes | Textarea | Interne Notizen |
| working_hours | Repeater | Arbeitszeiten pro Wochentag |
Working Hours Struktur:
Repeater::make('working_hours')
->schema([
Select::make('day')
->options([
'monday' => 'Montag',
'tuesday' => 'Dienstag',
// ...
]),
TimePicker::make('start_time'),
TimePicker::make('end_time'),
])
Skills & Kategorien
| Feld | Typ | Beschreibung |
|---|---|---|
| language_skills | Select (multiple) | SystemLanguage Multi-Select |
| category_blacklist | Select (multiple) | Kategorien, die nicht bedient werden |
Finanzinformationen
| Feld | Typ | Beschreibung |
|---|---|---|
| tax_id | TextInput | Steuer-ID |
| bank_account_owner | TextInput | Kontoinhaber |
| iban | TextInput | IBAN |
| bic | TextInput | BIC |
| billing_type | Select | Abrechnungsart |
Code-Beispiel: Rollenbasiertes Formular
public static function form(Form $form): Form
{
return $form->schema([
Forms\Components\Section::make('Benutzerdaten')
->schema([
Forms\Components\Select::make('role')
->options([
'admin' => 'Administrator',
'requester' => 'Auftraggeber',
'interpreter' => 'Sprachmittler',
])
->required()
->live(), // Wichtig für reactive visibility
// Weitere Basisfelder...
]),
// Nur für Auftraggeber
Forms\Components\Section::make('Organisation')
->visible(fn (Get $get) => $get('role') === 'requester')
->schema([
Forms\Components\TextInput::make('organization_name')
->required(),
// ...
]),
// Nur für Sprachmittler
Forms\Components\Section::make('Arbeitseinstellungen')
->visible(fn (Get $get) => $get('role') === 'interpreter')
->schema([
Forms\Components\TextInput::make('max_distance')
->numeric()
->minValue(10)
->maxValue(100)
->suffix('km'),
// ...
]),
]);
}
Table-Konfiguration
Spalten
| Spalte | Typ | Beschreibung |
|---|---|---|
| name | TextColumn | Mit Anrede und E-Mail als Description |
| roles | BadgeColumn | Farbcodiert nach Rolle |
| state | BadgeColumn | Farbcodiert nach Status |
| email_verified_at | IconColumn | ✓ wenn verifiziert |
| orders_count | TextColumn | Anzahl Aufträge |
| phone | TextColumn | Telefonnummer |
| last_login_at | TextColumn | Letzter Login |
State-Badges
Tables\Columns\TextColumn::make('state')
->badge()
->color(fn (string $state): string => match ($state) {
'requested' => 'warning',
'active' => 'success',
'rejected' => 'danger',
'deactivated' => 'gray',
})
Filter
| Filter | Typ | Optionen |
|---|---|---|
| state | SelectFilter | Requested, Active, Rejected, Deactivated |
| role | SelectFilter | Admin, Requester, Interpreter |
Actions
Einzel-Actions
| Action | Icon | Beschreibung |
|---|---|---|
| view | eye | Benutzer anzeigen |
| edit | pencil | Benutzer bearbeiten |
Bulk Actions
| Action | Icon | State-Transition | Sichtbarkeit |
|---|---|---|---|
| activate | check | → Active | state !== Active |
| deactivate | x-mark | → Deactivated | state === Active |
| reject | ban | → Rejected | state === Requested |
| delete | trash | - | - |
Header Actions
protected function getHeaderActions(): array
{
return [
ExportAction::make()
->exporter(UserExporter::class)
->formats([
ExportFormat::Xlsx,
ExportFormat::Csv,
]),
];
}
Relation Managers
NotificationPreferencesRelationManager
Zeigt und bearbeitet die Benachrichtigungs-Einstellungen des Benutzers.
| Spalte | Typ | Beschreibung |
|---|---|---|
| notification_type | TextColumn | Benachrichtigungstyp |
| email_enabled | ToggleColumn | E-Mail aktiviert |
| push_enabled | ToggleColumn | Push aktiviert |
| database_enabled | BadgeColumn | Immer aktiv |
LegalDocumentAcceptancesRelationManager
Zeigt akzeptierte Rechtstexte.
| Spalte | Beschreibung |
|---|---|
| legal_document.title | Dokumenttitel |
| legal_document.version | Version |
| accepted_at | Akzeptiert am |
| ip_address | IP-Adresse |
Global Search
public static function getGlobalSearchResultTitle(Model $record): string
{
return $record->full_name;
}
public static function getGloballySearchableAttributes(): array
{
return ['first_name', 'last_name', 'email'];
}
Pages
| Page | Beschreibung |
|---|---|
| ListUsers | Übersichtstabelle |
| CreateUser | Benutzer erstellen |
| ViewUser | Detailansicht mit Relation Managers |
| EditUser | Benutzer bearbeiten |