UKHomeOffice / design-system

Home Office Design System
https://design.homeoffice.gov.uk
76 stars 22 forks source link

Flexibility to use different headers on separate pages within the same app #288

Closed anandamaryon-gov closed 3 years ago

anandamaryon-gov commented 3 years ago

What

Allow a way for prototypes to have different headers, and potentially footers, on different pages within the same app.

For example: one page in a prototype could have a header with no navigation and other pages within that app could have a header with navigation links.

Why

My use-case for this is to allow for pages within my app that cater for logged in users, and logged out users.

My service will use SSO (Single Sign On) so my requirement is simply to have a landing page (start page) that logged out users can view. This start page should not have the same header links as the logged in pages within the app.

This would also be the case for a more standard login page, though I'm not sure whether any internal Home Office services use these instead of SSO.

For example:

A header for the start page (note, no navigation and no sign out button) image

A header for a logged in user, which includes navigation image

Potentially related issues:

https://github.com/UKHomeOffice/design-system/issues/229 https://github.com/UKHomeOffice/design-system/issues/232 (unsure whether this is relevant or not)

daniel-ac-martin commented 3 years ago

This should already be possible.

There's a hook that you can use in page-wrap.tsx to gain access to information about the user. If they are logged in you could provide you navigation to the Page component but not if they aren't.

import { useUserInfo } from '@not-govuk/user-info';

Then in the component itself:

const { username } = useUserInfo() || {};
const navigation = username && [
  { href: '/', text: 'Home' },
  { href: '/two', text: 'Two' }
];

You would need to set-up authentication though and I've only really done that with Keycloak so far.

As a hack maybe you could instead do it based on the page they are on. You can do that with the location. Something like:

export const PageWrap: FC<PageProps> = ({ location, routes, signInHRef, signOutHRef, children }) => {
  const navigation = (location.path !== '/logged-out') && [
    { href: '/', text: 'Home' },
    { href: '/two', text: 'Two' }
  ];

...
daniel-ac-martin commented 3 years ago

To add to this answer, we solved this with a page wrap as follows:

import { FC, createElement as h } from 'react';
import { PageProps } from '@not-govuk/app-composer';
import { Page } from '@hods/components';
import './app.scss';
export const PageWrap: FC<PageProps> = ({ routes, children, location }) => {
  const signOutHref = '/auth/start-page';
  const props = (
    location.pathname === signOutHref
      ? {
        signOutText: 'Sign in'
      }
      : {
        navigation: [
          { href: "/foo", text: "Foo"},
          { href: "/bar", text: "Bar"},
          { href: "/baz", text: "Baz"}
        ],
        signOutText: 'Sign out',
        username: 'User name'
      }
  );
  return (
    <Page
      {...props}
      accountHref={'#/my-account'}
      serviceName="Service name"
      signOutHref={signOutHref}
      footerNavigation={[
        { href: "/foo", text: "Foo"},
      ]}
    >
      {children}
    </Page>
  );
};
export default PageWrap;