@open-tender/utils
Version:
A library of utils for use with Open Tender applications that utilize our cloud-based Order API.
192 lines (191 loc) • 7.54 kB
JavaScript
import { __awaiter } from "tslib";
import { useMemo, useRef, useState, useEffect } from 'react';
import { makeFormErrors, validateCreditCard } from '../utils';
export const useGiftCardsForm = (purchase, reset, setAlert, loading, error, success, initState, customer, creditCards, includeRecaptcha, cardData, cardType, url, kountSessionId, requireCardholderName = false) => {
const submitRef = useRef(null);
const inputRef = useRef(null);
const recaptchaRef = useRef(null);
const [name, setName] = useState(null);
const [email, setEmail] = useState(null);
const [cards, setCards] = useState([initState]);
const [isNewCard, setIsNewCard] = useState(true);
const [creditCard, setCreditCard] = useState(null);
const [creditCardOptions, setCreditCardOptions] = useState([]);
const [errors, setErrors] = useState({});
const [submitting, setSubmitting] = useState(false);
const newCardErrors = useMemo(() => errors
? Object.entries(errors)
.filter(([key]) => key !== 'form')
.reduce((obj, [key, value]) => (Object.assign(Object.assign({}, obj), { [key]: value })), {})
: {}, [errors]);
useEffect(() => {
if (loading === 'idle') {
setSubmitting(false);
setAlert({ type: 'close' });
if (error) {
if (recaptchaRef.current)
recaptchaRef.current.reset();
setErrors(makeFormErrors(error));
}
}
}, [loading, error, setAlert, success]);
useEffect(() => {
if (creditCards === null || creditCards === void 0 ? void 0 : creditCards.length) {
const options = creditCards.map(i => ({
name: `${i.card_type_name} ending in ${i.last4}`,
value: i.customer_card_id
}));
setCreditCardOptions(options);
const defaultCard = creditCards.length
? { customer_card_id: creditCards[0].customer_card_id }
: null;
setCreditCard(defaultCard);
setIsNewCard(false);
}
}, [creditCards]);
useEffect(() => {
var _a;
if (customer) {
setEmail((_a = customer.email) !== null && _a !== void 0 ? _a : null);
setName(`${customer.first_name} ${customer.last_name}`);
}
}, [customer]);
const makeGiftCards = (giftCards) => {
return giftCards.reduce((arr, card) => {
const { amount, quantity, email } = card;
const giftCard = !email || !email.length ? { amount, quantity } : card;
return [...arr, giftCard];
}, []);
};
const handleName = (value) => {
setName(value);
};
const handleEmail = (value) => {
setEmail(value);
};
const handleChange = (name, value) => {
const [field, index] = name.split('-');
const newCards = cards.map((card, idx) => {
return idx === parseInt(index) ? Object.assign(Object.assign({}, card), { [field]: value }) : card;
});
setCards(newCards);
};
const handleQuantity = (index, quantity) => {
const newCards = quantity > 0
? cards.map((card, idx) => {
return idx === parseInt(`${index}`)
? Object.assign(Object.assign({}, card), { quantity: quantity }) : card;
})
: cards.filter((_, idx) => idx !== index);
setCards(newCards);
};
const handleAddAnother = () => {
setCards([...cards, initState]);
};
const handleCreditCard = (value) => {
const customerCardId = parseInt(`${value}`);
setCreditCard({ customer_card_id: customerCardId });
};
const purchaseWithCaptcha = (credit_card) => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b, _c;
const alert = {
type: 'working',
args: { text: 'Submitting your purchase...' }
};
const formData = {
credit_card,
name: name !== null && name !== void 0 ? name : '',
email: email !== null && email !== void 0 ? email : '',
url: url !== null && url !== void 0 ? url : ''
};
if (kountSessionId)
formData.kount_device_session_id = kountSessionId;
if (includeRecaptcha) {
try {
const isEnterpriseRecaptcha = ((_a = recaptchaRef.current) === null || _a === void 0 ? void 0 : _a.props.size) === 'invisible';
const token = isEnterpriseRecaptcha
? yield ((_b = recaptchaRef.current) === null || _b === void 0 ? void 0 : _b.executeAsync())
: (_c = recaptchaRef.current) === null || _c === void 0 ? void 0 : _c.getValue();
if (!token) {
setSubmitting(false);
setErrors({
form: 'Please complete the recaptcha before submitting'
});
}
else {
setSubmitting(true);
setAlert(alert);
const gift_cards = makeGiftCards(cards);
purchase(Object.assign(Object.assign({}, formData), { token,
gift_cards }));
}
}
catch (err) {
setSubmitting(false);
setErrors({ form: 'Please complete the recaptcha before submitting' });
}
}
else {
setSubmitting(true);
setAlert(alert);
const gift_cards = makeGiftCards(cards);
purchase(Object.assign(Object.assign({}, formData), { gift_cards }));
}
});
const handleSubmit = (evt) => {
var _a, _b, _c;
evt === null || evt === void 0 ? void 0 : evt.preventDefault();
if (!name || !email) {
setErrors({ form: 'Both name and email are required' });
if (inputRef.current)
((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus) && inputRef.current.focus();
}
else {
if (isNewCard) {
if (cardData && cardType) {
const { card, errors } = validateCreditCard(cardData, cardType, requireCardholderName);
if (errors) {
setErrors(Object.assign(Object.assign({}, errors), { form: 'There are one or more credit card errors below' }));
setSubmitting(false);
}
else {
purchaseWithCaptcha(card);
}
}
}
else {
if (creditCard)
purchaseWithCaptcha(creditCard);
}
((_b = submitRef.current) === null || _b === void 0 ? void 0 : _b.blur) && ((_c = submitRef.current) === null || _c === void 0 ? void 0 : _c.blur());
}
};
const handleReset = () => {
setCards([initState]);
setErrors({});
reset();
};
return {
inputRef,
submitRef,
recaptchaRef,
creditCardOptions,
handleName,
handleEmail,
handleChange,
handleQuantity,
handleAddAnother,
handleCreditCard,
handleSubmit,
handleReset,
name,
email,
cards,
isNewCard,
newCardErrors,
creditCard,
setCreditCard,
errors,
submitting
};
};