Fixes and improvements to Donations Home Page
Co-authored-by: yash-signal <yash@signal.org>
This commit is contained in:
parent
62cecc0a1c
commit
3b9d7e180a
5 changed files with 170 additions and 23 deletions
|
@ -8807,20 +8807,32 @@
|
|||
"description": "Title shown at the top of the donations preferences page"
|
||||
},
|
||||
"icu:PreferencesDonations__description": {
|
||||
"messageformat": "Private messaging, funded by you. No ads, no tracking, no compromise. Donate now to support Signal. <learnMoreLink>Learn more</learnMoreLink>",
|
||||
"messageformat": "Private messaging, funded by you. No ads, no tracking, no compromise. Donate now to support Signal. <readMoreLink>Read more</readMoreLink>",
|
||||
"description": "Description text explaining Signal's donation model with learn more link"
|
||||
},
|
||||
"icu:PreferencesDonations__donate-button": {
|
||||
"messageformat": "Donate",
|
||||
"description": "Button text to make a donation"
|
||||
},
|
||||
"icu:PreferencesDonations__my-support": {
|
||||
"messageformat": "My Support",
|
||||
"description": "Section header for the user's current donations"
|
||||
},
|
||||
"icu:PreferencesDonations__donate-button-with-amount": {
|
||||
"messageformat": "Donate {formattedCurrencyAmount}",
|
||||
"description": "Button text to make a donation after selecting a currency amount. Amount includes the currency symbol and is formatted in the locale's standard format. Examples: Donate $10; Donate ¥1000; Donate €10"
|
||||
},
|
||||
"icu:PreferencesDonations__mobile-info": {
|
||||
"messageformat": "Badges and monthly donations can be managed on your mobile device.",
|
||||
"description": "(Deleted 2025/07/09) Information about donations receipt syncing limitations"
|
||||
"description": "Information about some donations features only existing on mobile"
|
||||
},
|
||||
"icu:PreferencesDonations__privacy-modal-title": {
|
||||
"messageformat": "Your information is private",
|
||||
"description": "Title for the modal that explains donation privacy information"
|
||||
},
|
||||
"icu:PreferencesDonations__privacy-modal-content": {
|
||||
"messageformat": "<paragraph>Signal does not collect or store any of your personal information when you make a donation.</paragraph><paragraph>We use Stripe as our payment processor to receive your donations. We don't access, store, or save any of the information you provide to them.</paragraph><paragraph>Signal does not and cannot connect your donation to your Signal account.</paragraph><paragraph>Thank you for your support!</paragraph>",
|
||||
"description": "Content for the modal that explains donation privacy information"
|
||||
},
|
||||
"icu:PreferencesDonations__receipts": {
|
||||
"messageformat": "Receipts",
|
||||
|
|
1
images/icons/v3/open/open.svg
Normal file
1
images/icons/v3/open/open.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.802 1.77c-.907 0-1.632 0-2.217.049-.601.049-1.12.152-1.596.395a4.062 4.062 0 0 0-1.775 1.775c-.243.476-.346.995-.395 1.596-.048.585-.048 1.31-.048 2.217v4.396c0 .907 0 1.632.048 2.217.049.601.152 1.12.395 1.596a4.063 4.063 0 0 0 1.775 1.775c.476.243.995.346 1.596.395.585.048 1.31.048 2.217.048h4.396c.907 0 1.632 0 2.217-.048.601-.049 1.12-.152 1.596-.395a4.063 4.063 0 0 0 1.775-1.775c.243-.476.346-.995.395-1.596.048-.585.048-1.31.048-2.217v-1.365a.73.73 0 0 0-1.458 0v1.334c0 .945 0 1.61-.043 2.13-.042.51-.12.815-.241 1.052-.25.49-.648.888-1.138 1.138-.237.12-.542.2-1.053.24-.519.043-1.184.044-2.13.044H7.834c-.945 0-1.61 0-2.13-.043-.51-.042-.815-.12-1.052-.241a2.604 2.604 0 0 1-1.138-1.138c-.12-.237-.2-.542-.24-1.052-.043-.52-.044-1.185-.044-2.13V7.833c0-.945 0-1.61.043-2.13.042-.51.12-.815.24-1.052a2.61 2.61 0 0 1 1.139-1.138c.237-.12.542-.2 1.052-.24.52-.043 1.185-.044 2.13-.044h1.334a.73.73 0 0 0 0-1.458H7.802Z" fill="#000"/><path d="M18.23 2.5a.729.729 0 0 0-.73-.73h-5.417a.73.73 0 1 0 0 1.46h3.866l-1.256 1.046-6.459 6.458a.73.73 0 1 0 1.032 1.032l6.458-6.459 1.047-1.256v3.866a.73.73 0 1 0 1.458 0V2.5Z" fill="#000"/></svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -50,6 +50,7 @@
|
|||
height: 0.5px;
|
||||
border: none;
|
||||
margin: 0;
|
||||
margin-bottom: 12px;
|
||||
background-color: light-dark(
|
||||
variables.$color-black-alpha-12,
|
||||
variables.$color-white-alpha-12
|
||||
|
@ -59,8 +60,9 @@
|
|||
&__section-header {
|
||||
@include mixins.font-body-2-bold;
|
||||
width: 100%;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 8px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 12px;
|
||||
padding-inline: 8px;
|
||||
color: light-dark(
|
||||
variables.$color-black-alpha-85,
|
||||
variables.$color-white-alpha-85
|
||||
|
@ -68,7 +70,6 @@
|
|||
}
|
||||
|
||||
&__list {
|
||||
margin-top: 24px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
@ -81,7 +82,7 @@
|
|||
align-items: center;
|
||||
gap: 12px;
|
||||
padding-block: 12px;
|
||||
padding-inline: 24px;
|
||||
padding-inline: 8px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
|
@ -143,6 +144,30 @@
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
&__open {
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
@include mixins.color-svg(
|
||||
'../images/icons/v3/open/open.svg',
|
||||
light-dark(variables.$color-gray-45, variables.$color-gray-25)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__mobile-info {
|
||||
@include mixins.font-subtitle;
|
||||
margin-top: 18px;
|
||||
align-self: flex-start;
|
||||
padding-inline: 8px;
|
||||
color: light-dark(
|
||||
variables.$color-black-alpha-50,
|
||||
variables.$color-white-alpha-50
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,3 +364,25 @@
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
.DonationPrivacyInformationModal {
|
||||
&__footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
&__faqs-link {
|
||||
@include mixins.button-reset;
|
||||
|
||||
& {
|
||||
color: variables.$color-ultramarine;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
62
ts/components/DonationPrivacyInformationModal.tsx
Normal file
62
ts/components/DonationPrivacyInformationModal.tsx
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import { Modal } from './Modal';
|
||||
import { Button } from './Button';
|
||||
import { I18n } from './I18n';
|
||||
import type { LocalizerType } from '../types/Util';
|
||||
import { openLinkInWebBrowser } from '../util/openLinkInWebBrowser';
|
||||
|
||||
export type DonationPrivacyInformationModalProps = {
|
||||
i18n: LocalizerType;
|
||||
onClose: () => void;
|
||||
};
|
||||
|
||||
export function DonationPrivacyInformationModal({
|
||||
i18n,
|
||||
onClose,
|
||||
}: DonationPrivacyInformationModalProps): JSX.Element {
|
||||
const handleDonationFAQsClick = () => {
|
||||
openLinkInWebBrowser(
|
||||
'https://support.signal.org/hc/articles/360031949872-Donor-FAQs'
|
||||
);
|
||||
};
|
||||
|
||||
const modalFooter = (
|
||||
<div className="DonationPrivacyInformationModal__footer">
|
||||
<button
|
||||
type="button"
|
||||
className="DonationPrivacyInformationModal__faqs-link"
|
||||
onClick={handleDonationFAQsClick}
|
||||
>
|
||||
{i18n('icu:PreferencesDonations__faqs')}
|
||||
</button>
|
||||
<Button onClick={onClose}>{i18n('icu:Confirmation--confirm')}</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
const paragraphComponent = useCallback(
|
||||
(parts: Array<string | JSX.Element>) => <p>{parts}</p>,
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
modalName="DonationPrivacyInformationModal"
|
||||
i18n={i18n}
|
||||
title={i18n('icu:PreferencesDonations__privacy-modal-title')}
|
||||
onClose={onClose}
|
||||
hasXButton
|
||||
modalFooter={modalFooter}
|
||||
>
|
||||
<I18n
|
||||
components={{
|
||||
paragraph: paragraphComponent,
|
||||
}}
|
||||
i18n={i18n}
|
||||
id="icu:PreferencesDonations__privacy-modal-content"
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
}
|
|
@ -28,6 +28,8 @@ import { ToastType } from '../types/Toast';
|
|||
import { createLogger } from '../logging/log';
|
||||
import { toLogFormat } from '../types/errors';
|
||||
import { I18n } from './I18n';
|
||||
import { openLinkInWebBrowser } from '../util/openLinkInWebBrowser';
|
||||
import { DonationPrivacyInformationModal } from './DonationPrivacyInformationModal';
|
||||
import type { SubmitDonationType } from '../state/ducks/donations';
|
||||
import { getHumanDonationAmount } from '../util/currency';
|
||||
|
||||
|
@ -86,20 +88,6 @@ function isDonationPage(page: SettingsPage): page is DonationPage {
|
|||
);
|
||||
}
|
||||
|
||||
function LearnMoreButton(parts: ReactNode): JSX.Element {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="PreferencesDonations__description__read-more"
|
||||
onClick={() => {
|
||||
// DESKTOP-8973
|
||||
}}
|
||||
>
|
||||
{parts}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function DonationsHome({
|
||||
i18n,
|
||||
userAvatarData,
|
||||
|
@ -114,6 +102,24 @@ function DonationsHome({
|
|||
const avatarData = userAvatarData[0];
|
||||
const avatarBuffer = avatarData?.buffer;
|
||||
const hasReceipts = donationReceipts.length > 0;
|
||||
const [showPrivacyModal, setShowPrivacyModal] = useState(false);
|
||||
|
||||
const ReadMoreButtonWithModal = useCallback(
|
||||
(parts: ReactNode): JSX.Element => {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="PreferencesDonations__description__read-more"
|
||||
onClick={() => {
|
||||
setShowPrivacyModal(true);
|
||||
}}
|
||||
>
|
||||
{parts}
|
||||
</button>
|
||||
);
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="PreferencesDonations">
|
||||
|
@ -136,7 +142,7 @@ function DonationsHome({
|
|||
<div className="PreferencesDonations__description">
|
||||
<I18n
|
||||
components={{
|
||||
learnMoreLink: LearnMoreButton,
|
||||
readMoreLink: ReadMoreButtonWithModal,
|
||||
}}
|
||||
i18n={i18n}
|
||||
id="icu:PreferencesDonations__description"
|
||||
|
@ -157,6 +163,12 @@ function DonationsHome({
|
|||
|
||||
<hr className="PreferencesDonations__separator" />
|
||||
|
||||
{hasReceipts && (
|
||||
<div className="PreferencesDonations__section-header">
|
||||
{i18n('icu:PreferencesDonations__my-support')}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ListBox className="PreferencesDonations__list">
|
||||
{hasReceipts && (
|
||||
<ListBoxItem
|
||||
|
@ -175,16 +187,29 @@ function DonationsHome({
|
|||
<ListBoxItem
|
||||
className="PreferencesDonations__list-item"
|
||||
onAction={() => {
|
||||
// TODO: Handle donation FAQs action
|
||||
openLinkInWebBrowser(
|
||||
'https://support.signal.org/hc/articles/360031949872-Donor-FAQs'
|
||||
);
|
||||
}}
|
||||
>
|
||||
<span className="PreferencesDonations__list-item__icon PreferencesDonations__list-item__icon--faqs" />
|
||||
<span className="PreferencesDonations__list-item__text">
|
||||
{i18n('icu:PreferencesDonations__faqs')}
|
||||
</span>
|
||||
<span className="PreferencesDonations__list-item__chevron" />
|
||||
<span className="PreferencesDonations__list-item__open" />
|
||||
</ListBoxItem>
|
||||
</ListBox>
|
||||
|
||||
<div className="PreferencesDonations__mobile-info">
|
||||
{i18n('icu:PreferencesDonations__mobile-info')}
|
||||
</div>
|
||||
|
||||
{showPrivacyModal && (
|
||||
<DonationPrivacyInformationModal
|
||||
i18n={i18n}
|
||||
onClose={() => setShowPrivacyModal(false)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue