Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/salty-rabbits-bow.md
Comment thread
leagrdv marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@swisspost/design-system-documentation': minor
'@swisspost/design-system-styles': minor
---

Added different page templates for the following errors: 400, 401, 403, 404, 451, 500, 503 and 504.

The previous 404 error page template is now deprecated.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
describe('ErrorPage', () => {
it('error page', () => {
cy.visit('/iframe.html?id=snapshots--error-page');
cy.get('.error', { timeout: 30000 }).should('be.visible');
cy.percySnapshot('Error page', { widths: [1440] });
});
});
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import { Meta, Canvas } from '@storybook/addon-docs/blocks';
import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks';
import * as ErrorPageStories from './error-page.stories';

<Meta of={ErrorPageStories} />

# Error page template

A generic error page pattern with an image. The image can be exchanged based on the type of error.

## Assets

- <a download href="/images/content/404.png">
Download "404 not found" image
</a>
A generic error page pattern. The image is set automatically based on the container class that is set.

<Canvas of={ErrorPageStories.Default} sourceState="shown" />
<div className="hide-col-default">
<Controls of={ErrorPageStories.Default} />
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Args, StoryContext, StoryObj } from '@storybook/web-components-vite';
import meta from './error-page.stories';
import { html } from 'lit';
import { schemes } from '@/shared/snapshots/schemes';

const { id, ...metaWithoutId } = meta;

export default {
...metaWithoutId,
title: 'Snapshots',
};

type Story = StoryObj;

export const ErrorPage: Story = {
render: (_args: Args, context: StoryContext) => {
return schemes(
() => html`
${['400', '401', '403', '404', '451', '500', '503', '504'].map(
type =>
html`<div class="mb-16">${meta.render?.({ ...context.args, type }, context)}</div>`,
)}
`,
);
},
};
Original file line number Diff line number Diff line change
@@ -1,47 +1,151 @@
import { Meta, StoryObj } from '@storybook/web-components-vite';
import { html } from 'lit';

type ErrorType = '400' | '401' | '403' | '404' | '451' | '500' | '503' | '504';
const contentByType: Record<
ErrorType,
{
subtitle: string;
description: string;
secondaryButtonLabel?: string;
secondaryButtonHref?: string;
}
> = {
'400': {
subtitle: 'Something went wrong.',
description:
'The page you requested could not be loaded.\n' +
'\n' +
'Please check the URL again. We may also have moved, archived or renamed the page in question. You may be able to find the content you are looking for via our homepage. Or use the search function on our portal to find the page you want.',
},
'401': {
subtitle: 'No authorization.',
description:
'Access to the page accessed has been denied. This can happen if your browser is not authenticated or if the required login information is missing.\n' +
'\n' +
'Please contact your IT administrator.',
},
'403': {
subtitle: 'No access.',
description:
'Server understood the request but rejected it. Access to the requested resource is not permitted.\n' +
'\n' +
'This may be due to incorrect URLs, a lack of login permissions, outdated browser data such as caches and cookies, or security settings.',
},
'404': {
subtitle: 'This page could not be found.',
description:
'Reasons for this could be that you have called up an incorrect or outdated URL.\n' +
'\n' +
'We kindly ask you to check this again. We may also have moved, archived or renamed the page in question. You may be able to find the content you are looking for via our homepage. Or use the search function on our portal to find the page you want.',
},
'451': {
subtitle: 'The page is unavailable for legal reasons.',
description:
'The site is blocked due to laws, court orders or other legal orders.\n' +
'\n' +
'The error can also be caused by technical problems on the server, e.g. if the server is overloaded or there are errors in the configuration. ',
},
'500': {
subtitle: 'Unexpected problem.',
description:
'This can be due to various server-side problems and usually requires the website operator or server administrator to rectify the problem.\n' +
'\n' +
'Try to reload the page, clear the browser cache or try to load the page again later. If the error persists, please inform the website operator.',
secondaryButtonLabel: 'Contact the website operator',
secondaryButtonHref: 'https://www.post.ch/en/help-and-contact',
},
'503': {
subtitle: 'The page you requested could not be loaded.',
description:
'The server appears to be temporarily unable to process requests. This can be caused by various factors, such as overloading, maintenance work or problems with server configuration.\n' +
'\n' +
'You can try to access the page again later or clear your browserโ€™s cache.',
},
'504': {
subtitle: 'The page took too long to load.',
description:
'The server had to wait too long for a response from another server. The error is often only temporary.\n' +
'\n' +
'You can try to access the page again later or clear your browserโ€™s cache.',
},
};

