peertube-plugin-sell-storage 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +69 -0
- package/assets/style.css +11 -0
- package/client/common-client-plugin.js +75 -0
- package/client/pages/cancel.js +16 -0
- package/client/pages/subscription.js +161 -0
- package/client/pages/success.js +85 -0
- package/dist/common-client-plugin.js +64 -0
- package/languages/fr.json +14 -0
- package/main.js +628 -0
- package/package.json +55 -0
- package/public/images/.gitkeep +0 -0
- package/scripts/build.js +20 -0
- package/shell.nix +7 -0
package/README.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# PeerTube Plugin Sell Storage
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [About](#about)
|
|
6
|
+
- [Getting Started](#getting_started)
|
|
7
|
+
- [Usage](#usage)
|
|
8
|
+
|
|
9
|
+
## About <a name = "about"></a>
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
This plugin allow you to sell storage space to your users using Stripe subscription. Payments are automated with Stripe.
|
|
13
|
+
|
|
14
|
+
## Getting Started <a name = "getting_started"></a>
|
|
15
|
+
|
|
16
|
+
This is a fork of [peertube-plugin-ncd-sell-storage](https://gitea.nicecrew.digital/matty/peertube-plugin-ncd-sell-storage). Unfortunately, the published version on NPM is outdated and therefore does not work despite the fix being available on their Git repository. For that reason, their repository was forked and published separately with the updated code.
|
|
17
|
+
|
|
18
|
+
As with [peertube-plugin-ncd-sell-storage](https://gitea.nicecrew.digital/matty/peertube-plugin-ncd-sell-storage), this fork allows you to add five packages rather than three.
|
|
19
|
+
|
|
20
|
+
Check [Prerequisites](#Prerequisites) to install this plugin
|
|
21
|
+
|
|
22
|
+
### Prerequisites
|
|
23
|
+
|
|
24
|
+
- Peertube >= v4.3.0
|
|
25
|
+
|
|
26
|
+
### Installing
|
|
27
|
+
|
|
28
|
+
- Go to your instance Admin
|
|
29
|
+
- Navigate to the "Plugins" page
|
|
30
|
+
- Search for "sell-storage"
|
|
31
|
+
- Click Install near the plugin name
|
|
32
|
+
|
|
33
|
+
## If installing locally
|
|
34
|
+
- Clone Git repository
|
|
35
|
+
- cd peertube-plugin-sell-storage
|
|
36
|
+
- yarn
|
|
37
|
+
- yarn build
|
|
38
|
+
- Install via PeerTube CLI
|
|
39
|
+
|
|
40
|
+
### Configuration
|
|
41
|
+
You need to configuration the plugin to work.
|
|
42
|
+
Create an account on https://stripe.com to start.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
In your Stripe dashboard, you can test in "Test mode", and go live by unchecking "Test mode" in the top right.
|
|
46
|
+
To go in live mode, you need to fill form in Stripe side. We recommand you to test in Test mode the integration before go in live.
|
|
47
|
+
|
|
48
|
+
### Note: If you perform a transaction in Test Mode, you'll need to manually clear the subscription status because the webhook will not send back the correct validation response, meaning the changes will take effect but nothing will be charged. Use a dedicated test account.
|
|
49
|
+
|
|
50
|
+
First, go to the Developer tab, and navigate to "API Keys". Grab your Secret API key, and insert it in your plugin settings.
|
|
51
|
+
After that, always in the Developer tab, navigate to Webhook and create a webhook.
|
|
52
|
+
|
|
53
|
+
An example of webhook URL is available in your plugin settings. An example is also shown here:
|
|
54
|
+
https://your-instance.tld/plugins/sell-storage/1.1.3/router/webhook
|
|
55
|
+
|
|
56
|
+
### Note: If you update the plugin, you'll have to update the webhook link in Stripe with the new version. For example, update 1.1.3 to 1.1.4. Don't forget this!
|
|
57
|
+
|
|
58
|
+
Now, configure your Currency and Page description in the plugin settings.
|
|
59
|
+
|
|
60
|
+
Its time to add your Plans! In stripe, go to Product page, and add new product. Set a name, description and the price.
|
|
61
|
+
After creation, go in this new Product and grab the "API ID" near the price field.
|
|
62
|
+
|
|
63
|
+
Now, you can continue configure your Plan (1, 2, 3, 4, 5) in the plugin settings.
|
|
64
|
+
Repeat this process for each plans. Add new product, and grab the API ID corresponding to this price to insert it in your Product ID field, in the plugin settings.
|
|
65
|
+
|
|
66
|
+
## Usage <a name = "usage"></a>
|
|
67
|
+
|
|
68
|
+
- Navigate to "My Account""
|
|
69
|
+
- Navigate to the new navigation link "My Subscription"
|
package/assets/style.css
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const subPage = require("./pages/subscription");
|
|
2
|
+
const successPage = require("./pages/success");
|
|
3
|
+
const cancelPage = require("./pages/cancel");
|
|
4
|
+
|
|
5
|
+
async function register({
|
|
6
|
+
registerHook,
|
|
7
|
+
peertubeHelpers,
|
|
8
|
+
registerClientRoute,
|
|
9
|
+
}) {
|
|
10
|
+
/**
|
|
11
|
+
* Add link admin page
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
registerHook({
|
|
15
|
+
target: "filter:left-menu.links.create.result",
|
|
16
|
+
handler: (links) => {
|
|
17
|
+
if (!Array.isArray(links)) {
|
|
18
|
+
return links;
|
|
19
|
+
}
|
|
20
|
+
let myLibraryLinks;
|
|
21
|
+
// Searching the 'in-my-library' entry.
|
|
22
|
+
for (const link of links) {
|
|
23
|
+
if (typeof link !== "object") {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (!("key" in link)) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (link.key === "in-my-library" || link.key === "my-video-space") {
|
|
30
|
+
myLibraryLinks = link;
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (!myLibraryLinks) {
|
|
35
|
+
return links;
|
|
36
|
+
}
|
|
37
|
+
if (!Array.isArray(myLibraryLinks.links)) {
|
|
38
|
+
return links;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const label = "NCTV Storage";
|
|
42
|
+
myLibraryLinks.links.unshift({
|
|
43
|
+
label,
|
|
44
|
+
shortLabel: label,
|
|
45
|
+
path: "/p/ncd-my-subscription",
|
|
46
|
+
icon: "film",
|
|
47
|
+
});
|
|
48
|
+
return links;
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Register routes
|
|
53
|
+
registerClientRoute({
|
|
54
|
+
route: "ncd-my-subscription",
|
|
55
|
+
onMount: ({ rootEl }) => {
|
|
56
|
+
subPage.showPage({ rootEl, peertubeHelpers });
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
registerClientRoute({
|
|
61
|
+
route: "ncd-subscription-success",
|
|
62
|
+
onMount: ({ rootEl }) => {
|
|
63
|
+
successPage.showPage({ rootEl, peertubeHelpers });
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
registerClientRoute({
|
|
68
|
+
route: "ncd-subscription-cancel",
|
|
69
|
+
onMount: ({ rootEl }) => {
|
|
70
|
+
cancelPage.showPage({ rootEl, peertubeHelpers });
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { register };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
async function showPage({ rootEl, peertubeHelpers }) {
|
|
2
|
+
// Redirect to login page if not auth
|
|
3
|
+
if (!peertubeHelpers.isLoggedIn()) return (window.location.href = "/login");
|
|
4
|
+
|
|
5
|
+
const settings = await peertubeHelpers.getSettings();
|
|
6
|
+
const description = await peertubeHelpers.markdownRenderer.enhancedMarkdownToHTML(settings["sell-cancel-description"]);
|
|
7
|
+
|
|
8
|
+
rootEl.innerHTML = `
|
|
9
|
+
<div class="ncd-content text-center mt-5">
|
|
10
|
+
<h1>${await peertubeHelpers.translate("Subscription canceled.")}</h1>
|
|
11
|
+
<p>${description}</p>
|
|
12
|
+
</div>
|
|
13
|
+
`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { showPage };
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
async function showPage({ rootEl, peertubeHelpers }) {
|
|
2
|
+
// Redirect to login page if not auth
|
|
3
|
+
if (!peertubeHelpers.isLoggedIn()) return (window.location.href = "/login");
|
|
4
|
+
|
|
5
|
+
const { translate } = peertubeHelpers;
|
|
6
|
+
const loading = await peertubeHelpers.translate("Loading");
|
|
7
|
+
rootEl.innerHTML = loading + "...";
|
|
8
|
+
|
|
9
|
+
// Get settings
|
|
10
|
+
const settings = await peertubeHelpers.getSettings();
|
|
11
|
+
const currency = settings['sell-currency'];
|
|
12
|
+
const description = await peertubeHelpers.markdownRenderer.enhancedMarkdownToHTML(settings["sell-description"]);
|
|
13
|
+
const plans = [];
|
|
14
|
+
|
|
15
|
+
for (let i = 1; i <= 5; i++) {
|
|
16
|
+
const name = settings["plan-" + i + "-name"];
|
|
17
|
+
const key = settings["plan-" + i + "-key"];
|
|
18
|
+
const storage = settings["plan-" + i + "-storage"];
|
|
19
|
+
const price = settings["plan-" + i + "-price"];
|
|
20
|
+
|
|
21
|
+
plans.push({
|
|
22
|
+
name: name,
|
|
23
|
+
key: key,
|
|
24
|
+
storage: storage,
|
|
25
|
+
price: price
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Fetch session id and subscribed plan (if any)
|
|
30
|
+
let session_id = null, sub_plan = null;
|
|
31
|
+
const response = await fetch(peertubeHelpers.getBaseRouterRoute() + "/get-session-id", {
|
|
32
|
+
method: "GET",
|
|
33
|
+
headers: peertubeHelpers.getAuthHeader(),
|
|
34
|
+
});
|
|
35
|
+
const data = await response.json();
|
|
36
|
+
|
|
37
|
+
// If have error
|
|
38
|
+
if (!data || !data.status || (data.status && data.status !== "success")) {
|
|
39
|
+
peertubeHelpers.notifier.error(data.message || "Unknown error");
|
|
40
|
+
} else {
|
|
41
|
+
session_id = data?.data?.session_id;
|
|
42
|
+
sub_plan = data?.data?.sub_plan;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
rootEl.innerHTML = `
|
|
46
|
+
<div class="ncd-content text-center">
|
|
47
|
+
<h1>${await peertubeHelpers.translate("Choose your Storage Plan")}</h1>
|
|
48
|
+
<h5><i>To subscribe to a storage plan with cryptocurrency (BTC, ETH, XMR), <a href="/about/contact">contact us</a>.</i></h5>
|
|
49
|
+
<h6><i>Note: Cryptocurrency prices are 25% higher to cover transaction fees.</i></h6>
|
|
50
|
+
<!-- <p>${description.length ? description : await peertubeHelpers.translate("You want tu spport us ? Or need more space ? Your in the right place!")}</p> -->
|
|
51
|
+
<div class="mt-5" style="max-width: 90%; margin: 0 auto;">
|
|
52
|
+
<div class="row">
|
|
53
|
+
${(await Promise.all(plans.map(async (plan) =>
|
|
54
|
+
`<div class="col-sm-12 col-md-6 col-lg-4" style="margin-bottom: 1rem;">
|
|
55
|
+
<div class="card">
|
|
56
|
+
<div class="card-body">
|
|
57
|
+
<form method="POST" action="#" class="ncdSubscriptionForm">
|
|
58
|
+
<h3 class="card-title">${plan.name}</h3>
|
|
59
|
+
<h4>${currency}${plan.price} /${await peertubeHelpers.translate("month")}</h4>
|
|
60
|
+
<p class="card-text">${plan.storage} ${await peertubeHelpers.translate("GB Storage")}</p>
|
|
61
|
+
|
|
62
|
+
<input type="hidden" name="lookup_key" value="${plan.key}">
|
|
63
|
+
<button class="btn btn-primary" type="submit">${await peertubeHelpers.translate("Subscribe")}</button>
|
|
64
|
+
</form>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
`))).join("")}
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
${session_id ? `
|
|
73
|
+
<div class="mt-5">
|
|
74
|
+
<form method="POST" action="#" id="formManageSub">
|
|
75
|
+
<input type="hidden" id="session-id" name="session_id" value="${session_id}" />
|
|
76
|
+
<button id="checkout-and-portal-button" type="submit" class="btn btn-primary">${await translate("Manage my Subscription")}</button>
|
|
77
|
+
</form>
|
|
78
|
+
</div>
|
|
79
|
+
` : ""}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
${sub_plan ? `
|
|
83
|
+
<p><i><b>${await translate("Your current plan")}</b>: ${sub_plan.name}, ${currency}${sub_plan.price} /${await peertubeHelpers.translate("month")}, ${sub_plan.storage} ${await peertubeHelpers.translate("GB Storage")}</i></p>
|
|
84
|
+
|
|
85
|
+
<div>
|
|
86
|
+
<a href="https://billing.stripe.com/p/login/aEUg0YcdE3ff9j2cMM" target="_blank" style="font-size: 1.25rem; background-color: #0083f5; color: white; border-radius: 0.25rem; padding: 0.5rem 0.75rem; margin-top: 1.25rem;">Manage Subcription</a>
|
|
87
|
+
<div>
|
|
88
|
+
` : ""}
|
|
89
|
+
|
|
90
|
+
</div>
|
|
91
|
+
`;
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
const checkForListen = () => {
|
|
95
|
+
document.querySelectorAll(".ncdSubscriptionForm").length === 5 ? listenSubmitSubscription(peertubeHelpers) : setTimeout(() => checkForListen(), 1000);
|
|
96
|
+
};
|
|
97
|
+
checkForListen();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function listenSubmitSubscription(peertubeHelpers) {
|
|
101
|
+
const baseUrl = peertubeHelpers.getBaseRouterRoute();
|
|
102
|
+
|
|
103
|
+
// Sub
|
|
104
|
+
document.querySelectorAll(".ncdSubscriptionForm").forEach(el => {
|
|
105
|
+
el.addEventListener("submit", (e) => {
|
|
106
|
+
e.preventDefault();
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
const form = new URLSearchParams(new FormData(e.target));
|
|
110
|
+
fetch(baseUrl + "/create-checkout-session", {
|
|
111
|
+
method: "POST",
|
|
112
|
+
headers: peertubeHelpers.getAuthHeader(),
|
|
113
|
+
body: form,
|
|
114
|
+
}).then((res) => res.json()).then((data) => {
|
|
115
|
+
if (!data || !data.status || data.status !== "success") {
|
|
116
|
+
peertubeHelpers.notifier.error(data.message || "Unknown error");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
window.location.href = data.data.redirectUrl;
|
|
121
|
+
}).catch(err => {
|
|
122
|
+
console.error(err);
|
|
123
|
+
peertubeHelpers.notifier.error(err);
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
} catch (error) {
|
|
127
|
+
peertubeHelpers.notifier.error(error);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
// Manage sub
|
|
134
|
+
document.getElementById("formManageSub")?.addEventListener("submit", (e) => {
|
|
135
|
+
e.preventDefault();
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
const form = new URLSearchParams(new FormData(e.target));
|
|
139
|
+
fetch(baseUrl + "/create-portal-session", {
|
|
140
|
+
method: "POST",
|
|
141
|
+
headers: peertubeHelpers.getAuthHeader(),
|
|
142
|
+
body: form,
|
|
143
|
+
}).then((res) => res.json()).then((data) => {
|
|
144
|
+
if (!data || !data.status || data.status !== "success") {
|
|
145
|
+
peertubeHelpers.notifier.error(data.message || "Unknown error");
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
window.location.href = data.data.redirectUrl;
|
|
150
|
+
}).catch(err => {
|
|
151
|
+
console.error(err);
|
|
152
|
+
peertubeHelpers.notifier.error(err);
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
} catch (error) {
|
|
156
|
+
peertubeHelpers.notifier.error(error);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export { showPage };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
async function showPage({ rootEl, peertubeHelpers }) {
|
|
2
|
+
// Redirect to login page if not auth
|
|
3
|
+
if (!peertubeHelpers.isLoggedIn()) return (window.location.href = "/login");
|
|
4
|
+
|
|
5
|
+
const loading = await peertubeHelpers.translate("Loading");
|
|
6
|
+
rootEl.innerHTML = loading + "...";
|
|
7
|
+
|
|
8
|
+
const { translate } = peertubeHelpers;
|
|
9
|
+
const description = await peertubeHelpers.markdownRenderer.enhancedMarkdownToHTML(settings["sell-thx-description"]);
|
|
10
|
+
|
|
11
|
+
rootEl.innerHTML = `
|
|
12
|
+
<div class="ncd-content text-center mt-5">
|
|
13
|
+
<h1>${await peertubeHelpers.translate("Subscription succesfull!")}</h1>
|
|
14
|
+
|
|
15
|
+
<div class="mt-5">
|
|
16
|
+
<form action="#" method="POST" class="ncdSubscriptionForm">
|
|
17
|
+
<input type="hidden" id="session-id" name="session_id" value="" />
|
|
18
|
+
<button id="checkout-and-portal-button" type="submit" class="btn btn-primary">${await translate("Manage my Subscription")}</button>
|
|
19
|
+
</form>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<p>${description}</p>
|
|
23
|
+
</div>
|
|
24
|
+
`;
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
setTimeout(() => listenSubmitSubscription(peertubeHelpers), 1000);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function listenSubmitSubscription(peertubeHelpers) {
|
|
31
|
+
const baseUrl = peertubeHelpers.getBaseRouterRoute();
|
|
32
|
+
|
|
33
|
+
const params = new URLSearchParams(window.location.search);
|
|
34
|
+
if(params.has("session_id")) {
|
|
35
|
+
document.getElementById("session-id").value = params.get("session_id");
|
|
36
|
+
localStorage.setItem("ncd-sub-session-id", params.get("session_id"));
|
|
37
|
+
|
|
38
|
+
const formData = new FormData();
|
|
39
|
+
formData.append("session_id", params.get("session_id"));
|
|
40
|
+
|
|
41
|
+
const form = new URLSearchParams(formData);
|
|
42
|
+
|
|
43
|
+
fetch(baseUrl + "/save-session-id", {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: peertubeHelpers.getAuthHeader(),
|
|
46
|
+
body: form,
|
|
47
|
+
}).then((res) => res.json()).then((data) => {
|
|
48
|
+
if(!data || !data.status || data.status !== "success") {
|
|
49
|
+
peertubeHelpers.notifier.error(data.message || "Unknown error");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
}).catch(err => {
|
|
53
|
+
console.error(err);
|
|
54
|
+
peertubeHelpers.notifier.error(err);
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
document.querySelector(".ncdSubscriptionForm").addEventListener("submit", (e) => {
|
|
59
|
+
e.preventDefault();
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
const form = new URLSearchParams(new FormData(e.target));
|
|
63
|
+
fetch(baseUrl + "/create-portal-session", {
|
|
64
|
+
method: "POST",
|
|
65
|
+
headers: peertubeHelpers.getAuthHeader(),
|
|
66
|
+
body: form,
|
|
67
|
+
}).then((res) => res.json()).then((data) => {
|
|
68
|
+
if(!data || !data.status || data.status !== "success") {
|
|
69
|
+
peertubeHelpers.notifier.error(data.message || "Unknown error");
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
window.location.href = data.data.redirectUrl;
|
|
74
|
+
}).catch(err => {
|
|
75
|
+
console.error(err);
|
|
76
|
+
peertubeHelpers.notifier.error(err);
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
} catch (error) {
|
|
80
|
+
peertubeHelpers.notifier.error(error);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export { showPage };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
var h=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var u=(o,t)=>()=>(o&&(t=o(o=0)),t);var l=(o,t)=>{for(var a in t)h(o,a,{get:t[a],enumerable:!0})},x=(o,t,a,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of A(t))!p.call(o,s)&&s!==a&&h(o,s,{get:()=>t[s],enumerable:!(i=_(t,s))||i.enumerable});return o};var g=o=>x(h({},"__esModule",{value:!0}),o);var v={};l(v,{showPage:()=>F});async function F({rootEl:o,peertubeHelpers:t}){var y,S;if(!t.isLoggedIn())return window.location.href="/login";let{translate:a}=t,i=await t.translate("Loading");o.innerHTML=i+"...";let s=await t.getSettings(),n=s["sell-currency"],r=await t.markdownRenderer.enhancedMarkdownToHTML(s["sell-description"]),f=[];for(let c=1;c<=5;c++){let P=s["plan-"+c+"-name"],M=s["plan-"+c+"-key"],U=s["plan-"+c+"-storage"],R=s["plan-"+c+"-price"];f.push({name:P,key:M,storage:U,price:R})}let m=null,d=null,e=await(await fetch(t.getBaseRouterRoute()+"/get-session-id",{method:"GET",headers:t.getAuthHeader()})).json();!e||!e.status||e.status&&e.status!=="success"?t.notifier.error(e.message||"Unknown error"):(m=(y=e==null?void 0:e.data)==null?void 0:y.session_id,d=(S=e==null?void 0:e.data)==null?void 0:S.sub_plan),o.innerHTML=`
|
|
2
|
+
<div class="ncd-content text-center">
|
|
3
|
+
<h1>${await t.translate("Choose your Storage Plan")}</h1>
|
|
4
|
+
<h5><i>To subscribe to a storage plan with cryptocurrency (BTC, ETH, XMR), <a href="/about/contact">contact us</a>.</i></h5>
|
|
5
|
+
<h6><i>Note: Cryptocurrency prices are 25% higher to cover transaction fees.</i></h6>
|
|
6
|
+
<!-- <p>${r.length?r:await t.translate("You want tu spport us ? Or need more space ? Your in the right place!")}</p> -->
|
|
7
|
+
<div class="mt-5" style="max-width: 90%; margin: 0 auto;">
|
|
8
|
+
<div class="row">
|
|
9
|
+
${(await Promise.all(f.map(async c=>`<div class="col-sm-12 col-md-6 col-lg-4" style="margin-bottom: 1rem;">
|
|
10
|
+
<div class="card">
|
|
11
|
+
<div class="card-body">
|
|
12
|
+
<form method="POST" action="#" class="ncdSubscriptionForm">
|
|
13
|
+
<h3 class="card-title">${c.name}</h3>
|
|
14
|
+
<h4>${n}${c.price} /${await t.translate("month")}</h4>
|
|
15
|
+
<p class="card-text">${c.storage} ${await t.translate("GB Storage")}</p>
|
|
16
|
+
|
|
17
|
+
<input type="hidden" name="lookup_key" value="${c.key}">
|
|
18
|
+
<button class="btn btn-primary" type="submit">${await t.translate("Subscribe")}</button>
|
|
19
|
+
</form>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
`))).join("")}
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
${m?`
|
|
28
|
+
<div class="mt-5">
|
|
29
|
+
<form method="POST" action="#" id="formManageSub">
|
|
30
|
+
<input type="hidden" id="session-id" name="session_id" value="${m}" />
|
|
31
|
+
<button id="checkout-and-portal-button" type="submit" class="btn btn-primary">${await a("Manage my Subscription")}</button>
|
|
32
|
+
</form>
|
|
33
|
+
</div>
|
|
34
|
+
`:""}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
${d?`
|
|
38
|
+
<p><i><b>${await a("Your current plan")}</b>: ${d.name}, ${n}${d.price} /${await t.translate("month")}, ${d.storage} ${await t.translate("GB Storage")}</i></p>
|
|
39
|
+
|
|
40
|
+
<div>
|
|
41
|
+
<a href="https://billing.stripe.com/p/login/aEUg0YcdE3ff9j2cMM" target="_blank" style="font-size: 1.25rem; background-color: #0083f5; color: white; border-radius: 0.25rem; padding: 0.5rem 0.75rem; margin-top: 1.25rem;">Manage Subcription</a>
|
|
42
|
+
<div>
|
|
43
|
+
`:""}
|
|
44
|
+
|
|
45
|
+
</div>
|
|
46
|
+
`;let w=()=>{document.querySelectorAll(".ncdSubscriptionForm").length===5?j(t):setTimeout(()=>w(),1e3)};w()}function j(o){var a;let t=o.getBaseRouterRoute();document.querySelectorAll(".ncdSubscriptionForm").forEach(i=>{i.addEventListener("submit",s=>{s.preventDefault();try{let n=new URLSearchParams(new FormData(s.target));fetch(t+"/create-checkout-session",{method:"POST",headers:o.getAuthHeader(),body:n}).then(r=>r.json()).then(r=>{if(!r||!r.status||r.status!=="success"){o.notifier.error(r.message||"Unknown error");return}window.location.href=r.data.redirectUrl}).catch(r=>{console.error(r),o.notifier.error(r)})}catch(n){o.notifier.error(n)}})}),(a=document.getElementById("formManageSub"))==null||a.addEventListener("submit",i=>{i.preventDefault();try{let s=new URLSearchParams(new FormData(i.target));fetch(t+"/create-portal-session",{method:"POST",headers:o.getAuthHeader(),body:s}).then(n=>n.json()).then(n=>{if(!n||!n.status||n.status!=="success"){o.notifier.error(n.message||"Unknown error");return}window.location.href=n.data.redirectUrl}).catch(n=>{console.error(n),o.notifier.error(n)})}catch(s){o.notifier.error(s)}})}var b=u(()=>{});var k={};l(k,{showPage:()=>B});async function B({rootEl:o,peertubeHelpers:t}){if(!t.isLoggedIn())return window.location.href="/login";let a=await t.translate("Loading");o.innerHTML=a+"...";let{translate:i}=t,s=await t.markdownRenderer.enhancedMarkdownToHTML(settings["sell-thx-description"]);o.innerHTML=`
|
|
47
|
+
<div class="ncd-content text-center mt-5">
|
|
48
|
+
<h1>${await t.translate("Subscription succesfull!")}</h1>
|
|
49
|
+
|
|
50
|
+
<div class="mt-5">
|
|
51
|
+
<form action="#" method="POST" class="ncdSubscriptionForm">
|
|
52
|
+
<input type="hidden" id="session-id" name="session_id" value="" />
|
|
53
|
+
<button id="checkout-and-portal-button" type="submit" class="btn btn-primary">${await i("Manage my Subscription")}</button>
|
|
54
|
+
</form>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<p>${s}</p>
|
|
58
|
+
</div>
|
|
59
|
+
`,setTimeout(()=>D(t),1e3)}function D(o){let t=o.getBaseRouterRoute(),a=new URLSearchParams(window.location.search);if(a.has("session_id")){document.getElementById("session-id").value=a.get("session_id"),localStorage.setItem("ncd-sub-session-id",a.get("session_id"));let i=new FormData;i.append("session_id",a.get("session_id"));let s=new URLSearchParams(i);fetch(t+"/save-session-id",{method:"POST",headers:o.getAuthHeader(),body:s}).then(n=>n.json()).then(n=>{(!n||!n.status||n.status!=="success")&&o.notifier.error(n.message||"Unknown error")}).catch(n=>{console.error(n),o.notifier.error(n)})}document.querySelector(".ncdSubscriptionForm").addEventListener("submit",i=>{i.preventDefault();try{let s=new URLSearchParams(new FormData(i.target));fetch(t+"/create-portal-session",{method:"POST",headers:o.getAuthHeader(),body:s}).then(n=>n.json()).then(n=>{if(!n||!n.status||n.status!=="success"){o.notifier.error(n.message||"Unknown error");return}window.location.href=n.data.redirectUrl}).catch(n=>{console.error(n),o.notifier.error(n)})}catch(s){o.notifier.error(s)}})}var $=u(()=>{});var L={};l(L,{showPage:()=>E});async function E({rootEl:o,peertubeHelpers:t}){if(!t.isLoggedIn())return window.location.href="/login";let a=await t.getSettings(),i=await t.markdownRenderer.enhancedMarkdownToHTML(a["sell-cancel-description"]);o.innerHTML=`
|
|
60
|
+
<div class="ncd-content text-center mt-5">
|
|
61
|
+
<h1>${await t.translate("Subscription canceled.")}</h1>
|
|
62
|
+
<p>${i}</p>
|
|
63
|
+
</div>
|
|
64
|
+
`}var T=u(()=>{});var O=(b(),g(v)),q=($(),g(k)),I=(T(),g(L));async function C({registerHook:o,peertubeHelpers:t,registerClientRoute:a}){o({target:"filter:left-menu.links.create.result",handler:i=>{if(!Array.isArray(i))return i;let s;for(let r of i)if(typeof r=="object"&&"key"in r&&(r.key==="in-my-library"||r.key==="my-video-space")){s=r;break}if(!s||!Array.isArray(s.links))return i;let n="NCTV Storage";return s.links.unshift({label:n,shortLabel:n,path:"/p/ncd-my-subscription",icon:"film"}),i}}),a({route:"ncd-my-subscription",onMount:({rootEl:i})=>{O.showPage({rootEl:i,peertubeHelpers:t})}}),a({route:"ncd-subscription-success",onMount:({rootEl:i})=>{q.showPage({rootEl:i,peertubeHelpers:t})}}),a({route:"ncd-subscription-cancel",onMount:({rootEl:i})=>{I.showPage({rootEl:i,peertubeHelpers:t})}})}export{C as register};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Choose your Subscription": "Choisissez votre Abonnement",
|
|
3
|
+
"My Subscription": "Mon Abonnement",
|
|
4
|
+
"month": "mois",
|
|
5
|
+
"GB Storage": "GO de Stockage",
|
|
6
|
+
"Subscribe": "Souscrire",
|
|
7
|
+
"You want tu spport us ? Or need more space ? Your in the right place!" : "Vous souhaitez nous aider ? Vous avez besoin de plus d'espace ? Vous êtes au bon endroit !",
|
|
8
|
+
"Subscription succesfull!": "Souscription réussi !",
|
|
9
|
+
"Manage my Subscription": "Gérer mon abonnement",
|
|
10
|
+
"Subscription canceled.": "Souscription annulée.",
|
|
11
|
+
"Secure payment with Stripe": "Paiement sécurisé via Stripe",
|
|
12
|
+
"Your current plan": "Votre offre actuelle",
|
|
13
|
+
"NCTV Storage": "NCTV Stockage"
|
|
14
|
+
}
|