diff options
author | Drew DeVault <sir@cmpwn.com> | 2019-05-06 09:36:41 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2019-05-06 09:36:41 -0400 |
commit | 7d21723b0e2649016f46fe37dacbdf00a9dc5bd3 (patch) | |
tree | 0cc859a5dc4d1ea942f17e3b5988360021fbce8f /donation-calc | |
parent | 8d45fb169c23961b9b6e5727bc84f4ee2984aaa2 (diff) |
Add patreon fees article
Diffstat (limited to 'donation-calc')
-rw-r--r-- | donation-calc/index.js | 794 |
1 files changed, 372 insertions, 422 deletions
diff --git a/donation-calc/index.js b/donation-calc/index.js index 08faee2..c24ef82 100644 --- a/donation-calc/index.js +++ b/donation-calc/index.js @@ -6,351 +6,152 @@ import React, { Component } from 'react'; import ReactDOM from 'react-dom'; +const vatRates = { + "Austria": 0.020, + "Belgium": 0.021, + "Bulgaria": 0.020, + "Croatia": 0.025, + "Cyprus": 0.019, + "Czech Republic": 0.021, + "Denmark": 0.025, + "Estonia": 0.020, + "Finland": 0.024, + "France": 0.020, + "Germany": 0.019, + "Greece": 0.024, + "Hungary": 0.027, + "Ireland": 0.023, + "Italy": 0.022, + "Latvia": 0.021, + "Lithuania": 0.021, + "Luxembourg": 0.017, + "Malta": 0.018, + "Netherlands": 0.021, + "Poland": 0.023, + "Portugal": 0.023, + "Romania": 0.019, + "Slovakia": 0.020, + "Slovenia": 0.022, + "Spain": 0.021, + "Sweden": 0.025, +}; + class Calculator extends Component { constructor() { super(); this.state = { - provider: "fosspay", + country: "Germany", amount: "5.00", - inMethod: "card-usd", - inAmount: "100.00", - frequency: "month", - outMethod: "usd", + paypal: false, + vat: false, patreonCreators: [ - { "id": 0, "username": "SirCmpwn", "amount": "5.00" } + { + id: 0, + username: "SirCmpwn", + amount: 5, + displayAmount: "5.00", + founding: true, + plan: "pro", + upfront: false, + } ] }; - this.renderFosspay = this.renderFosspay.bind(this); - this.renderLiberapay = this.renderLiberapay.bind(this); this.renderPatreon = this.renderPatreon.bind(this); } - renderFosspay() { - const { amount } = this.state; - let amt = parseFloat(amount); - const stripe = amt * 0.029 + 0.30; - const creator = amt - stripe; - return ( - <div> - <div class="form-group"> - <label for="amount">Amount</label> - <div class="input-group"> - <span class="input-group-addon">$</span> - <input - type="text" - class="form-control" - aria-label="Amount" - onChange={e => this.setState({ amount: e.target.value })} - value={amount} - /> - <span class="input-group-addon">per month</span> - </div> - </div> - <table class="table"> - <thead> - <tr> - <th style={{ width: "12rem" }}>You pay</th> - <th></th> - <th - style={{ textAlign: "right" }} - >${amt.toFixed(2)}</th> - <th></th> - </tr> - </thead> - <tbody> - <tr> - <td>Stripe fee</td> - <td>2.9% + 30¢</td> - <td - style={{ textAlign: "right" }} - >${stripe.toFixed(2)}</td> - <td></td> - </tr> - <tr class="active"> - <th>Creator earns (pre-tax)</th> - <th></th> - <th - style={{ textAlign: "right" }} - >${creator.toFixed(2)}</th> - <td>per month</td> - </tr> - <tr> - <th></th> - <th></th> - <th - style={{ textAlign: "right" }} - >{(creator / amt * 100).toFixed(0)}%</th> - <td>of your donation</td> - </tr> - </tbody> - </table> - </div> - ); + patreonFee(creator) { + let text, rate, fixed; + if (creator.founding) { + return { + text: "5%", + fee: creator.amount * 0.05, + }; + } else { + switch (creator.plan) { + case "lite": + return { + text: "5%", + fee: creator.amount * 0.05, + }; + case "pro": + if (creator.founding) { + return { + text: "5%", + fee: creator.amount * 0.05, + }; + } + return { + text: "8%", + fee: creator.amount * 0.08, + }; + case "premium": + if (creator.founding) { + return { + text: "9%", + fee: creator.amount * 0.09, + }; + } + return { + text: "12%", + fee: creator.amount * 0.12, + }; + } + } } - renderLiberapay() { - const { amount, inMethod, frequency, outMethod } = this.state; - let amt = parseFloat(this.state.amount); - let inAmount = parseFloat(this.state.inAmount); - let inFee; - switch (inMethod) { - case "card-usd": - inFee = inAmount * 0.02925 + 0.35; - break; - case "card-euro": - inFee = inAmount * 0.02106 + 0.26; - break; - case "wire": - inFee = inAmount * 0.00585; - break; - case "debit": - inFee = 0.72; - break; + transactionFee(creator, paypal) { + let text, rate, fixed; + if (creator === null) { + return { + text: paypal ? "3.9% + 30¢" : "2.9% + 30¢", + }; + } + if (creator.founding && creator.upfront) { + return { + text: paypal ? "3.9% + 30¢" : "2.9% + 30¢", + fee: creator.amount * (paypal ? 0.039 : 0.029) + 0.30, + }; + } else { + if (creator.amount <= 3) { + return { + text: paypal ? "5% + 10¢" : "5% + 10¢", + fee: creator.amount * (paypal ? 0.06 : 0.05) + 0.10, + }; + } else { + return { + text: paypal ? "3.9% + 30¢" : "2.9% + 30¢", + fee: creator.amount * 0.029 + 0.30, + }; + } } - let lpBalance = inAmount - inFee; - const creator = amt; - const outFee = ({ - "sepa": 0, - "euro": 2.93, - "usd": 3.51 - })[outMethod]; - const creatorOut = lpBalance - outFee; - const duration = Math.floor(lpBalance / amt); - const inTypes = { - "card-usd": "Card", - "card-euro": "Card", - "wire": "Wire", - "debit": "Debit", - }; - const humanInFee = { - "card-usd": "2.925%+35¢", - "card-euro": "2.106%+€0.21", - "wire": "0.585%", - "debit": "€0.59", - }; - return ( - <div> - <p> - If you transfer this amount into your Liberapay wallet: - </p> - <div class="form-group"> - <label for="amount">Amount</label> - <div class="input-group"> - <span class="input-group-addon">$</span> - <input - type="text" - class="form-control" - aria-label="Amount" - onChange={e => this.setState({ inAmount: e.target.value })} - value={this.state.inAmount} - /> - </div> - <div style={{marginTop: "1rem"}}> - <label>Transfer method</label> - </div> - <fieldset class="form-group"> - <label class="radio-inline"> - <input - type="radio" - name="inMethod" - checked={inMethod === "card-usd"} - onChange={e => this.setState({ inMethod: "card-usd" })} - /> - Card - USD (2.925%+35¢) - </label> - <label class="radio-inline"> - <input - type="radio" - name="inMethod" - checked={inMethod === "card-euro"} - onChange={e => this.setState({ inMethod: "card-euro" })} - /> - Card - Euro (2.106%+€0.21) - </label> - </fieldset> - <fieldset class="form-group"> - <label class="radio-inline"> - <input - type="radio" - name="inMethod" - checked={inMethod === "wire"} - onChange={e => this.setState({ inMethod: "wire" })} - /> - Wire transfer (0.585%) - </label> - <label class="radio-inline"> - <input - type="radio" - name="inMethod" - checked={inMethod === "debit"} - onChange={e => this.setState({ inMethod: "debit" })} - /> - Direct debit - Euro (€0.59) - </label> - </fieldset> - </div> - <p>Your <strong>transaction fees</strong> will be:</p> - <table class="table"> - <thead> - <tr> - <th style={{ width: "12rem" }}>You pay</th> - <th></th> - <th>${inAmount.toFixed(2)}</th> - </tr> - </thead> - <tbody> - <tr class="active"> - <td>{inTypes[inMethod]} fee</td> - <td>{humanInFee[inMethod]}</td> - <td>(${inFee.toFixed(2)})</td> - </tr> - <tr> - <td>Liberapay balance</td> - <td></td> - <td>${lpBalance.toFixed(2)}</td> - </tr> - </tbody> - </table> - <p>If you support your creators for this amount:</p> - <div class="form-group"> - <label for="amount">Amount</label> - <div class="input-group"> - <span class="input-group-addon">$</span> - <input - type="text" - class="form-control" - aria-label="Amount" - onChange={e => this.setState({ amount: e.target.value })} - value={amount} - /> - </div> - </div> - <fieldset class="form-group" style={{ marginTop: "1rem" }}> - <label class="radio-inline"> - <input - type="radio" - name="frequency" - checked={frequency === "week"} - onChange={e => this.setState({ frequency: "week" })} - /> Per week - </label> - <label class="radio-inline"> - <input - type="radio" - name="frequency" - checked={frequency === "month"} - onChange={e => this.setState({ frequency: "month" })} - /> Per month - </label> - <label class="radio-inline"> - <input - type="radio" - name="frequency" - checked={frequency === "year"} - onChange={e => this.setState({ frequency: "year" })} - /> Per year - </label> - </fieldset> - <p> - Your creators earn <strong>${ - creator.toFixed(2)}</strong> per { - frequency} for <strong>{duration} {frequency}(s)</strong>. - If they wait until the end of this timeframe to withdraw their funds, - their <strong>withdrawal fees</strong> will look like this: - </p> - <fieldset class="form-group" style={{ marginTop: "1rem" }}> - <label class="radio-inline"> - <input - type="radio" - name="outMethod" - checked={outMethod === "sepa"} - onChange={e => this.setState({ outMethod: "sepa" })} - /> - <a href="https://en.wikipedia.org/wiki/Single_Euro_Payments_Area"> - SEPA - </a> (Europe): Free - </label> - <label class="radio-inline"> - <input - type="radio" - name="outMethod" - checked={outMethod === "euro"} - onChange={e => this.setState({ outMethod: "euro" })} - /> Other Europe: €2.93 - </label> - <label class="radio-inline"> - <input - type="radio" - name="outMethod" - checked={outMethod === "usd"} - onChange={e => this.setState({ outMethod: "usd" })} - /> USD: $3.51 - </label> - </fieldset> - <table class="table"> - <thead> - <tr> - <th style={{ width: "12rem" }}>You pay</th> - <th></th> - <th - style={{ textAlign: "right" }} - >${lpBalance.toFixed(2)}</th> - <th></th> - </tr> - </thead> - <tbody> - <tr> - <td>Withdrawal fee</td> - <td></td> - <td - style={{ textAlign: "right" }} - >(${outFee.toFixed(2)})</td> - <th></th> - </tr> - <tr class="active"> - <th>Creator earns (pre-tax)</th> - <th></th> - <th - style={{ textAlign: "right" }} - >${creatorOut.toFixed(2)}</th> - <td> - over {duration} {frequency}(s) - </td> - </tr> - <tr> - <th></th> - <th></th> - <th - style={{ textAlign: "right" }} - >{(creatorOut / inAmount * 100).toFixed(0)}%</th> - <td>of your donation</td> - </tr> - </tbody> - </table> - <div class="alert alert-info"> - Fees in euros are for reference only. All amounts should be input in - USD and all computed amounts are shown in USD based on the (probably - dated) assumption that €1 EUR = $1.22 USD. Sorry. - </div> - </div> - ); } renderPatreon() { - const creators = this.state.patreonCreators.sort(c => c.id); - const total = creators.map(c => parseFloat(c.amount)) - .reduce((i, acc) => acc + i, 0); - const tx_fee = total * 0.029 + 0.30; + const creators = this.state.patreonCreators.slice() + .sort((a, b) => a.id - b.id); + const { country, paypal, vat } = this.state; + const total = creators.reduce((a, c) => a + c.amount, 0); + const batch_total = creators + .filter(c => c.founding && !c.upfront) + .reduce((a, c) => a + c.amount, 0); + const batch_tx_fee = batch_total ? batch_total * + (this.state.paypal ? 0.039 : 0.029) + 0.30 : 0; + const tx_fees = creators.filter(c => !c.founding || c.upfront) + .reduce((a, c) => a + this.transactionFee(c, paypal).fee, 0) + batch_tx_fee; + const patreon_fees = + creators.reduce((a, c) => a + this.patreonFee(c).fee, 0); + const total_fees = tx_fees + patreon_fees; + const total_after_fees = total - total_fees; return ( <div> {creators.map(creator => <div key={creator.id}> - <div class="form-group"> - <label for={`user-${creator.id}`}>Creator</label> + <div className="form-group"> + <label htmlFor={`user-${creator.id}`}>Creator</label> <input id={`user-${creator.id}`} type="text" - class="form-control" + className="form-control" aria-label="Username" onChange={e => this.setState({ patreonCreators: [ @@ -361,46 +162,143 @@ class Calculator extends Component { value={creator.username} /> </div> - <div class="form-group"> - <label for="amount">Amount</label> - <div class="input-group"> - <span class="input-group-addon">$</span> + <div className="form-group"> + <label className="checkbox-inline"> + <input type="checkbox" + name={"founding-" + creator.id} + name={"founding-" + creator.id} + checked={creator.founding} + onChange={e => this.setState({ + patreonCreators: [ + { ...creator, founding: e.target.checked }, + ...creators.filter(c => c.id != creator.id) + ] + })} + /> Founding creator + {" "} + <a + href="#founding-creators" + >(?)</a> + </label> + <label className="checkbox-inline"> + <input type="checkbox" + name={"upfront-" + creator.id} + name={"upfront-" + creator.id} + checked={creator.upfront} + onChange={e => this.setState({ + patreonCreators: [ + { ...creator, upfront: e.target.checked }, + ...creators.filter(c => c.id != creator.id) + ] + })} + /> Charge up front + {" "} + <a + href="#charge-up-front" + >(?)</a> + </label> + </div> + <div className="form-group"> + <label className="radio-inline"> + <input type="radio" + name={"type-" + creator.id} + name={"type-" + creator.id} + value="lite" + checked={creator.plan === "lite"} + onChange={e => this.setState({ + patreonCreators: [ + { ...creator, plan: "lite" }, + ...creators.filter(c => c.id != creator.id) + ] + })} + /> Lite + </label> + <label className="radio-inline"> + <input type="radio" + name={"type-" + creator.id} + name={"type-" + creator.id} + value="pro" + checked={creator.plan === "pro"} + onChange={e => this.setState({ + patreonCreators: [ + { ...creator, plan: "pro" }, + ...creators.filter(c => c.id != creator.id) + ] + })} + /> Pro + </label> + <label className="radio-inline"> + <input type="radio" + name={"type-" + creator.id} + name={"type-" + creator.id} + value="premium" + checked={creator.plan === "premium"} + onChange={e => this.setState({ + patreonCreators: [ + { ...creator, plan: "premium" }, + ...creators.filter(c => c.id != creator.id) + ] + })} + /> Premium + {" "} + <a + href="#which-plan" + >(?)</a> + </label> + </div> + <div className="form-group"> + <label htmlFor="amount">Amount</label> + <div className="input-group"> + <span className="input-group-addon">$</span> <input type="text" - class="form-control" + className="form-control" aria-label="Amount" onChange={e => this.setState({ patreonCreators: [ - { ...creator, amount: e.target.value }, + { + ...creator, + amount: parseFloat(e.target.value), + displayAmount: e.target.value, + }, ...creators.filter(c => c.id != creator.id) ] })} - value={creator.amount} + value={creator.displayAmount} /> - <span class="input-group-addon">per month</span> + <span className="input-group-addon">per month</span> </div> </div> + {creator.plan === "premium" ? + <p> + <strong>Note</strong>: Large creators with a premium plan may + receive a special rate. + </p> + : null} </div> )} - <div class="form-group"> + <div className="form-group"> <button - class="btn btn-default" + className="btn btn-default" onClick={e => { e.preventDefault(); this.setState({ patreonCreators: [ ...creators, { - "id": Math.max(...creators.map(c => c.id)) + 1, - "username": "", - "amount": "5.00", + id: Math.max(...creators.map(c => c.id)) + 1, + username: "", + amount: 5, + plan: "pro", + founding: false, + upfront: false, } ] }); }} >Add another creator</button> {creators.length > 1 && <button - class="btn btn-default" + className="btn btn-default" style={{marginLeft: "1rem"}} onClick={e => { e.preventDefault(); @@ -411,56 +309,151 @@ class Calculator extends Component { >Remove a creator</button>} </div> <p> - You only pay one <strong>transaction fee</strong> for all of your - creators: + You only pay one <strong>transaction fee</strong> between all of your + founding creators, except for creators which use the "charge up + front" option. You get charged a separate transaction fee for each + non-founding creator you support, based on your pledge amount. </p> - <table class="table"> + <div class="form-group"> + <label className="checkbox-inline"> + <input type="checkbox" + name="paypal" + checked={paypal} + onChange={e => this.setState({ paypal: e.target.checked })} + /> Pay with PayPal + </label> + <label className="checkbox-inline"> + <input type="checkbox" + name="vat" + checked={vat} + onChange={e => this.setState({ vat: e.target.checked })} + /> Pay from EU (add VAT) + </label> + </div> + {vat ? + <div className="form-group"> + <label htmlFor="country">Country</label> + <select + className="form-control" + name="country" + value={country} + onChange={e => this.setState({ country: e.target.value })} + > + {Object.keys(vatRates).map(country => + <option value={country}>{country}</option> + )} + </select> + <p> + Unlike other fees, adding VAT increases the amount you actually + pay, rather than subtracting more fees from your base pledge. + </p> + </div> + : null} + <table className="table"> <thead> <tr> - <th style={{ width: "12rem" }}>You pay</th> + <th style={{ width: "16rem" }}>You pay</th> <th></th> <th style={{ textAlign: "right" }} - >${total.toFixed(2)}</th> + >${(vat ? total * vatRates[country] + total : total).toFixed(2)}</th> <th></th> </tr> </thead> <tbody> - <tr> - <td>Transaction fee</td> - <td>2.9% + 30¢</td> - <td + {vat ? + <tr key={-3}> + <td>VAT</td> + <td>{(vatRates[country] * 100).toFixed(2)}%</td> + <td + style={{ textAlign: "right" }} + >(${(total * vatRates[country]).toFixed(2)})</td> + <td></td> + </tr> + : null} + {batch_tx_fee !== 0 ? + <tr key={-1}> + <td>Transaction fee (batch)</td> + <td>{this.transactionFee(null, paypal).text}<a href="#fn:2"><sup>2</sup></a></td> + <td + style={{ textAlign: "right" }} + >(${batch_tx_fee.toFixed(2)})</td> + <td></td> + </tr> + : null} + {creators.filter(c => !c.founding || c.upfront).map(c => { + return <tr key={c.id}> + <td>Transaction fee ({c.username})</td> + <td>{this.transactionFee(c, paypal).text}<a href="#fn:2"><sup>2</sup></a></td> + <td + style={{ textAlign: "right" }} + >(${this.transactionFee(c, paypal).fee.toFixed(2)})</td> + <td></td> + </tr>; + })} + <tr key={-2}> + <th>Payment processing fees</th> + <th style={{textAlign: "right"}}>=</th> + <th style={{ textAlign: "right" }} - >(${tx_fee.toFixed(2)})</td> - <td></td> + >${tx_fees.toFixed(2)}</th> + <th></th> </tr> + </tbody> + </table> + <p> + Patreon also charges its own fees, depending on the creator's plan + and founder status. + </p> + <table className="table"> + <thead> <tr> + <th style={{ width: "16rem" }}>You pay</th> + <th></th> + <th + style={{ textAlign: "right" }} + >${total.toFixed(2)}</th> <th></th> + </tr> + </thead> + <tbody> + {creators.map(c => { + return <tr key={c.id}> + <td>Patreon fee ({c.username})</td> + <td>{this.patreonFee(c).text}</td> + <td + style={{ textAlign: "right" }} + >(${this.patreonFee(c).fee.toFixed(2)})</td> + <td></td> + </tr>; + })} + <tr key={-2}> + <th>Patreon fees</th> <th style={{textAlign: "right"}}>=</th> <th style={{ textAlign: "right" }} - >${(total - tx_fee).toFixed(2)}</th> + >${patreon_fees.toFixed(2)}</th> <th></th> </tr> </tbody> </table> <p> - Your total minus the transaction fee is distributed to your creators - like so: + Your total minus the transaction fees & Patreon fees is + distributed to your creators like so: </p> - <table class="table"> + <table className="table"> <tbody> {creators.map(c => { - const amt = parseFloat(c.amount); - const share = (amt / total) * (total - tx_fee); - const patreon_fee = share * 0.05; - const after_patreon = share - patreon_fee; + const tx_fee = this.transactionFee(c, paypal); + if (c.founding && !c.upfront) { + tx_fee.fee = (c.amount / batch_total) * batch_tx_fee; + } + const patreon_fee = this.patreonFee(c); const clamp = (value, min, max) => Math.min(Math.max(min, value), max); - const withdrawl_fee = clamp(after_patreon * 0.01, 0.25, 20); - const creator_total = after_patreon - withdrawl_fee; + const creator_total = c.amount - tx_fee.fee - patreon_fee.fee; return [ - <tr class="active"> + <tr className="active" key={c.id}> <th>{c.username}</th> <td></td> <td></td> @@ -471,35 +464,29 @@ class Calculator extends Component { <td></td> <td style={{textAlign: "right"}} - >${amt.toFixed(2)}</td> + >${c.amount.toFixed(2)}</td> <td></td> </tr>, <tr> - <td>Transaction fee</td> - <td>(see above)</td> + <td>Transaction fees</td> + <td> + {c.founding && !c.upfront ? '(see above)' : tx_fees.text} + </td> <td style={{textAlign: "right"}} - >(${(amt - share).toFixed(2)})</td> + >(${tx_fee.fee.toFixed(2)})</td> <td></td> </tr>, <tr> - <td>Patreon fee</td> - <td>5%</td> + <td>Patreon fees</td> + <td>{patreon_fee.text}</td> <td style={{ textAlign: "right" }} - >(${patreon_fee.toFixed(2)})</td> + >(${patreon_fee.fee.toFixed(2)})</td> <td></td> </tr>, <tr> - <td>Withdrawal fee*</td> - <td>1% (25¢ min, $20 max)</td> - <td - style={{ textAlign: "right" }} - >(${withdrawl_fee.toFixed(2)})</td> - <td></td> - </tr>, - <tr> - <th>Creator earns (pre-tax)</th> + <th>Creator earns</th> <th></th> <th style={{ textAlign: "right" }} @@ -511,68 +498,31 @@ class Calculator extends Component { <th></th> <th style={{ textAlign: "right" }} - >{(creator_total / amt * 100).toFixed(0)}%</th> + >{(creator_total / c.amount * 100).toFixed(0)}%</th> <td>of your donation</td> </tr> ]; })} </tbody> </table> - <small> - * Withdrawal fee assumes payout via PayPal. Numbers for payout via - Stripe are not available, and numbers for Payoneer are different. <a - href="https://patreon.zendesk.com/hc/en-us/articles/203913489-What-are-my-options-to-receive-payout-">Details here</a>. - Withdrawal fees are also applied on the total sum of the creator's - earnings, and capped at $20 across all earnings. - </small> + <p> + After all is said and done, of the ${total.toFixed(2)} you spend on + Patreon, ${total_after_fees.toFixed(2)}, or + <strong> {(total_after_fees / total * 100).toFixed(0)}%</strong> makes + it to your creators. + </p> </div> ); } render() { - const { amount, provider } = this.state; return ( - <form class="calculator panel panel-default"> - <div class="panel-heading"> - Fee Calculator (based on 2018-01-16 fees) + <form className="calculator panel panel-default"> + <div className="panel-heading"> + Fee Calculator (based on 2019-05-07 fees) </div> - <div class="panel-body"> - <div> - {/* I know this is supposed to be a legend inside the fieldset */} - <label>Platform</label> - </div> - <fieldset class="form-group"> - <label class="radio-inline"> - <input - type="radio" - name="platform" - checked={provider === "fosspay"} - onChange={e => this.setState({ provider: "fosspay" })} - /> - fosspay - </label> - <label class="radio-inline"> - <input - type="radio" - name="platform" - checked={provider === "liberapay"} - onChange={e => this.setState({ provider: "liberapay" })} - /> - Liberapay - </label> - <label class="radio-inline"> - <input - type="radio" - name="platform" - checked={provider === "patreon"} - onChange={e => this.setState({ provider: "patreon" })} - /> - Patreon - </label> - </fieldset> - {provider === "fosspay" && this.renderFosspay()} - {provider === "liberapay" && this.renderLiberapay()} - {provider === "patreon" && this.renderPatreon()} + <div className="panel-body"> + {this.renderPatreon()} </div> </form> ); |