Spoke-Frontend-Audit: Fake-Inhalte raus, Newsletter-Rueckbau, echte Boersendaten, EN-Lokalisierung
Frontend-Umbau (Kevin, 06.07.2026), Ergebnis des businessportal24-Audits: - Fake-Anzeigen und Mock-/Fallback-Daten entfernt (focus-ad, feed-ad, highlight-card, press-release-card, featured-releases, press-releases-grid); Sektionen rendern nur noch mit echten Daten oder gar nicht - Newsletter-Strip und Newsletter-Box zurueckgebaut (Feature nachgelagert, vor Reaktivierung DOI-Flow noetig) - Echte Boersendaten: MarketDataService (Yahoo-Finance-Quotes, config/market.php, Cache) + market:refresh alle 15 Min. im Scheduler; live-ticker blendet sich ohne Daten aus - EN-Lokalisierung der Kern-Seiten via lang/de/web.php + lang/en/web.php; Carbon-Locale folgt app()->getLocale() - Web-Tests auf den neuen Frontend-Stand nachgezogen (Suite: 993 gruen) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
3320aaaa85
commit
bfad13af7d
67 changed files with 1735 additions and 1521 deletions
|
|
@ -1,8 +1,5 @@
|
|||
@props([
|
||||
'navigation' => null,
|
||||
'ticker' => [],
|
||||
'marketIndex' => null,
|
||||
'asideSlides' => null,
|
||||
'brand' => null,
|
||||
])
|
||||
|
||||
|
|
@ -32,7 +29,7 @@
|
|||
// Navigation = echte Rubriken der aktiven Ausgabe. Es gibt keine separate
|
||||
// Übersichtsseite; jeder Eintrag führt direkt auf die Kategorieseite.
|
||||
$navigation ??= collect([
|
||||
['label' => 'Startseite', 'href' => route('web.home'), 'active' => request()->routeIs('web.home')],
|
||||
['label' => __('web.nav.home'), 'href' => route('web.home'), 'active' => request()->routeIs('web.home')],
|
||||
])->concat(
|
||||
\App\Support\CategoryNavigation::items()->map(fn (array $category): array => [
|
||||
'label' => $category['label'],
|
||||
|
|
@ -41,7 +38,7 @@
|
|||
])
|
||||
)->all();
|
||||
|
||||
$activeLabel = collect($navigation)->firstWhere('active', true)['label'] ?? 'Menü';
|
||||
$activeLabel = collect($navigation)->firstWhere('active', true)['label'] ?? __('web.nav.menu');
|
||||
@endphp
|
||||
|
||||
<header>
|
||||
|
|
@ -54,7 +51,7 @@
|
|||
</span>
|
||||
|
||||
<span class="hidden md:flex items-center px-3.5 text-[9.5px] uppercase font-semibold tracking-[0.16em] text-ink-3 whitespace-nowrap">
|
||||
Ausgabe
|
||||
{{ __('web.header.edition') }}
|
||||
</span>
|
||||
|
||||
@foreach ($editions as $edition)
|
||||
|
|
@ -62,7 +59,7 @@
|
|||
class="flex items-center gap-1 sm:gap-1.5 px-1.5 sm:px-2.5 py-2 text-[11px] sm:text-[11.5px] whitespace-nowrap -mb-px border-b-2 transition-colors
|
||||
@if ($edition['code'] === $activeEdition) font-semibold text-ink-on-dark bg-white/[0.06] border-brand
|
||||
@else font-medium text-ink-on-dark-2 border-transparent hover:text-ink-on-dark hover:bg-white/[0.04] @endif"
|
||||
aria-label="Ausgabe {{ $edition['label'] }}"
|
||||
aria-label="{{ __('web.header.edition') }} {{ $edition['label'] }}"
|
||||
@if ($edition['code'] === $activeEdition) aria-current="true" @endif>
|
||||
<span class="text-[11px] sm:text-[12px] leading-none">{{ $edition['flag'] }}</span>
|
||||
<span>{{ $edition['label'] }}</span>
|
||||
|
|
@ -71,7 +68,7 @@
|
|||
|
||||
<span class="flex-1"></span>
|
||||
|
||||
{{-- Sprache: mobil verkürzt; ab lg mit Newsletter/RSS/API --}}
|
||||
{{-- Sprache: mobil verkürzt; ab lg mit FAQ/API --}}
|
||||
<span class="flex items-center gap-3 sm:gap-4 py-2 whitespace-nowrap">
|
||||
<span class="inline-flex items-center gap-1.5">
|
||||
<svg width="11" height="11" viewBox="0 0 12 12" fill="none" class="opacity-60" aria-hidden="true">
|
||||
|
|
@ -84,7 +81,7 @@
|
|||
</strong>
|
||||
</span>
|
||||
<span class="hidden lg:inline-block w-px h-[14px] bg-ink-on-dark-rule"></span>
|
||||
<a href="{{ route('preise') }}" class="cursor-pointer font-medium text-ink-on-dark hover:text-brand transition-colors">Preise</a>
|
||||
<a href="{{ route('preise') }}" class="cursor-pointer font-medium text-ink-on-dark hover:text-brand transition-colors">{{ __('web.header.pricing') }}</a>
|
||||
<span class="hidden lg:inline-block w-px h-[14px] bg-ink-on-dark-rule"></span>
|
||||
<a href="{{ route('faq') }}" class="hidden lg:inline cursor-pointer hover:text-ink-on-dark transition-colors">FAQ</a>
|
||||
<a href="{{ route('api') }}" class="hidden lg:inline cursor-pointer hover:text-ink-on-dark transition-colors">API</a>
|
||||
|
|
@ -95,9 +92,11 @@
|
|||
{{-- Header (Logo + Suche + Buttons + Burger) --}}
|
||||
<div id="header" class="header-normal bg-bg border-b border-bg-rule"
|
||||
x-data="{ searchOpen: false }"
|
||||
@keydown.escape.window="searchOpen = false">
|
||||
@keydown.escape.window="searchOpen = false"
|
||||
@keydown.window.prevent.cmd.k="$refs.desktopSearch ? $refs.desktopSearch.focus() : searchOpen = true"
|
||||
@keydown.window.prevent.ctrl.k="$refs.desktopSearch ? $refs.desktopSearch.focus() : searchOpen = true">
|
||||
<div class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 py-3 lg:py-[18px] flex items-center gap-3 sm:gap-4 lg:gap-6">
|
||||
<a href="{{ route('web.home') }}" class="block cursor-pointer group flex-shrink-0" aria-label="{{ $brandName }}{{ $brandAccent }} Startseite">
|
||||
<a href="{{ route('web.home') }}" class="block cursor-pointer group flex-shrink-0" aria-label="{{ $brandName }}{{ $brandAccent }} {{ __('web.header.homepage') }}">
|
||||
<div class="text-[22px] sm:text-[24px] lg:text-[28px] font-semibold leading-none tracking-[-0.5px]">
|
||||
<x-web.brand-mark :brand="$themeKey" />
|
||||
</div>
|
||||
|
|
@ -108,14 +107,14 @@
|
|||
|
||||
{{-- Suchfeld nur ab md sichtbar --}}
|
||||
<form action="{{ route('suche') }}" method="get" class="hidden md:block flex-1 max-w-[460px]">
|
||||
<label class="sr-only" for="site-search">Pressemitteilungen, Unternehmen, Branchen, ISIN durchsuchen</label>
|
||||
<label class="sr-only" for="site-search">{{ __('web.header.search_label') }}</label>
|
||||
<div class="flex items-center gap-2.5 px-3.5 py-2.5 border border-bg-rule bg-bg-elev text-[13px] text-ink-3 rounded-[2px] focus-within:border-brand transition-colors">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
|
||||
<circle cx="7" cy="7" r="5" stroke="currentColor" stroke-width="1.5" />
|
||||
<path d="M11 11l3 3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
|
||||
</svg>
|
||||
<input id="site-search" type="search" name="q"
|
||||
placeholder="Pressemitteilungen, Unternehmen, Branchen, ISIN…"
|
||||
<input id="site-search" type="search" name="q" x-ref="desktopSearch"
|
||||
placeholder="{{ __('web.header.search_placeholder') }}"
|
||||
class="flex-1 bg-transparent border-0 p-0 text-[13px] text-ink placeholder:text-ink-3 focus:outline-none focus:ring-0 min-w-0">
|
||||
<span class="hidden xl:inline-block text-[10.5px] text-ink-4 border border-bg-rule px-1.5 py-0.5 rounded-[2px] font-mono">⌘K</span>
|
||||
</div>
|
||||
|
|
@ -124,7 +123,7 @@
|
|||
<svg width="10" height="10" viewBox="0 0 12 12" fill="none" aria-hidden="true">
|
||||
<path d="M2 3h8M3.5 6h5M5 9h2" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" />
|
||||
</svg>
|
||||
Erweiterte Suche
|
||||
{{ __('web.header.advanced_search') }}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
|
@ -135,7 +134,7 @@
|
|||
<button type="button"
|
||||
@click="searchOpen = true"
|
||||
class="md:hidden inline-flex items-center justify-center w-10 h-10 text-ink rounded-[2px] cursor-pointer hover:bg-bg-elev transition-colors"
|
||||
aria-label="Suche öffnen">
|
||||
aria-label="{{ __('web.header.search_open') }}">
|
||||
<svg width="20" height="20" viewBox="0 0 16 16" fill="none" aria-hidden="true">
|
||||
<circle cx="7" cy="7" r="5" stroke="currentColor" stroke-width="1.5" />
|
||||
<path d="M11 11l3 3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
|
||||
|
|
@ -145,23 +144,23 @@
|
|||
{{-- Anmelden: führt in den Hub (Portal-Domain). --}}
|
||||
<a href="{{ rtrim(config('domains.domain_portal_url', config('app.url')), '/') }}/login"
|
||||
class="inline-flex items-center gap-2 px-2 sm:px-3 lg:px-4 py-2 lg:py-2.5 text-[13px] font-semibold text-ink rounded-[2px] cursor-pointer hover:text-brand transition-colors"
|
||||
aria-label="Anmelden">
|
||||
aria-label="{{ __('web.header.login') }}">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" class="sm:hidden" aria-hidden="true">
|
||||
<circle cx="12" cy="8" r="4" stroke="currentColor" stroke-width="1.8" />
|
||||
<path d="M4 21c0-4 4-7 8-7s8 3 8 7" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" />
|
||||
</svg>
|
||||
<span class="hidden sm:inline">Anmelden</span>
|
||||
<span class="hidden sm:inline">{{ __('web.header.login') }}</span>
|
||||
</a>
|
||||
|
||||
{{-- Veröffentlichen --}}
|
||||
<a href="{{ route('veroeffentlichen') }}"
|
||||
class="inline-flex items-center gap-1.5 sm:gap-2 px-3 sm:px-4 lg:px-[18px] py-2 lg:py-2.5 text-[12.5px] sm:text-[13px] font-semibold text-white bg-brand cursor-pointer hover:bg-brand-deep rounded-[2px] transition-colors whitespace-nowrap"
|
||||
aria-label="Pressemitteilung veröffentlichen">
|
||||
aria-label="{{ __('web.header.publish_aria') }}">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" class="sm:hidden" aria-hidden="true">
|
||||
<path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" />
|
||||
</svg>
|
||||
<span class="sm:hidden">PM</span>
|
||||
<span class="hidden sm:inline">Veröffentlichen</span>
|
||||
<span class="hidden sm:inline">{{ __('web.header.publish') }}</span>
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" class="hidden sm:inline" aria-hidden="true">
|
||||
<path d="M3 6h6M6 3l3 3-3 3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
|
|
@ -180,13 +179,13 @@
|
|||
<div class="max-w-layout mx-auto px-4 sm:px-6 py-6">
|
||||
<div class="flex items-start justify-between mb-4">
|
||||
<div>
|
||||
<div class="eyebrow mb-1">Suche</div>
|
||||
<h2 class="font-serif text-[22px] font-semibold text-ink">Pressemitteilungen durchsuchen</h2>
|
||||
<div class="eyebrow mb-1">{{ __('web.header.search_eyebrow') }}</div>
|
||||
<h2 class="font-serif text-[22px] font-semibold text-ink">{{ __('web.header.search_title') }}</h2>
|
||||
</div>
|
||||
<button type="button"
|
||||
@click="searchOpen = false"
|
||||
class="inline-flex items-center justify-center w-10 h-10 text-ink rounded-[2px] cursor-pointer hover:bg-bg-elev transition-colors"
|
||||
aria-label="Suche schließen">
|
||||
aria-label="{{ __('web.header.search_close') }}">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||||
<path d="M6 6l12 12M6 18L18 6" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" />
|
||||
</svg>
|
||||
|
|
@ -194,20 +193,20 @@
|
|||
</div>
|
||||
|
||||
<form action="{{ route('suche') }}" method="get">
|
||||
<label class="sr-only" for="site-search-mobile">Pressemitteilungen durchsuchen</label>
|
||||
<label class="sr-only" for="site-search-mobile">{{ __('web.header.search_title') }}</label>
|
||||
<div class="flex items-center gap-2.5 px-4 py-3.5 border border-bg-rule-strong bg-bg-elev text-[15px] text-ink-3 rounded-[2px]">
|
||||
<svg width="20" height="20" viewBox="0 0 16 16" fill="none" aria-hidden="true">
|
||||
<circle cx="7" cy="7" r="5" stroke="currentColor" stroke-width="1.5" />
|
||||
<path d="M11 11l3 3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
|
||||
</svg>
|
||||
<input id="site-search-mobile" type="search" name="q"
|
||||
placeholder="Pressemitteilungen, Unternehmen, Branchen, ISIN…"
|
||||
placeholder="{{ __('web.header.search_placeholder') }}"
|
||||
x-ref="searchInput"
|
||||
x-init="$watch('searchOpen', value => value && setTimeout(() => $refs.searchInput.focus(), 50))"
|
||||
class="flex-1 bg-transparent border-0 p-0 text-[15px] text-ink placeholder:text-ink-3 focus:outline-none focus:ring-0 min-w-0">
|
||||
<button type="submit"
|
||||
class="px-3 py-1.5 text-[12px] font-semibold bg-brand text-white rounded-[2px] cursor-pointer hover:bg-brand-deep transition-colors">
|
||||
Suchen
|
||||
{{ __('web.header.search_submit') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-3 flex justify-between text-[11.5px] text-ink-3">
|
||||
|
|
@ -215,12 +214,12 @@
|
|||
<svg width="10" height="10" viewBox="0 0 12 12" fill="none" aria-hidden="true">
|
||||
<path d="M2 3h8M3.5 6h5M5 9h2" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" />
|
||||
</svg>
|
||||
Erweiterte Suche
|
||||
{{ __('web.header.advanced_search') }}
|
||||
</a>
|
||||
<span class="hidden sm:inline-flex items-center gap-1.5">
|
||||
Drücken Sie
|
||||
{{ __('web.header.press') }}
|
||||
<kbd class="font-mono text-[10.5px] text-ink-4 border border-bg-rule px-1.5 py-0.5 rounded-[2px]">Esc</kbd>
|
||||
zum Schließen
|
||||
{{ __('web.header.to_close') }}
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
|
|
@ -234,7 +233,7 @@
|
|||
x-data="{ menuOpen: false }"
|
||||
@keydown.escape.window="menuOpen = false"
|
||||
@click.outside="menuOpen = false"
|
||||
aria-label="Hauptnavigation">
|
||||
aria-label="{{ __('web.nav.aria_label') }}">
|
||||
|
||||
{{-- Desktop: horizontale Tabs --}}
|
||||
<div class="hidden lg:flex max-w-layout mx-auto px-8 items-stretch">
|
||||
|
|
@ -255,7 +254,7 @@
|
|||
class="flex items-center justify-between w-full py-3 cursor-pointer group"
|
||||
:aria-expanded="menuOpen.toString()"
|
||||
aria-controls="mobile-nav-menu"
|
||||
aria-label="Hauptmenü öffnen">
|
||||
aria-label="{{ __('web.nav.open_menu') }}">
|
||||
<span class="flex items-center gap-3">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" class="text-ink"
|
||||
:class="{ 'hidden': menuOpen }" aria-hidden="true">
|
||||
|
|
@ -265,7 +264,7 @@
|
|||
:class="{ 'hidden': !menuOpen, '!block': menuOpen }" aria-hidden="true">
|
||||
<path d="M6 6l12 12M6 18L18 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
|
||||
</svg>
|
||||
<span class="text-[10px] font-bold tracking-[0.18em] uppercase text-ink-3 group-hover:text-ink transition-colors">Rubrik</span>
|
||||
<span class="text-[10px] font-bold tracking-[0.18em] uppercase text-ink-3 group-hover:text-ink transition-colors">{{ __('web.nav.section') }}</span>
|
||||
<span class="font-serif text-[15px] font-semibold text-ink leading-none">{{ $activeLabel }}</span>
|
||||
</span>
|
||||
<svg width="14" height="14" viewBox="0 0 12 12" fill="none" class="text-ink-3 transition-transform"
|
||||
|
|
@ -304,5 +303,6 @@
|
|||
</div>
|
||||
</nav>
|
||||
|
||||
<x-web.live-ticker :items="$ticker" :market-index="$marketIndex" :aside-slides="$asideSlides" />
|
||||
{{-- Befüllt sich selbst (TickerData) — auf allen Seiten identisch. --}}
|
||||
<x-web.live-ticker />
|
||||
</header>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue