Website: update 404 page (#47726)
Changes: - Added api/responses/notFound.js, an updated version of the notFound response built into Sails that sets a `hideFooter` page local variable to hide the website footer on the 404 page. - Updated the styles and layout of the 404 page to match the latest wireframes. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Completely redesigned the 404 error page with refreshed content and a more modern layout. * Added new visual styling, including animated interactive elements on the 404 page. * **Bug Fixes** * Improved 404 response handling to consistently return the correct status for JSON requests and render the 404 page when available. * Ensures the 404 page can render cleanly even if view rendering fails, and hides the footer for a cleaner error-page presentation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Vendored
+62
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
// n/a
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 404 (Not Found) Handler
|
||||
*
|
||||
* Usage:
|
||||
* return res.notFound();
|
||||
* return res.notFound(err);
|
||||
* return res.notFound(err, 'some/specific/notfound/view');
|
||||
*
|
||||
* e.g.:
|
||||
* ```
|
||||
* return res.notFound();
|
||||
* ```
|
||||
*
|
||||
* NOTE:
|
||||
* If a request doesn't match any explicit routes (i.e. `config/routes.js`)
|
||||
* or route blueprints (i.e. "shadow routes", Sails will call `res.notFound()`
|
||||
* automatically.
|
||||
*/
|
||||
|
||||
module.exports = function notFound () {
|
||||
|
||||
// Get access to `req` and `res`
|
||||
var req = this.req;
|
||||
var res = this.res;
|
||||
// Get access to `sails`
|
||||
var sails = req._sails;
|
||||
|
||||
// Set status code
|
||||
res.status(404);
|
||||
|
||||
// If the request wants JSON, send back the appropriate status code.
|
||||
if (req.wantsJSON || !res.view) {
|
||||
return res.sendStatus(404);
|
||||
}
|
||||
|
||||
return res.view('404', { hideFooter: true }, (err, html)=> {
|
||||
// If a view error occured, fall back to JSON.
|
||||
if (err) {
|
||||
//
|
||||
// Additionally:
|
||||
// • If the view was missing, ignore the error but provide a verbose log.
|
||||
if (err.code === 'E_VIEW_FAILED') {
|
||||
sails.log.verbose('res.notFound() :: Could not locate view for error page (sending text instead). Details: ', err);
|
||||
}
|
||||
// Otherwise, if this was a more serious error, log to the console with the details.
|
||||
else {
|
||||
sails.log.warn('res.notFound() :: When attempting to render error page view, an error occured (sending text instead). Details: ', err);
|
||||
}
|
||||
return res.sendStatus(404);
|
||||
}
|
||||
return res.send(html);
|
||||
});
|
||||
|
||||
};
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 256 KiB |
Vendored
+76
-1
@@ -1,5 +1,80 @@
|
||||
[id='404'] {
|
||||
background: linear-gradient(180deg, #FFF 45%, #E1F1F1 100%);
|
||||
min-height: calc(~'100vh - 80px');
|
||||
h2 {
|
||||
.section-heading();
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
//…
|
||||
p {
|
||||
.body-l();
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
[purpose='page-container'] {
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
padding-bottom: 64px;
|
||||
padding-top: 64px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
[purpose='page-content'] {
|
||||
max-width: 1072px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
}
|
||||
[purpose='404-image'] {
|
||||
max-width: 774px;
|
||||
img {
|
||||
width: 100%;
|
||||
aspect-ratio: 43 / 27;
|
||||
}
|
||||
}
|
||||
[purpose='animated-arrow-button'] {
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6px 0px;
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
color: @core-fleet-black;
|
||||
font-weight: 700;
|
||||
[purpose='button-text'] {
|
||||
color: @core-fleet-black;
|
||||
}
|
||||
[purpose='animated-arrow'] {
|
||||
margin-left: 8px;
|
||||
stroke-width: 2px;
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
fill: none;
|
||||
stroke: @core-vibrant-green;
|
||||
}
|
||||
[purpose='arrow-line'] {
|
||||
opacity: 0;
|
||||
transition: opacity 10ms ease-out;
|
||||
}
|
||||
[purpose='chevron'] {
|
||||
transition: transform 100ms ease-out;
|
||||
}
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
[purpose='button-text'] {
|
||||
color: @core-fleet-black;
|
||||
}
|
||||
[purpose='arrow-line'] {
|
||||
opacity: 1;
|
||||
transition: opacity 150ms ease-out;
|
||||
}
|
||||
[purpose='chevron'] {
|
||||
transform: translateX(5px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Vendored
+16
-6
@@ -1,10 +1,20 @@
|
||||
<div id="404">
|
||||
<div style="max-width: 650px;" class="container text-center pt-5 pb-5">
|
||||
<h1 class="display-1 mb-3">404</h1>
|
||||
<hr/>
|
||||
<h2>The page you seek doesn't exist.</h2>
|
||||
<div>
|
||||
<p>Think you're seeing this message in error?<br class="d-none d-sm-inline" /><span class="d-inline d-sm-none"> </span>Please <a href="/contact?sendMessage">let us know.</a></p>
|
||||
<div purpose="page-container">
|
||||
<div purpose="page-content">
|
||||
<div purpose="404-image">
|
||||
<img alt="404" src="/images/404-774x486@2x.png">
|
||||
</div>
|
||||
<h2>404: We can’t find that page!</h2>
|
||||
<p>The page you are looking for has either moved, or doesn’t exist.</p>
|
||||
<div>
|
||||
<a purpose="animated-arrow-button" href="/support" no-underline>
|
||||
Get help with Fleet
|
||||
<svg purpose="animated-arrow" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
|
||||
<path purpose="arrow-line" d="M1 6H9" stroke-width="2" stroke-linecap="round"/>
|
||||
<path purpose="chevron" d="M1.35712 1L5.64283 6L1.35712 11" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Vendored
+4
-1
@@ -7,6 +7,7 @@
|
||||
var currentSection;
|
||||
var hideHeaderLinks;// Hides the header navigation links.
|
||||
var hideFooterLinks;// Hides footer links, reduces the height of the footer to 60px;
|
||||
var hideFooter;// Hides the footer.
|
||||
var showAdminLinks;// Shows links to admin pages to admin users.
|
||||
var showConfigurationProfileLayout;
|
||||
var disableChatbotAndIndexing;// Disables the chatbot and adds a noindex meta tag. Used on pages linked to from Fleet.
|
||||
@@ -162,7 +163,7 @@
|
||||
<!--STYLES END-->
|
||||
</head>
|
||||
<body>
|
||||
<div purpose="page-wrap" class="<%= hideFooterLinks ? 'reduced-footer-links' : showConfigurationProfileLayout ? 'header-hidden' : '' %> collapse" id="navbarToggleExternalContent">
|
||||
<div purpose="page-wrap" class="<%= hideFooterLinks ? 'reduced-footer-links' : (showConfigurationProfileLayout || hideFooter) ? 'header-hidden' : '' %> collapse" id="navbarToggleExternalContent">
|
||||
<%// Page header%>
|
||||
<% if(!showConfigurationProfileLayout) {%>
|
||||
<div class="header" purpose="header-container" hide-when-scrolled data-nosnippet>
|
||||
@@ -758,6 +759,7 @@
|
||||
<% } %>
|
||||
|
||||
<%- body %>
|
||||
<% if(!hideFooter) {%>
|
||||
<% if(!showConfigurationProfileLayout) {%>
|
||||
<%/* Note: footer is hidden until the page is loaded. See «script» tag at the bottom of this file. */%>
|
||||
<% if(!hideFooterLinks) { %>
|
||||
@@ -881,6 +883,7 @@
|
||||
</div>
|
||||
<% } %>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</div>
|
||||
<% /*
|
||||
Client-side JavaScript
|
||||
|
||||
Reference in New Issue
Block a user