From 07688217494e2a6864d8fa72a76f3e2222d5fe21 Mon Sep 17 00:00:00 2001 From: nradkova Date: Fri, 15 Jul 2022 08:22:34 +0300 Subject: [PATCH 01/13] fixed: spaces and indent in details box --- src/components/campaigns/CampaignInfo.tsx | 41 ++++++----------------- 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/src/components/campaigns/CampaignInfo.tsx b/src/components/campaigns/CampaignInfo.tsx index 2153ce489..8a64d7ebd 100644 --- a/src/components/campaigns/CampaignInfo.tsx +++ b/src/components/campaigns/CampaignInfo.tsx @@ -19,8 +19,7 @@ const classes = { campaignText: `${PREFIX}-campaignText`, campaignTextWithIcon: `${PREFIX}-campaignTextWithIcon`, divider: `${PREFIX}-divider`, - stateActiveDivider: `${PREFIX}-stateActiveDivider`, - stateCompletedDivider: `${PREFIX}-stateCompletedDivider`, + stateSpan: `${PREFIX}-stateSpan`, } const StyledGrid = styled(Grid)(({ theme }) => ({ @@ -55,7 +54,7 @@ const StyledGrid = styled(Grid)(({ theme }) => ({ [`& .${classes.campaignText}`]: { fontSize: theme.spacing(1.8), flexWrap: 'wrap', - paddingLeft: theme.spacing(3.5), + paddingLeft: '29px', [theme.breakpoints.up('lg')]: { fontSize: theme.spacing(2), }, @@ -68,25 +67,10 @@ const StyledGrid = styled(Grid)(({ theme }) => ({ fontSize: theme.spacing(2), }, }, - - [`& .${classes.stateActiveDivider}`]: { - borderRightWidth: 2, - borderBottomWidth: 2, - borderColor: '#00FF00', - marginLeft: theme.spacing(3.5), - width: '145px', - [theme.breakpoints.up('lg')]: { - display: 'none', - }, - }, - [`& .${classes.stateCompletedDivider}`]: { - borderRightWidth: 2, - borderBottomWidth: 2, - borderColor: '#00FF00', - marginLeft: theme.spacing(3.5), - width: '163px', + [`& .${classes.stateSpan}`]: { + borderBottom: '2px solid #00FF00', [theme.breakpoints.up('lg')]: { - display: 'none', + borderBottom: 'none', }, }, })) @@ -113,7 +97,7 @@ export default function CampaignInfo({ campaign }: Props) { display="block" gap="5px" className={classes.campaignTextWithIcon}> - + {t('campaigns:filters.' + `${campaign.campaignType.category}`)}/{' '} {t('campaigns:campaign.types.' + `${campaign.campaignType?.slug}`)} @@ -129,14 +113,11 @@ export default function CampaignInfo({ campaign }: Props) { {t('campaigns:campaign.profile')}Спешна */} - {t('campaigns:campaign.status')}{' '} - {t(`campaigns:campaign-status.${campaign.state}`)} + + {t('campaigns:campaign.status')}{' '} + {t(`campaigns:campaign-status.${campaign.state}`)} + - {campaign.state === 'active' ? ( - - ) : ( - - )} - + {t('campaigns:campaign.start-date')}{' '} {getExactDate(campaign.startDate, locale)} From 150ac3749da82c720c448921c6b616de58d898d0 Mon Sep 17 00:00:00 2001 From: nradkova Date: Fri, 15 Jul 2022 08:40:13 +0300 Subject: [PATCH 02/13] removed: position sticky of mobile donation box --- src/components/campaigns/ViewCampaignPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/campaigns/ViewCampaignPage.tsx b/src/components/campaigns/ViewCampaignPage.tsx index ebaa90f41..36e25068d 100644 --- a/src/components/campaigns/ViewCampaignPage.tsx +++ b/src/components/campaigns/ViewCampaignPage.tsx @@ -28,7 +28,6 @@ const useStyles = makeStyles((theme: Theme) => }, donationMobileWrapper: { top: theme.spacing(10), - position: 'sticky', order: -1, marginTop: `-${theme.spacing(2)}`, minWidth: '100vw', From 679a4ec96958adeaf07286640a40f13330f16d7a Mon Sep 17 00:00:00 2001 From: nradkova Date: Fri, 15 Jul 2022 09:12:56 +0300 Subject: [PATCH 03/13] removed: green bottom border of status --- src/components/campaigns/CampaignInfo.tsx | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/components/campaigns/CampaignInfo.tsx b/src/components/campaigns/CampaignInfo.tsx index 8a64d7ebd..5212185d2 100644 --- a/src/components/campaigns/CampaignInfo.tsx +++ b/src/components/campaigns/CampaignInfo.tsx @@ -19,7 +19,6 @@ const classes = { campaignText: `${PREFIX}-campaignText`, campaignTextWithIcon: `${PREFIX}-campaignTextWithIcon`, divider: `${PREFIX}-divider`, - stateSpan: `${PREFIX}-stateSpan`, } const StyledGrid = styled(Grid)(({ theme }) => ({ @@ -67,12 +66,6 @@ const StyledGrid = styled(Grid)(({ theme }) => ({ fontSize: theme.spacing(2), }, }, - [`& .${classes.stateSpan}`]: { - borderBottom: '2px solid #00FF00', - [theme.breakpoints.up('lg')]: { - borderBottom: 'none', - }, - }, })) type Props = { @@ -113,10 +106,8 @@ export default function CampaignInfo({ campaign }: Props) { {t('campaigns:campaign.profile')}Спешна */} - - {t('campaigns:campaign.status')}{' '} - {t(`campaigns:campaign-status.${campaign.state}`)} - + {t('campaigns:campaign.status')}{' '} + {t(`campaigns:campaign-status.${campaign.state}`)} Date: Fri, 15 Jul 2022 09:18:02 +0300 Subject: [PATCH 04/13] fixed: margin-right of FavouriteIcon --- src/components/campaigns/CampaignInfo.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/campaigns/CampaignInfo.tsx b/src/components/campaigns/CampaignInfo.tsx index 5212185d2..f1c8bb52b 100644 --- a/src/components/campaigns/CampaignInfo.tsx +++ b/src/components/campaigns/CampaignInfo.tsx @@ -90,7 +90,7 @@ export default function CampaignInfo({ campaign }: Props) { display="block" gap="5px" className={classes.campaignTextWithIcon}> - + {t('campaigns:filters.' + `${campaign.campaignType.category}`)}/{' '} {t('campaigns:campaign.types.' + `${campaign.campaignType?.slug}`)} From c2a38b1f5517eadb300452ef755c4e588314d30c Mon Sep 17 00:00:00 2001 From: nradkova Date: Fri, 15 Jul 2022 09:46:18 +0300 Subject: [PATCH 05/13] removed: Donor 1 label --- src/components/campaigns/DonorsAndDonations.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/campaigns/DonorsAndDonations.tsx b/src/components/campaigns/DonorsAndDonations.tsx index f4d7d8024..c2789d9a8 100644 --- a/src/components/campaigns/DonorsAndDonations.tsx +++ b/src/components/campaigns/DonorsAndDonations.tsx @@ -68,7 +68,6 @@ export default function DonorsAndDonations({ - {t('campaigns:cta.donor')} {key + 1}.{' '} {person ? person.firstName + ' ' + person.lastName : t('campaigns:donations.anonymous')} From 88334d1575148d2dec24a3716dcef56e92bc7bad Mon Sep 17 00:00:00 2001 From: nradkova Date: Fri, 15 Jul 2022 11:41:18 +0300 Subject: [PATCH 06/13] created: new money function --- src/common/util/money.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/common/util/money.ts b/src/common/util/money.ts index 0056c61fb..a5031f8b1 100644 --- a/src/common/util/money.ts +++ b/src/common/util/money.ts @@ -14,6 +14,21 @@ export const money = (number: number, currency = 'BGN', divisionFactor = 100) => ) } +export const moneyPublic = (number: number, currency = 'BGN', divisionFactor = 100) => { + const amount = new Intl.NumberFormat('en-US', { + style: 'decimal', + maximumFractionDigits: 0, + }).format(number / divisionFactor) + + if (currency === 'EUR') { + return `€${amount}` + } + if (currency === 'USD') { + return `$${amount}` + } + return `${amount} лв.` +} + /** * Used for formatting a number into internal Money value * From 910b61fe7e13ddeeb54d0fdc3913f45660d89046 Mon Sep 17 00:00:00 2001 From: nradkova Date: Fri, 15 Jul 2022 11:42:27 +0300 Subject: [PATCH 07/13] replaced: money function --- src/components/campaigns/CampaignCard.tsx | 8 +++++--- src/components/campaigns/DonorsAndDonations.tsx | 5 +++-- src/components/campaigns/InlineDonation.tsx | 8 ++++---- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/components/campaigns/CampaignCard.tsx b/src/components/campaigns/CampaignCard.tsx index 26f9667de..05978efa4 100644 --- a/src/components/campaigns/CampaignCard.tsx +++ b/src/components/campaigns/CampaignCard.tsx @@ -2,7 +2,7 @@ import React from 'react' import { styled } from '@mui/material/styles' import { useTranslation } from 'next-i18next' import { routes } from 'common/routes' -import { money } from 'common/util/money' +import { moneyPublic } from 'common/util/money' import LinkButton from 'components/common/LinkButton' import { CampaignResponse } from 'gql/campaigns' import CampaignProgress from './CampaignProgress' @@ -75,6 +75,7 @@ export default function CampaignCard({ campaign }: Props) { const summary = campaign.summary.find(() => true) const pictureUrl = campaignListPictureUrl(campaign) const reached = summary ? summary.reachedAmount : 0 + const currency = campaign.currency return ( @@ -101,8 +102,9 @@ export default function CampaignCard({ campaign }: Props) { - {t('campaigns:campaign.reached')} {money(reached)} {t('campaigns:campaign.from')}{' '} - {t('campaigns:campaign.target')} {money(target)} + {t('campaigns:campaign.reached')} {moneyPublic(reached, currency)}{' '} + {t('campaigns:campaign.from')} {t('campaigns:campaign.target')}{' '} + {moneyPublic(target, currency)} diff --git a/src/components/campaigns/DonorsAndDonations.tsx b/src/components/campaigns/DonorsAndDonations.tsx index c2789d9a8..4f260dce0 100644 --- a/src/components/campaigns/DonorsAndDonations.tsx +++ b/src/components/campaigns/DonorsAndDonations.tsx @@ -8,7 +8,7 @@ import { CampaignDonation } from 'gql/campaigns' import { formatRelative, parseISO } from 'date-fns' import { bg, enUS } from 'date-fns/locale' import theme from 'common/theme' -import { money } from 'common/util/money' +import { moneyPublic } from 'common/util/money' const PREFIX = 'DonorsAndDonations' @@ -59,6 +59,7 @@ export default function DonorsAndDonations({ } return donations?.slice(0, shownDonationsNumber) }, [donations, all]) + return ( @@ -73,7 +74,7 @@ export default function DonorsAndDonations({ : t('campaigns:donations.anonymous')} - {money(amount, currency)} + {moneyPublic(amount, currency)} {formatRelative(parseISO(createdAt), new Date(), { diff --git a/src/components/campaigns/InlineDonation.tsx b/src/components/campaigns/InlineDonation.tsx index 119f8b9c0..3c12d19f3 100644 --- a/src/components/campaigns/InlineDonation.tsx +++ b/src/components/campaigns/InlineDonation.tsx @@ -3,7 +3,7 @@ import { styled } from '@mui/material/styles' import { useTranslation } from 'next-i18next' import { CampaignResponse } from 'gql/campaigns' import { baseUrl, routes } from 'common/routes' -import { money } from 'common/util/money' +import { moneyPublic } from 'common/util/money' import CampaignProgress from './CampaignProgress' import DonorsAndDonations from './DonorsAndDonations' import { Button, CircularProgress, Grid, lighten, Menu, Typography } from '@mui/material' @@ -132,8 +132,8 @@ export default function InlineDonation({ campaign }: Props) { const { mobile } = useMobile() const [isOpen, setIsOpen] = useState(false) + const currency = campaign.currency const detailsShown = isOpen || !mobile - console.log('detailsShown', detailsShown) const [anchorEl, setAnchorEl] = useState(null) @@ -144,11 +144,11 @@ export default function InlineDonation({ campaign }: Props) { - {money(reached)} + {moneyPublic(reached, currency)} {' '} - {t('campaigns:campaign.from')} {money(target)} + {t('campaigns:campaign.from')} {moneyPublic(target, currency)} From ef790ab525fd435f169e2c1378816c7d33880725 Mon Sep 17 00:00:00 2001 From: nradkova Date: Fri, 15 Jul 2022 12:32:30 +0300 Subject: [PATCH 08/13] refactored: buttons size --- src/components/irregularity/Actions.tsx | 1 + src/components/irregularity/helpers/Fail.tsx | 10 +++++++--- src/components/irregularity/helpers/Remark.tsx | 1 - src/components/irregularity/helpers/Success.tsx | 10 +++++++--- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/components/irregularity/Actions.tsx b/src/components/irregularity/Actions.tsx index c7518631c..3723374e2 100644 --- a/src/components/irregularity/Actions.tsx +++ b/src/components/irregularity/Actions.tsx @@ -22,6 +22,7 @@ const useStyles = makeStyles((theme: Theme) => color: '#FFFFFF', fontSize: '18px', '&:hover': { backgroundColor: '#62C4FB', color: '#000000' }, + [theme.breakpoints.down('sm')]: { fontSize: '12px' }, }, actions: { justifyContent: 'space-between', diff --git a/src/components/irregularity/helpers/Fail.tsx b/src/components/irregularity/helpers/Fail.tsx index 44c75f5ac..0137b5761 100644 --- a/src/components/irregularity/helpers/Fail.tsx +++ b/src/components/irregularity/helpers/Fail.tsx @@ -1,4 +1,5 @@ import { useTranslation } from 'next-i18next' +import { useEffect } from 'react' import { ThemeProvider } from '@mui/styles' import { createStyles, makeStyles } from '@mui/styles' @@ -21,6 +22,7 @@ const useStyles = makeStyles(() => color: '#FFFFFF', fontSize: '16px', '&:hover': { backgroundColor: '#62C4FB', color: '#000000' }, + [theme.breakpoints.down('sm')]: { fontSize: '12px' }, }, container: { marginTop: '20%', @@ -48,9 +50,11 @@ export default function Fail({ setFail, setActiveStep }: Props) { const classes = useStyles() const { t } = useTranslation('irregularity') - if (window) { - window.scrollTo({ top: 0, behavior: 'smooth' }) - } + useEffect(() => { + if (window) { + window.scrollTo({ top: 0, behavior: 'smooth' }) + } + }, []) const handleClick = () => { setFail(false) diff --git a/src/components/irregularity/helpers/Remark.tsx b/src/components/irregularity/helpers/Remark.tsx index b523280d6..184b79935 100644 --- a/src/components/irregularity/helpers/Remark.tsx +++ b/src/components/irregularity/helpers/Remark.tsx @@ -6,7 +6,6 @@ type RemarkProps = { const textStyles = { fontSize: '13px', - textAlign: 'center', marginTop: '100px', } diff --git a/src/components/irregularity/helpers/Success.tsx b/src/components/irregularity/helpers/Success.tsx index b9e2b30d6..05f4d2ef3 100644 --- a/src/components/irregularity/helpers/Success.tsx +++ b/src/components/irregularity/helpers/Success.tsx @@ -1,4 +1,5 @@ import { useTranslation } from 'next-i18next' +import { useEffect } from 'react' import { ThemeProvider } from '@mui/styles' import { Grid, Typography } from '@mui/material' @@ -21,6 +22,7 @@ const useStyles = makeStyles(() => color: '#FFFFFF', fontSize: '18px', '&:hover': { backgroundColor: '#62C4FB', color: '#000000' }, + [theme.breakpoints.down('sm')]: { fontSize: '12px' }, }, container: { marginTop: '20%', @@ -42,9 +44,11 @@ export default function Success() { const classes = useStyles() const { t } = useTranslation('irregularity') - if (window) { - window.scrollTo({ top: 0, behavior: 'smooth' }) - } + useEffect(() => { + if (window) { + window.scrollTo({ top: 0, behavior: 'smooth' }) + } + }, []) return ( From 18810dc52e9cf5574ab61c2aa57284ca2e88af6e Mon Sep 17 00:00:00 2001 From: nradkova Date: Fri, 15 Jul 2022 12:33:41 +0300 Subject: [PATCH 09/13] added: scroll to top on load --- src/components/irregularity/steps/Contacts.tsx | 10 ++++++++-- src/components/irregularity/steps/Greeting.tsx | 10 ++++++++-- src/components/irregularity/steps/Info.tsx | 12 +++++++++--- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/components/irregularity/steps/Contacts.tsx b/src/components/irregularity/steps/Contacts.tsx index 99b6b1ad7..94ec73927 100644 --- a/src/components/irregularity/steps/Contacts.tsx +++ b/src/components/irregularity/steps/Contacts.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect } from 'react' import { useTranslation } from 'next-i18next' import { styled } from '@mui/system' @@ -21,11 +21,17 @@ const CssTextField = styled(FormTextField)({ export default function Contacts() { const { t } = useTranslation('irregularity') + useEffect(() => { + if (window) { + window.scrollTo({ top: 0, behavior: 'smooth' }) + } + }, []) + return ( - + {t('steps.contacts.text')} {t('steps.contacts.text-link') + '.'} diff --git a/src/components/irregularity/steps/Greeting.tsx b/src/components/irregularity/steps/Greeting.tsx index 531095316..9b7e4bd80 100644 --- a/src/components/irregularity/steps/Greeting.tsx +++ b/src/components/irregularity/steps/Greeting.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect } from 'react' import { useSession } from 'next-auth/react' import { useTranslation } from 'next-i18next' import { Grid, Typography } from '@mui/material' @@ -15,6 +15,12 @@ export default function Greeting() { const { t } = useTranslation('irregularity') const { data: session } = useSession() + useEffect(() => { + if (window) { + window.scrollTo({ top: 0, behavior: 'smooth' }) + } + }, []) + return ( @@ -35,7 +41,7 @@ export default function Greeting() { {t('steps.greeting.text-info')} - + {t('steps.greeting.text-description-first')} {t('steps.greeting.text-link')} diff --git a/src/components/irregularity/steps/Info.tsx b/src/components/irregularity/steps/Info.tsx index 7c1efd4a0..0999cb850 100644 --- a/src/components/irregularity/steps/Info.tsx +++ b/src/components/irregularity/steps/Info.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect } from 'react' import { Field } from 'formik' import { useTranslation } from 'next-i18next' @@ -31,6 +31,12 @@ type Props = { export default function Info({ files, setFiles }: Props) { const { t } = useTranslation('irregularity') + useEffect(() => { + if (window) { + window.scrollTo({ top: 0, behavior: 'smooth' }) + } + }, []) + return ( @@ -85,11 +91,11 @@ export default function Info({ files, setFiles }: Props) { - + {t('steps.info.files')} - + { setFiles((prevFiles: File[]) => [...prevFiles, ...newFiles]) From d6b2bdad807610f086e9fee22806d569315fbc43 Mon Sep 17 00:00:00 2001 From: nradkova Date: Fri, 15 Jul 2022 15:17:13 +0300 Subject: [PATCH 10/13] fixed: fontsize of card title due to length --- src/components/campaigns/CampaignCard.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/components/campaigns/CampaignCard.tsx b/src/components/campaigns/CampaignCard.tsx index 05978efa4..ef84fdcb0 100644 --- a/src/components/campaigns/CampaignCard.tsx +++ b/src/components/campaigns/CampaignCard.tsx @@ -64,11 +64,23 @@ const StyledCard = styled(Card)(({ theme }) => ({ }, [`& .${classes.cardContent}`]: { - minHeight: theme.spacing(20), + minHeight: theme.spacing(24), + maxHeight: theme.spacing(24), }, })) type Props = { campaign: CampaignResponse } + +const titleSize = (campaign: CampaignResponse) => { + if (campaign.title.length > 120) { + return 'subtitle1' + } + if (campaign.title.length > 90) { + return 'h6' + } + return 'h5' +} + export default function CampaignCard({ campaign }: Props) { const { t } = useTranslation() const target = campaign.targetAmount @@ -88,7 +100,7 @@ export default function CampaignCard({ campaign }: Props) { - + {campaign.title} From c5ae880126eb5cf5f497500d20cf4bca6f64bbef Mon Sep 17 00:00:00 2001 From: quantum-grit Date: Fri, 15 Jul 2022 16:16:44 +0300 Subject: [PATCH 11/13] fixed: slugify to remove special characters from campaign title --- src/common/util/createSlug.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/util/createSlug.ts b/src/common/util/createSlug.ts index 0afed082e..03c3796b4 100644 --- a/src/common/util/createSlug.ts +++ b/src/common/util/createSlug.ts @@ -1,5 +1,5 @@ import slugify from 'slugify' export function createSlug(title: string): string { - return slugify(title, { lower: true }) + return slugify(title, { lower: true, strict: true }) } From 2eb0858dbfd579976b403746c4a11216ded59fe0 Mon Sep 17 00:00:00 2001 From: quantum-grit Date: Fri, 15 Jul 2022 16:18:07 +0300 Subject: [PATCH 12/13] displayed coordinator mail in campaign page --- src/components/campaigns/CampaignInfoCoordinator.tsx | 9 +++++++-- src/components/campaigns/CampaignInfoOrganizer.tsx | 6 +++--- src/gql/campaigns.ts | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/components/campaigns/CampaignInfoCoordinator.tsx b/src/components/campaigns/CampaignInfoCoordinator.tsx index 414d92342..f76bfaba5 100644 --- a/src/components/campaigns/CampaignInfoCoordinator.tsx +++ b/src/components/campaigns/CampaignInfoCoordinator.tsx @@ -83,9 +83,14 @@ export default function CampaignInfoCoordinator({ campaign }: Props) { diff --git a/src/components/campaigns/CampaignInfoOrganizer.tsx b/src/components/campaigns/CampaignInfoOrganizer.tsx index d913143c7..372f5265d 100644 --- a/src/components/campaigns/CampaignInfoOrganizer.tsx +++ b/src/components/campaigns/CampaignInfoOrganizer.tsx @@ -94,10 +94,10 @@ export default function CampaignInfoOrganizer({ campaign }: Props) { {t('common:cta.see-profile')} */} - - + diff --git a/src/gql/campaigns.ts b/src/gql/campaigns.ts index 3148879c4..342181005 100644 --- a/src/gql/campaigns.ts +++ b/src/gql/campaigns.ts @@ -84,7 +84,7 @@ export type CampaignResponse = BaseCampaignResponse & { } coordinator: { id: UUID - person: { id: UUID; firstName: string; lastName: string } + person: { id: UUID; firstName: string; lastName: string; email: string } } organizer?: { id: UUID From 8bb2c6575dfc268045ccd06f988cbc543c9fd485 Mon Sep 17 00:00:00 2001 From: quantum-grit Date: Fri, 15 Jul 2022 16:58:06 +0300 Subject: [PATCH 13/13] adjusted campaign cards grid for small screen --- src/components/campaigns/CampaignsList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/campaigns/CampaignsList.tsx b/src/components/campaigns/CampaignsList.tsx index 914501ab4..a8b57c8e8 100644 --- a/src/components/campaigns/CampaignsList.tsx +++ b/src/components/campaigns/CampaignsList.tsx @@ -25,7 +25,7 @@ export default function CampaignsList({ campaignToShow }: Props) { {/*
{JSON.stringify(data, null, 2)}
*/} {campaigns?.map((campaign, index) => ( - +