added watermark settings tab on the branding page and added more package details to the billing page, added a new guest notifications page

This commit is contained in:
Codex Agent
2025-12-17 16:39:25 +01:00
parent efe697f155
commit 5f3e7ae8c8
25 changed files with 2062 additions and 202 deletions

View File

@@ -21,6 +21,7 @@ use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpException;
@@ -140,6 +141,7 @@ class EventController extends Controller
}
$settings['branding_allowed'] = $package->branding_allowed !== false;
$settings['watermark_allowed'] = $package->watermark_allowed !== false;
$eventData['settings'] = $settings;
@@ -258,7 +260,9 @@ class EventController extends Controller
unset($validated[$unused]);
}
$brandingAllowed = optional($event->eventPackage?->package)->branding_allowed !== false;
$package = $event->eventPackage?->package;
$brandingAllowed = optional($package)->branding_allowed !== false;
$watermarkAllowed = optional($package)->watermark_allowed !== false;
if (isset($validated['settings']) && is_array($validated['settings'])) {
$validated['settings'] = array_merge($event->settings ?? [], $validated['settings']);
@@ -267,6 +271,92 @@ class EventController extends Controller
}
$validated['settings']['branding_allowed'] = $brandingAllowed;
$validated['settings']['watermark_allowed'] = $watermarkAllowed;
$settings = $validated['settings'];
$watermark = Arr::get($settings, 'watermark', []);
$existingWatermark = is_array($watermark) ? $watermark : [];
if (is_array($watermark)) {
$mode = $watermark['mode'] ?? 'base';
$policy = $watermarkAllowed ? 'basic' : 'none';
if (! $watermarkAllowed) {
$mode = 'off';
} elseif (! $brandingAllowed) {
$mode = 'base';
} elseif ($mode === 'off' && $policy === 'basic') {
$mode = 'base';
}
$assetPath = $watermark['asset'] ?? null;
$assetDataUrl = $watermark['asset_data_url'] ?? null;
if (! $watermarkAllowed) {
$assetPath = null;
}
if ($assetDataUrl && $mode === 'custom' && $brandingAllowed) {
if (! preg_match('/^data:image\\/(png|webp|jpe?g);base64,(.+)$/i', $assetDataUrl, $matches)) {
throw ValidationException::withMessages([
'settings.watermark.asset_data_url' => __('Ungültiges Wasserzeichen-Bild.'),
]);
}
$decoded = base64_decode($matches[2], true);
if ($decoded === false) {
throw ValidationException::withMessages([
'settings.watermark.asset_data_url' => __('Wasserzeichen konnte nicht gelesen werden.'),
]);
}
if (strlen($decoded) > 3 * 1024 * 1024) { // 3 MB
throw ValidationException::withMessages([
'settings.watermark.asset_data_url' => __('Wasserzeichen ist zu groß (max. 3 MB).'),
]);
}
$extension = str_starts_with(strtolower($matches[1]), 'jp') ? 'jpg' : strtolower($matches[1]);
$path = sprintf('branding/watermarks/event-%s.%s', $event->id, $extension);
Storage::disk('public')->put($path, $decoded);
$assetPath = $path;
}
$position = $watermark['position'] ?? 'bottom-right';
$validPositions = [
'top-left',
'top-center',
'top-right',
'middle-left',
'center',
'middle-right',
'bottom-left',
'bottom-center',
'bottom-right',
];
if (! in_array($position, $validPositions, true)) {
$position = 'bottom-right';
}
$settings['watermark'] = [
'mode' => $mode,
'asset' => $assetPath,
'position' => $position,
'opacity' => isset($watermark['opacity']) ? (float) $watermark['opacity'] : ($existingWatermark['opacity'] ?? null),
'scale' => isset($watermark['scale']) ? (float) $watermark['scale'] : ($existingWatermark['scale'] ?? null),
'padding' => isset($watermark['padding']) ? (int) $watermark['padding'] : ($existingWatermark['padding'] ?? null),
'offset_x' => isset($watermark['offset_x']) ? (int) $watermark['offset_x'] : ($existingWatermark['offset_x'] ?? 0),
'offset_y' => isset($watermark['offset_y']) ? (int) $watermark['offset_y'] : ($existingWatermark['offset_y'] ?? 0),
];
}
if (array_key_exists('watermark_serve_originals', $settings)) {
$settings['watermark_serve_originals'] = (bool) $settings['watermark_serve_originals'];
}
$validated['settings'] = $settings;
$event->update($validated);
$event->load(['eventType', 'tenant']);

View File

@@ -30,8 +30,16 @@ class TenantPackageController extends Controller
->get();
$packages->each(function ($package) {
$package->remaining_events = $package->package->max_events_per_year - $package->used_events;
$package->package_limits = $package->package->getAttributes(); // Or custom accessor for limits
$pkg = $package->package;
$package->remaining_events = $pkg->max_events_per_year - $package->used_events;
$package->package_limits = array_merge(
$pkg->limits,
[
'branding_allowed' => $pkg->branding_allowed,
'watermark_allowed' => $pkg->watermark_allowed,
'features' => $pkg->features,
]
);
});
return response()->json([