19-05-2026 Rebrand Pressekonto, Hub-Flux UI und Legacy-Media-Migration
Umbenennung presseportale → pressekonto in Domains, Themes und Dokumentation. Design-Tokens, Portal-Shell, Customer-Dashboard, Auth- und Admin-PM-Views. Artisan-Befehl migrate:legacy-media mit Tests und Hub-Flux-Entwicklungsdocs. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
092ee0e918
commit
0a3e52d603
112 changed files with 8464 additions and 1649 deletions
|
|
@ -137,44 +137,56 @@ new #[Layout('components.layouts.app'), Title('Neue Pressemitteilung')] class ex
|
|||
|
||||
}; ?>
|
||||
|
||||
<div class="space-y-6">
|
||||
<flux:card>
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<flux:heading size="lg">{{ __('Neue Pressemitteilung') }}</flux:heading>
|
||||
<flux:subheading>{{ __('Entwurf erstellen oder direkt zur Prüfung einreichen.') }}</flux:subheading>
|
||||
<div class="space-y-8">
|
||||
{{-- ============== PAGE HEADER ============== --}}
|
||||
<header class="grid items-end gap-8" style="grid-template-columns:1fr auto;">
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-center gap-3 mb-3 flex-nowrap whitespace-nowrap">
|
||||
<span class="badge hub dot">{{ __('Admin Backend') }}</span>
|
||||
<span class="eyebrow muted">{{ __('Content · Neu anlegen') }}</span>
|
||||
</div>
|
||||
<h1 class="text-[30px] font-bold tracking-[-0.6px] leading-[1.15] m-0 text-[color:var(--color-ink)]">
|
||||
{{ __('Neue Pressemitteilung') }}
|
||||
</h1>
|
||||
<p class="text-[13px] leading-[1.55] mt-2 m-0 max-w-[640px] text-[color:var(--color-ink-2)]">
|
||||
{{ __('Entwurf erstellen oder direkt zur Prüfung einreichen.') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 flex-shrink-0">
|
||||
<flux:button variant="ghost" icon="arrow-left" href="{{ route('admin.press-releases.index') }}" wire:navigate>
|
||||
{{ __('Zurück') }}
|
||||
</flux:button>
|
||||
</div>
|
||||
</flux:card>
|
||||
</header>
|
||||
|
||||
<div class="grid gap-6 lg:grid-cols-[1fr,320px]">
|
||||
{{-- Hauptinhalt --}}
|
||||
{{-- ============== HAUPTINHALT ============== --}}
|
||||
<div class="space-y-6">
|
||||
<flux:card>
|
||||
<flux:heading size="md" class="mb-4">{{ __('Inhalt') }}</flux:heading>
|
||||
|
||||
<div class="space-y-4">
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Inhalt') }}</span>
|
||||
</div>
|
||||
<div class="p-5 space-y-4">
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Titel') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:label>{{ __('Titel') }} <span class="text-[color:var(--color-err)]">*</span></flux:label>
|
||||
<flux:input wire:model.live.debounce.500ms="title" placeholder="{{ __('Aussagekräftiger Titel…') }}" />
|
||||
<flux:error name="title" />
|
||||
</flux:field>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Text') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:label>{{ __('Text') }} <span class="text-[color:var(--color-err)]">*</span></flux:label>
|
||||
<flux:textarea wire:model="text" rows="16" placeholder="{{ __('Vollständiger Text der Pressemitteilung…') }}" />
|
||||
<flux:error name="text" />
|
||||
</flux:field>
|
||||
</div>
|
||||
</flux:card>
|
||||
</article>
|
||||
|
||||
<flux:card>
|
||||
<flux:heading size="md" class="mb-4">{{ __('SEO & Links') }}</flux:heading>
|
||||
|
||||
<div class="space-y-4">
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('SEO & Links') }}</span>
|
||||
</div>
|
||||
<div class="p-5 space-y-4">
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Stichwörter') }}</flux:label>
|
||||
<flux:input wire:model="keywords" placeholder="{{ __('Kommagetrennte Stichwörter…') }}" />
|
||||
|
|
@ -187,19 +199,20 @@ new #[Layout('components.layouts.app'), Title('Neue Pressemitteilung')] class ex
|
|||
<flux:error name="backlinkUrl" />
|
||||
</flux:field>
|
||||
</div>
|
||||
</flux:card>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
{{-- Sidebar --}}
|
||||
<div class="space-y-4">
|
||||
<flux:card>
|
||||
<flux:heading size="md" class="mb-4">{{ __('Metadaten') }}</flux:heading>
|
||||
|
||||
<div class="space-y-4">
|
||||
{{-- ============== SIDEBAR ============== --}}
|
||||
<aside class="space-y-4">
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Metadaten') }}</span>
|
||||
</div>
|
||||
<div class="p-5 space-y-4">
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Portal') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:label>{{ __('Portal') }} <span class="text-[color:var(--color-err)]">*</span></flux:label>
|
||||
<flux:select wire:model="portal">
|
||||
@foreach($portalOptions as $p)
|
||||
@foreach ($portalOptions as $p)
|
||||
<option value="{{ $p->value }}">{{ $p->label() }}</option>
|
||||
@endforeach
|
||||
</flux:select>
|
||||
|
|
@ -215,7 +228,7 @@ new #[Layout('components.layouts.app'), Title('Neue Pressemitteilung')] class ex
|
|||
</flux:field>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Firma') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:label>{{ __('Firma') }} <span class="text-[color:var(--color-err)]">*</span></flux:label>
|
||||
<flux:select
|
||||
wire:model.live="companyId"
|
||||
variant="combobox"
|
||||
|
|
@ -229,14 +242,14 @@ new #[Layout('components.layouts.app'), Title('Neue Pressemitteilung')] class ex
|
|||
placeholder="{{ __('Name eingeben…') }}"
|
||||
/>
|
||||
</x-slot>
|
||||
@foreach($companies as $company)
|
||||
@foreach ($companies as $company)
|
||||
<flux:select.option :value="$company->id" wire:key="{{ $company->id }}">
|
||||
{{ $company->name }}
|
||||
</flux:select.option>
|
||||
@endforeach
|
||||
<x-slot name="empty">
|
||||
<flux:select.option.empty>
|
||||
@if(blank(trim($companySearch)))
|
||||
@if (blank(trim($companySearch)))
|
||||
{{ __('Mindestens 1 Zeichen eingeben…') }}
|
||||
@else
|
||||
{{ __('Keine Firma gefunden.') }}
|
||||
|
|
@ -248,11 +261,11 @@ new #[Layout('components.layouts.app'), Title('Neue Pressemitteilung')] class ex
|
|||
</flux:field>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Kategorie') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:label>{{ __('Kategorie') }} <span class="text-[color:var(--color-err)]">*</span></flux:label>
|
||||
<flux:select wire:model="categoryId">
|
||||
<option value="">{{ __('Bitte wählen…') }}</option>
|
||||
@foreach($categories as $cat)
|
||||
@php $catName = $cat->translations->firstWhere('locale', 'de')?->name ?? $cat->id; @endphp
|
||||
@foreach ($categories as $cat)
|
||||
@php($catName = $cat->translations->firstWhere('locale', 'de')?->name ?? $cat->id)
|
||||
<option value="{{ $cat->id }}">{{ $catName }}</option>
|
||||
@endforeach
|
||||
</flux:select>
|
||||
|
|
@ -261,10 +274,13 @@ new #[Layout('components.layouts.app'), Title('Neue Pressemitteilung')] class ex
|
|||
|
||||
<flux:checkbox wire:model="noExport" label="{{ __('Kein Export') }}" />
|
||||
</div>
|
||||
</flux:card>
|
||||
</article>
|
||||
|
||||
<flux:card>
|
||||
<div class="space-y-2">
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Aktionen') }}</span>
|
||||
</div>
|
||||
<div class="p-5 space-y-2">
|
||||
<flux:button
|
||||
type="button"
|
||||
variant="primary"
|
||||
|
|
@ -284,7 +300,7 @@ new #[Layout('components.layouts.app'), Title('Neue Pressemitteilung')] class ex
|
|||
{{ __('Als Entwurf speichern') }}
|
||||
</flux:button>
|
||||
</div>
|
||||
</flux:card>
|
||||
</div>
|
||||
</article>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -264,53 +264,80 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung bearbeiten')] cl
|
|||
|
||||
}; ?>
|
||||
|
||||
<div class="space-y-6">
|
||||
@if(session('success'))
|
||||
<div class="rounded-md border border-green-200 bg-green-50 px-4 py-3 text-sm text-green-800 dark:border-green-800 dark:bg-green-900/20 dark:text-green-300">
|
||||
<div class="space-y-8">
|
||||
@php
|
||||
$statusClass = match ($currentStatus) {
|
||||
'published' => 'ok',
|
||||
'review' => 'warn',
|
||||
'rejected' => 'err',
|
||||
default => 'hub',
|
||||
};
|
||||
@endphp
|
||||
|
||||
@if (session('success'))
|
||||
<div class="px-4 py-3 rounded-[5px] border text-[12.5px]
|
||||
bg-[color:var(--color-ok-soft)] border-[color:var(--color-ok)]/30 text-[color:var(--color-gain-deep)]">
|
||||
{{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<flux:card>
|
||||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||||
<div>
|
||||
<flux:heading size="lg">{{ __('Pressemitteilung bearbeiten') }}</flux:heading>
|
||||
<flux:subheading>ID: {{ $id }}</flux:subheading>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<flux:badge :color="$statusColor" size="lg">{{ $statusEnum?->label() ?? $currentStatus }}</flux:badge>
|
||||
<flux:button variant="ghost" icon="arrow-left" href="{{ route('admin.press-releases.index') }}" wire:navigate>
|
||||
{{ __('Zurück') }}
|
||||
</flux:button>
|
||||
</div>
|
||||
@if (session('error'))
|
||||
<div class="px-4 py-3 rounded-[5px] border text-[12.5px]
|
||||
bg-[color:var(--color-err-soft)] border-[color:var(--color-err)]/30 text-[color:var(--color-loss)]">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
</flux:card>
|
||||
@endif
|
||||
|
||||
{{-- ============== PAGE HEADER ============== --}}
|
||||
<header class="grid items-end gap-8" style="grid-template-columns:1fr auto;">
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-center gap-3 mb-3 flex-wrap">
|
||||
<span class="badge hub dot">{{ __('Admin Backend') }}</span>
|
||||
<span class="eyebrow muted">{{ __('Content · Bearbeiten') }}</span>
|
||||
<span @class(['badge', $statusClass])>{{ $statusEnum?->label() ?? $currentStatus }}</span>
|
||||
<span class="badge hub">ID {{ $id }}</span>
|
||||
</div>
|
||||
<h1 class="text-[30px] font-bold tracking-[-0.6px] leading-[1.15] m-0 text-[color:var(--color-ink)]">
|
||||
{{ __('Pressemitteilung bearbeiten') }}
|
||||
</h1>
|
||||
<p class="text-[13px] leading-[1.55] mt-2 m-0 max-w-[640px] text-[color:var(--color-ink-2)]">
|
||||
{{ __('Inhalt, Metadaten und Status der PM aktualisieren. Änderungen werden sofort wirksam.') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 flex-shrink-0">
|
||||
<flux:button variant="ghost" icon="arrow-left" href="{{ route('admin.press-releases.index') }}" wire:navigate>
|
||||
{{ __('Zurück') }}
|
||||
</flux:button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="grid gap-6 lg:grid-cols-[1fr,320px]">
|
||||
{{-- Hauptinhalt --}}
|
||||
{{-- ============== HAUPTINHALT ============== --}}
|
||||
<div class="space-y-6">
|
||||
<flux:card>
|
||||
<flux:heading size="md" class="mb-4">{{ __('Inhalt') }}</flux:heading>
|
||||
|
||||
<div class="space-y-4">
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Inhalt') }}</span>
|
||||
</div>
|
||||
<div class="p-5 space-y-4">
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Titel') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:label>{{ __('Titel') }} <span class="text-[color:var(--color-err)]">*</span></flux:label>
|
||||
<flux:input wire:model="title" />
|
||||
<flux:error name="title" />
|
||||
</flux:field>
|
||||
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Text') }} <span class="text-red-500">*</span></flux:label>
|
||||
<flux:label>{{ __('Text') }} <span class="text-[color:var(--color-err)]">*</span></flux:label>
|
||||
<flux:textarea wire:model="text" rows="20" />
|
||||
<flux:error name="text" />
|
||||
</flux:field>
|
||||
</div>
|
||||
</flux:card>
|
||||
</article>
|
||||
|
||||
<flux:card>
|
||||
<flux:heading size="md" class="mb-4">{{ __('SEO & Links') }}</flux:heading>
|
||||
|
||||
<div class="space-y-4">
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('SEO & Links') }}</span>
|
||||
</div>
|
||||
<div class="p-5 space-y-4">
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Stichwörter') }}</flux:label>
|
||||
<flux:input wire:model="keywords" placeholder="{{ __('Kommagetrennt…') }}" />
|
||||
|
|
@ -322,22 +349,23 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung bearbeiten')] cl
|
|||
<flux:error name="backlinkUrl" />
|
||||
</flux:field>
|
||||
</div>
|
||||
</flux:card>
|
||||
</article>
|
||||
|
||||
<livewire:components.press-release-images-manager :press-release-id="$id" :wire:key="'pr-images-'.$id" />
|
||||
</div>
|
||||
|
||||
{{-- Sidebar --}}
|
||||
<div class="space-y-4">
|
||||
{{-- Status-Aktionen --}}
|
||||
<flux:card>
|
||||
<flux:heading size="sm" class="mb-3">{{ __('Status-Aktionen') }}</flux:heading>
|
||||
|
||||
<div class="space-y-3">
|
||||
{{-- ============== SIDEBAR ============== --}}
|
||||
<aside class="space-y-4">
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Status-Aktionen') }}</span>
|
||||
<span @class(['badge', $statusClass])>{{ $statusEnum?->label() ?? $currentStatus }}</span>
|
||||
</div>
|
||||
<div class="p-5 space-y-3">
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Neuer Status') }}</flux:label>
|
||||
<flux:select wire:model.live="targetStatus">
|
||||
@foreach($statusOptions as $statusOption)
|
||||
@foreach ($statusOptions as $statusOption)
|
||||
<option value="{{ $statusOption->value }}">
|
||||
{{ $statusOption->label() }}{{ $statusOption->value === $currentStatus ? ' (aktuell)' : '' }}
|
||||
</option>
|
||||
|
|
@ -352,17 +380,17 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung bearbeiten')] cl
|
|||
</flux:button>
|
||||
</flux:modal.trigger>
|
||||
</div>
|
||||
</flux:card>
|
||||
</article>
|
||||
|
||||
{{-- Metadaten --}}
|
||||
<flux:card>
|
||||
<flux:heading size="sm" class="mb-3">{{ __('Metadaten') }}</flux:heading>
|
||||
|
||||
<div class="space-y-4">
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Metadaten') }}</span>
|
||||
</div>
|
||||
<div class="p-5 space-y-4">
|
||||
<flux:field>
|
||||
<flux:label>{{ __('Portal') }}</flux:label>
|
||||
<flux:select wire:model="portal">
|
||||
@foreach($portalOptions as $p)
|
||||
@foreach ($portalOptions as $p)
|
||||
<option value="{{ $p->value }}">{{ $p->label() }}</option>
|
||||
@endforeach
|
||||
</flux:select>
|
||||
|
|
@ -391,14 +419,14 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung bearbeiten')] cl
|
|||
placeholder="{{ __('Name eingeben…') }}"
|
||||
/>
|
||||
</x-slot>
|
||||
@foreach($companies as $company)
|
||||
@foreach ($companies as $company)
|
||||
<flux:select.option :value="$company->id" wire:key="{{ $company->id }}">
|
||||
{{ $company->name }}
|
||||
</flux:select.option>
|
||||
@endforeach
|
||||
<x-slot name="empty">
|
||||
<flux:select.option.empty>
|
||||
@if(blank(trim($companySearch)))
|
||||
@if (blank(trim($companySearch)))
|
||||
{{ __('Mindestens 1 Zeichen eingeben…') }}
|
||||
@else
|
||||
{{ __('Keine Firma gefunden.') }}
|
||||
|
|
@ -413,8 +441,8 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung bearbeiten')] cl
|
|||
<flux:label>{{ __('Kategorie') }}</flux:label>
|
||||
<flux:select wire:model="categoryId">
|
||||
<option value="">{{ __('Bitte wählen…') }}</option>
|
||||
@foreach($categories as $cat)
|
||||
@php $catName = $cat->translations->firstWhere('locale', 'de')?->name ?? $cat->id; @endphp
|
||||
@foreach ($categories as $cat)
|
||||
@php($catName = $cat->translations->firstWhere('locale', 'de')?->name ?? $cat->id)
|
||||
<option value="{{ $cat->id }}">{{ $catName }}</option>
|
||||
@endforeach
|
||||
</flux:select>
|
||||
|
|
@ -423,18 +451,24 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung bearbeiten')] cl
|
|||
|
||||
<flux:checkbox wire:model="noExport" label="{{ __('Kein Export') }}" />
|
||||
</div>
|
||||
</flux:card>
|
||||
</article>
|
||||
|
||||
<flux:button type="button" variant="primary" class="w-full" wire:click="save">
|
||||
{{ __('Änderungen speichern') }}
|
||||
</flux:button>
|
||||
|
||||
<flux:modal.trigger name="confirm-delete-press-release">
|
||||
<flux:button type="button" variant="danger" icon="trash" class="w-full">
|
||||
{{ __('Pressemitteilung löschen') }}
|
||||
</flux:button>
|
||||
</flux:modal.trigger>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Aktionen') }}</span>
|
||||
</div>
|
||||
<div class="p-5 space-y-2">
|
||||
<flux:button type="button" variant="primary" class="w-full" wire:click="save">
|
||||
{{ __('Änderungen speichern') }}
|
||||
</flux:button>
|
||||
<flux:modal.trigger name="confirm-delete-press-release">
|
||||
<flux:button type="button" variant="danger" icon="trash" class="w-full">
|
||||
{{ __('Pressemitteilung löschen') }}
|
||||
</flux:button>
|
||||
</flux:modal.trigger>
|
||||
</div>
|
||||
</article>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<flux:modal name="confirm-status-change" class="max-w-lg">
|
||||
|
|
|
|||
|
|
@ -349,43 +349,68 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilungen')] class exten
|
|||
}
|
||||
}; ?>
|
||||
|
||||
<div class="space-y-6">
|
||||
<div class="space-y-8">
|
||||
@if (session('success'))
|
||||
<div
|
||||
class="rounded-md border border-green-200 bg-green-50 px-4 py-3 text-sm text-green-800 dark:border-green-800 dark:bg-green-900/20 dark:text-green-300">
|
||||
<div class="px-4 py-3 rounded-[5px] border text-[12.5px]
|
||||
bg-[color:var(--color-ok-soft)] border-[color:var(--color-ok)]/30 text-[color:var(--color-gain-deep)]">
|
||||
{{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
@if (session('error'))
|
||||
<div class="px-4 py-3 rounded-[5px] border text-[12.5px]
|
||||
bg-[color:var(--color-err-soft)] border-[color:var(--color-err)]/30 text-[color:var(--color-loss)]">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Statistiken --}}
|
||||
<div class="grid grid-cols-2 gap-4 sm:grid-cols-4">
|
||||
<flux:card>
|
||||
<flux:text class="text-xs text-zinc-500">{{ __('Gesamt') }}</flux:text>
|
||||
<flux:text size="xl" weight="bold">{{ $stats['total'] }}</flux:text>
|
||||
</flux:card>
|
||||
<flux:card>
|
||||
<flux:text class="text-xs text-green-600">{{ __('Veröffentlicht') }}</flux:text>
|
||||
<flux:text size="xl" weight="bold">{{ $stats['published'] }}</flux:text>
|
||||
</flux:card>
|
||||
<flux:card>
|
||||
<flux:text class="text-xs text-yellow-600">{{ __('In Prüfung') }}</flux:text>
|
||||
<flux:text size="xl" weight="bold">{{ $stats['review'] }}</flux:text>
|
||||
</flux:card>
|
||||
<flux:card>
|
||||
<flux:text class="text-xs text-zinc-500">{{ __('Entwürfe') }}</flux:text>
|
||||
<flux:text size="xl" weight="bold">{{ $stats['draft'] }}</flux:text>
|
||||
</flux:card>
|
||||
</div>
|
||||
{{-- ============== PAGE HEADER ============== --}}
|
||||
<header class="grid items-end gap-8" style="grid-template-columns:1fr auto;">
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-center gap-3 mb-3 flex-nowrap whitespace-nowrap">
|
||||
<span class="badge hub dot">{{ __('Admin Backend') }}</span>
|
||||
<span class="eyebrow muted">{{ __('Content · Pressemitteilungen') }}</span>
|
||||
</div>
|
||||
<h1 class="text-[34px] font-bold tracking-[-0.7px] leading-[1.1] m-0 text-[color:var(--color-ink)]">
|
||||
{{ __('Pressemitteilungen') }}
|
||||
</h1>
|
||||
<p class="text-[13.5px] leading-[1.55] mt-2 m-0 max-w-[640px] text-[color:var(--color-ink-2)]">
|
||||
{{ __('Übersicht aller PMs beider Portale, mit Filter, Status-Workflow und Schnellaktionen.') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<flux:button icon="plus" variant="primary" href="{{ route('admin.press-releases.create') }}" wire:navigate>
|
||||
{{ __('Neue PM') }}
|
||||
</flux:button>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 flex-shrink-0">
|
||||
<flux:button icon="plus" variant="primary" href="{{ route('admin.press-releases.create') }}" wire:navigate>
|
||||
{{ __('Neue PM') }}
|
||||
</flux:button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{{-- Filter --}}
|
||||
<flux:card>
|
||||
<div class="flex flex-col gap-3">
|
||||
{{-- ============== KPI-Reihe ============== --}}
|
||||
<section class="grid gap-4 grid-cols-2 sm:grid-cols-4">
|
||||
<x-portal.stat-card variant="primary" :label="__('Gesamt')" :value="number_format($stats['total'])">
|
||||
<x-slot:meta>{{ now()->format('Y') }}</x-slot:meta>
|
||||
<x-slot:trend>{{ __('über beide Portale') }}</x-slot:trend>
|
||||
</x-portal.stat-card>
|
||||
<x-portal.stat-card variant="ok" :label="__('Veröffentlicht')" :value="number_format($stats['published'])">
|
||||
<x-slot:meta>{{ __('live') }}</x-slot:meta>
|
||||
<x-slot:trend>{{ __('öffentlich sichtbar') }}</x-slot:trend>
|
||||
</x-portal.stat-card>
|
||||
<x-portal.stat-card variant="warn" :label="__('In Prüfung')" :value="number_format($stats['review'])">
|
||||
<x-slot:meta>{{ __('queue') }}</x-slot:meta>
|
||||
<x-slot:trend>{{ __('redaktionelle Prüfung') }}</x-slot:trend>
|
||||
</x-portal.stat-card>
|
||||
<x-portal.stat-card variant="muted" :label="__('Entwürfe')" :value="number_format($stats['draft'])">
|
||||
<x-slot:meta>{{ __('privat') }}</x-slot:meta>
|
||||
<x-slot:trend>{{ __('nicht eingereicht') }}</x-slot:trend>
|
||||
</x-portal.stat-card>
|
||||
</section>
|
||||
|
||||
{{-- ============== FILTER-PANEL ============== --}}
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Filter & Suche') }}</span>
|
||||
</div>
|
||||
<div class="p-5 flex flex-col gap-3">
|
||||
<div class="grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-6">
|
||||
<flux:input
|
||||
wire:model.live.debounce.300ms="search"
|
||||
|
|
@ -551,10 +576,16 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilungen')] class exten
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</flux:card>
|
||||
</article>
|
||||
|
||||
{{-- Tabelle --}}
|
||||
<flux:card class="overflow-hidden">
|
||||
{{-- ============== TABELLE-PANEL ============== --}}
|
||||
<article class="panel overflow-hidden">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Alle Pressemitteilungen') }}</span>
|
||||
<span class="text-[11.5px] text-[color:var(--color-ink-3)]">
|
||||
{{ __(':count Einträge', ['count' => $pressReleases->count()]) }}
|
||||
</span>
|
||||
</div>
|
||||
<flux:table>
|
||||
<flux:table.columns>
|
||||
<flux:table.column>{{ __('Aktionen') }}</flux:table.column>
|
||||
|
|
@ -604,16 +635,15 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilungen')] class exten
|
|||
</div>
|
||||
</flux:table.cell>
|
||||
<flux:table.cell>
|
||||
<flux:badge
|
||||
color="{{ match ($pr->status->value) {
|
||||
'published' => 'green',
|
||||
'review' => 'yellow',
|
||||
'draft' => 'zinc',
|
||||
'rejected' => 'red',
|
||||
'archived' => 'blue',
|
||||
} }}">
|
||||
<span @class([
|
||||
'badge',
|
||||
'ok' => $pr->status->value === 'published',
|
||||
'warn' => $pr->status->value === 'review',
|
||||
'err' => $pr->status->value === 'rejected',
|
||||
'hub' => in_array($pr->status->value, ['archived', 'draft'], true),
|
||||
])>
|
||||
{{ $pr->status->label() }}
|
||||
</flux:badge>
|
||||
</span>
|
||||
</flux:table.cell>
|
||||
<flux:table.cell>
|
||||
<flux:text class="text-sm">{{ $pr->portal->label() }}</flux:text>
|
||||
|
|
@ -704,16 +734,23 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilungen')] class exten
|
|||
@empty
|
||||
<flux:table.row>
|
||||
<flux:table.cell colspan="8">
|
||||
<div class="flex flex-col items-center justify-center py-10">
|
||||
<flux:icon.newspaper class="size-10 text-zinc-300" />
|
||||
<flux:text class="mt-3 text-zinc-500">{{ __('Keine Pressemitteilungen gefunden.') }}
|
||||
</flux:text>
|
||||
<div class="flex flex-col items-center justify-center py-12 text-center">
|
||||
<div class="w-14 h-14 rounded-[6px] flex items-center justify-center mb-4
|
||||
bg-[color:var(--color-hub-soft)] border border-[color:var(--color-hub-soft-2)] text-[color:var(--color-hub)]">
|
||||
<flux:icon.newspaper class="size-6" />
|
||||
</div>
|
||||
<div class="text-[14px] font-semibold text-[color:var(--color-ink)] mb-1">
|
||||
{{ __('Keine Pressemitteilungen gefunden') }}
|
||||
</div>
|
||||
<p class="text-[12px] text-[color:var(--color-ink-3)] max-w-md m-0">
|
||||
{{ __('Passen Sie die Filter an oder erstellen Sie eine neue Pressemitteilung.') }}
|
||||
</p>
|
||||
</div>
|
||||
</flux:table.cell>
|
||||
</flux:table.row>
|
||||
@endforelse
|
||||
</flux:table>
|
||||
</flux:card>
|
||||
</article>
|
||||
|
||||
{{ $pressReleases->links() }}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -90,46 +90,75 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung')] class extends
|
|||
}
|
||||
}; ?>
|
||||
|
||||
<div class="space-y-6">
|
||||
@if(session('success'))
|
||||
<div class="rounded-md border border-green-200 bg-green-50 px-4 py-3 text-sm text-green-800 dark:border-green-800 dark:bg-green-900/20 dark:text-green-300">
|
||||
<div class="space-y-8">
|
||||
@php
|
||||
$statusClass = match ($pr->status->value) {
|
||||
'published' => 'ok',
|
||||
'review' => 'warn',
|
||||
'rejected' => 'err',
|
||||
default => 'hub',
|
||||
};
|
||||
@endphp
|
||||
|
||||
@if (session('success'))
|
||||
<div class="px-4 py-3 rounded-[5px] border text-[12.5px]
|
||||
bg-[color:var(--color-ok-soft)] border-[color:var(--color-ok)]/30 text-[color:var(--color-gain-deep)]">
|
||||
{{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<flux:card>
|
||||
<div class="flex flex-wrap items-start justify-between gap-3">
|
||||
<div class="flex-1">
|
||||
<div class="flex items-center gap-2">
|
||||
<flux:badge :color="$statusColor">{{ $pr->status->label() }}</flux:badge>
|
||||
<flux:badge color="zinc" size="sm">{{ strtoupper($pr->language) }}</flux:badge>
|
||||
<flux:badge color="zinc" size="sm">{{ $pr->portal->label() }}</flux:badge>
|
||||
</div>
|
||||
<flux:heading size="xl" class="mt-2">{{ $pr->title }}</flux:heading>
|
||||
<flux:text class="mt-1 text-sm text-zinc-500">
|
||||
{{ __('Firma') }}: {{ $pr->company?->name ?? '–' }} ·
|
||||
{{ __('Kategorie') }}: {{ $categoryName }} ·
|
||||
{{ __('Autor') }}: {{ $pr->user?->name ?? '–' }}
|
||||
</flux:text>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<flux:button variant="ghost" icon="pencil" href="{{ route('admin.press-releases.edit', $pr->id) }}" wire:navigate>
|
||||
{{ __('Bearbeiten') }}
|
||||
</flux:button>
|
||||
<flux:button variant="ghost" icon="arrow-left" href="{{ route('admin.press-releases.index') }}" wire:navigate>
|
||||
{{ __('Zurück') }}
|
||||
</flux:button>
|
||||
</div>
|
||||
@if (session('error'))
|
||||
<div class="px-4 py-3 rounded-[5px] border text-[12.5px]
|
||||
bg-[color:var(--color-err-soft)] border-[color:var(--color-err)]/30 text-[color:var(--color-loss)]">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
</flux:card>
|
||||
@endif
|
||||
|
||||
{{-- Status-Aktionen --}}
|
||||
@if($pr->status === \App\Enums\PressReleaseStatus::Review)
|
||||
<flux:card>
|
||||
<div class="flex flex-wrap items-center gap-3">
|
||||
<flux:text weight="medium" class="text-yellow-700 dark:text-yellow-400">
|
||||
{{-- ============== PAGE HEADER ============== --}}
|
||||
<header class="grid items-end gap-8" style="grid-template-columns:1fr auto;">
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-center gap-3 mb-3 flex-wrap">
|
||||
<span class="badge hub dot">{{ __('Admin Backend') }}</span>
|
||||
<span class="eyebrow muted">{{ __('Content · Pressemitteilung') }}</span>
|
||||
<span @class(['badge', $statusClass])>{{ $pr->status->label() }}</span>
|
||||
<span class="badge hub">{{ strtoupper($pr->language) }}</span>
|
||||
<span class="badge hub">{{ $pr->portal->label() }}</span>
|
||||
</div>
|
||||
<h1 class="text-[30px] font-bold tracking-[-0.6px] leading-[1.15] m-0 text-[color:var(--color-ink)]">
|
||||
{{ $pr->title }}
|
||||
</h1>
|
||||
<p class="text-[13px] leading-[1.55] mt-2 m-0 max-w-[720px] text-[color:var(--color-ink-2)]">
|
||||
<strong class="font-semibold text-[color:var(--color-ink)]">{{ __('Firma') }}:</strong>
|
||||
{{ $pr->company?->name ?? '–' }}
|
||||
<span class="text-[color:var(--color-bg-rule)] mx-1">·</span>
|
||||
<strong class="font-semibold text-[color:var(--color-ink)]">{{ __('Kategorie') }}:</strong>
|
||||
{{ $categoryName }}
|
||||
<span class="text-[color:var(--color-bg-rule)] mx-1">·</span>
|
||||
<strong class="font-semibold text-[color:var(--color-ink)]">{{ __('Autor') }}:</strong>
|
||||
{{ $pr->user?->name ?? '–' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 flex-shrink-0">
|
||||
<flux:button variant="ghost" icon="pencil" href="{{ route('admin.press-releases.edit', $pr->id) }}" wire:navigate>
|
||||
{{ __('Bearbeiten') }}
|
||||
</flux:button>
|
||||
<flux:button variant="ghost" icon="arrow-left" href="{{ route('admin.press-releases.index') }}" wire:navigate>
|
||||
{{ __('Zurück') }}
|
||||
</flux:button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{{-- ============== STATUS-WORKFLOW ============== --}}
|
||||
@if ($pr->status === \App\Enums\PressReleaseStatus::Review)
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Status-Workflow') }}</span>
|
||||
<span class="badge warn dot">{{ __('Wartet auf Prüfung') }}</span>
|
||||
</div>
|
||||
<div class="p-5 flex flex-wrap items-center gap-3">
|
||||
<p class="text-[13px] text-[color:var(--color-ink-2)] m-0 flex-1 min-w-[200px]">
|
||||
{{ __('Diese PM wartet auf Prüfung.') }}
|
||||
</flux:text>
|
||||
</p>
|
||||
<flux:modal.trigger name="confirm-show-publish">
|
||||
<flux:button type="button" variant="primary">{{ __('Veröffentlichen') }}</flux:button>
|
||||
</flux:modal.trigger>
|
||||
|
|
@ -137,136 +166,162 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung')] class extends
|
|||
<flux:button type="button" variant="danger">{{ __('Ablehnen') }}</flux:button>
|
||||
</flux:modal.trigger>
|
||||
</div>
|
||||
</flux:card>
|
||||
</article>
|
||||
@endif
|
||||
@if($pr->status === \App\Enums\PressReleaseStatus::Published)
|
||||
<flux:card>
|
||||
<div class="flex items-center gap-3">
|
||||
@if ($pr->status === \App\Enums\PressReleaseStatus::Published)
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Status-Workflow') }}</span>
|
||||
<span class="badge ok dot">{{ __('Live') }}</span>
|
||||
</div>
|
||||
<div class="p-5 flex flex-wrap items-center gap-3">
|
||||
@if ($pr->hits > 0)
|
||||
<p class="text-[13px] text-[color:var(--color-ink-2)] m-0 flex-1 min-w-[200px]">
|
||||
<strong class="text-[color:var(--color-ink)] font-semibold">{{ number_format($pr->hits) }}</strong>
|
||||
{{ __('Aufrufe seit Veröffentlichung') }}
|
||||
</p>
|
||||
@endif
|
||||
<flux:modal.trigger name="confirm-show-archive">
|
||||
<flux:button type="button" variant="ghost">{{ __('Archivieren') }}</flux:button>
|
||||
</flux:modal.trigger>
|
||||
@if($pr->hits > 0)
|
||||
<flux:text class="text-sm text-zinc-500">{{ number_format($pr->hits) }} {{ __('Aufrufe') }}</flux:text>
|
||||
@endif
|
||||
</div>
|
||||
</flux:card>
|
||||
</article>
|
||||
@endif
|
||||
|
||||
<div class="grid gap-6 lg:grid-cols-[1fr,280px]">
|
||||
{{-- Text --}}
|
||||
<flux:card>
|
||||
<div class="prose prose-zinc dark:prose-invert max-w-none">
|
||||
{!! nl2br(e($pr->text)) !!}
|
||||
{{-- ============== TEXT + SIDEBAR ============== --}}
|
||||
<div class="grid gap-6 lg:grid-cols-[1fr,300px]">
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Inhalt') }}</span>
|
||||
</div>
|
||||
</flux:card>
|
||||
<div class="p-5">
|
||||
<div class="prose prose-zinc dark:prose-invert max-w-none text-[color:var(--color-ink)]">
|
||||
{!! nl2br(e($pr->text)) !!}
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
{{-- Details --}}
|
||||
<div class="space-y-4">
|
||||
<flux:card>
|
||||
<flux:heading size="sm" class="mb-3">{{ __('Details') }}</flux:heading>
|
||||
<dl class="space-y-2 text-sm">
|
||||
<aside class="space-y-4">
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Details') }}</span>
|
||||
</div>
|
||||
<dl class="p-5 space-y-2.5 text-[12.5px]">
|
||||
<div class="flex justify-between gap-2">
|
||||
<dt class="text-zinc-500">{{ __('Status') }}</dt>
|
||||
<dd class="font-medium">{{ $pr->status->label() }}</dd>
|
||||
<dt class="text-[color:var(--color-ink-3)]">{{ __('Status') }}</dt>
|
||||
<dd class="font-semibold text-[color:var(--color-ink)]">{{ $pr->status->label() }}</dd>
|
||||
</div>
|
||||
<div class="flex justify-between gap-2">
|
||||
<dt class="text-zinc-500">{{ __('Erstellt') }}</dt>
|
||||
<dd>{{ $pr->created_at->format('d.m.Y H:i') }}</dd>
|
||||
<dt class="text-[color:var(--color-ink-3)]">{{ __('Erstellt') }}</dt>
|
||||
<dd class="text-[color:var(--color-ink)]">{{ $pr->created_at->format('d.m.Y H:i') }}</dd>
|
||||
</div>
|
||||
@if($pr->published_at)
|
||||
@if ($pr->published_at)
|
||||
<div class="flex justify-between gap-2">
|
||||
<dt class="text-zinc-500">{{ __('Veröffentlicht') }}</dt>
|
||||
<dd>{{ $pr->published_at->format('d.m.Y H:i') }}</dd>
|
||||
<dt class="text-[color:var(--color-ink-3)]">{{ __('Veröffentlicht') }}</dt>
|
||||
<dd class="text-[color:var(--color-ink)]">{{ $pr->published_at->format('d.m.Y H:i') }}</dd>
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex justify-between gap-2">
|
||||
<dt class="text-zinc-500">{{ __('Aufrufe') }}</dt>
|
||||
<dd>{{ number_format($pr->hits) }}</dd>
|
||||
<dt class="text-[color:var(--color-ink-3)]">{{ __('Aufrufe') }}</dt>
|
||||
<dd class="text-[color:var(--color-ink)] font-semibold">{{ number_format($pr->hits) }}</dd>
|
||||
</div>
|
||||
@if($pr->keywords)
|
||||
<div>
|
||||
<dt class="text-zinc-500">{{ __('Stichwörter') }}</dt>
|
||||
<dd class="mt-1">{{ $pr->keywords }}</dd>
|
||||
@if ($pr->keywords)
|
||||
<div class="pt-2 border-t border-[color:var(--color-bg-rule)]">
|
||||
<dt class="text-[color:var(--color-ink-3)] mb-1">{{ __('Stichwörter') }}</dt>
|
||||
<dd class="text-[color:var(--color-ink)]">{{ $pr->keywords }}</dd>
|
||||
</div>
|
||||
@endif
|
||||
@if($pr->backlink_url)
|
||||
<div>
|
||||
<dt class="text-zinc-500">{{ __('Backlink') }}</dt>
|
||||
<dd class="mt-1 break-all">
|
||||
<a href="{{ $pr->backlink_url }}" target="_blank" class="text-blue-600 underline dark:text-blue-400">
|
||||
@if ($pr->backlink_url)
|
||||
<div class="pt-2 border-t border-[color:var(--color-bg-rule)]">
|
||||
<dt class="text-[color:var(--color-ink-3)] mb-1">{{ __('Backlink') }}</dt>
|
||||
<dd class="break-all">
|
||||
<a href="{{ $pr->backlink_url }}" target="_blank"
|
||||
class="text-[color:var(--color-hub)] underline underline-offset-2 decoration-[color:var(--color-hub)]/40 hover:decoration-[color:var(--color-hub)]">
|
||||
{{ $pr->backlink_url }}
|
||||
</a>
|
||||
</dd>
|
||||
</div>
|
||||
@endif
|
||||
@if($pr->no_export)
|
||||
<div class="rounded bg-zinc-100 px-2 py-1 text-xs text-zinc-600 dark:bg-zinc-700 dark:text-zinc-300">
|
||||
{{ __('Kein Export') }}
|
||||
@if ($pr->no_export)
|
||||
<div class="mt-2 pt-2 border-t border-[color:var(--color-bg-rule)]">
|
||||
<span class="badge hub">{{ __('Kein Export') }}</span>
|
||||
</div>
|
||||
@endif
|
||||
</dl>
|
||||
</flux:card>
|
||||
</article>
|
||||
|
||||
@if($pr->images->isNotEmpty())
|
||||
<flux:card>
|
||||
<flux:heading size="sm" class="mb-3">{{ __('Bilder') }}</flux:heading>
|
||||
<div class="space-y-2">
|
||||
@foreach($pr->images as $image)
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<flux:icon.photo class="size-4 text-zinc-400" />
|
||||
<span class="truncate text-zinc-600 dark:text-zinc-400">{{ basename($image->path) }}</span>
|
||||
@if($image->is_preview)
|
||||
<flux:badge size="sm" color="blue">{{ __('Preview') }}</flux:badge>
|
||||
@if ($pr->images->isNotEmpty())
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Bilder') }}</span>
|
||||
<span class="text-[11.5px] text-[color:var(--color-ink-3)]">
|
||||
{{ $pr->images->count() }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="p-5 space-y-2">
|
||||
@foreach ($pr->images as $image)
|
||||
<div class="flex items-center gap-2 text-[12.5px]">
|
||||
<flux:icon.photo class="size-4 flex-shrink-0 text-[color:var(--color-ink-3)]" />
|
||||
<span class="truncate text-[color:var(--color-ink-2)]">{{ basename($image->path) }}</span>
|
||||
@if ($image->is_preview)
|
||||
<span class="badge hub">{{ __('Preview') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</flux:card>
|
||||
</article>
|
||||
@endif
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
@if($statusLogs->isNotEmpty())
|
||||
<flux:card>
|
||||
<flux:heading size="sm" class="mb-3">{{ __('Status-Verlauf') }}</flux:heading>
|
||||
<ol class="space-y-3 border-s border-zinc-200 ps-4 dark:border-zinc-700">
|
||||
@foreach($statusLogs as $log)
|
||||
<li class="text-sm">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
@php
|
||||
$color = match($log->to_status?->value) {
|
||||
'published' => 'green',
|
||||
'review' => 'yellow',
|
||||
'rejected' => 'red',
|
||||
'archived' => 'blue',
|
||||
default => 'zinc',
|
||||
};
|
||||
@endphp
|
||||
<flux:badge size="sm" :color="$color">{{ $log->to_status?->label() ?? $log->to_status }}</flux:badge>
|
||||
@if($log->from_status)
|
||||
<span class="text-xs text-zinc-500">
|
||||
{{ __('von') }} {{ $log->from_status->label() }}
|
||||
{{-- ============== STATUS-VERLAUF ============== --}}
|
||||
@if ($statusLogs->isNotEmpty())
|
||||
<article class="panel">
|
||||
<div class="panel-head">
|
||||
<span class="section-eyebrow">{{ __('Status-Verlauf') }}</span>
|
||||
<span class="text-[11.5px] text-[color:var(--color-ink-3)]">
|
||||
{{ $statusLogs->count() }} {{ __('Einträge') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="p-5">
|
||||
<ol class="space-y-3 border-s border-[color:var(--color-bg-rule)] ps-4">
|
||||
@foreach ($statusLogs as $log)
|
||||
<li class="text-[12.5px]">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
@php
|
||||
$logClass = match ($log->to_status?->value) {
|
||||
'published' => 'ok',
|
||||
'review' => 'warn',
|
||||
'rejected' => 'err',
|
||||
default => 'hub',
|
||||
};
|
||||
@endphp
|
||||
<span @class(['badge', $logClass])>{{ $log->to_status?->label() ?? $log->to_status }}</span>
|
||||
@if ($log->from_status)
|
||||
<span class="text-[11.5px] text-[color:var(--color-ink-3)]">
|
||||
{{ __('von') }} {{ $log->from_status->label() }}
|
||||
</span>
|
||||
@endif
|
||||
<span class="text-[11.5px] text-[color:var(--color-ink-3)]">·</span>
|
||||
<span class="text-[11.5px] text-[color:var(--color-ink-3)]">
|
||||
{{ $log->created_at->format('d.m.Y H:i') }}
|
||||
</span>
|
||||
@if ($log->changedBy)
|
||||
<span class="text-[11.5px] text-[color:var(--color-ink-3)]">·</span>
|
||||
<span class="text-[11.5px] text-[color:var(--color-ink-3)]">{{ $log->changedBy->name }}</span>
|
||||
@endif
|
||||
@if ($log->source !== 'admin')
|
||||
<span class="badge hub">{{ $log->source }}</span>
|
||||
@endif
|
||||
</div>
|
||||
@if ($log->reason)
|
||||
<p class="mt-1.5 text-[color:var(--color-ink-2)] m-0">{{ $log->reason }}</p>
|
||||
@endif
|
||||
<span class="text-xs text-zinc-500">·</span>
|
||||
<span class="text-xs text-zinc-500">
|
||||
{{ $log->created_at->format('d.m.Y H:i') }}
|
||||
</span>
|
||||
@if($log->changedBy)
|
||||
<span class="text-xs text-zinc-500">·</span>
|
||||
<span class="text-xs text-zinc-500">{{ $log->changedBy->name }}</span>
|
||||
@endif
|
||||
@if($log->source !== 'admin')
|
||||
<flux:badge size="xs" color="zinc">{{ $log->source }}</flux:badge>
|
||||
@endif
|
||||
</div>
|
||||
@if($log->reason)
|
||||
<p class="mt-1 text-zinc-600 dark:text-zinc-400">{{ $log->reason }}</p>
|
||||
@endif
|
||||
</li>
|
||||
@endforeach
|
||||
</ol>
|
||||
</flux:card>
|
||||
</li>
|
||||
@endforeach
|
||||
</ol>
|
||||
</div>
|
||||
</article>
|
||||
@endif
|
||||
|
||||
@if($pr->status === \App\Enums\PressReleaseStatus::Review)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue