Skip to content

Commit

Permalink
Add public testimony input (#409)
Browse files Browse the repository at this point in the history
* fix: default color does not work

* feat: Add public testimony feature to donation widget

* feat: Update donation amount input value handling
  • Loading branch information
Fishbakh-N authored Aug 5, 2024
1 parent 6c8291f commit 95e0ba3
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
SmallPaymentMethodSelect
} from 'src/components/widget/components/PaymentProcess/PaymentMethodSelect';
import {PrivateNote} from 'src/components/widget/components/PaymentProcess/PrivateNote';
import {PublicTestimony} from 'src/components/widget/components/PaymentProcess/PublicTestimony';
import {RedirectNotice} from 'src/components/widget/components/PaymentProcess/RedirectNotice';
import {SubmitButton} from 'src/components/widget/components/PaymentProcess/SubmitButton';
import {
Expand Down Expand Up @@ -57,6 +58,7 @@ export const CryptoFlow = () => {
)}
</fieldset>
<PrivateNote />
<PublicTestimony />
<ErrorMessage message={submitError} />
<SubmitButton disabled={!cryptoAmount || !cryptoCurrency}>
{getSubmitButtonText({method: PaymentMethod.CRYPTO, cryptoCurrency})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import {DonationAmount} from 'src/components/widget/components/PaymentProcess/DonationAmount';
import {Frequency} from 'src/components/widget/components/PaymentProcess/Frequency';
import {PrivateNote} from 'src/components/widget/components/PaymentProcess/PrivateNote';
import {PublicTestimony} from 'src/components/widget/components/PaymentProcess/PublicTestimony';
import {RedirectNotice} from 'src/components/widget/components/PaymentProcess/RedirectNotice';
import {SubmitButton} from 'src/components/widget/components/PaymentProcess/SubmitButton';
import {
Expand Down Expand Up @@ -34,6 +35,7 @@ export const DafAmountView = ({changeView}: DafFlowViewProps) => {
<Frequency />
<DonationAmount />
<PrivateNote />
<PublicTestimony />
<ErrorMessage message={submitError} />
<SubmitButton
disabled={!donationAmount || Number.isNaN(donationAmount)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
SmallPaymentMethodSelect
} from 'src/components/widget/components/PaymentProcess/PaymentMethodSelect';
import {PrivateNote} from 'src/components/widget/components/PaymentProcess/PrivateNote';
import {PublicTestimony} from 'src/components/widget/components/PaymentProcess/PublicTestimony';
import {RedirectNotice} from 'src/components/widget/components/PaymentProcess/RedirectNotice';
import {SubmitButton} from 'src/components/widget/components/PaymentProcess/SubmitButton';
import {
Expand Down Expand Up @@ -43,6 +44,7 @@ export const DefaultFlow = () => {
<DonationAmount />
</div>
<PrivateNote />
<PublicTestimony />
<ErrorMessage message={submitError} />
<SubmitButton
disabled={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export const DonationAmount = () => {
inputMode="numeric"
min={0}
step={1}
value={donationAmount ? donationAmount : undefined}
value={donationAmount ? donationAmount : ''}
prefix={DEFAULT_CURRENCY.symbol}
inputClassName={donationAmountInputCss}
prefixClassName={donationAmountInputPrefixCss}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import cxs from 'cxs';
import {useState} from 'preact/hooks';
import {Checkbox} from 'src/components/widget/components/Checkbox';
import {
fieldSetCss,
legendCss
} from 'src/components/widget/components/PaymentProcess/styles';
import {TextArea} from 'src/components/widget/components/TextInput';
import {useNonprofitOrError} from 'src/components/widget/hooks/useNonprofit';
import {useWidgetContext} from 'src/components/widget/hooks/useWidgetContext';
import {verticalStackCss, Spacing} from 'src/components/widget/theme/spacing';

export const PublicTestimony = () => {
const nonprofit = useNonprofitOrError();

const {publicTestimony, setPublicTestimony} = useWidgetContext();
const [showPublicTestimonyField, setShowPublicTestimonyField] = useState(
Boolean(publicTestimony)
);

return (
<div className={verticalStackCss.className(Spacing.L)}>
<Checkbox
checked={showPublicTestimonyField}
onChange={() => {
setShowPublicTestimonyField((previous) => !previous);
}}
>
Add public testimony
</Checkbox>
{showPublicTestimonyField && (
<fieldset
className={cxs({fieldSetCss, ...verticalStackCss.cxs(Spacing.XS)})}
>
<legend className={legendCss}>
Help {nonprofit.name} by sharing why you support them with the world
</legend>
<TextArea
rows={3}
label="Note"
id="publicTestimony"
value={publicTestimony}
inputClassName={cxs({resize: 'none'})}
onChange={({currentTarget}) => {
setPublicTestimony(currentTarget.value);
}}
/>
</fieldset>
)}
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
SmallPaymentMethodSelect
} from 'src/components/widget/components/PaymentProcess/PaymentMethodSelect';
import {PrivateNote} from 'src/components/widget/components/PaymentProcess/PrivateNote';
import {PublicTestimony} from 'src/components/widget/components/PaymentProcess/PublicTestimony';
import {RedirectNotice} from 'src/components/widget/components/PaymentProcess/RedirectNotice';
import {SubmitButton} from 'src/components/widget/components/PaymentProcess/SubmitButton';
import {
Expand Down Expand Up @@ -90,6 +91,7 @@ export const StocksFlow = () => {
</div>
</fieldset>
<PrivateNote />
<PublicTestimony />
<ErrorMessage message={submitError} />
<SubmitButton disabled={!stockAmount || !stockSymbol}>
{getSubmitButtonText({method: PaymentMethod.STOCKS})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ interface WidgetContextProps {
privateNote?: string;
setPrivateNote: StateUpdater<string | undefined>;

publicTestimony?: string;
setPublicTestimony: StateUpdater<string | undefined>;

giftCardCode?: string;
setGiftCardCode: StateUpdater<string | undefined>;
}
Expand All @@ -58,6 +61,11 @@ export const WidgetContextProvider: FunctionalComponent<{hide: () => void}> = ({
const [donationAmount, setDonationAmount] = useState(
config.amount ?? config.defaultDonationAmount
);

useEffect(() => {
setDonationAmount(config.amount);
}, [config.amount]);

const [submitError, setSubmitError] = useState<string | null>(null);
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState(
config.methods[0]
Expand All @@ -78,6 +86,7 @@ export const WidgetContextProvider: FunctionalComponent<{hide: () => void}> = ({
const paymentRequestAvailable = useCheckPaymentRequest();

const [privateNote, setPrivateNote] = useState<string>();
const [publicTestimony, setPublicTestimony] = useState<string>();

const [giftCardCode, setGiftCardCode] = useState<string>();

Expand All @@ -104,6 +113,8 @@ export const WidgetContextProvider: FunctionalComponent<{hide: () => void}> = ({
paymentRequestAvailable,
privateNote,
setPrivateNote,
publicTestimony,
setPublicTestimony,
giftCardCode,
setGiftCardCode
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const useSubmitDonation = () => {
cryptoAmount,
cryptoCurrency,
privateNote,
publicTestimony,
giftCardCode
} = useWidgetContext();
const {minDonationAmount, webhookToken, redeemGiftCardInFlow} =
Expand All @@ -46,6 +47,7 @@ export const useSubmitDonation = () => {
fundraiserSlug: config.fundraiserSlug,
utmSource: config.utmSource,
privateNote,
publicTestimony,
webhookToken
};
switch (selectedPaymentMethod) {
Expand Down Expand Up @@ -123,6 +125,7 @@ export const useSubmitDonation = () => {
cryptoAmount,
cryptoCurrency,
privateNote,
publicTestimony,
giftCardCode,
webhookToken,
redeemGiftCardInFlow
Expand Down
4 changes: 4 additions & 0 deletions packages/donate-button-v4/src/helpers/constructDonateUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface BaseUrlParams {
noExit?: boolean;
methods?: PaymentMethod[];
privateNote?: string;
publicTestimony?: string;
utmSource?: string;
webhookToken?: string;
}
Expand Down Expand Up @@ -67,6 +68,7 @@ function getBaseParams({
nonprofitSlug,
noExit,
privateNote,
publicTestimony,
utmSource,
webhookToken
}: Pick<
Expand All @@ -75,6 +77,7 @@ function getBaseParams({
| 'methods'
| 'noExit'
| 'privateNote'
| 'publicTestimony'
| 'utmSource'
| 'webhookToken'
>) {
Expand All @@ -85,6 +88,7 @@ function getBaseParams({
utm_medium: UTM_MEDIUM,
no_exit: noExit ?? 1,
private_note: privateNote,
public_testimony: publicTestimony,
webhook_token: webhookToken
};
}
Expand Down
10 changes: 8 additions & 2 deletions packages/donate-button-v4/src/helpers/parseDonateUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ function intFromString(string?: string | null) {
return Number.isNaN(number) ? undefined : number;
}

function removeEmptyValues<T extends Record<string, unknown>>(object: T): T {
return Object.fromEntries(
Object.entries(object).filter(([, value]) => value !== undefined)
) as T;
}

export function parseDonateUrl(
urlString: string
): (Partial<WidgetConfig> & {nonprofitSlug: string}) | undefined {
Expand Down Expand Up @@ -88,7 +94,7 @@ export function parseDonateUrl(
return;
}

return {
return removeEmptyValues({
fundraiserSlug,
nonprofitSlug,
frequency,
Expand All @@ -101,5 +107,5 @@ export function parseDonateUrl(
defaultDonationAmount: amount,
minDonationAmount: minAmount,
primaryColor
};
});
}

0 comments on commit 95e0ba3

Please sign in to comment.