Skip to content

Commit cc01576

Browse files
feat: add subscription plans (#22)
1 parent dd5e016 commit cc01576

14 files changed

Lines changed: 1660 additions & 387 deletions

File tree

Caddyfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ http://localhost:9090 {
1010

1111
handle @saas {
1212
uri strip_prefix /api
13-
reverse_proxy https://api.lnbits.com {
13+
reverse_proxy http://localhost:8888 {
1414
header_up Host api.lnbits.com
1515
}
1616
}
1717

1818
handle /* {
19-
reverse_proxy localhost:5005
20-
19+
reverse_proxy localhost:8080
20+
2121
}
2222
}

src/boot/saas.js

Lines changed: 161 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,144 +1,215 @@
1-
import axios from "axios";
2-
import { secondsToDhm } from "src/boot/utils";
1+
import axios from 'axios'
2+
import {secondsToDhm} from 'src/boot/utils'
33

44
var saas = {
5-
slideimg: "assets/images/hero/bitcoin-accounts.png",
6-
url: "https://api.lnbits.com",
5+
slideimg: 'assets/images/hero/bitcoin-accounts.png',
6+
url: 'https://api.lnbits.com',
77
// for local development togegther with Caddy
8-
// url: "/api",
8+
// url: '/api',
99
serverTime: null,
1010

11-
username: localStorage.getItem("username"),
11+
username: localStorage.getItem('username'),
1212

1313
signup: async function (username, password, password2) {
14-
const { data } = await axios({
15-
method: "POST",
16-
url: this.url + "/signup",
14+
const {data} = await axios({
15+
method: 'POST',
16+
url: this.url + '/signup',
1717
withCredentials: true,
1818
data: {
1919
username,
2020
password,
21-
password_repeat: password2,
22-
},
23-
});
21+
password_repeat: password2
22+
}
23+
})
2424

25-
localStorage.setItem("username", username);
25+
localStorage.setItem('username', username)
2626

27-
return data;
27+
return data
2828
},
2929
login: async function (username, password) {
30-
const formData = new FormData();
31-
formData.append("username", username);
32-
formData.append("password", password);
33-
const { data } = await axios({
34-
method: "POST",
35-
url: this.url + "/login",
30+
const formData = new FormData()
31+
formData.append('username', username)
32+
formData.append('password', password)
33+
const {data} = await axios({
34+
method: 'POST',
35+
url: this.url + '/login',
3636
data: formData,
3737
withCredentials: true,
3838
headers: {
39-
"Content-Type": "multipart/form-data",
40-
},
41-
});
42-
localStorage.setItem("username", username);
39+
'Content-Type': 'multipart/form-data'
40+
}
41+
})
42+
localStorage.setItem('username', username)
4343

44-
return data;
44+
return data
4545
},
4646

4747
createInstance: async function () {
4848
return axios({
49-
method: "POST",
50-
url: this.url + "/instance",
51-
withCredentials: true,
52-
});
49+
method: 'POST',
50+
url: this.url + '/instance',
51+
withCredentials: true
52+
})
5353
},
5454

5555
updateInstance: function (id, action) {
5656
return axios({
57-
method: "PUT",
58-
url: this.url + "/instance",
57+
method: 'PUT',
58+
url: this.url + '/instance',
5959
withCredentials: true,
6060
data: {
6161
action: action,
62-
instance_id: id,
63-
},
64-
});
62+
instance_id: id
63+
}
64+
})
65+
},
66+
67+
createOneTimePlan: function (instanceId, planName, quantity, isFiat) {
68+
return axios({
69+
method: 'PUT',
70+
url: this.url + '/instance/buy',
71+
withCredentials: true,
72+
data: {
73+
instance_id: instanceId,
74+
quantity: quantity,
75+
payment_plan_name: planName,
76+
is_fiat: isFiat
77+
}
78+
})
79+
},
80+
subscribeToPlan: function (instanceId, planName) {
81+
return axios({
82+
method: 'PUT',
83+
url: this.url + '/instance/subscribe',
84+
withCredentials: true,
85+
data: {
86+
instance_id: instanceId,
87+
payment_plan_name: planName
88+
}
89+
})
90+
},
91+
unsubscribe: function (instanceId, subscriptionRequestId) {
92+
return axios({
93+
method: 'PUT',
94+
url: this.url + '/instance/unsubscribe',
95+
withCredentials: true,
96+
data: {
97+
instance_id: instanceId,
98+
subscription_request_id: subscriptionRequestId
99+
}
100+
})
65101
},
66102
getInstances: async function () {
67103
const response = await axios({
68-
method: "GET",
69-
url: this.url + "/instance",
70-
withCredentials: true,
71-
});
72-
73-
return response;
104+
method: 'GET',
105+
url: this.url + '/instance',
106+
withCredentials: true
107+
})
108+
return response
74109
},
75110
getUserInstancesLogs: async function () {
76111
const response = await axios({
77-
method: "GET",
78-
url: this.url + "/instance/logs",
79-
withCredentials: true,
80-
});
112+
method: 'GET',
113+
url: this.url + '/instance/logs',
114+
withCredentials: true
115+
})
81116

82-
return response;
117+
return response
83118
},
84119
getInstancesLogs: async function (id) {
85120
const response = await axios({
86-
method: "GET",
121+
method: 'GET',
87122
url: this.url + `/instance/${id}/logs`,
88-
withCredentials: true,
89-
});
123+
withCredentials: true
124+
})
125+
126+
return response
127+
},
128+
getUserPayments: async function () {
129+
const response = await axios({
130+
method: 'GET',
131+
url: this.url + '/instance/payments',
132+
withCredentials: true
133+
})
134+
135+
return response
136+
},
137+
getInstancePayments: async function (id) {
138+
const response = await axios({
139+
method: 'GET',
140+
url: this.url + `/instance/${id}/payments`,
141+
withCredentials: true
142+
})
143+
144+
return response
145+
},
146+
getUserSubscriptions: async function () {
147+
const response = await axios({
148+
method: 'GET',
149+
url: this.url + '/instance/subscriptions',
150+
withCredentials: true
151+
})
152+
153+
return response
154+
},
155+
getInstanceSubscriptions: async function (id) {
156+
const response = await axios({
157+
method: 'GET',
158+
url: this.url + `/instance/${id}/subscriptions`,
159+
withCredentials: true
160+
})
90161

91-
return response;
162+
return response
92163
},
93164
status: async function () {
94165
const response = await axios({
95-
method: "GET",
166+
method: 'GET',
96167
url: this.url,
97-
withCredentials: true,
98-
});
168+
withCredentials: true
169+
})
99170

100-
this.serverTime = response.data.timestamp;
171+
this.serverTime = response.data.timestamp
101172

102-
return response;
173+
return response
103174
},
104175
logout: async function () {
105176
const response = await axios({
106-
method: "POST",
107-
url: this.url + "/logout",
108-
withCredentials: true,
109-
});
110-
this.username = null;
111-
localStorage.clear();
112-
return response;
177+
method: 'POST',
178+
url: this.url + '/logout',
179+
withCredentials: true
180+
})
181+
this.username = null
182+
localStorage.clear()
183+
return response
113184
},
114185

115186
mapInstance: function (instance) {
116187
const progress = (start, stop, serverTime) => {
117188
if (!serverTime) {
118-
return 0;
189+
return 0
119190
}
120191
if (stop - start <= 0 || stop - serverTime <= 0) {
121-
return 100;
192+
return 100
122193
}
123194

124-
const percentage = (1 - (stop - serverTime) / (stop - start)) * 100;
195+
const percentage = (1 - (stop - serverTime) / (stop - start)) * 100
125196

126-
return Math.floor(percentage);
127-
};
197+
return Math.floor(percentage)
198+
}
128199

129200
const status = (active, enabled) => {
130-
if (!active){
131-
return "Not Paid"
201+
if (!active) {
202+
return 'Not Paid'
132203
}
133204
if (!enabled) {
134-
return "Disabled"
205+
return 'Disabled'
135206
}
136-
return "Running"
207+
return 'Running'
137208
}
138209

139210
const timeLeft = Math.floor(
140211
Math.max(instance.timestamp_stop - this.serverTime, 0)
141-
);
212+
)
142213
return {
143214
id: instance.id,
144215
instanceLink: `https://${instance.domain}/wallet`,
@@ -160,34 +231,34 @@ var saas = {
160231
instance.timestamp_start || instance.timestamp,
161232
instance.timestamp_stop,
162233
this.serverTime
163-
),
164-
};
234+
)
235+
}
165236
},
166237
mapErrorToString(error) {
167-
const data = error.response?.data;
238+
const data = error.response?.data
168239
if (!data) {
169-
return;
240+
return
170241
}
171-
if (typeof data === "string") {
172-
return data;
242+
if (typeof data === 'string') {
243+
return data
173244
}
174-
return data?.detail?.map((d) => d.msg).join(", ");
175-
},
176-
};
245+
return data?.detail?.map(d => d.msg).join(', ')
246+
}
247+
}
177248

178-
(async () => {
249+
;(async () => {
179250
axios.interceptors.response.use(
180-
(response) => response,
181-
(err) => {
251+
response => response,
252+
err => {
182253
if (err?.response?.status === 401) {
183-
saas.logout();
184-
if (window.location.pathname !== "/login") {
185-
setTimeout(() => (window.location.href = "/login"), 500);
254+
saas.logout()
255+
if (window.location.pathname !== '/login') {
256+
setTimeout(() => (window.location.href = '/login'), 500)
186257
}
187258
}
188-
return Promise.reject(err);
259+
return Promise.reject(err)
189260
}
190-
);
191-
})();
261+
)
262+
})()
192263

193-
export { saas };
264+
export {saas}

0 commit comments

Comments
 (0)