feat: optional fixed viewport background on public pages
Adds background_fixed column, admin checkbox, fixed-position layers on the public layout, Dutch strings, and store tests. Made-with: Cursor
This commit is contained in:
@@ -23,6 +23,7 @@ trait ValidatesPreregistrationPageInput
|
||||
'post_submit_redirect_url' => ['nullable', 'string', 'url:http,https', 'max:500'],
|
||||
'background_overlay_color' => ['nullable', 'string', 'regex:/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/'],
|
||||
'background_overlay_opacity' => ['nullable', 'integer', 'min:0', 'max:100'],
|
||||
'background_fixed' => ['sometimes', 'boolean'],
|
||||
'page_background' => ['nullable', 'file', 'image', 'mimes:jpeg,png,jpg,webp', 'max:5120'],
|
||||
'remove_page_background' => ['sometimes', 'boolean'],
|
||||
'start_date' => ['required', 'date'],
|
||||
@@ -69,6 +70,7 @@ trait ValidatesPreregistrationPageInput
|
||||
|
||||
$this->merge([
|
||||
'is_active' => $this->boolean('is_active'),
|
||||
'background_fixed' => $this->boolean('background_fixed'),
|
||||
'remove_page_background' => $this->boolean('remove_page_background'),
|
||||
'ticketshop_url' => $ticketshopNormalized,
|
||||
'post_submit_redirect_url' => $redirectNormalized,
|
||||
|
||||
@@ -32,6 +32,7 @@ class PreregistrationPage extends Model
|
||||
'background_image',
|
||||
'background_overlay_color',
|
||||
'background_overlay_opacity',
|
||||
'background_fixed',
|
||||
'logo_image',
|
||||
'is_active',
|
||||
];
|
||||
@@ -42,6 +43,7 @@ class PreregistrationPage extends Model
|
||||
'start_date' => 'datetime',
|
||||
'end_date' => 'datetime',
|
||||
'phone_enabled' => 'boolean',
|
||||
'background_fixed' => 'boolean',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('preregistration_pages', function (Blueprint $table): void {
|
||||
$table->boolean('background_fixed')->default(false)->after('background_overlay_opacity');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('preregistration_pages', function (Blueprint $table): void {
|
||||
$table->dropColumn('background_fixed');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -22,5 +22,7 @@
|
||||
"Subscriber removed.": "Abonnee verwijderd.",
|
||||
"Delete this subscriber? This cannot be undone.": "Deze abonnee verwijderen? Dit kan niet ongedaan worden gemaakt.",
|
||||
"Remove": "Verwijderen",
|
||||
"Actions": "Acties"
|
||||
"Actions": "Acties",
|
||||
"Fix background to viewport": "Achtergrond vastzetten op het scherm",
|
||||
"When enabled, the background image and overlay stay fixed while visitors scroll long content.": "Als dit aan staat, blijven de achtergrondafbeelding en de overlay stilstaan terwijl bezoekers door lange inhoud scrollen."
|
||||
}
|
||||
|
||||
@@ -98,6 +98,19 @@
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<label class="inline-flex cursor-pointer items-center gap-2 text-sm text-slate-800">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="background_fixed"
|
||||
value="1"
|
||||
class="rounded border-slate-300 text-indigo-600 focus:ring-indigo-500"
|
||||
@checked(old('background_fixed', $page?->background_fixed ?? false))
|
||||
/>
|
||||
{{ __('Fix background to viewport') }}
|
||||
</label>
|
||||
<p class="mt-1 text-xs text-slate-600">{{ __('When enabled, the background image and overlay stay fixed while visitors scroll long content.') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-6 sm:grid-cols-2">
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
$formButtonLabel = (string) (data_get($formContent, 'button_label') ?: __('public.register_button'));
|
||||
$formButtonColor = (string) data_get($formContent, 'button_color', '#F47B20');
|
||||
$formButtonTextColor = (string) data_get($formContent, 'button_text_color', '#FFFFFF');
|
||||
$bgFixed = $page->background_fixed;
|
||||
$bgLayerPosition = $bgFixed ? 'fixed inset-0 pointer-events-none z-0' : 'absolute inset-0';
|
||||
$overlayPosition = $bgFixed ? 'fixed inset-0 pointer-events-none z-[1]' : 'absolute inset-0';
|
||||
@endphp
|
||||
|
||||
@extends('layouts.public')
|
||||
@@ -28,19 +31,19 @@
|
||||
<div class="relative min-h-screen w-full overflow-x-hidden">
|
||||
@if ($bgUrl !== null)
|
||||
<div
|
||||
class="absolute inset-0 bg-cover bg-center bg-no-repeat"
|
||||
class="{{ $bgLayerPosition }} bg-cover bg-center bg-no-repeat"
|
||||
style="background-image: url('{{ e($bgUrl) }}')"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
@else
|
||||
<div
|
||||
class="absolute inset-0 bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950"
|
||||
class="{{ $bgLayerPosition }} bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
@endif
|
||||
|
||||
<div
|
||||
class="absolute inset-0"
|
||||
class="{{ $overlayPosition }}"
|
||||
style="background-color: {{ e($overlayColor) }}; opacity: {{ $overlayOpacity }}"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
|
||||
@@ -32,9 +32,31 @@ class StorePreregistrationPageTest extends TestCase
|
||||
$page = PreregistrationPage::query()->first();
|
||||
$response->assertRedirect(route('admin.pages.edit', $page));
|
||||
$this->assertSame('Summer Fest', $page?->title);
|
||||
$this->assertFalse($page?->background_fixed);
|
||||
$this->assertGreaterThanOrEqual(4, PageBlock::query()->where('preregistration_page_id', $page?->id)->count());
|
||||
}
|
||||
|
||||
public function test_store_can_enable_fixed_background(): void
|
||||
{
|
||||
$user = User::factory()->create(['role' => 'user']);
|
||||
|
||||
$response = $this->actingAs($user)->post(route('admin.pages.store'), [
|
||||
'title' => 'Winter Fest',
|
||||
'thank_you_message' => null,
|
||||
'expired_message' => null,
|
||||
'ticketshop_url' => null,
|
||||
'start_date' => '2026-06-01T10:00',
|
||||
'end_date' => '2026-06-30T18:00',
|
||||
'is_active' => true,
|
||||
'background_fixed' => true,
|
||||
]);
|
||||
|
||||
$page = PreregistrationPage::query()->where('title', 'Winter Fest')->first();
|
||||
$response->assertRedirect(route('admin.pages.edit', $page));
|
||||
$this->assertNotNull($page);
|
||||
$this->assertTrue($page->background_fixed);
|
||||
}
|
||||
|
||||
public function test_validation_failure_redirects_back_with_input(): void
|
||||
{
|
||||
$user = User::factory()->create(['role' => 'user']);
|
||||
|
||||
Reference in New Issue
Block a user