summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorJoe Carstairs <65492573+joeacarstairs@users.noreply.github.com>2024-01-25 17:02:50 +0000
committerGitHub <noreply@github.com>2024-01-25 17:02:50 +0000
commit64c5ee53a0d158b38caff3285dac008826d7ae88 (patch)
tree7542f8c5b82b3327d82cc5defe2e84f86d6f11e7 /src/components
parent7140956da0820d4b818119eff7dfc72345f3328e (diff)
Update from staging (#70)
* 33 / Pay annual subscription by PayPal (#68) * Refactors paypal-buttons -> paypal-product-buttons WebComponent * Pulls out address to data file * Defines annual subscription prices data hash * Styles paypal-product-buttons * Styles <address> * Details have cursor:pointer on the summary * Moves Jyne section to separate page * Rewrites payment options using details components * Reworks translation typing * Defines MembershipType enum * Adds translations for MembershipType enum * Can pay annual subs by PayPal * Styles tables better * Replaces a few straggler --margins with --spacing (#67) --------- Co-authored-by: Joe Carstairs <118172583+jcarstairs-scottlogic@users.noreply.github.com>
Diffstat (limited to 'src/components')
-rw-r--r--src/components/LallansIssue.astro4
-rw-r--r--src/components/Navbar/NavLinks.astro3
-rw-r--r--src/components/PayPalButtons.astro150
-rw-r--r--src/components/PaypalProductButtons.astro26
-rw-r--r--src/components/Scotsoun.astro4
5 files changed, 32 insertions, 155 deletions
diff --git a/src/components/LallansIssue.astro b/src/components/LallansIssue.astro
index c8bc6eb..317ff2d 100644
--- a/src/components/LallansIssue.astro
+++ b/src/components/LallansIssue.astro
@@ -7,7 +7,7 @@ import type LallansIssue from '$types/LallansIssue';
import { Image } from 'astro:assets';
import LallansIssueContributions from './LallansIssueContributions.astro';
import LallansIssueContributors from './LallansIssueContributors.astro';
-import PayPalButtons from './PayPalButtons.astro';
+import PaypalProductButtons from './PaypalProductButtons.astro';
interface Props {
issue: LallansIssue;
@@ -27,7 +27,7 @@ const t = translate(locale);
<div class="product__action-block">
<Image alt="" src={issue.img.width274} />
- <PayPalButtons
+ <PaypalProductButtons
successPageUrl={relativePath(Astro.url.pathname, `payment-success-confirmation`)}
productDescription={`Lallans ${issue.issueNumber} | ${issue.issueName}`}
shortDescription={`Lallans ${issue.issueNumber}`}
diff --git a/src/components/Navbar/NavLinks.astro b/src/components/Navbar/NavLinks.astro
index 798c24e..36c7f6f 100644
--- a/src/components/Navbar/NavLinks.astro
+++ b/src/components/Navbar/NavLinks.astro
@@ -4,6 +4,7 @@ import translate from '$i18n/translate';
import tNews from '$i18n/translations/pages/news';
import tFurthsettins from '$i18n/translations/pages/furthsettins';
import tHame from '$i18n/translations/pages/home';
+import tJyne from '$i18n/translations/pages/jyne';
const locale = getLocaleFromPathOrDefault(Astro.url.pathname);
const t = translate(locale);
@@ -20,7 +21,7 @@ const t = translate(locale);
<a class="btn" href={`/${locale}/furthsettins`}>{t(tFurthsettins, { key: 'title' })}</a>
</li>
<li>
- <a class="btn" href={`/${locale}/#jyne`}>{t(tHame, { key: 'jyne' })}</a>
+ <a class="btn" href={`/${locale}/jyne`}>{t(tJyne, { key: 'title' })}</a>
</li>
<li>
<a class="btn" href={`/${locale}/#contact`}>{t(tHame, { key: 'contact' })}</a>
diff --git a/src/components/PayPalButtons.astro b/src/components/PayPalButtons.astro
deleted file mode 100644
index cdea5cb..0000000
--- a/src/components/PayPalButtons.astro
+++ /dev/null
@@ -1,150 +0,0 @@
----
-import env from '$lib/env';
-import type Price from '$types/Price';
-
-interface Props {
- successPageUrl: string;
- productDescription: string;
- shortDescription: string;
- totalPrice: Price;
-}
-
-const { successPageUrl, productDescription, shortDescription, totalPrice } = Astro.props;
-
-const PAYPAL_CLIENT_ID =
- env.ENVIRONMENT === 'prod' ? env.PAYPAL_LIVE_CLIENT_ID : env.PAYPAL_SANDBOX_CLIENT_ID;
----
-
-<paypal-buttons
- data-paypal-client-id={PAYPAL_CLIENT_ID}
- data-success-page-url={successPageUrl}
- data-product-description={productDescription}
- data-short-description={shortDescription}
- data-total-price={totalPrice}
->
- <div id="paypal-button-container"></div>
-</paypal-buttons>
-
-<script>
- import { PayPalNamespace, loadScript } from '@paypal/paypal-js';
-
- const backendUrl = '/api';
-
- class PayPalButtons extends HTMLElement {
- constructor() {
- super();
-
- const paypalClientId = this.getStringDataAttribute('paypalClientId');
-
- const paypalOptions = {
- clientId: paypalClientId,
- locale: 'en_GB',
- commit: false,
- currency: 'GBP',
- intent: 'capture',
- };
-
- loadScript(paypalOptions)
- .catch((err) => {
- throw new Error('Failed to load the PayPal JS SDK script. ', err);
- })
- .then((paypal) => {
- const constructButtons = paypal?.Buttons;
- if (paypal && constructButtons) {
- const successPageUrl = this.dataset['successPageUrl'] ?? '.';
- this.makePaypalButtons(constructButtons, successPageUrl).render(
- '#paypal-button-container'
- );
- }
- });
- }
-
- makePaypalButtons(
- constructButtons: Required<PayPalNamespace>['Buttons'],
- successPageUrl: string
- ) {
- const productDescription = this.getStringDataAttribute('productDescription');
- const shortDescription = this.getStringDataAttribute('shortDescription');
- const totalPrice = this.getStringDataAttribute('totalPrice');
-
- return constructButtons({
- // This function is called to set up the transaction details without actually carrying it out
- async createOrder() {
- const body = JSON.stringify({
- productDescription,
- shortDescription,
- totalPrice,
- });
- const headers = {
- 'Content-Type': 'application/json',
- };
-
- let response;
- try {
- response = await fetch(`${backendUrl}/order`, { method: 'POST', body, headers });
- } catch (err) {
- throw new Error(`Failed to create order. ${err}`);
- }
-
- if (!response.ok) {
- throw new Error(`
- Failed to create order. Backend response was
- ${response.status} ${response.statusText}. ${await response.text()}
- `);
- }
-
- const { orderId, approvalLink } = await response.json();
- console.info(`
- Successfully created order with ID
- ${orderId}. Approval link: ${approvalLink}
- `);
- return orderId;
- },
-
- // This function is called after payment is confirmed
- async onApprove(data) {
- const body = JSON.stringify({
- id: data.orderID,
- isApproved: true,
- });
- const headers = {
- 'Content-Type': 'application/json',
- };
-
- let response;
- try {
- response = await fetch(`${backendUrl}/order`, { method: 'PATCH', body, headers });
- } catch (err) {
- throw new Error(`Failed to capture order. ${err}`);
- }
-
- if (!response.ok) {
- throw new Error(`
- Failed to capture order. Backend response was ${response.status}
- ${response.statusText}. ${await response.text()}
- `);
- }
-
- const { orderId, requestStatus } = await response.json();
- console.info(`
- Successfully captured order with ID ${orderId},
- request status is ${requestStatus}.
- `);
-
- console.info('Redirecting to confirmation page...');
- window.location.href = successPageUrl;
- },
- });
- }
-
- getStringDataAttribute(key: string): string {
- const value = this.dataset[key];
- if (!value || typeof value !== 'string') {
- throw new Error(`data-${key} attribute not provided to PayPalButtons component.`);
- }
- return value;
- }
- }
-
- customElements.define('paypal-buttons', PayPalButtons);
-</script>
diff --git a/src/components/PaypalProductButtons.astro b/src/components/PaypalProductButtons.astro
new file mode 100644
index 0000000..0ebbd3f
--- /dev/null
+++ b/src/components/PaypalProductButtons.astro
@@ -0,0 +1,26 @@
+---
+import env from '$lib/env';
+import type Price from '$types/Price';
+
+interface Props {
+ successPageUrl: string;
+ productDescription: string;
+ shortDescription: string;
+ totalPrice: Price;
+}
+
+const { successPageUrl, productDescription, shortDescription, totalPrice } = Astro.props;
+
+const PAYPAL_CLIENT_ID =
+ env.ENVIRONMENT === 'prod' ? env.PAYPAL_LIVE_CLIENT_ID : env.PAYPAL_SANDBOX_CLIENT_ID;
+---
+
+<paypal-product-buttons
+ paypal-client-id={PAYPAL_CLIENT_ID}
+ success-page-url={successPageUrl}
+ product-description={productDescription}
+ short-description={shortDescription}
+ total-price={totalPrice}
+>
+ Loading PayPal buttons…
+</paypal-product-buttons>
diff --git a/src/components/Scotsoun.astro b/src/components/Scotsoun.astro
index cca330d..7acae8b 100644
--- a/src/components/Scotsoun.astro
+++ b/src/components/Scotsoun.astro
@@ -4,7 +4,7 @@ import translate from '$i18n/translate';
import tSite from '$i18n/translations/site';
import tComponent from '$i18n/translations/components/scotsoun';
import type Scotsoun from '$types/Scotsoun';
-import PayPalButtons from './PayPalButtons.astro';
+import PaypalProductButtons from './PaypalProductButtons.astro';
import relativePath from '$lib/relativePath';
import { getLocaleFromPathOrThrow } from '$lib/getLocaleFromPath';
@@ -27,7 +27,7 @@ const t = translate(locale);
</header>
<div class="product__action-block">
<Image src={scotsoun.img.width192} alt="" />
- <PayPalButtons
+ <PaypalProductButtons
successPageUrl={relativePath(Astro.url.pathname, `payment-success-confirmation`)}
productDescription={`SSCD${scotsoun.scotsounId} | ${scotsoun.longName}`}
shortDescription={`SSCD${scotsoun.scotsounId}`}