12 KiB
Migration der Presswave Landingpage zu Laravel/Livewire
Dokumentation der Konvertierung der React/TypeScript Presswave-Landingpage zu Laravel Blade + Livewire für Business Portal 24.
Datum: 15. Oktober 2025 Ziel-Domain: businessportal24.test Theme-Farben: Primary #cf3628 (Rot), Secondary #f0834a (Orange)
1. Analyse der Quellstruktur
Ursprüngliche React-Struktur (dev/presswave)
src/
├── pages/
│ └── Index.tsx # Haupt-Landingpage
├── components/
│ ├── Header.tsx # Navigation & Suche
│ ├── FilterBar.tsx # Filter-Komponente
│ ├── PressReleaseCard.tsx # Karten-Komponente für Pressemitteilungen
│ └── BurgerMenu.tsx # Mobile Navigation
└── assets/
└── *.jpg # Bilder
Hauptkomponenten identifiziert:
- Header - Sticky Navigation mit Logo, Suchleiste und CTA-Buttons
- FilterBar - Sticky Filter mit Zeitraum, Branche, Region und Sortierung
- Hero Section - Gradient-Banner mit Überschrift
- Featured Section - 3-spaltiges Grid mit hervorgehobenen Releases
- Main Grid - 3-spaltiges Responsive Grid mit allen Releases
- Footer - 4-spaltige Link-Struktur mit Social Media
2. Laravel Blade Struktur erstellt
Haupt-Blade-Datei
Pfad: resources/views/web/businessportal24.blade.php
@extends('web.layouts.web-master')
@section('content')
<main class="min-h-screen flex flex-col">
<livewire:web.header />
<livewire:web.filter-bar />
<!-- Hero Banner -->
<!-- Featured Section -->
<livewire:web.featured-releases />
<!-- Main Grid -->
<livewire:web.press-releases-grid />
<livewire:web.footer />
</main>
@endsection
Features:
- Verwendet CSS-Variablen für Theme-Farben:
var(--color-primary)undvar(--color-secondary) - Animationen via CSS Keyframes (
@keyframes fade-in-up) - Responsive Design mit Tailwind CSS
- Alpine.js für interaktive Elemente
3. Livewire-Komponenten erstellt
3.1 Header-Komponente
Pfad: resources/views/livewire/web/header.blade.php
Funktionen:
- Sticky Header mit Gradient-Border-Top
- Responsive Suchleiste (Desktop & Mobile)
- Burger-Menü für Mobile
- Logo mit dynamischem Gradient
- CTA-Buttons: "Anmelden" und "Veröffentlichen"
Livewire Properties:
public $searchQuery = '';
public $showMobileSearch = false;
Alpine.js Integration:
- Mobile Search Toggle
- Smooth Transitions
3.2 FilterBar-Komponente
Pfad: resources/views/livewire/web/filter-bar.blade.php
Funktionen:
- Sticky Position unterhalb Header (top-16)
- 4 Filter-Dropdowns: Zeitraum, Branche, Region, Sortierung
- Active Filters Display mit Remove-Buttons
- "Alle zurücksetzen" Button
- Live-Wire: Real-time Filtering
Livewire Properties:
public $timeframe = '7';
public $industry = 'all';
public $region = 'all';
public $sortBy = 'newest';
public $activeFilters = [];
Events:
$this->dispatch('filters-updated', [...]);
3.3 PressReleaseCard-Komponente
Pfad: resources/views/components/web/press-release-card.blade.php
Props:
title,teaser,company,industry,region,datehasImage,hasPdf,companyLogo,slug,imageUrl
Features:
- Image Preview mit Lazy Loading
- Company Logo Overlay
- Meta-Informationen (Branche, Region, Datum)
- Badges für Medien (Bild, PDF)
- Hover-Effekte: Scale & Border-Color
- Transition-Animationen (300ms)
CSS-Klassen:
.card {
@apply hover:scale-[1.02] hover:border-primary/20;
@apply transition-all duration-300;
}
3.4 Featured Releases-Komponente
Pfad: resources/views/livewire/web/featured-releases.blade.php
Layout:
- 3-spaltiges Grid (lg:grid-cols-3)
- Linke Seite: 1 große Featured Card (lg:col-span-2)
- Rechte Seite: 2 gestapelte Cards
Mock-Daten:
- 3 Releases mit unterschiedlichen Bildern (Unsplash)
- Verschiedene Branchen: IT, Energie, Finanzen
3.5 Press Releases Grid-Komponente
Pfad: resources/views/livewire/web/press-releases-grid.blade.php
Layout:
- Responsive Grid: 1 col (mobile), 2 cols (md), 3 cols (lg)
- 6 Mock-Releases
Features:
- Verwendet
x-web.press-release-cardKomponente - Loop durch
$releasesArray
3.6 Footer-Komponente
Pfad: resources/views/livewire/web/footer.blade.php
Layout:
- 4-spaltiges Grid (md:grid-cols-4)
- Spalten: Unternehmen, Services, Rechtliches, Social Media
- Theme-Toggle Button (Alpine.js)
Links:
- Interne Links:
/ueber-uns,/kontakt,/preise, etc. - Externe Links: LinkedIn, Twitter (target="_blank")
4. Theme & Styling
4.1 CSS-Theme-Datei
Pfad: resources/css/web/theme-businessportal24.css
Farb-Variablen (HSL):
--primary: 4 61% 49%; /* #cf3628 */
--secondary: 22 84% 61%; /* #f0834a */
Dark Mode Support:
.dark {
--background: 4 20% 10%;
--primary: 4 61% 49%;
/* ... */
}
4.2 Animationen
Keyframes definiert:
@keyframes fade-in-up {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes fade-in-down { /* ... */ }
@keyframes slide-in-right { /* ... */ }
@keyframes scale-in { /* ... */ }
Utility-Klassen:
.animate-fade-in-up { animation: fade-in-up 0.6s ease-out forwards; }
.animation-delay-200 { animation-delay: 0.2s; opacity: 0; }
Verwendung in Blade:
<h1 class="animate-fade-in-up">Titel</h1>
<p class="animate-fade-in-up animation-delay-200">Text</p>
4.3 Component Styles
Buttons:
.btn-primary {
@apply bg-gradient-to-r from-primary to-secondary;
@apply shadow-md hover:shadow-lg;
@apply transition-all duration-300;
}
Cards:
.card {
@apply rounded-xl border shadow-sm hover:shadow-lg;
@apply transition-all duration-300;
}
Badges:
.badge-primary {
@apply bg-primary/10 text-primary border border-primary/20;
}
5. React → Blade/Livewire Konvertierung
Mapping-Tabelle
| React-Konzept | Laravel-Äquivalent | Beispiel |
|---|---|---|
useState() |
public $property |
public $searchQuery = ''; |
props |
@props([...]) |
@props(['title', 'teaser']) |
onClick |
wire:click |
wire:click="search" |
onChange |
wire:model.live |
wire:model.live="timeframe" |
map() |
@foreach |
@foreach($releases as $release) |
x-show (React) |
x-show (Alpine) |
x-show="showMobileSearch" |
dispatch() |
$this->dispatch() |
$this->dispatch('event') |
| CSS-in-JS | Tailwind Classes | class="bg-primary text-white" |
Spezifische Konvertierungen:
React Search Component:
const [searchQuery, setSearchQuery] = useState('');
<input
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
Livewire Äquivalent:
public $searchQuery = '';
<input wire:model="searchQuery" />
React Filter Update:
const [timeframe, setTimeframe] = useState('7');
<select
value={timeframe}
onChange={(e) => setTimeframe(e.target.value)}
>
Livewire Äquivalent:
public $timeframe = '7';
<select wire:model.live="timeframe">
React Conditional Rendering:
{hasImage && (
<Badge>Bild</Badge>
)}
Blade Äquivalent:
@if($hasImage)
<span class="badge">Bild</span>
@endif
6. Routing & Integration
Route hinzufügen
Pfad: routes/web.php oder routes/domains.php
Route::domain('businessportal24.test')->group(function () {
Route::get('/', function () {
return view('web.businessportal24');
});
});
Domain-Config
Pfad: config/domains.php
'businessportal24' => [
'domain_name' => 'businessportal24.test',
'theme' => 'businessportal24',
'view_prefix' => 'web',
'assets_dir' => 'build/web',
'color_scheme' => [
'primary' => '#cf3628',
'secondary' => '#f0834a',
],
'font' => 'Montserrat',
],
7. Verbesserungen & Best Practices
Implementierte Verbesserungen:
-
Performance:
- Lazy Loading für Bilder (
loading="lazy") - CSS-Transitions statt JavaScript-Animationen
- Livewire Live-Updates nur wo nötig
- Lazy Loading für Bilder (
-
Accessibility:
aria-labelfür Icon-Buttons- Semantische HTML-Tags (
<header>,<footer>,<article>) - Keyboard-Navigation Support
-
SEO:
- Semantische Meta-Informationen
- Alt-Texte für Bilder
- Strukturierte Daten via
<article>
-
Responsive Design:
- Mobile-First Approach
- Breakpoints:
sm:,md:,lg: - Touch-optimierte Buttons
8. Testing & Debugging
Lokales Testing:
- Vite Dev-Server starten:
npm run dev:web
- Laravel Dev-Server:
php artisan serve
- Domain-Simulation (.env):
DEV_SIMULATE_DOMAIN=true
DEV_SIMULATED_DOMAIN=businessportal24.test
- Browser öffnen:
http://localhost:8000
Debug-Tipps:
Livewire-Debugging:
<div>
{{ var_dump($searchQuery) }}
@json($activeFilters)
</div>
Alpine.js Debugging:
<div x-data="{ debug: true }">
<template x-if="debug">
<pre x-text="JSON.stringify($data, null, 2)"></pre>
</template>
</div>
9. Nächste Schritte
Zu implementieren:
-
Datenbank-Integration:
- Eloquent Model für
PressRelease - Migration erstellen
- Seeder für Test-Daten
- Eloquent Model für
-
Pagination:
- Livewire Pagination implementieren
- Infinite Scroll Option
-
Suche:
- Laravel Scout Integration
- Full-Text Search mit Meilisearch
-
Filter-Persistenz:
- Query-Parameter für Filter
- Browser-History Integration
-
API:
- REST API für Releases
- API-Dokumentation (Swagger)
-
Admin-Panel:
- CRUD für Pressemitteilungen
- Bild-Upload mit Media Library
10. Dateistruktur (Zusammenfassung)
resources/
├── views/
│ ├── web/
│ │ └── businessportal24.blade.php # Haupt-Blade
│ ├── livewire/
│ │ └── web/
│ │ ├── header.blade.php
│ │ ├── filter-bar.blade.php
│ │ ├── featured-releases.blade.php
│ │ ├── press-releases-grid.blade.php
│ │ └── footer.blade.php
│ └── components/
│ └── web/
│ └── press-release-card.blade.php
└── css/
└── web/
└── theme-businessportal24.css # Theme-Styles
config/
└── domains.php # Domain-Config
routes/
└── domains.php # Routing
11. Lessons Learned
Was gut funktioniert hat:
-
Livewire für State Management:
- Einfache Syntax
- Keine JS-Komplexität
- Reaktive Updates
-
Tailwind CSS:
- Schnelles Styling
- Konsistentes Design
- Responsive Utilities
-
Alpine.js für UI-Interaktionen:
- Leichtgewichtig
- Vue-ähnliche Syntax
- Perfekt für kleine Interaktionen
Herausforderungen:
-
Komplexe React-Hooks → Livewire:
- Lösung: Einfachere State-Struktur
-
CSS-in-JS → Tailwind:
- Lösung: Utility-Klassen + @layer
-
React Context → Laravel:
- Lösung: View::share() & Config
12. Performance-Metriken
Ziel-Metriken:
- First Contentful Paint: < 1.5s
- Time to Interactive: < 3.5s
- Lighthouse Score: > 90
Optimierungen:
-
Asset-Optimierung:
- Vite Build: Code-Splitting
- Image Optimization (WebP)
- CSS Minification
-
Livewire-Optimierung:
wire:model.lazywo möglich- Polling vermeiden
- Lazy-Loading von Komponenten
13. Maintenance & Updates
Regelmäßige Updates:
- Dependencies:
composer update
npm update
- Laravel Updates:
php artisan migrate
php artisan optimize:clear
- Vite Rebuild:
npm run build:web
Kontakt & Support
Entwickler: Claude Code Datum: 15. Oktober 2025 Version: 1.0.0
Bei Fragen oder Problemen:
- CLAUDE.md im Root-Verzeichnis konsultieren
- Laravel Dokumentation: https://laravel.com/docs
- Livewire Dokumentation: https://livewire.laravel.com
Ende der Dokumentation