feat: complete user authentication, admin guard, customer account dashboard and branded HTML emails

This commit is contained in:
2026-11-01 13:55:45 +01:00
parent b6ee6938cb
commit ee89da5e61
37 changed files with 1895 additions and 22 deletions
@@ -0,0 +1,99 @@
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@yield('title', 'Jouwdriedee.nl')</title>
<style>
/* Base styles */
body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; }
img { -ms-interpolation-mode: bicubic; border: 0; outline: none; text-decoration: none; }
body { margin: 0; padding: 0; width: 100% !important; background-color: #F8FAFC; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; }
/* Interactive elements */
.btn-primary {
display: inline-block;
background-color: #FBBF24;
color: #0F172A !important;
font-weight: 800;
font-size: 14px;
padding: 12px 28px;
border-radius: 12px;
text-decoration: none;
text-align: center;
}
.btn-primary:hover {
background-color: #F59E0B;
}
</style>
</head>
<body style="margin: 0; padding: 0; background-color: #F8FAFC; color: #1E293B;">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: #F8FAFC; padding: 30px 10px;">
<tr>
<td align="center">
<!-- Outer Container (Max 600px) -->
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px; background-color: #FFFFFF; border-radius: 20px; overflow: hidden; border: 1px solid #E2E8F0; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);">
<!-- Top Colorful Accent Gradient Bar -->
<tr>
<td height="6" style="background: linear-gradient(90deg, #F43F5E 0%, #F59E0B 50%, #38BDF8 100%);"></td>
</tr>
<!-- Header with Logo -->
<tr>
<td align="center" style="padding: 28px 24px 20px 24px; border-bottom: 1px solid #F1F5F9; background-color: #FFFFFF;">
<a href="{{ config('app.url') }}" target="_blank" style="text-decoration: none; display: inline-block;">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<!-- Isometric 3D Logo Mark representation in SVG/colors -->
<td align="center" valign="middle" style="background: linear-gradient(135deg, #F59E0B 0%, #F43F5E 50%, #6366F1 100%); border-radius: 12px; width: 40px; height: 40px; text-align: center; color: #FFFFFF; font-weight: 900; font-size: 18px; line-height: 40px;">
3D
</td>
<td valign="middle" style="padding-left: 12px; text-align: left;">
<span style="font-size: 22px; font-weight: 900; color: #0F172A; letter-spacing: -0.5px;">Jouw<span style="color: #F43F5E;">driedee</span><span style="background-color: #6366F1; color: #FFFFFF; font-size: 10px; font-weight: 900; padding: 2px 5px; border-radius: 4px; margin-left: 4px; vertical-align: top;">.NL</span></span>
<span style="display: block; font-size: 11px; font-weight: 700; color: #64748B;">Nederlandse 3D Printstudio &amp; Webshop</span>
</td>
</tr>
</table>
</a>
</td>
</tr>
<!-- Main Email Content Slot -->
<tr>
<td style="padding: 32px 32px 28px 32px;">
@yield('content')
</td>
</tr>
<!-- Footer Info & Trust Badges -->
<tr>
<td style="background-color: #0F172A; padding: 28px 32px; color: #94A3B8; text-align: center; font-size: 12px; line-height: 1.6;">
<div style="font-weight: 800; color: #F1F5F9; font-size: 13px; margin-bottom: 6px;">
Jouwdriedee.nl &bull; Hoogwaardige 3D Prints &amp; Collectibles
</div>
<div style="color: #94A3B8; margin-bottom: 14px;">
Geprint met precisie op Bambu Lab printers met 100% veilig Bio-PLA+ en PETG filament.
</div>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="margin-bottom: 16px; border-top: 1px solid #1E293B; padding-top: 14px;">
<tr>
<td align="center" style="color: #F59E0B; font-size: 11px; font-weight: 700;">
&bull; Vragen of speciale wensen? Stuur een e-mail naar <a href="mailto:info@jouwdriedee.nl" style="color: #FBBF24; text-decoration: underline;">info@jouwdriedee.nl</a> &bull;
</td>
</tr>
</table>
<div style="font-size: 11px; color: #64748B;">
&copy; {{ date('Y') }} Jouwdriedee.nl. Alle rechten voorbehouden.
</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
@@ -0,0 +1,104 @@
@extends('emails.layouts.master')
@section('title', 'Bestelbevestiging #' . $order->order_number . ' | Jouwdriedee.nl')
@section('content')
<div style="text-align: left;">
<div style="display: inline-block; background-color: #D1FAE5; color: #065F46; font-size: 11px; font-weight: 800; padding: 4px 10px; border-radius: 999px; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px;">
✓ Bestelling Ontvangen
</div>
<h1 style="color: #0F172A; font-size: 22px; font-weight: 900; margin: 0 0 10px 0; line-height: 1.3;">
Bedankt voor je bestelling, {{ $order->customer_name }}!
</h1>
<p style="color: #475569; font-size: 14px; line-height: 1.6; margin: 0 0 18px 0;">
We hebben je bestelling <strong>#{{ $order->order_number }}</strong> in goede orde ontvangen. Onze 3D-printers worden voorbereid en jouw items worden met zorg en precisie geprint.
</p>
<!-- Bestelde Items Overzicht -->
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="margin: 20px 0; border: 1px solid #E2E8F0; border-radius: 14px; overflow: hidden;">
<tr style="background-color: #F8FAFC; border-bottom: 1px solid #E2E8F0;">
<th align="left" style="padding: 12px 16px; font-size: 11px; font-weight: 800; text-transform: uppercase; color: #64748B;">Item</th>
<th align="center" style="padding: 12px 16px; font-size: 11px; font-weight: 800; text-transform: uppercase; color: #64748B;">Aantal</th>
<th align="right" style="padding: 12px 16px; font-size: 11px; font-weight: 800; text-transform: uppercase; color: #64748B;">Prijs</th>
</tr>
@foreach($order->items as $item)
<tr style="border-bottom: 1px solid #F1F5F9;">
<td style="padding: 14px 16px;">
<div style="font-weight: 800; font-size: 13px; color: #0F172A;">
{{ $item->product_name }}
</div>
<div style="font-size: 11px; color: #64748B; margin-top: 3px;">
@if($item->material) Materiaal: <strong>{{ strtoupper($item->material) }}</strong> &bull; @endif
@if($item->color) Kleur: <strong>{{ $item->color }}</strong> &bull; @endif
Schaal: {{ $item->scale ?? '100%' }}
</div>
</td>
<td align="center" style="padding: 14px 16px; font-size: 13px; font-weight: 700; color: #334155;">
{{ $item->quantity }}x
</td>
<td align="right" style="padding: 14px 16px; font-size: 13px; font-weight: 800; color: #0F172A;">
&euro; {{ number_format($item->total_price, 2, ',', '.') }}
</td>
</tr>
@endforeach
<!-- Subtotaal & Verzending -->
<tr style="background-color: #FAFAFA;">
<td colspan="2" style="padding: 10px 16px; font-size: 12px; color: #64748B;">Subtotaal</td>
<td align="right" style="padding: 10px 16px; font-size: 12px; font-weight: 700; color: #334155;">
&euro; {{ number_format($order->subtotal, 2, ',', '.') }}
</td>
</tr>
<tr style="background-color: #FAFAFA;">
<td colspan="2" style="padding: 10px 16px; font-size: 12px; color: #64748B;">Verzendkosten (PostNL)</td>
<td align="right" style="padding: 10px 16px; font-size: 12px; font-weight: 700; color: #334155;">
{{ $order->shipping_cost > 0 ? '€ ' . number_format($order->shipping_cost, 2, ',', '.') : 'Gratis' }}
</td>
</tr>
<tr style="background-color: #F1F5F9; border-top: 2px solid #E2E8F0;">
<td colspan="2" style="padding: 12px 16px; font-size: 14px; font-weight: 900; color: #0F172A;">Totaal incl. btw</td>
<td align="right" style="padding: 12px 16px; font-size: 16px; font-weight: 900; color: #D97706;">
{{ $order->formatted_total }}
</td>
</tr>
</table>
<!-- Afleveradres -->
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: #F8FAFC; border: 1px solid #E2E8F0; border-radius: 14px; margin-bottom: 24px; padding: 16px;">
<tr>
<td>
<div style="font-weight: 800; font-size: 12px; text-transform: uppercase; color: #64748B; margin-bottom: 6px;">
📦 Afleveradres:
</div>
<div style="font-size: 13px; color: #1E293B; line-height: 1.5;">
<strong>{{ $order->customer_name }}</strong><br>
{{ $order->shipping_street }} {{ $order->shipping_number }}<br>
{{ $order->shipping_postal_code }} {{ $order->shipping_city }}<br>
{{ $order->shipping_country ?? 'Nederland' }}
</div>
</td>
</tr>
</table>
<!-- Wat gebeurt er nu? -->
<div style="background-color: #EFF6FF; border: 1px solid #BFDBFE; border-radius: 12px; padding: 14px; font-size: 12px; color: #1E40AF; line-height: 1.5; margin-bottom: 20px;">
<strong>Wat gebeurt er nu?</strong><br>
1. We printen jouw model op hoge resolutie.<br>
2. We controleren de scharnieren en details met de hand.<br>
3. Je ontvangt een verzendbevestiging zodra het pakketje is overgedragen aan PostNL (binnen 2-3 werkdagen).
</div>
@auth
<div style="text-align: center; margin: 24px 0 10px 0;">
<a href="{{ route('account.index') }}" class="btn-primary" style="display: inline-block; background-color: #FBBF24; color: #0F172A !important; font-weight: 800; font-size: 13px; padding: 12px 24px; border-radius: 12px; text-decoration: none;">
Volg Bestelling in Mijn Account &rarr;
</a>
</div>
@endauth
</div>
@endsection
@@ -0,0 +1,37 @@
@extends('emails.layouts.master')
@section('title', 'Wachtwoord Opnieuw Instellen | Jouwdriedee.nl')
@section('content')
<div style="text-align: left;">
<div style="display: inline-block; background-color: #E0E7FF; color: #3730A3; font-size: 11px; font-weight: 800; padding: 4px 10px; border-radius: 999px; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px;">
🔒 Beveiliging
</div>
<h1 style="color: #0F172A; font-size: 22px; font-weight: 900; margin: 0 0 14px 0; line-height: 1.3;">
Wachtwoord opnieuw instellen
</h1>
<p style="color: #475569; font-size: 14px; line-height: 1.6; margin: 0 0 16px 0;">
Hallo {{ $user->name }},<br>
We hebben een verzoek ontvangen om het wachtwoord van jouw account bij <strong>Jouwdriedee.nl</strong> te resetten. Klik op onderstaande knop om een nieuw wachtwoord te kiezen:
</p>
<div style="text-align: center; margin: 30px 0;">
<a href="{{ $resetUrl }}" class="btn-primary" style="display: inline-block; background-color: #FBBF24; color: #0F172A !important; font-weight: 800; font-size: 14px; padding: 14px 32px; border-radius: 12px; text-decoration: none; box-shadow: 0 4px 12px rgba(251, 191, 36, 0.3);">
Wachtwoord Opnieuw Instellen &rarr;
</a>
</div>
<div style="background-color: #FFFBEB; border: 1px solid #FDE68A; border-radius: 12px; padding: 14px; margin-top: 24px; font-size: 12px; color: #92400E; line-height: 1.5;">
<strong>Let op:</strong> Deze link is om veiligheidsredenen slechts <strong>60 minuten</strong> geldig. Heb je zelf geen wachtwoordreset aangevraagd? Dan kun je deze e-mail veilig negeren. Jouw huidige wachtwoord blijft ongewijzigd.
</div>
<p style="color: #94A3B8; font-size: 11px; line-height: 1.4; margin-top: 24px; word-break: break-all;">
Werkt de knop niet? Kopieer en plak de volgende URL direct in je browser:<br>
<a href="{{ $resetUrl }}" style="color: #6366F1;">{{ $resetUrl }}</a>
</p>
</div>
@endsection
+51
View File
@@ -0,0 +1,51 @@
@extends('emails.layouts.master')
@section('title', 'Welkom bij Jouwdriedee.nl!')
@section('content')
<div style="text-align: left;">
<div style="display: inline-block; background-color: #FEF3C7; color: #92400E; font-size: 11px; font-weight: 800; padding: 4px 10px; border-radius: 999px; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px;">
🎉 Account Aangemaakt
</div>
<h1 style="color: #0F172A; font-size: 22px; font-weight: 900; margin: 0 0 14px 0; line-height: 1.3;">
Welkom bij Jouwdriedee, {{ $user->name }}!
</h1>
<p style="color: #475569; font-size: 14px; line-height: 1.6; margin: 0 0 16px 0;">
Leuk dat je een account hebt aangemaakt bij onze 3D printstudio. Vanaf nu kun je eenvoudig jouw bestellingen volgen, favoriete modellen bewaren en nóg sneller afrekenen.
</p>
<!-- Highlight Box -->
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: #F8FAFC; border: 1px solid #E2E8F0; border-radius: 14px; margin: 20px 0; padding: 18px;">
<tr>
<td>
<div style="font-weight: 800; font-size: 13px; color: #0F172A; margin-bottom: 8px;">
Wat kun je verwachten van onze 3D prints?
</div>
<div style="font-size: 12px; color: #475569; line-height: 1.6;">
&bull; <strong>Haarscherpe Bambu Lab kwaliteit:</strong> Laagdiktes vanaf 0.12 mm voor soepele scharnieren.<br>
&bull; <strong>16+ Kleurvariaties:</strong> Van zijdeglans Silk tot levendige fluor en pastel tinten.<br>
&bull; <strong>Duurzaam PLA+ filament:</strong> 100% biologisch afbreekbaar en reukloos.
</div>
</td>
</tr>
</table>
<!-- Call to Actions -->
<div style="text-align: center; margin: 28px 0 20px 0;">
<a href="{{ route('catalog') }}" class="btn-primary" style="display: inline-block; background-color: #FBBF24; color: #0F172A !important; font-weight: 800; font-size: 14px; padding: 12px 28px; border-radius: 12px; text-decoration: none; margin-right: 8px;">
Bekijk de Collectie &rarr;
</a>
<a href="{{ route('account.index') }}" style="display: inline-block; background-color: #F1F5F9; color: #334155 !important; font-weight: 700; font-size: 13px; padding: 12px 20px; border-radius: 12px; text-decoration: none;">
Mijn Account
</a>
</div>
<p style="color: #64748B; font-size: 12px; line-height: 1.5; margin: 20px 0 0 0; border-top: 1px solid #F1F5F9; padding-top: 16px;">
Heb je een vraag over een print of wil je iets op maat laten maken? Neem gerust contact op met ons via <a href="mailto:info@jouwdriedee.nl" style="color: #F59E0B; font-weight: 700;">info@jouwdriedee.nl</a>.
</p>
</div>
@endsection