Commit 3b335c6d authored by Stephanie Kirtiadi's avatar Stephanie Kirtiadi Committed by peterh-gr
Browse files

Style the donate page and the donate thank you page.

Moved the styling in lego.

Issue #45540
parent bfdb9198
_model: page
---
_template: layout-donate.html
---
title: Thank You
---
section: Donate
---
body: Thank you for your support of the Tor Project. You should receive an email receipt shortly. With your support, we'll be able to tackle ambitious projects, like increasing the capacity and scalability of the Tor network, taking our anti-censorship protections to the next level, and optimizing our development of Tor Browser for Android.
It's an incredible time to stand up for world-leading security and privacy software. Tell family, friends, and colleagues that you're supporting privacy and security and taking back the internet with Tor!
---
html: empty.html
......@@ -6,6 +6,6 @@ section:
---
title: Donate
---
_template: layout.html
_template: layout-donate.html
---
html: donate-form.html
import React, {useState, useRef, useContext, useEffect} from 'react';
import {injectStripe} from 'react-stripe-elements';
import {GivingForm} from './giving_form';
export function _ChampionsOfPrivacyGivingForm(props) {
const {stripe, donateProccessorBaseUrl} = props;
return(
<React.Fragment>
<GivingForm
frequencyOptions='champions-of-privacy'
stripe={stripe}
donateProccessorBaseUrl={donateProccessorBaseUrl}
/>
</React.Fragment>
);
}
export const ChampionsOfPrivacyGivingForm = injectStripe(_ChampionsOfPrivacyGivingForm);
import React from 'react';
import {useState} from 'react';
import {useEffect} from 'react';
import {Checkbox} from './checkbox';
import {WalletAddresses} from './wallet_addresses';
import {AmountField} from './amount_field';
import {t} from './i18n';
export function CryptocurrencyForm(props) {
const [donateAnonymously, setDonateAnonymously] = useState(false);
const [selectedCountry, setSelectedCountry] = useState('US');
const [fieldErrors, setFieldErrors] = useState([]);
const {wallets} = props;
const countryChanged = (event) => {
setSelectedCountry(event.target.value);
};
const onAnonymousCheckboxChange = (event) => {
setDonateAnonymously(event.target.checked);
};
const onFieldValidate = (fieldName, valid) => {
if (valid) {
const pos = fieldErrors.indexOf(fieldName);
fieldErrors.splice(pos, 1);
setFieldErrors([...fieldErrors]);
} else {
setFieldErrors([fieldName, ...fieldErrors]);
}
};
const onSubmit = (event) => {
if (fieldErrors.length > 0) {
event.preventDefault();
}
};
const walletOptions = wallets.map((wallet) => {
return (<option key={wallet.symbol} value={wallet.symbol}>{wallet.name} ({wallet.symbol})</option>)
});
let conditionalFields = null;
if (!donateAnonymously) {
conditionalFields = (
<React.Fragment>
<input className="field" name="firstName" placeholder={t('t-first-name')} maxLength="256" type="text" required />
<input className="field" name="lastName" placeholder={t('t-last-name')} maxLength="256" type="text" />
</React.Fragment>
);
}
return(
<form action="/cryptocurrency/donate" method="POST" onSubmit={onSubmit}>
<div className="section">
<div className="form-column">
<h4>{t('t-your-info')}</h4>
<div className="form-fields">
<div className="anonymous-selection checkbox-row">
<Checkbox name="donateAnonymously" onChange={onAnonymousCheckboxChange} />
<label className="light" htmlFor="donateAnonymously">{t('t-donate-anonymously')}</label>
</div>
{conditionalFields}
<div className="mailing-list-opt-in checkbox-row">
<input name="mailingListOptIn" id="mailingListOptIn" type="checkbox" />
<label className="light" htmlFor="mailingListOptIn">{t('t-start-email-updates')}</label>
</div>
<input className="field" name="email" placeholder={t('t-email')} maxLength="256" type="text" required />
<label htmlFor="estimatedDonationDate">{t('t-estimated-donation-date')}</label>
<input name="estimatedDonationDate" id="estimatedDonationDate" placeholder={t('t-estimated-donation-date')} type="date" required />
<select className="field required" name="cryptocurrencyType" required>
<option value="">{t('t-choose-currency')}</option>
{walletOptions}
</select>
<AmountField name="currencyAmount" placeHolder={t('t-currency-amount')} onFieldValidate={onFieldValidate} />
</div>
</div>
<div className="wallet-column">
<h4>{t('t-wallet-addresses')}</h4>
<WalletAddresses wallets={wallets} />
</div>
</div>
<div className="section button-section">
<input className="donate button" type="submit" value={t('t-report-donation')}/>
</div>
</form>
);
}
......@@ -8,7 +8,7 @@ export function FrequencyOptionButton(props) {
label = 'Monthly';
}
var classes = ['btn'];
var classes = ['btn', name];
if (name == frequency) {
classes.push('selected');
}
......
......@@ -281,7 +281,7 @@ export function _GivingForm(props) {
setLoading(false);
newErrors.push(new NamedError('stripeError', errorMessage));
} else {
window.location.href = donateProccessorBaseUrl + '/thank-you';
window.location.href = '/donate-thank-you';
}
} else if ('error' in tokenCreated) {
const errorMessage = tokenCreated['error'].message;
......@@ -418,7 +418,7 @@ export function _GivingForm(props) {
</div>
<div className="payment-method-area">
<h4 className="payment-method-question">
how do you want to <span className="green">DONATE</span>?
how do you want to <span className="lime">DONATE</span>?
</h4>
<div className="payment-option">
{getPaymentOptionButtons()}
......
import '../sass/style.scss';
import 'babel-polyfill';
import {CryptocurrencyForm} from './cryptocurrency_form';
import {LoadingDialog} from './loading_dialog';
import {GivingForm} from './giving_form';
import {ChampionsOfPrivacyGivingForm} from './champions_of_privacy_giving_form';
import {PaymentController, GiftMatchingController} from './payment_controller'
import React from 'react';
import ReactDOM from 'react-dom';
......@@ -12,10 +10,8 @@ import {StripeProvider, Elements} from 'react-stripe-elements';
const reactCallbacks = {};
const availableComponents = {
'CryptocurrencyForm': CryptocurrencyForm,
'LoadingDialog': LoadingDialog,
'GivingForm': GivingForm,
'ChampionsOfPrivacyGivingForm': ChampionsOfPrivacyGivingForm,
};
const appContext = {};
......
......@@ -48,7 +48,7 @@ export function PayPalButton(props) {
toggleLoading(false);
throw new Error(errorMessage);
} else {
document.location = '/thank-you';
document.location = '/donate-thank-you';
}
}
};
......
......@@ -13,7 +13,7 @@ export function PaymentOptionButton(props) {
return (
<React.Fragment>
<button type="button" className={classes.join(" ")} name={method.name} onClick={onPaymentSelection}>{method.label}</button>
<button className={classes.join(" ")} name={method.name} onClick={onPaymentSelection}>{method.label}</button>
</React.Fragment>
);
}
......@@ -16,7 +16,6 @@ export function PriceButtons(props) {
}
return (
<button
type="button"
className={classes.join(' ')}
key={price}
name={price}
......
......@@ -68,7 +68,6 @@ export const perks = [
export const pricesOnButtons = {
'single': [2500, 7500, 12500, 25000, 50000],
'monthly': [500, 1000, 2500, 5000, 10000],
'champions-of-privacy': [100000, 500000, 1000000],
};
export const paymentMethods = [
......@@ -215,19 +214,16 @@ export const initialSelectedPrices = {
'single': 12500,
'monthly': 2500,
'both': 12500,
'champions-of-privacy': 100000
}
export const displayPerkSelections = {
'single': true,
'monthly': true,
'both': true,
'champions-of-privacy': false
}
export const initialFrequency = {
'single': 'single',
'monthly': 'monthly',
'both': 'single',
'champions-of-privacy': 'champions-of-privacy'
}
import React from 'react';
import {useEffect} from 'react';
import {useRef} from 'react';
import {useState} from 'react';
import {Manager} from 'react-popper';
import {Popper} from 'react-popper';
import {Reference} from 'react-popper';
import copy from 'copy-to-clipboard';
import {t} from './i18n';
export function WalletAddress(props) {
const [showPopup, setShowPopup] = useState(false);
const {symbol, id, name} = props;
const walletIdRef = useRef(null);
const buttonClicked = (e) => {
setShowPopup(true);
const walletId = walletIdRef.current;
const value = walletId.getAttribute('value');
copy(value);
};
const renderPopper = () => {
const classes = ['notify-popup'];
if (showPopup) {
classes.push('start');
}
return (
<Popper placement="top">
{({ref, style, placement, arrowProps}) => (
<div className={classes.join(' ')} ref={ref} style={style} data-placement={placement}>
{ t('t-copied') }
<div className="arrow" ref={arrowProps.ref} style={arrowProps.style} />
</div>
)}
</Popper>
);
};
useEffect(() => {
if (showPopup) {
setTimeout(() => { setShowPopup(false); }, 100);
}
}, [showPopup]);
const popup = renderPopper();
return (
<li>
<div className="currency-name">{ name } ({ symbol })</div>
<input ref={walletIdRef} className="wallet-id" type="text" value={id} readOnly />
<Manager>
<Reference>
{({ref}) => (
<button type="button" className="copy-button" ref={ref} onClick={buttonClicked}></button>
)}
</Reference>
{popup}
</Manager>
</li>
);
}
import React from 'react';
import {WalletAddress} from './wallet_address';
export function WalletAddresses(props) {
const {wallets} = props;
const walletAddresses = props.wallets.map((wallet) => {
return (<WalletAddress key={wallet.symbol} {...wallet} />);
});
return (
<ul>
{walletAddresses}
</ul>
);
}
......@@ -20,12 +20,11 @@
}
}
&:hover {
background-color: $color-green;
color: $color-white;
background-color: $color-lime;
}
&.selected {
background-color: $color-green;
color: $color-white;
background-color: $color-lime;
color: $color-black;
cursor: default;
}
@include breakpoint($screen-s) {
......
......@@ -10,7 +10,7 @@ textarea {
border: 1px solid $color-dark-grey;
color: $color-grey;
font-size: 16px;
height: 27px;
height: 43px;
margin: 9px;
padding: 8px 12px;
&.required {
......
.champions-of-privacy {
.payment-other-link {
margin-bottom: 10px;
}
}
.cryptocurrency {
.content {
display: flex;
flex: 0 0 100%;
flex-wrap: wrap;
justify-content: center;
h4 {
text-align: center;
width: 100%;
}
&.cryptocurrency-main a {
color: $color-blue-violet;
}
}
.btc-form {
.btc-onion-link {
text-align: center;
width: 100%;
display: block;
margin-top: 17px;
}
}
.intro-text-section {
margin: 0 15px;
}
#cryptocurrency-form {
margin: auto;
max-width: 1024px;
}
.copy-button {
background: url('../../assets/static/images/donate/copy.svg') center / 12px 12px no-repeat;
border: none;
height: 43px;
width: 43px;
padding: 5px 5px 2px 5px;
margin: 0;
z-index: 100;
&:focus {
outline: none;
}
}
.donate.button {
background-color: $color-lime;
color: $color-black;
height: 50px;
width: 300px;
}
.field-error {
color: $color-red;
font-size: 12px;
}
.form-column {
margin-bottom: 20px;
padding-left: 15px;
padding-right: 15px;
@include breakpoint($screen-m) {
width: 50%;
}
}
.form-fields {
display: grid;
grid-column-gap: 10px;
grid-row-gap: 10px;
grid-template-columns: [first] 1fr [second] 1fr [end];
margin-top: 20px;
@include breakpoint($screen-s) {
grid-template-columns: [first] 1fr [second] 1fr [third] 1fr [fourth] 1fr [end];
}
}
input {
box-sizing: border-box;
height: 43px;
margin: 0;
width: 100%;
&[type=checkbox] {
width: auto;
}
&[required] {
border-color: $color-lime;
}
&.error {
border-color: $color-red;
}
&[name=firstName] {
grid-column: first / span 2;
}
&[name=lastName] {
grid-column: first / end;
@include breakpoint($screen-s) {
grid-column-start: third;
}
}
&[name=streetAddress] {
grid-column: first / end;
@include breakpoint($screen-s) {
grid-column: first / fourth;
}
}
&[name=extendedAddress] {
grid-column-start: first;
@include breakpoint($screen-s) {
grid-column-start: fourth;
}
}
&[name=locality] {
grid-column: first / span 2;
}
&[name=postalCode] {
grid-column: first / span 2;
}
&[name=email] {
grid-column: first / end;
}
&[name=estimatedDonationDate] {
@include breakpoint($screen-s) {
grid-column: 3 / span 2;
}
}
&[name=region] {
grid-column: first / span 2;
@include breakpoint($screen-s) {
grid-column: third / span 2;
}
}
}
label[for=estimatedDonationDate] {
align-self: center;
grid-column: first;
text-align: right;
@include breakpoint($screen-s) {
grid-column: first / span 2;
}
}
.field-area.currencyAmount {
grid-column: first / span 2;
@include breakpoint($screen-s) {
grid-column: third / span 2;
}
}
.checkbox-row {
display: flex;
grid-column: first / end;
align-items: center;
input {
margin-right: 5px;
}
}
select {
box-sizing: border-box;
height: 43px;
margin: 0;
&[name=country] {
grid-column: first / end;
}
&[name=region] {
grid-column: first / span 2;
@include breakpoint($screen-s) {
grid-column: third / span 2;
}
}
&[name=cryptocurrencyType] {
grid-column: first / span 2;
color: $color-black;
border-color: $color-lime;
}
}
.wallet-column {
padding-left: 15px;
padding-right: 15px;
width: 100%;
@include breakpoint($screen-m) {
width: 50%;
}
ul {
list-style-type: none;
margin-top: 20px;
padding: 0;
width: 100%;
}
li {
align-items: center;
display: flex;
margin-bottom: 10px;
width: 100%;
&:first-child {
.wallet-id {
border-top: solid 1px;
}
}
}
.currency-name {
padding: 5px;
width: 30%;
}
.wallet-id {
font-family: $mono-font-family;
padding: 5px;
width: 60%;
}
}
.section {
display: flex;
flex-wrap: wrap;
justify-content: center;
padding: 10px;
}
.button-section {
justify-content: center;