diff --git a/website/api/responses/notFound.js b/website/api/responses/notFound.js new file mode 100644 index 0000000000..f6fe7f52db --- /dev/null +++ b/website/api/responses/notFound.js @@ -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); + }); + +}; diff --git a/website/assets/images/404-774x486@2x.png b/website/assets/images/404-774x486@2x.png new file mode 100644 index 0000000000..a3199494d7 Binary files /dev/null and b/website/assets/images/404-774x486@2x.png differ diff --git a/website/assets/styles/pages/404.less b/website/assets/styles/pages/404.less index b17ea3ae78..9122c7a854 100644 --- a/website/assets/styles/pages/404.less +++ b/website/assets/styles/pages/404.less @@ -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); + } + } + } } diff --git a/website/views/404.ejs b/website/views/404.ejs index 2afd35b0fe..1810bf4a86 100644 --- a/website/views/404.ejs +++ b/website/views/404.ejs @@ -1,10 +1,20 @@
-
-

404

-
-

The page you seek doesn't exist.

-
-

Think you're seeing this message in error?
 Please let us know.

+
+
+
+ 404 +
+

404: We can’t find that page!

+

The page you are looking for has either moved, or doesn’t exist.

+
diff --git a/website/views/layouts/layout.ejs b/website/views/layouts/layout.ejs index 0d428efeeb..db6f8c16c5 100644 --- a/website/views/layouts/layout.ejs +++ b/website/views/layouts/layout.ejs @@ -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 @@ -