diff options
author | Stefan Malzner <stefan@adlk.io> | 2017-10-13 12:29:40 +0200 |
---|---|---|
committer | Stefan Malzner <stefan@adlk.io> | 2017-10-13 12:29:40 +0200 |
commit | 58cda9cc7fb79ca9df6746de7f9662bc08dc156a (patch) | |
tree | 1211600c2a5d3b5f81c435c6896618111a611720 /src/components/ui/Subscription.js | |
download | ferdium-app-58cda9cc7fb79ca9df6746de7f9662bc08dc156a.tar.gz ferdium-app-58cda9cc7fb79ca9df6746de7f9662bc08dc156a.tar.zst ferdium-app-58cda9cc7fb79ca9df6746de7f9662bc08dc156a.zip |
initial commit
Diffstat (limited to 'src/components/ui/Subscription.js')
-rw-r--r-- | src/components/ui/Subscription.js | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/src/components/ui/Subscription.js b/src/components/ui/Subscription.js new file mode 100644 index 000000000..ada5cc3e0 --- /dev/null +++ b/src/components/ui/Subscription.js | |||
@@ -0,0 +1,265 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | ||
4 | import { defineMessages, intlShape } from 'react-intl'; | ||
5 | |||
6 | import Form from '../../lib/Form'; | ||
7 | import Radio from '../ui/Radio'; | ||
8 | import Button from '../ui/Button'; | ||
9 | import Loader from '../ui/Loader'; | ||
10 | |||
11 | import { required } from '../../helpers/validation-helpers'; | ||
12 | |||
13 | const messages = defineMessages({ | ||
14 | submitButtonLabel: { | ||
15 | id: 'subscription.submit.label', | ||
16 | defaultMessage: '!!!Support the development of Franz', | ||
17 | }, | ||
18 | paymentSessionError: { | ||
19 | id: 'subscription.paymentSessionError', | ||
20 | defaultMessage: '!!!Could not initialize payment form', | ||
21 | }, | ||
22 | typeFree: { | ||
23 | id: 'subscription.type.free', | ||
24 | defaultMessage: '!!!free', | ||
25 | }, | ||
26 | typeMonthly: { | ||
27 | id: 'subscription.type.month', | ||
28 | defaultMessage: '!!!month', | ||
29 | }, | ||
30 | typeYearly: { | ||
31 | id: 'subscription.type.year', | ||
32 | defaultMessage: '!!!year', | ||
33 | }, | ||
34 | typeMining: { | ||
35 | id: 'subscription.type.mining', | ||
36 | defaultMessage: '!!!Support Franz with processing power', | ||
37 | }, | ||
38 | includedFeatures: { | ||
39 | id: 'subscription.includedFeatures', | ||
40 | defaultMessage: '!!!The Franz Premium Supporter Account includes', | ||
41 | }, | ||
42 | features: { | ||
43 | unlimitedServices: { | ||
44 | id: 'subscription.features.unlimitedServices', | ||
45 | defaultMessage: '!!!Add unlimited services', | ||
46 | }, | ||
47 | onpremise: { | ||
48 | id: 'subscription.features.onpremise', | ||
49 | defaultMessage: '!!!Add on-premise/hosted services like HipChat', | ||
50 | }, | ||
51 | customServices: { | ||
52 | id: 'subscription.features.customServices', | ||
53 | defaultMessage: '!!!Add your custom services', | ||
54 | }, | ||
55 | encryptedSync: { | ||
56 | id: 'subscription.features.encryptedSync', | ||
57 | defaultMessage: '!!!Encrypted session synchronization', | ||
58 | }, | ||
59 | vpn: { | ||
60 | id: 'subscription.features.vpn', | ||
61 | defaultMessage: '!!!Proxy & VPN support', | ||
62 | }, | ||
63 | ads: { | ||
64 | id: 'subscription.features.ads', | ||
65 | defaultMessage: '!!!No ads, ever!', | ||
66 | }, | ||
67 | comingSoon: { | ||
68 | id: 'subscription.features.comingSoon', | ||
69 | defaultMessage: '!!!coming soon', | ||
70 | }, | ||
71 | }, | ||
72 | miningHeadline: { | ||
73 | id: 'subscription.mining.headline', | ||
74 | defaultMessage: '!!!How does this work?', | ||
75 | }, | ||
76 | experimental: { | ||
77 | id: 'subscription.mining.experimental', | ||
78 | defaultMessage: '!!!experimental', | ||
79 | }, | ||
80 | miningDetail1: { | ||
81 | id: 'subscription.mining.line1', | ||
82 | defaultMessage: '!!!By enabling "Support with processing power", Franz will use about 20-50% of your CPU to mine cryptocurrency Monero which equals approximately $ 5/year.', | ||
83 | }, | ||
84 | miningDetail2: { | ||
85 | id: 'subscription.mining.line2', | ||
86 | defaultMessage: '!!!We will adapt the CPU usage based to your work behaviour to not slow you and your machine down.', | ||
87 | }, | ||
88 | miningDetail3: { | ||
89 | id: 'subscription.mining.line3', | ||
90 | defaultMessage: '!!!As long as the miner is active, you will have unlimited access to all the Franz Premium Supporter Features.', | ||
91 | }, | ||
92 | miningMoreInfo: { | ||
93 | id: 'subscription.mining.moreInformation', | ||
94 | defaultMessage: '!!!Get more information about this plan', | ||
95 | }, | ||
96 | }); | ||
97 | |||
98 | @observer | ||
99 | export default class SubscriptionForm extends Component { | ||
100 | static propTypes = { | ||
101 | plan: MobxPropTypes.objectOrObservableObject.isRequired, | ||
102 | isLoading: PropTypes.bool.isRequired, | ||
103 | handlePayment: PropTypes.func.isRequired, | ||
104 | retryPlanRequest: PropTypes.func.isRequired, | ||
105 | isCreatingHostedPage: PropTypes.bool.isRequired, | ||
106 | error: PropTypes.bool.isRequired, | ||
107 | showSkipOption: PropTypes.bool, | ||
108 | skipAction: PropTypes.func, | ||
109 | skipButtonLabel: PropTypes.string, | ||
110 | hideInfo: PropTypes.bool.isRequired, | ||
111 | openExternalUrl: PropTypes.func.isRequired, | ||
112 | }; | ||
113 | |||
114 | static defaultProps ={ | ||
115 | content: '', | ||
116 | showSkipOption: false, | ||
117 | skipAction: () => null, | ||
118 | skipButtonLabel: '', | ||
119 | } | ||
120 | |||
121 | static contextTypes = { | ||
122 | intl: intlShape, | ||
123 | }; | ||
124 | |||
125 | componentWillMount() { | ||
126 | this.form = this.prepareForm(); | ||
127 | } | ||
128 | |||
129 | prepareForm() { | ||
130 | const { intl } = this.context; | ||
131 | |||
132 | const form = { | ||
133 | fields: { | ||
134 | paymentTier: { | ||
135 | value: 'year', | ||
136 | validate: [required], | ||
137 | options: [{ | ||
138 | value: 'month', | ||
139 | label: `$ ${Object.hasOwnProperty.call(this.props.plan, 'month') | ||
140 | ? `${this.props.plan.month.price} / ${intl.formatMessage(messages.typeMonthly)}` | ||
141 | : 'monthly'}`, | ||
142 | }, { | ||
143 | value: 'year', | ||
144 | label: `$ ${Object.hasOwnProperty.call(this.props.plan, 'year') | ||
145 | ? `${this.props.plan.year.price} / ${intl.formatMessage(messages.typeYearly)}` | ||
146 | : 'yearly'}`, | ||
147 | }, { | ||
148 | value: 'mining', | ||
149 | label: intl.formatMessage(messages.typeMining), | ||
150 | }], | ||
151 | }, | ||
152 | }, | ||
153 | }; | ||
154 | |||
155 | if (this.props.showSkipOption) { | ||
156 | form.fields.paymentTier.options.unshift({ | ||
157 | value: 'skip', | ||
158 | label: `$ 0 / ${intl.formatMessage(messages.typeFree)}`, | ||
159 | }); | ||
160 | } | ||
161 | |||
162 | return new Form(form, this.context.intl); | ||
163 | } | ||
164 | |||
165 | render() { | ||
166 | const { | ||
167 | isLoading, | ||
168 | isCreatingHostedPage, | ||
169 | handlePayment, | ||
170 | retryPlanRequest, | ||
171 | error, | ||
172 | showSkipOption, | ||
173 | skipAction, | ||
174 | skipButtonLabel, | ||
175 | hideInfo, | ||
176 | openExternalUrl, | ||
177 | } = this.props; | ||
178 | const { intl } = this.context; | ||
179 | |||
180 | if (error) { | ||
181 | return ( | ||
182 | <Button | ||
183 | label="Reload" | ||
184 | onClick={retryPlanRequest} | ||
185 | isLoaded={!isLoading} | ||
186 | /> | ||
187 | ); | ||
188 | } | ||
189 | |||
190 | return ( | ||
191 | <Loader loaded={!isLoading}> | ||
192 | <Radio field={this.form.$('paymentTier')} showLabel={false} className="paymentTiers" /> | ||
193 | {!hideInfo && ( | ||
194 | <div className="subscription__premium-info"> | ||
195 | {this.form.$('paymentTier').value !== 'mining' && ( | ||
196 | <div> | ||
197 | <p> | ||
198 | <strong>{intl.formatMessage(messages.includedFeatures)}</strong> | ||
199 | </p> | ||
200 | <div className="subscription"> | ||
201 | <ul className="subscription__premium-features"> | ||
202 | <li>{intl.formatMessage(messages.features.onpremise)}</li> | ||
203 | <li> | ||
204 | {intl.formatMessage(messages.features.encryptedSync)} | ||
205 | <span className="badge">{intl.formatMessage(messages.features.comingSoon)}</span> | ||
206 | </li> | ||
207 | <li> | ||
208 | {intl.formatMessage(messages.features.customServices)} | ||
209 | <span className="badge">{intl.formatMessage(messages.features.comingSoon)}</span> | ||
210 | </li> | ||
211 | <li> | ||
212 | {intl.formatMessage(messages.features.vpn)} | ||
213 | <span className="badge">{intl.formatMessage(messages.features.comingSoon)}</span> | ||
214 | </li> | ||
215 | <li> | ||
216 | {intl.formatMessage(messages.features.ads)} | ||
217 | </li> | ||
218 | </ul> | ||
219 | </div> | ||
220 | </div> | ||
221 | )} | ||
222 | {this.form.$('paymentTier').value === 'mining' && ( | ||
223 | <div className="subscription mining-details"> | ||
224 | <p> | ||
225 | <strong>{intl.formatMessage(messages.miningHeadline)}</strong> | ||
226 | | ||
227 | <span className="badge">{intl.formatMessage(messages.experimental)}</span> | ||
228 | </p> | ||
229 | <p>{intl.formatMessage(messages.miningDetail1)}</p> | ||
230 | <p>{intl.formatMessage(messages.miningDetail2)}</p> | ||
231 | <p>{intl.formatMessage(messages.miningDetail3)}</p> | ||
232 | <p> | ||
233 | <button | ||
234 | onClick={() => openExternalUrl({ url: 'http://meetfranz.com/mining' })} | ||
235 | > | ||
236 | {intl.formatMessage(messages.miningMoreInfo)} | ||
237 | </button> | ||
238 | </p> | ||
239 | </div> | ||
240 | )} | ||
241 | </div> | ||
242 | )} | ||
243 | <div> | ||
244 | {error.code === 'no-payment-session' && ( | ||
245 | <p className="error-message center">{intl.formatMessage(messages.paymentSessionError)}</p> | ||
246 | )} | ||
247 | </div> | ||
248 | {showSkipOption && this.form.$('paymentTier').value === 'skip' ? ( | ||
249 | <Button | ||
250 | label={skipButtonLabel} | ||
251 | className="auth__button" | ||
252 | onClick={skipAction} | ||
253 | /> | ||
254 | ) : ( | ||
255 | <Button | ||
256 | label={intl.formatMessage(messages.submitButtonLabel)} | ||
257 | className="auth__button" | ||
258 | loaded={!isCreatingHostedPage} | ||
259 | onClick={() => handlePayment(this.form.$('paymentTier').value)} | ||
260 | /> | ||
261 | )} | ||
262 | </Loader> | ||
263 | ); | ||
264 | } | ||
265 | } | ||