Das Abschalten des Aufgaben-Modus wird nun sauber in der App reflektiert- die UI passt sich an und der Admin erhält einen Hinweis, dass die Aufgabenverwaltung nicht verfügbar ist

This commit is contained in:
Codex Agent
2025-12-17 13:20:48 +01:00
parent 03e37d7e23
commit efe697f155
15 changed files with 297 additions and 62 deletions

View File

@@ -659,6 +659,25 @@ class EventPublicController extends BaseController
return $trimmed;
}
/**
* @return array<string, mixed>
*/
private function normalizeSettings(array|string|null $settings): array
{
if (is_array($settings)) {
return $settings;
}
if (is_string($settings)) {
$decoded = json_decode($settings, true);
if (is_array($decoded)) {
return $decoded;
}
}
return [];
}
private function buildDeterministicSeed(?string $identifier): int
{
if ($identifier === null || trim($identifier) === '') {
@@ -1757,6 +1776,8 @@ class EventPublicController extends BaseController
];
$branding = $this->buildGalleryBranding($event);
$settings = $this->normalizeSettings($event->settings ?? []);
$engagementMode = $settings['engagement_mode'] ?? 'tasks';
if ($joinToken) {
$this->joinTokenService->incrementUsage($joinToken);
@@ -1774,6 +1795,7 @@ class EventPublicController extends BaseController
'photobooth_enabled' => (bool) $event->photobooth_enabled,
'branding' => $branding,
'guest_upload_visibility' => Arr::get($event->settings ?? [], 'guest_upload_visibility', 'review'),
'engagement_mode' => $engagementMode,
])->header('Cache-Control', 'no-store');
}
@@ -2365,7 +2387,7 @@ class EventPublicController extends BaseController
public function stats(Request $request, string $token)
{
$result = $this->resolvePublishedEvent($request, $token, ['id']);
$result = $this->resolvePublishedEvent($request, $token, ['id', 'settings']);
if ($result instanceof JsonResponse) {
return $result;
@@ -2374,6 +2396,8 @@ class EventPublicController extends BaseController
[$event, $joinToken] = $result;
$eventId = $event->id;
$eventModel = Event::with('storageAssignments.storageTarget')->findOrFail($eventId);
$settings = $this->normalizeSettings($event->settings ?? null);
$engagementMode = $settings['engagement_mode'] ?? 'tasks';
// Approximate online guests as distinct recent uploaders in last 10 minutes.
$tenMinutesAgo = CarbonImmutable::now()->subMinutes(10);
@@ -2384,7 +2408,9 @@ class EventPublicController extends BaseController
->count('guest_name');
// Tasks solved as number of photos linked to a task (proxy metric).
$tasksSolved = DB::table('photos')->where('event_id', $eventId)->whereNotNull('task_id')->count();
$tasksSolved = $engagementMode === 'photo_only'
? 0
: DB::table('photos')->where('event_id', $eventId)->whereNotNull('task_id')->count();
$latestPhotoAt = DB::table('photos')->where('event_id', $eventId)->max('created_at');
@@ -2392,6 +2418,7 @@ class EventPublicController extends BaseController
'online_guests' => $onlineGuests,
'tasks_solved' => $tasksSolved,
'latest_photo_at' => $latestPhotoAt,
'engagement_mode' => $engagementMode,
];
$etag = sha1(json_encode($payload));
@@ -2472,7 +2499,7 @@ class EventPublicController extends BaseController
public function tasks(Request $request, string $token)
{
$result = $this->resolvePublishedEvent($request, $token, ['id', 'default_locale']);
$result = $this->resolvePublishedEvent($request, $token, ['id', 'default_locale', 'settings']);
if ($result instanceof JsonResponse) {
return $result;
@@ -2480,8 +2507,35 @@ class EventPublicController extends BaseController
[$event, $joinToken] = $result;
$settings = $this->normalizeSettings($event->settings ?? null);
$engagementMode = $settings['engagement_mode'] ?? 'tasks';
[$resolvedLocale] = $this->resolveGuestLocale($request, $event);
$page = max(1, (int) $request->query('page', 1));
$perPage = max(1, min(100, (int) $request->query('per_page', 20)));
if ($engagementMode === 'photo_only') {
$payload = [
'data' => [],
'meta' => [
'total' => 0,
'per_page' => $perPage,
'current_page' => $page,
'last_page' => 1,
'has_more' => false,
'seed' => null,
],
'engagement_mode' => $engagementMode,
];
return response()->json($payload)
->header('Cache-Control', 'public, max-age=120')
->header('Vary', 'Accept-Language, X-Locale')
->header('X-Content-Locale', $resolvedLocale)
->header('X-Engagement-Mode', $engagementMode);
}
$cached = $this->eventTasksCache->remember((int) $event->id, $resolvedLocale, function () use ($event, $resolvedLocale) {
return $this->buildLocalizedTasksPayload((int) $event->id, $resolvedLocale, $event->default_locale ?? null);
});
@@ -2489,9 +2543,6 @@ class EventPublicController extends BaseController
$tasks = $cached['tasks'];
$baseHash = $cached['hash'] ?? sha1(json_encode($tasks));
$page = max(1, (int) $request->query('page', 1));
$perPage = max(1, min(100, (int) $request->query('per_page', 20)));
// Shuffle per request for unpredictability; stable when seeded by guest/device or explicit seed.
$seedParam = $request->query('seed');
$guestIdentifier = $this->determineGuestIdentifier($request);