8889841cPK [cV components/GreenButton.jsnu [ import React from 'react';
import cx from 'classnames';
import styles from './GreenButton.module.css';
export default function GreenButton({as: Element = 'button', text, className, shadow = false, ...props}) {
const classes = cx(styles.button, shadow && styles.shadow, className);
if (Element === 'input') {
return ;
}
return (
{text}
);
}
PK [Q Q ! components/GreenButton.module.cssnu [ .button {
appearance: none;
display: block;
cursor: pointer;
padding: 0.888em;
border-radius: 9999px;
border-width: 0.125rem;
border-style: solid;
border-color: #66bb6a;
background-color: #66bb6a;
color: #fff;
font-weight: 700;
font-size: 1.125rem;
text-align: center;
text-decoration: none;
line-height: 1;
letter-spacing: -0.0278em;
transition-duration: 200ms;
transition-property: filter, color, background-color, text-shadow, box-shadow;
transition-timing-function: ease;
}
.shadow {
box-shadow: 0 2px 10px 0 rgba(105, 184, 107, 0.6);
}
.button:hover,
.button:active,
.button:focus {
text-shadow: 0 0 0.125em rgba(0, 0, 0, 0.3);
filter: brightness(115%);
color: #fff;
}
.button:focus {
box-shadow: 0 0 0.0625em 0.25em rgba(102, 187, 106, 0.4);
}
PK [^J J ! hooks/useFreeAddonSubscription.jsnu [ import {useState, useCallback} from 'react';
/**
* Handles making a request to add a user to the Free Addon email subscription. It returns whether the request worked,
* failed, and the callback to trigger it all.
*
* @param {String} reason "rejected" or "subscribed"
* @returns {boolean} Whether the request was successful.
*/
async function markSubscriptionComplete(reason) {
const response = await fetch(giveFreeAddonModal.apiRoot, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
'X-WP-Nonce': giveFreeAddonModal.nonce,
},
body: JSON.stringify({reason}),
});
return response.ok;
}
export default function useFreeAddonSubscription() {
const [userSubscribed, setUserSubscribed] = useState(false);
const [hasSubmissionError, setHasSubmissionError] = useState(false);
const handleSubscribe = useCallback(
/**
* @param {String} firstName
* @param {String} email
* @param {String} siteUrl
* @param {String} siteName
* @returns {Promise}
*/
async (firstName, email, siteUrl, siteName) => {
try {
const response = await fetch('https://connect.givewp.com/activecampaign/subscribe/free-add-on', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
first_name: firstName,
email,
website_url: siteUrl,
website_name: siteName,
}),
});
if (response.ok) {
setUserSubscribed(true);
markSubscriptionComplete('subscribed');
} else {
setHasSubmissionError(true);
}
} catch (error) {
setHasSubmissionError(true);
}
},
[setUserSubscribed, setHasSubmissionError]
);
return {
userSubscribed,
hasSubscriptionError: hasSubmissionError,
subscribeUser: handleSubscribe,
rejectOffer: () => markSubscriptionComplete('rejected'),
};
}
PK [ЖP
hooks/useRecommendations.tsnu [ import {useCallback, useState} from 'react';
import dismissRecommendation from '@givewp/promotions/requests/dismissRecommendation';
type EnumValues =
| 'givewp_donations_recurring_recommendation_dismissed'
| 'givewp_donations_fee_recovery_recommendation_dismissed'
| 'givewp_donations_designated_funds_recommendation_dismissed'
| 'givewp_reports_recurring_recommendation_dismissed'
| 'givewp_reports_fee_recovery_recommendation_dismissed'
| 'givewp_donors_fee_recovery_recommendation_dismissed'
| 'givewp_reports_fee_recovery_recommendation_dismissed';
export interface RecommendedProductData {
enum: EnumValues;
documentationPage: string;
message: string;
innerHtml: string;
}
/**
* @since 2.27.1
*/
export function useRecommendations(apiSettings, options) {
const [dismissedRecommendations, setDismissedRecommendations] = useState(
apiSettings.dismissedRecommendations
);
const getRandomRecommendation = useCallback((): RecommendedProductData | null => {
const availableOptions = options.filter((option) => !dismissedRecommendations.includes(option.enum));
if (availableOptions.length === 0) {
return null;
}
const randomIndex = Math.floor(Math.random() * availableOptions.length);
return availableOptions[randomIndex];
}, [dismissedRecommendations]);
const getRecommendation = useCallback((): RecommendedProductData | null => {
const availableOptions = options.filter((option) => !dismissedRecommendations.includes(option.enum));
if (availableOptions.length === 0) {
return null;
}
return availableOptions[0];
}, [dismissedRecommendations]);
const removeRecommendation = async (data: {option: EnumValues}): Promise => {
setDismissedRecommendations((prev) => [...prev, data.option]);
await dismissRecommendation(data.option, apiSettings.apiNonce);
};
return {getRecommendation, getRandomRecommendation, removeRecommendation};
}
PK [^ ! requests/dismissRecommendation.tsnu [ /**
*
* @since 2.27.1
*
*/
export default async function dismissRecommendation(option: string, nonce: string) {
const url = '/wp-json/give-api/v2/admin/recommended-options';
await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': nonce,
},
body: JSON.stringify({
option
}),
});
}
PK [cV components/GreenButton.jsnu [ PK [Q Q ! ^ components/GreenButton.module.cssnu [ PK [^J J ! hooks/useFreeAddonSubscription.jsnu [ PK [ЖP
hooks/useRecommendations.tsnu [ PK [^ ! requests/dismissRecommendation.tsnu [ PK