Skip to content

Commit d6d5ed2

Browse files
authored
Merge pull request #54 from commonknowledge/bug-fixes
Bug fixes
2 parents c8e35d0 + 6612403 commit d6d5ed2

10 files changed

Lines changed: 111 additions & 32 deletions

File tree

packages/join-block/join.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/**
44
* Plugin Name: Common Knowledge Join Flow
55
* Description: Common Knowledge join flow plugin.
6-
* Version: 1.3.11
6+
* Version: 1.3.12
77
* Author: Common Knowledge <hello@commonknowledge.coop>
88
* Text Domain: common-knowledge-join-flow
99
* License: GPLv2 or later

packages/join-block/readme.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Tags: membership, subscription, join
44
Contributors: commonknowledgecoop
55
Requires at least: 5.4
66
Tested up to: 6.8
7-
Stable tag: 1.3.11
7+
Stable tag: 1.3.12
88
Requires PHP: 8.1
99
License: GPLv2 or later
1010
License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -107,6 +107,13 @@ Need help? Contact us at [hello@commonknowledge.coop](mailto:hello@commonknowled
107107

108108
== Changelog ==
109109

110+
= 1.3.12 =
111+
* Hide price display for zero-price membership tiers (global setting)
112+
* Block-level option to completely hide address section
113+
* Customisable sidebar heading (global + per-block override)
114+
* Customisable membership stage label (global + per-block override)
115+
* Customisable loading spinner verb (global + per-block override)
116+
* All new text customizations include sensible fallback defaults for backwards compatibility
110117
= 1.3.11 =
111118
* Fix bug with display of Direct Debit information when we have a zero priced tier.
112119
= 1.3.10 =

packages/join-block/src/Blocks.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ private static function registerJoinFormBlock()
175175
Field::make('separator', 'ck_join_form', 'CK Join Form'),
176176
$joined_page_association,
177177
Field::make('checkbox', 'require_address')->set_default_value(true),
178+
Field::make('checkbox', 'hide_address')
179+
->set_help_text('Check to completely hide the address section from the form.'),
178180
Field::make('checkbox', 'require_phone_number')->set_default_value(true),
179181
Field::make('checkbox', 'ask_for_additional_donation'),
180182
Field::make('checkbox', 'hide_home_address_copy')
@@ -194,6 +196,12 @@ private static function registerJoinFormBlock()
194196
$custom_membership_plans,
195197
Field::make('text', 'custom_webhook_url')
196198
->set_help_text('Leave blank to use the default Join Complete webhook from the settings page.'),
199+
Field::make('text', 'custom_sidebar_heading')
200+
->set_help_text('Leave blank to use the default from settings page.'),
201+
Field::make('text', 'custom_membership_stage_label')
202+
->set_help_text('Leave blank to use the default from settings page.'),
203+
Field::make('text', 'custom_joining_verb')
204+
->set_help_text('Leave blank to use the default from settings page (e.g., "Joining").'),
197205

198206
));
199207
$join_form_block->set_render_callback(function ($fields, $attributes, $inner_blocks) {
@@ -431,6 +439,33 @@ function ($o) {
431439
return $field;
432440
}, $fields['custom_fields'] ?? []);
433441

442+
// Determine sidebar heading
443+
$sidebar_heading = $fields['custom_sidebar_heading'] ?? '';
444+
if (!$sidebar_heading) {
445+
$sidebar_heading = Settings::get("JOIN_FORM_SIDEBAR_HEADING");
446+
}
447+
if (!$sidebar_heading) {
448+
$sidebar_heading = "Join Us";
449+
}
450+
451+
// Determine membership stage label
452+
$membership_stage_label = $fields['custom_membership_stage_label'] ?? '';
453+
if (!$membership_stage_label) {
454+
$membership_stage_label = Settings::get("MEMBERSHIP_STAGE_LABEL");
455+
}
456+
if (!$membership_stage_label) {
457+
$membership_stage_label = "Your Membership";
458+
}
459+
460+
// Determine joining verb
461+
$joining_verb = $fields['custom_joining_verb'] ?? '';
462+
if (!$joining_verb) {
463+
$joining_verb = Settings::get("JOINING_VERB");
464+
}
465+
if (!$joining_verb) {
466+
$joining_verb = "Joining";
467+
}
468+
434469
$environment = [
435470
'HOME_URL' => $homeUrl,
436471
"WP_REST_API" => get_rest_url(),
@@ -455,20 +490,25 @@ function ($o) {
455490
"HEAR_ABOUT_US_DETAILS" => Settings::get("HEAR_ABOUT_US_DETAILS"),
456491
"HEAR_ABOUT_US_HEADING" => Settings::get("HEAR_ABOUT_US_HEADING"),
457492
"HEAR_ABOUT_US_OPTIONS" => $hearAboutUsOptions,
493+
"HIDE_ZERO_PRICE_DISPLAY" => Settings::get("HIDE_ZERO_PRICE_DISPLAY"),
458494
"HOME_ADDRESS_COPY" => wpautop(Settings::get("HOME_ADDRESS_COPY")),
459495
"MEMBERSHIP_TIERS_HEADING" => Settings::get("MEMBERSHIP_TIERS_HEADING"),
460496
"MEMBERSHIP_TIERS_COPY" => wpautop(Settings::get("MEMBERSHIP_TIERS_COPY")),
461497
"MINIMAL_JOIN_FORM" => $block_mode === self::MINIMAL_BLOCK_MODE,
462498
"IS_UPDATE_FLOW" => $fields['is_update_flow'] ?? false,
463499
"INCLUDE_SKIP_PAYMENT_BUTTON" => $fields['include_skip_payment_button'] ?? false,
500+
"JOIN_FORM_SIDEBAR_HEADING" => $sidebar_heading,
501+
"JOINING_VERB" => $joining_verb,
464502
"MEMBERSHIP_PLANS" => $membership_plans_prepared,
503+
"MEMBERSHIP_STAGE_LABEL" => $membership_stage_label,
465504
"ORGANISATION_NAME" => Settings::get("ORGANISATION_NAME"),
466505
"ORGANISATION_BANK_NAME" => Settings::get("ORGANISATION_BANK_NAME"),
467506
"ORGANISATION_EMAIL_ADDRESS" => Settings::get("ORGANISATION_EMAIL_ADDRESS"),
468507
"PASSWORD_PURPOSE" => wpautop(Settings::get("PASSWORD_PURPOSE")),
469508
"POSTCODE_ADDRESS_PROVIDER" => Settings::get("POSTCODE_ADDRESS_PROVIDER"),
470509
"PRIVACY_COPY" => wpautop(Settings::get("PRIVACY_COPY")),
471510
"REQUIRE_ADDRESS" => $fields["require_address"] ?? false,
511+
"HIDE_ADDRESS" => $fields["hide_address"] ?? false,
472512
"REQUIRE_PHONE_NUMBER" => $fields["require_phone_number"] ?? false,
473513
"SENTRY_DSN" => Settings::get("SENTRY_DSN"),
474514
"STRIPE_DIRECT_DEBIT" => Settings::get("STRIPE_DIRECT_DEBIT"),

packages/join-block/src/Settings.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public static function init()
5353
Field::make('checkbox', 'collect_county'),
5454
Field::make('checkbox', 'collect_phone_and_email_contact_consent')
5555
->set_help_text('May or may not be necessary for your organisation to be given this explicit consent'),
56+
Field::make('checkbox', 'hide_zero_price_display', 'Hide price display for zero-price items')
57+
->set_help_text('When enabled, membership tiers with a price of zero will not show a price label'),
5658
Field::make('checkbox', 'create_auth0_account'),
5759
Field::make('checkbox', 'use_zetkin', 'Use Zetkin'),
5860
Field::make('checkbox', 'use_gocardless', 'Use GoCardless'),
@@ -121,10 +123,19 @@ public static function init()
121123
Field::make('rich_text', 'privacy_copy')
122124
->set_help_text("E.G. We will always do our very best to keep the information we hold about you safe and secure."),
123125
Field::make('text', 'membership_tiers_heading')
124-
->set_default_value("Choose the plan thats right for you"),
126+
->set_default_value("Choose the plan that's right for you"),
125127
Field::make('rich_text', 'membership_tiers_copy')
126128
->set_help_text("E.G. Choose tier X if you are Y, otherwise choose tier Z."),
127129
Field::make('text', 'subscription_day_of_month_copy', 'Only valid for monthly subscriptions')->set_default_value("Day of month to take payment"),
130+
Field::make('text', 'join_form_sidebar_heading')
131+
->set_default_value("Join Us")
132+
->set_help_text("The heading shown in the sidebar progress steps"),
133+
Field::make('text', 'membership_stage_label')
134+
->set_default_value("Your Membership")
135+
->set_help_text("The label for the membership selection stage"),
136+
Field::make('text', 'joining_verb')
137+
->set_default_value("Joining")
138+
->set_help_text("The verb used in the loading spinner (e.g., 'Joining Organisation Name')"),
128139
];
129140
$integration_fields = [
130141
Field::make('separator', 'zetkin', 'Zetkin'),

packages/join-flow/src/app.tsx

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { PaymentDetailsPage } from "./pages/payment-details.page";
2121
import { Stager } from "./components/stager";
2222
import { FormSchema, getPaymentPlan, getTestDataIfEnabled } from "./schema";
2323
import { ConfirmationPage } from "./pages/confirm.page";
24-
import { get as getEnv, getPaymentMethods } from "./env";
24+
import { get as getEnv, getStr as getEnvStr, getPaymentMethods } from "./env";
2525
import { usePostResource } from "./services/rest-resource.service";
2626
import gocardless from "./images/gocardless.svg";
2727
import chargebee from "./images/chargebee.png";
@@ -37,19 +37,6 @@ interface Stage {
3737
breadcrumb: boolean;
3838
}
3939

40-
let stages: Stage[] = [
41-
{ id: "enter-details", label: "Your Details", breadcrumb: true },
42-
{ id: "plan", label: "Your Membership", breadcrumb: true },
43-
{ id: "donation", label: "Can you chip in?", breadcrumb: false },
44-
{ id: "payment-details", label: "Payment", breadcrumb: true },
45-
{ id: "payment-method", label: "Payment", breadcrumb: false },
46-
{ id: "confirm", label: "Confirm", breadcrumb: false }
47-
];
48-
49-
if (getEnv("IS_UPDATE_FLOW")) {
50-
stages = stages.filter((s) => s.id !== "enter-details");
51-
}
52-
5340
// Redirect to confirm page if ?gocardless_success === "true"
5441
// because that is a redirect from GoCardless
5542
// Also require a billing request ID to be present.
@@ -72,6 +59,18 @@ let shouldRedirectToConfirm =
7259
const stripePromise = loadStripe(getEnv("STRIPE_PUBLISHABLE_KEY"));
7360

7461
const App = () => {
62+
let stages: Stage[] = [
63+
{ id: "enter-details", label: "Your Details", breadcrumb: true },
64+
{ id: "plan", label: getEnvStr("MEMBERSHIP_STAGE_LABEL"), breadcrumb: true },
65+
{ id: "donation", label: "Can you chip in?", breadcrumb: false },
66+
{ id: "payment-details", label: "Payment", breadcrumb: true },
67+
{ id: "payment-method", label: "Payment", breadcrumb: false },
68+
{ id: "confirm", label: "Confirm", breadcrumb: false }
69+
];
70+
71+
if (getEnv("IS_UPDATE_FLOW")) {
72+
stages = stages.filter((s) => s.id !== "enter-details");
73+
}
7574
const [data, setData] = useState(getInitialState);
7675
const [blockingMessage, setBlockingMessage] = useState<string | null>(null);
7776

@@ -282,7 +281,7 @@ const App = () => {
282281
<>
283282
<RouterContext.Provider value={router}>
284283
<div className="progress-steps">
285-
<h6>Join Us</h6>
284+
<h6>{getEnvStr("JOIN_FORM_SIDEBAR_HEADING")}</h6>
286285
<div className="progress-steps__secure">
287286
<p>
288287
🔒 Secure payment with

packages/join-flow/src/components/atoms.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Form, Button } from "react-bootstrap";
33
import { Controller, UseFormMethods } from "react-hook-form";
44
import { PageState, useCurrentRouter } from "../services/router.service";
55
import { currencyCodeToSymbol } from "../schema";
6+
import { get as getEnv } from "../env";
67

78
interface ContinueButtonProps {
89
disabled?: boolean;
@@ -101,6 +102,8 @@ export const PlanRadioPanel: FC<PlanRadioPanelProps> = ({
101102
name,
102103
className = ""
103104
}) => {
105+
const hideZeroPriceDisplay = Boolean(getEnv("HIDE_ZERO_PRICE_DISPLAY"));
106+
104107
return (
105108
<Controller
106109
name={name}
@@ -120,6 +123,9 @@ export const PlanRadioPanel: FC<PlanRadioPanelProps> = ({
120123
amount: number;
121124
frequency: string;
122125
}) => {
126+
if (hideZeroPriceDisplay && amount === 0) {
127+
return "";
128+
}
123129
const currencySymbol = currencyCodeToSymbol(currency);
124130
return `${currencySymbol}${amount}, ${frequency}`;
125131
};
@@ -177,7 +183,9 @@ export const PlanRadioPanel: FC<PlanRadioPanelProps> = ({
177183
</Form.Control>
178184

179185
{!checked || !currentPlan.allowCustomAmount ? (
180-
`${currencyCodeToSymbol(currentPlan.currency)}${currentPlan.amount}`
186+
(hideZeroPriceDisplay && currentPlan.amount === 0)
187+
? ""
188+
: `${currencyCodeToSymbol(currentPlan.currency)}${currentPlan.amount}`
181189
) : (
182190
<div
183191
className={

packages/join-flow/src/env.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@ interface StaticEnv {
1919
HEAR_ABOUT_US_DETAILS: string;
2020
HEAR_ABOUT_US_HEADING: string;
2121
HEAR_ABOUT_US_OPTIONS: string[];
22+
HIDE_ADDRESS: boolean;
2223
HIDE_HOME_ADDRESS_COPY: boolean;
24+
HIDE_ZERO_PRICE_DISPLAY: boolean;
2325
HOME_ADDRESS_COPY: string;
26+
JOIN_FORM_SIDEBAR_HEADING: string;
27+
JOINING_VERB: string;
2428
MEMBERSHIP_PLANS: object[];
29+
MEMBERSHIP_STAGE_LABEL: string;
2530
MEMBERSHIP_TIERS_HEADING: string;
2631
MEMBERSHIP_TIERS_COPY: string;
2732
ORGANISATION_NAME: string;
@@ -83,9 +88,14 @@ const staticEnv: StaticEnv = {
8388
HEAR_ABOUT_US_DETAILS: process.env.REACT_APP_HEAR_ABOUT_US_DETAILS || '',
8489
HEAR_ABOUT_US_HEADING: process.env.REACT_APP_HEAR_ABOUT_US_HEADING || '',
8590
HEAR_ABOUT_US_OPTIONS: (process.env.REACT_APP_HEAR_ABOUT_US_OPTIONS || '').split('.').map(i => i.trim()).filter(Boolean),
91+
HIDE_ADDRESS: parseBooleanEnvVar("REACT_APP_HIDE_ADDRESS"),
8692
HIDE_HOME_ADDRESS_COPY: parseBooleanEnvVar("REACT_APP_HIDE_HOME_ADDRESS_COPY"),
93+
HIDE_ZERO_PRICE_DISPLAY: parseBooleanEnvVar("REACT_APP_HIDE_ZERO_PRICE_DISPLAY"),
8794
HOME_ADDRESS_COPY: process.env.REACT_APP_HOME_ADDRESS_COPY || '',
95+
JOIN_FORM_SIDEBAR_HEADING: process.env.REACT_APP_JOIN_FORM_SIDEBAR_HEADING || 'Join Us',
96+
JOINING_VERB: process.env.REACT_APP_JOINING_VERB || 'Joining',
8897
MEMBERSHIP_PLANS: JSON.parse(process.env.REACT_APP_MEMBERSHIP_PLANS || '[]') as object[],
98+
MEMBERSHIP_STAGE_LABEL: process.env.REACT_APP_MEMBERSHIP_STAGE_LABEL || 'Your Membership',
8999
MEMBERSHIP_TIERS_HEADING: process.env.REACT_APP_MEMBERSHIP_TIERS_HEADING || '',
90100
MEMBERSHIP_TIERS_COPY: process.env.REACT_APP_MEMBERSHIP_TIERS_COPY || '',
91101
MINIMAL_JOIN_FORM: parseBooleanEnvVar("REACT_APP_MINIMAL_JOIN_FORM"),

packages/join-flow/src/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const init = () => {
2424
const sentryDsn = getEnvStr("SENTRY_DSN")
2525
Sentry.init({
2626
dsn: sentryDsn,
27-
release: "1.3.11"
27+
release: "1.3.12"
2828
});
2929

3030
if (getEnv('USE_CHARGEBEE')) {

packages/join-flow/src/pages/confirm.page.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { FormSchema, getPaymentFrequency, getPaymentPlan } from "../schema";
77
import { usePostResource } from "../services/rest-resource.service";
88
import { upperFirst } from "lodash-es";
99

10-
import { get as getEnv } from '../env';
10+
import { get as getEnv, getStr as getEnvStr } from '../env';
1111
import { useCurrentRouter } from "../services/router.service";
1212

1313
export const ConfirmationPage: StagerComponent<FormSchema> = ({
@@ -19,6 +19,7 @@ export const ConfirmationPage: StagerComponent<FormSchema> = ({
1919
const organisationEmailAddress = getEnv('ORGANISATION_EMAIL_ADDRESS');
2020
const organisationMailToLink = `mailto:${organisationEmailAddress}`;
2121
const chargebeeSiteName = getEnv('CHARGEBEE_SITE_NAME');
22+
const joiningVerb = getEnvStr('JOINING_VERB');
2223

2324
const form = useForm();
2425
const router = useCurrentRouter();
@@ -39,7 +40,7 @@ export const ConfirmationPage: StagerComponent<FormSchema> = ({
3940
<div className="spinner-border" role="status">
4041
<span className="sr-only">Please wait</span>
4142
</div>
42-
<div className="mt-3">Joining {organisationName}</div>
43+
<div className="mt-3">{joiningVerb} {organisationName}</div>
4344
</div>
4445
);
4546

packages/join-flow/src/pages/details.page.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const addressLookupFormSchema = yup.object().shape({
1919
});
2020

2121
const requireAddress = Boolean(getEnv("REQUIRE_ADDRESS"));
22+
const hideAddress = Boolean(getEnv("HIDE_ADDRESS"));
2223
const homeAddressCopy = getEnvStr("HOME_ADDRESS_COPY");
2324
const passwordPurpose = getEnvStr("PASSWORD_PURPOSE");
2425
const privacyCopy = getEnvStr("PRIVACY_COPY");
@@ -149,15 +150,16 @@ export const DetailsPage: StagerComponent<FormSchema> = ({
149150
</section>
150151
) : null}
151152

152-
<section className="form-section">
153-
<h2>Home address</h2>
154-
{getEnv("HIDE_HOME_ADDRESS_COPY") ? (
155-
<div
156-
className="text-secondary"
157-
dangerouslySetInnerHTML={{ __html: homeAddressCopy }}
158-
></div>
159-
) : null}
160-
{usePostcodeLookup ? (
153+
{!hideAddress ? (
154+
<section className="form-section">
155+
<h2>Home address</h2>
156+
{getEnv("HIDE_HOME_ADDRESS_COPY") ? (
157+
<div
158+
className="text-secondary"
159+
dangerouslySetInnerHTML={{ __html: homeAddressCopy }}
160+
></div>
161+
) : null}
162+
{usePostcodeLookup ? (
161163
<>
162164
<FormItem
163165
label="Postcode"
@@ -271,7 +273,8 @@ export const DetailsPage: StagerComponent<FormSchema> = ({
271273
</FormItem>
272274
</div>
273275
</Collapse>
274-
</section>
276+
</section>
277+
) : null}
275278

276279
{customFields.length ? (
277280
<section className="form-section">

0 commit comments

Comments
 (0)