upgrade subscription popup

This commit is contained in:
Čarodej
2022-03-04 11:35:38 +01:00
parent 6155173d82
commit 0f4b80ddac
34 changed files with 269 additions and 67 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
public/js/main.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -14,7 +14,7 @@
/>
<div
v-else
class="flex items-center justify-center"
class="flex items-center justify-center mx-auto"
:class="[
borderRadius,
{

View File

@@ -79,7 +79,7 @@ import paystack from 'vue-paystack'
import { mapGetters } from 'vuex'
export default {
name: 'SelectSingleChargeMethodPopup',
name: 'ChargePaymentPopup',
components: {
PaymentMethod,
PopupWrapper,
@@ -175,15 +175,3 @@ export default {
},
}
</script>
<style lang="scss" scoped>
@import '../../../sass/vuefilemanager/variables';
@import '../../../sass/vuefilemanager/mixins';
.mobile-actions {
white-space: nowrap;
overflow-x: auto;
margin: 0 -20px;
padding: 10px 0 10px 20px;
}
</style>

View File

@@ -0,0 +1,183 @@
<template>
<PopupWrapper name="change-plan-subscription">
<PopupHeader :title="$t('Change Your Plan')" icon="credit-card" />
<!--Select Payment Plans-->
<PopupContent v-if="plans">
<InfoBox v-if="plans.data.length === 0" class="!mb-0">
<p>There isn't any plan yet.</p>
</InfoBox>
<!--Toggle yearly billing-->
<PlanPeriodSwitcher v-if="yearlyPlans.length > 0" v-model="isSelectedYearlyPlans" />
<!--List available plans-->
<div>
<PlanDetail
v-for="(plan, i) in plans.data"
:plan="plan"
:key="plan.data.id"
v-if="plan.data.attributes.interval === intervalPlanType"
:class="{'opacity-50 pointer-events-none': userSubscribedPlanId === plan.data.id}"
:is-selected="selectedPlan && selectedPlan.data.id === plan.data.id"
@click.native="selectPlan(plan)"
/>
</div>
</PopupContent>
<!--Actions-->
<PopupActions>
<ButtonBase class="w-full" @click.native="$closePopup()" button-style="secondary"
>{{ $t('popup_move_item.cancel') }}
</ButtonBase>
<ButtonBase
class="w-full"
v-if="plans && plans.data.length !== 0"
:button-style="buttonStyle"
:loading="isLoading"
@click.native="proceedToPayment"
>{{ $t('Change Plan') }}
</ButtonBase>
</PopupActions>
</PopupWrapper>
</template>
<script>
import PaymentMethod from '../Others/PaymentMethod'
import {loadScript} from '@paypal/paypal-js'
import PopupWrapper from '../Others/Popup/PopupWrapper'
import PopupActions from '../Others/Popup/PopupActions'
import PopupContent from '../Others/Popup/PopupContent'
import PopupHeader from '../Others/Popup/PopupHeader'
import ButtonBase from '../FilesView/ButtonBase'
import PlanDetail from './PlanDetail'
import paystack from 'vue-paystack'
import {mapGetters} from 'vuex'
import {events} from '../../bus'
import axios from 'axios'
import Spinner from '../FilesView/Spinner'
import InfoBox from '../Others/Forms/InfoBox'
import PlanPeriodSwitcher from "./PlanPeriodSwitcher";
export default {
name: 'ChangeSubscriptionPopup',
components: {
PlanPeriodSwitcher,
InfoBox,
Spinner,
PaymentMethod,
paystack,
PlanDetail,
PopupWrapper,
PopupActions,
PopupContent,
PopupHeader,
ButtonBase,
},
watch: {
isSelectedYearlyPlans() {
this.selectedPlan = undefined
},
},
computed: {
...mapGetters(['config', 'user']),
intervalPlanType() {
return this.isSelectedYearlyPlans ? 'year' : 'month'
},
buttonStyle() {
return this.selectedPlan ? 'theme' : 'secondary'
},
userSubscribedPlanId() {
return (
this.user &&
this.user.data.relationships.subscription &&
this.user.data.relationships.subscription.data.relationships.plan.data.id
)
},
yearlyPlans() {
return this.plans.data.filter((plan) => plan.data.attributes.interval === 'year')
},
subscriptionDriver() {
return this.user.data.relationships.subscription.data.attributes.driver
}
},
data() {
return {
stripe: {
isGettingCheckoutLink: false,
},
paypal: {
isMethodsLoaded: false,
isMethodLoading: false,
},
isPaymentOptionPage: false,
isSelectedYearlyPlans: false,
isLoading: false,
selectedPlan: undefined,
plans: undefined,
}
},
methods: {
proceedToPayment() {
// Start button spinner
this.isLoading = true
if (this.subscriptionDriver === 'stripe') {
this.payByStripe()
}
if (this.subscriptionDriver === 'paypal') {
this.payByPayPal()
}
if (this.subscriptionDriver === 'paystack') {
this.payByPaystack()
}
},
payByPayPal() {
axios.post(`/api/subscriptions/swap/${this.selectedPlan.data.id}`)
.then((response) => {
console.log(response.data.links[0].href);
//window.location = response.data.links[0].href
})
},
payByStripe() {
axios
.post('/api/stripe/checkout', {
planCode: this.selectedPlan.data.meta.driver_plan_id.stripe,
})
.then((response) => {
window.location = response.data.url
})
},
payByPaystack() {
axios
.post('/api/paystack/checkout', {
planCode: this.selectedPlan.data.meta.driver_plan_id.stripe,
})
.then((response) => {
console.log(response.data.data.authorization_url);
//window.location = response.data.data.authorization_url
})
},
selectPlan(plan) {
this.selectedPlan = plan
},
},
created() {
// Load available plans
axios.get('/api/subscriptions/plans').then((response) => {
this.plans = response.data
})
// Reset states on popup close
events.$on('popup:close', () => {
this.isSelectedYearlyPlans = false
this.isPaymentOptionPage = false
this.selectedPlan = undefined
this.paypal.isMethodsLoaded = false
})
},
}
</script>

View File

@@ -0,0 +1,37 @@
<template>
<div class="mb-2 text-right">
<label
:class="{ 'text-gray-400': !isSelectedYearlyPlans }"
class="cursor-pointer text-xs font-bold"
>
{{ $t('Billed Annually') }}
</label>
<div class="relative inline-block w-12 select-none align-middle">
<SwitchInput
class="scale-75 transform"
v-model="isSelectedYearlyPlans"
:state="isSelectedYearlyPlans"
/>
</div>
</div>
</template>
<script>
import SwitchInput from '../Others/Forms/SwitchInput'
export default {
name: 'PlanPeriodSwitcher',
components: {
SwitchInput
},
watch: {
'isSelectedYearlyPlans': function () {
this.$emit('input', this.isSelectedYearlyPlans)
}
},
data() {
return {
isSelectedYearlyPlans: false
}
}
}
</script>

View File

@@ -61,7 +61,7 @@
v-if="user && config"
:channels="['bank', 'ussd', 'qr', 'mobile_money', 'bank_transfer']"
class="font-bold"
currency="ZAR"
:currency="config.isDev ? 'ZAR' : selectedPlan.data.attributes.currency"
:plan="selectedPlan.data.meta.driver_plan_id.paystack"
:amount="selectedPlan.data.attributes.amount * 100"
:email="user.data.attributes.email"
@@ -91,22 +91,7 @@
<p>There isn't any plan yet.</p>
</InfoBox>
<!--Toggle yearly billing-->
<div v-if="hasYearlyPlans.length > 0" class="mb-2 text-right">
<label
:class="{ 'text-gray-400': !isSelectedYearlyPlans }"
class="cursor-pointer text-xs font-bold"
>
{{ $t('Billed Annually') }}
</label>
<div class="relative inline-block w-12 select-none align-middle">
<SwitchInput
class="scale-75 transform"
v-model="isSelectedYearlyPlans"
:state="isSelectedYearlyPlans"
/>
</div>
</div>
<PlanPeriodSwitcher v-if="yearlyPlans.length > 0" v-model="isSelectedYearlyPlans" />
<!--List available plans-->
<div>
@@ -155,10 +140,12 @@ import { events } from '../../bus'
import axios from 'axios'
import Spinner from '../FilesView/Spinner'
import InfoBox from '../Others/Forms/InfoBox'
import PlanPeriodSwitcher from "./PlanPeriodSwitcher"
export default {
name: 'SelectPlanSubscriptionPopup',
name: 'SubscribeAccountPopup',
components: {
PlanPeriodSwitcher,
InfoBox,
Spinner,
PaymentMethod,
@@ -191,7 +178,7 @@ export default {
this.user.data.relationships.subscription.data.relationships.plan.data.id
)
},
hasYearlyPlans() {
yearlyPlans() {
return this.plans.data.filter((plan) => plan.data.attributes.interval === 'year')
},
},

View File

@@ -28,7 +28,7 @@
:description="$t('You can upgrade your plan at any time you want.')"
:is-last="true"
>
<ButtonBase @click.native="$openUpgradeOptions" class="w-full sm:w-auto" button-style="secondary">
<ButtonBase @click.native="$changeSubscriptionOptions" class="w-full sm:w-auto" button-style="secondary">
{{ $t('Change Plan') }}
</ButtonBase>
</AppInputButton>

View File

@@ -14,7 +14,7 @@
<ButtonBase
v-if="$store.getters.config.allowed_payments"
@click.native="$openUpgradeOptions"
@click.native="$openSubscribeOptions"
type="submit"
button-style="theme"
class="mt-4 w-full"

View File

@@ -559,9 +559,13 @@ const FunctionHelpers = {
events.$emit('mobile-menu:show', name)
}
Vue.prototype.$openUpgradeOptions = function () {
Vue.prototype.$openSubscribeOptions = function () {
events.$emit('popup:open', { name: 'select-plan-subscription' })
}
Vue.prototype.$changeSubscriptionOptions = function () {
events.$emit('popup:open', { name: 'change-plan-subscription' })
}
},
}

View File

@@ -20,8 +20,9 @@
<CreatePersonalTokenPopup />
<!--Payments Popup-->
<SelectPlanSubscriptionPopup v-if="config.subscriptionType === 'fixed'" />
<SelectSingleChargeMethodPopup v-if="config.subscriptionType === 'metered'" />
<SubscribeAccountPopup v-if="config.subscriptionType === 'fixed'" />
<ChangeSubscriptionPopup v-if="config.subscriptionType === 'fixed'" />
<ChargePaymentPopup v-if="config.subscriptionType === 'metered'" />
<SidebarNavigation />
@@ -75,8 +76,8 @@
<script>
import MobileNavigation from '../components/Others/MobileNavigation'
import SelectSingleChargeMethodPopup from '../components/Others/SelectSingleChargeMethodPopup'
import SelectPlanSubscriptionPopup from '../components/Subscription/SelectPlanSubscriptionPopup'
import ChargePaymentPopup from '../components/Others/ChargePaymentPopup'
import SubscribeAccountPopup from '../components/Subscription/SubscribeAccountPopup'
import ConfirmPopup from '../components/Others/Popup/ConfirmPopup'
import FilePreview from '../components/FilePreview/FilePreview'
import Spotlight from '../components/Spotlight/Spotlight'
@@ -93,17 +94,19 @@ import ConfirmPassword from '../components/Others/ConfirmPassword'
import MobileNavigationToolbar from '../components/Mobile/MobileNavigationToolbar'
import CreateUploadRequestPopup from "../components/Others/CreateUploadRequestPopup";
import CreateTeamFolderPopup from "../components/Teams/CreateTeamFolderPopup";
import ChangeSubscriptionPopup from "../components/Subscription/ChangeSubscriptionPopup";
export default {
name: 'Settings',
components: {
ChangeSubscriptionPopup,
CreateTeamFolderPopup,
CreateUploadRequestPopup,
MobileNavigationToolbar,
MobileNavigation,
ConfirmPassword,
SelectSingleChargeMethodPopup,
SelectPlanSubscriptionPopup,
ChargePaymentPopup,
SubscribeAccountPopup,
ConfirmPopup,
CardNavigation,
FilePreview,

View File

@@ -768,7 +768,7 @@ if (! function_exists('is_dev')) {
*/
function is_dev()
{
return env('APP_ENV') === 'local';
return config('app.env') === 'local';
}
}