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

Feature campaign profile page #888

Merged
merged 14 commits into from
Jul 15, 2022
2 changes: 1 addition & 1 deletion src/common/util/createSlug.ts
Original file line number Diff line number Diff line change
@@ -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 })
}
15 changes: 15 additions & 0 deletions src/common/util/money.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
24 changes: 19 additions & 5 deletions src/components/campaigns/CampaignCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -64,17 +64,30 @@ 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
const summary = campaign.summary.find(() => true)
const pictureUrl = campaignListPictureUrl(campaign)
const reached = summary ? summary.reachedAmount : 0
const currency = campaign.currency

return (
<StyledCard variant="outlined" className={classes.cardWrapper}>
Expand All @@ -87,7 +100,7 @@ export default function CampaignCard({ campaign }: Props) {
</CardMedia>
</Link>
<CardContent className={classes.cardContent}>
<Typography textAlign={'center'} gutterBottom variant="h5" component="h2">
<Typography textAlign={'center'} gutterBottom variant={titleSize(campaign)}>
{campaign.title}
</Typography>
<Typography textAlign={'left'} variant="body2" color="textSecondary" component="p">
Expand All @@ -101,8 +114,9 @@ export default function CampaignCard({ campaign }: Props) {
<CampaignProgress raised={reached} target={target} />
</Box>
<Typography variant="body1" component="p" className={classes.progressBar}>
{t('campaigns:campaign.reached')} <b>{money(reached)}</b> {t('campaigns:campaign.from')}{' '}
{t('campaigns:campaign.target')} <b>{money(target)}</b>
{t('campaigns:campaign.reached')} <b>{moneyPublic(reached, currency)}</b>{' '}
{t('campaigns:campaign.from')} {t('campaigns:campaign.target')}{' '}
<b>{moneyPublic(target, currency)}</b>
</Typography>
<Grid item xs={12}>
<Box mx={2} mb={2}>
Expand Down
37 changes: 3 additions & 34 deletions src/components/campaigns/CampaignInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ const classes = {
campaignText: `${PREFIX}-campaignText`,
campaignTextWithIcon: `${PREFIX}-campaignTextWithIcon`,
divider: `${PREFIX}-divider`,
stateActiveDivider: `${PREFIX}-stateActiveDivider`,
stateCompletedDivider: `${PREFIX}-stateCompletedDivider`,
}

const StyledGrid = styled(Grid)(({ theme }) => ({
Expand Down Expand Up @@ -55,7 +53,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),
},
Expand All @@ -68,27 +66,6 @@ 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',
[theme.breakpoints.up('lg')]: {
display: 'none',
},
},
}))

