-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🔧 refactor(providers.js): import lodash's isUndefined function for be…
…tter null checking 🔧 refactor(providers.js): add subscription ref to keep track of subscription data 🔧 refactor(providers.js): add senderNo to defaultSystemProvider for better SMS handling 🔧 refactor(providers.js): add subscription value assignment after fetching subscription data 🔧 refactor(providers.js): change creditsCount calculation to include consumed credits 🔧 refactor(providers.js): add upsellSubscription function to handle subscription upgrades 🔧 refactor(providers.js): refactor topupProvider function to handle credit top-ups and limit checks 🔧 refactor(providers.js): add subscription to returned object for external access 📦 feat(CreditPurchaseDialog.vue): add new component for handling credit purchases 🔧 refactor(SettingsEmail.vue): import CreditPurchaseDialog component 🔧 refactor(SettingsEmail.vue): add creditsDialog ref for handling credit purchase dialog 🔧 refactor(SettingsEmail.vue): add openCreditsDialog function to handle opening of credit purchase dialog 🔧 refactor(SettingsEmail.vue): add processPurchase function to handle credit purchase processing 🔧 refactor(SettingsEmail.vue): add event listener for purchase event from CreditPurchaseDialog component 🔧 refactor(SettingsEmail.vue): add disabled attribute to Buy more credits button for system provider 🔧 refactor(SettingsEmail.vue): add default value for systemProvider's defaultFrom 🔧 refactor(SettingsSMS.vue): import CreditPurchaseDialog component 🔧 refactor(SettingsSMS.vue): add creditsDialog ref for handling credit purchase dialog 🔧 refactor(SettingsSMS.vue): add openCreditsDialog function to handle opening of credit purchase dialog 🔧 refactor(SettingsSMS.vue): add processPurchase function to handle credit purchase processing 🔧 refactor(SettingsSMS.vue): add event listener for purchase event from CreditPurchaseDialog component 🔧 refactor(SettingsSMS.vue): add disabled attribute to Buy more credits button for system provider 🔧 refactor(SettingsSMS.vue): add default value for provider's senderNo or defaultFrom The changes were made to improve the handling of credit purchases and subscription upgrades. The addition of the CreditPurchaseDialog component allows users to purchase credits directly from the settings page. The refactoring of the topupProvider function in providers.js now handles credit top-ups and checks if the new credit amount exceeds the maximum limit. The addition of the upsellSubscription function handles subscription upgrades
- Loading branch information
Showing
4 changed files
with
145 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ import { ref } from 'vue'; | |
import { useSdk } from 'boot/sdk.js'; | ||
import { useActiveMembership } from 'boot/membership.js'; | ||
import { deepFreeze } from 'boot/helpers'; | ||
import { isUndefined } from 'lodash' | ||
|
||
export function fetchProvider (type, opts) { | ||
opts = Object.assign({ | ||
|
@@ -10,13 +11,15 @@ export function fetchProvider (type, opts) { | |
|
||
const sdk = useSdk(); | ||
const activeMembership = useActiveMembership(); | ||
const subscription = ref(null); | ||
|
||
// default 0-credit system provider | ||
const defaultSystemProvider = deepFreeze({ | ||
id: `system-${type}`, | ||
type: 'sms', | ||
label: `MYCURE ${type} provider`, | ||
defaultFrom: '[email protected]', | ||
senderNo: '+12017482119', | ||
isSystemProvider: true, | ||
creditsCount: 0, | ||
}); | ||
|
@@ -39,10 +42,11 @@ export function fetchProvider (type, opts) { | |
const sub = await sdk.get('subscriptions', { | ||
organization: activeMembership.value.organization.id, | ||
}); | ||
subscription.value = sub; | ||
const creditsMax = sub?.[`${type}CreditsMax`] || 0; | ||
const creditsConsumed = sub?.[`${type}CreditsConsumed`] || 0; | ||
return Object.assign({}, defaultSystemProvider, { | ||
creditsCount: Math.max(0, creditsMax - creditsConsumed), | ||
creditsCount: Math.max(0, creditsMax + creditsConsumed), | ||
}); | ||
}; | ||
const fetchProvider = async () => { | ||
|
@@ -96,15 +100,31 @@ export function fetchProvider (type, opts) { | |
provider.value = await fetchSystemProvider(); | ||
}; | ||
|
||
// upgrade subscription | ||
const upsellSubscription = (subscription) => { | ||
// redirect trialing user to upgrade their subscription plan | ||
console.warn('SUBSCRIPTION-CHECK', subscription); | ||
} | ||
|
||
// for system provider | ||
const topupProvider = async (item, credits) => { | ||
// TODO: implement | ||
await new Promise(resolve => setTimeout(resolve, 1000)); | ||
const topupProvider = async (type, credits) => { | ||
const newAmt = credits + subscription.value?.[`${type}CreditsMax`] | ||
const maxAmt = subscription.value?.package?.products?.[`${type}CreditsMax`]?.max | ||
if (!subscription.value && !type) return; | ||
if (!isUndefined(maxAmt) && newAmt > maxAmt) return new Error('New credit exceeds acceptable limit!') | ||
// if (subscription.value?.status !== 'paid') await upsellSubscription(subscription); | ||
const query = {}; | ||
query[`${type}CreditsMax`] = newAmt; | ||
// const res = await sdk.get('subscriptions', { id: subscription.value?.id } ) | ||
// // console.warn('SUBSCRIPTION-DATA', res); | ||
const res = await sdk.update('subscriptions', subscription.value?.id, query) | ||
subscription.value = res | ||
}; | ||
|
||
return { | ||
loading, | ||
provider, | ||
subscription, | ||
fetchProvider, | ||
fetchSystemProvider, | ||
createProvider, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<template lang="pug"> | ||
q-card(style="width: 400px") | ||
q-card-section.row.justify-between.q-pb-sm | ||
div.column | ||
span.text-h6 Add credits | ||
span.text-caption.text-grey-6 Input the number of credits for purchase. | ||
q-space | ||
q-btn(dense flat round icon="mdi-close" @click.stop="onClose" style="height: 25px") | ||
q-card-section.q-pa-none.q-pb-md | ||
q-input( | ||
v-model.number="creditsForPurchase" | ||
type="number" | ||
label="Credits" | ||
).q-px-md.q-pt-none | ||
//- span.q-px-md.text-weight-normal.text-caption Max amount | ||
q-card-actions.row.justify-end.q-gutter-xs.bg-grey-2.q-pr-md | ||
q-btn( | ||
unelevated | ||
no-caps | ||
color="primary" | ||
@click.stop="onPurchase" | ||
) Purchase | ||
</template> | ||
|
||
<script> | ||
import { ref } from 'vue'; | ||
export default { | ||
props: { | ||
dialog: { | ||
type: Boolean, | ||
default: false, | ||
} | ||
}, | ||
setup (props, { emit }) { | ||
const dialog = ref(props.creditsDialog); | ||
const creditsForPurchase = ref(0); | ||
const onPurchase = () => { | ||
emit('purchase', creditsForPurchase) | ||
dialog.value = false | ||
} | ||
const onClose = () => { | ||
emit('close') | ||
} | ||
return { | ||
dialog, | ||
creditsForPurchase, | ||
onPurchase, | ||
onClose, | ||
} | ||
} | ||
} | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,13 @@ div.row.q-mb-md | |
span.text-h6 Select Email Provider | ||
span.text-caption.text-grey-6 Manage your Email providers here | ||
|
||
// set credit amount | ||
q-dialog(v-model="creditsDialog" persistent) | ||
credit-purchase-dialog( | ||
@close="creditsDialog = false" | ||
@purchase="processPurchase" | ||
) | ||
|
||
// providers | ||
q-card(bordered flat) | ||
// loading | ||
|
@@ -42,7 +49,7 @@ q-card(bordered flat) | |
q-card-section.row.items-center.q-pr-md | ||
span.subtitle2.text-grey {{ systemProvider?.creditsCount || '0' }} Credits | ||
q-space | ||
q-btn(flat unelevated dense no-caps type="a") Buy more credits | ||
q-btn(flat unelevated dense no-caps type="a" disabled) Buy more credits | ||
|
||
div.col-xs-12.col-sm-6 | ||
q-card(bordered flat style="height:180px;").bg-blue-1.text-primary | ||
|
@@ -65,6 +72,7 @@ q-card(bordered flat) | |
q-item-section Edit | ||
q-item(clickable v-close-popup @click="onDelete(provider)") | ||
q-item-section Delete | ||
//- q-icon(name="mdi-delete" color="negative") | ||
q-card-section.row.items-center.q-pr-md | ||
span.subtitle2.text-grey {{ provider?.creditsCount || '0' }} Credits | ||
q-space | ||
|
@@ -81,7 +89,7 @@ q-card(bordered flat) | |
q-avatar(rounded size="lg" :style="{ width: '50px' }").bg-white | ||
q-img(src="../assets/logo.png" :style="{ width: '50%' }") | ||
span.text-h6 MYCURE Email provider | ||
span.text-body2.text-weight-medium {{ systemProvider?.defaultFrom }} | ||
span.text-body2.text-weight-medium {{ systemProvider?.defaultFrom || '[email protected]' }} | ||
//- span.text-subtitle1.text-grey-6 This is a backend provided by the system if you have enough credits | ||
q-space | ||
q-btn(flat unelevated dense icon="mdi-dots-vertical" disabled size="md") | ||
|
@@ -93,7 +101,7 @@ q-card(bordered flat) | |
q-card-section.row.items-center.q-pr-md | ||
span.subtitle2.text-grey {{ provider.creditsCount }} Credits | ||
q-space | ||
q-btn(flat unelevated dense no-caps type="a") Buy more credits | ||
q-btn(flat unelevated dense no-caps type="a" @click.stop="openCreditsDialog") Buy more credits | ||
// div | ||
q-btn( | ||
no-caps | ||
|
@@ -120,13 +128,15 @@ q-card(bordered flat) | |
|
||
<script> | ||
import EmailProviderForm from 'components/EmailProviderForm.vue'; | ||
import CreditPurchaseDialog from 'components/CreditPurchaseDialog.vue'; | ||
import { ref, onMounted, watch, toRef } from 'vue'; | ||
import { fetchProvider } from 'boot/providers'; | ||
import { handleAction } from 'boot/helpers'; | ||
export default { | ||
name: 'SettingsEmail', | ||
components: { | ||
CreditPurchaseDialog, | ||
EmailProviderForm, | ||
}, | ||
setup () { | ||
|
@@ -137,6 +147,7 @@ export default { | |
// actions | ||
const createDialog = ref(false); | ||
const creditsDialog = ref(false); | ||
const onCreateBtnClick = () => { | ||
createDialog.value = true; | ||
}; | ||
|
@@ -161,13 +172,21 @@ export default { | |
}); | ||
onMounted(() => { | ||
console.warn('DATASET-PROVIDER', dataset.provider) | ||
if (dataset.provider.backend !== 'system') { | ||
selected.value = 'custom_provider'; | ||
} else { | ||
selected.value = 'system'; | ||
} | ||
}) | ||
const openCreditsDialog = () => { | ||
creditsDialog.value = true; | ||
} | ||
const processPurchase = (creditsForPurchase) => { | ||
const topupProvider = dataset.topupProvider; | ||
topupProvider('email', creditsForPurchase.value); | ||
} | ||
return { | ||
loading: dataset.loading, | ||
|
@@ -176,11 +195,14 @@ export default { | |
selected, | ||
createDialog, | ||
creditsDialog, | ||
onCreateBtnClick, | ||
onEditBtnClick, | ||
onCreateCancel, | ||
onCreate, | ||
onDelete, | ||
openCreditsDialog, | ||
processPurchase, | ||
}; | ||
}, | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters