feat: add invite notification emails, functionality to admin dashboard and sign up page

Signed-off-by: Miguel Nogueira <me@nogueira.codes>
This commit is contained in:
2025-08-07 18:46:34 +01:00
parent 22cffaffca
commit f7c62a4ac2
19 changed files with 1141 additions and 2 deletions

View File

@@ -0,0 +1,50 @@
@extends('breadcrumbs.auth.main')
@section('authpage')
<div class="container">
<div class="card login-card">
<div class="row no-gutters">
<div class="col-md-5">
<img src="{{ asset(config('customization.authbanner')) }}" alt="login" class="login-card-img">
</div>
<div class="col-md-7">
<div class="card-body">
<div class="brand-wrapper">
<img src="{{ asset(config('adminlte.logo_img_xl')) }}" alt="logo" class="logo rounded mr-2">
</div> <!-- main content start -->
@if(!\App\Facades\Options::getOption('enable_registrations'))
<p class="login-card-description">{{__('Invite validation')}}</p>
<div class="alert alert-warning">
<i class="fa fa-exclamation-circle"></i>
{{ __('Warning: If you clear your cookies or close your browser, you will not be able to sign up after validating your invite. Invites can\'t be validated twice. Please complete the registration process without interruption.') }}
</div>
<form action="{{ route('invitations.validate-invite') }}" method="POST" id="registerForm">
@csrf
<input type="text" name="validation_token" id="validationToken" class="form-control mb-3" value="{{ old('validation_token', $validationToken ?? '') }}" readonly tabindex="-1" style="background-color: #e9ecef; color: #495057;"> <input type="email" name="email" id="email" class="form-control mb-3" placeholder="{{ __('Enter your email address (must be the same as the one on file)') }}" value="{{ old('email') }}" required>
<input name="submitValidation" id="submitValidation" class="btn btn-block login-btn mb-4" type="submit" value="{{__('Validate')}}">
</form>
@else
<div class="alert alert-danger">
<b><i class="fa fa-exclamation-triangle"></i> {{ __('Looks like you\'re lost!') }}</b>
<p>{{ __('Sign ups are currently open. No need to validate anything!') }}</p>
</div>
@endif
<p class="login-card-footer-text">{{__('Have an account with us?')}} <a href="{{ route('login') }}" class="text-reset">{{__('Sign in here')}}</a></p>
<nav class="login-card-footer-nav">
<a href="{{ config('app.terms_url') }}">{{__('Terms of Service')}}</a>
<a href="{{ config('app.privacy_url') }}">{{__('Privacy Policy')}}</a>
<a href="{{ config('app.guidelines_url') }}">{{__('Community Guidelines')}}</a>
</nav>
</div>
</div>
</div>
</div>
</div>
@stop

View File

