From 1199bc6d08c6c5d9c3b18936b7168e2af877294b Mon Sep 17 00:00:00 2001 From: Immanuel Onyeka Date: Wed, 22 May 2024 20:59:23 -0400 Subject: [PATCH] Show billing prompt if there are payment errors automatically prompts for a new card if past payments were unsuccessful. Does not actually disable API access. --- components/app.vue | 34 +++++++- components/dialog.vue | 2 +- components/login.vue | 7 +- components/update-billing/billing.vue | 42 ++++++++++ components/update-billing/completed.vue | 19 +++++ components/update-billing/prompt.vue | 35 ++++++++ components/update-billing/update-billing.vue | 86 ++++++++++++++++++++ main.css | 12 +-- skouter.go | 15 +++- 9 files changed, 238 insertions(+), 14 deletions(-) create mode 100644 components/update-billing/billing.vue create mode 100644 components/update-billing/completed.vue create mode 100644 components/update-billing/prompt.vue create mode 100644 components/update-billing/update-billing.vue diff --git a/components/app.vue b/components/app.vue index de745cf..29b7ab3 100644 --- a/components/app.vue +++ b/components/app.vue @@ -2,6 +2,7 @@
@@ -57,6 +61,7 @@ import Estimates from "./estimates.vue" import Settings from "./settings.vue" import SignOut from "./sign-out.vue" import Login from "./login.vue" +import Biller from "./update-billing/update-billing.vue" function getCookie(name) { var re = new RegExp(name + "=([^;]+)") @@ -86,6 +91,20 @@ function refreshToken() { }) } +function fetchUser() { + return fetch(`/api/user`, + {method: 'GET', + headers: { + "Accept": "application/json", + "Authorization": `Bearer ${getCookie("skouter")}`, + }, + }).then(response => { + if (response.ok) { + return response.json() + } + }) +} + function getUser() { const token = getCookie("skouter") this.token = token @@ -206,17 +225,28 @@ function active() { // Fetch data before showing UI. If requests fail, assume token is expired. function start() { this.loading = true + const validStatuses = ["incomplete", "trialing", "active"] let loaders = [] loaders.push(this.getUser()) loaders.push(this.getFees()) Promise.all(loaders).then((a, b) => { this.loading = false - if (!b) { + if (!b) { // !b means there is no rejection error for any promise // Time untill token expiration may have elapsed before the page // reloaded this.refreshToken() + fetchUser().then( u => { + if (u.sub.customerId && + validStatuses.includes(u.sub.paymentStatus)) { + return + } + // Payment must be updated + console.log("paying...") + this.invalidSub = true + }) } + window.location.hash = '' }).catch(error => { console.log("An error occured %O", error) this.loadingError = "Could not initialize app." @@ -249,6 +279,7 @@ export default { NewEstimate, Estimates, Settings, + Biller, SignOut, Login }, @@ -273,6 +304,7 @@ export default { fees: [], loadingError: "", token: '', + invalidSub: false, } }, created() { diff --git a/components/dialog.vue b/components/dialog.vue index bf02d52..2fde4e0 100644 --- a/components/dialog.vue +++ b/components/dialog.vue @@ -1,5 +1,5 @@