Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show wishes on the top of campaign page #1633

Merged
Merged
4 changes: 3 additions & 1 deletion public/locales/bg/campaigns.json
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@
"tag": "Таг:",
"date": "Дата:",
"news": "Новини",
"wishes": "Пожелания"
"wishes": "Пожелания",
"nowishes": "Няма добавени пожелания",
"seeAll": "Виж всички"
},
"info-graphics": {
"donation-title": "100% от дарението отива при нуждаещите се",
Expand Down
4 changes: 3 additions & 1 deletion public/locales/en/campaigns.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@
"tag": "Tag:",
"date": "Date:",
"news": "News",
"wishes": "Wishes"
"wishes": "Wishes",
"nowishes": "No wishes yet",
"seeAll": "Show all"
},
"info-graphics": {
"donation-title": "100% of the donation goes to those in need",
Expand Down
137 changes: 137 additions & 0 deletions src/components/client/campaigns/DonationWishesInline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { useMemo } from 'react'

import { useTranslation } from 'next-i18next'

import { DonationWishPaginatedResponse } from 'gql/donationWish'

import AccountCircleIcon from '@mui/icons-material/AccountCircle'
import { Grid, Typography } from '@mui/material'
import { styled } from '@mui/material/styles'

import theme from 'common/theme'
import { bg, enUS } from 'date-fns/locale'
import { getExactDate } from 'common/util/date'

const PREFIX = 'DonationsWishesInline'

const classes = {
donationsWrapper: `${PREFIX}-donationsWrapper`,
donationItemWrapper: `${PREFIX}-donationItemWrapper`,
donationQuantityAndTimeWrapper: `${PREFIX}-donationQuantityAndTimeWrapper`,
separatorIcon: `${PREFIX}-separatorIcon`,
donatorName: `${PREFIX}-donatorName`,
donatorAvatar: `${PREFIX}-donatorAvatar`,
}

const Root = styled('div')(({ theme }) => ({
[`& .${classes.donationsWrapper}`]: {
maxHeight: 400,
},

[`& .${classes.donationItemWrapper}`]: {
display: 'flex',
gap: theme.spacing(1),
alignItems: 'start',
marginBottom: theme.spacing(1.7),
maxHeight: 'fit-content',

'&:last-of-type': {
marginBottom: 0,
},
},

[`& .${classes.donationQuantityAndTimeWrapper}`]: {
display: 'flex',
gap: theme.spacing(1),
color: '#909090',
alignItems: 'center',
lineHeight: '145%',

'& p': {
fontSize: theme.typography.pxToRem(12),
},
},

[`& .${classes.separatorIcon}`]: {
fontSize: theme.typography.pxToRem(21),
fontWeight: 200,
},

[`& .${classes.donatorName}`]: {
color: theme.palette.common.black,
fontWeight: 500,
},

[`& .${classes.donatorAvatar}`]: {
width: theme.spacing(5.25),
height: theme.spacing(5.25),
},
}))

export default function DonationsWishesInline({
wishList,
pageSize = 3,
}: {
wishList: DonationWishPaginatedResponse
pageSize?: number
}) {
const { t, i18n } = useTranslation()

const wishListToShow = useMemo(() => {
if (wishList?.items?.length <= pageSize) {
return wishList?.items
}

const wishListSortByMsgLengthAndCreateDate = wishList?.items
?.sort((a, b) => b?.message?.length - a?.message?.length)
?.slice(0, 5)
.map((value) => ({ value, sort: Math.random() }))
.sort((a, b) => a.sort - b.sort)
.map(({ value }) => value)
?.slice(0, pageSize)
?.sort((c, d) => (c.createdAt > d.createdAt ? -1 : 1))

return wishListSortByMsgLengthAndCreateDate
}, [wishList?.items])

return (
<Root>
<Grid item className={classes.donationsWrapper}>
{wishListToShow && wishListToShow.length !== 0 ? (
wishListToShow.map(({ person, createdAt, message }, key) => (
<Grid key={key} className={classes.donationItemWrapper}>
<AccountCircleIcon color="disabled" className={classes.donatorAvatar} />
<Grid>
<Grid className={classes.donationQuantityAndTimeWrapper}>
<Typography className={classes.donatorName}>
{person
? `${person?.firstName} ${person?.lastName}`
: t('campaigns:donations.anonymous')}
</Typography>
<span className={classes.separatorIcon}>|</span>
<Typography className={classes.donatorName}>
{getExactDate(createdAt, i18n.language == 'bg' ? bg : enUS)}
</Typography>
</Grid>
<Typography
component="blockquote"
sx={{
fontSize: theme.typography.pxToRem(12),
lineHeight: '160%',
'&:before': { content: 'open-quote' },
'&:after': { content: 'close-quote' },
}}>
{message}
</Typography>
</Grid>
</Grid>
))
) : (
<Typography sx={{ textAlign: 'center', marginBottom: theme.spacing(4) }}>
{t('campaigns:campaign.nowishes')}
</Typography>
)}
</Grid>
</Root>
)
}
160 changes: 130 additions & 30 deletions src/components/client/campaigns/InlineDonation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,24 @@ import { useRouter } from 'next/router'

import { CampaignResponse } from 'gql/campaigns'

import { Button, CircularProgress, Grid, IconButton, Menu, Typography } from '@mui/material'
import {
Button,
Chip,
CircularProgress,
FormControl,
Grid,
IconButton,
Menu,
Typography,
} from '@mui/material'
import { AddLinkOutlined, Favorite } from '@mui/icons-material'
import { lighten } from '@mui/material/styles'
import { styled } from '@mui/material/styles'
import ExpandLessIcon from '@mui/icons-material/ExpandLess'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos'
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos'
import ArrowForwardIcon from '@mui/icons-material/ArrowForward'
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'

import { baseUrl, routes } from 'common/routes'
Expand All @@ -25,11 +35,13 @@ import useMobile from 'common/hooks/useMobile'
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'

Expand All @@ -38,7 +50,9 @@ const classes = {
reachedAndTargetMoneyWrapper: `${PREFIX}-reachedAndTargetMoneyWrapper`,
moneyUnit: `${PREFIX}-moneyUnit`,
moneyFraction: `${PREFIX}-moneyFraction`,
donorsSharesCount: `${PREFIX}-donorsSharesCount`,
donorsWishesTabs: `${PREFIX}-donorsWishesTabs`,
donorsWishesTab: `${PREFIX}-donorsWishesTab`,
selected: `${PREFIX}-selected`,
donationPriceList: `${PREFIX}-donationPriceList`,
dropdownLinkButton: `${PREFIX}-dropdownLinkButton`,
dropdownLinkText: `${PREFIX}-dropdownLinkText`,
Expand Down Expand Up @@ -91,11 +105,29 @@ const StyledGrid = styled(Grid)(({ theme }) => ({
margin: theme.spacing(0.25, 0, 0, 0.25),
},

[`& .${classes.donorsSharesCount}`]: {
textTransform: 'capitalize',
[`& .${classes.donorsWishesTabs}`]: {
display: 'rowflex',
flexDirection: 'row',
width: '100%',
border: '1px solid grey',
borderRadius: '60px',
margin: theme.spacing(1.7, 0),
fontSize: theme.typography.pxToRem(14),
color: theme.palette.common.black,
},

[`& .${classes.donorsWishesTab}`]: {
textTransform: 'capitalize',
display: 'flex',
justifyContent: 'center',
width: '50%',
fontSize: '13px',
backgroundColor: 'transparant',
paddingBottom: theme.spacing(0.2),
borderRadius: '60px',
cursor: 'pointer',
},

[`& .${classes.selected}`]: {
backgroundColor: '#b1defe',
},

[`& .${classes.donationPriceList}`]: {
Expand Down Expand Up @@ -172,7 +204,8 @@ const StyledGrid = styled(Grid)(({ theme }) => ({
},

[`& .${classes.infoIcon}`]: {
marginTop: `-${theme.spacing(0.25)}`,
marginTop: `${theme.spacing(0.125)}`,
marginRight: `${theme.spacing(0.25)}`,
fontSize: theme.typography.pxToRem(16),
color: '#6d6d6d',
},
Expand Down Expand Up @@ -264,6 +297,76 @@ export default function InlineDonation({ campaign }: Props) {

const handleClose = () => setAnchorEl(null)

const [selected, setSelected] = useState('donors')

const donorsDisplay = (
<>
<DonorsAndDonations donations={donations} />
{donations && donations.length !== 0 ? (
<Grid container className={classes.pagination}>
<Typography m={1}>{`${page * pageSize + 1}-${rowCount} ${t(
'campaigns:of',
)} ${all_rows}`}</Typography>
<IconButton
aria-label="back"
disabled={page == 0}
onClick={() => setPage((index) => index - 1)}>
<ArrowBackIosIcon fontSize="small" />
</IconButton>
<IconButton
aria-label="next"
disabled={rowCount == all_rows}
onClick={() => setPage((index) => index + 1)}>
<ArrowForwardIosIcon fontSize="small" />
</IconButton>
</Grid>
) : null}
</>
)

const { data: wishList } = useDonationWishesList(
campaignId,
{ pageIndex: 0, pageSize },
{ sortBy: 'createdAt', sortOrder: 'desc' },
'',
)

const wishesDisplay = (
<>
{wishList && <DonationWishesInline wishList={wishList} />}
{wishList?.totalCount !== 0 && (
<Chip
label={t('campaigns:campaign.seeAll')}
deleteIcon={<ArrowForwardIcon />}
onDelete={() => {
return
}}
component="a"
href="#wishes"
clickable
size="medium"
sx={{
border: `2px solid ${theme.palette.primary.dark}`,
color: theme.palette.primary.dark,
backgroundColor: '#EEEEEE',
marginTop: theme.spacing(1.7),
padding: '0 4px',
'.MuiChip-label': {
paddingRight: theme.spacing(1.7),
},
'.MuiChip-deleteIcon': {
color: theme.palette.primary.dark,
':hover': {
color: theme.palette.primary.dark,
},
fontSize: 'large',
},
}}
/>
)}
</>
)

return (
<StyledGrid item xs={12} p={3} className={classes.inlineDonationWrapper}>
<Grid className={classes.reachedAndTargetMoneyWrapper}>
Expand Down Expand Up @@ -364,29 +467,26 @@ export default function InlineDonation({ campaign }: Props) {
<InfoOutlinedIcon className={classes.infoIcon} />
<Typography>{t('campaign.noCommissionInfo')}</Typography>
</Grid>
<Typography className={classes.donorsSharesCount}>
{t('campaign.donors')}: {donors}
</Typography>
<DonorsAndDonations donations={donations} />
{donations && donations.length !== 0 ? (
<Grid container className={classes.pagination}>
<Typography m={1}>{`${page * pageSize + 1}-${rowCount} ${t(
'campaigns:of',
)} ${all_rows}`}</Typography>
<IconButton
aria-label="back"
disabled={page == 0}
onClick={() => setPage((index) => index - 1)}>
<ArrowBackIosIcon fontSize="small" />
</IconButton>
<IconButton
aria-label="next"
disabled={rowCount == all_rows}
onClick={() => setPage((index) => index + 1)}>
<ArrowForwardIosIcon fontSize="small" />
</IconButton>
</Grid>
) : null}
<FormControl className={classes.donorsWishesTabs}>
<Typography
className={[
classes.donorsWishesTab,
selected === 'donors' && classes.selected,
].join(' ')}
onClick={() => setSelected('donors')}>{`${t(
'campaign.donors',
)} (${donors})`}</Typography>
<Typography
className={[
classes.donorsWishesTab,
selected === 'wishes' && classes.selected,
].join(' ')}
onClick={() => setSelected('wishes')}>{`${t('campaign.wishes')} (${
wishList?.totalCount
})`}</Typography>
</FormControl>

{selected === 'donors' ? donorsDisplay : wishesDisplay}
</>
))}
{mobile && (
Expand Down
Loading