Skip to content

Commit 0bf85e1

Browse files
authored
✨ Frontend: Payment methods (#4759)
1 parent 4f51fb4 commit 0bf85e1

File tree

6 files changed

+695
-15
lines changed

6 files changed

+695
-15
lines changed

services/static-webserver/client/source/class/osparc/data/Resources.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,50 @@ qx.Class.define("osparc.data.Resources", {
671671
}
672672
}
673673
},
674+
/*
675+
* PAYMENTS METHODS
676+
*/
677+
"payments-methods": {
678+
useCache: false,
679+
endpoints: {
680+
init: {
681+
method: "POST",
682+
url: statics.API + "/wallets/{walletId}/payments-methods:init"
683+
},
684+
cancel: {
685+
method: "POST",
686+
url: statics.API + "/wallets/{walletId}/payments-methods/{paymentMethodId}:cancel"
687+
},
688+
get: {
689+
method: "GET",
690+
url: statics.API + "/wallets/{walletId}/payments-methods"
691+
},
692+
delete: {
693+
method: "DELETE",
694+
url: statics.API + "/wallets/{walletId}/payments-methods/{paymentMethodId}"
695+
}
696+
}
697+
},
698+
/*
699+
* AUTO RECHARGE
700+
*/
701+
"auto-recharge": {
702+
useCache: false,
703+
endpoints: {
704+
get: {
705+
method: "GET",
706+
url: statics.API + "/wallets/{walletId}/auto-recharge"
707+
},
708+
start: {
709+
method: "POST",
710+
url: statics.API + "/wallets/{walletId}/auto-recharge"
711+
},
712+
stop: {
713+
method: "DELETE",
714+
url: statics.API + "/wallets/{walletId}/auto-recharge"
715+
}
716+
}
717+
},
674718
/*
675719
* CLUSTERS
676720
*/

services/static-webserver/client/source/class/osparc/desktop/credits/BuyCredits.js

