Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Move Pay default values to model #3993

Merged
merged 2 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
50 changes: 2 additions & 48 deletions editor.planx.uk/src/@planx/components/Pay/Editor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import {
ComponentType as TYPES,
} from "@opensystemslab/planx-core/types";
import {
parsePay,
Pay,
validationSchema,
} from "@planx/components/Pay/model";
import { parseBaseNodeData } from "@planx/components/shared";
import { Form, Formik } from "formik";
import { useStore } from "pages/FlowEditor/lib/store";
import React from "react";
import { ComponentTagSelect } from "ui/editor/ComponentTagSelect";
import { InternalNotes } from "ui/editor/InternalNotes";
Expand All @@ -27,51 +26,6 @@ import { InviteToPaySection } from "./InviteToPaySection";
export type Props = EditorProps<TYPES.Pay, Pay>;

const Component: React.FC<Props> = (props: Props) => {
const [flowName] = useStore((store) => [store.flowName]);
const initialValues: Pay = {
title: props.node?.data?.title || "Pay for your application",
bannerTitle:
props.node?.data?.bannerTitle ||
"The planning fee for this application is",
description:
props.node?.data?.description ||
`<p>The planning fee covers the cost of processing your application.\
<a href="https://www.gov.uk/guidance/fees-for-planning-applications" target="_self">Find out more about how planning fees are calculated</a> (opens in new tab).</p>`,
fn: props.node?.data?.fn,
instructionsTitle: props.node?.data?.instructionsTitle || "How to pay",
instructionsDescription:
props.node?.data?.instructionsDescription ||
`<p>You can pay for your application by using GOV.UK Pay.</p>\
<p>Your application will be sent after you have paid the fee. \
Wait until you see an application sent message before closing your browser.</p>`,
hidePay: props.node?.data?.hidePay || false,
allowInviteToPay: props.node?.data?.allowInviteToPay ?? true,
secondaryPageTitle:
props.node?.data?.secondaryPageTitle ||
"Invite someone else to pay for this application",
nomineeTitle:
props.node?.data?.nomineeTitle || "Details of the person paying",
nomineeDescription: props.node?.data?.nomineeDescription,
yourDetailsTitle: props.node?.data?.yourDetailsTitle || "Your details",
yourDetailsDescription: props.node?.data?.yourDetailsDescription,
yourDetailsLabel:
props.node?.data?.yourDetailsLabel || "Your name or organisation name",
govPayMetadata: props.node?.data?.govPayMetadata || [
{
key: "flow",
value: flowName,
},
{
key: "source",
value: "PlanX",
},
{
key: "paidViaInviteToPay",
value: "@paidViaInviteToPay",
},
],
...parseBaseNodeData(props.node?.data),
};

const onSubmit = (newValues: Pay) => {
if (props.handleSubmit) {
Expand All @@ -81,7 +35,7 @@ const Component: React.FC<Props> = (props: Props) => {

return (
<Formik<Pay>
initialValues={initialValues}
initialValues={parsePay(props.node?.data)}
onSubmit={onSubmit}
validationSchema={validationSchema}
validateOnChange={true}
Expand Down
15 changes: 7 additions & 8 deletions editor.planx.uk/src/@planx/components/Pay/Public/Confirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import FormWrapper from "ui/public/FormWrapper";
import ErrorSummary from "ui/shared/ErrorSummary/ErrorSummary";
import ReactMarkdownOrHtml from "ui/shared/ReactMarkdownOrHtml/ReactMarkdownOrHtml";

import { formattedPriceWithCurrencySymbol } from "../model";
import { formattedPriceWithCurrencySymbol, getDefaultContent } from "../model";
import InviteToPayForm, { InviteToPayFormProps } from "./InviteToPayForm";
import { PAY_API_ERROR_UNSUPPORTED_TEAM } from "./Pay";

Expand Down Expand Up @@ -56,6 +56,7 @@ const PayText = styled(Box)(({ theme }) => ({
const PayBody: React.FC<PayBodyProps> = (props) => {
const path = useStore((state) => state.path);
const isSaveReturn = path === ApplicationPath.SaveAndReturn;
const defaults = getDefaultContent();

if (props.error) {
if (props.error.startsWith(PAY_API_ERROR_UNSUPPORTED_TEAM)) {
Expand Down Expand Up @@ -85,14 +86,11 @@ const PayBody: React.FC<PayBodyProps> = (props) => {
<Card>
<PayText>
<Typography variant="h2" component={props.hideFeeBanner ? "h2" : "h3"}>
{props.instructionsTitle || "How to pay"}
{props.instructionsTitle || defaults.instructionsTitle }
</Typography>
<ReactMarkdownOrHtml
source={
props.instructionsDescription ||
`<p>You can pay for your application by using GOV.UK Pay.</p>\
<p>Your application will be sent after you have paid the fee. \
Wait until you see an application sent message before closing your browser.</p>`
props.instructionsDescription || defaults.instructionsDescription
}
openLinksOnNewTab
/>
Expand Down Expand Up @@ -128,6 +126,8 @@ export default function Confirm(props: Props) {
const theme = useTheme();
const [page, setPage] = useState<"Pay" | "InviteToPay">("Pay");

const defaults = getDefaultContent();

const changePage = () => {
if (page === "Pay" && !props.paymentStatus) {
setPage("InviteToPay");
Expand Down Expand Up @@ -168,8 +168,7 @@ export default function Confirm(props: Props) {
className="marginBottom"
component="h2"
>
{props.bannerTitle ||
"The planning fee for this application is"}
{props.bannerTitle || defaults.bannerTitle}
</Typography>
<Typography
variant="h1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import ErrorWrapper from "ui/shared/ErrorWrapper";
import Input from "ui/shared/Input/Input";
import ReactMarkdownOrHtml from "ui/shared/ReactMarkdownOrHtml/ReactMarkdownOrHtml";
import { object, string } from "yup";
import { getDefaultContent } from "../model";

// Passport keys which will be used to display a preview of the session to the payee as part of their journey
const SESSION_PREVIEW_KEYS = [["_address", "title"], ["proposal.projectType"]];
Expand Down Expand Up @@ -95,6 +96,8 @@ const InviteToPayForm: React.FC<InviteToPayFormProps> = ({
data: { mountpath },
} = useCurrentRoute();

const defaults = getDefaultContent();

// Scroll to top when loading component
useEffect(() => {
window.scrollTo(0, 0);
Expand Down Expand Up @@ -226,7 +229,7 @@ const InviteToPayForm: React.FC<InviteToPayFormProps> = ({
/>
</Typography>
)}
<InputLabel label={yourDetailsLabel || ""} htmlFor="applicantName">
<InputLabel label={yourDetailsLabel || defaults.yourDetailsLabel } htmlFor="applicantName">
<Input
bordered
name="applicantName"
Expand Down
8 changes: 2 additions & 6 deletions editor.planx.uk/src/@planx/components/Pay/Public/Pay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { useErrorHandler } from "react-error-boundary";
import type { Session } from "types";

import { makeData } from "../../shared/utils";
import { createPayload, GOV_UK_PAY_URL, Pay, toDecimal } from "../model";
import { createPayload, getDefaultContent, GOV_UK_PAY_URL, Pay, toDecimal } from "../model";
import Confirm from "./Confirm";

export default Component;
Expand Down Expand Up @@ -67,11 +67,7 @@ function Component(props: Props) {
]);
const fee = props.fn ? Number(passport.data?.[props.fn]) : 0;

const defaultMetadata = [
{ key: "source", value: "PlanX" },
{ key: "flow", value: flowSlug },
{ key: "paidViaInviteToPay", value: "@paidViaInviteToPay" },
];
const defaultMetadata = getDefaultContent().govPayMetadata;

const metadata = [...(props.govPayMetadata || []), ...defaultMetadata];

Expand Down
40 changes: 39 additions & 1 deletion editor.planx.uk/src/@planx/components/Pay/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useStore } from "pages/FlowEditor/lib/store";
import { ApplicationPath, Passport } from "types";
import { array, boolean, object, string } from "yup";

import type { BaseNodeData } from "../shared";
import { parseBaseNodeData, type BaseNodeData } from "../shared";

export interface Pay extends BaseNodeData {
title: string;
Expand Down Expand Up @@ -164,3 +164,41 @@ export const validationSchema = object({
}),
govPayMetadata: govPayMetadataSchema,
});

export const getDefaultContent = (): Pay => ({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be a function so that useStore.getState().flowName is called when the component mounts and we have a flowName.

title: "Pay for your application",
bannerTitle: "The planning fee for this application is",
fn: "application.fee.payable",
description: `<p>The planning fee covers the cost of processing your application.\
<a href="https://www.gov.uk/guidance/fees-for-planning-applications" target="_self">Find out more about how planning fees are calculated</a> (opens in new tab).</p>`,
instructionsTitle: "How to pay",
instructionsDescription: `<p>You can pay for your application by using GOV.UK Pay.</p>\
<p>Your application will be sent after you have paid the fee. \
Wait until you see an application sent message before closing your browser.</p>`,
hidePay: false,
allowInviteToPay: true,
secondaryPageTitle: "Invite someone else to pay for this application",
nomineeTitle: "Details of the person paying",
yourDetailsTitle: "Your details",
yourDetailsLabel: "Your name or organisation name",
govPayMetadata: [
{
key: "flow",
value: useStore.getState().flowName,
},
{
key: "source",
value: "PlanX",
},
{
key: "paidViaInviteToPay",
value: "@paidViaInviteToPay",
},
],
});

export const parsePay = (data?: Record<string, any>): Pay => ({
...parseBaseNodeData(data),
...getDefaultContent(),
...data,
});
Loading