Skip to content

Commit

Permalink
Fundraiser card (#380)
Browse files Browse the repository at this point in the history
* create fundraiser card

* image size

* add fundraiser example
  • Loading branch information
Fishbakh-N authored Dec 15, 2023
1 parent 65d941e commit 8dba500
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import cxs from 'cxs';
import {Fragment} from 'preact/jsx-runtime';
import {GridCard} from 'src/components/widget/components/GridCard';
import {
nonprofitNameCss,
descriptionCss,
truncatedTextCss,
fundraiserCardLogoCss,
fundraiserAvatarAndNameWrapperCss,
largeFundraiserCardCss,
smallFundraiserCardCss
} from 'src/components/widget/components/NonprofitInfo/styles';
import {useNonprofitOrError} from 'src/components/widget/hooks/useNonprofit';
import {Fundraiser} from 'src/components/widget/types/Fundraiser';
import {LOGO_IMAGE_PLACEHOLDER_ID} from 'src/constants/placeholders';
import {getCloudinaryUrl} from 'src/helpers/getCloudinaryUrl';
import joinClassNames from 'src/helpers/joinClassNames';

const coverImageCss = (url: string) =>
cxs({
backgroundImage: `url(${url})`,
backgroundSize: 'cover',
width: 'calc(100% + 25px + 25px)',
height: '160px',
position: 'relative',
left: '-25px'
});

interface FundraiserCardProps {
fundraiser: Fundraiser;
}

export const FundraiserCard = ({fundraiser}: FundraiserCardProps) => {
return (
<Fragment>
<LargeFundraiserCard fundraiser={fundraiser} />
<SmallFundraiserCard fundraiser={fundraiser} />
</Fragment>
);
};

const LargeFundraiserCard = ({fundraiser}: FundraiserCardProps) => {
const {
name: nonprofitName,
logoCloudinaryId,
coverImageCloudinaryId,
hasAdmin
} = useNonprofitOrError();
const logoUrl = getCloudinaryUrl(
logoCloudinaryId ?? LOGO_IMAGE_PLACEHOLDER_ID
);
const coverImageUrl =
coverImageCloudinaryId &&
getCloudinaryUrl(coverImageCloudinaryId, {width: 320});

return (
<GridCard className={largeFundraiserCardCss}>
<div className={fundraiserAvatarAndNameWrapperCss}>
<div alt="nonprofit logo" className={fundraiserCardLogoCss(logoUrl)} />
<div className="every-embedded-fundraiser-card__nonprofit-name">
<h2 className={truncatedTextCss(1)}>{nonprofitName}</h2>
{fundraiser.creatorNonprofitId === fundraiser.nonprofitId && (
<p className={descriptionCss}>Official fundraiser</p>
)}
</div>
</div>
{coverImageUrl && <div className={coverImageCss(coverImageUrl)} />}
<h1 className={nonprofitNameCss}>
<span>{fundraiser.title}</span>
</h1>
{fundraiser.description && (
<p className={joinClassNames([descriptionCss, truncatedTextCss(3)])}>
{fundraiser.description}
</p>
)}
</GridCard>
);
};

const SmallFundraiserCard = ({fundraiser}: FundraiserCardProps) => {
const {
name: nonprofitName,
logoCloudinaryId,
coverImageCloudinaryId,
hasAdmin
} = useNonprofitOrError();
const logoUrl = getCloudinaryUrl(
logoCloudinaryId ?? LOGO_IMAGE_PLACEHOLDER_ID
);
const coverImageUrl =
coverImageCloudinaryId && getCloudinaryUrl(coverImageCloudinaryId);

return (
<GridCard className={smallFundraiserCardCss}>
<div className={fundraiserAvatarAndNameWrapperCss}>
<div alt="nonprofit logo" className={fundraiserCardLogoCss(logoUrl)} />
<h1 className={nonprofitNameCss}>
<span>{fundraiser.title}</span>
</h1>
</div>
</GridCard>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
nonprofitNameCss,
descriptionCss,
avatarAndNameWrapperCss,
cardCss
nonprofitCardCss
} from 'src/components/widget/components/NonprofitInfo/styles';
import {useNonprofitOrError} from 'src/components/widget/hooks/useNonprofit';
import {LOGO_IMAGE_PLACEHOLDER_ID} from 'src/constants/placeholders';
Expand All @@ -17,7 +17,7 @@ export const NonprofitCard = () => {
logoCloudinaryId ?? LOGO_IMAGE_PLACEHOLDER_ID
);
return (
<GridCard className={cardCss}>
<GridCard className={nonprofitCardCss}>
<div className={avatarAndNameWrapperCss}>
<div alt="nonprofit logo" className={logoImageCss(logoUrl)} />
<h1 className={nonprofitNameCss}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import {FundraiserCard} from 'src/components/widget/components/NonprofitInfo/FundraiserCard';
import {NonprofitCard} from 'src/components/widget/components/NonprofitInfo/NonprofitCard';
import {useFundraiserOrUndefined} from 'src/components/widget/hooks/useFundraiser';

export const NonprofitInfo = () => {
const fundraiser = useFundraiserOrUndefined();

if (fundraiser) {
return <FundraiserCard fundraiser={fundraiser} />;
}

return <NonprofitCard />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,19 @@ import {
Spacing,
verticalStackCss
} from 'src/components/widget/theme/spacing';
import joinClassNames from 'src/helpers/joinClassNames';

export const nonprofitNameCss = cxs({
lineHeight: '20px',
fontWeight: 'unset',
'> span': {
fontWeight: 700
}
});

export const fundraiserNameCss = cxs({
lineHeight: '20px',
fontWeight: 'unset',
'> span': {
fontWeight: 700
}
Expand All @@ -31,19 +41,69 @@ export const logoImageCss = (logoUrl: string) =>
}
});

export const cardCss = cxs({
export const fundraiserCardLogoCss = (logoUrl: string) =>
joinClassNames([
logoImageCss(logoUrl),
cxs({
width: '32px',
height: '32px',
flexShrink: 0,
[BREAKPOINTS.TabletLandscapeUp]: {
width: '40px',
height: '40px'
}
})
]);

export const nonprofitCardCss = cxs({
padding: `${Spacing.XL}`,
[BREAKPOINTS.TabletLandscapeUp]: {
...verticalStackCss.cxs(Spacing.S),
padding: `${Spacing.L}`
}
});

export const largeFundraiserCardCss = cxs({
display: 'none',
overflow: 'hidden',
[BREAKPOINTS.TabletLandscapeUp]: {
display: 'flex',
gap: `${Spacing.S}`,
flexDirection: 'column',
padding: `${Spacing.L}`
}
});

export const smallFundraiserCardCss = cxs({
display: 'flex',
gap: `${Spacing.S}`,
padding: `${Spacing.XL}`,
overflow: 'hidden',
[BREAKPOINTS.TabletLandscapeUp]: {
display: 'none',
flexDirection: 'column',
padding: `${Spacing.L}`
}
});

export const avatarAndNameWrapperCss = cxs({
...horizontalStackCss.cxs(Spacing.S),
alignItems: 'center'
});

export const fundraiserAvatarAndNameWrapperCss = cxs({
display: 'flex',
gap: `${Spacing.S}`,
alignItems: 'center',

'& > .every-embedded-fundraiser-card__nonprofit-name': {
display: 'none',
[BREAKPOINTS.TabletLandscapeUp]: {
display: 'block'
}
}
});

export const descriptionCss = cxs({
...textSize.xs,
color: 'rgba(0, 0, 0, 0.7)',
Expand All @@ -52,3 +112,15 @@ export const descriptionCss = cxs({
display: 'block'
}
});

export const truncatedTextCss = (numberLines: number) =>
cxs({
overflow: 'hidden',
overflowWrap: 'anywhere',
wordBreak: 'break-word',
textOverflow: 'ellipsis',
display: '-webkit-box',
'-webkit-box-orient': 'vertical',
'-webkit-line-clamp': numberLines,
alignItems: 'start'
});
31 changes: 28 additions & 3 deletions packages/donate-button-v4/src/helpers/getCloudinaryUrl.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
import {BASE_CLOUDINARY_URL} from 'src/constants/url';

const FLAGS = 'f_auto,q_auto/';
interface CloudinaryOptions {
width?: number;
height?: number;
fillMode?: 'fill' | 'lfill';
}

export const getCloudinaryUrl = (cloudinaryId: string) => {
return `${BASE_CLOUDINARY_URL}${FLAGS}${cloudinaryId}`;
const FLAGS = 'f_auto,q_auto';

export function fillDimensionsTransform(options: CloudinaryOptions) {
if (options.width === 0 || options.height === 0) {
throw new Error('dimensions cannot be 0');
}

return [
`c_${options.fillMode ?? 'lfill'}`,
options.width ? `w_${Math.floor(options.width)}` : undefined,
options.height ? `h_${Math.floor(options.height)}` : undefined
]
.filter((value?: string) => value !== undefined)
.join(',');
}

export const getCloudinaryUrl = (
cloudinaryId: string,
options?: CloudinaryOptions
) => {
return `${BASE_CLOUDINARY_URL}${FLAGS}${
options ? `,${fillDimensionsTransform(options)}` : ''
}/${cloudinaryId}`;
};
23 changes: 19 additions & 4 deletions packages/donate-button-v4/src/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,39 @@

<body style="height: 200vh">
<div>
<a style="font-size: 30px; margin-top: 10px;" href="https://www.every.org/irc?utm_source=testexample&method=stocks#/donate"
<a
style="font-size: 30px; margin-top: 10px"
href="https://www.every.org/irc#/donate"
>Donate</a
>
</div>
<div>
<a style="font-size: 30px; margin-top: 10px;" href="https://www.every.org/irc?utm_source=testexample&suggestedAmounts=2500,25000,250000&method=daf#/donate"
<a
style="font-size: 30px; margin-top: 10px"
href="https://www.every.org/irc?suggestedAmounts=2500,25000,250000&method=daf#/donate"
>Donate DAF</a
>
</div>
<div>
<a style="font-size: 30px; margin-top: 10px;" href="https://www.every.org/irc?utm_source=testexample&utm_campaign=donate-link&method=stocks#/donate"
<a
style="font-size: 30px; margin-top: 10px"
href="https://www.every.org/irc?utm_campaign=donate-link&method=stocks#/donate"
>Donate Asset</a
>
</div>
<div>
<a style="font-size: 30px; margin-top: 10px;" href="https://www.every.org/irc?utm_source=testexample&utm_campaign=donate-link&method=crypto#/donate/crypto"
<a
style="font-size: 30px; margin-top: 10px"
href="https://www.every.org/irc?utm_campaign=donate-link&method=crypto#/donate/crypto"
>Donate Crypto</a
>
</div>
<div>
<a
style="font-size: 30px; margin-top: 10px"
href="https://www.every.org/undp/f/undp-turkiye-earthquake#/donate/card"
>Donate Fundraiser</a
>
</div>
</body>
</html>

1 comment on commit 8dba500

@vercel
Copy link

@vercel vercel bot commented on 8dba500 Dec 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.