From c9d59398c141dd459a08c0f18aa713667b852b7d Mon Sep 17 00:00:00 2001 From: Jessica McInchak Date: Thu, 22 Aug 2024 11:13:17 +0200 Subject: [PATCH 1/9] chore: update Confirmation banner description to use rich text & reword details (#3545) --- .../Confirmation/Confirmation.stories.tsx | 10 +- .../@planx/components/Confirmation/Editor.tsx | 12 +- .../components/Confirmation/Public.test.tsx | 2 +- .../@planx/components/Confirmation/Public.tsx | 112 +++++++++++++----- .../@planx/components/Confirmation/model.ts | 1 - editor.planx.uk/src/pages/Preview/Node.tsx | 56 ++------- 6 files changed, 103 insertions(+), 90 deletions(-) diff --git a/editor.planx.uk/src/@planx/components/Confirmation/Confirmation.stories.tsx b/editor.planx.uk/src/@planx/components/Confirmation/Confirmation.stories.tsx index 0f6491de86..4cd47a1676 100644 --- a/editor.planx.uk/src/@planx/components/Confirmation/Confirmation.stories.tsx +++ b/editor.planx.uk/src/@planx/components/Confirmation/Confirmation.stories.tsx @@ -3,12 +3,12 @@ import React from "react"; import Wrapper from "../fixtures/Wrapper"; import Editor from "./Editor"; -import Confirmation from "./Public"; +import Confirmation, { Presentational } from "./Public"; const meta = { title: "PlanX Components/Confirmation", - component: Confirmation, -} satisfies Meta; + component: Presentational, +} satisfies Meta; export default meta; @@ -20,7 +20,8 @@ export const Basic = { description: `A payment receipt has been emailed to you. You will also receive an email to confirm when your application has been received.`, color: { background: "rgba(1, 99, 96, 0.1)", text: "#000" }, - details: { + sessionId: "123-t3st-456", + applicableDetails: { "Planning Application Reference": "LBL–LDCP-2138261", "Property Address": "45, Greenfield Road, London SE22 7FF", "Application type": @@ -48,6 +49,7 @@ export const Basic = {

What did you think of this service? Please give us your feedback using the link in the footer below. `, + data: [], }, } satisfies Story; diff --git a/editor.planx.uk/src/@planx/components/Confirmation/Editor.tsx b/editor.planx.uk/src/@planx/components/Confirmation/Editor.tsx index 099361c90f..d2159d3049 100644 --- a/editor.planx.uk/src/@planx/components/Confirmation/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Confirmation/Editor.tsx @@ -16,7 +16,7 @@ import { Confirmation, parseNextSteps, Step } from "./model"; export type Props = EditorProps; -function StepEditor(props: ListManagerEditorProps) { +function NextStepEditor(props: ListManagerEditorProps) { return ( @@ -55,10 +55,14 @@ export default function ConfirmationEditor(props: Props) { const type = TYPES.Confirmation; const formik = useFormik({ initialValues: { + color: props.node?.color || { + text: "#000", + background: "rgba(1, 99, 96, 0.1)", + }, heading: props.node?.data?.heading || "Application sent", description: props.node?.data?.description || - `A payment receipt has been emailed to you. You will also receive an email to confirm when your application has been received.`, + `

A payment receipt has been emailed to you. You will also receive an email to confirm when your application has been received.

`, moreInfo: props.node?.data?.moreInfo || `

You will be contacted

@@ -95,7 +99,7 @@ export default function ConfirmationEditor(props: Props) { />
- { formik.setFieldValue("nextSteps", steps); }} - Editor={StepEditor} + Editor={NextStepEditor} newValue={() => ({ title: "", description: "" })} /> diff --git a/editor.planx.uk/src/@planx/components/Confirmation/Public.test.tsx b/editor.planx.uk/src/@planx/components/Confirmation/Public.test.tsx index 5c29b2f68d..b2ac15c6b1 100644 --- a/editor.planx.uk/src/@planx/components/Confirmation/Public.test.tsx +++ b/editor.planx.uk/src/@planx/components/Confirmation/Public.test.tsx @@ -16,9 +16,9 @@ jest.mock("@opensystemslab/planx-core", () => { it("should not have any accessibility violations", async () => { const { container } = setup( ; export default function ConfirmationComponent(props: Props) { const [data, setData] = useState([]); - const [sessionId, saveToEmail, $public] = useStore((state) => [ - state.sessionId, - state.saveToEmail, - state.$public, - ]); + const [sessionId, saveToEmail, $public, passport, govUkPayment, flowName] = + useStore((state) => [ + state.sessionId, + state.saveToEmail, + state.$public, + state.computePassport(), + state.govUkPayment, + state.flowName, + ]); + + const details = { + "Application reference": sessionId, + "Property address": passport.data?._address?.title, + "Application type": [ + flowName.replace("Apply", "Application"), + getWorkStatus(passport), + ] + .filter(Boolean) + .join(" - "), + "GOV.UK payment reference": govUkPayment?.payment_id, + "Paid at": + govUkPayment?.created_date && + new Date(govUkPayment.created_date).toLocaleDateString("en-gb", { + day: "numeric", + month: "long", + year: "numeric", + }), + }; + const applicableDetails = objectWithoutNullishValues(details) as Record< + string, + string + >; useEffect(() => { const makeCsvData = async () => { @@ -40,6 +68,23 @@ export default function ConfirmationComponent(props: Props) { } }); + return ( + + ); +} + +interface PresentationalProps extends Props { + sessionId: string; + applicableDetails: Record; + data: QuestionAndResponses[]; +} + +export function Presentational(props: PresentationalProps) { return ( {props.description && ( - - {props.description} + + )} - {props.details && ( - - {Object.entries(props.details).map((item) => ( - <> - {item[0]} - {item[1]} - - ))} - - )} - - {} - + + {Object.entries(props.applicableDetails).map(([k, v], i) => ( + + {k} + {v} + + ))} + + {props.nextSteps && Boolean(props.nextSteps?.length) && ( @@ -76,7 +120,6 @@ export default function ConfirmationComponent(props: Props) { )} - {props.moreInfo && ( <> @@ -85,18 +128,25 @@ export default function ConfirmationComponent(props: Props) {
)} - {props.contactInfo && ( - <> - - - Contact us - - - - + + + Contact us + + + )}
); } + +// TODO - Retire in favor of ODP Schema application type descriptions or fallback to flowName +function getWorkStatus(passport: Store.passport): string | undefined { + switch (passport?.data?.["application.type"]?.toString()) { + case "ldc.existing": + return "existing"; + case "ldc.proposed": + return "proposed"; + } +} diff --git a/editor.planx.uk/src/@planx/components/Confirmation/model.ts b/editor.planx.uk/src/@planx/components/Confirmation/model.ts index ea060cf3bd..3622f1f23b 100644 --- a/editor.planx.uk/src/@planx/components/Confirmation/model.ts +++ b/editor.planx.uk/src/@planx/components/Confirmation/model.ts @@ -7,7 +7,6 @@ export interface Confirmation { heading?: string; description?: string; color?: { text: string; background: string }; - details?: { [key: string]: string }; nextSteps?: Step[]; moreInfo?: string; contactInfo?: string; diff --git a/editor.planx.uk/src/pages/Preview/Node.tsx b/editor.planx.uk/src/pages/Preview/Node.tsx index c31b5d8d08..73d43e3b47 100644 --- a/editor.planx.uk/src/pages/Preview/Node.tsx +++ b/editor.planx.uk/src/pages/Preview/Node.tsx @@ -1,9 +1,7 @@ import { + ComponentType as TYPES, DEFAULT_FLAG_CATEGORY, - GOV_PAY_PASSPORT_KEY, - GovUKPayment, } from "@opensystemslab/planx-core/types"; -import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; import AddressInput from "@planx/components/AddressInput/Public"; import Calculate from "@planx/components/Calculate/Public"; import Checklist from "@planx/components/Checklist/Public"; @@ -31,7 +29,6 @@ import Send from "@planx/components/Send/Public"; import SetValue from "@planx/components/SetValue/Public"; import TaskList from "@planx/components/TaskList/Public"; import TextInput from "@planx/components/TextInput/Public"; -import { objectWithoutNullishValues } from "lib/objectHelpers"; import mapAccum from "ramda/src/mapAccum"; import React from "react"; @@ -87,6 +84,7 @@ const Node: React.FC = (props: Props) => { switch (props.node.type) { case TYPES.Calculate: return ; + case TYPES.Checklist: { const childNodes = childNodesOf(props.node.id); return ( @@ -114,43 +112,10 @@ const Node: React.FC = (props: Props) => { /> ); } - case TYPES.Confirmation: { - const payment: GovUKPayment | undefined = - passport.data?.[GOV_PAY_PASSPORT_KEY]; - - const details = { - "Planning application reference": payment?.reference ?? sessionId, - - "Property address": passport.data?._address?.title, - - "Application type": [ - flowName.replace("Apply", "Application"), - getWorkStatus(passport), - ] - .filter(Boolean) - .join(" - "), - - // XXX: If there is no payment we can't alternatively show Date.now() because it - // will change after page refresh. BOPS submission time needs to be queryable. - Submitted: payment?.created_date - ? new Date(payment.created_date).toLocaleDateString("en-gb", { - day: "numeric", - month: "long", - year: "numeric", - }) - : undefined, - - "GOV.UK Payment reference": payment?.payment_id, - }; - return ( - - ); - } + case TYPES.Confirmation: + return ; + case TYPES.Content: return ; @@ -209,6 +174,7 @@ const Node: React.FC = (props: Props) => { /> ); } + case TYPES.Review: return ; @@ -267,6 +233,7 @@ const Node: React.FC = (props: Props) => { case TYPES.Answer: case undefined: return null; + default: console.error({ nodeNotFound: props }); return exhaustiveCheck(props.node.type); @@ -277,13 +244,4 @@ function exhaustiveCheck(type: never): never { throw new Error(`Missing type ${type}`); } -function getWorkStatus(passport: Store.passport): string | undefined { - switch (passport?.data?.["application.type"]?.toString()) { - case "ldc.existing": - return "existing"; - case "ldc.proposed": - return "proposed"; - } -} - export default Node; From 900e30b121fb0d8241fb93338945d94f9fdf0122 Mon Sep 17 00:00:00 2001 From: Rory Doak <138574807+RODO94@users.noreply.github.com> Date: Thu, 22 Aug 2024 11:58:22 +0100 Subject: [PATCH 2/9] refactor: Alter layout and copy of Feedback component in Footer (#3542) --- .../src/components/Feedback/FeedbackForm.tsx | 21 +++++++++++++++++-- .../src/components/Feedback/index.test.tsx | 12 ++++++----- .../src/components/Feedback/index.tsx | 4 ++-- .../src/ui/public/FeedbackDisclaimer.tsx | 20 +++++------------- 4 files changed, 33 insertions(+), 24 deletions(-) diff --git a/editor.planx.uk/src/components/Feedback/FeedbackForm.tsx b/editor.planx.uk/src/components/Feedback/FeedbackForm.tsx index f374b36b60..63fb6408f7 100644 --- a/editor.planx.uk/src/components/Feedback/FeedbackForm.tsx +++ b/editor.planx.uk/src/components/Feedback/FeedbackForm.tsx @@ -7,8 +7,8 @@ import FeedbackDisclaimer from "ui/public/FeedbackDisclaimer"; import InputLabel from "ui/public/InputLabel"; import ErrorWrapper from "ui/shared/ErrorWrapper"; import Input from "ui/shared/Input"; - import { FeedbackFormInput, FormProps, UserFeedback } from "."; +import Link from "@mui/material/Link"; const StyledForm = styled(Form)(({ theme }) => ({ "& > *": contentFlowSpacing(theme), @@ -52,8 +52,25 @@ const FeedbackForm: React.FC = ({ inputs, handleSubmit }) => { return ( + + Do not share personal or financial information in your feedback. If + you do we’ll act according to our{" "} + + privacy policy + + . + - + + This information is not monitored frequently by planning officers, do + not use it to provide extra information or queries with regard to your + application or project. Any information of this nature will be + disregarded. +