const meta: Meta = {
id: 'a536a61d-cac2-4f39-adbf-092bdd445ce5',
title: 'Templates/Error page',
parameters: {
layout: 'fullscreen',
},
render,
args: {
type: '404',
},
argTypes: {
type: {
name: 'Type',
description:
'HTTP error type displayed on the page (determines the message, image, and available actions).',
control: {
type: 'radio',
labels: {
'400': '400: Bad Request',
'401': '401: Unauthorized',
'403': '403: Forbidden',
'404': '404: Not Found',
'451': '451: Unavailable For Legal Reasons',
'500': '500: Error on Server side',
'503': '503: Service unavailable',
'504': '504: Gateway time-out',
},
},
options: ['400', '401', '403', '404', '451', '500', '503', '504'],
table: {
category: 'General',
},
},
},
render: ({ type }) => renderErrorPages(type),
};

function render() {
function renderErrorPages(type: ErrorType) {
const { subtitle, description, secondaryButtonLabel, secondaryButtonHref } = contentByType[type];
const descriptionWithLineBreaks = description
.split('\n')
.map((line, index, lines) => (index < lines.length - 1 ? html`${line}<br />` : line));

return html`
<div class="palette palette-alternate error-container">
<div class="palette palette-alternate error error-${type}">
<div class="container">
<div class="row">
<div class="col-sm-8 py-56">
<h2>
This page could not be found.
<br />
<span class="fw-normal">A reasons for this could be a misspelled URL.</span>
</h2>
<p class="mt-16">
We kindly ask you to review this once again. It is also possible that we have moved,
archived, or renamed the relevant page. Perhaps you can find the content you're
looking for on our homepage. Or use the search on our portal to locate the desired
page.
</p>
<div class="d-flex gap-16 mt-24">
<a class="btn btn-primary" href="/" @click="${(e: Event) => e.preventDefault()}"
>Home page</a
>
<a
class="btn btn-secondary"
href="https://www.post.ch/de/pages/suche#t=AllTab"
@click="${(e: Event) => e.preventDefault()}"
>
Search
</a>
</div>
</div>
<div class="col-6 offset-3 offset-sm-0 col-sm-4 align-self-end">
<img class="error-container--image" src="/images/content/404.png" alt="" />
<div class="error-content">
<h2 class="error-title">Error ${type}</h2>
<h3 class="error-subtitle">${subtitle}</h3>

<p>${descriptionWithLineBreaks}</p>

<div class="error-buttons">
${secondaryButtonLabel
? html`
<a
class="btn btn-secondary"
href="${secondaryButtonHref}"
@click="${(e: Event) => e.preventDefault()}"
>
${secondaryButtonLabel}
</a>
`
: html`
<a class="btn btn-primary" href="/" @click="${(e: Event) => e.preventDefault()}">
<post-icon name="arrowleft" aria-hidden="true"></post-icon>
Go to homepage
</a>
<a
class="btn btn-secondary"
href="https://www.post.ch/en/pages/suche#t=AllTab"
Comment thread
leagrdv marked this conversation as resolved.
@click="${(e: Event) => e.preventDefault()}"
>
Go to search
</a>
`}
</div>
</div>
</div>
Expand Down
Loading
Loading