diff --git a/app/layout.tsx b/app/layout.tsx
index adb0be4..c908e02 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,75 +1,34 @@
'use client';
-import ConfigureAmplifyClientSide from '../components/ConfigureAmplify';
-
import React from 'react';
-import { Authenticator, Heading, useTheme } from '@aws-amplify/ui-react';
+import { Authenticator } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
import { Col, Container, Footer, Header, Row } from 'nhsuk-react-components';
+import ConfigureAmplifyClientSide from '../components/ConfigureAmplify';
+import LoginStatus from '../components/LoginStatus';
+
import 'nhsuk-frontend/dist/nhsuk.css';
import './styles.css';
-import Logout from '../components/Logout';
-import { signInWithRedirect } from '@aws-amplify/auth';
-import { Amplify } from 'aws-amplify';
-
-export default function RootLayout({
- children,
- }: {
- children: React.ReactNode
-}) {
-
- async function auth0Login() {
- console.log(Amplify.getConfig());
- await signInWithRedirect({
- provider: {
- custom: 'Auth0'
- }
- })
- }
-
- const components = {
- SignIn: {
- Header() {
- const { tokens } = useTheme();
-
- return (<>
-
- Sign in to your account
-
-
- >
- );
- }
- }
- };
+export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
-
+
-
- Notify
-
-
+
{/**/}
{/* Health A-Z*/}
{/**/}
-
+
Home
@@ -79,9 +38,7 @@ export default function RootLayout({
-
- {children}
-
+ {children}
diff --git a/app/page.tsx b/app/page.tsx
index 0b7217a..e46d6fa 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,16 +1,36 @@
-import React from 'react';
-import Redirect from '../components/Redirect';
+'use client';
-export default async function Page({ searchParams }: {
+import React, { useEffect, useState } from 'react';
+import { Hub } from '@aws-amplify/core';
+import Login from '../components/Login';
+
+export default function Page({ searchParams }: {
searchParams: { [key: string]: string | string[] | undefined }
}) {
- const redirectPath = [searchParams.redirect].flat().pop() || '/';
- if (!redirectPath.match(/^\/[a-z/]*$/)) {
+ const [redirect, setRedirect] = useState();
+
+ useEffect(() => {
+ return Hub.listen('auth', ({ payload }) => {
+ switch (payload.event) {
+ case 'customOAuthState':
+ try {
+ const { redirectPath } = JSON.parse(payload.data);
+ setRedirect(redirectPath);
+ } catch (err) {
+ console.error(err);
+ setRedirect('Invalid redirect path');
+ }
+ break;
+ }
+ });
+ }, []);
+
+ let redirectPath = redirect || [searchParams.redirect].flat().pop() || '/';
+ if (redirectPath === '/auth') redirectPath = '/';
+ if (redirectPath && !redirectPath.match(/^\/[a-z/]*$/)) {
return Invalid redirect path
;
}
- return <>
-
- >
+ return
}
diff --git a/app/signout/page.tsx b/app/signout/page.tsx
new file mode 100644
index 0000000..b13f2b8
--- /dev/null
+++ b/app/signout/page.tsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import { AuthGetCurrentUserServer } from '../../utils/amplify-utils';
+import Logout from '../../components/Logout';
+import { redirect } from 'next/navigation';
+
+export default async function Page() {
+
+ const { currentUser, attributes } = await AuthGetCurrentUserServer() ?? {};
+ if (!currentUser) {
+ redirect('/');
+ }
+
+ return <>
+ Sign out
+ You are currently logged in as {attributes?.email}
+
+ >
+}
diff --git a/app/status/page.tsx b/app/status/page.tsx
index 728fef1..d148c51 100644
--- a/app/status/page.tsx
+++ b/app/status/page.tsx
@@ -5,12 +5,7 @@ export default async function Page({ searchParams }: {
searchParams: { [key: string]: string | string[] | undefined }
}) {
- // Client side user lookup
- // const { user, signOut } = useAuthenticator((context) => [context.user]);
-
- // Server side lookup
const { currentUser, attributes } = await AuthGetCurrentUserServer() ?? {};
-
const redirectPath = [searchParams.redirect].flat().pop() || '/';
return <>
diff --git a/app/styles.css b/app/styles.css
index 73008d4..e7263db 100644
--- a/app/styles.css
+++ b/app/styles.css
@@ -2,3 +2,12 @@
flex-grow: 100;
text-align: right;
}
+
+div.nhsuk-header__content > li.nhsuk-header__navigation-item {
+ list-style: none;
+}
+
+div.nhsuk-header__content > li.nhsuk-header__navigation-item > a {
+ padding: 0;
+ display: inline-block;
+}
diff --git a/components/Login.tsx b/components/Login.tsx
new file mode 100644
index 0000000..aa16dfc
--- /dev/null
+++ b/components/Login.tsx
@@ -0,0 +1,75 @@
+'use client';
+
+import { Heading, useTheme, withAuthenticator } from '@aws-amplify/ui-react';
+import { AuthUser } from 'aws-amplify/auth';
+import React, { useEffect } from 'react';
+import { Amplify } from 'aws-amplify';
+import { signInWithRedirect } from '@aws-amplify/auth';
+import { Button } from 'nhsuk-react-components';
+import {
+ DefaultComponents
+} from '@aws-amplify/ui-react/dist/types/components/Authenticator/hooks/useCustomComponents/defaultComponents';
+
+function auth0Login(redirectPath: string) {
+ console.log(Amplify.getConfig());
+ signInWithRedirect({
+ provider: {
+ custom: 'Auth0'
+ },
+ customState: JSON.stringify({ redirectPath })
+ }).catch(console.error);
+}
+
+function components(redirectPath: string): DefaultComponents {
+ return {
+
+ SignIn: {
+ Header() {
+ const { tokens } = useTheme();
+
+ return (<>
+
+ Sign in to your account
+
+
+
+
+
+ or
+
+ >
+ );
+ }
+ }
+ }
+};
+
+function Login({ user, redirectPath }: { user?: AuthUser, redirectPath?: string }) {
+ useEffect(() => {
+ if (user && redirectPath) {
+ location.href = redirectPath;
+ }
+ }, [user, redirectPath]);
+ if (redirectPath && user) {
+ return ;
+ }
+ return null;
+}
+
+export default (props: { redirectPath?: string; user?: AuthUser }) => {
+ const { redirectPath } = props;
+ return withAuthenticator(Login, {
+ variation: 'default',
+ hideSignUp: true,
+ components: components(redirectPath || '/')
+ })(props);
+};
diff --git a/components/LoginStatus.tsx b/components/LoginStatus.tsx
new file mode 100644
index 0000000..771ec0f
--- /dev/null
+++ b/components/LoginStatus.tsx
@@ -0,0 +1,21 @@
+'use client';
+
+import { Header } from 'nhsuk-react-components';
+import React from 'react';
+import { useAuthenticator } from '@aws-amplify/ui-react';
+
+export default function LoginStatus() {
+ const { authStatus } = useAuthenticator();
+ switch (authStatus) {
+ case 'authenticated':
+ return
+ Sign out
+ ;
+ case 'unauthenticated':
+ return
+ Sign in
+ ;
+ default:
+ return null;
+ }
+}
diff --git a/components/Logout.tsx b/components/Logout.tsx
index 076a079..d8ec1d6 100644
--- a/components/Logout.tsx
+++ b/components/Logout.tsx
@@ -1,23 +1,15 @@
'use client';
-import { useRouter } from 'next/navigation';
import { useAuthenticator } from '@aws-amplify/ui-react';
+import { Button } from 'nhsuk-react-components';
export default function Logout() {
- const router = useRouter();
- const { user, signOut } = useAuthenticator();
+ const { authStatus, signOut } = useAuthenticator();
async function handleSignOut() {
signOut();
location.href = '/';
}
- return user ? (
-
- ) : [];
+ return ;
}
diff --git a/components/Redirect.tsx b/components/Redirect.tsx
deleted file mode 100644
index 45ecf06..0000000
--- a/components/Redirect.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-'use client';
-
-import React, { useEffect } from 'react';
-
-/**
- * Client-side redirect triggered on component load
- *
- * This is a workaround for server-side redirect not working after client-side login via Authenticator component
- *
- * @param path
- * @constructor
- */
-export default function Redirect({ path }: { path: string }) {
- useEffect(() => {
- location.href = path;
- }, [path]);
- return <>
- Redirecting to {path}
- >
-}