Lines changed: 136 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ qx.Class.define("osparc.desktop.credits.BuyCredits", {
2121
construct: function() {
2222
this.base(arguments);
2323

24-
this._setLayout(new qx.ui.layout.HBox(80));
24+
const grid = new qx.ui.layout.Grid(80, 50);
25+
grid.setColumnMaxWidth(0, 400);
26+
grid.setColumnMaxWidth(1, 400);
27+
this._setLayout(grid);
2528

2629
this.__buildLayout();
2730

@@ -81,14 +84,32 @@ qx.Class.define("osparc.desktop.credits.BuyCredits", {
8184
_createChildControlImpl: function(id) {
8285
let control;
8386
switch (id) {
84-
case "left-side":
85-
control = new qx.ui.container.Composite(new qx.ui.layout.VBox(20));
86-
this._add(control);
87+
case "wallet-layout":
88+
control = new qx.ui.container.Composite(new qx.ui.layout.VBox(10));
89+
this._add(control, {
90+
row: 0,
91+
column: 0
92+
});
93+
break;
94+
case "explanation-layout":
95+
control = new qx.ui.container.Composite(new qx.ui.layout.VBox(10));
96+
this._add(control, {
97+
row: 0,
98+
column: 1
99+
});
87100
break;
88-
case "right-side":
89-
control = new qx.ui.container.Composite(new qx.ui.layout.VBox(20));
101+
case "one-time-payment-layout":
102+
control = new qx.ui.container.Composite(new qx.ui.layout.VBox(15));
90103
this._add(control, {
91-
flex: 1
104+
row: 1,
105+
column: 0
106+
});
107+
break;
108+
case "auto-recharge-layout":
109+
control = new qx.ui.container.Composite(new qx.ui.layout.VBox(15));
110+
this._add(control, {
111+
row: 1,
112+
column: 1
92113
});
93114
break;
94115
case "wallet-info": {
@@ -98,7 +119,7 @@ qx.Class.define("osparc.desktop.credits.BuyCredits", {
98119
font: "text-14"
99120
});
100121
control.add(label);
101-
this.getChildControl("left-side").add(control);
122+
this.getChildControl("wallet-layout").add(control);
102123
break;
103124
}
104125
case "wallet-selector":
@@ -109,9 +130,21 @@ qx.Class.define("osparc.desktop.credits.BuyCredits", {
109130
control = this.__getCreditsLeftView();
110131
this.getChildControl("wallet-info").add(control);
111132
break;
112-
case "one-time-payment-layout":
113-
control = new qx.ui.container.Composite(new qx.ui.layout.VBox(15));
114-
this.getChildControl("left-side").add(control);
133+
case "one-time-payment-title":
134+
control = new qx.ui.basic.Label().set({
135+
value: this.tr("One time payment:"),
136+
font: "text-16"
137+
});
138+
this.getChildControl("one-time-payment-layout").add(control);
139+
break;
140+
case "one-time-payment-description":
141+
control = new qx.ui.basic.Label().set({
142+
value: this.tr("A one-off, non-recurring payment."),
143+
font: "text-14",
144+
rich: true,
145+
wrap: true
146+
});
147+
this.getChildControl("one-time-payment-layout").add(control);
115148
break;
116149
case "credit-selector":
117150
control = this.__getCreditSelector();
@@ -127,7 +160,31 @@ qx.Class.define("osparc.desktop.credits.BuyCredits", {
127160
break;
128161
case "credits-explanation":
129162
control = this.__getCreditsExplanation();
130-
this.getChildControl("right-side").add(control);
163+
this.getChildControl("explanation-layout").add(control);
164+
break;
165+
case "auto-recharge-title":
166+
control = new qx.ui.basic.Label().set({
167+
value: this.tr("Auto recharge:"),
168+
font: "text-16"
169+
});
170+
this.getChildControl("auto-recharge-layout").add(control);
171+
break;
172+
case "auto-recharge-description":
173+
control = new qx.ui.basic.Label().set({
174+
value: this.tr("Keep your balance running smoothly by automatically setting your credits to be recharged when it runs low."),
175+
font: "text-14",
176+
rich: true,
177+
wrap: true
178+
});
179+
this.getChildControl("auto-recharge-layout").add(control);
180+
break;
181+
case "auto-recharge-options":
182+
control = this.__getAutoRechargeOptions();
183+
this.getChildControl("auto-recharge-layout").add(control);
184+
break;
185+
case "auto-recharge-button":
186+
control = this.__getAutoRechargeButton();
187+
this.getChildControl("auto-recharge-layout").add(control);
131188
break;
132189
}
133190
return control || this.base(arguments, id);
@@ -147,17 +204,27 @@ qx.Class.define("osparc.desktop.credits.BuyCredits", {
147204
__buildLayout: function() {
148205
this.getChildControl("wallet-selector");
149206
this.getChildControl("credits-left-view");
150-
this.__builyOneTimePayment();
207+
this.__buildOneTimePayment();
151208

152209
this.getChildControl("credits-explanation");
210+
this.__buildAutoRecharge();
153211
},
154212

155-
__builyOneTimePayment: function() {
213+
__buildOneTimePayment: function() {
214+
this.getChildControl("one-time-payment-title");
215+
this.getChildControl("one-time-payment-description");
156216
this.getChildControl("credit-selector");
157217
this.getChildControl("summary-view");
158218
this.getChildControl("buy-button");
159219
},
160220

221+
__buildAutoRecharge: function() {
222+
this.getChildControl("auto-recharge-title");
223+
this.getChildControl("auto-recharge-description");
224+
this.getChildControl("auto-recharge-options");
225+
this.getChildControl("auto-recharge-button");
226+
},
227+
161228
__applyTotalPrice: function(totalPrice) {
162229
let creditPrice = this.self().CREDIT_PRICES[0][1];
163230

@@ -209,7 +276,7 @@ qx.Class.define("osparc.desktop.credits.BuyCredits", {
209276
const vLayout = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
210277

211278
const label = new qx.ui.basic.Label().set({
212-
value: this.tr("Payment amount:"),
279+
value: this.tr("Payment amount ($):"),
213280
font: "text-14"
214281
});
215282
vLayout.add(label);
@@ -529,6 +596,60 @@ qx.Class.define("osparc.desktop.credits.BuyCredits", {
529596
layout.add(label2);
530597

531598
return layout;
599+
},
600+
601+
__getAutoRechargeOptions: function() {
602+
const layout = new qx.ui.container.Composite(new qx.ui.layout.VBox(10));
603+
604+
const lowerThresholdLabel = new qx.ui.basic.Label().set({
605+
value: this.tr("When balance goes below ($):"),
606+
font: "text-14"
607+
});
608+
layout.add(lowerThresholdLabel);
609+
610+
const lowerThresholdField = new qx.ui.form.TextField().set({
611+
maxWidth: 100,
612+
textAlign: "center",
613+
font: "text-14"
614+
});
615+
layout.add(lowerThresholdField);
616+
617+
const balanceBackLabel = new qx.ui.basic.Label().set({
618+
value: this.tr("Top up with ($):"),
619+
font: "text-14"
620+
});
621+
layout.add(balanceBackLabel);
622+
623+
const paymentAmountField = new qx.ui.form.TextField().set({
624+
maxWidth: 100,
625+
textAlign: "center",
626+
font: "text-14"
627+
});
628+
layout.add(paymentAmountField);
629+
630+
const label = new qx.ui.basic.Label().set({
631+
value: this.tr("Payment Method:"),
632+
font: "text-14"
633+
});
634+
layout.add(label);
635+
636+
const paymentMethods = new qx.ui.form.SelectBox().set({
637+
allowGrowX: false
638+
});
639+
layout.add(paymentMethods);
640+
641+
return layout;
642+
},
643+
644+
__getAutoRechargeButton: function() {
645+
const autoRechargeBtn = new osparc.ui.form.FetchButton().set({
646+
label: this.tr("Enable Auto Recharge"),
647+
font: "text-16",
648+
appearance: "strong-button",
649+
maxWidth: 200,
650+
center: true
651+
});
652+
return autoRechargeBtn;
532653
}
533654
}
534655
});

services/static-webserver/client/source/class/osparc/desktop/credits/UserCenter.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ qx.Class.define("osparc.desktop.credits.UserCenter", {
5454
tabViews.add(buyCreditsPage);
5555
}
5656

57+
if (this.__walletsEnabled) {
58+
const paymentMethodsPage = this.__paymentMethodsPage = this.__getPaymentMethodsPage();
59+
tabViews.add(paymentMethodsPage);
60+
}
61+
5762
if (this.__walletsEnabled) {
5863
const transactionsPage = this.__transactionsPage = this.__getTransactionsPage();
5964
tabViews.add(transactionsPage);
@@ -83,6 +88,7 @@ qx.Class.define("osparc.desktop.credits.UserCenter", {
8388
__profilePage: null,
8489
__walletsPage: null,
8590
__buyCreditsPage: null,
91+
__paymentMethodsPage: null,
8692
__transactionsPage: null,
8793
__usageOverviewPage: null,
8894
__buyCredits: null,
@@ -205,6 +211,19 @@ qx.Class.define("osparc.desktop.credits.UserCenter", {
205211
return page;
206212
},
207213

214+
__getPaymentMethodsPage: function() {
215+
const title = this.tr("Payment Methods");
216+
const iconSrc = "@FontAwesome5Solid/credit-card/22";
217+
const page = new osparc.desktop.preferences.pages.BasePage(title, iconSrc);
218+
page.showLabelOnTab();
219+
const paymentPethods = new osparc.desktop.paymentMethods.PaymentMethods();
220+
paymentPethods.set({
221+
margin: 10
222+
});
223+
page.add(paymentPethods);
224+
return page;
225+
},
226+
208227
__getTransactionsPage: function() {
209228
const title = this.tr("Transactions");
210229
const iconSrc = "@FontAwesome5Solid/exchange-alt/22";
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* ************************************************************************
2+
3+
osparc - the simcore frontend
4+
5+
https://osparc.io
6+
7+
Copyright:
8+
2023 IT'IS Foundation, https://itis.swiss
9+
10+
License:
11+
MIT: https://opensource.org/licenses/MIT
12+
13+
Authors:
14+
* Odei Maiz (odeimaiz)
15+
16+
************************************************************************ */
17+
18+
qx.Class.define("osparc.desktop.paymentMethods.PaymentMethodDetails", {
19+
extend: qx.ui.core.Widget,
20+
21+
construct: function(paymentMethodData) {
22+
this.base(arguments);
23+
24+
const grid = new qx.ui.layout.Grid(20, 10);
25+
grid.setColumnAlign(0, "right", "middle"); // resource limit value
26+
this._setLayout(grid);
27+
28+
this.__buildLayout(paymentMethodData);
29+
},
30+
31+
statics: {
32+
popUpInWindow: function(paymentMethodData) {
33+
const title = qx.locale.Manager.tr("Payment Method details");
34+
const paymentMethodDetails = new osparc.desktop.paymentMethods.PaymentMethodDetails(paymentMethodData);
35+
paymentMethodDetails.set({
36+
padding: 10
37+
});
38+
const viewWidth = 300;
39+
const viewHeight = 300;
40+
const win = osparc.ui.window.Window.popUpInWindow(paymentMethodDetails, title, viewWidth, viewHeight);
41+
win.center();
42+
win.open();
43+
return win;
44+
}
45+
},
46+
47+
members: {
48+
__buildLayout: function(paymentMethodData) {
49+
[
50+
[this.tr("Holder name"), paymentMethodData["cardHolderName"]],
51+
[this.tr("Type"), paymentMethodData["cardType"]],
52+
[this.tr("Number"), paymentMethodData["cardNumberMasked"]],
53+
[this.tr("Expiration date"), paymentMethodData["expirationMonth"] + "/" + paymentMethodData["expirationYear"]],
54+
[this.tr("Address"), paymentMethodData["streetAddress"]],
55+
[this.tr("ZIP code"), paymentMethodData["zipcode"]],
56+
[this.tr("Country"), paymentMethodData["country"]]
57+
].forEach((pair, idx) => {
58+
this._add(new qx.ui.basic.Label(pair[0]).set({
59+
font: "text-14"
60+
}), {
61+
row: idx,
62+
column: 0
63+
});
64+
this._add(new qx.ui.basic.Label(pair[1]).set({
65+
font: "text-14"
66+
}), {
67+
row: idx,
68+
column: 1
69+
});
70+
});
71+
}
72+
}
73+
});

0 commit comments

Comments
 (0)