feat: add webshop offline maintenance mode with admin toggle and red maintenance screen
This commit is contained in:
@@ -107,6 +107,16 @@
|
||||
<i data-lucide="mail" class="w-3.5 h-3.5"></i>
|
||||
<span>7. E-mail & SMTP Testen</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
@click="activeTab = 'offline'"
|
||||
:class="activeTab === 'offline' ? 'bg-rose-600 text-white shadow-sm font-black' : 'bg-slate-800 text-slate-300 hover:bg-slate-700'"
|
||||
class="px-4 py-2.5 rounded-xl transition flex items-center space-x-1.5 whitespace-nowrap cursor-pointer"
|
||||
>
|
||||
<span class="w-2 h-2 rounded-full {{ setting('shop_offline', '0') === '1' ? 'bg-rose-400 animate-ping' : 'bg-emerald-400' }}"></span>
|
||||
<span>8. Offline Modus</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- ==================================================== -->
|
||||
@@ -631,6 +641,95 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================================================== -->
|
||||
<!-- TAB 8: WEBSHOP OFFLINE MODUS (ONDERHOUDSMODUS) -->
|
||||
<!-- ==================================================== -->
|
||||
<div x-show="activeTab === 'offline'" class="space-y-6">
|
||||
<div class="p-6 rounded-3xl bg-slate-900 border border-slate-800 space-y-6">
|
||||
|
||||
<div class="flex flex-col sm:flex-row sm:items-center justify-between pb-4 border-b border-slate-800 gap-3">
|
||||
<div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="w-2.5 h-2.5 rounded-full {{ setting('shop_offline', '0') === '1' ? 'bg-rose-500 animate-ping' : 'bg-emerald-400' }}"></span>
|
||||
<h3 class="font-heading font-black text-lg text-white">Webshop Offline Modus (Onderhoud)</h3>
|
||||
</div>
|
||||
<p class="text-xs text-slate-400 mt-0.5">
|
||||
Wanneer ingeschakeld, kunnen gewone bezoekers niets bestellen en zien zij direct de grote rode offline banner. Alleen ingelogde beheerders kunnen de website bekijken.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Directe 1-klik Toggle Knop -->
|
||||
<button
|
||||
type="submit"
|
||||
formaction="{{ route('admin.toggle-offline') }}"
|
||||
formmethod="POST"
|
||||
class="px-5 py-2.5 rounded-xl {{ setting('shop_offline', '0') === '1' ? 'bg-emerald-500 hover:bg-emerald-400 text-slate-950' : 'bg-rose-600 hover:bg-rose-500 text-white' }} font-black text-xs uppercase tracking-wider transition flex items-center justify-center space-x-2 shrink-0 cursor-pointer shadow-lg"
|
||||
>
|
||||
<i data-lucide="power" class="w-4 h-4"></i>
|
||||
<span>{{ setting('shop_offline', '0') === '1' ? 'Zet Webshop Weer ONLINE' : 'Zet Webshop Nu DIRECT OFFLINE' }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="shop_offline_submitted" value="1">
|
||||
|
||||
<!-- Toggle Switch -->
|
||||
<div class="p-4 rounded-2xl {{ setting('shop_offline', '0') === '1' ? 'bg-rose-950/40 border-2 border-rose-500/50' : 'bg-slate-950 border border-slate-800' }} flex items-center justify-between">
|
||||
<div>
|
||||
<span class="text-xs font-black text-white block">Status Webshop Bereikbaarheid</span>
|
||||
<span class="text-[11px] text-slate-400">
|
||||
{{ setting('shop_offline', '0') === '1' ? 'De webshop is momenteel OFFLINE voor gewone bezoekers.' : 'De webshop is momenteel LIVE en open voor bestellingen.' }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<label class="relative inline-flex items-center cursor-pointer">
|
||||
<input type="checkbox" name="shop_offline" value="1" {{ setting('shop_offline', '0') === '1' ? 'checked' : '' }} class="sr-only peer">
|
||||
<div class="w-14 h-7 bg-slate-800 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[4px] after:bg-white after:border-slate-300 after:border after:rounded-full after:h-6 after:w-6 after:transition-all peer-checked:bg-rose-600"></div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- Teksten van de Rode Offline Banner -->
|
||||
<div class="grid grid-cols-1 gap-4 pt-2">
|
||||
<div class="space-y-1.5">
|
||||
<label class="block text-xs font-bold text-slate-300">Titel op de Rode Offline Banner</label>
|
||||
<input
|
||||
type="text"
|
||||
name="shop_offline_title"
|
||||
value="{{ setting('shop_offline_title', 'Aan deze webshop wordt hard gewerkt! 🛠️') }}"
|
||||
class="w-full bg-slate-950 border border-slate-700 rounded-xl px-3.5 py-2.5 text-xs text-white font-bold focus:outline-none focus:ring-2 focus:ring-rose-400"
|
||||
>
|
||||
<p class="text-[10px] text-slate-500">De grote rode hoofdtitel die bezoekers in beeld krijgen.</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1.5">
|
||||
<label class="block text-xs font-bold text-slate-300">Toelichting / Onderhoudsbericht</label>
|
||||
<textarea
|
||||
name="shop_offline_message"
|
||||
rows="3"
|
||||
class="w-full bg-slate-950 border border-slate-700 rounded-xl px-3.5 py-2.5 text-xs text-white leading-relaxed focus:outline-none focus:ring-2 focus:ring-rose-400"
|
||||
>{{ setting('shop_offline_message', 'Onze 3D printers worden momenteel opnieuw gekalibreerd en we bouwen aan nieuwe toffe prints en functies. We zijn heel snel weer online voor bestellingen!') }}</textarea>
|
||||
<p class="text-[10px] text-slate-500">Uitleg over waarom de webshop tijdelijk offline staat en wanneer klanten terug kunnen komen.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Preview Box van de Offline Banner -->
|
||||
<div class="pt-4 border-t border-slate-800 space-y-2">
|
||||
<span class="text-xs font-black uppercase tracking-wider text-slate-400 block">Voorvertoning van de Offline Banner:</span>
|
||||
<div class="rounded-2xl bg-gradient-to-b from-rose-950/80 to-slate-950 border-2 border-rose-500/60 p-6 text-center space-y-3">
|
||||
<span class="inline-block px-3 py-1 rounded-full bg-rose-600 text-white font-black text-[10px] uppercase tracking-wider">
|
||||
🔴 Webshop Tijdelijk Offline
|
||||
</span>
|
||||
<h4 class="font-heading text-xl font-black text-white">
|
||||
{{ setting('shop_offline_title', 'Aan deze webshop wordt hard gewerkt! 🛠️') }}
|
||||
</h4>
|
||||
<p class="text-xs text-slate-300 max-w-lg mx-auto">
|
||||
{{ setting('shop_offline_message', 'Onze 3D printers worden momenteel opnieuw gekalibreerd en we bouwen aan nieuwe toffe prints en functies. We zijn heel snel weer online voor bestellingen!') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sticky Save Action Bar -->
|
||||
<div class="sticky bottom-4 z-20 p-4 rounded-2xl bg-slate-900/95 backdrop-blur-md border border-amber-400/30 shadow-2xl flex items-center justify-between">
|
||||
<div class="flex items-center space-x-2 text-xs text-slate-300 font-bold">
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="nl" class="h-full bg-slate-950 text-slate-100 antialiased">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Aan deze webshop wordt hard gewerkt! 🛠️ | Jouwdriedee.nl</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/images/logo-icon.svg">
|
||||
|
||||
<!-- Google Fonts: Fredoka & Nunito -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@500;600;700;800&family=Nunito:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
||||
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
|
||||
<style>
|
||||
body { font-family: 'Nunito', system-ui, sans-serif; }
|
||||
h1, h2, h3, h4, .font-heading { font-family: 'Fredoka', ui-rounded, 'Nunito', sans-serif; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="min-h-full flex flex-col justify-between bg-gradient-to-b from-rose-950 via-slate-950 to-slate-950 text-slate-100 p-4 sm:p-6 lg:p-8 selection:bg-rose-500 selection:text-white">
|
||||
|
||||
<!-- Top Logo Bar -->
|
||||
<div class="max-w-4xl mx-auto w-full flex items-center justify-between py-2">
|
||||
<div class="flex items-center space-x-3">
|
||||
<img src="/images/logo.svg" alt="Jouwdriedee.nl" class="h-9 sm:h-11 w-auto brightness-200 invert">
|
||||
</div>
|
||||
<div class="inline-flex items-center space-x-2 px-3 py-1 rounded-full bg-rose-600/30 border border-rose-500/40 text-rose-300 text-xs font-bold">
|
||||
<span class="w-2 h-2 rounded-full bg-rose-500 animate-ping"></span>
|
||||
<span>Onderhoudsmodus</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Large Red Offline Banner / Card -->
|
||||
<main class="max-w-3xl mx-auto w-full my-auto py-8">
|
||||
<div class="rounded-3xl bg-slate-900/90 border-2 border-rose-500/80 shadow-2xl shadow-rose-900/50 p-6 sm:p-10 text-center relative overflow-hidden backdrop-blur-xl">
|
||||
|
||||
<!-- Glow effect behind content -->
|
||||
<div class="absolute -top-24 -left-24 w-72 h-72 bg-rose-600/20 rounded-full blur-3xl pointer-events-none"></div>
|
||||
<div class="absolute -bottom-24 -right-24 w-72 h-72 bg-amber-500/10 rounded-full blur-3xl pointer-events-none"></div>
|
||||
|
||||
<!-- Pulsing Alert Badge -->
|
||||
<div class="inline-flex items-center space-x-2 px-4 py-1.5 rounded-full bg-rose-600 text-white font-black text-xs uppercase tracking-wider shadow-lg shadow-rose-600/40 mb-6">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-white animate-pulse"></span>
|
||||
<span>Webshop Tijdelijk Offline</span>
|
||||
</div>
|
||||
|
||||
<!-- Animated 3D Printer Icon Illustration -->
|
||||
<div class="w-20 h-20 sm:w-24 sm:h-24 rounded-3xl bg-rose-500/20 border border-rose-500/40 text-rose-400 mx-auto flex items-center justify-center text-4xl sm:text-5xl mb-6 shadow-inner animate-bounce" style="animation-duration: 3s;">
|
||||
🖨️
|
||||
</div>
|
||||
|
||||
<!-- Big Main Headline -->
|
||||
<h1 class="font-heading text-2xl sm:text-4xl md:text-5xl font-black text-white tracking-tight leading-tight mb-4">
|
||||
{{ $offlineTitle ?? 'Aan deze webshop wordt hard gewerkt!' }}
|
||||
</h1>
|
||||
|
||||
<!-- Explanatory message -->
|
||||
<p class="text-slate-300 text-sm sm:text-base max-w-xl mx-auto leading-relaxed font-medium mb-8">
|
||||
{{ $offlineMessage ?? 'Onze 3D printers worden momenteel opnieuw gekalibreerd en we bouwen aan nieuwe toffe prints en functies. We zijn heel snel weer online voor bestellingen!' }}
|
||||
</p>
|
||||
|
||||
<!-- 3 Info Columns -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3 text-left pt-6 border-t border-slate-800">
|
||||
<div class="p-4 rounded-2xl bg-slate-950/60 border border-slate-800/80">
|
||||
<div class="text-xl mb-1">🛠️</div>
|
||||
<h3 class="text-xs font-black text-white uppercase tracking-wider mb-1">Printstudio Update</h3>
|
||||
<p class="text-[11px] text-slate-400 leading-normal">Finetunen van laagdiktes en toevoegen van nieuwe multi-color designs.</p>
|
||||
</div>
|
||||
|
||||
<div class="p-4 rounded-2xl bg-slate-950/60 border border-slate-800/80">
|
||||
<div class="text-xl mb-1">📦</div>
|
||||
<h3 class="text-xs font-black text-white uppercase tracking-wider mb-1">Lopende Orders</h3>
|
||||
<p class="text-[11px] text-slate-400 leading-normal">Reeds geplaatste bestellingen worden gewoon geprint en verzonden via PostNL.</p>
|
||||
</div>
|
||||
|
||||
<div class="p-4 rounded-2xl bg-slate-950/60 border border-slate-800/80">
|
||||
<div class="text-xl mb-1">✉️</div>
|
||||
<h3 class="text-xs font-black text-white uppercase tracking-wider mb-1">Vragen of Contact?</h3>
|
||||
<p class="text-[11px] text-slate-400 leading-normal">
|
||||
Bereikbaar via <a href="mailto:info@jouwdriedee.nl" class="text-rose-400 font-bold hover:underline">info@jouwdriedee.nl</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Footer with Admin Login Shortcut -->
|
||||
<footer class="max-w-4xl mx-auto w-full py-4 text-center text-xs text-slate-500 flex flex-col sm:flex-row items-center justify-between gap-2 border-t border-slate-900">
|
||||
<div>
|
||||
© {{ date('Y') }} Jouwdriedee.nl • Tot snel!
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a href="{{ route('login') }}" class="text-slate-500 hover:text-slate-300 transition text-[11px] font-bold flex items-center space-x-1">
|
||||
<span>Beheerder inloggen</span>
|
||||
<span>→</span>
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -76,6 +76,27 @@
|
||||
|
||||
<!-- Right Actions -->
|
||||
<div class="flex items-center space-x-3">
|
||||
@php
|
||||
$isShopOffline = \App\Models\Setting::get('shop_offline', '0') === '1';
|
||||
@endphp
|
||||
|
||||
<!-- Webshop Offline / Online Status Switcher -->
|
||||
<form action="{{ route('admin.toggle-offline') }}" method="POST" class="inline">
|
||||
@csrf
|
||||
@if($isShopOffline)
|
||||
<button type="submit" class="px-3 py-1.5 rounded-xl bg-rose-600 hover:bg-rose-500 text-white text-xs font-black transition flex items-center space-x-1.5 shadow-lg shadow-rose-600/30 animate-pulse cursor-pointer" title="Klik om de webshop weer direct online te zetten">
|
||||
<span class="w-2 h-2 rounded-full bg-white"></span>
|
||||
<span>Webshop: OFFLINE</span>
|
||||
</button>
|
||||
@else
|
||||
<button type="submit" class="px-2.5 sm:px-3 py-1.5 rounded-xl bg-slate-800 hover:bg-rose-950/40 text-slate-300 hover:text-rose-400 text-xs font-bold transition flex items-center space-x-1.5 border border-slate-700 cursor-pointer" title="Klik om de webshop direct offline te zetten voor bezoekers">
|
||||
<span class="w-2 h-2 rounded-full bg-emerald-400"></span>
|
||||
<span class="hidden sm:inline">Webshop: Online</span>
|
||||
<span class="text-[10px] text-slate-500 hover:text-rose-300">(Zet Offline)</span>
|
||||
</button>
|
||||
@endif
|
||||
</form>
|
||||
|
||||
<a href="{{ route('home') }}" target="_blank" class="px-3 py-1.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-slate-200 text-xs font-bold transition flex items-center space-x-1.5 border border-slate-700">
|
||||
<span>Naar Webshop</span>
|
||||
<i data-lucide="external-link" class="w-3.5 h-3.5"></i>
|
||||
@@ -118,6 +139,24 @@
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Prominent Offline Alert Banner -->
|
||||
@if($isShopOffline ?? (\App\Models\Setting::get('shop_offline', '0') === '1'))
|
||||
<div class="bg-gradient-to-r from-rose-700 via-rose-600 to-rose-700 text-white px-4 py-3 text-xs font-bold border-b-2 border-rose-800 shadow-xl flex flex-col sm:flex-row items-center justify-between gap-3 sticky top-16 z-20">
|
||||
<div class="flex items-center space-x-2.5">
|
||||
<span class="w-3 h-3 rounded-full bg-white animate-ping shrink-0"></span>
|
||||
<span class="px-2 py-0.5 rounded-md bg-white text-rose-800 font-black text-[10px] uppercase tracking-wider shrink-0">Offline Actief</span>
|
||||
<span>De webshop staat momenteel <strong>OFFLINE</strong> voor bezoekers. Bezoekers zien de grote rode onderhoudsbanner. Alleen jij als beheerder kunt de website bezoeken.</span>
|
||||
</div>
|
||||
<form action="{{ route('admin.toggle-offline') }}" method="POST" class="shrink-0">
|
||||
@csrf
|
||||
<button type="submit" class="px-4 py-1.5 bg-white hover:bg-slate-100 text-rose-700 font-black rounded-xl text-xs transition shadow-md cursor-pointer flex items-center space-x-1.5">
|
||||
<span class="w-2 h-2 rounded-full bg-emerald-500"></span>
|
||||
<span>Zet Webshop Nu Weer Online →</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Main Admin Container -->
|
||||
<main class="flex-1 max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-6 sm:py-8">
|
||||
|
||||
|
||||
@@ -25,6 +25,27 @@
|
||||
</head>
|
||||
<body class="min-h-full flex flex-col bg-[#FBFBFA] text-slate-800 selection:bg-amber-300 selection:text-slate-900" x-data="{ mobileMenuOpen: false }">
|
||||
|
||||
<!-- Admin Offline Preview Notice -->
|
||||
@if(\App\Models\Setting::get('shop_offline', '0') === '1' && auth()->check() && auth()->user()->isAdmin())
|
||||
<div class="bg-rose-600 text-white px-4 py-2 text-xs font-black flex flex-col sm:flex-row items-center justify-between sticky top-0 z-50 border-b border-rose-700 shadow-lg gap-2">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-white animate-pulse"></span>
|
||||
<span>⚠️ OFFLINE BEHEERDERS-PREVIEW: De webshop staat momenteel OFFLINE voor gewone bezoekers. Alleen jij als beheerder ziet deze pagina.</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<a href="{{ route('admin.content.index') }}" class="px-2.5 py-1 rounded-lg bg-rose-700 hover:bg-rose-800 text-white text-[11px] font-bold transition">
|
||||
Naar Beheer
|
||||
</a>
|
||||
<form action="{{ route('admin.toggle-offline') }}" method="POST" class="inline">
|
||||
@csrf
|
||||
<button type="submit" class="px-3 py-1 rounded-lg bg-white text-rose-700 hover:bg-rose-50 text-[11px] font-black shadow transition">
|
||||
Zet Nu Weer Online
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Top Announcement Bar (Inschakelbaar en bewerkbaar via Admin) -->
|
||||
@if(setting('announcement_enabled', '1') == '1')
|
||||
<div class="bg-slate-900 text-white text-xs py-2 px-3 sm:px-4 font-bold border-b border-slate-800">
|
||||
|
||||
Reference in New Issue
Block a user