diff --git a/crabfit-frontend/src/App.tsx b/crabfit-frontend/src/App.tsx index a31812d..743c72f 100644 --- a/crabfit-frontend/src/App.tsx +++ b/crabfit-frontend/src/App.tsx @@ -107,6 +107,11 @@ const App = () => { }, })} /> + + }> + + + ( }> @@ -135,10 +140,6 @@ const App = () => { )} /> - }> - - - {eggVisible && setEggVisible(false)} />} diff --git a/crabfit-frontend/src/components/Donate/Donate.tsx b/crabfit-frontend/src/components/Donate/Donate.tsx index 03dabfe..d245e57 100644 --- a/crabfit-frontend/src/components/Donate/Donate.tsx +++ b/crabfit-frontend/src/components/Donate/Donate.tsx @@ -1,15 +1,33 @@ -import { useEffect } from 'react'; +import { useState, useEffect, useRef } from 'react'; import { Button } from 'components'; import { useTWAStore } from 'stores'; import { useTranslation } from 'react-i18next'; +import { + Wrapper, + Options, +} from './donateStyle'; + const PAYMENT_METHOD = 'https://play.google.com/billing'; const SKU = 'crab_donation'; -const Donate = ({ onDonate = null }) => { +const Donate = () => { const store = useTWAStore(); const { t } = useTranslation('common'); + const firstLinkRef = useRef(); + const buttonRef = useRef(); + const modalRef = useRef(); + const [isOpen, _setIsOpen] = useState(false); + + const setIsOpen = open => { + _setIsOpen(open); + + if (open) { + window.setTimeout(() => firstLinkRef.current.focus(), 150); + } + }; + useEffect(() => { if (store.TWA === undefined) { store.setTWA(document.referrer.includes('android-app://fit.crab')); @@ -71,7 +89,7 @@ const Donate = ({ onDonate = null }) => { }; return ( -
+ { gtag('event', 'donate', { 'event_category': 'donate' }); @@ -82,14 +100,15 @@ const Donate = ({ onDonate = null }) => { alert(t('donate.messages.error')); } } - } else if (onDonate !== null) { + } else { event.preventDefault(); - onDonate(); + setIsOpen(true); } }} href="https://www.paypal.com/donate?business=N89X6YXRT5HKW&item_name=Crab+Fit+Donation¤cy_code=AUD&amount=5" target="_blank" rel="noreferrer" + ref={buttonRef} > -
+ + { + if (modalRef.current.contains(e.relatedTarget)) return; + setIsOpen(false); + }} + > + setIsOpen(false)} ref={firstLinkRef} href="https://www.paypal.com/donate?business=N89X6YXRT5HKW&item_name=Crab+Fit+Donation¤cy_code=AUD&amount=2" target="_blank" rel="noreferrer">{t('donate.options.$2')} + setIsOpen(false)} href="https://www.paypal.com/donate?business=N89X6YXRT5HKW&item_name=Crab+Fit+Donation¤cy_code=AUD&amount=5" target="_blank" rel="noreferrer">{t('donate.options.$5')} + setIsOpen(false)} href="https://www.paypal.com/donate?business=N89X6YXRT5HKW&item_name=Crab+Fit+Donation¤cy_code=AUD&amount=10" target="_blank" rel="noreferrer">{t('donate.options.$10')} + setIsOpen(false)} href="https://www.paypal.com/donate?business=N89X6YXRT5HKW&item_name=Crab+Fit+Donation¤cy_code=AUD" target="_blank" rel="noreferrer">{t('donate.options.choose')} + + ); } diff --git a/crabfit-frontend/src/components/Donate/donateStyle.ts b/crabfit-frontend/src/components/Donate/donateStyle.ts new file mode 100644 index 0000000..280813f --- /dev/null +++ b/crabfit-frontend/src/components/Donate/donateStyle.ts @@ -0,0 +1,52 @@ +import styled from '@emotion/styled'; + +export const Wrapper = styled.div` + margin-top: 6px; + margin-left: 12px; + position: relative; +`; + +export const Options = styled.div` + position: absolute; + bottom: calc(100% + 20px); + right: 0; + background-color: ${props => props.theme.background}; + ${props => props.theme.mode === 'dark' && ` + border: 1px solid ${props.theme.primaryBackground}; + `} + z-index: 60; + padding: 4px 10px; + border-radius: 14px; + box-sizing: border-box; + max-width: calc(100vw - 20px); + box-shadow: 0 3px 6px 0 rgba(0,0,0,.3); + + visibility: hidden; + pointer-events: none; + opacity: 0; + transform: translateY(5px); + transition: opacity .15s, transform .15s, visibility .15s; + + ${props => props.isOpen && ` + pointer-events: all; + opacity: 1; + transform: translateY(0); + visibility: visible; + `} + + & a { + display: block; + white-space: nowrap; + text-align: center; + padding: 4px 20px; + margin: 6px 0; + text-decoration: none; + border-radius: 100px; + background-color: ${props => props.theme.primary}; + color: ${props => props.theme.background}; + + &:hover { + text-decoration: underline; + } + } +`; diff --git a/crabfit-frontend/src/components/Footer/Footer.tsx b/crabfit-frontend/src/components/Footer/Footer.tsx index cbbfcef..8603aaf 100644 --- a/crabfit-frontend/src/components/Footer/Footer.tsx +++ b/crabfit-frontend/src/components/Footer/Footer.tsx @@ -1,28 +1,15 @@ -import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Donate } from 'components'; -import { Wrapper, Link } from './footerStyle'; +import { Wrapper } from './footerStyle'; const Footer = (props) => { - const [donateMode, setDonateMode] = useState(false); const { t } = useTranslation('common'); return ( -