Skip to content

Commit

Permalink
feat: add option to use "Pay without pay" and show error in cases of …
Browse files Browse the repository at this point in the history
…undefined fee (#2284)
  • Loading branch information
jessicamcinchak authored Oct 9, 2023
1 parent 2ce327e commit 380f27e
Show file tree
Hide file tree
Showing 6 changed files with 310 additions and 98 deletions.
39 changes: 25 additions & 14 deletions editor.planx.uk/src/@planx/components/Pay/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ function Component(props: any) {
`<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 ||
Expand Down Expand Up @@ -113,20 +114,30 @@ function Component(props: any) {
/>
</InputRow>
</ModalSectionContent>
<ModalSectionContent>
<InputRow>
<OptionButton
selected={formik.values.allowInviteToPay}
onClick={() => {
formik.setFieldValue(
"allowInviteToPay",
!formik.values.allowInviteToPay,
);
}}
>
Allow applicants to invite someone else to pay
</OptionButton>
</InputRow>
<OptionButton
selected={formik.values.hidePay}
onClick={() => {
formik.setFieldValue("hidePay", !formik.values.hidePay);
}}
style={{ width: "100%" }}
>
Hide the pay buttons and show fee for information only
</OptionButton>
</ModalSection>
<ModalSection>
<ModalSectionContent title="Invite to Pay" Icon={ICONS[TYPES.Pay]}>
<OptionButton
selected={formik.values.allowInviteToPay}
onClick={() => {
formik.setFieldValue(
"allowInviteToPay",
!formik.values.allowInviteToPay,
);
}}
style={{ width: "100%" }}
>
Allow applicants to invite someone else to pay
</OptionButton>
{formik.values.allowInviteToPay ? (
<>
<Box>
Expand Down
120 changes: 70 additions & 50 deletions editor.planx.uk/src/@planx/components/Pay/Public/Confirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import ReactMarkdownOrHtml from "ui/ReactMarkdownOrHtml";

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

export interface Props {
title?: string;
Expand All @@ -35,6 +36,7 @@ export interface Props {
onConfirm: () => void;
error?: string;
hideFeeBanner?: boolean;
hidePay?: boolean;
}

interface PayBodyProps extends Props {
Expand All @@ -60,53 +62,9 @@ const PayBody: React.FC<PayBodyProps> = (props) => {
const path = useStore((state) => state.path);
const isSaveReturn = path === ApplicationPath.SaveAndReturn;

return (
<>
{!props.error ? (
<Card>
<PayText>
<Typography
variant="h2"
component={props.hideFeeBanner ? "h2" : "h3"}
>
{props.instructionsTitle || "How to pay"}
</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>`
}
openLinksOnNewTab
/>
<Button
variant="contained"
color="primary"
size="large"
onClick={props.onConfirm}
>
{props.buttonTitle || "Pay now using GOV.UK Pay"}
</Button>
{props.showInviteToPay && (
<>
<Button
variant="contained"
color="secondary"
style={{ borderBottom: `solid 2px lightgrey` }}
size="large"
onClick={props.changePage}
disabled={Boolean(props?.paymentStatus)}
data-testid="invite-page-link"
>
{"Invite someone else to pay for this application"}
</Button>
</>
)}
{isSaveReturn && <SaveResumeButton />}
</PayText>
</Card>
) : (
if (props.error) {
if (props.error.startsWith(PAY_API_ERROR_UNSUPPORTED_TEAM)) {
return (
<Card handleSubmit={props.onConfirm} isValid>
<ErrorSummary role="status" data-testid="error-summary">
<Typography variant="h4" component="h3" gutterBottom>
Expand All @@ -118,8 +76,68 @@ const PayBody: React.FC<PayBodyProps> = (props) => {
</Typography>
</ErrorSummary>
</Card>
)}
</>
);
} else {
return (
<Card>
<ErrorSummary role="status" data-testid="error-summary">
<Typography variant="h4" component="h3" gutterBottom>
{props.error}
</Typography>
<Typography variant="body2">
This error has been logged and our team will see it soon. You can
safely close this tab and try resuming again soon by returning to
this URL.
</Typography>
</ErrorSummary>
</Card>
);
}
}

return (
<Card>
<PayText>
<Typography variant="h2" component={props.hideFeeBanner ? "h2" : "h3"}>
{props.instructionsTitle || "How to pay"}
</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>`
}
openLinksOnNewTab
/>
<Button
variant="contained"
color="primary"
size="large"
onClick={props.onConfirm}
>
{props.hidePay
? "Continue"
: props.buttonTitle || "Pay now using GOV.UK Pay"}
</Button>
{!props.hidePay && props.showInviteToPay && (
<>
<Button
variant="contained"
color="secondary"
style={{ borderBottom: `solid 2px lightgrey` }}
size="large"
onClick={props.changePage}
disabled={Boolean(props?.paymentStatus)}
data-testid="invite-page-link"
>
{"Invite someone else to pay for this application"}
</Button>
</>
)}
{isSaveReturn && <SaveResumeButton />}
</PayText>
</Card>
);
};

Expand Down Expand Up @@ -176,7 +194,9 @@ export default function Confirm(props: Props) {
className="marginBottom"
component="span"
>
{formattedPriceWithCurrencySymbol(props.fee)}
{isNaN(props.fee)
? "Unknown"
: formattedPriceWithCurrencySymbol(props.fee)}
</Typography>
<Typography variant="subtitle1" component="span" color="inherit">
<ReactMarkdownOrHtml
Expand Down
14 changes: 14 additions & 0 deletions editor.planx.uk/src/@planx/components/Pay/Public/Pay.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,17 @@ export const WithInviteToPay = {
yourDetailsLabel: "Your name or organisation name",
},
} satisfies Story;

export const ForInformationOnly = {
args: {
title: "What you can expect to pay for your application",
bannerTitle: "The calculated fee is",
description:
"Based on your answers so far, this is the fee that we've calculated. The fee will cover the cost of processing your application.",
instructionsTitle: "How to pay",
instructionsDescription:
"Payments will be accepted for your future application via GOV.UK Pay. You will have the option to pay yourself or invite someone else to pay.",
fee: 103,
hidePay: true,
},
} satisfies Story;
Loading

0 comments on commit 380f27e

Please sign in to comment.