@@ -0,0 +1,148 @@
@extends('adminlte::page')
@section('title', config('app.name') . ' | ' . __('Invitation management'))
@section('content_header')
<h4>{{__('Administration')}} / {{__('Invitation management')}}</h4>
@stop
@section('js')
<x-global-errors></x-global-errors>
@stop
@section('content')
<div class="row mt-5">
<div class="col">
<x-card id="inviteManagement" card-title="{{ __('Invitation management system') }}" footer-style="text-muted">
<x-slot name="cardHeader">
<div class="d-flex justify-content-end">
<button type="button" id="inviteUserBtn" class="btn btn-success btn-sm ml-3" data-toggle="modal" data-target="#inviteUserModal">
<i class="fas fa-user-plus"></i> {{ __('Invite user') }}
</button>
</div>
</x-slot>
@if(!empty($invites) && count($invites) > 0)
<table class="table table-striped table-hover align-middle shadow-sm rounded">
<thead class="thead-dark">
<tr>
<th scope="col"><i class="fas fa-envelope"></i> {{ __('Email') }}</th>
<th scope="col"><i class="fas fa-network-wired"></i> {{ __('IP Address') }}</th>
<th scope="col"><i class="fas fa-clipboard-check"></i> {{ __('Status') }}</th>
<th scope="col"><i class="fas fa-bell"></i> {{ __('Notified?') }}</th>
<th scope="col"><i class="fas fa-calendar-alt"></i> {{ __('Received at') }}</th>
<th scope="col"><i class="fas fa-tasks"></i> {{ __('Actions') }}</th>
</tr>
</thead>
<tbody>
@foreach($invites as $invite)
<tr>
<td>
<span class="font-weight-bold text-primary">{{ $invite->requestor_email }}</span>
</td>
<td>
<span class="badge badge-info">{{ $invite->requestor_ip_address }}</span>
</td>
<td>
@php
$statusColors = [
'approved' => 'success',
'denied' => 'danger',
'pending' => 'warning',
'completed' => 'primary'
];
$status = strtolower($invite->status);
$color = $statusColors[$status] ?? 'secondary';
@endphp
<span class="badge badge-{{ $color }} text-uppercase px-3 py-2">
<i class="fas fa-circle"></i> {{ __(ucfirst($status)) }}
</span>
</td>
<td>
@if($invite->notified)
<span class="badge badge-success">{{ __('Yes') }}</span>
@else
<span class="badge badge-secondary">{{ __('No') }}</span>
@endif
</td>
<td>
<span class="text-muted">{{ $invite->created_at->format('Y-m-d H:i') }}</span>
</td>
<td>
@if(strtolower($invite->status) === 'pending')
<form method="POST" action="{{ route('invitations.approve-invite', $invite->id) }}" style="display:inline;">
@csrf
@method('PATCH')
<button type="submit" class="btn btn-success btn-sm" title="{{ __('Approve') }}">
<i class="fas fa-check"></i>
</button>
</form>
<form method="POST" action="{{ route('invitations.deny-invite', $invite->id) }}" style="display:inline;">
@csrf
@method('PATCH')
<button type="submit" class="btn btn-danger btn-sm" title="{{ __('Deny') }}">
<i class="fas fa-times"></i>
</button>
</form>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
@else
<x-alert alert-type="warning" title="{{ __('Nothing here') }}" icon="fas fa-exclamation-triangle">
{{ __('There are currently no outgoing invites or any user requests. Feel free to send out any invites if necessary.') }}
</x-alert>
@endif
<x-slot name="cardFooter">
<p><i class="fas fa-info-circle"></i> {{ __('Here, you can manage the invitation system, and approve any invite requests that might have come through. You can also send invites from here if necessary.') }}</p>
</x-slot>
</x-card>
</div>
</div>
<x-modal id="inviteUserModal" :modalTitle="__('Invite a User')" :modalLabel="'inviteUserModalLabel'" :includeCloseButton="true">
<form method="POST" action="{{ route('invitations.request') }}">
@csrf
<div class="input-group mt-3">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="fas fa-envelope"></i>
</span>
</div>
<label for="inviteEmail" class="sr-only">{{ __('Email address') }}</label>
<input type="email" class="form-control" id="inviteEmail" name="email" required placeholder="{{ __('Enter an email address to send the invite to') }}">
</div>
<p class="text-muted mt-2 mb-2"><i class="fas fa-info-circle"></i> {{ __('Sending an invite here will immediately create an approved invite request which will in turn send this user an email message with a link. Be aware that this will allow them to register for a new account.') }}</p>
</form>
<x-slot name="modalFooter">
<button id="sendInviteBtn" class="btn btn-success" type="button">
<i class="fas fa-paper-plane"></i> {{ __('Invite') }}
</button>
<script>
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('sendInviteBtn').addEventListener('click', function () {
document.querySelector('#inviteUserModal form').submit();
});
});
</script>
</x-slot>
</x-modal>
@stop
@section('footer')
@include('breadcrumbs.dashboard.footer')
@stop

View File

