Add a thanks banner to the donation page's flow

This commit is contained in:
Keavon Chambers
2026-08-29 02:36:24 -07:00
parent c64a9e5cee
commit 1c055bfaab
4 changed files with 32 additions and 38 deletions

View File

@@ -8,6 +8,10 @@ js = ["/js/page/donate.js"]
<section>
<div id="donation-thanks"><strong>Thank you for your donation!</strong> Your receipt is on its way by email, and your support goes straight into building Graphite.</div>
<div id="membership-welcome"><strong>Welcome, and thank you for becoming a member!</strong> Your receipt is on its way by email. We're fulfilling membership rewards by hand for now, so please forward that receipt to <a href="mailto:contact@graphite.art">contact<wbr />@graphite<wbr />.art</a> with your Discord username, the name you'd like in the credits, and/or any other details pertinent to your membership level.</div>
<div class="diptych donate-hero">
<div class="block">
@@ -15,7 +19,7 @@ js = ["/js/page/donate.js"]
**Own your tools. Own your art.** Graphite is 100% built and funded by our community. Invest in a sustainable, independent future for high-quality creative software that cannot ever be taken away.
<div class="statistics" data-statistics>
<div class="statistics">
<div class="statistic">
<span class="value" data-statistics-recurring></span>
<span class="label">In memberships</span>

View File

@@ -1,3 +1,22 @@
// Shown only when Stripe sends a member or one-time donor back to this banner's fragment
#donation-thanks,
#membership-welcome {
display: none;
box-sizing: border-box;
width: 100%;
padding: calc(20 * var(--variable-px)) calc(30 * var(--variable-px));
margin-bottom: calc(40 * var(--variable-px));
background-color: var(--color-seaside);
text-align: center;
text-justify: auto;
// Exceeding the distance from the page top keeps the browser from scrolling the header away
scroll-margin-top: 100vh;
&:target {
display: block;
}
}
// ==================================
// HERO SPLIT BETWEEN COPY AND PICKER
// ==================================

View File

@@ -1,11 +1,4 @@
const statisticsRequest = fetch("https://graphite.art/donate/sponsorship-stats").then((response) => response.json());
window.addEventListener("DOMContentLoaded", () => {
setUpAmountPresets();
showStatistics();
});
function setUpAmountPresets() {
const amountField = /** @type {HTMLInputElement | null} */ (document.querySelector("[data-donation-amount]"));
const presetButtons = /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll("[data-amount]"));
const githubOneTime = /** @type {HTMLAnchorElement | null} */ (document.querySelector("[data-github-one-time]"));
@@ -16,7 +9,8 @@ function setUpAmountPresets() {
if (!githubOneTime) return;
const amount = Number(amountField.value);
// GitHub accepts only whole-dollar amounts
const amount = Math.round(Number(amountField.value));
const suffix = Number.isFinite(amount) && amount > 0 ? `&amount=${amount}` : "";
githubOneTime.href = `https://github.com/sponsors/GraphiteEditor/sponsorships?frequency=one-time${suffix}`;
};
@@ -30,31 +24,4 @@ function setUpAmountPresets() {
amountField.addEventListener("input", syncAmount);
syncAmount();
}
async function showStatistics() {
const element = /** @type {HTMLElement | null} */ (document.querySelector("[data-statistics]"));
const recurringElement = /** @type {HTMLElement | null} */ (document.querySelector("[data-statistics-recurring]"));
const membersElement = /** @type {HTMLElement | null} */ (document.querySelector("[data-statistics-members]"));
const oneTimeElement = /** @type {HTMLElement | null} */ (document.querySelector("[data-statistics-one-time]"));
const donorsElement = /** @type {HTMLElement | null} */ (document.querySelector("[data-statistics-donors]"));
if (!element || !recurringElement || !membersElement || !oneTimeElement || !donorsElement) return;
try {
const json = await statisticsRequest;
if (!json || !json.recurring || !json.one_time_prior_12_month_sum) throw new Error();
const number = (/** @type {number} */ value) => Math.round(value).toLocaleString("en-US", { useGrouping: "min2" });
const dollars = (/** @type {number} */ value) => `$${number(value)}`;
recurringElement.innerText = dollars(parseInt(json.recurring.cents) / 100);
membersElement.innerText = number(json.recurring.count);
oneTimeElement.innerText = dollars(parseInt(json.one_time_prior_12_month_sum.cents) / 100);
donorsElement.innerText = number(json.one_time_prior_12_month_sum.count);
// Force repaint to work around Safari bug <https://bugs.webkit.org/show_bug.cgi?id=286403> (remove this and its data attribute when the bug is fixed and widely deployed)
element.style.transform = "scale(1)";
} catch {
element.remove();
}
}
});