v1.7 beta.8

This commit is contained in:
carodej
2020-07-20 08:54:57 +02:00
parent 827b34e1dd
commit 6f95fc2565
17 changed files with 149 additions and 29 deletions

View File

@@ -33,7 +33,7 @@ MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=
MAIL_FROM_ADDRESS="${MAIL_USERNAME}"
MAIL_FROM_NAME="${APP_NAME}"
MAIL_FROM_NAME="${MAIL_USERNAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=

View File

@@ -18,6 +18,14 @@ class WebhookController extends CashierController
*/
public function handleCustomerSubscriptionDeleted($payload)
{
if ($user = $this->getUserByStripeId($payload['data']['object']['customer'])) {
$user->subscriptions->filter(function ($subscription) use ($payload) {
return $subscription->stripe_id === $payload['data']['object']['id'];
})->each(function ($subscription) {
$subscription->markAsCancelled();
});
}
// Get user
$user = User::where('stripe_id', $payload['data']['object']['customer'])->firstOrFail();
@@ -29,4 +37,26 @@ class WebhookController extends CashierController
return $this->successMethod();
}
/**
* Handle Invoice Payment Succeeded
*
* @param $payload
* @return \Symfony\Component\HttpFoundation\Response
*/
public function handleInvoicePaymentSucceeded($payload)
{
// Get user
$user = User::where('stripe_id', $payload['data']['object']['customer'])->firstOrFail();
// Get requested plan
$plan = $this->stripe->getPlan($user->subscription('main')->stripe_plan);
// Update user storage limit
$user->settings()->update([
'storage_capacity' => $plan['product']['metadata']['capacity']
]);
return $this->successMethod();
}
}

View File

