Added stripe integration and donation modal
This commit is contained in:
parent
d662f5e107
commit
0015144d1a
@ -4,6 +4,7 @@
|
||||
"private": true,
|
||||
"homepage": "https://owlbear.rodeo",
|
||||
"dependencies": {
|
||||
"@stripe/stripe-js": "^1.3.2",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.3.2",
|
||||
"@testing-library/user-event": "^7.1.2",
|
||||
|
133
src/modals/DonationModal.js
Normal file
133
src/modals/DonationModal.js
Normal file
@ -0,0 +1,133 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { loadStripe } from "@stripe/stripe-js";
|
||||
import { Box, Label, Button, Flex, Radio, Text } from "theme-ui";
|
||||
import { useLocation, useHistory } from "react-router-dom";
|
||||
|
||||
import Modal from "../components/Modal";
|
||||
import LoadingOverlay from "../components/LoadingOverlay";
|
||||
import Banner from "../components/Banner";
|
||||
|
||||
const skus = [
|
||||
{ sku: "sku_H6DhHS1MimRPR9", price: "$5.00 AUD", name: "Small" },
|
||||
{ sku: "sku_H6DhiQfHUkYUKd", price: "$15.00 AUD", name: "Medium" },
|
||||
{ sku: "sku_H6DhbO2oUn9Sda", price: "$30.00 AUD", name: "Large" },
|
||||
];
|
||||
|
||||
function DonationModal({ isOpen, onRequestClose }) {
|
||||
// Handle callback from stripe
|
||||
const location = useLocation();
|
||||
const history = useHistory();
|
||||
const query = new URLSearchParams(location.search);
|
||||
const hasDonated = query.has("donated");
|
||||
const showDonationForm = isOpen || query.get("donated") === "false";
|
||||
|
||||
const [loading, setLoading] = useState(showDonationForm);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
const [stripe, setStripe] = useState();
|
||||
useEffect(() => {
|
||||
if (showDonationForm) {
|
||||
loadStripe("pk_live_MJjzi5djj524Y7h3fL5PNh4e00a852XD51")
|
||||
.then((stripe) => {
|
||||
setStripe(stripe);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((err) => {
|
||||
setError(err.message);
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
}, [showDonationForm]);
|
||||
|
||||
function handleClose() {
|
||||
if (hasDonated) {
|
||||
history.push(location.pathname);
|
||||
}
|
||||
onRequestClose();
|
||||
}
|
||||
|
||||
function handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
if (!stripe) {
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
stripe
|
||||
.redirectToCheckout({
|
||||
items: [{ sku: selectedSku, quantity: 1 }],
|
||||
successUrl: `${window.location.href}?donated=true`,
|
||||
cancelUrl: `${window.location.href}?donated=false`,
|
||||
submitType: "donate",
|
||||
})
|
||||
.then((response) => {
|
||||
setLoading(false);
|
||||
if (response.error) {
|
||||
setError(response.error.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const [selectedSku, setSelectedSku] = useState("sku_H6DhiQfHUkYUKd");
|
||||
function handleSkuChange(event) {
|
||||
setSelectedSku(event.target.value);
|
||||
}
|
||||
|
||||
const donationSuccessful = (
|
||||
<Box>
|
||||
<Text my={2} variant="heading" as="h1" sx={{ fontSize: 3 }}>
|
||||
Thanks for donating! ʕ•ᴥ•ʔ
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
|
||||
const donationForm = (
|
||||
<Box as="form" onSubmit={handleSubmit}>
|
||||
<Label py={2}>Support us with a donation</Label>
|
||||
<Text as="p" mb={2} variant="caption">
|
||||
One time donation
|
||||
</Text>
|
||||
{skus.map((sku) => (
|
||||
<Label key={sku.sku}>
|
||||
<Radio
|
||||
name="donation"
|
||||
checked={selectedSku === sku.sku}
|
||||
value={sku.sku}
|
||||
onChange={handleSkuChange}
|
||||
/>
|
||||
{sku.name} - {sku.price}
|
||||
</Label>
|
||||
))}
|
||||
<Flex mt={3}>
|
||||
<Button sx={{ flexGrow: 1 }} disabled={!stripe || loading}>
|
||||
Donate
|
||||
</Button>
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen || hasDonated} onRequestClose={handleClose}>
|
||||
<Flex
|
||||
sx={{
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
maxWidth: "300px",
|
||||
flexGrow: 1,
|
||||
}}
|
||||
m={2}
|
||||
>
|
||||
{query.get("donated") === "true" ? donationSuccessful : donationForm}
|
||||
{loading && <LoadingOverlay />}
|
||||
<Banner isOpen={!!error} onRequestClose={() => setError(null)}>
|
||||
<Box p={1}>
|
||||
<Text as="p" variant="body2">
|
||||
{error}
|
||||
</Text>
|
||||
</Box>
|
||||
</Banner>
|
||||
</Flex>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default DonationModal;
|
@ -1,10 +1,11 @@
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
import { Flex, Button, Image, Text } from "theme-ui";
|
||||
import { Flex, Button, Image, Text, Box } from "theme-ui";
|
||||
|
||||
import Footer from "../components/Footer";
|
||||
|
||||
import StartModal from "../modals/StartModal";
|
||||
import JoinModal from "../modals/JoinModal";
|
||||
import DonateModal from "../modals/DonationModal";
|
||||
|
||||
import AuthContext from "../contexts/AuthContext";
|
||||
|
||||
@ -13,6 +14,7 @@ import owlington from "../images/Owlington.png";
|
||||
function Home() {
|
||||
const [isStartModalOpen, setIsStartModalOpen] = useState(false);
|
||||
const [isJoinModalOpen, setIsJoinModalOpen] = useState(false);
|
||||
const [isDonateModalOpen, setIsDonateModalOpen] = useState(false);
|
||||
|
||||
// Reset password on visiting home
|
||||
const { setPassword } = useContext(AuthContext);
|
||||
@ -51,6 +53,14 @@ function Home() {
|
||||
<Text variant="caption" as="p" sx={{ textAlign: "center" }}>
|
||||
Alpha v0.10.2
|
||||
</Text>
|
||||
<Button
|
||||
m={2}
|
||||
onClick={() => setIsDonateModalOpen(true)}
|
||||
variant="secondary"
|
||||
>
|
||||
Support Us
|
||||
</Button>
|
||||
|
||||
<JoinModal
|
||||
isOpen={isJoinModalOpen}
|
||||
onRequestClose={() => setIsJoinModalOpen(false)}
|
||||
@ -59,6 +69,10 @@ function Home() {
|
||||
isOpen={isStartModalOpen}
|
||||
onRequestClose={() => setIsStartModalOpen(false)}
|
||||
/>
|
||||
<DonateModal
|
||||
isOpen={isDonateModalOpen}
|
||||
onRequestClose={() => setIsDonateModalOpen(false)}
|
||||
/>
|
||||
</Flex>
|
||||
<Footer />
|
||||
</Flex>
|
||||
|
@ -1408,6 +1408,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz#5405ee8e444ed212db44e79351f0c70a582aae25"
|
||||
integrity sha512-DetpxZw1fzPD5xUBrIAoplLChO2VB8DlL5Gg+I1IR9b2wPqYIca2WSUxL5g1vLeR4MsQq1NeWriXAVffV+U1Fw==
|
||||
|
||||
"@stripe/stripe-js@^1.3.2":
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.3.2.tgz#ddd9a34f732604909e0362b8b31d5584c5c8387a"
|
||||
integrity sha512-m8WogAMX0EzGRfKhuXTTTxfet8G+UozoCs6gEhGlzvDIhteQUuuuESzWEhlEAlEJXJCa1l6qqa20uWR4jqCl3g==
|
||||
|
||||
"@styled-system/background@^5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@styled-system/background/-/background-5.1.2.tgz#75c63d06b497ab372b70186c0bf608d62847a2ba"
|
||||
|
Loading…
Reference in New Issue
Block a user