Hub (Web): statische Seiten (Rechtstexte, API, FAQ ...) rendern das Hub-Geruest
x-web.static-page ist jetzt host-aware: Auf der pressekonto-Domain laden Utility-Bar + Hub-Header/-Footer (inkl. Kontakt- und Widerrufs-Modal, damit die Footer-Buttons ueberall funktionieren) statt des Spoke-Geruests; Breadcrumb fuehrt zur Hub-Landing. Hub-Anker-Navigation (#tarife/#funktion/#familie/#faq) absolut auf die Landing, damit sie auch von Unterseiten aus funktioniert. Spokes unveraendert (Test). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
6621b030e6
commit
c7450da301
4 changed files with 70 additions and 11 deletions
|
|
@ -44,7 +44,7 @@
|
||||||
<li><a href="{{ route('login') }}" class="hover:text-white transition-colors">Anmelden</a></li>
|
<li><a href="{{ route('login') }}" class="hover:text-white transition-colors">Anmelden</a></li>
|
||||||
<li><a href="{{ route('register') }}" class="hover:text-white transition-colors">Konto erstellen</a></li>
|
<li><a href="{{ route('register') }}" class="hover:text-white transition-colors">Konto erstellen</a></li>
|
||||||
@endauth
|
@endauth
|
||||||
<li><a href="#tarife" class="hover:text-white transition-colors">Tarife</a></li>
|
<li><a href="{{ route('home') }}#tarife" class="hover:text-white transition-colors">Tarife</a></li>
|
||||||
<li><button type="button" x-data @click="$dispatch('open-contact-modal')" class="hover:text-white transition-colors cursor-pointer">Kontakt aufnehmen</button></li>
|
<li><button type="button" x-data @click="$dispatch('open-contact-modal')" class="hover:text-white transition-colors cursor-pointer">Kontakt aufnehmen</button></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -52,8 +52,8 @@
|
||||||
<div>
|
<div>
|
||||||
<div class="eyebrow on-dark mb-3.5">Plattform</div>
|
<div class="eyebrow on-dark mb-3.5">Plattform</div>
|
||||||
<ul class="space-y-2 text-[13px] text-white/75 list-none p-0 m-0">
|
<ul class="space-y-2 text-[13px] text-white/75 list-none p-0 m-0">
|
||||||
<li><a href="#funktion" class="hover:text-white transition-colors">So funktioniert es</a></li>
|
<li><a href="{{ route('home') }}#funktion" class="hover:text-white transition-colors">So funktioniert es</a></li>
|
||||||
<li><a href="#familie" class="hover:text-white transition-colors">Die Portale</a></li>
|
<li><a href="{{ route('home') }}#familie" class="hover:text-white transition-colors">Die Portale</a></li>
|
||||||
<li><a href="{{ route('docs.api.v1') }}" class="hover:text-white transition-colors">API-Referenz</a></li>
|
<li><a href="{{ route('docs.api.v1') }}" class="hover:text-white transition-colors">API-Referenz</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,13 @@
|
||||||
]);
|
]);
|
||||||
$brandTagline = $brand['tagline_short'] ?? 'Publisher · Hub';
|
$brandTagline = $brand['tagline_short'] ?? 'Publisher · Hub';
|
||||||
|
|
||||||
|
// Absolute Anker auf die Landing, damit die Navigation auch von den
|
||||||
|
// statischen Unterseiten (Impressum, AGB, API …) aus funktioniert.
|
||||||
$navigation = $navigation ?? [
|
$navigation = $navigation ?? [
|
||||||
['label' => 'Tarife', 'href' => '#tarife'],
|
['label' => 'Tarife', 'href' => route('home').'#tarife'],
|
||||||
['label' => 'So funktioniert es', 'href' => '#funktion'],
|
['label' => 'So funktioniert es', 'href' => route('home').'#funktion'],
|
||||||
['label' => 'Plattform-Familie', 'href' => '#familie'],
|
['label' => 'Plattform-Familie', 'href' => route('home').'#familie'],
|
||||||
['label' => 'FAQ', 'href' => '#faq'],
|
['label' => 'FAQ', 'href' => route('home').'#faq'],
|
||||||
];
|
];
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,21 +11,34 @@
|
||||||
Liefert site-header, Breadcrumb, Masthead und site-footer; der Seiteninhalt
|
Liefert site-header, Breadcrumb, Masthead und site-footer; der Seiteninhalt
|
||||||
kommt als Slot. Prosa-Seiten wrappen ihren Inhalt in `.pm-body` (zentrale
|
kommt als Slot. Prosa-Seiten wrappen ihren Inhalt in `.pm-body` (zentrale
|
||||||
Editorial-Typografie aus shared-styles.css).
|
Editorial-Typografie aus shared-styles.css).
|
||||||
|
|
||||||
|
Host-aware: Auf der Hub-Domain (pressekonto) rendert das Hub-Gerüst
|
||||||
|
(Utility-Bar, Hub-Header/-Footer inkl. Kontakt- und Widerrufs-Modal),
|
||||||
|
auf den Spokes das Portal-Gerüst.
|
||||||
--}}
|
--}}
|
||||||
|
|
||||||
@php
|
@php
|
||||||
$brandConfig = config('domains.domains.'.config('app.theme').'.brand', []);
|
$isHub = str_contains(request()->getHost(), 'pressekonto');
|
||||||
|
$brandConfig = $isHub
|
||||||
|
? config('domains.domains.pressekonto.brand', [])
|
||||||
|
: config('domains.domains.'.config('app.theme').'.brand', []);
|
||||||
$brandName = $brandConfig['name'] ?? 'businessportal';
|
$brandName = $brandConfig['name'] ?? 'businessportal';
|
||||||
$brandAccent = $brandConfig['accent'] ?? '24';
|
$brandAccent = $brandConfig['accent'] ?? '24';
|
||||||
|
$homeHref = $isHub ? route('home') : route('web.home');
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
<x-web.site-header />
|
@if ($isHub)
|
||||||
|
<x-web.hub.top-utility-bar />
|
||||||
|
<x-web.hub.site-header />
|
||||||
|
@else
|
||||||
|
<x-web.site-header />
|
||||||
|
@endif
|
||||||
|
|
||||||
<main class="bg-bg text-ink">
|
<main class="bg-bg text-ink">
|
||||||
{{-- Breadcrumb --}}
|
{{-- Breadcrumb --}}
|
||||||
<div class="border-b border-bg-rule">
|
<div class="border-b border-bg-rule">
|
||||||
<div class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 py-2.5 flex items-center gap-2 text-[12px] text-ink-3">
|
<div class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 py-2.5 flex items-center gap-2 text-[12px] text-ink-3">
|
||||||
<a href="{{ route('web.home') }}" class="hover:text-ink transition-colors">{{ $brandName }}{{ $brandAccent }}</a>
|
<a href="{{ $homeHref }}" class="hover:text-ink transition-colors">{{ $brandName }}{{ $brandAccent }}</a>
|
||||||
@if ($breadcrumb)
|
@if ($breadcrumb)
|
||||||
<span class="text-ink-4" aria-hidden="true">›</span>
|
<span class="text-ink-4" aria-hidden="true">›</span>
|
||||||
<span class="text-ink">{{ $breadcrumb }}</span>
|
<span class="text-ink">{{ $breadcrumb }}</span>
|
||||||
|
|
@ -54,4 +67,10 @@
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<x-web.site-footer />
|
@if ($isHub)
|
||||||
|
<x-web.hub.contact-modal />
|
||||||
|
<x-web.hub.withdrawal-modal />
|
||||||
|
<x-web.hub.site-footer />
|
||||||
|
@else
|
||||||
|
<x-web.site-footer />
|
||||||
|
@endif
|
||||||
|
|
|
||||||
38
tests/Feature/Web/HubStaticPageShellTest.php
Normal file
38
tests/Feature/Web/HubStaticPageShellTest.php
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
test('static pages on the hub domain render the hub shell', function (string $path) {
|
||||||
|
/** @var TestCase $this */
|
||||||
|
$response = $this->get('https://pressekonto.test/de/'.$path)->assertSuccessful();
|
||||||
|
$content = $response->getContent();
|
||||||
|
|
||||||
|
expect($content)
|
||||||
|
// Hub-Kopf: Utility-Bar + Hub-Header statt Spoke-Gerüst.
|
||||||
|
->toContain('Publisher-Hub für')
|
||||||
|
->toContain('Publisher · Hub')
|
||||||
|
// Hub-Footer inkl. gesetzlichem Widerrufsbutton + Modals.
|
||||||
|
->toContain('Vertrag widerrufen')
|
||||||
|
->toContain('open-withdrawal-modal')
|
||||||
|
->toContain('open-contact-modal')
|
||||||
|
// Kein Spoke-Portal-Branding im Gerüst.
|
||||||
|
->not->toContain('Pressemitteilungen · DACH');
|
||||||
|
})->with(['impressum', 'agb', 'datenschutz', 'cookies', 'api']);
|
||||||
|
|
||||||
|
test('the hub static page breadcrumb links back to the hub landing', function () {
|
||||||
|
/** @var TestCase $this */
|
||||||
|
$this->get('https://pressekonto.test/de/impressum')
|
||||||
|
->assertSuccessful()
|
||||||
|
->assertSee('href="https://pressekonto.test"', false)
|
||||||
|
->assertSeeText('pressekonto');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('static pages on the spoke domains keep the spoke shell', function () {
|
||||||
|
/** @var TestCase $this */
|
||||||
|
$response = $this->get('https://businessportal24.test/de/impressum')->assertSuccessful();
|
||||||
|
$content = $response->getContent();
|
||||||
|
|
||||||
|
expect($content)
|
||||||
|
->not->toContain('Publisher-Hub für')
|
||||||
|
->not->toContain('Vertrag widerrufen');
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue