23-01-2026
This commit is contained in:
parent
07959c0ba2
commit
854ce02bf6
166 changed files with 32909 additions and 1262 deletions
441
resources/views/livewire/partner/my-data.blade.php
Normal file
441
resources/views/livewire/partner/my-data.blade.php
Normal file
|
|
@ -0,0 +1,441 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Partner;
|
||||
use App\Models\Brand;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Str;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Title;
|
||||
use Livewire\Volt\Component;
|
||||
|
||||
new #[Layout('components.layouts.app'), Title('Meine Daten')] class extends Component {
|
||||
public Partner $partner;
|
||||
public string $partnerType;
|
||||
|
||||
// Stammdaten
|
||||
public string $companyName = '';
|
||||
public string $displayName = '';
|
||||
public string $salutation = '';
|
||||
public string $firstName = '';
|
||||
public string $lastName = '';
|
||||
public string $description = '';
|
||||
public string $street = '';
|
||||
public string $houseNumber = '';
|
||||
public string $zip = '';
|
||||
public string $city = '';
|
||||
public string $country = 'Deutschland';
|
||||
public string $phone = '';
|
||||
public string $website = '';
|
||||
|
||||
// Retailer - Liefergebiete
|
||||
public ?int $deliveryRadius = null;
|
||||
public ?int $assemblyRadius = null;
|
||||
|
||||
// Manufacturer - Marke
|
||||
public string $brandName = '';
|
||||
public string $brandDescription = '';
|
||||
|
||||
public string $roleIcon = 'shield-check';
|
||||
public string $roleName = '-';
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if (!$user->partner_id) {
|
||||
$this->redirect(route('dashboard'), navigate: true);
|
||||
return;
|
||||
}
|
||||
|
||||
$role = $user->roles->first();
|
||||
if ($role) {
|
||||
$this->roleIcon = $role->icon ?? 'shield-check';
|
||||
$this->roleName = $role->display_name ?? $role->name;
|
||||
}
|
||||
|
||||
$this->partner = Partner::with('users')->findOrFail($user->partner_id);
|
||||
$this->partnerType = $this->partner->type;
|
||||
|
||||
// Vorausfüllen: Partner-Daten
|
||||
$this->companyName = $this->partner->company_name ?? '';
|
||||
$this->displayName = $this->partner->display_name ?? '';
|
||||
$this->salutation = $this->partner->salutation ?? '';
|
||||
$this->firstName = $this->partner->first_name ?? '';
|
||||
$this->lastName = $this->partner->last_name ?? '';
|
||||
$this->description = $this->partner->description ?? '';
|
||||
$this->street = $this->partner->street ?? '';
|
||||
$this->houseNumber = $this->partner->house_number ?? '';
|
||||
$this->zip = $this->partner->zip ?? '';
|
||||
$this->city = $this->partner->city ?? '';
|
||||
$this->country = $this->partner->country ?? 'Deutschland';
|
||||
$this->phone = $this->partner->phone ?? '';
|
||||
$this->website = $this->partner->website ?? '';
|
||||
$this->deliveryRadius = $this->partner->delivery_radius_km;
|
||||
$this->assemblyRadius = $this->partner->assembly_radius_km;
|
||||
|
||||
// Ersetze Platzhalter wie "roles.broker M10000004" durch Übersetzung + ID
|
||||
if(strpos($this->companyName, 'roles.') !== false) {
|
||||
$parts = explode(' ', $this->companyName, 2);
|
||||
$translatedRole = isset($parts[0]) ? __($parts[0]) : $this->companyName;
|
||||
$partnerId = isset($parts[1]) ? ' ' . $parts[1] : '';
|
||||
$this->companyName = $translatedRole . $partnerId;
|
||||
}
|
||||
|
||||
// Namen aus User übernehmen, falls Partner-Felder leer sind
|
||||
if (empty($this->firstName) && empty($this->lastName)) {
|
||||
$nameParts = explode(' ', $user->name, 2);
|
||||
$this->firstName = $nameParts[0] ?? '';
|
||||
$this->lastName = $nameParts[1] ?? '';
|
||||
}
|
||||
|
||||
// Marke laden für Manufacturer
|
||||
if (strtolower(str_replace('-', '', $this->partnerType)) === 'manufacturer') {
|
||||
$brand = Brand::where('partner_id', $this->partner->id)->first();
|
||||
if ($brand) {
|
||||
$this->brandName = $brand->name;
|
||||
$this->brandDescription = $brand->description ?? '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function saveData(): void
|
||||
{
|
||||
$normalizedType = strtolower(str_replace('-', '', $this->partnerType));
|
||||
$isCustomer = $normalizedType === 'customer';
|
||||
$isBroker = $normalizedType === 'broker' || $normalizedType === 'estateagent';
|
||||
$isRetailer = $normalizedType === 'retailer';
|
||||
$isManufacturer = $normalizedType === 'manufacturer';
|
||||
|
||||
$rules = [
|
||||
'salutation' => 'required|in:Herr,Frau,Divers',
|
||||
'firstName' => 'required|string|max:255',
|
||||
'lastName' => 'required|string|max:255',
|
||||
'street' => 'required|string|max:255',
|
||||
'houseNumber' => 'required|string|max:20',
|
||||
'zip' => 'required|string|max:10',
|
||||
'city' => 'required|string|max:255',
|
||||
'country' => 'required|string|max:255',
|
||||
'phone' => 'nullable|string|max:50',
|
||||
];
|
||||
|
||||
if (!$isCustomer) {
|
||||
$rules['companyName'] = 'required|string|max:255';
|
||||
$rules['description'] = 'nullable|string|max:1000';
|
||||
$rules['website'] = 'nullable|url|max:255';
|
||||
}
|
||||
|
||||
if ($isBroker) {
|
||||
$rules['displayName'] = 'required|string|max:255';
|
||||
}
|
||||
|
||||
if ($isRetailer) {
|
||||
$rules['deliveryRadius'] = 'required|integer|min:1|max:500';
|
||||
$rules['assemblyRadius'] = 'required|integer|min:1|max:500';
|
||||
}
|
||||
|
||||
if ($isManufacturer) {
|
||||
$rules['brandName'] = 'required|string|max:255';
|
||||
$rules['brandDescription'] = 'nullable|string|max:1000';
|
||||
}
|
||||
|
||||
$this->validate($rules, [
|
||||
'salutation.required' => __('Bitte wählen Sie eine Anrede.'),
|
||||
'firstName.required' => __('Bitte geben Sie einen Vornamen ein.'),
|
||||
'lastName.required' => __('Bitte geben Sie einen Nachnamen ein.'),
|
||||
'companyName.required' => __('Bitte geben Sie einen Firmennamen ein.'),
|
||||
'displayName.required' => __('Bitte geben Sie einen Anzeigenamen ein.'),
|
||||
'street.required' => __('Bitte geben Sie eine Straße ein.'),
|
||||
'houseNumber.required' => __('Bitte geben Sie eine Hausnummer ein.'),
|
||||
'zip.required' => __('Bitte geben Sie eine Postleitzahl ein.'),
|
||||
'city.required' => __('Bitte geben Sie eine Stadt ein.'),
|
||||
'country.required' => __('Bitte wählen Sie ein Land.'),
|
||||
'website.url' => __('Bitte geben Sie eine gültige URL ein.'),
|
||||
'deliveryRadius.required' => __('Bitte geben Sie einen Lieferradius ein.'),
|
||||
'deliveryRadius.min' => __('Der Lieferradius muss mindestens 1 km betragen.'),
|
||||
'assemblyRadius.required' => __('Bitte geben Sie einen Montageradius ein.'),
|
||||
'assemblyRadius.min' => __('Der Montageradius muss mindestens 1 km betragen.'),
|
||||
'brandName.required' => __('Bitte geben Sie einen Markennamen ein.'),
|
||||
]);
|
||||
|
||||
// Update Partner
|
||||
$updateData = [
|
||||
'salutation' => $this->salutation,
|
||||
'first_name' => $this->firstName,
|
||||
'last_name' => $this->lastName,
|
||||
'street' => $this->street,
|
||||
'house_number' => $this->houseNumber,
|
||||
'zip' => $this->zip,
|
||||
'city' => $this->city,
|
||||
'country' => $this->country,
|
||||
'phone' => $this->phone,
|
||||
];
|
||||
|
||||
if (!$isCustomer) {
|
||||
$updateData['company_name'] = $this->companyName;
|
||||
$updateData['description'] = $this->description;
|
||||
$updateData['website'] = $this->website;
|
||||
}
|
||||
|
||||
if ($isBroker) {
|
||||
$updateData['display_name'] = $this->displayName;
|
||||
}
|
||||
|
||||
if ($isRetailer) {
|
||||
$updateData['delivery_radius_km'] = $this->deliveryRadius;
|
||||
$updateData['assembly_radius_km'] = $this->assemblyRadius;
|
||||
}
|
||||
|
||||
$this->partner->update($updateData);
|
||||
|
||||
// Für Manufacturer: Marke aktualisieren oder erstellen
|
||||
if ($isManufacturer) {
|
||||
Brand::updateOrCreate(
|
||||
['partner_id' => $this->partner->id],
|
||||
[
|
||||
'name' => $this->brandName,
|
||||
'slug' => Str::slug($this->brandName),
|
||||
'description' => $this->brandDescription,
|
||||
'is_active' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
session()->flash('message', __('Ihre Daten wurden erfolgreich aktualisiert.'));
|
||||
}
|
||||
}; ?>
|
||||
|
||||
<div class="space-y-6">
|
||||
{{-- Header --}}
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<flux:heading size="xl">{{ __('Meine Daten') }}</flux:heading>
|
||||
<flux:subheading>{{ __('Verwalten Sie Ihre Firmendaten und Kontaktinformationen') }}</flux:subheading>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
@svg('heroicon-o-'.$roleIcon, 'w-6 h-6 text-accent-600 dark:text-accent-400')
|
||||
<span class="text-sm font-medium text-zinc-700 dark:text-zinc-300">{{ $roleName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Success Message --}}
|
||||
<x-success-alert />
|
||||
|
||||
{{-- Formular --}}
|
||||
<flux:card>
|
||||
<form wire:submit="saveData" class="space-y-6">
|
||||
@php
|
||||
$isCustomer = strtolower(str_replace('-', '', $partnerType)) === 'customer';
|
||||
$isRetailer = strtolower(str_replace('-', '', $partnerType)) === 'retailer';
|
||||
$isManufacturer = strtolower(str_replace('-', '', $partnerType)) === 'manufacturer';
|
||||
$isBroker = strtolower(str_replace('-', '', $partnerType)) === 'broker' || strtolower(str_replace('-', '', $partnerType)) === 'estateagent';
|
||||
@endphp
|
||||
|
||||
{{-- Firmenname (nur für Nicht-Kunden) --}}
|
||||
@if (!$isCustomer)
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Firmenname') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:input wire:model="companyName" name="companyName" icon="building-office" placeholder="{{ __('z.B. Müller GmbH') }}" />
|
||||
@error('companyName')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
|
||||
@if ($isBroker)
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Anzeigename') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:description>{{ __('Der Name, der Ihren Kunden angezeigt wird') }}</flux:description>
|
||||
<flux:input wire:model="displayName" name="displayName" icon="user" placeholder="{{ __('z.B. Max Schmidt') }}" />
|
||||
@error('displayName')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
@endif
|
||||
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Kurzbeschreibung') }} ({{ __('optional') }})</flux:label>
|
||||
<flux:textarea wire:model="description" name="description" rows="3" placeholder="{{ __('Ein kurzer Text über Ihr Unternehmen...') }}" />
|
||||
@error('description')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
|
||||
<flux:separator />
|
||||
@endif
|
||||
|
||||
{{-- Persönliche Daten --}}
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Anrede') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:select wire:model="salutation" name="salutation">
|
||||
<flux:select.option value="">{{ __('Bitte wählen') }}</flux:select.option>
|
||||
<flux:select.option value="Herr">{{ __('Herr') }}</flux:select.option>
|
||||
<flux:select.option value="Frau">{{ __('Frau') }}</flux:select.option>
|
||||
<flux:select.option value="Divers">{{ __('Divers') }}</flux:select.option>
|
||||
</flux:select>
|
||||
@error('salutation')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Vorname') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:input wire:model="firstName" name="firstName" icon="user" />
|
||||
@error('firstName')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Nachname') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:input wire:model="lastName" name="lastName" icon="user" />
|
||||
@error('lastName')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
</div>
|
||||
|
||||
<flux:separator />
|
||||
|
||||
{{-- Adresse --}}
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
||||
<flux:field class="md:col-span-3">
|
||||
<flux:label>{{ __('Straße') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:input wire:model="street" name="street" icon="map-pin" placeholder="{{ __('Musterstraße') }}" />
|
||||
@error('street')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Hausnummer') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:input wire:model="houseNumber" name="houseNumber" placeholder="{{ __('123a') }}" />
|
||||
@error('houseNumber')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Postleitzahl') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:input wire:model="zip" name="zip" icon="map" placeholder="{{ __('12345') }}" />
|
||||
@error('zip')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
|
||||
<flux:field class="md:col-span-2">
|
||||
<flux:label>{{ __('Ort') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:input wire:model="city" name="city" icon="building-office" placeholder="{{ __('Musterstadt') }}" />
|
||||
@error('city')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
</div>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Land') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:select wire:model="country" name="country">
|
||||
<flux:select.option value="Deutschland">{{ __('Deutschland') }}</flux:select.option>
|
||||
<flux:select.option value="Österreich">{{ __('Österreich') }}</flux:select.option>
|
||||
<flux:select.option value="Schweiz">{{ __('Schweiz') }}</flux:select.option>
|
||||
</flux:select>
|
||||
@error('country')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Telefon') }}</flux:label>
|
||||
<flux:input wire:model="phone" name="phone" type="tel" icon="phone" placeholder="{{ __('optional') }}" />
|
||||
@error('phone')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
|
||||
@if (!$isCustomer)
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Website') }}</flux:label>
|
||||
<flux:input wire:model="website" name="website" type="url" icon="globe-alt" placeholder="https://..." />
|
||||
@error('website')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
@endif
|
||||
|
||||
{{-- Liefergebiete für Händler (Retailer) --}}
|
||||
@if ($isRetailer)
|
||||
<flux:separator />
|
||||
|
||||
<div class="bg-blue-50 dark:bg-blue-900/20 p-4 rounded-lg">
|
||||
<p class="text-sm text-blue-800 dark:text-blue-200 font-medium mb-1">
|
||||
{{ __('Liefergebiete') }}
|
||||
</p>
|
||||
<p class="text-xs text-blue-600 dark:text-blue-300">
|
||||
{{ __('Definieren Sie, in welchem Umkreis Sie liefern und montieren können.') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Lieferradius (km)') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:description>{{ __('Ich liefere im Umkreis von ... km') }}</flux:description>
|
||||
<flux:input wire:model="deliveryRadius" name="deliveryRadius" type="number" min="1" max="500" placeholder="z.B. 50" />
|
||||
@error('deliveryRadius')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Montageradius (km)') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:description>{{ __('Ich montiere im Umkreis von ... km') }}</flux:description>
|
||||
<flux:input wire:model="assemblyRadius" name="assemblyRadius" type="number" min="1" max="500" placeholder="z.B. 30" />
|
||||
@error('assemblyRadius')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Marke für Hersteller (Manufacturer) --}}
|
||||
@if ($isManufacturer)
|
||||
<flux:separator />
|
||||
|
||||
<div class="bg-purple-50 dark:bg-purple-900/20 p-4 rounded-lg">
|
||||
<p class="text-sm text-purple-800 dark:text-purple-200 font-medium mb-1">
|
||||
{{ __('Ihre Marke') }}
|
||||
</p>
|
||||
<p class="text-xs text-purple-600 dark:text-purple-300">
|
||||
{{ __('Unter dieser Marke werden Ihre Produkte auf B2In gelistet.') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Markenname') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:input wire:model="brandName" name="brandName" icon="tag" placeholder="{{ __('z.B. Möbelwerke Premium') }}" />
|
||||
@error('brandName')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Marken-Beschreibung') }} ({{ __('optional') }})</flux:label>
|
||||
<flux:textarea wire:model="brandDescription" name="brandDescription" rows="4" placeholder="{{ __('Ein kurzer Text über Ihre Marke...') }}" />
|
||||
@error('brandDescription')
|
||||
<flux:error>{{ $message }}</flux:error>
|
||||
@enderror
|
||||
</flux:field>
|
||||
@endif
|
||||
|
||||
<flux:separator />
|
||||
|
||||
<x-error-alert />
|
||||
|
||||
<div class="flex justify-end">
|
||||
<flux:button type="submit" variant="primary" icon="check-circle">
|
||||
{{ __('Änderungen speichern') }}
|
||||
</flux:button>
|
||||
</div>
|
||||
</form>
|
||||
</flux:card>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue