presseportale/dev/_old/presswave/MIGRATION-TO-LARAVEL.md
Kevin Adametz 5b8bdf4182
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
12-05-2026 Frontend dev
2026-05-12 18:32:33 +02:00

590 lines
12 KiB
Markdown

# 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:
1. **Header** - Sticky Navigation mit Logo, Suchleiste und CTA-Buttons
2. **FilterBar** - Sticky Filter mit Zeitraum, Branche, Region und Sortierung
3. **Hero Section** - Gradient-Banner mit Überschrift
4. **Featured Section** - 3-spaltiges Grid mit hervorgehobenen Releases
5. **Main Grid** - 3-spaltiges Responsive Grid mit allen Releases
6. **Footer** - 4-spaltige Link-Struktur mit Social Media
---
## 2. Laravel Blade Struktur erstellt
### Haupt-Blade-Datei
**Pfad:** `resources/views/web/businessportal24.blade.php`
```blade
@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)` und `var(--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:**
```php
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:**
```php
public $timeframe = '7';
public $industry = 'all';
public $region = 'all';
public $sortBy = 'newest';
public $activeFilters = [];
```
**Events:**
```php
$this->dispatch('filters-updated', [...]);
```
---
### 3.3 PressReleaseCard-Komponente
**Pfad:** `resources/views/components/web/press-release-card.blade.php`
**Props:**
- `title`, `teaser`, `company`, `industry`, `region`, `date`
- `hasImage`, `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:**
```css
.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-card` Komponente
- Loop durch `$releases` Array
---
### 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):**
```css
--primary: 4 61% 49%; /* #cf3628 */
--secondary: 22 84% 61%; /* #f0834a */
```
**Dark Mode Support:**
```css
.dark {
--background: 4 20% 10%;
--primary: 4 61% 49%;
/* ... */
}
```
---
### 4.2 Animationen
**Keyframes definiert:**
```css
@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:**
```css
.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:**
```html
<h1 class="animate-fade-in-up">Titel</h1>
<p class="animate-fade-in-up animation-delay-200">Text</p>
```
---
### 4.3 Component Styles
**Buttons:**
```css
.btn-primary {
@apply bg-gradient-to-r from-primary to-secondary;
@apply shadow-md hover:shadow-lg;
@apply transition-all duration-300;
}
```
**Cards:**
```css
.card {
@apply rounded-xl border shadow-sm hover:shadow-lg;
@apply transition-all duration-300;
}
```
**Badges:**
```css
.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:
```tsx
const [searchQuery, setSearchQuery] = useState('');
<input
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
```
#### Livewire Äquivalent:
```php
public $searchQuery = '';
<input wire:model="searchQuery" />
```
---
#### React Filter Update:
```tsx
const [timeframe, setTimeframe] = useState('7');
<select
value={timeframe}
onChange={(e) => setTimeframe(e.target.value)}
>
```
#### Livewire Äquivalent:
```php
public $timeframe = '7';
<select wire:model.live="timeframe">
```
---
#### React Conditional Rendering:
```tsx
{hasImage && (
<Badge>Bild</Badge>
)}
```
#### Blade Äquivalent:
```blade
@if($hasImage)
<span class="badge">Bild</span>
@endif
```
---
## 6. Routing & Integration
### Route hinzufügen
**Pfad:** `routes/web.php` oder `routes/domains.php`
```php
Route::domain('businessportal24.test')->group(function () {
Route::get('/', function () {
return view('web.businessportal24');
});
});
```
### Domain-Config
**Pfad:** `config/domains.php`
```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:
1. **Performance:**
- Lazy Loading für Bilder (`loading="lazy"`)
- CSS-Transitions statt JavaScript-Animationen
- Livewire Live-Updates nur wo nötig
2. **Accessibility:**
- `aria-label` für Icon-Buttons
- Semantische HTML-Tags (`<header>`, `<footer>`, `<article>`)
- Keyboard-Navigation Support
3. **SEO:**
- Semantische Meta-Informationen
- Alt-Texte für Bilder
- Strukturierte Daten via `<article>`
4. **Responsive Design:**
- Mobile-First Approach
- Breakpoints: `sm:`, `md:`, `lg:`
- Touch-optimierte Buttons
---
## 8. Testing & Debugging
### Lokales Testing:
1. **Vite Dev-Server starten:**
```bash
npm run dev:web
```
2. **Laravel Dev-Server:**
```bash
php artisan serve
```
3. **Domain-Simulation (.env):**
```env
DEV_SIMULATE_DOMAIN=true
DEV_SIMULATED_DOMAIN=businessportal24.test
```
4. **Browser öffnen:**
```
http://localhost:8000
```
---
### Debug-Tipps:
**Livewire-Debugging:**
```blade
<div>
{{ var_dump($searchQuery) }}
@json($activeFilters)
</div>
```
**Alpine.js Debugging:**
```html
<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:
1. **Datenbank-Integration:**
- Eloquent Model für `PressRelease`
- Migration erstellen
- Seeder für Test-Daten
2. **Pagination:**
- Livewire Pagination implementieren
- Infinite Scroll Option
3. **Suche:**
- Laravel Scout Integration
- Full-Text Search mit Meilisearch
4. **Filter-Persistenz:**
- Query-Parameter für Filter
- Browser-History Integration
5. **API:**
- REST API für Releases
- API-Dokumentation (Swagger)
6. **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:
1. **Livewire für State Management:**
- Einfache Syntax
- Keine JS-Komplexität
- Reaktive Updates
2. **Tailwind CSS:**
- Schnelles Styling
- Konsistentes Design
- Responsive Utilities
3. **Alpine.js für UI-Interaktionen:**
- Leichtgewichtig
- Vue-ähnliche Syntax
- Perfekt für kleine Interaktionen
### Herausforderungen:
1. **Komplexe React-Hooks → Livewire:**
- Lösung: Einfachere State-Struktur
2. **CSS-in-JS → Tailwind:**
- Lösung: Utility-Klassen + @layer
3. **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:
1. **Asset-Optimierung:**
- Vite Build: Code-Splitting
- Image Optimization (WebP)
- CSS Minification
2. **Livewire-Optimierung:**
- `wire:model.lazy` wo möglich
- Polling vermeiden
- Lazy-Loading von Komponenten
---
## 13. Maintenance & Updates
### Regelmäßige Updates:
1. **Dependencies:**
```bash
composer update
npm update
```
2. **Laravel Updates:**
```bash
php artisan migrate
php artisan optimize:clear
```
3. **Vite Rebuild:**
```bash
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**