@@ -25,6 +25,7 @@ class UserResource extends JsonResource
'attributes' => [
'storage_capacity' => $this->settings->storage_capacity,
'subscription' => $this->subscribed('main'),
'incomplete_payment' => $this->hasIncompletePayment('main') ? route('cashier.payment', $this->subscription('main')->latestPayment()->id) : null,
'stripe_customer' => is_null($this->stripe_id) ? false : true,
'name' => $this->name,
'email' => env('APP_DEMO') ? obfuscate_email($this->email) : $this->email,

View File

@@ -31,8 +31,8 @@ class UserSubscription extends JsonResource
'id' => $subscription['plan']['id'],
'type' => 'subscription',
'attributes' => [
/*'is_highest' => is_highest_plan($this->plan),*/
'active' => $subscription['plan']['active'],
'incomplete' => $this->subscription('main')->incomplete(),
'active' => $this->subscription('main')->active(),
'canceled' => $this->subscription('main')->cancelled(),
'name' => $subscription['product']['name'],
'capacity' => (int)$subscription['product']['metadata']['capacity'],

View File

@@ -8,6 +8,7 @@ use Artisan;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Laravel\Cashier\Exceptions\IncompletePayment;
use Laravel\Cashier\Exceptions\PaymentActionRequired;
use Stripe;
use Symfony\Component\HttpKernel\Exception\HttpException;
@@ -116,6 +117,7 @@ class StripeService
* @param $request
* @param $user
* @param $paymentMethod
* @return \Illuminate\Http\RedirectResponse
*/
public function createOrReplaceSubscription($request, $user)
{
@@ -138,7 +140,15 @@ class StripeService
} catch (IncompletePayment $exception) {
throw new HttpException(400, 'We can\'t charge your card');
if ($exception instanceof PaymentActionRequired) {
$cashier_route = route('cashier.payment', [$exception->payment->id, 'redirect' => url('/settings/subscription')]);
throw new HttpException(402, $cashier_route);
} else {
throw new HttpException(400, $exception->getMessage());
}
}
}

2
public/js/main.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -23,7 +23,7 @@
{{ $t('page_index.menu.log_in') }}
</router-link>
</li>
<li>
<li v-if="config.userRegistration">
<router-link class="cta-button" :to="{name: 'SignUp'}">
{{ $t('page_index.menu.sign_in') }}
</router-link>

View File

@@ -28,6 +28,10 @@
p, a {
color: $danger;
}
a {
text-decoration: underline;
}
}
p {

View File

@@ -1,5 +1,6 @@
<template>
<div class="user-avatar" :class="size">
<span v-if="isIncompletePayment || isNearlyFullStorageCapacity" class="notification"></span>
<img :src="user.data.attributes.avatar" :alt="user.data.attributes.name">
</div>
</template>
@@ -14,6 +15,12 @@
],
computed: {
...mapGetters(['user']),
isIncompletePayment() {
return this.user.data.attributes.incomplete_payment
},
isNearlyFullStorageCapacity() {
return this.config.storageLimit && this.user.relationships.storage.data.attributes.used > 95
}
},
}
</script>
@@ -24,6 +31,22 @@
.user-avatar {
line-height: 0;
position: relative;
width: 40px;
margin: 0 auto;
.notification {
width: 12px;
height: 12px;
display: block;
position: absolute;
bottom: -5px;
right: -4px;
border-radius: 10px;
z-index: 2;
background: $red;
border: 2px solid $light_background;
}
img {
border-radius: 6px;
@@ -32,6 +55,8 @@
}
&.large {
margin: 0;
width: 54px;
img {
border-radius: 9px;
@@ -42,6 +67,11 @@
}
@media (prefers-color-scheme: dark) {
.user-avatar {
.notification {
border-color: $dark_mode_foreground;
}
}
}
</style>

View File

@@ -297,6 +297,7 @@
"item_counts": "{count} 个文件 | {count} 个文件"
},
"global": {
"incomplete": "Incomplete",
"active": "活性",
"admin": "管理员",
"cancel": "取消",
@@ -671,6 +672,10 @@
"description": "You nearly reach your storage capacity.",
"title": "You reach your storage capacity. Please upgrade."
},
"incomplete_payment": {
"description": "Your latest payment is incomplete. {0}",
"href": "Please confirm your payment."
},
"uploading": {
"progress": "上传文件 {current}/{total}"
},

View File

@@ -297,6 +297,7 @@
"item_counts": "{count} Item | {count} Items"
},
"global": {
"incomplete": "Incomplete",
"active": "Active",
"admin": "Admin",
"cancel": "Cancel",
@@ -671,6 +672,10 @@
"description": "You nearly reach your storage capacity.",
"title": "You reach your storage capacity. Please upgrade."
},
"incomplete_payment": {
"description": "Your latest payment is incomplete. {0}",
"href": "Please confirm your payment."
},
"uploading": {
"progress": "Uploading files {current}/{total}"
},

View File

@@ -297,6 +297,7 @@
"item_counts": "{count} Položka | {count} Položky"
},
"global": {
"incomplete": "Incomplete",
"active": "Aktívny",
"admin": "Admin",
"cancel": "Zrušiť",
@@ -671,6 +672,10 @@
"description": "Takmer ste dosiahli kapacitu úložiska",
"title": "Dosiahli ste kapacitu úložiska. Prosím inovujte úložisko."
},
"incomplete_payment": {
"description": "Vaša posledná platba nie je dokončená. {0}",
"href": "Prosím potvrďte Vašu platbu."
},
"uploading": {
"progress": "Nahrávam súbory {current}/{total}"
},

View File

