diff --git a/README.md b/README.md
index 158dd3ea0..825cd8c9a 100644
--- a/README.md
+++ b/README.md
@@ -100,7 +100,9 @@ Watch releases of this repository to be notified about future updates:
## Contributors ✨
+
[![All Contributors](https://img.shields.io/badge/all_contributors-76-orange.svg?style=flat-square)](#contributors-)
+
Please check [contributors guide](https://github.com/podkrepi-bg/frontend/blob/master/CONTRIBUTING.md) for:
diff --git a/next.config.js b/next.config.js
index 963dfefc6..a968f4c27 100644
--- a/next.config.js
+++ b/next.config.js
@@ -53,8 +53,8 @@ const moduleExports = {
},
{
source: '/robots.txt',
- destination: '/api/robots'
- }
+ destination: '/api/robots',
+ },
]
},
async redirects() {
diff --git a/public/locales/bg/auth.json b/public/locales/bg/auth.json
index 77cf1f132..440e59019 100644
--- a/public/locales/bg/auth.json
+++ b/public/locales/bg/auth.json
@@ -12,6 +12,7 @@
},
"cta": {
"login": "Вход",
+ "guest": "Като гост",
"logout": "Изход",
"register": "Регистрация",
"send": "Изпрати",
@@ -19,6 +20,7 @@
},
"fields": {
"email": "Email",
+ "email-descriptive": "Въведи email адрес",
"password": "Парола",
"confirm-password": "Потвърждение на парола",
"first-name": "Име",
diff --git a/public/locales/bg/campaigns.json b/public/locales/bg/campaigns.json
index 7d85d65e0..6bf51eda7 100644
--- a/public/locales/bg/campaigns.json
+++ b/public/locales/bg/campaigns.json
@@ -73,7 +73,14 @@
"save": "Запази",
"submit": "Изпрати",
"apply": "Кандидатствайте",
- "subscribe": "Абониране за известия",
+ "subscribe": "Абонирай се за email известия за кампанията",
+ "subscribeFooter": "Абонирай се за бюлетина",
+ "subscribeGeneral": "Абонирайте се за email известия от Подкрепи.бг",
+ "subscribe-monthly-newsletter": "Месечен бюлтеин на Подкрепи.бг",
+ "subscribeGeneralSubtext": "Получавайте нашия месечен бюлетин, в който ще Ви информираме за най-интересните новини от Подкрепи.бг!",
+ "subscribe-general-monthly-newsletter": "Получавайте нашия месечен бюлетин, за да сте в час най-интересните новини от Подкрепи.бг!",
+ "subscribeGeneralButton": "Абонирайте се за новини",
+ "subscribe-general-newsletter-button": "Абонирайте се",
"support": "Дарете",
"support-cause-today": "Подкрепете кауза днес!",
"support-now": "Подкрепете сега",
@@ -95,10 +102,18 @@
"allow-donation-on-complete": "Разрешете дарения след достигане на сумата"
},
"subscribe": {
- "confirm-sent": "Благодарим ви! На посочения e-mail адрес беше изпратено съобщение за потвърждение на вашето абониране.",
- "confirm-subscribe": "Благодарим ви! Абонирахте се успешно.",
- "subscribe-title": "Абониране за известия и новини от Podkrepi.bg",
- "subscribe-campaign-title": "Абониране за известия по тази кампания"
+ "confirm-sent": "Моля, активирай абонамента си от email-a, който ти изпратихме на {{email}}",
+ "confirm-subscribe": "Записа се успешно.",
+ "subscribe-title": "Абониране за новините на Подкрепи.бг",
+ "subscribe-campaign-title": "Абониране за новините по кампанията",
+ "subscribe-text-nonLoggedUser": "Моля, продължи като гост и въведи email адреса, на който желаеш да получаваш известия за тази кампания, или влез в профила си. Вписвайки се с потребителското си име и парола, ще можеш да управляваш абонамента си от своя Личен профил.",
+ "subscribe-text-nonLoggedUser-general": "Моля, продължи като гост и въведи email адреса, на който желаеш да получаваш известия от нас, или влез в профила си. Вписвайки се с потребителското си име и парола, ще можеш да управляваш абонамента си от своя Личен профил.",
+ "subscribe-text-loggedUser": "Моля, избери дали желаеш да получаваш новините за кампанията на email адреса, асоцииран с профила ти, или на алтернативен адрес:",
+ "subscribe-subtitle": "Искам да получавам новини и известия от Подкрепи.бг на този email адрес:",
+ "subscribe-campaign-subtTitle": "Искам да получавам новини за кампанията на този email адрес:",
+ "subscribe-button": "Запиши ме",
+ "profile-button": "На профилния",
+ "another-button": "На друг"
},
"campaign": {
"subheading": "Вашата подкрепа променя света и има значение. Всички подкрепящи чрез Подкрепи.бг са наши партньори в подпомагането на кампании за общността. Като щедър дарител Вие ставате важен партньор в подпомагането на кампания за нечие здраве или за успеха на кауза, която ви е близка до сърцето.",
diff --git a/public/locales/bg/index.json b/public/locales/bg/index.json
index e2d2e6ef3..732554929 100644
--- a/public/locales/bg/index.json
+++ b/public/locales/bg/index.json
@@ -10,6 +10,10 @@
"content": "Подкрепи.бг представлява общност от специалисти в областта на програмирането, правото, маркетинга, дизайна, медицината, финансите, социалното предприемачество и др. Обединени сме от целта да създадем устойчива и прозрачна платформа за дарения, която подкрепя каузи и хора в нужда, като заедно с това популяризира и връща доверието към дарителството в България.",
"meet-our-team": "Запознайте се с екипа ни"
},
+ "subscription-section": {
+ "heading": "Искаш да си в час с бъдещите ни постижения?",
+ "content": "Абонирай се за нашия бюлетин и ние ще те информираме за най-важното от живота на Подкрепи.бг. Всеки месец ще получваш email от нас, в който ще ти споделяме най-интересното за кампаниите, които поддържаме, както и за техните организатори и бенефициенти. Ще получаваш новините за нашите партньори, доброволци и дарители в електронната си пощенска кутия. Ако ти звучи добре, запиши се, като въведеш email адреса си тук:"
+ },
"support-us-section": {
"heading": "Подкрепете ни като:",
"financial-support": "- дарител",
diff --git a/public/locales/bg/notifications.json b/public/locales/bg/notifications.json
index b65e5c755..6a1a3a9fa 100644
--- a/public/locales/bg/notifications.json
+++ b/public/locales/bg/notifications.json
@@ -1,7 +1,9 @@
{
"subscribe": {
- "thank-you-msg": "Абонирането за получаване на известия e успешно! Благодарим ❤️",
- "subscription-fail": "Възникна проблем при потвърджаването на абонамента за известия 🙄",
+ "thank-you-msg-heading": "Абонаментът ти е активен!",
+ "thank-you-msg-text": "Успешно активира своя абонамент. Очаквай новини от нас на {{email}}",
+ "subscription-fail-heading": "Възникна грешка",
+ "subscription-fail-text": "Не успяхме да активираме абонамента ти. Моля, опитай пак.",
"cta": "Към сайта",
"cta-retry": "Опитай пак"
},
diff --git a/public/locales/bg/profile.json b/public/locales/bg/profile.json
index 6de138c5f..d6e713daf 100644
--- a/public/locales/bg/profile.json
+++ b/public/locales/bg/profile.json
@@ -56,7 +56,6 @@
"refund": "възстановено",
"cancelled": "отменено",
"guaranteed": "гарантирано"
-
}
},
"certificates-history": {
diff --git a/public/locales/bg/validation.json b/public/locales/bg/validation.json
index 3018432bb..ef89b0927 100644
--- a/public/locales/bg/validation.json
+++ b/public/locales/bg/validation.json
@@ -16,6 +16,7 @@
"agree-terms": "Съгласявам се с Общите условия",
"agree-with": "Съгласявам се с",
"agree-with-newsletter": "Съгласявам се да получавам известия ",
+ "agree-with-newsletter-campaign": "Съгласявам се да получавам новини за тази кампания и известия от Подкрепи.бг *",
"informed-agree-with": "Запознат съм и се съгласявам с",
"terms-and-conditions": "общите условия",
"gdpr": "политиката за защита на личните данни",
diff --git a/public/locales/en/auth.json b/public/locales/en/auth.json
index 0e11270fb..8fb087a09 100644
--- a/public/locales/en/auth.json
+++ b/public/locales/en/auth.json
@@ -11,6 +11,7 @@
},
"cta": {
"login": "Login",
+ "guest": "As guest",
"logout": "Logout",
"register": "Register",
"send": "Send",
@@ -18,6 +19,7 @@
},
"fields": {
"email": "Email",
+ "email-descriptive": "Fill in your email",
"password": "Password",
"confirm-password": "Confirm Password",
"first-name": "First name",
diff --git a/public/locales/en/campaigns.json b/public/locales/en/campaigns.json
index b147a792f..12d24f108 100644
--- a/public/locales/en/campaigns.json
+++ b/public/locales/en/campaigns.json
@@ -74,6 +74,14 @@
"save": "Save",
"submit": "Submit",
"apply": "Apply",
+ "subscribe": "Subscribe for email notifications for the campaign",
+ "subscribeFooter": "Subscribe for the newsletter",
+ "subscribeGeneral": "Subscribe for email notifications from Podkrepi.bg",
+ "subscribe-monthly-newsletter": "Monthly newsletter of Podkrepi.bg",
+ "subscribeGeneralSubtext": "Receive our monthly newsletter which will inform you about the most interesting news from Podkrepi.bg!!",
+ "subscribe-general-monthly-newsletter": "Receive our monthly newsletter so that you are aware of the most interesting news from Podkrepi.bg!",
+ "subscribeGeneralButton": "Subscribe for news",
+ "subscribe-general-newsletter-button": "Subscribe",
"support": "Donate",
"support-cause-today": "Support a campaign today!",
"support-now": "Support now",
@@ -93,6 +101,20 @@
"attached-files": "Attached files",
"download": "Download"
},
+ "subscribe": {
+ "confirm-sent": "Please, activate your subscription from the email that we sent to {{email}}",
+ "confirm-subscribe": "You subscribed successfully",
+ "subscribe-title": "Subscribe for news from Podkrepi.bg",
+ "subscribe-campaign-title": "Subscribe for news about the campaign",
+ "subscribe-text-nonLoggedUser": "Please, proceed as a guest and write down your email, on which you want to receive notifications for this campaign or you can log in. If you log in with your and password you will be able to manage your subscription from your Personal profile",
+ "subscribe-text-nonLoggedUser-general": "Please, proceed as a guest and write down your email, on which you want to receive notifications from us or you can log in. If you log in with your and password you will be able to manage your subscription from your Personal profile",
+ "subscribe-text-loggedUser": "Please, choose if you want to receive the news about the campaign on your profile email or on another one:",
+ "subscribe-subtitle": "I want to receive news and notifications from Podkrepi.bg on this email:",
+ "subscribe-campaign-subtTitle": "I want to receive news about the campaign on this email:",
+ "subscribe-button": "Subscribe me",
+ "profile-button": "On the profile one",
+ "another-button": "On another one"
+ },
"campaign": {
"subheading": "Your support for the world matters. All supporters through Podkrepi.bg are our partners in supporting the community campaign. As a generous benefactor, you become an important partner in supporting a campaign regarding someone's health or the success of a cause that is close to your heart.",
"subheading-bold": "Even the slightest help can be the engine of great change",
diff --git a/public/locales/en/index.json b/public/locales/en/index.json
index bc92241a8..2f546d6c5 100644
--- a/public/locales/en/index.json
+++ b/public/locales/en/index.json
@@ -10,6 +10,10 @@
"content": "Podkrepi.bg is a community of specialists in the field of programming, law, marketing, design, medicine, finance, social entrepreneurship and others. We are united by the goal of creating a sustainable and transparent donation platform that supports causes and people in need, while promoting and restoring trust in donations in Bulgaria.",
"meet-our-team": "Meet our team"
},
+ "subscription-section": {
+ "heading": "You want to know about our future achievements?",
+ "content": "Subscribe for our newsletter we will infrom you about the most important from the life of Podkrepi.bg. Every month you will receive email from us in which we will share with you the most important things about the campaigns that we have and their organizers and beneficiaries. You will receive news for our partners, volunteers and donors in your email box. If this sounds good for you, subscribe as you fill in your email here:"
+ },
"support-us-section": {
"heading": "Support us as:",
"financial-support": "- a benefactor",
diff --git a/public/locales/en/notifications.json b/public/locales/en/notifications.json
new file mode 100644
index 000000000..3d9f6a360
--- /dev/null
+++ b/public/locales/en/notifications.json
@@ -0,0 +1,16 @@
+{
+ "subscribe": {
+ "thank-you-msg-heading": "Your subscription is active!",
+ "thank-you-msg-text": "You successfully activated your subscription. You can wait news from us on {{email}}",
+ "subscription-fail-heading": "An error occurred",
+ "subscription-fail-text": "We couldn`t activate your subscription. Please, try again.",
+ "cta": "To the site",
+ "cta-retry": "Try again"
+ },
+ "unsubscribe": {
+ "thank-you-msg": "You successfully deactivated your news subscription!",
+ "subscription-fail": "An error occurred while deactivating your news subscription",
+ "cta": "To the site",
+ "cta-retry": "Try again"
+ }
+}
diff --git a/public/locales/en/validation.json b/public/locales/en/validation.json
index a91ffb1ac..4e1a9592e 100644
--- a/public/locales/en/validation.json
+++ b/public/locales/en/validation.json
@@ -16,6 +16,8 @@
"agree-terms": "Agree to the Terms and Conditions",
"agree-with": "I agree to the",
"informed-agree-with": "I understand and I agree to the",
+ "agree-with-newsletter": "I agree to receive news",
+ "agree-with-newsletter-campaign": "I agree to receive news about this campaign and news by Podkrepi.bg *",
"terms-and-conditions": "Terms and Conditions",
"gdpr": "General Data Protection Regulation (GDPR)",
"legal-entity": "Legal entity",
diff --git a/src/components/client/auth/register/CorporateRegisterForm.tsx b/src/components/client/auth/register/CorporateRegisterForm.tsx
index 3418905cb..35b1e2caa 100644
--- a/src/components/client/auth/register/CorporateRegisterForm.tsx
+++ b/src/components/client/auth/register/CorporateRegisterForm.tsx
@@ -9,7 +9,7 @@ import PasswordField from 'components/common/form/PasswordField'
import AcceptPrivacyPolicyField from 'components/common/form/AcceptPrivacyPolicyField'
import AcceptTermsField from 'components/common/form/AcceptTermsField'
import EmailField from 'components/common/form/EmailField'
-import AcceptNewsLetterField from 'components/common/form/AcceptNewsletterField'
+import { AcceptNewsLetterField } from 'components/common/form/AcceptNewsletterField'
import { AccountType } from 'gql/user-registration'
import { validateEIK13, validateEIK9 } from 'components/common/validations/EIKValidator'
diff --git a/src/components/client/auth/register/RegisterForm.tsx b/src/components/client/auth/register/RegisterForm.tsx
index b56f2a08c..5ee114f58 100644
--- a/src/components/client/auth/register/RegisterForm.tsx
+++ b/src/components/client/auth/register/RegisterForm.tsx
@@ -9,7 +9,7 @@ import PasswordField from 'components/common/form/PasswordField'
import AcceptPrivacyPolicyField from 'components/common/form/AcceptPrivacyPolicyField'
import AcceptTermsField from 'components/common/form/AcceptTermsField'
import EmailField from 'components/common/form/EmailField'
-import AcceptNewsLetterField from 'components/common/form/AcceptNewsletterField'
+import { AcceptNewsLetterField } from 'components/common/form/AcceptNewsletterField'
import { AccountType } from 'gql/user-registration'
import { IndividualRegisterFormData } from 'gql/user-registration'
diff --git a/src/components/client/campaigns/CampaignDetails.tsx b/src/components/client/campaigns/CampaignDetails.tsx
index f60bd78c1..6cf7451e6 100644
--- a/src/components/client/campaigns/CampaignDetails.tsx
+++ b/src/components/client/campaigns/CampaignDetails.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, { useState } from 'react'
import { useTranslation } from 'next-i18next'
import dynamic from 'next/dynamic'
@@ -26,6 +26,8 @@ import { routes } from 'common/routes'
import { useCanEditCampaign } from 'common/hooks/campaigns'
import { moneyPublic } from 'common/util/money'
import CampaignPublicExpensesChart from './CampaignPublicExpensesChart'
+import EmailIcon from '@mui/icons-material/Email'
+import RenderCampaignSubscribeModal from '../notifications/CampaignSubscribeModal'
const ReactQuill = dynamic(() => import('react-quill'), { ssr: false })
const CampaignNewsSection = dynamic(() => import('./CampaignNewsSection'), { ssr: false })
@@ -37,6 +39,7 @@ const classes = {
campaignTitle: `${PREFIX}-campaignTitle`,
linkButton: `${PREFIX}-linkButton`,
securityIcon: `${PREFIX}-securityIcon`,
+ subscribeLink: `${PREFIX}-subscribe`,
financeSummary: `${PREFIX}-financeSummary`,
}
@@ -93,7 +96,18 @@ const StyledGrid = styled(Grid)(({ theme }) => ({
width: theme.spacing(2.25),
height: theme.spacing(2.75),
},
+ [`& .${classes.subscribeLink}`]: {
+ fontWeight: 500,
+ fontSize: theme.typography.pxToRem(16.5),
+ textAlign: 'center',
+ '&:hover': {
+ textDecoration: 'underline',
+ transform: 'scale(1.01)',
+ cursor: 'pointer',
+ transition: 'all 0.3s ease',
+ },
+ },
[`& .${classes.financeSummary}`]: {
fontSize: `1.2rem`,
[theme.breakpoints.up('sm')]: {
@@ -109,6 +123,7 @@ type Props = {
export default function CampaignDetails({ campaign }: Props) {
const { t } = useTranslation()
+ const [subscribeIsOpen, setSubscribeOpen] = useState(false)
const sliderImages = campaignSliderUrls(campaign)
const canEditCampaign = useCanEditCampaign(campaign.slug)
const { data: expensesList } = useCampaignApprovedExpensesList(campaign.slug)
@@ -124,7 +139,22 @@ export default function CampaignDetails({ campaign }: Props) {
showExpensesLink={(expensesList && expensesList?.length > 0) || canEditCampaign}
/>
-
+ {subscribeIsOpen && (
+
+ )}
+
+ setSubscribeOpen(true)}
+ cursor="pointer"
+ />
+ setSubscribeOpen(true)} className={classes.subscribeLink}>
+ {t('campaigns:cta.subscribe')}
+
+
+
@@ -172,6 +202,21 @@ export default function CampaignDetails({ campaign }: Props) {
)}
+ {subscribeIsOpen && (
+
+ )}
+
+ setSubscribeOpen(true)}
+ cursor="pointer"
+ />
+ setSubscribeOpen(true)} className={classes.subscribeLink}>
+ {t('campaigns:cta.subscribe')}
+
+
diff --git a/src/components/client/campaigns/InlineDonation.tsx b/src/components/client/campaigns/InlineDonation.tsx
index cd58f931f..382ba6e57 100644
--- a/src/components/client/campaigns/InlineDonation.tsx
+++ b/src/components/client/campaigns/InlineDonation.tsx
@@ -36,11 +36,11 @@ import LinkButton from '../../common/LinkButton'
import CampaignProgress from './CampaignProgress'
import DonorsAndDonations from './DonorsAndDonations'
import DonationWishesInline from './DonationWishesInline'
+
import CustomListItem from 'components/common/navigation/CustomListItem'
import { socialMedia } from './helpers/socialMedia'
import { CampaignState } from './helpers/campaign.enums'
import { AlertStore } from 'stores/AlertStore'
-import RenderCampaignSubscribeModal from '../notifications/CampaignSubscribeModal'
import { useDonationWishesList } from 'common/hooks/donationWish'
const PREFIX = 'InlineDonation'
@@ -66,7 +66,6 @@ const classes = {
campaignInfoKey: `${PREFIX}-campaignInfoKey`,
campaignInfoValue: `${PREFIX}-campaignInfoValue`,
pagination: `${PREFIX}-pagination`,
- subscribeLink: `${PREFIX}-subscribe`,
}
const StyledGrid = styled(Grid)(({ theme }) => ({
@@ -243,19 +242,6 @@ const StyledGrid = styled(Grid)(({ theme }) => ({
fontSize: theme.typography.pxToRem(15),
},
},
-
- [`& .${classes.subscribeLink}`]: {
- fontWeight: 500,
- fontSize: theme.typography.pxToRem(16.5),
- textAlign: 'center',
-
- '&:hover': {
- textDecoration: 'underline',
- transform: 'scale(1.01)',
- cursor: 'pointer',
- transition: 'all 0.3s ease',
- },
- },
}))
type Props = {
@@ -266,7 +252,6 @@ export default function InlineDonation({ campaign }: Props) {
const { t } = useTranslation('campaigns')
const { asPath } = useRouter()
const [status, copyUrl] = useCopyToClipboard(1000)
- const [subscribeIsOpen, setSubscribeOpen] = useState(false)
const active = status === 'copied' ? 'inherit' : 'primary'
const [page, setPage] = useState(0)
const { mobile } = useMobile()
@@ -439,22 +424,6 @@ export default function InlineDonation({ campaign }: Props) {
- {subscribeIsOpen && (
-
- )}
- {/* Hide until notifications is ready */}
- {/*
- setSubscribeOpen(true)} className={classes.subscribeLink}>
- {t('campaigns:cta.subscribe')}
-
- setSubscribeOpen(true)} cursor="pointer" />
- */}
{detailsShown &&
(donationHistoryError ? (
'Error fetching donation history'
diff --git a/src/components/client/index/IndexPage.tsx b/src/components/client/index/IndexPage.tsx
index 9917614b0..819b2bc95 100644
--- a/src/components/client/index/IndexPage.tsx
+++ b/src/components/client/index/IndexPage.tsx
@@ -7,6 +7,7 @@ import PlatformStatisticsSection from './sections/PlatformStatisticsSection/Plat
import MediaSection from './sections/MediaSection/MediaSection'
import HowWeWorkSection from './sections/HowWeWorkSection/HowWeWorkSection'
import PartnersSection from './sections/PartnersSection/PartnersSection'
+import SubscriptionSection from './sections/SubscriptionSection/SubscriptionSection'
import TeamMembersSection from './sections/TeamMembersSection/TeamMembersSection'
import JoinPodkrepiBgSection from './sections/JoinPodkrepiBgSection/JoinPodkrepiBgSection'
import FaqSection from './sections/FaqSection/FaqSection'
@@ -28,6 +29,7 @@ export default function IndexPage() {
+
)
diff --git a/src/components/client/index/sections/PlatformStatisticsSection/PlatformStatisticsSection.styled.tsx b/src/components/client/index/sections/PlatformStatisticsSection/PlatformStatisticsSection.styled.tsx
index c24d71384..51c99674e 100644
--- a/src/components/client/index/sections/PlatformStatisticsSection/PlatformStatisticsSection.styled.tsx
+++ b/src/components/client/index/sections/PlatformStatisticsSection/PlatformStatisticsSection.styled.tsx
@@ -1,4 +1,4 @@
-import { Typography, Grid } from '@mui/material'
+import { Button, Typography, Grid } from '@mui/material'
import { styled } from '@mui/material/styles'
import theme from 'common/theme'
@@ -73,3 +73,33 @@ export const HelpThoseInNeedButton = styled(LinkButton)(() => ({
},
},
}))
+
+export const SubscribeHeading = styled(Typography)(() => ({
+ fontWeight: 500,
+ fontSize: theme.typography.pxToRem(16.5),
+ textAlign: 'center',
+}))
+
+export const SubscribeButton = styled(Button)(() => ({
+ fontWeight: 600,
+ borderRadius: theme.borders.round,
+ backgroundColor: theme.palette.secondary.main,
+ minWidth: theme.spacing(3.75),
+ fontSize: theme.typography.pxToRem(15),
+ margin: theme.spacing(2, 0, 0, 'auto'),
+ boxShadow:
+ '0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px rgba(0, 0, 0, 0.14), 0px 1px 5px rgba(0, 0, 0, 0.12)',
+
+ '& span': {
+ display: 'none',
+ },
+
+ [theme.breakpoints.up('md')]: {
+ fontSize: theme.typography.pxToRem(17),
+ minWidth: theme.spacing(50),
+
+ '& span': {
+ display: 'inline-flex',
+ },
+ },
+}))
diff --git a/src/components/client/index/sections/PlatformStatisticsSection/PlatformStatisticsSection.tsx b/src/components/client/index/sections/PlatformStatisticsSection/PlatformStatisticsSection.tsx
index b10ed3359..4fe900a49 100644
--- a/src/components/client/index/sections/PlatformStatisticsSection/PlatformStatisticsSection.tsx
+++ b/src/components/client/index/sections/PlatformStatisticsSection/PlatformStatisticsSection.tsx
@@ -1,8 +1,9 @@
-import React from 'react'
+import React, { useState } from 'react'
import { useTranslation } from 'next-i18next'
-import ArrowForwardSharp from '@mui/icons-material/ArrowForwardSharp'
import { Grid } from '@mui/material'
+import ArrowForwardSharp from '@mui/icons-material/ArrowForwardSharp'
+import EmailIcon from '@mui/icons-material/Email'
import { routes } from 'common/routes'
import Statistics from './Statistics/Statistics'
@@ -13,10 +14,14 @@ import {
Root,
SectionGridWrapper,
Subtitle,
+ SubscribeButton,
+ SubscribeHeading,
} from './PlatformStatisticsSection.styled'
+import RenderSubscribeModal from 'components/client/notifications/GeneralSubscribeModal'
export default function PlatformStatisticsSection() {
- const { t } = useTranslation('index')
+ const { t } = useTranslation()
+ const [subscribeIsOpen, setSubscribeOpen] = useState(false)
return (
@@ -26,14 +31,26 @@ export default function PlatformStatisticsSection() {
margin: '0 auto',
maxWidth: theme.spacing(67),
})}>
- {t('platform-statistics.heading')}
- {t('platform-statistics.text')}
+ {t('index:platform-statistics.heading')}
+ {t('index:platform-statistics.text')}
}>
- {t('platform-statistics.donate-to-those-in-need')}
+ {t('index:platform-statistics.donate-to-those-in-need')}
+ {subscribeIsOpen && }
+
+
+ {t('campaigns:cta.subscribeGeneral')}
+
+ {t('campaigns:cta.subscribeGeneralSubtext')}
+ setSubscribeOpen(true)}
+ variant="contained"
+ endIcon={}>
+ {t('campaigns:cta.subscribeGeneralButton')}
+
diff --git a/src/components/client/index/sections/SubscriptionSection/SubscriptionSection.styled.tsx b/src/components/client/index/sections/SubscriptionSection/SubscriptionSection.styled.tsx
new file mode 100644
index 000000000..b10a43bfb
--- /dev/null
+++ b/src/components/client/index/sections/SubscriptionSection/SubscriptionSection.styled.tsx
@@ -0,0 +1,28 @@
+import { Grid, Typography } from '@mui/material'
+import { styled } from '@mui/material/styles'
+
+import theme from 'common/theme'
+
+export const InfoText = styled(Typography)(() => ({
+ textAlign: 'center',
+ fontSize: theme.typography.pxToRem(16),
+ lineHeight: theme.spacing(3),
+ padding: theme.spacing(0, 8, 6, 8),
+}))
+
+export const SubscribeGrid = styled(Grid)(() => ({
+ margin: theme.spacing(4, 'auto'),
+
+ [`& .subscribeBtn`]: {
+ fontSize: theme.typography.pxToRem(16),
+ background: `${theme.palette.primary}`,
+
+ '&:hover': {
+ background: theme.palette.primary.main,
+ },
+ },
+
+ [theme.breakpoints.up(768)]: {
+ margin: theme.spacing(8, 'auto'),
+ },
+}))
diff --git a/src/components/client/index/sections/SubscriptionSection/SubscriptionSection.tsx b/src/components/client/index/sections/SubscriptionSection/SubscriptionSection.tsx
new file mode 100644
index 000000000..9b2190a23
--- /dev/null
+++ b/src/components/client/index/sections/SubscriptionSection/SubscriptionSection.tsx
@@ -0,0 +1,62 @@
+import React, { useState } from 'react'
+import { useTranslation } from 'next-i18next'
+import { Heading } from '../../IndexPage.styled'
+import { InfoText } from './SubscriptionSection.styled'
+import { Grid } from '@mui/material'
+import ArrowForwardSharp from '@mui/icons-material/ArrowForwardSharp'
+import EmailIcon from '@mui/icons-material/Email'
+import RenderSubscribeModal from 'components/client/notifications/GeneralSubscribeModal'
+import {
+ SectionGridWrapper,
+ SubscribeButton,
+ SubscribeHeading,
+ Subtitle,
+} from '../PlatformStatisticsSection/PlatformStatisticsSection.styled'
+
+export type SubscribeToNotificationsInput = {
+ email: string
+}
+
+const SubscriptionSection = () => {
+ const { t } = useTranslation()
+ const [subscribeIsOpen, setSubscribeOpen] = useState(false)
+
+ return (
+ ({
+ marginBottom: theme.spacing(5),
+ })}>
+ ({
+ margin: '0 auto',
+ maxWidth: theme.spacing(95),
+ textAlign: 'center',
+ })}>
+ {t('index:subscription-section.heading')}
+ {t('index:subscription-section.content')}
+ {subscribeIsOpen && }
+
+ setSubscribeOpen(true)}
+ cursor="pointer"
+ />
+ setSubscribeOpen(true)}>
+ {t('campaigns:cta.subscribe-monthly-newsletter')}
+
+
+ {t('campaigns:cta.subscribe-general-monthly-newsletter')}
+ setSubscribeOpen(true)}
+ variant="contained"
+ endIcon={}>
+ {t('campaigns:cta.subscribe-general-newsletter-button')}
+
+
+
+ )
+}
+
+export default SubscriptionSection
diff --git a/src/components/client/index/sections/TeamMembersSection/TeamMembersSection.tsx b/src/components/client/index/sections/TeamMembersSection/TeamMembersSection.tsx
index 4b38e2eaa..5ca93f554 100644
--- a/src/components/client/index/sections/TeamMembersSection/TeamMembersSection.tsx
+++ b/src/components/client/index/sections/TeamMembersSection/TeamMembersSection.tsx
@@ -1,13 +1,13 @@
-import React from 'react'
+import React, { useState } from 'react'
import Image from 'next/image'
import { useTranslation } from 'next-i18next'
import ChevronRightIcon from '@mui/icons-material/ChevronRight'
import { Box, Grid } from '@mui/material'
-
import { routes } from 'common/routes'
import { Heading, InfoText, OutlinedButton } from '../../IndexPage.styled'
import { Root } from './TeamMembersSection.styled'
+import { SectionGridWrapper } from '../PlatformStatisticsSection/PlatformStatisticsSection.styled'
export default function TeamMembersSection() {
const { t } = useTranslation('index')
@@ -27,11 +27,9 @@ export default function TeamMembersSection() {
/>
{/* A11Y TODO: Translate alt text */}
-
- }>
- {t('team-section.meet-our-team')}
-
-
+ }>
+ {t('team-section.meet-our-team')}
+
)
}
diff --git a/src/components/client/layout/Footer/Footer.styled.tsx b/src/components/client/layout/Footer/Footer.styled.tsx
index 3e23b93ad..2be5e2134 100644
--- a/src/components/client/layout/Footer/Footer.styled.tsx
+++ b/src/components/client/layout/Footer/Footer.styled.tsx
@@ -75,3 +75,12 @@ export const SubscribeLinkWrapper = styled(Grid)(({ theme }) => ({
transition: 'all 0.3s ease',
},
}))
+
+export const SubscriptionTitle = styled(Typography)(() => ({
+ '&:hover': {
+ textDecoration: 'underline',
+ transform: 'scale(1.01)',
+ cursor: 'pointer',
+ transition: 'all 0.3s ease',
+ },
+}))
diff --git a/src/components/client/layout/Footer/LogoSocialIcons.tsx b/src/components/client/layout/Footer/LogoSocialIcons.tsx
index 5460efe7b..5d1efb84a 100644
--- a/src/components/client/layout/Footer/LogoSocialIcons.tsx
+++ b/src/components/client/layout/Footer/LogoSocialIcons.tsx
@@ -6,7 +6,6 @@ import { Grid } from '@mui/material'
import { routes } from 'common/routes'
import PodkrepiLogo from 'components/common/brand/PodkrepiLogo'
import { SocialIcons } from './SocialIcons'
-// import { SubscribeBtn } from './SubscribeBtn'
export const LogoSocialIcons = () => {
const { locale } = useRouter()
@@ -20,8 +19,6 @@ export const LogoSocialIcons = () => {
- {/* Hide until notifications is ready */}
- {/* */}
)
}
diff --git a/src/components/client/layout/Footer/SocialIcons.tsx b/src/components/client/layout/Footer/SocialIcons.tsx
index 0894ee91b..15804174f 100644
--- a/src/components/client/layout/Footer/SocialIcons.tsx
+++ b/src/components/client/layout/Footer/SocialIcons.tsx
@@ -5,6 +5,7 @@ import ExternalLink from 'components/common/ExternalLink'
import { useTranslation } from 'next-i18next'
import { SocialIconsWrapper } from './Footer.styled'
+import Subscription from './Subscription'
export const SocialIcons = () => {
const { t } = useTranslation()
@@ -25,6 +26,7 @@ export const SocialIcons = () => {
aria-label={t('components.footer.social.instagram')}>
+
)
}
diff --git a/src/components/client/layout/Footer/Subscription.tsx b/src/components/client/layout/Footer/Subscription.tsx
new file mode 100644
index 000000000..8bf5afe7c
--- /dev/null
+++ b/src/components/client/layout/Footer/Subscription.tsx
@@ -0,0 +1,29 @@
+import React, { useState } from 'react'
+import { useTranslation } from 'next-i18next'
+
+import { Grid } from '@mui/material'
+import EmailIcon from '@mui/icons-material/Email'
+
+import RenderSubscribeModal from 'components/client/notifications/GeneralSubscribeModal'
+import { SubscriptionTitle } from './Footer.styled'
+
+export default function Subscription() {
+ const { t } = useTranslation()
+ const [subscribeIsOpen, setSubscribeOpen] = useState(false)
+
+ return (
+
+ {subscribeIsOpen && }
+ setSubscribeOpen(true)}
+ cursor="pointer"
+ />
+ setSubscribeOpen(true)}>
+ {t('campaigns:cta.subscribeFooter')}
+
+
+ )
+}
diff --git a/src/components/client/notifications/CampaignSubscribeModal.tsx b/src/components/client/notifications/CampaignSubscribeModal.tsx
index ab029399a..88a626a6e 100644
--- a/src/components/client/notifications/CampaignSubscribeModal.tsx
+++ b/src/components/client/notifications/CampaignSubscribeModal.tsx
@@ -1,23 +1,26 @@
+import React, { useState } from 'react'
import * as yup from 'yup'
-import { email } from 'common/form/validation'
+import { Trans } from 'react-i18next'
import { useTranslation } from 'next-i18next'
-import { useState } from 'react'
+import { useMutation } from '@tanstack/react-query'
+import { useSession } from 'next-auth/react'
import { AxiosError, AxiosResponse } from 'axios'
import { ApiError } from 'next/dist/server/api-utils'
+import { useRouter } from 'next/router'
import { AlertStore } from 'stores/AlertStore'
import { useSubscribeToCampaign } from 'service/notification'
import { CampaignResponse, CampaignSubscribeInput, CampaignSubscribeResponse } from 'gql/campaigns'
-import { useMutation } from '@tanstack/react-query'
-import { Dialog, DialogContent, DialogTitle, Grid } from '@mui/material'
+import { Dialog, DialogContent, DialogTitle, Grid, Typography } from '@mui/material'
+import EmailIcon from '@mui/icons-material/Email'
+import ThumbUpIcon from '@mui/icons-material/ThumbUp'
+import { styled } from '@mui/material/styles'
import CloseModalButton from 'components/common/CloseModalButton'
import GenericForm from 'components/common/form/GenericForm'
-import { styled } from '@mui/material/styles'
import SubmitButton from 'components/common/form/SubmitButton'
import EmailField from 'components/common/form/EmailField'
-import AcceptNewsLetterField from 'components/common/form/AcceptNewsletterField'
-import { useSession } from 'next-auth/react'
-import { getCurrentPerson } from 'common/util/useCurrentPerson'
-import React from 'react'
+import { email } from 'common/form/validation'
+import { AcceptNewsLetterFieldCampaign } from 'components/common/form/AcceptNewsletterField'
+import { routes } from 'common/routes'
const PREFIX = 'CampaignSubscribeModal'
@@ -28,14 +31,7 @@ const classes = {
const StyledGrid = styled(Grid)(({ theme }) => ({
[`& .${classes.subscribeBtn}`]: {
fontSize: theme.typography.pxToRem(16),
- background: `${theme.palette.secondary.main}`,
-
- '&:hover': {
- background: theme.palette.primary.main,
- },
- '& svg': {
- color: '#ab2f26',
- },
+ background: `${theme.palette.primary}`,
},
}))
@@ -60,9 +56,12 @@ const validationSchema: yup.SchemaOf = yup
export default function RenderCampaignSubscribeModal({ campaign, setOpen }: ModalProps) {
const { t } = useTranslation()
const { status } = useSession()
-
const [loading, setLoading] = useState(false)
const [isSuccess, setIsSuccess] = useState(false)
+ const [isGuest, setIsGuest] = useState(false)
+ const [email, setEmail] = useState('')
+ const [consent, setConsent] = useState(false)
+ const router = useRouter()
const handleError = (e: AxiosError) => {
const error = e.response?.data?.message
@@ -75,7 +74,11 @@ export default function RenderCampaignSubscribeModal({ campaign, setOpen }: Moda
CampaignSubscribeInput
>({
mutationFn: useSubscribeToCampaign(campaign.id),
- onError: (error) => handleError(error),
+ onError: (error) => {
+ console.log(error.message)
+
+ handleError(error)
+ },
onSuccess: () => {
AlertStore.show(t('common:alerts.message-sent'), 'success')
@@ -89,6 +92,8 @@ export default function RenderCampaignSubscribeModal({ campaign, setOpen }: Moda
async function onSubmit(values: { email: string; consent: boolean }) {
setLoading(true)
+ setEmail(values.email)
+ setConsent(values.consent)
try {
await mutation.mutateAsync(values)
} finally {
@@ -96,35 +101,7 @@ export default function RenderCampaignSubscribeModal({ campaign, setOpen }: Moda
}
}
- function AuthenticatedForm() {
- const { data: user } = getCurrentPerson()
-
- return (
-
-
- {/* Show consent checkbox if user has not provided it previously */}
- {!user?.user?.newsletter && (
-
-
-
- )}
-
-
-
-
-
- )
- }
-
- function NonAuthenticatedForm() {
+ const NonAuthenticatedForm = () => {
return (
-
+
+ {t('campaigns:subscribe.subscribe-campaign-subtTitle')}
+
-
-
+
+
+
+
+
@@ -150,36 +132,127 @@ export default function RenderCampaignSubscribeModal({ campaign, setOpen }: Moda
)
}
- return (
-
- )
+
+
+ )
+ } else {
+ return (
+
+
+
+ {!isSuccess ? (
+
+
+
+ {t('campaigns:subscribe.subscribe-campaign-title')}
+
+
+
+
+
+ ) : (
+
+
+
+
+
+
+ {t('campaigns:subscribe.confirm-subscribe')}
+
+
+
+
+
+
+
+ )}
+
+
+ )
+ }
}
diff --git a/src/components/client/notifications/GeneralSubscribeModal.tsx b/src/components/client/notifications/GeneralSubscribeModal.tsx
index b35cc42fb..40f0a7a91 100644
--- a/src/components/client/notifications/GeneralSubscribeModal.tsx
+++ b/src/components/client/notifications/GeneralSubscribeModal.tsx
@@ -1,22 +1,29 @@
+import React, { useState } from 'react'
import * as yup from 'yup'
-import { email } from 'common/form/validation'
+import { Trans } from 'react-i18next'
import { useTranslation } from 'next-i18next'
-import { useState } from 'react'
+import { useMutation } from '@tanstack/react-query'
+import { useSession } from 'next-auth/react'
import { AxiosError, AxiosResponse } from 'axios'
import { ApiError } from 'next/dist/server/api-utils'
+import { useRouter } from 'next/router'
import { AlertStore } from 'stores/AlertStore'
-import { useMutation } from '@tanstack/react-query'
-import { Dialog, DialogContent, DialogTitle, Grid } from '@mui/material'
+import { Dialog, DialogContent, DialogTitle, Grid, Typography } from '@mui/material'
+import EmailIcon from '@mui/icons-material/Email'
+import ThumbUpIcon from '@mui/icons-material/ThumbUp'
+import { styled } from '@mui/material/styles'
import CloseModalButton from 'components/common/CloseModalButton'
import GenericForm from 'components/common/form/GenericForm'
-import { styled } from '@mui/material/styles'
import SubmitButton from 'components/common/form/SubmitButton'
import EmailField from 'components/common/form/EmailField'
+import { email } from 'common/form/validation'
+import { AcceptNewsLetterField } from 'components/common/form/AcceptNewsletterField'
+import { routes } from 'common/routes'
+
import { useSendConfirmationEmail } from 'service/notification'
import { SendConfirmationEmailResponse, SendConfirmationEmailInput } from 'gql/notification'
-import React from 'react'
-const PREFIX = 'SubscribeModal'
+const PREFIX = 'GeneralSubscribeModal'
const classes = {
subscribeBtn: `${PREFIX}-subscribe`,
@@ -25,7 +32,7 @@ const classes = {
const StyledGrid = styled(Grid)(({ theme }) => ({
[`& .${classes.subscribeBtn}`]: {
fontSize: theme.typography.pxToRem(16),
- background: `${theme.palette.secondary.main}`,
+ background: `${theme.palette.primary}`,
'&:hover': {
background: theme.palette.primary.main,
@@ -42,17 +49,26 @@ interface ModalProps {
export type SubscribeToNotificationsInput = {
email: string
+ consent: boolean
}
-const validationSchema: yup.SchemaOf = yup.object().defined().shape({
- email: email.required(),
-})
+const validationSchema: yup.SchemaOf = yup
+ .object()
+ .defined()
+ .shape({
+ email: email.required(),
+ consent: yup.bool().required().oneOf([true], 'validation:newsletter'),
+ })
export default function RenderSubscribeModal({ setOpen }: ModalProps) {
const { t } = useTranslation()
+ const { status } = useSession()
const [loading, setLoading] = useState(false)
const [isSuccess, setIsSuccess] = useState(false)
+ const [isGuest, setIsGuest] = useState(false)
+ const [email, setEmail] = useState('')
+ const router = useRouter()
const handleError = (e: AxiosError) => {
const error = e.response?.data?.message
@@ -79,6 +95,7 @@ export default function RenderSubscribeModal({ setOpen }: ModalProps) {
async function onSubmit(values: { email: string }) {
setLoading(true)
+ setEmail(values.email)
try {
await mutation.mutateAsync(values)
} finally {
@@ -86,21 +103,29 @@ export default function RenderSubscribeModal({ setOpen }: ModalProps) {
}
}
- function SubscribeForm() {
+ const SubscribeForm = () => {
return (
-
+
+ {t('campaigns:subscribe.subscribe-subtitle')}
+
+
+
+
+
+
+
@@ -109,34 +134,127 @@ export default function RenderSubscribeModal({ setOpen }: ModalProps) {
)
}
- return (
-
-
-
+ const openAsGuest = () => {
+ setIsGuest(true)
+ }
+
+ const sendOnProfileEmail = (status: string) => {
+ if (status !== 'authenticated') {
+ router.push(routes.login)
+ } else {
+ onSubmit({ email: email || '' })
+ handleClose()
+ }
+ }
+
+ if (!isGuest) {
+ return (
+
+
-
- {!isSuccess ? (
+
{t('campaigns:subscribe.subscribe-title')}
-
+
+
+
+ {status !== 'authenticated'
+ ? t('campaigns:subscribe.subscribe-text-nonLoggedUser-general')
+ : t('campaigns:subscribe.subscribe-text-loggedUser')}
+
+
+
+ sendOnProfileEmail(status)}
+ />
+ openAsGuest()}
+ />
+
+
- ) : (
-
- {t('campaigns:subscribe.confirm-sent').split('{{email}}')}
-
- )}
-
-
- )
+
+
+ )
+ } else {
+ return (
+
+
+
+ {!isSuccess ? (
+
+
+
+ {t('campaigns:subscribe.subscribe-title')}
+
+
+
+
+
+ ) : (
+
+
+
+
+
+
+ {t('campaigns:subscribe.confirm-subscribe')}
+
+
+
+
+
+
+
+ )}
+
+
+ )
+ }
}
diff --git a/src/components/client/notifications/SubscriptionPage.tsx b/src/components/client/notifications/SubscriptionPage.tsx
index e0e5e26f1..aa73c8dce 100644
--- a/src/components/client/notifications/SubscriptionPage.tsx
+++ b/src/components/client/notifications/SubscriptionPage.tsx
@@ -1,8 +1,10 @@
-import { useTranslation } from 'next-i18next'
+import { useTranslation, Trans } from 'react-i18next'
import Layout from '../layout/Layout'
import PodkrepiLogo from 'components/common/brand/PodkrepiLogo'
import { useRouter } from 'next/router'
-import { Button, DialogContent, Grid } from '@mui/material'
+import { Button, DialogTitle, Grid, Typography } from '@mui/material'
+import ThumbUpIcon from '@mui/icons-material/ThumbUp'
+import AnnouncementIcon from '@mui/icons-material/Announcement'
import { styled } from '@mui/material/styles'
import LinkButton from 'components/common/LinkButton'
import React, { useEffect, useState } from 'react'
@@ -95,8 +97,6 @@ export default function SubscriptionPage(data: Props) {
}, [])
const handleError = (e: AxiosError) => {
- const error = e.response?.data?.message
- console.log(error)
setLoading(false)
setIsSuccess(false)
}
@@ -147,26 +147,44 @@ export default function SubscriptionPage(data: Props) {
{isSuccess ? (
-
-
- {t('notifications:subscribe.thank-you-msg')}
-
+
+
+
+
+ {t('notifications:subscribe.thank-you-msg-heading')}
+
+
+
+
+
{t('notifications:subscribe.cta')}
- {' '}
+
) : (
-
-
- {t('notifications:subscribe.subscription-fail')}
-
+
+
+
+
+ {t('notifications:subscribe.subscription-fail-heading')}
+
+
+
+
+