- Created a new error page (error.twig) with a user-friendly design for displaying error messages. - Created a new not found page (not-found.twig) to handle 404 errors with appropriate messaging and actions. - Added a SAML authentication configuration file (settings-custom.php) to support group-based admin assignment and user provisioning.
193 lines
7.2 KiB
Twig
193 lines
7.2 KiB
Twig
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<title>{% trans "Error" %} | {{ theme.getThemeConfig("theme_title") }}</title>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="public-path" content="{{ theme.rootUri() }}"/>
|
|
<link rel="shortcut icon" href="{{ theme.uri("img/favicon.ico") }}" />
|
|
<script src="{{ theme.rootUri() }}dist/style.bundle.min.js?v={{ version }}&rev={{revision}}" nonce="{{ cspNonce }}"></script>
|
|
<link href="{{ theme.uri("css/override.css") }}?{{ version }}" rel="stylesheet" media="screen">
|
|
<link href="{{ theme.uri("css/override-dark.css") }}?{{ version }}" rel="stylesheet" media="screen">
|
|
<style type="text/css" nonce="{{ cspNonce }}">
|
|
html, body {
|
|
height: 100%;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
body {
|
|
background-color: #0f172a;
|
|
color: #f1f5f9;
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-height: 100vh;
|
|
}
|
|
.error-page {
|
|
text-align: center;
|
|
padding: 40px 24px;
|
|
max-width: 560px;
|
|
width: 100%;
|
|
}
|
|
.error-logo {
|
|
height: 48px;
|
|
width: auto;
|
|
margin-bottom: 32px;
|
|
}
|
|
.error-icon {
|
|
width: 64px;
|
|
height: 64px;
|
|
border-radius: 50%;
|
|
background-color: rgba(239, 68, 68, 0.15);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin: 0 auto 20px;
|
|
color: #ef4444;
|
|
}
|
|
.error-title {
|
|
font-size: 1.5rem;
|
|
font-weight: 600;
|
|
color: #ffffff;
|
|
margin: 0 0 16px;
|
|
}
|
|
.error-detail {
|
|
background-color: rgba(239, 68, 68, 0.1);
|
|
border: 1px solid rgba(239, 68, 68, 0.25);
|
|
border-radius: 8px;
|
|
padding: 14px 18px;
|
|
font-size: 0.9rem;
|
|
color: #fca5a5;
|
|
text-align: left;
|
|
margin-bottom: 28px;
|
|
line-height: 1.6;
|
|
word-break: break-word;
|
|
}
|
|
.error-fallback {
|
|
font-size: 0.95rem;
|
|
color: #94a3b8;
|
|
margin: 0 0 28px;
|
|
line-height: 1.6;
|
|
}
|
|
.error-actions {
|
|
display: flex;
|
|
gap: 12px;
|
|
justify-content: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
.btn-home {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 10px 24px;
|
|
background-color: #e87800;
|
|
color: #ffffff;
|
|
text-decoration: none;
|
|
border-radius: 8px;
|
|
font-size: 0.9rem;
|
|
font-weight: 500;
|
|
transition: background-color 0.2s;
|
|
}
|
|
.btn-home:hover {
|
|
background-color: #c46500;
|
|
color: #ffffff;
|
|
text-decoration: none;
|
|
}
|
|
.btn-back {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 10px 24px;
|
|
background-color: rgba(255, 255, 255, 0.08);
|
|
color: #e2e8f0;
|
|
text-decoration: none;
|
|
border-radius: 8px;
|
|
font-size: 0.9rem;
|
|
font-weight: 500;
|
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
cursor: pointer;
|
|
transition: background-color 0.2s;
|
|
}
|
|
.btn-back:hover {
|
|
background-color: rgba(255, 255, 255, 0.14);
|
|
color: #ffffff;
|
|
text-decoration: none;
|
|
}
|
|
.redirect-notice {
|
|
margin-top: 28px;
|
|
font-size: 0.8rem;
|
|
color: #64748b;
|
|
}
|
|
.redirect-notice span {
|
|
color: #e87800;
|
|
font-weight: 600;
|
|
}
|
|
.error-divider {
|
|
width: 48px;
|
|
height: 3px;
|
|
background: #ef4444;
|
|
border-radius: 2px;
|
|
margin: 16px auto 24px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="error-page" role="main">
|
|
<a href="{{ homeUrl }}">
|
|
<img class="error-logo" src="{{ theme.uri("img/xibologo.png") }}" alt="OTS Signs">
|
|
</a>
|
|
|
|
<div class="error-icon" aria-hidden="true">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="currentColor" viewBox="0 0 16 16">
|
|
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
|
|
</svg>
|
|
</div>
|
|
|
|
<h1 class="error-title">{% trans "Something Went Wrong" %}</h1>
|
|
<div class="error-divider" aria-hidden="true"></div>
|
|
|
|
{% if message is defined and message != "" %}
|
|
<div class="error-detail" role="alert">{{ message }}</div>
|
|
{% else %}
|
|
<p class="error-fallback">
|
|
{% trans "An unexpected error occurred. Please try again or contact support if the problem persists." %}
|
|
</p>
|
|
{% endif %}
|
|
|
|
<div class="error-actions">
|
|
<a class="btn-home" href="{{ homeUrl }}">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true"><path d="M8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4.5a.5.5 0 0 0 .5-.5v-4h2v4a.5.5 0 0 0 .5.5H14a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L8.354 1.146z"/></svg>
|
|
{% trans "Go to Dashboard" %}
|
|
</a>
|
|
<button class="btn-back" onclick="history.back()" type="button">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true"><path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8z"/></svg>
|
|
{% trans "Go Back" %}
|
|
</button>
|
|
</div>
|
|
|
|
<p class="redirect-notice" id="redirect-notice" aria-live="polite">
|
|
{% trans "Redirecting to dashboard in" %} <span id="countdown">15</span> {% trans "seconds" %}…
|
|
</p>
|
|
</div>
|
|
|
|
<script src="{{ theme.rootUri() }}dist/vendor.bundle.min.js?v={{ version }}&rev={{revision}}" nonce="{{ cspNonce }}"></script>
|
|
<script type="text/javascript" nonce="{{ cspNonce }}">
|
|
(function () {
|
|
var homeUrl = {{ homeUrl | json_encode | raw }};
|
|
var seconds = 15;
|
|
var el = document.getElementById('countdown');
|
|
var interval = setInterval(function () {
|
|
seconds -= 1;
|
|
if (el) el.textContent = seconds;
|
|
if (seconds <= 0) {
|
|
clearInterval(interval);
|
|
window.location.replace(homeUrl);
|
|
}
|
|
}, 1000);
|
|
}());
|
|
</script>
|
|
</body>
|
|
</html>
|