@@ -91,7 +91,7 @@
<span class="email">{{ user.data.attributes.email }}</span>
</div>
</div>
<div v-if="config.storageLimit && config.isSaaS && config.app_payments_active" class="headline-actions">
<div v-if="config.storageLimit && config.isSaaS && config.app_payments_active && !canShowIncompletePayment" class="headline-actions">
<router-link :to="{name: 'UpgradePlan'}" v-if="canShowUpgradeButton">
<ButtonBase class="upgrade-button" button-style="secondary" type="button">
{{ $t('global.upgrade_plan') }}
@@ -100,7 +100,15 @@
</div>
</div>
<InfoBox v-if="canShowUpgradeWarning" type="error" class="upgrade-box">
<!--Incomplete Payment Warning-->
<InfoBox v-if="canShowIncompletePayment" type="error" class="message-box">
<i18n path="incomplete_payment.description" tag="p">
<a :href="user.data.attributes.incomplete_payment">{{ $t('incomplete_payment.href') }}</a>
</i18n>
</InfoBox>
<!--Upgrade Storage Plan Warning-->
<InfoBox v-if="canShowUpgradeWarning && !canShowIncompletePayment" type="error" class="message-box">
<p>{{ $t('upgrade_banner.title') }}</p>
</InfoBox>
@@ -171,6 +179,9 @@
},
canShowUpgradeWarning() {
return this.config.storageLimit && this.user.relationships.storage.data.attributes.used > 95
},
canShowIncompletePayment() {
return this.user.data.attributes.incomplete_payment
}
},
data() {
@@ -226,8 +237,8 @@
}
}
.upgrade-box {
margin-top: -30px;
.message-box {
margin-top: -15px;
}
@media (prefers-color-scheme: dark) {

View File

@@ -305,9 +305,6 @@
// Update user data
this.$store.dispatch('getAppData')
// End loading
this.isSubmitted = false
// Show toaster
events.$emit('toaster', {
type: 'success',
@@ -319,13 +316,16 @@
},
errorOrder(error) {
if (error.response.status = 402) {
// Redirect user to confirmation payment page
if (error.response.status === 402) {
window.location.href = error.response.data.message;
}
// Show user error message
if (error.response.status === 400) {
this.isError = true
this.errorMessage = error.response.data.message
}
// End loading
this.isSubmitted = false
},
async submitOrder() {
@@ -375,6 +375,9 @@
})
.then(() => this.successOrder())
.catch((error) => this.errorOrder(error))
.finally(() => {
this.isSubmitted = false
})
}
}
@@ -391,6 +394,9 @@
})
.then(() => this.successOrder())
.catch((error) => this.errorOrder(error))
.finally(() => {
this.isSubmitted = false
})
}
},
},

View File

@@ -2,14 +2,16 @@
<div id="single-page">
<div id="page-content" class="large-width center-page" v-show="! isLoading">
<MobileHeader :title="$router.currentRoute.meta.title"/>
<div class="content-page">
<!--Page Title-->
<div class="plan-title">
<cloud-icon size="42" class="title-icon"></cloud-icon>
<h1>{{ $t('page_pricing_tables.title') }}</h1>
<h2>{{ $t('page_pricing_tables.description') }}</h2>
</div>
<!--Pricing Tables-->
<PlanPricingTables @load="onLoadPricingTables" @selected-plan="onSelectTable"/>
</div>
</div>
@@ -55,6 +57,10 @@
StripeElementsScript.setAttribute('src', 'https://js.stripe.com/v3/')
document.head.appendChild(StripeElementsScript)
},
mounted() {
// Reload user data
this.$store.dispatch('getAppData')
}
}
</script>

View File

@@ -92,6 +92,9 @@
return this.isConfirmedResume ? 'theme-solid' : 'secondary'
},
status() {
if (this.subscription.data.attributes.incomplete) {
return this.$t('global.incomplete')
}
if (this.subscription.data.attributes.canceled) {
return this.$t('global.canceled')
}

View File

@@ -34,7 +34,11 @@
<div id="invoice-wrapper">
<header class="invoice-header">
<div class="logo">
<img src="/assets/images/vuefilemanager-horizontal-logo.svg" alt="VueFileManager">
@if(isset($settings->app_logo_horizontal))
<img src="{{ url($settings->app_logo_horizontal) }}" alt="{{ $settings->app_title ?? 'VueFileManager' }}">
@else
<h1>{{ $settings->app_title ?? 'VueFileManager' }}</h1>
@endif
</div>
<div class="title">
<h1>@lang('vuefilemanager.invoice_title')</h1>