type Props = {
Expand All @@ -113,7 +90,7 @@ export default function CampaignInfo({ campaign }: Props) {
display="block"
gap="5px"
className={classes.campaignTextWithIcon}>
<FavoriteIcon color="action" sx={{ mb: '-6px', mr: '3px' }} />
<FavoriteIcon color="action" sx={{ mb: '-6px', mr: '6px', ml: '-2px' }} />
<strong>
{t('campaigns:filters.' + `${campaign.campaignType.category}`)}/{' '}
{campaign.campaignType.name}
Expand All @@ -132,22 +109,14 @@ export default function CampaignInfo({ campaign }: Props) {
<strong>{t('campaigns:campaign.status')}</strong>{' '}
{t(`campaigns:campaign-status.${campaign.state}`)}
</Typography>
{
// campaign.state === 'active'
// ? (
// <Divider className={classes.stateActiveDivider} />
// ) : (
// <Divider className={classes.stateCompletedDivider} />
// )
}
<Typography
variant="subtitle2"
component="p"
display="flex"
gap="5px"
pr={2}
className={classes.campaignTextWithIcon}>
<CalendarTodayIcon fontSize="small" color="action" />
<CalendarTodayIcon fontSize="small" color="action" sx={{ mr: '4px' }} />
<strong>{t('campaigns:campaign.start-date')}</strong>{' '}
{getExactDate(campaign.startDate, locale)}
</Typography>
Expand Down
9 changes: 7 additions & 2 deletions src/components/campaigns/CampaignInfoCoordinator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,14 @@ export default function CampaignInfoCoordinator({ campaign }: Props) {
</Typography>
<Button
startIcon={<EmailIcon color="action" />}
href={'mailto:[email protected]?subject=Question about: ' + campaign.title}
href={
'mailto:' +
campaign.coordinator.person.email +
'?subject=Question about: ' +
campaign.title
}
className={classes.trustedButton}>
[email protected]
{campaign.coordinator.person.email}
</Button>
</Grid>
</StyledGrid>
Expand Down
6 changes: 3 additions & 3 deletions src/components/campaigns/CampaignInfoOrganizer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ export default function CampaignInfoOrganizer({ campaign }: Props) {
{t('common:cta.see-profile')}
</Button> */}
<Grid container alignItems="center" className={classes.infoButtonWrapper}>
<ThumbUpIcon color="action" className={classes.infoButtonIcon} />
<Button href={''} className={classes.trustedButton}>
<ThumbUpIcon color="success" className={classes.infoButtonIcon} />
<Typography variant="subtitle2" component="p">
{t('campaigns:cta.trusted')}
</Button>
</Typography>
</Grid>
</Grid>
</StyledGrid>
Expand Down
2 changes: 1 addition & 1 deletion src/components/campaigns/CampaignsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function CampaignsList({ campaignToShow }: Props) {
<Grid container justifyContent="center" spacing={2}>
{/* <pre>{JSON.stringify(data, null, 2)}</pre> */}
{campaigns?.map((campaign, index) => (
<Grid key={index} item xs={12} sm={6} lg={3}>
<Grid key={index} item xs={12} sm={4} lg={3}>
<Box textAlign="center">
<CampaignCard campaign={campaign} />
</Box>
Expand Down
6 changes: 3 additions & 3 deletions src/components/campaigns/DonorsAndDonations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -59,6 +59,7 @@ export default function DonorsAndDonations({
}
return donations?.slice(0, shownDonationsNumber)
}, [donations, all])

return (
<Root>
<Grid item className={classes.donationsWrapper}>
Expand All @@ -68,13 +69,12 @@ export default function DonorsAndDonations({
<AccountCircleIcon fontSize="large" color="disabled" />
<Grid>
<Typography>
{t('campaigns:cta.donor')} {key + 1}.{' '}
{person
? person.firstName + ' ' + person.lastName
: t('campaigns:donations.anonymous')}
</Typography>
<Grid className={classes.donationQuantityAndTimeWrapper}>
<Typography>{money(amount, currency)}</Typography>
<Typography>{moneyPublic(amount, currency)}</Typography>
<FiberManualRecordIcon className={classes.separatorIcon} />
<Typography>
{formatRelative(parseISO(createdAt), new Date(), {
Expand Down
8 changes: 4 additions & 4 deletions src/components/campaigns/InlineDonation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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<Element | null>(null)

Expand All @@ -144,11 +144,11 @@ export default function InlineDonation({ campaign }: Props) {
<StyledGrid item xs={12} mt={5} p={3} className={classes.inlineDonationWrapper}>
<Grid mb={2}>
<Typography component="span" className={classes.reachedMoney}>
{money(reached)}
{moneyPublic(reached, currency)}
</Typography>
<Typography component="span" className={classes.targetMoney}>
{' '}
{t('campaigns:campaign.from')} {money(target)}
{t('campaigns:campaign.from')} {moneyPublic(target, currency)}
</Typography>
</Grid>
<CampaignProgress raised={reached} target={target} />
Expand Down
1 change: 0 additions & 1 deletion src/components/campaigns/ViewCampaignPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ const useStyles = makeStyles((theme: Theme) =>
},
donationMobileWrapper: {
top: theme.spacing(10),
position: 'sticky',
order: -1,
marginTop: `-${theme.spacing(2)}`,
minWidth: '100vw',
Expand Down
1 change: 1 addition & 0 deletions src/components/irregularity/Actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
10 changes: 7 additions & 3 deletions src/components/irregularity/helpers/Fail.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useTranslation } from 'next-i18next'
import { useEffect } from 'react'

import { ThemeProvider } from '@mui/styles'
import { createStyles, makeStyles } from '@mui/styles'
Expand All @@ -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%',
Expand Down Expand Up @@ -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)
Expand Down
1 change: 0 additions & 1 deletion src/components/irregularity/helpers/Remark.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ type RemarkProps = {

const textStyles = {
fontSize: '13px',
textAlign: 'center',
marginTop: '100px',
}

Expand Down
10 changes: 7 additions & 3 deletions src/components/irregularity/helpers/Success.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useTranslation } from 'next-i18next'
import { useEffect } from 'react'

import { ThemeProvider } from '@mui/styles'
import { Grid, Typography } from '@mui/material'
Expand All @@ -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%',
Expand All @@ -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 (
<ThemeProvider theme={theme}>
Expand Down
10 changes: 8 additions & 2 deletions src/components/irregularity/steps/Contacts.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useEffect } from 'react'
import { useTranslation } from 'next-i18next'

import { styled } from '@mui/system'
Expand All @@ -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 (
<Grid container spacing={4} alignContent="center">
<Subtitle label={t('steps.contacts.subtitle')} />
<Grid item xs={12}>
<Typography variant="body1" textAlign="justify">
<Typography variant="body1">
{t('steps.contacts.text')}
<Link href={routes.privacyPolicy}>
<span>{t('steps.contacts.text-link') + '.'}</span>
Expand Down
Loading