summaryrefslogtreecommitdiff
path: root/moneyjsx/src/upgrade.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'moneyjsx/src/upgrade.tsx')
-rw-r--r--moneyjsx/src/upgrade.tsx206
1 files changed, 206 insertions, 0 deletions
diff --git a/moneyjsx/src/upgrade.tsx b/moneyjsx/src/upgrade.tsx
new file mode 100644
index 0000000..ab29e34
--- /dev/null
+++ b/moneyjsx/src/upgrade.tsx
@@ -0,0 +1,206 @@
+import * as JSX from './jsx';
+import * as user from './user';
+import * as api from './api';
+import $ from 'jquery';
+
+import { Page, GroupBox, Spinner } from './components';
+
+let stripe = null;
+let card = null;
+let selected_product = 2;
+
+async function loadStripe() {
+ return new Promise( function (resolve, reject ) {
+ const s = document.createElement( 'script' );
+ s.src = 'https://js.stripe.com/v3/';
+ s.onload = resolve;
+ s.onerror = reject;
+ document.head.appendChild( s );
+ } );
+}
+
+function showError( text: string ) {
+ $( "#payment-error" ).show();
+ $( "#payment-error" ).text( text );
+}
+
+async function onFormSubmit( e: Event ) {
+ e.preventDefault();
+ const { paymentMethod, error } = await stripe.createPaymentMethod( {
+ type: 'card',
+ card
+ } );
+
+ if( error )
+ return showError( error.message );
+
+ const res = await api.post( 'create-payment-intent', {
+ token: localStorage.getItem( 'session' ),
+ paymentMethodId: paymentMethod.id,
+ subLength: selected_product
+ } );
+
+ if( res.status == 'ok' ) {
+ const intent = res.paymentIntent;
+ if( intent.status == 'succeeded' )
+ return JSX.navigateParams( '/payment-success', {} );
+ else
+ return showError( "Payment failed. Contact support if the issue persists." );
+ }
+ else if( res.msg )
+ return showError( "Error: " + res.msg );
+ else
+ return showError( "Payment failed. Contact support if the issue persists." );
+}
+
+function waitForStripe() {
+ const iframes = $( 'iframe' );
+ if( !iframes.length )
+ return setTimeout( waitForStripe, 50 );
+
+ for( let iframe of iframes ) {
+ if( iframe.attributes.getNamedItem( 'name' ).value == 'hcaptcha-invisible' ) {
+ $( '#upgrade-loading' ).remove();
+ $( '#upgrade-inner' ).show();
+
+ return;
+ }
+ }
+
+ setTimeout( waitForStripe, 50 );
+}
+
+async function initStripe() {
+ stripe = window['Stripe']( 'pk_live_51Q9JG602rmv2yeiGYNNfwFkqp5ntpXIDIMIoiwDoEOrB5IsC75WDy3XOqekvuwY6PecviSSo5ERt0umrdBdUtqhd00FyYZe5p3' );
+ const font = user.settings.site_prefs.font;
+
+ const params = {
+ mode: 'billing',
+ style: {
+ base: {
+ color: '#fff',
+ fontFamily: font,
+ fontSize: '15px',
+ '::placeholder': {
+ color: '#ccc',
+ },
+ },
+ },
+ }
+
+ const el = getComputedStyle( document.body );
+ const back = el.getPropertyValue( '--back' );
+ const front = el.getPropertyValue( '--front' );
+ const appearance = {
+ theme: 'stripe',
+ disableAnimations: true,
+
+ variables: {
+ colorPrimary: front,
+ colorBackground: back,
+ colorText: '#fff',
+ fontFamily: font,
+ fontSizeBase: '15px',
+ fontSizeSm: '13px',
+ spacingUnit: '2px',
+ borderRadius: '0px',
+ },
+ rules: {
+ ".Input": {
+ border: 'none'
+ }
+ }
+ }
+
+ const elements = stripe.elements( { appearance } );
+ const name = elements.create( 'address', { mode: 'billing', appearance } );
+ name.mount( '#name-element' );
+
+ card = elements.create( 'card', params );
+ card.mount( '#card-element' );
+}
+
+function onProductChange( e: Event ) {
+ selected_product = parseInt( (e.target as HTMLInputElement).value );
+}
+
+function SelectionRadio( params: any ) {
+ return <div style="display: flex">
+ { params.checked &&
+ <input type="radio"
+ name="product"
+ value={ params.value }
+ onChange={ onProductChange }
+ checked="checked"
+ />
+ }
+ { !params.checked &&
+ <input type="radio"
+ name="product"
+ value={ params.value }
+ onChange={ onProductChange }
+ />
+ }
+ <label class="radio-label" style="margin-left: 5px">
+ { params.text } <span style="color: var(--front)">-- ${ params.price }</span>
+ </label>
+ </div>
+}
+
+function UpgradeLoaded() {
+ return <GroupBox
+ title="Account upgrade"
+ style="width: 90%; max-width: 550px; display: none"
+ innerStyle="width: calc( 100% - 10px )"
+ id="upgrade-inner"
+ >
+ <div style="border-bottom: 1px solid var(--front);">
+ <h2 style="padding: 8px 0px; margin: 0px; font-size: 28px">Summary</h2>
+ <div style="width: 60%">
+ <h3 style="margin: 5px 0;">
+ Product:
+ </h3>
+ <h4 style="margin: 5px 0">
+ <span id="product-name">Axonbox premium account upgrade</span><br />
+ <SelectionRadio text="1 week" price="2.70" value="1"/>
+ <SelectionRadio text="1 month" price="10" value="2" checked="checked"/>
+ <SelectionRadio text="1 year" price="100" value="3"/>
+ </h4>
+ </div>
+ </div>
+ <div>
+ <h3 style="margin: 5px 0">
+ Payment information
+ </h3>
+ </div>
+ <form id="upgrade-form" method="POST" action="" onsubmit={ onFormSubmit }>
+ <div>
+ <label for="name-element">Contact information</label>
+ <div id="name-element"></div>
+ <label for="card-element">Credit or debit card</label>
+ <div id="card-element" style="padding: 10px 0"></div>
+ <div id="card-errors" role="alert"></div>
+ </div>
+ <div>
+ <span style="display:none" id='payment-error'></span>
+ </div>
+ <button type="submit">Submit</button>
+ </form>
+ </GroupBox>
+}
+
+export default function Upgrade() {
+ setTimeout( () => {
+ loadStripe().then( () => {
+ $( <UpgradeLoaded /> ).insertAfter( "#upgrade-loading" );
+ initStripe();
+ waitForStripe();
+ } );
+ } );
+
+ return <Page>
+ <GroupBox title="Account upgrade" id="upgrade-loading">
+ <span>Loading... &nbsp;<Spinner style="display: inline" /></span>
+ </GroupBox>
+ </Page>
+}