From ca369b85857207bc2902beda6f0a62f77059cb8e Mon Sep 17 00:00:00 2001 From: Ahmad Abdolsaheb Date: Fri, 6 Nov 2020 14:30:14 +0300 Subject: [PATCH] feat: update donation plans on donate page. (#40102) Co-authored-by: Oliver Eyton-Williams --- client/src/components/Donation/DonateForm.js | 80 +++++------------- .../components/Donation/DonateSupportText.js | 19 +++++ client/src/components/Donation/DonateText.js | 19 +---- client/src/components/Donation/Donation.css | 81 +++++++++++++++--- .../Donation/PayPalButtonScriptLoader.js | 2 +- .../landing/components/CampersImage.js | 47 +++++++++++ .../landing/components/LandingTop.js | 24 +----- client/src/components/layouts/variables.css | 2 +- client/src/pages/donate.js | 55 ++++++------ config/donation-settings.js | 84 +++++++------------ 10 files changed, 218 insertions(+), 195 deletions(-) create mode 100644 client/src/components/Donation/DonateSupportText.js create mode 100644 client/src/components/landing/components/CampersImage.js diff --git a/client/src/components/Donation/DonateForm.js b/client/src/components/Donation/DonateForm.js index 5d5e6bd6e8..3008bc4f7c 100644 --- a/client/src/components/Donation/DonateForm.js +++ b/client/src/components/Donation/DonateForm.js @@ -12,9 +12,6 @@ import { ToggleButton, ToggleButtonGroup } from '@freecodecamp/react-bootstrap'; -import ApplePay from './assets/ApplePay'; -import GooglePay from './assets/GooglePay'; -import acceptedCards from './assets/accepted-cards.png'; import { amountsConfig, durationsConfig, @@ -241,7 +238,7 @@ class DonateForm extends Component { const { donationAmount, donationDuration, processing } = this.state; return !processing ? (
-

Duration and amount:

+

Select gift frequency:

+

Select gift amount:

)} - - - - - + - - - - +
); } @@ -415,12 +383,8 @@ class DonateForm extends Component { renderPageForm() { return ( - - {this.renderDurationAmountOptions()} - - - {this.renderDonationOptions()} - + {this.renderDurationAmountOptions()} + {this.renderDonationOptions()} ); } diff --git a/client/src/components/Donation/DonateSupportText.js b/client/src/components/Donation/DonateSupportText.js new file mode 100644 index 0000000000..a7f098f417 --- /dev/null +++ b/client/src/components/Donation/DonateSupportText.js @@ -0,0 +1,19 @@ +import React from 'react'; +import { Row, Col } from '@freecodecamp/react-bootstrap'; + +const DonateSupportText = () => ( + + +
+

+ Need help with your current or past donations? +

+

+ Forward a copy of your donation receipt to donors@freecodecamp.org and + tell us how we can help. +

+ +
+); +DonateSupportText.displayName = 'DonateText'; +export default DonateSupportText; diff --git a/client/src/components/Donation/DonateText.js b/client/src/components/Donation/DonateText.js index 7532b2b819..628ba2c7c5 100644 --- a/client/src/components/Donation/DonateText.js +++ b/client/src/components/Donation/DonateText.js @@ -4,17 +4,8 @@ import { Row, Col } from '@freecodecamp/react-bootstrap'; const DonateText = () => { return ( - +

freeCodeCamp is a highly efficient education nonprofit.

-

- In 2019 alone, we provided 18 million hours of free education to - people around the world. -

-

- Since freeCodeCamp's total budget is only $373,000, that means every - dollar you donate to freeCodeCamp translates into 50 hours worth of - technology education. -

When you donate to freeCodeCamp, you help people learn new skills and provide for their families. @@ -23,14 +14,6 @@ const DonateText = () => { You also help us create new resources for you to use to expand your own technology skills.

-
-

- Need help with your current or past donations? -

-

- Forward a copy of your donation receipt to donors@freecodecamp.org and - tell us how we can help. -

); diff --git a/client/src/components/Donation/Donation.css b/client/src/components/Donation/Donation.css index 8f49fc6648..2d96910a18 100644 --- a/client/src/components/Donation/Donation.css +++ b/client/src/components/Donation/Donation.css @@ -92,7 +92,7 @@ .donate-tabs > .nav-pills > li > a { text-transform: capitalize; text-decoration: none; - border: 2px solid var(--yellow-light); + border: 3px solid var(--yellow-light); border-radius: 0px; color: var(--gray-85); margin: 0 1px; @@ -109,7 +109,7 @@ .donate-tabs > .nav-pills > li.active > a:focus { color: var(--gray-85); background-color: var(--yellow-light); - border: 2px solid var(--yellow-light); + border: 3px solid var(--yellow-light); text-decoration: none; border-radius: 0px; box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); @@ -125,13 +125,17 @@ } .amount-values > label { - margin: 0 2px !important; + margin: 0 2px; color: var(--gray-85); - border: 2px solid var(--yellow-light); + border: 3px solid var(--yellow-light); border-radius: 0px; background-color: transparent; } +.amount-values.btn-group .btn + .btn { + margin: 0 2px; +} + .amount-values > label:hover, .amount-values > label:focus, .amount-values > label:active:hover { @@ -155,17 +159,36 @@ .amount-values > label.active:focus { color: var(--gray-85); background-color: var(--yellow-light); - border: 2px solid var(--yellow-light); + border: 3px solid var(--yellow-light); border-radius: 0px; box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } +@media (max-width: 500px) { + .amount-values { + display: flex; + flex-wrap: wrap; + } + .amount-values > label { + width: 31.3%; + margin-bottom: 3px; + } + .amount-values.btn-group > .btn:first-child { + margin-left: 2px; + margin-bottom: 3px; + } + .amount-values.btn-group .btn + .btn { + /* margin: 0 2px; */ + margin-bottom: 3px; + } +} + li.disabled { cursor: not-allowed; } li.disabled > a { - border: 2px solid var(--gray-15) !important; + border: 3px solid var(--gray-15) !important; color: var(--gray-15) !important; } @@ -178,12 +201,6 @@ li.disabled > a { font-family: 'Lato', sans-serif; } -@media (max-width: 991px) { - .donate-text { - margin-top: 30px; - } -} - @media (max-width: 400px) { .donate-tabs > .nav-pills > li > a { font-size: 0.8rem; @@ -342,13 +359,51 @@ li.disabled > a { align-self: center; } -#confirm-donation-btn { +button#confirm-donation-btn { display: flex; flex-direction: row; justify-content: center; align-content: center; + border-radius: 5px; + background-color: var(--yellow-light); + border-color: var(--yellow-light); +} +button#confirm-donation-btn:active, +button#confirm-donation-btn:active:focus, +button#confirm-donation-btn:hover { + color: var(--secondary-color); + background-color: #f2ba38; + border-color: #f2ba38; } .hide { display: none; } + +.donate-btn-group { + display: flex; + flex-direction: column; +} + +.donate-btn-group > * { + width: 100%; + height: 43px; +} + +.donate-btn-group button:first-child { + margin-bottom: 10px; +} + +@media (min-width: 500px) { + .donate-btn-group { + flex-direction: row; + } + .donate-btn-group > * { + width: 49%; + } + + .donate-btn-group button:first-child { + margin-bottom: 0px; + margin-right: auto; + } +} diff --git a/client/src/components/Donation/PayPalButtonScriptLoader.js b/client/src/components/Donation/PayPalButtonScriptLoader.js index ce8be6a63e..263d8f2bad 100644 --- a/client/src/components/Donation/PayPalButtonScriptLoader.js +++ b/client/src/components/Donation/PayPalButtonScriptLoader.js @@ -34,7 +34,7 @@ export class PayPalButtonScriptLoader extends Component { loadScript(subscription, deleteScript) { if (deleteScript) scriptRemover('paypal-sdk'); - let queries = `?client-id=${this.props.clientId}&disable-funding=credit,card`; + let queries = `?client-id=${this.props.clientId}&disable-funding=credit,card,bancontact,blik,eps,giropay,ideal,mybank,p24,sepa,sofort,venmo`; if (subscription) queries += '&vault=true'; scriptLoader( diff --git a/client/src/components/landing/components/CampersImage.js b/client/src/components/landing/components/CampersImage.js new file mode 100644 index 0000000000..fec5835281 --- /dev/null +++ b/client/src/components/landing/components/CampersImage.js @@ -0,0 +1,47 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import Media from 'react-responsive'; +import { Spacer, ImageLoader } from '../../helpers'; +import wideImg from '../../../assets/images/landing/wide-image.png'; + +const propTypes = { + page: PropTypes.string +}; + +const LARGE_SCREEN_SIZE = 1200; + +const imageConfig = { + donate: { + spacerSize: 0, + height: 345, + width: 585 + }, + landing: { + spacerSize: 2, + height: 442, + width: 750 + } +}; + +function CampersImage({ page }) { + const { spacerSize, height, width } = imageConfig[page]; + return ( + + + +

+ freeCodeCamp students at a local study group in South Korea. +

+
+ ); +} + +CampersImage.displayName = 'CampersImage'; +CampersImage.propTypes = propTypes; +export default CampersImage; diff --git a/client/src/components/landing/components/LandingTop.js b/client/src/components/landing/components/LandingTop.js index 12ef44a9c7..f58dc2e0d6 100644 --- a/client/src/components/landing/components/LandingTop.js +++ b/client/src/components/landing/components/LandingTop.js @@ -1,9 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import Media from 'react-responsive'; import { Col, Row } from '@freecodecamp/react-bootstrap'; -import { Spacer, ImageLoader } from '../../helpers'; -import wideImg from '../../../assets/images/landing/wide-image.png'; +import { Spacer } from '../../helpers'; import Login from '../../Header/components/Login'; import { AmazonLogo, @@ -12,29 +10,13 @@ import { SpotifyLogo, GoogleLogo } from '../../../assets/images/components'; +import CampersImage from './CampersImage'; const propTypes = { page: PropTypes.string }; -const LARGE_SCREEN_SIZE = 1200; - function landingTop({ page }) { - const landingImageSection = ( - - - -

- freeCodeCamp students at a local study group in South Korea. -

-
- ); const BigCallToAction = ( {page === 'landing' @@ -65,7 +47,7 @@ function landingTop({ page }) { {BigCallToAction} - {landingImageSection} + diff --git a/client/src/components/layouts/variables.css b/client/src/components/layouts/variables.css index cae43b0435..002529032f 100644 --- a/client/src/components/layouts/variables.css +++ b/client/src/components/layouts/variables.css @@ -12,7 +12,7 @@ --gray-90: #0a0a23; --purple-light: #dbb8ff; --purple-dark: #5a01a7; - --yellow-light: #f1be32; + --yellow-light: #ffc300; --yellow-dark: #4d3800; --blue-light: #99c9ff; --blue-dark: #002ead; diff --git a/client/src/pages/donate.js b/client/src/pages/donate.js index c6b6a7a510..78c1be8dfd 100644 --- a/client/src/pages/donate.js +++ b/client/src/pages/donate.js @@ -9,7 +9,9 @@ import { Grid, Row, Col, Alert } from '@freecodecamp/react-bootstrap'; import { Spacer, Loader } from '../components/helpers'; import DonateForm from '../components/Donation/DonateForm'; import DonateText from '../components/Donation/DonateText'; +import DonateSupportText from '../components/Donation/DonateSupportText'; import { signInLoadingSelector, userSelector, executeGA } from '../redux'; +import CampersImage from '../components/landing/components/CampersImage'; const propTypes = { executeGA: PropTypes.func, @@ -78,43 +80,42 @@ export class DonatePage extends Component { - - -

- {isDonating - ? 'Thank You for Your Support' - : 'Become a Supporter'} -

- - -
- - - + + + {isDonating ? ( - -

- Thank you for being a supporter of freeCodeCamp. You - currently have a recurring donation. -

-
-

- If you would like to make additional donations, those - will help our nonprofit and our mission, too. -

-
- ) : null} +

Thank you for your support

+ ) : ( +

Help us do more

+ )} +
+ {isDonating ? ( + +

+ Thank you for being a supporter of freeCodeCamp. You + currently have a recurring donation. +

+
+

+ If you would like to make additional donations, those will + help our nonprofit and our mission, too. +

+
+ ) : null} + + + - - + +
diff --git a/config/donation-settings.js b/config/donation-settings.js index d4d979d9b0..a62486b784 100644 --- a/config/donation-settings.js +++ b/config/donation-settings.js @@ -1,18 +1,15 @@ // Configuration for client side const durationsConfig = { - year: 'yearly', month: 'monthly', onetime: 'one-time' }; const amountsConfig = { - year: [100000, 25000, 6000], - month: [25000, 3500, 500], - onetime: [100000, 25000, 6000] + month: [1000, 2000, 3000, 4000, 5000], + onetime: [2500, 5000, 7500, 10000, 15000] }; const defaultAmount = { - year: 25000, - month: 500, - onetime: 25000 + month: 1000, + onetime: 2500 }; const defaultDonation = { donationAmount: defaultAmount['month'], @@ -25,79 +22,54 @@ const modalDefaultDonation = { const onetimeSKUConfig = { live: [ - { amount: '100000', id: 'sku_GwHogRRJrCYGms' }, - { amount: '25000', id: 'sku_GwHnCde23uDH5R' }, - { amount: '6000', id: 'sku_H5mjFgpayAzJzT' } + { amount: '15000', id: 'sku_IElisJHup0nojP' }, + { amount: '10000', id: 'sku_IEliodY88lglPk' }, + { amount: '7500', id: 'sku_IEli9AXW8DwNtT' }, + { amount: '5000', id: 'sku_IElhJxkNh9UgDp' }, + { amount: '2500', id: 'sku_IElhQtqLgKZC8y' } ], staging: [ - { amount: '100000', id: 'sku_GvAeUdWLsmGO9O' }, - { amount: '25000', id: 'sku_GvAdXbsotjFi7G' }, - { amount: '6000', id: 'sku_GvAeJDgwjnGAdy' } + { amount: '15000', id: 'sku_IEPNpHACYJmUwz' }, + { amount: '10000', id: 'sku_IEPMY1OXxnY4WU' }, + { amount: '7500', id: 'sku_IEPLOotEqlMOWC' }, + { amount: '5000', id: 'sku_IEPKAxxAxfMnUI' }, + { amount: '2500', id: 'sku_IEPIgLRzViwq5z' } ] }; // Configuration for server side -const durationKeysConfig = ['year', 'month', 'onetime']; +const durationKeysConfig = ['month', 'onetime']; const donationOneTimeConfig = [100000, 25000, 6000]; const donationSubscriptionConfig = { duration: { - year: 'Yearly', month: 'Monthly' }, plans: { - year: [100000, 25000, 6000], month: [25000, 3500, 500] } }; // Shared paypal configuration +// keep the 5 dollars for the modal const paypalConfigTypes = { live: { month: { - '500': { - planId: 'P-1L11422374370240ULZKX3PA' - }, - '3500': { - planId: 'P-81U00703FF076883HLZ2PWMI' - }, - '25000': { - planId: 'P-7M045671FN915794KLZ2PW6I' - } - }, - year: { - '6000': { - planId: 'P-9Y661558DW462253NLZZ2IMQ' - }, - '25000': { - planId: 'P-3NN39392MK1889318LZZ2KQY' - }, - '100000': { - planId: 'P-7YN43286C4599382LLZZ2JUI' - } + '500': { planId: 'P-1L11422374370240ULZKX3PA' }, + '1000': { planId: 'P-61K21421WY874920PL6E36YI' }, + '2000': { planId: 'P-31999436LF709112VL6E374A' }, + '3000': { planId: 'P-1KY930839N8045117L6E4BKY' }, + '4000': { planId: 'P-0JW4843250567551AL6E4CAI' }, + '5000': { planId: 'P-0WR49877YD949401BL6E4CTA' } } }, staging: { month: { - '500': { - planId: 'P-37N14480BW163382FLZYPVMA' - }, - '3500': { - planId: 'P-3E678937P5715503NLZZTRVY' - }, - '25000': { - planId: 'P-97K80194AU368022JLZ2Q27Y' - } - }, - year: { - '6000': { - planId: 'P-0UY77185EM3077131LZYP6VY' - }, - '25000': { - planId: 'P-7K1585908S634694XLZZTHUQ' - }, - '100000': { - planId: 'P-0J5231134H608574XLZZTDLQ' - } + '500': { planId: 'P-37N14480BW163382FLZYPVMA' }, + '1000': { planId: 'P-28B62039J8092810UL6E3FXA' }, + '2000': { planId: 'P-7HR706961M9170433L6HI5VI' }, + '3000': { planId: 'P-35V33574BU596924JL6HI6XY' }, + '4000': { planId: 'P-45M45060289267734L6HJSXA' }, + '5000': { planId: 'P-0MD70861FY4172444L6HJTUQ' } } } };