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

feat: add option to use "Pay without pay" and show error in cases of undefined fee #2284

Merged
merged 5 commits into from
Oct 9, 2023
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
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
Loading