216 lines
10 KiB
PHP
216 lines
10 KiB
PHP
<?php
|
||
|
||
use App\Enums\ProductStatus;
|
||
use App\Models\Partner;
|
||
use App\Models\Product;
|
||
use Livewire\Volt\Component;
|
||
use function Livewire\Volt\{layout, title};
|
||
|
||
layout('components.layouts.app');
|
||
|
||
new class extends Component {
|
||
public Partner $partner;
|
||
public string $title = '';
|
||
|
||
public function mount(int $partnerId): void
|
||
{
|
||
$this->partner = Partner::with(['hub', 'products' => function ($q) {
|
||
$q->where('status', ProductStatus::Active)
|
||
->where('is_curated', true)
|
||
->where('is_available', true)
|
||
->with(['categories', 'media'])
|
||
->latest()
|
||
->limit(6);
|
||
}])->findOrFail($partnerId);
|
||
|
||
$this->title = $this->partner->display_name ?? $this->partner->company_name;
|
||
}
|
||
|
||
public function with(): array
|
||
{
|
||
return [
|
||
'partner' => $this->partner,
|
||
'products' => $this->partner->products,
|
||
];
|
||
}
|
||
}; ?>
|
||
|
||
<div class="space-y-8 p-6">
|
||
{{-- Partner-Header --}}
|
||
<flux:card class="shadow-elegant">
|
||
<div class="flex flex-col md:flex-row items-start gap-6">
|
||
{{-- Logo / Placeholder --}}
|
||
<div class="flex h-24 w-24 shrink-0 items-center justify-center rounded-xl bg-zinc-100 dark:bg-zinc-800">
|
||
<flux:icon.building-office class="h-12 w-12 text-zinc-400" />
|
||
</div>
|
||
|
||
<div class="flex-1">
|
||
<flux:heading size="2xl">{{ $partner->display_name ?? $partner->company_name }}</flux:heading>
|
||
@if($partner->display_name && $partner->display_name !== $partner->company_name)
|
||
<div class="text-sm text-zinc-500 dark:text-zinc-400 mt-1">{{ $partner->company_name }}</div>
|
||
@endif
|
||
|
||
<div class="mt-3 flex flex-wrap gap-3">
|
||
@if($partner->type)
|
||
<flux:badge color="blue">{{ $partner->type?->label() ?? $partner->type }}</flux:badge>
|
||
@endif
|
||
@if($partner->hub)
|
||
<flux:badge color="zinc" icon="map-pin">{{ $partner->hub->name }}</flux:badge>
|
||
@endif
|
||
@if($partner->is_active)
|
||
<flux:badge color="green">{{ __('Aktiv') }}</flux:badge>
|
||
@endif
|
||
</div>
|
||
|
||
{{-- Kontaktdaten --}}
|
||
<div class="mt-4 flex flex-wrap gap-x-6 gap-y-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||
@if($partner->city)
|
||
<span class="flex items-center gap-1">
|
||
<flux:icon.map-pin class="h-4 w-4" />
|
||
{{ $partner->zip }} {{ $partner->city }}
|
||
</span>
|
||
@endif
|
||
@if($partner->phone)
|
||
<span class="flex items-center gap-1">
|
||
<flux:icon.phone class="h-4 w-4" />
|
||
{{ $partner->phone }}
|
||
</span>
|
||
@endif
|
||
@if($partner->website)
|
||
<a href="{{ $partner->website }}" target="_blank" rel="noopener noreferrer"
|
||
class="flex items-center gap-1 hover:text-zinc-900 dark:hover:text-zinc-100">
|
||
<flux:icon.globe-alt class="h-4 w-4" />
|
||
{{ parse_url($partner->website, PHP_URL_HOST) }}
|
||
</a>
|
||
@endif
|
||
@if($partner->founded_year)
|
||
<span class="flex items-center gap-1">
|
||
<flux:icon.calendar class="h-4 w-4" />
|
||
{{ __('Seit') }} {{ $partner->founded_year }}
|
||
</span>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</flux:card>
|
||
|
||
<div class="grid grid-cols-1 gap-8 lg:grid-cols-3">
|
||
{{-- Linke Spalte: Story + Spezialisierungen --}}
|
||
<div class="space-y-6 lg:col-span-2">
|
||
{{-- Story / Über uns --}}
|
||
@if($partner->story_text)
|
||
<flux:card class="shadow-elegant">
|
||
<flux:heading size="lg" class="mb-4">{{ __('Über uns') }}</flux:heading>
|
||
<div class="text-zinc-700 dark:text-zinc-300 leading-relaxed whitespace-pre-line">
|
||
{{ $partner->story_text }}
|
||
</div>
|
||
</flux:card>
|
||
@endif
|
||
|
||
{{-- Produkte --}}
|
||
@if($products->isNotEmpty())
|
||
<flux:card class="shadow-elegant">
|
||
<div class="flex items-center justify-between mb-4">
|
||
<flux:heading size="lg">{{ __('Aktuelle Produkte') }}</flux:heading>
|
||
<flux:button variant="ghost" size="sm" href="{{ route('products.index') }}" icon="arrow-right">
|
||
{{ __('Alle ansehen') }}
|
||
</flux:button>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||
@foreach($products as $product)
|
||
<div class="rounded-lg border border-zinc-200 dark:border-zinc-700 overflow-hidden">
|
||
<div class="flex h-32 items-center justify-center bg-zinc-100 dark:bg-zinc-800">
|
||
@if($product->media->first()?->url)
|
||
<img src="{{ $product->media->first()->url }}"
|
||
alt="{{ $product->name }}"
|
||
class="h-full w-full object-cover">
|
||
@else
|
||
<flux:icon.photo class="h-10 w-10 text-zinc-400" />
|
||
@endif
|
||
</div>
|
||
<div class="p-3">
|
||
<div class="font-medium text-sm text-zinc-900 dark:text-zinc-100">
|
||
{{ $product->name }}
|
||
</div>
|
||
@if($product->price_display_text)
|
||
<div class="text-sm text-zinc-500 mt-1">{{ $product->price_display_text }}</div>
|
||
@elseif($product->price)
|
||
<div class="text-sm font-semibold mt-1">{{ number_format($product->price, 2, ',', '.') }} €</div>
|
||
@else
|
||
<div class="text-sm text-zinc-400 mt-1">{{ __('Auf Anfrage') }}</div>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
@endforeach
|
||
</div>
|
||
</flux:card>
|
||
@endif
|
||
</div>
|
||
|
||
{{-- Rechte Spalte: Öffnungszeiten + Spezialisierungen --}}
|
||
<div class="space-y-6">
|
||
{{-- Öffnungszeiten --}}
|
||
@if($partner->opening_hours)
|
||
<flux:card class="shadow-elegant">
|
||
<flux:heading size="lg" class="mb-4">{{ __('Öffnungszeiten') }}</flux:heading>
|
||
@php
|
||
$days = [
|
||
'monday' => __('Montag'),
|
||
'tuesday' => __('Dienstag'),
|
||
'wednesday' => __('Mittwoch'),
|
||
'thursday' => __('Donnerstag'),
|
||
'friday' => __('Freitag'),
|
||
'saturday' => __('Samstag'),
|
||
'sunday' => __('Sonntag'),
|
||
];
|
||
@endphp
|
||
<div class="space-y-2">
|
||
@foreach($days as $key => $label)
|
||
@if(isset($partner->opening_hours[$key]))
|
||
@php $hours = $partner->opening_hours[$key]; @endphp
|
||
<div class="flex items-center justify-between text-sm">
|
||
<span class="text-zinc-600 dark:text-zinc-400">{{ $label }}</span>
|
||
@if(!empty($hours['closed']))
|
||
<span class="text-zinc-400">{{ __('Geschlossen') }}</span>
|
||
@elseif(!empty($hours['open']) && !empty($hours['close']))
|
||
<span class="font-medium">{{ $hours['open'] }} – {{ $hours['close'] }}</span>
|
||
@else
|
||
<span class="text-zinc-400">–</span>
|
||
@endif
|
||
</div>
|
||
@endif
|
||
@endforeach
|
||
</div>
|
||
</flux:card>
|
||
@endif
|
||
|
||
{{-- Spezialisierungen --}}
|
||
@if($partner->specialties && count($partner->specialties) > 0)
|
||
<flux:card class="shadow-elegant">
|
||
<flux:heading size="lg" class="mb-4">{{ __('Spezialisierungen') }}</flux:heading>
|
||
<div class="flex flex-wrap gap-2">
|
||
@foreach($partner->specialties as $specialty)
|
||
<flux:badge color="zinc">{{ $specialty }}</flux:badge>
|
||
@endforeach
|
||
</div>
|
||
</flux:card>
|
||
@endif
|
||
|
||
{{-- Adresse --}}
|
||
@if($partner->street || $partner->city)
|
||
<flux:card class="shadow-elegant">
|
||
<flux:heading size="lg" class="mb-4">{{ __('Adresse') }}</flux:heading>
|
||
<address class="not-italic text-sm text-zinc-700 dark:text-zinc-300 space-y-1">
|
||
@if($partner->street)
|
||
<div>{{ $partner->street }} {{ $partner->house_number }}</div>
|
||
@endif
|
||
@if($partner->zip || $partner->city)
|
||
<div>{{ $partner->zip }} {{ $partner->city }}</div>
|
||
@endif
|
||
</address>
|
||
</flux:card>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
</div>
|