@@ -0,0 +1,166 @@
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Your invite request for {{ config('app.name') }} has been approved </title>
<style>
/* -------------------------------------
INLINED WITH htmlemail.io/inline
------------------------------------- */
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 620px) {
table[class=body] h1 {
font-size: 28px !important;
margin-bottom: 10px !important;
}
table[class=body] p,
table[class=body] ul,
table[class=body] ol,
table[class=body] td,
table[class=body] span,
table[class=body] a {
font-size: 16px !important;
}
table[class=body] .wrapper,
table[class=body] .article {
padding: 10px !important;
}
table[class=body] .content {
padding: 0 !important;
}
table[class=body] .container {
padding: 0 !important;
width: 100% !important;
}
table[class=body] .main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important;
}
table[class=body] .btn table {
width: 100% !important;
}
table[class=body] .btn a {
width: 100% !important;
}
table[class=body] .img-responsive {
height: auto !important;
max-width: 100% !important;
width: auto !important;
}
}
/* -------------------------------------
PRESERVE THESE STYLES IN THE HEAD
------------------------------------- */
@media all {
.ExternalClass {
width: 100%;
}
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%;
}
.apple-link a {
color: inherit !important;
font-family: inherit !important;
font-size: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
text-decoration: none !important;
}
#MessageViewBody a {
color: inherit;
text-decoration: none;
font-size: inherit;
font-family: inherit;
font-weight: inherit;
line-height: inherit;
}
.btn-primary table td:hover {
background-color: #34495e !important;
}
.btn-primary a:hover {
background-color: #34495e !important;
border-color: #34495e !important;
}
}
</style>
</head>
<body class="" style="background-color: #f6f6f6; font-family: sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;">
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">You have invite request to {{ config('app.name') }} has just been approved</span>
<table border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background-color: #f6f6f6;">
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">&nbsp;</td>
<td class="container" style="font-family: sans-serif; font-size: 14px; vertical-align: top; display: block; Margin: 0 auto; max-width: 580px; padding: 10px; width: 580px;">
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 580px; padding: 10px;">
<!-- START CENTERED WHITE CONTAINER -->
<table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: #ffffff; border-radius: 3px;">
<!-- START MAIN CONTENT AREA -->
<tr>
<td class="wrapper" style="font-family: sans-serif; font-size: 14px; vertical-align: top; box-sizing: border-box; padding: 20px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">Hello there!</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">Congrats! Your invite request has just been approved and an admin has sent you an invitation link. You should now validate the invite so that you can sign up.</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">Currently, public registrations are closed but you can sign up with this invite link.</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">This invite expires in 48 hours after approval. If you'd still like to sign up after this period, you can request another one <a href="{{route('register')}}">here</a> and one will be sent to you after admin approval.</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">You are receiving this email because you requested an invite at {{ config('app.name') }} {{ $invitedDaysSince }} days ago. If you believe you received this message in error, you can ignore it safely; otherwise, feel free to unsubscribe at the bottom of this email.</p>
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border-box;">
<tbody>
<tr>
<td align="left" style="font-family: sans-serif; font-size: 14px; vertical-align: top; padding-bottom: 15px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: auto;">
<tbody>
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top; background-color: #3498db; border-radius: 5px; text-align: center; margin-left: 5px;"> <a href="{{ route('invitations.redeem-invite', ['token' => $token]) }}" target="_blank" style="display: inline-block; color: #ffffff; background-color: #3498db; border: solid 1px #3498db; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 14px; font-weight: bold; margin: 0; padding: 12px 25px; text-transform: capitalize; border-color: #3498db;">Accept invite & sign up</a> </td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">Kind regards,</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">The {{ config('app.name') }} Team</p>
</td>
</tr>
</table>
</td>
</tr>
<!-- END MAIN CONTENT AREA -->
</table>
<!-- START FOOTER -->
<div class="footer" style="clear: both; Margin-top: 10px; text-align: center; width: 100%;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
<td class="content-block" style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; font-size: 12px; color: #999999; text-align: center;">
<span class="apple-link" style="color: #999999; font-size: 12px; text-align: center;">Staff Manager</span>
</td>
</tr>
</table>
</div>
<!-- END FOOTER -->
<!-- END CENTERED WHITE CONTAINER -->
</div>
</td>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">&nbsp;</td>
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,150 @@
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Invite request confirmation - {{ config('app.name') }} </title>
<style>
/* -------------------------------------
INLINED WITH htmlemail.io/inline
------------------------------------- */
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 620px) {
table[class=body] h1 {
font-size: 28px !important;
margin-bottom: 10px !important;
}
table[class=body] p,
table[class=body] ul,
table[class=body] ol,
table[class=body] td,
table[class=body] span,
table[class=body] a {
font-size: 16px !important;
}
table[class=body] .wrapper,
table[class=body] .article {
padding: 10px !important;
}
table[class=body] .content {
padding: 0 !important;
}
table[class=body] .container {
padding: 0 !important;
width: 100% !important;
}
table[class=body] .main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important;
}
table[class=body] .btn table {
width: 100% !important;
}
table[class=body] .btn a {
width: 100% !important;
}
table[class=body] .img-responsive {
height: auto !important;
max-width: 100% !important;
width: auto !important;
}
}
/* -------------------------------------
PRESERVE THESE STYLES IN THE HEAD
------------------------------------- */
@media all {
.ExternalClass {
width: 100%;
}
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%;
}
.apple-link a {
color: inherit !important;
font-family: inherit !important;
font-size: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
text-decoration: none !important;
}
#MessageViewBody a {
color: inherit;
text-decoration: none;
font-size: inherit;
font-family: inherit;
font-weight: inherit;
line-height: inherit;
}
.btn-primary table td:hover {
background-color: #34495e !important;
}
.btn-primary a:hover {
background-color: #34495e !important;
border-color: #34495e !important;
}
}
</style>
</head>
<body class="" style="background-color: #f6f6f6; font-family: sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;">
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">Your invite request to {{ config('app.name') }} has just been received</span>
<table border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background-color: #f6f6f6;">
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">&nbsp;</td>
<td class="container" style="font-family: sans-serif; font-size: 14px; vertical-align: top; display: block; Margin: 0 auto; max-width: 580px; padding: 10px; width: 580px;">
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 580px; padding: 10px;">
<!-- START CENTERED WHITE CONTAINER -->
<table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: #ffffff; border-radius: 3px;">
<!-- START MAIN CONTENT AREA -->
<tr>
<td class="wrapper" style="font-family: sans-serif; font-size: 14px; vertical-align: top; box-sizing: border-box; padding: 20px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">Hello there! Thank you for your interest in {{ config('app.name') }}.</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">We just wanted to let you know that we've received your invitation request to sign up for an account at {{ config('app.name') }}. It is now under consideration, pending admin approval.</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">If approved, you'll receive a link to accept and validate your invite. Otherwise, you won't receive any more notifications.</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">If you believe you received this message in error, you can ignore it safely; otherwise, feel free to unsubscribe at the bottom of this email.</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">Kind regards,</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">The {{ config('app.name') }} Team</p>
</td>
</tr>
</table>
</td>
</tr>
<!-- END MAIN CONTENT AREA -->
</table>
<!-- START FOOTER -->
<div class="footer" style="clear: both; Margin-top: 10px; text-align: center; width: 100%;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
<td class="content-block" style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; font-size: 12px; color: #999999; text-align: center;">
<span class="apple-link" style="color: #999999; font-size: 12px; text-align: center;">Staff Manager</span>
</td>
</tr>
</table>
</div>
<!-- END FOOTER -->
<!-- END CENTERED WHITE CONTAINER -->
</div>
</td>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">&nbsp;</td>
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,166 @@
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>You have just been invited create an account at {{ config('app.name') }} </title>
<style>
/* -------------------------------------
INLINED WITH htmlemail.io/inline
------------------------------------- */
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 620px) {
table[class=body] h1 {
font-size: 28px !important;
margin-bottom: 10px !important;
}
table[class=body] p,
table[class=body] ul,
table[class=body] ol,
table[class=body] td,
table[class=body] span,
table[class=body] a {
font-size: 16px !important;
}
table[class=body] .wrapper,
table[class=body] .article {
padding: 10px !important;
}
table[class=body] .content {
padding: 0 !important;
}
table[class=body] .container {
padding: 0 !important;
width: 100% !important;
}
table[class=body] .main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important;
}
table[class=body] .btn table {
width: 100% !important;
}
table[class=body] .btn a {
width: 100% !important;
}
table[class=body] .img-responsive {
height: auto !important;
max-width: 100% !important;
width: auto !important;
}
}
/* -------------------------------------
PRESERVE THESE STYLES IN THE HEAD
------------------------------------- */
@media all {
.ExternalClass {
width: 100%;
}
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%;
}
.apple-link a {
color: inherit !important;
font-family: inherit !important;
font-size: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
text-decoration: none !important;
}
#MessageViewBody a {
color: inherit;
text-decoration: none;
font-size: inherit;
font-family: inherit;
font-weight: inherit;
line-height: inherit;
}
.btn-primary table td:hover {
background-color: #34495e !important;
}
.btn-primary a:hover {
background-color: #34495e !important;
border-color: #34495e !important;
}
}
</style>
</head>
<body class="" style="background-color: #f6f6f6; font-family: sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;">
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">You have just been invited to {{ config('app.name') }}</span>
<table border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background-color: #f6f6f6;">
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">&nbsp;</td>
<td class="container" style="font-family: sans-serif; font-size: 14px; vertical-align: top; display: block; Margin: 0 auto; max-width: 580px; padding: 10px; width: 580px;">
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 580px; padding: 10px;">
<!-- START CENTERED WHITE CONTAINER -->
<table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: #ffffff; border-radius: 3px;">
<!-- START MAIN CONTENT AREA -->
<tr>
<td class="wrapper" style="font-family: sans-serif; font-size: 14px; vertical-align: top; box-sizing: border-box; padding: 20px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">Hello there!</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">An administrator has invited you to create an account over at {{ config('app.name') }}. This will allow you to apply to a vacancy of your choosing.</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">Currently, public registrations are closed but you can sign up with this invite link.</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">This invite expires in 48 hours. If you'd still like to sign up after this period, you can request another one <a href="{{route('register')}}">here</a> and one will be sent to you after admin approval.</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">If you believe you received this message in error, you can ignore it safely; otherwise, feel free to unsubscribe at the bottom of this email.</p>
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border-box;">
<tbody>
<tr>
<td align="left" style="font-family: sans-serif; font-size: 14px; vertical-align: top; padding-bottom: 15px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: auto;">
<tbody>
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top; background-color: #3498db; border-radius: 5px; text-align: center; margin-left: 5px;"> <a href="{{ route('invitations.redeem-invite', ['token' => $token]) }}" target="_blank" style="display: inline-block; color: #ffffff; background-color: #3498db; border: solid 1px #3498db; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 14px; font-weight: bold; margin: 0; padding: 12px 25px; text-transform: capitalize; border-color: #3498db;">Accept invite & sign up</a> </td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">Kind regards,</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">The {{ config('app.name') }} Team</p>
</td>
</tr>
</table>
</td>
</tr>
<!-- END MAIN CONTENT AREA -->
</table>
<!-- START FOOTER -->
<div class="footer" style="clear: both; Margin-top: 10px; text-align: center; width: 100%;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
<td class="content-block" style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; font-size: 12px; color: #999999; text-align: center;">
<span class="apple-link" style="color: #999999; font-size: 12px; text-align: center;">Staff Manager</span>
</td>
</tr>
</table>
</div>
<!-- END FOOTER -->
<!-- END CENTERED WHITE CONTAINER -->
</div>
</td>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">&nbsp;</td>
</tr>
</table>
</body>
</html>