From 970b4909fa7e316d0d29d044e8feef93c9dfbc2c Mon Sep 17 00:00:00 2001 From: Kevin Adametz Date: Fri, 12 Jun 2026 16:20:23 +0000 Subject: [PATCH] =?UTF-8?q?PM-Vorschau:=20Firmen-Kachel=20im=20Stil=20der?= =?UTF-8?q?=20Firmen=C3=BCbersicht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- ...unktionen & Magic-Link-Änderungsprozess.md | 33 ++++- .../customer/press-releases/show.blade.php | 116 ++++++++++++++++-- 2 files changed, 131 insertions(+), 18 deletions(-) diff --git a/docs/weiteres/Decision-Update Phase-2-Funktionen & Magic-Link-Änderungsprozess.md b/docs/weiteres/Decision-Update Phase-2-Funktionen & Magic-Link-Änderungsprozess.md index fb1d299..0824942 100644 --- a/docs/weiteres/Decision-Update Phase-2-Funktionen & Magic-Link-Änderungsprozess.md +++ b/docs/weiteres/Decision-Update Phase-2-Funktionen & Magic-Link-Änderungsprozess.md @@ -1,6 +1,6 @@ -**Version:** Juni 2026 (Rev. 2) **Datum:** 12.06.2026 **Status:** Abgestimmt – bereit zur Integration ins Konzept-/Decision-Log **Scope:** Definition von Boost und Veröffentlichungsnachweis (Launch), des Magic-Link-Zugangs- und Änderungsprozesses sowie der Phase-2-Funktionen (Vorab-Prüfung/Redigieren, Prüfzähler, höheres Prüfkontingent, kostenpflichtige Änderungspfade). **Änderungen Rev. 2:** KI bei E/F entfernt (Admin-Panel statt KI-Check); A nutzt Algorithmus-Diff statt KI; Bremsen-/Limit-Spalte für alle Pfade ergänzt. **Änderungen Rev. 3:** A & B als Launch bestätigt; Boost-Preisstaffel (12/20/35) und PDF-Preis (3 Credits) festgelegt; G Depublizieren = 25 Credits. +**Version:** Juni 2026 (Rev. 2) **Datum:** 12.06.2026 **Status:** Abgestimmt – bereit zur Integration ins Konzept-/Decision-Log **Scope:** Definition von Boost und Veröffentlichungsnachweis (Launch), des Magic-Link-Zugangs- und Änderungsprozesses sowie der Phase-2-Funktionen (Vorab-Prüfung/Redigieren, Prüfzähler, höheres Prüfkontingent, kostenpflichtige Änderungspfade). **Änderungen Rev. 2:** KI bei E/F entfernt (Admin-Panel statt KI-Check); A nutzt Algorithmus-Diff statt KI; Bremsen-/Limit-Spalte für alle Pfade ergänzt. **Änderungen Rev. 3:** A & B als Launch bestätigt; Boost-Preisstaffel (12/20/35) und PDF-Preis (3 Credits) festgelegt; G Depublizieren = 25 Credits. **Änderungen Rev. 4:** Extra-PM ergänzt – tier-gestaffelt (19/15/12/10/8 Credits); Cross-Portal-Veröffentlichung als kein Thema vermerkt (Portale getrennt). --- @@ -17,7 +17,27 @@ Dieses Update definiert die credit-nahen Funktionen und den Änderungsprozess f ## 2. Launch-Funktionen -### 2.1 Boost (Platzierung) +### 2.1 Extra-Pressemitteilung (Kontingent-Nachkauf) + +Die Brücke zwischen Tarif-Kontingent und Credit-Wallet: Ist das monatliche PM-Kontingent voll, kann eine einzelne weitere PM über die Wallet nachgekauft werden – ohne Zwang zum nächsthöheren Tarif. Das ist die faire Alternative zum erzwungenen Upgrade und der genau gewünschte Fall „ich brauche _einmalig_ eine PM mehr". + +**Preis ist tier-gestaffelt** (Treuevorteil: höheres Abo = günstigere Extra-PM): + +|Situation|Extra-PM|Inkl. PM-Preis|Logik| +|---|---|---|---| +|Kein Abo (Einzel)|19 Credits|19,00 €|voller Satz = Einzel-PM-Preis| +|Starter|15 Credits|9,67 €|günstiger als Einzel, mild über inkludiert| +|Business|12 Credits|4,90 €|–| +|Pro|10 Credits|3,96 €|–| +|Agency|8 Credits|3,32 €|–| + +**Mechanik:** Der Extra-PM-Preis wird **zur Kaufzeit aus dem aktiven Abo abgeleitet**, nicht statisch gespeichert. Reicht das Wallet-Guthaben nicht, greift der kontextuelle Mini-Checkout („Kostet 15 Credits, du hast 8" → Paket nachladen). Der Volumenrabatt steckt bereits in den Credit-Paketen – **keine** separaten Extra-PM-Bündel nötig (eine Wallet, ein tier-abhängiger Preis). + +**Design-Entscheidung (bewusst):** Der prozentuale Aufschlag ggü. dem inkludierten PM-Preis ist bei Starter am mildesten (+55 %), bei den oberen Tiers höher (~140–150 %). Das ist gewollt: Die gelegentliche 4. PM eines Starter-Kunden wird _nicht_ bestraft, um künstlichen Upgrade-Druck zu erzeugen – passt zur „fair bleiben, kein Zwang"-Linie. Wer dauerhaft viel veröffentlicht, wandert ohnehin in höhere Tiers. + +**Tageslimit gilt auch hier:** Nachgekaufte Extra-PMs unterliegen demselben Tageslimit wie das Kontingent (kein „Spam freikaufen"; höherer Tagesdurchsatz = Enterprise-Fall). + +### 2.2 Boost (Platzierung) - **Was:** bezahlte Hervorhebung einer PM – Platzierung auf Startseite und Branchen-/Kategorieseite - **Gate:** nur **grüne** PMs sind boostbar; gelb/rot nicht @@ -35,7 +55,7 @@ Dieses Update definiert die credit-nahen Funktionen und den Änderungsprozess f Moderate Staffel: Pro-Tag-Preis sinkt mit der Dauer, der Einstieg (7 Tage / 12) bleibt unter dem PM-Preis von 19 – ein Boost wirkt nie teurer als das Veröffentlichen selbst. Passt zur „Nische besetzen statt abschöpfen"-Linie (Volumen statt Einzelmarge). -### 2.2 Veröffentlichungsnachweis / PDF +### 2.3 Veröffentlichungsnachweis / PDF - **Was:** generiertes PDF „PM XY wurde am … auf … veröffentlicht" inkl. URL, Datum, Vorschau - **Zweck:** Reporting an Vorgesetzte/Kunden – klassische PR-Mitnahme @@ -173,8 +193,9 @@ Depublizieren bewusst am teuersten und mit Bedenkzeit, weil irreversibelste Akti --- -## 6. Offene Punkte -- **Kosten-Anker C/D** final bestätigen, sobald das Credit-/Prüf-System gebaut wird (aktuell ≈ 8 / ≈ 4 Credits). -**In Rev. 3 abgeschlossen:** A/B-Launch ✓ · Boost-Staffel 12/20/35 ✓ · PDF 3 Credits ✓ · G Depublizieren 25 Credits ✓ \ No newline at end of file +**Bewusst nicht im Scope – Cross-Portal-Veröffentlichung:** Die beiden Portale (presseecho.de, businessportal24.com) sind optisch, inhaltlich und systemisch vollständig getrennt; im Relaunch laufen sie lediglich auf einem gemeinsamen Backend zusammen. Eine PM auf beiden Portalen gleichzeitig zu veröffentlichen ist **kein Feature** – wer in beiden präsent sein will, bucht zwei getrennte Einträge (zwei Slots / zwei Extra-PMs). Das vermeidet Duplicate-Content über die eigenen Domains und passt zur getrennten Zielgruppen-Logik. Kein Phase-2-Punkt, sondern bewusst ausgeschlossen. +Noch mal ein wichtiger Hintergrund, der noch dokumentiert werden muss. Das sollte auch zukünftig gegebenenfalls geprüft werden. + +**In Rev. 3 abgeschlossen:** A/B-Launch ✓ · Boost-Staffel 12/20/35 ✓ · PDF 3 Credits ✓ · G Depublizieren 25 Credits ✓ **In Rev. 4 abgeschlossen:** Extra-PM tier-gestaffelt (19/15/12/10/8) ✓ · Cross-Portal ausgeschlossen ✓ \ No newline at end of file diff --git a/resources/views/livewire/customer/press-releases/show.blade.php b/resources/views/livewire/customer/press-releases/show.blade.php index bc3570a..bb1b330 100644 --- a/resources/views/livewire/customer/press-releases/show.blade.php +++ b/resources/views/livewire/customer/press-releases/show.blade.php @@ -99,8 +99,13 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung')] class extends $cover = app(PressReleaseCoverImage::class); $user = auth()->user(); + $company = $pr->company?->loadCount(['pressReleases', 'contacts']); + return [ 'pr' => $pr, + 'companyLogoUrl' => $company?->logoUrl(), + 'companyInitials' => $this->companyInitials($company?->name), + 'companyMetaLine' => $this->companyMetaLine($company), 'categoryName' => $categoryName, 'coverUrl' => $cover->coverUrl($pr, 'cover'), 'coverIsPlaceholder' => $cover->coverIsPlaceholder($pr), @@ -122,12 +127,59 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung')] class extends ]; } + /** + * Initialen für die Logo-Kachel (analog zur Firmenübersicht). + */ + private function companyInitials(?string $name): string + { + $name = trim((string) $name); + + if ($name === '') { + return '–'; + } + + $letters = collect(preg_split('/\s+/u', $name) ?: []) + ->map(fn (string $word): string => mb_substr($word, 0, 1)) + ->filter() + ->take(2) + ->implode(''); + + return mb_strtoupper($letters ?: mb_substr($name, 0, 2)); + } + + /** + * Kompakte Meta-Zeile: Ort (letzte Adresszeile) · Firmentyp. + */ + private function companyMetaLine(?\App\Models\Company $company): string + { + if (! $company) { + return ''; + } + + $parts = []; + + $lastAddressLine = collect(preg_split('/\r?\n/', trim((string) $company->address)) ?: []) + ->map(fn ($line) => trim((string) $line)) + ->filter() + ->last(); + + if (is_string($lastAddressLine) && $lastAddressLine !== '') { + $parts[] = $lastAddressLine; + } + + if ($company->type?->label()) { + $parts[] = $company->type->label(); + } + + return implode(' · ', $parts); + } + private function getMyPR(): PressRelease { return PressRelease::withoutGlobalScopes() ->where('user_id', auth()->id()) ->with([ - 'company:id,name,email,phone', + 'company:id,name,email,phone,address,portal,logo_path,legacy_portal,is_active,type', 'category.translations', 'contacts' => fn ($query) => $query ->withoutGlobalScopes() @@ -314,16 +366,30 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung')] class extends {{ __('Firma & Pressekontakt') }}
- {{-- Firma der Pressemitteilung --}} + {{-- Firma der Pressemitteilung — gleiche Kachel wie in der Firmenübersicht --}} @if ($pr->company) -
-
- +
+
+ + @if ($pr->company->is_active) + {{ __('Aktiv') }} + @else + {{ __('Inaktiv') }} + @endif
-
-
{{ $pr->company->name }}
-
+ +
+

{{ $pr->company->name }}

+ @if (filled($companyMetaLine)) +
{{ $companyMetaLine }}
+ @endif +
@if ($pr->company->email) {{ $pr->company->email }} @endif @@ -332,9 +398,35 @@ new #[Layout('components.layouts.app'), Title('Pressemitteilung')] class extends @endif
- - {{ __('Firma öffnen') }} - + +
+ @if ($pr->company->portal === \App\Enums\Portal::Both) + presseecho + businessportal24 + @elseif ($pr->company->portal === \App\Enums\Portal::Presseecho) + presseecho + @elseif ($pr->company->portal === \App\Enums\Portal::Businessportal24) + businessportal24 + @endif +
+ +
+
+ {{ number_format($pr->company->press_releases_count ?? 0, 0, ',', '.') }} + {{ __('PMs') }} +
+
+ {{ number_format($pr->company->contacts_count ?? 0, 0, ',', '.') }} + {{ __('Kontakte') }} +
+
+ +
@endif