mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 05:02:36 +01:00
- Bundle qty without ability to increment/decrement value ✅
- One time & subs ✅ - A table with all products included in subscription (qty, price, notes) ✅ - Two tables, one for subscriptions, one for one-time purchases ✅ - If no products, no table ✅ - Remove quantity from cached data that is being sent ✅ - Remove "billing_subscription_id" from data sent ✅
This commit is contained in:
parent
0173d0fe46
commit
ed4fff2385
@ -139,13 +139,6 @@ class BillingPortalPurchase extends Component
|
|||||||
*/
|
*/
|
||||||
public $request_data;
|
public $request_data;
|
||||||
|
|
||||||
/**
|
|
||||||
* Price of product.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $price;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle user authentication
|
* Handle user authentication
|
||||||
*
|
*
|
||||||
@ -291,8 +284,6 @@ class BillingPortalPurchase extends Component
|
|||||||
'email' => $this->email ?? $this->contact->email,
|
'email' => $this->email ?? $this->contact->email,
|
||||||
'client_id' => $this->contact->client->id,
|
'client_id' => $this->contact->client->id,
|
||||||
'invoice_id' => $this->invoice->id,
|
'invoice_id' => $this->invoice->id,
|
||||||
'quantity' => $this->quantity,
|
|
||||||
'subscription_id' => $this->subscription->id,
|
|
||||||
now()->addMinutes(60)]
|
now()->addMinutes(60)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ class Subscription extends BaseModel
|
|||||||
'deleted_at' => 'timestamp',
|
'deleted_at' => 'timestamp',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function service()
|
public function service(): SubscriptionService
|
||||||
{
|
{
|
||||||
return new SubscriptionService($this);
|
return new SubscriptionService($this);
|
||||||
}
|
}
|
||||||
@ -68,9 +68,4 @@ class Subscription extends BaseModel
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(User::class);
|
return $this->belongsTo(User::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function product(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Product::class);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
2
public/css/app.css
vendored
2
public/css/app.css
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"/js/app.js": "/js/app.js?id=696e8203d5e8e7cf5ff5",
|
"/js/app.js": "/js/app.js?id=696e8203d5e8e7cf5ff5",
|
||||||
"/css/app.css": "/css/app.css?id=1481aa442df903f3c38b",
|
"/css/app.css": "/css/app.css?id=9525909664b98602bd2a",
|
||||||
"/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=a09bb529b8e1826f13b4",
|
"/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=a09bb529b8e1826f13b4",
|
||||||
"/js/clients/invoices/payment.js": "/js/clients/invoices/payment.js?id=8ce8955ba775ea5f47d1",
|
"/js/clients/invoices/payment.js": "/js/clients/invoices/payment.js?id=8ce8955ba775ea5f47d1",
|
||||||
"/js/clients/linkify-urls.js": "/js/clients/linkify-urls.js?id=0dc8c34010d09195d2f7",
|
"/js/clients/linkify-urls.js": "/js/clients/linkify-urls.js?id=0dc8c34010d09195d2f7",
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
@extends('portal.ninja2020.layout.clean')
|
@extends('portal.ninja2020.layout.clean')
|
||||||
@section('meta_title', $billing_subscription->product->product_key)
|
@section('meta_title', ctrans('texts.purchase'))
|
||||||
|
|
||||||
@section('body')
|
@section('body')
|
||||||
@livewire('billing-portal-purchase', ['billing_subscription' => $billing_subscription, 'contact' => auth('contact')->user(), 'hash' => $hash, 'request_data' => $request_data, 'price' => $billing_subscription->product->price])
|
@livewire('billing-portal-purchase', ['subscription' => $subscription, 'contact' => auth('contact')->user(), 'hash' => $hash, 'request_data' => $request_data])
|
||||||
@stop
|
@stop
|
||||||
|
|
||||||
@push('footer')
|
@push('footer')
|
||||||
|
@ -1,48 +1,79 @@
|
|||||||
<div class="grid grid-cols-12">
|
<div class="grid grid-cols-12">
|
||||||
<div class="col-span-12 lg:col-span-6 bg-gray-50 shadow-lg lg:h-screen flex flex-col items-center">
|
<div class="col-span-12 lg:col-span-6 bg-gray-50 flex flex-col items-center">
|
||||||
<div class="w-full p-10 lg:w-1/2 lg:mt-48 lg:p-0">
|
<div class="w-full p-10 lg:w-1/2 lg:mt-24 lg:p-0">
|
||||||
<img class="h-8" src="{{ $billing_subscription->company->present()->logo }}"
|
<img class="h-8" src="{{ $subscription->company->present()->logo }}"
|
||||||
alt="{{ $billing_subscription->company->present()->name }}">
|
alt="{{ $subscription->company->present()->name }}">
|
||||||
|
|
||||||
<h1 id="billing-page-company-logo" class="text-3xl font-bold tracking-wide mt-8">
|
<div class="mt-6">
|
||||||
{{ $billing_subscription->product->product_key }}
|
<p
|
||||||
|
class="mb-4 uppercase leading-4 tracking-wide inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-primary text-white">
|
||||||
|
Subscription
|
||||||
|
</p>
|
||||||
|
<h1 id="billing-page-company-logo" class="text-3xl font-bold tracking-wide">
|
||||||
|
Invoice Ninja Pro+
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p class="my-6">{{ $billing_subscription->product->notes }}</p>
|
|
||||||
|
|
||||||
<span class="text-sm uppercase font-bold">{{ ctrans('texts.price') }}:</span>
|
|
||||||
|
|
||||||
<div class="flex space-x-2">
|
|
||||||
<h1 class="text-2xl font-bold tracking-wide">{{ App\Utils\Number::formatMoney($price, $billing_subscription->company) }}</h1>
|
|
||||||
|
|
||||||
@if($billing_subscription->is_recurring)
|
|
||||||
<span class="text-xs uppercase">/ {{ \App\Models\RecurringInvoice::frequencyForKey($billing_subscription->frequency_id) }}</span>
|
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if(!empty($subscription->product_ids))
|
||||||
|
<div class="flex flex-col mt-8">
|
||||||
|
<span
|
||||||
|
class="mb-4 uppercase leading-4 tracking-wide inline-flex items-center rounded-full text-xs font-medium">
|
||||||
|
One-time purchases:
|
||||||
|
</span>
|
||||||
|
|
||||||
@if($billing_subscription->per_seat_enabled && $billing_subscription->max_seats_limit > 1)
|
<div class="flex items-center justify-between mb-4 bg-white rounded px-6 py-4 shadow-sm border">
|
||||||
<div class="flex mt-4 space-x-4 items-center">
|
<div class="text-sm">Pro+ plan</div>
|
||||||
<span class="text-sm">{{ ctrans('texts.qty') }}</span>
|
<div data-ref="price-and-quantity-container">
|
||||||
<button wire:click="updateQuantity('decrement')" class="bg-gray-100 border rounded p-1">
|
<span data-ref="price">$10</span>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none"
|
<span data-ref="quantity" class="text-sm">(1x)</span>
|
||||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
</div>
|
||||||
class="feather feather-minus">
|
</div>
|
||||||
<line x1="5" y1="12" x2="19" y2="12"></line>
|
<div class="flex items-center justify-between mb-4 bg-white rounded px-6 py-4 shadow-sm border">
|
||||||
</svg>
|
<div class="text-sm">Another awesome product</div>
|
||||||
</button>
|
<div data-ref="price-and-quantity-container">
|
||||||
<button>{{ $quantity }}</button>
|
<span data-ref="price">$5</span>
|
||||||
<button wire:click="updateQuantity('increment')" class="bg-gray-100 border rounded p-1">
|
<span data-ref="quantity" class="text-sm">(2x)</span>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none"
|
</div>
|
||||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
</div>
|
||||||
class="feather feather-plus">
|
|
||||||
<line x1="12" y1="5" x2="12" y2="19"></line>
|
|
||||||
<line x1="5" y1="12" x2="19" y2="12"></line>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
@if(!empty($subscription->recurring_product_ids))
|
||||||
|
<div class="flex flex-col mt-8">
|
||||||
|
<span
|
||||||
|
class="mb-4 uppercase leading-4 tracking-wide inline-flex items-center rounded-full text-xs font-medium">
|
||||||
|
Recurring purchases:
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between mb-4 bg-white rounded px-6 py-4 shadow-sm border">
|
||||||
|
<div class="text-sm">Pro+ plan</div>
|
||||||
|
<div data-ref="price-and-quantity-container">
|
||||||
|
<span data-ref="price">$10</span>
|
||||||
|
<span data-ref="quantity" class="text-sm">(1x)</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between mb-4 bg-white rounded px-6 py-4 shadow-sm border">
|
||||||
|
<div class="text-sm">Another awesome product</div>
|
||||||
|
<div data-ref="price-and-quantity-container">
|
||||||
|
<span data-ref="price">$5</span>
|
||||||
|
<span data-ref="quantity" class="text-sm">(2x)</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="relative mt-8">
|
||||||
|
<div class="absolute inset-0 flex items-center">
|
||||||
|
<div class="w-full border-t border-gray-300"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="relative flex justify-center text-sm leading-5">
|
||||||
|
<h1 class="text-2xl font-bold tracking-wide bg-gray-50 px-6 py-0">
|
||||||
|
{{ ctrans('texts.total') }}: {{ App\Utils\Number::formatMoney(20, $subscription->company) }}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
@if(auth('contact')->user())
|
@if(auth('contact')->user())
|
||||||
<a href="{{ route('client.invoices.index') }}" class="block mt-16 inline-flex items-center space-x-2">
|
<a href="{{ route('client.invoices.index') }}" class="block mt-16 inline-flex items-center space-x-2">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"
|
||||||
@ -58,7 +89,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-span-12 lg:col-span-6 bg-white lg:shadow-lg lg:h-screen">
|
<div class="col-span-12 lg:col-span-6 bg-white lg:h-screen">
|
||||||
<div class="grid grid-cols-12 flex flex-col p-10 lg:mt-48 lg:ml-16">
|
<div class="grid grid-cols-12 flex flex-col p-10 lg:mt-48 lg:ml-16">
|
||||||
<div class="col-span-12 w-full lg:col-span-6">
|
<div class="col-span-12 w-full lg:col-span-6">
|
||||||
<h2 class="text-2xl font-bold tracking-wide">{{ $heading_text ?? ctrans('texts.login') }}</h2>
|
<h2 class="text-2xl font-bold tracking-wide">{{ $heading_text ?? ctrans('texts.login') }}</h2>
|
||||||
@ -140,7 +171,7 @@
|
|||||||
</form>
|
</form>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if(!empty($billing_subscription->promo_code) && !$billing_subscription->trial_enabled)
|
@if(!empty($subscription->promo_code) && !$subscription->trial_enabled)
|
||||||
<div class="relative mt-8">
|
<div class="relative mt-8">
|
||||||
<div class="absolute inset-0 flex items-center">
|
<div class="absolute inset-0 flex items-center">
|
||||||
<div class="w-full border-t border-gray-300"></div>
|
<div class="w-full border-t border-gray-300"></div>
|
||||||
|
@ -76,7 +76,7 @@ Route::group(['middleware' => ['auth:contact', 'locale', 'check_client_existence
|
|||||||
Route::get('logout', 'Auth\ContactLoginController@logout')->name('logout');
|
Route::get('logout', 'Auth\ContactLoginController@logout')->name('logout');
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::get('client/subscription/{billing_subscription}/purchase', 'ClientPortal\BillingSubscriptionPurchaseController@index')->name('client.subscription.purchase');
|
Route::get('client/subscription/{subscription}/purchase', 'ClientPortal\SubscriptionPurchaseController@index')->name('client.subscription.purchase');
|
||||||
|
|
||||||
Route::group(['middleware' => ['invite_db'], 'prefix' => 'client', 'as' => 'client.'], function () {
|
Route::group(['middleware' => ['invite_db'], 'prefix' => 'client', 'as' => 'client.'], function () {
|
||||||
/*Invitation catches*/
|
/*Invitation catches*/
|
||||||
|
3
tailwind.config.js
vendored
3
tailwind.config.js
vendored
@ -1,6 +1,9 @@
|
|||||||
const defaultTheme = require("tailwindcss/defaultTheme");
|
const defaultTheme = require("tailwindcss/defaultTheme");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
future: {
|
||||||
|
purgeLayersByDefault: true
|
||||||
|
},
|
||||||
purge: [
|
purge: [
|
||||||
'./resources/views/portal/ninja2020/**/*.blade.php',
|
'./resources/views/portal/ninja2020/**/*.blade.php',
|
||||||
'./resources/views/email/template/**/*.blade.php',
|
'./resources/views/email/template/**/*.blade.php',
|
||||||
|
Loading…
Reference in New Issue
Block a user