From 67faed73d0679a03c7650052a55729fdeeaac07f Mon Sep 17 00:00:00 2001 From: Ahmad Abdolsaheb Date: Sat, 23 Dec 2023 03:19:11 +0300 Subject: [PATCH] feat: add supporters page (#52711) --- client/i18n/locales/english/links.json | 4 +- client/i18n/locales/english/translations.json | 12 +- client/src/assets/icons/supporter-badge.tsx | 29 ++++ .../components/Donation/donate-completion.tsx | 17 +- .../Donation/donation-text-components.tsx | 80 ++++++--- client/src/components/Donation/donation.css | 51 ++++-- .../Header/components/nav-links.tsx | 56 +++---- .../Header/components/universal-nav.css | 18 +++ client/src/components/layouts/global.css | 6 +- .../components/profile/components/camper.css | 6 + .../components/profile/components/camper.tsx | 11 +- client/src/pages/donate.tsx | 40 +++-- client/src/pages/supporters.tsx | 152 ++++++++++++++++++ .../default/learn/donate/donate-page-donor.ts | 10 +- .../learn/header/universal-navigation.ts | 2 +- 15 files changed, 387 insertions(+), 107 deletions(-) create mode 100644 client/src/assets/icons/supporter-badge.tsx create mode 100644 client/src/pages/supporters.tsx diff --git a/client/i18n/locales/english/links.json b/client/i18n/locales/english/links.json index ebfacc8ee93..1c6eace5e18 100644 --- a/client/i18n/locales/english/links.json +++ b/client/i18n/locales/english/links.json @@ -16,7 +16,9 @@ "other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp", "download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf", "download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf", - "one-time-url": "https://paypal.me/freecodecamp" + "one-time-url": "https://paypal.me/freecodecamp", + "one-time-external-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp/#how-can-i-make-a-one-time-donation", + "mail-check-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp/#can-i-mail-a-physical-check" }, "nav": { "contribute": "https://contribute.freecodecamp.org/#/", diff --git a/client/i18n/locales/english/translations.json b/client/i18n/locales/english/translations.json index 574df39920e..d14116e732c 100644 --- a/client/i18n/locales/english/translations.json +++ b/client/i18n/locales/english/translations.json @@ -36,6 +36,8 @@ "profile": "Profile", "news": "News", "donate": "Donate", + "supporters": "Supporters", + "go-to-supporters": "Go to Supporters Page", "update-settings": "Update my account settings", "sign-me-out": "Sign me out of freeCodeCamp", "flag-user": "Flag This User's Account for Abuse", @@ -386,6 +388,7 @@ "chal-preview": "Challenge Preview", "donation-record-not-found": "Your donation record has not been found.", "sign-in-card-update": "Sign in to update your card", + "sign-in-see-benefits": "Sign in to see your supporter benefits", "card-has-been-updated": "Your card has been updated successfully.", "contact-support-mistake": "If you think there has been a mistake, please contact us at donors@freecodecamp.org", "cert-map-estimates": { @@ -474,7 +477,7 @@ "processing": "We are processing your donation.", "redirecting": "Redirecting...", "thanks": "Thanks for donating", - "thank-you": "Thank you for being a supporter.", + "thank-you": "Thank You for Being a Supporter", "success-card-update": "Your card has been updated successfully.", "additional": "You can make an additional one-time donation of any amount using this link: <0>{{url}}", "help-more": "Help Our Charity Do More", @@ -483,7 +486,7 @@ "error-2": "Something is not right. Please contact donors@freecodecamp.org", "error-3": "Please try again or contact donors@freecodecamp.org", "free-tech": "Your donations will support free technology education for people all over the world.", - "no-halo": "If you don't see a gold halo around your profile picture, contact donors@freecodecamp.org.", + "visit-supporters": "Visit supporters page to learn about your supporter benefits.", "gift-frequency": "Select gift frequency:", "gift-amount": "Select gift amount:", "confirm": "Confirm your donation:", @@ -529,6 +532,7 @@ "why-donate-2": "You also help us create new resources for you to use to expand your own technology skills.", "bigger-donation": "Want to make a bigger one-time donation, mail us a check, or give in other ways?", "other-ways": "Here are many <0>other ways you can support our charity's mission.", + "if-support-further": "If you want to support our charity further, please consider <0>making a one-time donation, <1>sending us a check, or <2>learning about other ways you could support our charity.", "failed-pay": "Uh - oh. It looks like your transaction didn't go through. Could you please try again?", "try-again": "Please try again.", "card-number": "Your Card Number:", @@ -573,14 +577,15 @@ "bear-progress-alt": "Illustration of an adorable teddy bear with a pleading expression holding an empty money jar.", "bear-completion-alt": "Illustration of an adorable teddy bear holding a large trophy.", "crucial-contribution": "Your contribution will be crucial in creating resources that empower millions of people to learn new skills and support their families.", - "if-another-monthly": "If you want to make another monthly donation, please proceed with selecting your monthly donation amount.", "support-benefits-title": "Benefits from becoming a Supporter:", "support-benefits-1": "No more donation prompt popups", "support-benefits-2": "You'll get a Supporter badge", "support-benefits-3": "Your profile image will get a golden halo around it", "support-benefits-4": "You'll gain access to special Supporter Discord channels", "support-benefits-5": "And more benefits to come in 2024", + "exclusive-features": "Here is the list of exclusive features for you as a Supporter:", "current-initiatives-title": "Current Initiatives:", + "your-donation-helps-followings": "Your donation makes the following initiatives possible:", "current-initiatives-1": "Creating new JavaScript and Python curricula", "current-initiatives-2": "Creating English and math curricula", "current-initiatives-3": "Translating our curriculum and tutorials into 32 languages", @@ -631,6 +636,7 @@ "email": "Email", "and": "and", "update-your-card": "Update your card", + "supporters-page-title": "Supporters page", "change-theme": "Sign in to change theme.", "translation-pending": "Help us translate", "certification-project": "Certification Project", diff --git a/client/src/assets/icons/supporter-badge.tsx b/client/src/assets/icons/supporter-badge.tsx new file mode 100644 index 00000000000..d16c669078b --- /dev/null +++ b/client/src/assets/icons/supporter-badge.tsx @@ -0,0 +1,29 @@ +import React from 'react'; + +function SupporterBadge( + props: JSX.IntrinsicAttributes & React.SVGProps +): JSX.Element { + return ( + <> + + + + + ); +} + +SupporterBadge.displayName = 'SupporterBadge'; + +export default SupporterBadge; diff --git a/client/src/components/Donation/donate-completion.tsx b/client/src/components/Donation/donate-completion.tsx index 09ecf970cad..99cb4d5ff8a 100644 --- a/client/src/components/Donation/donate-completion.tsx +++ b/client/src/components/Donation/donate-completion.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'; import Spinner from 'react-spinkit'; import { Alert } from '@freecodecamp/ui'; -import { Spacer } from '../helpers'; +import { Link, Spacer } from '../helpers'; type DonateCompletionProps = { error: string | null; @@ -50,7 +50,20 @@ function DonateCompletion({ {success && (

{t('donate.free-tech')}

- {isSignedIn &&

{t('donate.no-halo')}

} + {isSignedIn && ( + <> +

{t('donate.visit-supporters')}

+ + + {t('buttons.go-to-supporters')} + + + )}
)} {error &&

{error}

} diff --git a/client/src/components/Donation/donation-text-components.tsx b/client/src/components/Donation/donation-text-components.tsx index 17c9992eedc..89ada93c1ea 100644 --- a/client/src/components/Donation/donation-text-components.tsx +++ b/client/src/components/Donation/donation-text-components.tsx @@ -33,9 +33,11 @@ export const CtaText = (): JSX.Element => { }; export const ThankYouMessage = ({ - askForDonation + askForDonation, + thankContributon }: { askForDonation: boolean; + thankContributon?: boolean; }): JSX.Element => { const { t } = useTranslation(); return ( @@ -43,25 +45,32 @@ export const ThankYouMessage = ({

{t('donate.thank-you')}

- {askForDonation && ( + {(askForDonation || thankContributon) && ( <>

{t('donate.crucial-contribution')}

-

- {t('donate.bigger-donation')}{' '} - - - placeholder - - -

-

- {t('donate.if-another-monthly')} -

)} + {askForDonation && } + + ); +}; + +export const OtherWaysToSupport = (): JSX.Element => { + const { t } = useTranslation(); + return ( + <> +

+ + placeholder + placeholder + + placeholder + + +

); }; @@ -198,27 +207,50 @@ export const DonationFaqText = (): JSX.Element => { ); }; -export const SupportBenefitsText = (): JSX.Element => { +export const SupportBenefitsText = ({ + isSupportersPage +}: { + isSupportersPage?: boolean; +}): JSX.Element => { const { t } = useTranslation(); return ( <> -

{t('donate.support-benefits-title')}

-
    -
  • {t('donate.support-benefits-1')}
  • -
  • {t('donate.support-benefits-2')}
  • -
  • {t('donate.support-benefits-3')}
  • -
  • {t('donate.support-benefits-4')}
  • -
  • {t('donate.support-benefits-5')}
  • -
+

+ {isSupportersPage + ? t('donate.exclusive-features') + : t('donate.support-benefits-title')} +

+ ); }; -export const CurrentInitiativesText = (): JSX.Element => { +const BenefitsList = (): JSX.Element => { + const { t } = useTranslation(); + return ( +
    +
  • {t('donate.support-benefits-1')}
  • +
  • {t('donate.support-benefits-2')}
  • +
  • {t('donate.support-benefits-3')}
  • +
  • {t('donate.support-benefits-4')}
  • +
  • {t('donate.support-benefits-5')}
  • +
+ ); +}; + +export const CurrentInitiativesText = ({ + isSupportersPage +}: { + isSupportersPage?: boolean; +}): JSX.Element => { const { t } = useTranslation(); return ( <> -

{t('donate.current-initiatives-title')}

+

+ {isSupportersPage + ? t('donate.your-donation-helps-followings') + : t('donate.current-initiatives-title')} +

  • {t('donate.current-initiatives-1')}
  • {t('donate.current-initiatives-2')}
  • diff --git a/client/src/components/Donation/donation.css b/client/src/components/Donation/donation.css index d0c7e221823..f48a7423864 100644 --- a/client/src/components/Donation/donation.css +++ b/client/src/components/Donation/donation.css @@ -638,22 +638,22 @@ a.patreon-button:hover { /* donation page */ -.donate-page-container h1, -.donate-page-container h2, -.donate-page-container h3 { +.donate-supporter-page-section h1, +.donate-supporter-page-section h2, +.donate-supporter-page-section h3 { font-family: var(--font-family-sans-serif); } -.donate-page-container h1 { +.donate-supporter-page-section h1 { font-size: 2.5rem; } -.donate-page-container .donation-section > div { +.donate-supporter-page-section .donation-section > div { margin-top: 40px; margin-bottom: 40px; } -.donate-page-container .donation-section { +.donate-supporter-page-section .donation-section { display: flex; justify-content: center; align-items: center; @@ -661,11 +661,12 @@ a.patreon-button:hover { min-height: 60vh; } -.donate-page-container .paypal-buttons-container { +.donate-supporter-page-section .paypal-buttons-container { margin-bottom: 0; } .dark-palette .gradient-container { + position: relative; background: linear-gradient( -10deg, rgb(7 40 94) 35%, @@ -676,6 +677,7 @@ a.patreon-button:hover { } .light-palette .gradient-container { + position: relative; background: linear-gradient( -10deg, rgb(223 243 255) 35%, @@ -689,19 +691,48 @@ a.patreon-button:hover { ); } +.supporters-background { + background-repeat: repeat; +} +.dark-palette .supporters-background { + background-image: url("data:image/svg+xml,%3Csvg width='248' height='307' viewBox='0 0 248 307' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M125 154V193.7L147.317 206.756L171 193.7V154H125ZM135.343 163.479C135.342 163.278 135.203 163.079 135.063 162.94C134.862 162.801 134.654 162.732 134.453 162.733C133.836 162.734 132.932 163.373 131.847 164.602C128.833 168.041 127.293 171.372 127.355 176.284C127.423 181.194 128.626 184.796 131.287 188.059C132.654 189.78 133.701 190.664 134.449 190.663C134.65 190.663 134.928 190.523 135.058 190.383C135.197 190.182 135.335 189.974 135.335 189.773C135.334 189.364 135.054 188.886 134.375 188.279C131.142 185.2 129.478 181.226 129.466 176.279C129.456 171.807 131.037 168.1 134.181 165.072C134.935 164.298 135.343 163.827 135.343 163.479ZM151.577 177.164C151.27 177.086 151.37 176.642 151.535 175.907C152.005 173.812 153.006 169.354 146.627 164.277C146.627 164.277 147.758 167.869 142.058 175.884C136.656 183.474 143.763 188.158 144.528 188.631C144.57 188.658 144.594 188.671 144.594 188.671C144.594 188.671 144.571 188.657 144.528 188.631C144.038 188.314 141.08 186.034 145.222 179.273C145.465 178.871 145.731 178.48 146.019 178.056C146.686 177.076 147.474 175.917 148.386 174.024C148.386 174.024 149.543 175.657 148.939 179.198C148.14 183.933 151.822 183.279 152.733 183.118C152.851 183.097 152.923 183.084 152.931 183.093C154.584 185.039 151.648 188.434 151.362 188.661C151.347 188.671 151.343 188.674 151.349 188.671C151.353 188.669 151.357 188.665 151.362 188.661L151.364 188.66C151.791 188.376 159.911 182.969 153.762 174.978C153.64 175.101 153.507 175.351 153.353 175.64C152.958 176.382 152.426 177.382 151.577 177.164ZM160.773 163.476C160.773 163.275 160.912 163.075 161.052 162.936C161.253 162.798 161.461 162.729 161.662 162.729C162.279 162.731 163.183 163.369 164.268 164.598C167.282 168.037 168.822 171.368 168.76 176.28C168.692 181.19 167.489 184.793 164.828 188.055C163.461 189.776 162.414 190.661 161.666 190.659C161.465 190.658 161.187 190.519 161.057 190.38C160.918 190.179 160.78 189.97 160.78 189.77C160.781 189.361 161.061 188.883 161.741 188.275C164.973 185.196 166.637 181.223 166.649 176.276C166.659 171.804 165.078 168.096 161.934 165.069C161.18 164.294 160.772 163.823 160.773 163.476Z' fill='%23FEB13E' fill-opacity='0.1'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 1V40.6997L22.3168 53.7558L46 40.6997V1H0ZM10.3425 10.4794C10.3419 10.2784 10.2026 10.0786 10.0633 9.93991C9.86238 9.80119 9.65373 9.73242 9.45338 9.73301C8.83631 9.7342 7.93176 10.3727 6.84701 11.6016C3.83281 15.0406 2.29282 18.3718 2.35506 23.284C2.42263 28.1938 3.62594 31.7964 6.28744 35.0588C7.65435 36.7798 8.70116 37.6643 9.44923 37.6625C9.64958 37.6625 9.92759 37.5226 10.058 37.3833C10.1967 37.1823 10.3348 36.9736 10.3348 36.7733C10.3336 36.3642 10.0544 35.8864 9.37454 35.2787C6.14162 32.1996 4.47833 28.2264 4.46648 23.2792C4.45581 18.8075 6.03729 15.0999 9.1813 12.0723C9.93529 11.2981 10.3431 10.8268 10.3425 10.4794ZM26.5768 24.1643C26.2701 24.0859 26.3698 23.6417 26.5348 22.9069C27.0051 20.8118 28.006 16.3539 21.6273 11.2767C21.6273 11.2767 22.7577 14.8686 17.0577 22.8843C11.6557 30.4742 18.7628 35.1577 19.5279 35.6309C19.5697 35.6578 19.5935 35.6705 19.5935 35.6705C19.5935 35.6705 19.5706 35.6572 19.5279 35.6309C19.038 35.3145 16.0798 33.0339 20.2218 26.273C20.4649 25.8708 20.7306 25.4802 21.0191 25.056C21.6856 24.0761 22.4739 22.9172 23.386 21.024C23.386 21.024 24.5431 22.6573 23.939 26.1983C23.1397 30.9329 26.822 30.2793 27.7326 30.1177C27.8511 30.0967 27.9227 30.084 27.9313 30.0926C29.5844 32.0392 26.6478 35.4336 26.3624 35.6611C26.3474 35.6711 26.3427 35.6743 26.3492 35.6705C26.3526 35.6685 26.357 35.6654 26.3624 35.6611L26.3637 35.6602C26.7912 35.3756 34.9112 29.9691 28.7623 21.9785C28.6397 22.1011 28.5067 22.351 28.3528 22.6403C27.9583 23.3816 27.4261 24.3817 26.5768 24.1643ZM35.7725 10.4757C35.7731 10.2747 35.9124 10.075 36.0517 9.93623C36.2527 9.79751 36.4613 9.72874 36.6617 9.72933C37.2787 9.73052 38.1833 10.369 39.2681 11.5979C42.2822 15.037 43.8222 18.3681 43.76 23.2803C43.6924 28.1901 42.4891 31.7928 39.8276 35.0551C38.4607 36.7761 37.4139 37.6606 36.6658 37.6588C36.4655 37.6582 36.1875 37.5189 36.0571 37.3796C35.9184 37.1786 35.7802 36.97 35.7802 36.7696C35.7814 36.3605 36.0606 35.8827 36.7405 35.2751C39.9734 32.1959 41.6367 28.2227 41.6486 23.2755C41.6592 18.8038 40.0778 15.0956 36.9338 12.0686C36.1798 11.2944 35.7719 10.8231 35.7725 10.4757Z' fill='%23FEB13E' fill-opacity='0.1'/%3E%3C/svg%3E%0A"); +} + +.light-palette .supporters-background { + background-image: url("data:image/svg+xml,%3Csvg width='248' height='307' viewBox='0 0 248 307' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M125 154V193.7L147.317 206.756L171 193.7V154H125ZM135.343 163.479C135.342 163.278 135.203 163.079 135.063 162.94C134.862 162.801 134.654 162.732 134.453 162.733C133.836 162.734 132.932 163.373 131.847 164.602C128.833 168.041 127.293 171.372 127.355 176.284C127.423 181.194 128.626 184.796 131.287 188.059C132.654 189.78 133.701 190.664 134.449 190.663C134.65 190.663 134.928 190.523 135.058 190.383C135.197 190.182 135.335 189.974 135.335 189.773C135.334 189.364 135.054 188.886 134.375 188.279C131.142 185.2 129.478 181.226 129.466 176.279C129.456 171.807 131.037 168.1 134.181 165.072C134.935 164.298 135.343 163.827 135.343 163.479ZM151.577 177.164C151.27 177.086 151.37 176.642 151.535 175.907C152.005 173.812 153.006 169.354 146.627 164.277C146.627 164.277 147.758 167.869 142.058 175.884C136.656 183.474 143.763 188.158 144.528 188.631C144.57 188.658 144.594 188.671 144.594 188.671C144.594 188.671 144.571 188.657 144.528 188.631C144.038 188.314 141.08 186.034 145.222 179.273C145.465 178.871 145.731 178.48 146.019 178.056C146.686 177.076 147.474 175.917 148.386 174.024C148.386 174.024 149.543 175.657 148.939 179.198C148.14 183.933 151.822 183.279 152.733 183.118C152.851 183.097 152.923 183.084 152.931 183.093C154.584 185.039 151.648 188.434 151.362 188.661C151.347 188.671 151.343 188.674 151.349 188.671C151.353 188.669 151.357 188.665 151.362 188.661L151.364 188.66C151.791 188.376 159.911 182.969 153.762 174.978C153.64 175.101 153.507 175.351 153.353 175.64C152.958 176.382 152.426 177.382 151.577 177.164ZM160.773 163.476C160.773 163.275 160.912 163.075 161.052 162.936C161.253 162.798 161.461 162.729 161.662 162.729C162.279 162.731 163.183 163.369 164.268 164.598C167.282 168.037 168.822 171.368 168.76 176.28C168.692 181.19 167.489 184.793 164.828 188.055C163.461 189.776 162.414 190.661 161.666 190.659C161.465 190.658 161.187 190.519 161.057 190.38C160.918 190.179 160.78 189.97 160.78 189.77C160.781 189.361 161.061 188.883 161.741 188.275C164.973 185.196 166.637 181.223 166.649 176.276C166.659 171.804 165.078 168.096 161.934 165.069C161.18 164.294 160.772 163.823 160.773 163.476Z' fill='%23FEB13E' fill-opacity='0.2'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 1V40.6997L22.3168 53.7558L46 40.6997V1H0ZM10.3425 10.4794C10.3419 10.2784 10.2026 10.0786 10.0633 9.93991C9.86238 9.80119 9.65373 9.73242 9.45338 9.73301C8.83631 9.7342 7.93176 10.3727 6.84701 11.6016C3.83281 15.0406 2.29282 18.3718 2.35506 23.284C2.42263 28.1938 3.62594 31.7964 6.28744 35.0588C7.65435 36.7798 8.70116 37.6643 9.44923 37.6625C9.64958 37.6625 9.92759 37.5226 10.058 37.3833C10.1967 37.1823 10.3348 36.9736 10.3348 36.7733C10.3336 36.3642 10.0544 35.8864 9.37454 35.2787C6.14162 32.1996 4.47833 28.2264 4.46648 23.2792C4.45581 18.8075 6.03729 15.0999 9.1813 12.0723C9.93529 11.2981 10.3431 10.8268 10.3425 10.4794ZM26.5768 24.1643C26.2701 24.0859 26.3698 23.6417 26.5348 22.9069C27.0051 20.8118 28.006 16.3539 21.6273 11.2767C21.6273 11.2767 22.7577 14.8686 17.0577 22.8843C11.6557 30.4742 18.7628 35.1577 19.5279 35.6309C19.5697 35.6578 19.5935 35.6705 19.5935 35.6705C19.5935 35.6705 19.5706 35.6572 19.5279 35.6309C19.038 35.3145 16.0798 33.0339 20.2218 26.273C20.4649 25.8708 20.7306 25.4802 21.0191 25.056C21.6856 24.0761 22.4739 22.9172 23.386 21.024C23.386 21.024 24.5431 22.6573 23.939 26.1983C23.1397 30.9329 26.822 30.2793 27.7326 30.1177C27.8511 30.0967 27.9227 30.084 27.9313 30.0926C29.5844 32.0392 26.6478 35.4336 26.3624 35.6611C26.3474 35.6711 26.3427 35.6743 26.3492 35.6705C26.3526 35.6685 26.357 35.6654 26.3624 35.6611L26.3637 35.6602C26.7912 35.3756 34.9112 29.9691 28.7623 21.9785C28.6397 22.1011 28.5067 22.351 28.3528 22.6403C27.9583 23.3816 27.4261 24.3817 26.5768 24.1643ZM35.7725 10.4757C35.7731 10.2747 35.9124 10.075 36.0517 9.93623C36.2527 9.79751 36.4613 9.72874 36.6617 9.72933C37.2787 9.73052 38.1833 10.369 39.2681 11.5979C42.2822 15.037 43.8222 18.3681 43.76 23.2803C43.6924 28.1901 42.4891 31.7928 39.8276 35.0551C38.4607 36.7761 37.4139 37.6606 36.6658 37.6588C36.4655 37.6582 36.1875 37.5189 36.0571 37.3796C35.9184 37.1786 35.7802 36.97 35.7802 36.7696C35.7814 36.3605 36.0606 35.8827 36.7405 35.2751C39.9734 32.1959 41.6367 28.2227 41.6486 23.2755C41.6592 18.8038 40.0778 15.0956 36.9338 12.0686C36.1798 11.2944 35.7719 10.8231 35.7725 10.4757Z' fill='%23FEB13E' fill-opacity='0.2'/%3E%3C/svg%3E%0A"); +} + @media screen and (min-width: 991px) { - .donate-page-container .form-payment-methods { + .donate-supporter-page-section .form-payment-methods { height: 22px; width: 220px; } } @media screen and (min-width: 1200px) { - .donate-page-container .form-payment-methods { + .donate-supporter-page-section .form-payment-methods { height: 25px; width: 250px; } - .donate-page-container .donation-section { + .donate-supporter-page-section .donation-section { flex-direction: row; } } + +.supporter-badge-container { + width: 100%; + display: flex; + align-items: center; + justify-content: center; + padding: 2em 0; +} + +@media screen and (min-width: 1200px) { + .supporter-badge-container { + justify-content: left; + } +} +.supporter-badge-container svg { + height: 6em; + width: auto; +} diff --git a/client/src/components/Header/components/nav-links.tsx b/client/src/components/Header/components/nav-links.tsx index 26dd4fe871c..83d730ea9d5 100644 --- a/client/src/components/Header/components/nav-links.tsx +++ b/client/src/components/Header/components/nav-links.tsx @@ -1,8 +1,7 @@ import { faCheckSquare, faSquare, - faExternalLinkAlt, - faHeart + faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import React, { Fragment } from 'react'; @@ -14,6 +13,7 @@ import { updateMyTheme } from '../../../redux/settings/actions'; import { Link } from '../../helpers'; import { type ThemeProps, Themes } from '../../settings/theme'; import { User } from '../../../redux/prop-types'; +import SupporterBadge from '../../../assets/icons/supporter-badge'; export interface NavLinksProps extends Pick { displayMenu: boolean; @@ -34,42 +34,34 @@ interface DonateButtonProps { handleMenuKeyDown: (event: React.KeyboardEvent) => void; } -type DonateItemProps = Pick & { - donateText: string; -}; - -const DonateItem = ({ handleMenuKeyDown, donateText }: DonateItemProps) => ( -
  • - - {donateText} - -
  • -); - -const ThankYouMessage = ({ message }: { message: string }) => ( -
  • - {message} - -
  • -); - const DonateButton = ({ isUserDonating, handleMenuKeyDown }: DonateButtonProps) => { const { t } = useTranslation(); - if (isUserDonating) return ; return ( - +
  • + + {isUserDonating ? ( + <> + {t('buttons.supporters')} + + + ) : ( + <>{t('buttons.donate')} + )} + +
  • ); }; diff --git a/client/src/components/Header/components/universal-nav.css b/client/src/components/Header/components/universal-nav.css index 37dc3b63058..2cc70158347 100644 --- a/client/src/components/Header/components/universal-nav.css +++ b/client/src/components/Header/components/universal-nav.css @@ -172,6 +172,24 @@ li > button.nav-link-signout:not([aria-disabled='true']):is(:hover, :focus) { color: var(--gray-45); } +.nav-link-supporter { + color: var(--yellow-light); + background: var(--yellow-dark); +} + +.nav-link-supporter:hover, +.nav-link-supporter:active, +.nav-link-supporter:focus, +.nav-link-supporter:focus-visible { + color: var(--yellow-dark) !important; + background: var(--yellow-light) !important; +} + +.nav-link-supporter svg { + height: auto; + width: 1em; +} + /** * Check mark for current language */ diff --git a/client/src/components/layouts/global.css b/client/src/components/layouts/global.css index 199f1681213..cf4113f1954 100644 --- a/client/src/components/layouts/global.css +++ b/client/src/components/layouts/global.css @@ -523,9 +523,9 @@ blockquote .small { .alert .btn, [role='alert'] .btn { - background-color: #d9edf7; - color: #31708f; - border-color: #31708f; + background-color: transparent; + color: inherit; + border-color: inherit; } .alert .btn:hover, .alert .btn:focus, diff --git a/client/src/components/profile/components/camper.css b/client/src/components/profile/components/camper.css index fbd7bbed570..30c7de28358 100644 --- a/client/src/components/profile/components/camper.css +++ b/client/src/components/profile/components/camper.css @@ -23,3 +23,9 @@ .avatar-camper .avatar-container { border-width: 10px; } + +.supporter svg { + height: 1.2em; + width: auto; + margin: 0 0.2em -0.3em 0.2em; +} diff --git a/client/src/components/profile/components/camper.tsx b/client/src/components/profile/components/camper.tsx index 92a6b1a3579..4df83eef13b 100644 --- a/client/src/components/profile/components/camper.tsx +++ b/client/src/components/profile/components/camper.tsx @@ -1,8 +1,4 @@ -import { - faAward, - faCalendar, - faHeart -} from '@fortawesome/free-solid-svg-icons'; +import { faAward, faCalendar } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import React from 'react'; import type { TFunction } from 'i18next'; @@ -14,6 +10,7 @@ import { getLangCode } from '../../../../../shared/config/i18n'; import type { User } from '../../../redux/prop-types'; import { AvatarRenderer } from '../../helpers'; import Link from '../../helpers/link'; +import SupporterBadge from '../../../assets/icons/supporter-badge'; import SocialIcons from './social-icons'; import './camper.css'; @@ -85,7 +82,6 @@ function Camper({ isDonating={isDonating} isTopContributor={yearsTopContributor.length > 0} picture={picture} - userName={username} /> @@ -102,7 +98,8 @@ function Camper({ {location &&

    {location}

    } {isDonating && (

    - {t('profile.supporter')} + + {t('profile.supporter')}

    )} {about &&

    {about}

    } diff --git a/client/src/pages/donate.tsx b/client/src/pages/donate.tsx index 17104859f0a..b57ed84cf53 100644 --- a/client/src/pages/donate.tsx +++ b/client/src/pages/donate.tsx @@ -82,24 +82,30 @@ function DonatePage({ <> - - - - {isDonating ? ( - - ) : ( - - )} - - - - - + +
    + + + {isDonating ? ( + + ) : ( + + )} + + + {!isDonating || donationFormState.success ? ( + + ) : null} + + +
    - + @@ -133,7 +139,7 @@ function DonatePage({ - + diff --git a/client/src/pages/supporters.tsx b/client/src/pages/supporters.tsx new file mode 100644 index 00000000000..acd69356d18 --- /dev/null +++ b/client/src/pages/supporters.tsx @@ -0,0 +1,152 @@ +import React from 'react'; +import Helmet from 'react-helmet'; +import { withTranslation, useTranslation } from 'react-i18next'; +import { connect } from 'react-redux'; +import { createSelector } from 'reselect'; +import { Container, Row, Col } from '@freecodecamp/ui'; +import BigCallToAction from '../components/landing/components/big-call-to-action'; + +import { Spacer } from '../components/helpers'; +import { + isSignedInSelector, + isDonatingSelector, + updateCardStateSelector +} from '../redux/selectors'; +import { updateCard, updateCardComplete } from '../redux/actions'; +import { UpdateCardState } from '../redux/types'; + +import { + DonationFaqText, + ThankYouMessage, + SupportBenefitsText, + CurrentInitiativesText +} from '../components/Donation/donation-text-components'; +import SupporterBadge from '../assets/icons/supporter-badge'; + +interface SupportersPageProps { + isNewEmail: boolean; + resetDonationFormState: () => void; + isSignedIn: boolean; + isDonating: boolean; + updateCardState: UpdateCardState; + updateCard: () => void; + updateCardComplete: () => void; +} + +const mapStateToProps = createSelector( + isSignedInSelector, + isDonatingSelector, + updateCardStateSelector, + ( + isSignedIn: boolean, + isDonating: boolean, + updateCardState: UpdateCardState + ) => ({ + isSignedIn, + isDonating, + updateCardState + }) +); + +const mapDispatchToProps = { updateCard, updateCardComplete }; + +function ConditionalContent({ + isSignedIn, + isDonating +}: { + isSignedIn: boolean; + isDonating: boolean; +}) { + const { t } = useTranslation(); + + if (isSignedIn && !isDonating) { + return ( + + +

    + {t('learn.donation-record-not-found')} +

    + +

    {t('learn.contact-support-mistake')}

    + + + ); + } else if (isSignedIn && isDonating) { + return ( + <> + +
    + +
    + + + + + + + + + ); + } else + return ( + + +

    + {t('learn.sign-in-see-benefits')} +

    + + + + + ); +} + +function SupportersPage({ isSignedIn, isDonating }: SupportersPageProps) { + const { t } = useTranslation(); + + return ( + <> + + {t('misc.supporters-page-title')} | freeCodeCamp.org + + + +
    + + + +
    +
    +
    + + + +
    + +
    +
    + + + + + + + + + + + ); +} + +SupportersPage.displayName = 'Supporters-Page'; + +export default connect( + mapStateToProps, + mapDispatchToProps +)(withTranslation()(SupportersPage)); diff --git a/cypress/e2e/default/learn/donate/donate-page-donor.ts b/cypress/e2e/default/learn/donate/donate-page-donor.ts index 25cd8494b38..4b3cb4e6546 100644 --- a/cypress/e2e/default/learn/donate/donate-page-donor.ts +++ b/cypress/e2e/default/learn/donate/donate-page-donor.ts @@ -8,24 +8,20 @@ describe('Donate page', () => { cy.visit('/donate'); cy.get('[data-cy="donate.thank-you"]').should( 'have.text', - 'Thank you for being a supporter.' + 'Thank You for Being a Supporter' ); cy.get('[data-cy="donate.crucial-contribution"]').should( 'have.text', 'Your contribution will be crucial in creating resources that empower millions of people to learn new skills and support their families.' ); - cy.get('[data-cy="donate.bigger-donation"]').should( + cy.get('[data-cy="donate.if-support-further"]').should( 'have.text', - "Want to make a bigger one-time donation, mail us a check, or give in other ways? Here are many other ways you can support our charity's mission." + 'If you want to support our charity further, please consider making a one-time donation, sending us a check, or learning about other ways you could support our charity.' ); cy.get('[data-cy="donate-link"]').should( 'contain.attr', 'href', 'https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp' ); - cy.get('[data-cy="donate.make-another-monthly"]').should( - 'have.text', - 'If you want to make another monthly donation, please proceed with selecting your monthly donation amount.' - ); }); }); diff --git a/cypress/e2e/default/learn/header/universal-navigation.ts b/cypress/e2e/default/learn/header/universal-navigation.ts index 5949807032a..17173ba8533 100644 --- a/cypress/e2e/default/learn/header/universal-navigation.ts +++ b/cypress/e2e/default/learn/header/universal-navigation.ts @@ -104,7 +104,7 @@ describe('Donor Navigation Menu', () => { 'have.class', 'gold-border' ); - cy.get(navigationItems['navigation-list']).contains('Thanks for donating'); + cy.get(navigationItems['navigation-list']).contains('Supporters'); }); });