Fotospiel GmbH entfernt, Jon Token des demo events gefixt + demoeventseeder. Favicon auf ".ico" gesetzt.

This commit is contained in:
Codex Agent
2025-11-16 16:24:30 +01:00
parent 4f78546ba3
commit 5290072ffe
23 changed files with 505 additions and 262 deletions

View File

@@ -298,8 +298,8 @@ class EventPublicController extends BaseController
return ApiError::response(
'token_rate_limited',
'Too Many Attempts',
'Too many invalid join token attempts. Try again later.',
$this->tokenErrorTitle('token_rate_limited'),
__('api.join_tokens.invalid_attempts_message'),
Response::HTTP_TOO_MANY_REQUESTS,
array_merge($context, ['rate_limiter_key' => $rateLimiterKey])
);
@@ -333,21 +333,22 @@ class EventPublicController extends BaseController
private function tokenErrorMessage(string $code): string
{
return match ($code) {
'invalid_token' => 'The provided join token is invalid.',
'token_expired' => 'The join token has expired.',
'token_revoked' => 'The join token has been revoked.',
default => 'Access denied.',
'invalid_token' => __('api.join_tokens.invalid_message'),
'token_expired' => __('api.join_tokens.expired_message'),
'token_revoked' => __('api.join_tokens.revoked_message'),
'token_rate_limited' => __('api.join_tokens.rate_limited_message'),
default => __('api.join_tokens.default_message'),
};
}
private function tokenErrorTitle(string $code): string
{
return match ($code) {
'invalid_token' => 'Invalid Join Token',
'token_expired' => 'Join Token Expired',
'token_revoked' => 'Join Token Revoked',
'token_rate_limited' => 'Join Token Rate Limited',
default => 'Access Denied',
'invalid_token' => __('api.join_tokens.invalid_title'),
'token_expired' => __('api.join_tokens.expired_title'),
'token_revoked' => __('api.join_tokens.revoked_title'),
'token_rate_limited' => __('api.join_tokens.rate_limited_title'),
default => __('api.join_tokens.default_title'),
};
}

View File

@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
use App\Mail\ContactConfirmation;
use App\Models\BlogPost;
use App\Models\Event;
use App\Models\CheckoutSession;
use App\Models\Package;
use App\Models\PackagePurchase;
@@ -14,6 +15,7 @@ use App\Services\Paddle\PaddleCheckoutService;
use App\Support\Concerns\PresentsPackages;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
@@ -258,9 +260,9 @@ class MarketingController extends Controller
return null;
}
public function blogIndex(Request $request)
public function blogIndex(Request $request, string $locale)
{
$locale = $request->get('locale', app()->getLocale());
$locale = $locale ?: app()->getLocale();
Log::info('Blog Index Debug - Initial', [
'locale' => $locale,
'full_url' => $request->fullUrl(),
@@ -288,31 +290,32 @@ class MarketingController extends Controller
Log::info('Blog Index Debug - With Translation', ['count' => $totalWithTranslation, 'locale' => $locale]);
$posts = $query->orderBy('published_at', 'desc')
->paginate(8);
// Transform posts to include translated strings for the current locale
$posts->getCollection()->transform(function ($post) use ($locale) {
$post->title = $post->getTranslation('title', $locale) ?? $post->getTranslation('title', 'de') ?? '';
$post->excerpt = $post->getTranslation('excerpt', $locale) ?? $post->getTranslation('excerpt', 'de') ?? '';
$post->content = $post->getTranslation('content', $locale) ?? $post->getTranslation('content', 'de') ?? '';
// Author name is a string, no translation needed; author is loaded via with('author')
return $post;
});
->paginate(4)
->through(function (BlogPost $post) use ($locale) {
return [
'id' => $post->id,
'slug' => $post->slug,
'title' => $post->getTranslation('title', $locale) ?? $post->getTranslation('title', 'de') ?? '',
'excerpt' => $post->getTranslation('excerpt', $locale) ?? $post->getTranslation('excerpt', 'de') ?? '',
'featured_image' => $post->featured_image ?? $post->banner_url ?? null,
'published_at' => optional($post->published_at)->toDateString(),
'author' => $post->author ? ['name' => $post->author->name] : null,
];
});
Log::info('Blog Index Debug - Final Posts', [
'count' => $posts->count(),
'total' => $posts->total(),
'posts_data' => $posts->toArray(),
'first_post_title' => $posts->count() > 0 ? $posts->first()->title : 'No posts',
'first_post_title' => $posts->count() > 0 ? ($posts->first()['title'] ?? 'No title') : 'No posts',
]);
return Inertia::render('marketing/Blog', compact('posts'));
}
public function blogShow($slug)
public function blogShow(string $locale, string $slug)
{
$locale = app()->getLocale();
$locale = $locale ?: app()->getLocale();
$postModel = BlogPost::query()
->with('author')
->whereHas('category', function ($query) {
@@ -362,7 +365,33 @@ class MarketingController extends Controller
public function demo()
{
return Inertia::render('marketing/Demo');
$joinToken = optional(Event::firstWhere('slug', 'demo-wedding-2025'))
?->joinTokens()
->latest('id')
->first();
$demoToken = null;
if ($joinToken) {
if (! empty($joinToken->token_encrypted)) {
try {
$demoToken = Crypt::decryptString($joinToken->token_encrypted);
} catch (\Throwable $exception) {
Log::warning('Failed to decrypt demo join token', [
'token_id' => $joinToken->id,
'exception' => $exception->getMessage(),
]);
}
}
if (! $demoToken) {
$demoToken = $joinToken->metadata['plain_token'] ?? null;
}
}
return Inertia::render('marketing/Demo', [
'demoToken' => $demoToken,
]);
}
public function packagesIndex()