PageSourceSearch

https://newleftreview.es/assets/controllers/stripe_controller-4f7a…e82c1ce2987d3f4abe6a6093bd6a96f2543f3427.js

js newleftreview.es collected 2026-10-02 09:58:58 UTC 4,669 bytes, 177 lines download raw bytes

1/* globals Stripe */
2
3import { Controller } from '@hotwired/stimulus'
4
5export default class StripeController extends Controller {
6  static values = {
7    key: String,
8    completePath: String,
9    clientSecret: String,
10    email: String
11  }
12
13  static targets = ['stripeForm', 'paymentElement', 'linkAuthenticationElement', 'submitButton', 'messagesElement']
14
15  connect() {
16    this.stripefy()
17  }
18
19  stripefy() {
20    const { stripe, clientSecretValue: secret, paymentElementTarget: paymentTag} = this
21    this.elements = stripe.elements({ clientSecret: secret, appearance, fonts })
22
23    const paymentElement = this.elements.create('payment', {
24      fields: {
25        billingDetails: {
26          email: "never",
27        },
28      },
29    })
30    paymentElement.mount(paymentTag)
31
32    this.addPrefilledLinkElement()
33  }
34
35  addPrefilledLinkElement() {
36    const { linkAuthenticationElementTarget: linkAuthTag, emailValue: email} = this
37
38    if (!email) return false
39
40    const linkAuthenticationElement = this.elements.create('linkAuthentication', {defaultValues: {email: email}})
41    linkAuthenticationElement.mount(linkAuthTag)
42  }
43
44  get stripe() {
45    this._stripe ||= Stripe(this.keyValue)
46
47    return this._stripe
48  }
49
50  async submit(e) {
51    const { elements, stripe, completePathValue } = this
52
53    e.preventDefault()
54    this.catchDuplicateSubmission()
55
56    try {
57      const result = await stripe.confirmPayment({
58        elements,
59        confirmParams: {
60          return_url: completePathValue,
61          payment_method_data: {
62            billing_details: {
63              email: this.emailValue
64            },
65          },
66        }   
67      })
68
69      if(result.error) { throw new Error(result.error.message) }
70
71    } catch (error) {
72      this.addMessage(error)
73
74      this.reEnableSubmittedForm()
75      return
76    }
77  }
78
79  addMessage(message) {
80    const { messagesElementTarget: element } = this
81
82    element.style.display = 'block'
83    element.innerHTML = message
84  }
85
86  catchDuplicateSubmission() {
87    const { formSubmitted } = this
88
89    if(formSubmitted) { return }
90    this.formSubmitted = true
91    this.submitButtonTarget.disabled = true
92  }
93
94  reEnableSubmittedForm() {
95    this.formSubmitted = false
96    this.submitButtonTarget.disabled = false
97  }
98}
99
100const appearance = {
101    theme: 'stripe',
102
103    variables: {
104      fontFamily: 'ff-scala-sans-pro, Ideal Sans, system-ui, sans-serif',
105      borderRadius: '0',
106      tabIconColor: 'white',
107      tabIconHoverColor: 'white',
108      tabIconSelectedColor: 'white',
109      tabLogoColor: 'dark',
110      tabLogoSelectedColor: 'dark'
111    },
112    rules: {
113      '.Label': {
114        color: 'white'
115      },
116      '.Input': {
117        color: 'black',
118        backgroundColor: 'white',
119        marginBottom: '10px'
120      },
121      '.Error': {
122        color: 'white',
123        backgroundColor: 'red',
124        border: '2px solid white',
125        paddingLeft: '0.2em',
126        paddingRight: '0.2em',
127        paddingTop: '0.2em',
128        paddingBottom: '0.2em'
129      },
130      '.TabLabel': {
131        color: 'white',
132      },
133      '.Tab': {
134        color: getComputedStyle(document.body).getPropertyValue('--button-primary-color'),
135        backgroundColor: getComputedStyle(document.body).getPropertyValue('--button-primary-background-color'),
136        border: 'none',
137        boxShadow: '2px 2px white'
138      },
139      '.Tab--selected': {
140        border: 'none',
141        boxShadow: '2px 2px white',
142        backgroundColor: getComputedStyle(document.body).getPropertyValue('--button-primary-hover-background-color')
143      },
144      '.Tab:hover': {
145        border: 'none',
146        color: 'white',
147        backgroundColor: getComputedStyle(document.body).getPropertyValue('--button-primary-hover-background-color')
148      },
149      '.Tab:active': {
150        border: 'none',
151        boxShadow: '2px 2px white',
152        backgroundColor: getComputedStyle(document.body).getPropertyValue('--button-primary-hover-background-color')
153      },
154      '.TabIcon': {
155        color: getComputedStyle(document.body).getPropertyValue('--button-primary-color'),
156      },
157      '.TabIcon:hover': {
158        color: getComputedStyle(document.body).getPropertyValue('--button-primary-color'),
159      },
160      '.Link': {
161        color: 'white',
162        textDecoration: 'underline',
163      },
164      '.TermsText': {
165        color: 'white'
166      },
167      '.CheckboxLabel': {
168        color: 'white'
169      }
170    }
171  }
172
173const fonts = [{
174    family: 'ff-scala-sans-pro',
175    src: 'url(https://use.typekit.net/af/0f7856/00000000000000003b9b1f5e/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3)',
176    weight: '300',
177  }];

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.