mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-18 08:12:15 +00:00
frontend/backend update
This commit is contained in:
@@ -63,10 +63,11 @@ class UpgradeApp extends Command
|
|||||||
|
|
||||||
// Migrate new tables and changes
|
// Migrate new tables and changes
|
||||||
$this->call('migrate');
|
$this->call('migrate');
|
||||||
|
$this->call('rinvex:migrate:subscriptions');
|
||||||
|
|
||||||
$this->call('db:seed', [
|
/*$this->call('db:seed', [
|
||||||
'--class' => 'PaymentGatewaysSeeder'
|
'--class' => 'PaymentGatewaysSeeder'
|
||||||
]);
|
]);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Exceptions;
|
namespace App\Exceptions;
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
class Handler extends ExceptionHandler
|
class Handler extends ExceptionHandler
|
||||||
{
|
{
|
||||||
@@ -29,12 +29,12 @@ class Handler extends ExceptionHandler
|
|||||||
/**
|
/**
|
||||||
* Report or log an exception.
|
* Report or log an exception.
|
||||||
*
|
*
|
||||||
* @param \Exception $exception
|
* @param \Throwable $exception
|
||||||
* @return void
|
* @return void
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function report(Exception $exception)
|
public function report(Throwable $exception)
|
||||||
{
|
{
|
||||||
parent::report($exception);
|
parent::report($exception);
|
||||||
}
|
}
|
||||||
@@ -43,13 +43,13 @@ class Handler extends ExceptionHandler
|
|||||||
* Render an exception into an HTTP response.
|
* Render an exception into an HTTP response.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @param \Exception $exception
|
* @param \Throwable $exception
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function render($request, Exception $exception)
|
public function render($request, Throwable $exception)
|
||||||
{
|
{
|
||||||
return parent::render($request, $exception);
|
return parent::render($request, $exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,8 +5,12 @@ namespace App\Http\Controllers\Admin;
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Resources\PlanCollection;
|
use App\Http\Resources\PlanCollection;
|
||||||
use App\Http\Resources\PlanResource;
|
use App\Http\Resources\PlanResource;
|
||||||
|
use App\Http\Resources\UserResource;
|
||||||
|
use App\Http\Resources\UsersCollection;
|
||||||
use App\Plan;
|
use App\Plan;
|
||||||
|
use App\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Rinvex\Subscriptions\Models\PlanFeature;
|
||||||
|
|
||||||
class PlanController extends Controller
|
class PlanController extends Controller
|
||||||
{
|
{
|
||||||
@@ -15,9 +19,11 @@ class PlanController extends Controller
|
|||||||
*
|
*
|
||||||
* @return PlanCollection
|
* @return PlanCollection
|
||||||
*/
|
*/
|
||||||
public function index() {
|
public function index()
|
||||||
|
{
|
||||||
return new PlanCollection(Plan::all());
|
return new PlanCollection(
|
||||||
|
app('rinvex.subscriptions.plan')->all()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,9 +34,9 @@ class PlanController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function show($id)
|
public function show($id)
|
||||||
{
|
{
|
||||||
$plan = Plan::findOrFail($id);
|
return new PlanResource(
|
||||||
|
app('rinvex.subscriptions.plan')->find($id)
|
||||||
return new PlanResource($plan);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,9 +47,24 @@ class PlanController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
// TODO: validation request
|
$plan = app('rinvex.subscriptions.plan')->create([
|
||||||
|
'description' => $request->input('attributes.description'),
|
||||||
|
'price' => $request->input('attributes.price'),
|
||||||
|
'name' => $request->input('attributes.name'),
|
||||||
|
'currency' => 'USD',
|
||||||
|
'invoice_period' => 1,
|
||||||
|
'sort_order' => 1,
|
||||||
|
'signup_fee' => 0,
|
||||||
|
]);
|
||||||
|
|
||||||
$plan = Plan::create($request->input('attributes'));
|
// Create multiple plan features at once
|
||||||
|
$plan->features()->saveMany([
|
||||||
|
new PlanFeature([
|
||||||
|
'name' => 'Storage capacity',
|
||||||
|
'value' => $request->input('attributes.capacity'),
|
||||||
|
'sort_order' => 1
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
|
||||||
return new PlanResource($plan);
|
return new PlanResource($plan);
|
||||||
}
|
}
|
||||||
@@ -58,11 +79,32 @@ class PlanController extends Controller
|
|||||||
public function update(Request $request, $id)
|
public function update(Request $request, $id)
|
||||||
{
|
{
|
||||||
// TODO: validation request
|
// TODO: validation request
|
||||||
$plan = Plan::findOrFail($id);
|
$plan = app('rinvex.subscriptions.plan')->find($id);
|
||||||
|
|
||||||
// Update text data
|
if ($request->name === 'capacity') {
|
||||||
$plan->update(make_single_input($request));
|
$plan->getFeatureBySlug('storage-capacity')->update(['value' => $request->value]);
|
||||||
|
} else {
|
||||||
|
$plan->update(make_single_input($request));
|
||||||
|
}
|
||||||
|
|
||||||
return response('Saved!', 204);
|
return response('Saved!', 204);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get subscriptions
|
||||||
|
*
|
||||||
|
* @param $id
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function subscribers($id)
|
||||||
|
{
|
||||||
|
$subscribers = app('rinvex.subscriptions.plan')
|
||||||
|
->find($id)
|
||||||
|
->subscriptions
|
||||||
|
->pluck('user_id');
|
||||||
|
|
||||||
|
return new UsersCollection(
|
||||||
|
User::findMany($subscribers)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ class UserController extends Controller
|
|||||||
|
|
||||||
// Delete thumbnail if exist
|
// Delete thumbnail if exist
|
||||||
if (!is_null($file->thumbnail)) {
|
if (!is_null($file->thumbnail)) {
|
||||||
Storage::delete('/file-manager/' . $file->getOriginal('thumbnail'));
|
Storage::delete('/file-manager/' . $file->getRawOriginal('thumbnail'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete file permanently
|
// Delete file permanently
|
||||||
@@ -232,7 +232,7 @@ class UserController extends Controller
|
|||||||
|
|
||||||
// Remove favourites
|
// Remove favourites
|
||||||
$user->settings->delete();
|
$user->settings->delete();
|
||||||
$user->favourites()->sync([]);
|
$user->favourite_folders()->sync([]);
|
||||||
|
|
||||||
// Delete user
|
// Delete user
|
||||||
$user->delete();
|
$user->delete();
|
||||||
|
|||||||
@@ -206,12 +206,12 @@ class FileAccessController extends Controller
|
|||||||
private function thumbnail_file($file)
|
private function thumbnail_file($file)
|
||||||
{
|
{
|
||||||
// Get file path
|
// Get file path
|
||||||
$path = '/file-manager/' . $file->getOriginal('thumbnail');
|
$path = '/file-manager/' . $file->getRawOriginal('thumbnail');
|
||||||
|
|
||||||
// Check if file exist
|
// Check if file exist
|
||||||
if (!Storage::exists($path)) abort(404);
|
if (!Storage::exists($path)) abort(404);
|
||||||
|
|
||||||
// Return image thumbnail
|
// Return image thumbnail
|
||||||
return Storage::download($path, $file->getOriginal('thumbnail'));
|
return Storage::download($path, $file->getRawOriginal('thumbnail'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ class FavouriteController extends Controller
|
|||||||
if ($folder->user_id !== $user->id) abort(403);
|
if ($folder->user_id !== $user->id) abort(403);
|
||||||
|
|
||||||
// Add folder to user favourites
|
// Add folder to user favourites
|
||||||
$user->favourites()->syncWithoutDetaching($request->unique_id);
|
$user->favourite_folders()->syncWithoutDetaching($request->unique_id);
|
||||||
|
|
||||||
// Return updated favourites
|
// Return updated favourites
|
||||||
return $user->favourites->makeHidden(['pivot']);
|
return $user->favourites;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,9 +61,9 @@ class FavouriteController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove folder from user favourites
|
// Remove folder from user favourites
|
||||||
$user->favourites()->detach($unique_id);
|
$user->favourite_folders()->detach($unique_id);
|
||||||
|
|
||||||
// Return updated favourites
|
// Return updated favourites
|
||||||
return $user->favourites->makeHidden(['pivot']);
|
return $user->favourites;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class TrashController extends Controller
|
|||||||
Storage::delete('/file-manager/' . $file->basename);
|
Storage::delete('/file-manager/' . $file->basename);
|
||||||
|
|
||||||
// Delete thumbnail if exist
|
// Delete thumbnail if exist
|
||||||
if ($file->thumbnail) Storage::delete('/file-manager/' . $file->getOriginal('thumbnail'));
|
if ($file->thumbnail) Storage::delete('/file-manager/' . $file->getRawOriginal('thumbnail'));
|
||||||
|
|
||||||
// Delete file permanently
|
// Delete file permanently
|
||||||
$file->forceDelete();
|
$file->forceDelete();
|
||||||
|
|||||||
22
app/Http/Controllers/General/PricingController.php
Normal file
22
app/Http/Controllers/General/PricingController.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\General;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Resources\PricingCollection;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class PricingController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get all active plans
|
||||||
|
*
|
||||||
|
* @return PricingCollection
|
||||||
|
*/
|
||||||
|
public function index() {
|
||||||
|
|
||||||
|
return new PricingCollection(
|
||||||
|
app('rinvex.subscriptions.plan')->where('is_active', 1)->get()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,9 +28,7 @@ class AccountController extends Controller
|
|||||||
public function user()
|
public function user()
|
||||||
{
|
{
|
||||||
// Get User
|
// Get User
|
||||||
$user = User::with(['favourites'])
|
$user = Auth::user();
|
||||||
->where('id', Auth::id())
|
|
||||||
->first();
|
|
||||||
|
|
||||||
// Get folder tree
|
// Get folder tree
|
||||||
$tree = FileManagerFolder::with(['folders.shared', 'shared:token,id,item_id,permission,protected'])
|
$tree = FileManagerFolder::with(['folders.shared', 'shared:token,id,item_id,permission,protected'])
|
||||||
@@ -40,7 +38,7 @@ class AccountController extends Controller
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'user' => $user->only(['name', 'email', 'avatar', 'role']),
|
'user' => $user->only(['name', 'email', 'avatar', 'role']),
|
||||||
'favourites' => $user->favourites->makeHidden(['pivot']),
|
'favourites' => $user->favourite_folders->makeHidden(['pivot']),
|
||||||
'tree' => $tree,
|
'tree' => $tree,
|
||||||
'storage' => [
|
'storage' => [
|
||||||
'used' => Metric::bytes($user->used_capacity)->format(),
|
'used' => Metric::bytes($user->used_capacity)->format(),
|
||||||
|
|||||||
44
app/Http/Controllers/User/SubscriptionController.php
Normal file
44
app/Http/Controllers/User/SubscriptionController.php
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\User;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Invoice;
|
||||||
|
use Auth;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class SubscriptionController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Upgrade account to subscription
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function upgrade(Request $request)
|
||||||
|
{
|
||||||
|
// TODO: validation request
|
||||||
|
|
||||||
|
// Get user
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
// Get requested plan
|
||||||
|
$plan = app('rinvex.subscriptions.plan')
|
||||||
|
->find($request->input('plan.data.id'));
|
||||||
|
|
||||||
|
// Create subscription
|
||||||
|
$user->newSubscription('main', $plan);
|
||||||
|
|
||||||
|
// Update user storage limig
|
||||||
|
$user->settings()->update([
|
||||||
|
'storage_capacity' => $plan->features->first()->value
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Store invoice
|
||||||
|
Invoice::create(
|
||||||
|
get_invoice_data($user, $plan)
|
||||||
|
);
|
||||||
|
|
||||||
|
return response('Done!', 204);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,12 +19,13 @@ class PlanResource extends JsonResource
|
|||||||
'id' => (string)$this->id,
|
'id' => (string)$this->id,
|
||||||
'type' => 'plans',
|
'type' => 'plans',
|
||||||
'attributes' => [
|
'attributes' => [
|
||||||
'status' => $this->status,
|
'subscribers' => $this->subscriptions->count(),
|
||||||
|
'status' => $this->is_active,
|
||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
'description' => $this->description,
|
'description' => $this->description,
|
||||||
'price' => $this->price,
|
'price' => $this->price,
|
||||||
'capacity_formatted' => format_gigabytes($this->capacity),
|
'capacity_formatted' => format_gigabytes($this->features->first()->value),
|
||||||
'capacity' => $this->capacity,
|
'capacity' => $this->features->first()->value,
|
||||||
'created_at_formatted' => format_date($this->created_at),
|
'created_at_formatted' => format_date($this->created_at),
|
||||||
'created_at' => $this->created_at,
|
'created_at' => $this->created_at,
|
||||||
'updated_at' => $this->updated_at,
|
'updated_at' => $this->updated_at,
|
||||||
|
|||||||
23
app/Http/Resources/PricingCollection.php
Normal file
23
app/Http/Resources/PricingCollection.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||||
|
|
||||||
|
class PricingCollection extends ResourceCollection
|
||||||
|
{
|
||||||
|
public $collects = PricingResource::class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the resource collection into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'data' => $this->collection,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
31
app/Http/Resources/PricingResource.php
Normal file
31
app/Http/Resources/PricingResource.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class PricingResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'data' => [
|
||||||
|
'id' => (string)$this->id,
|
||||||
|
'type' => 'plans',
|
||||||
|
'attributes' => [
|
||||||
|
'name' => $this->name,
|
||||||
|
'description' => $this->description,
|
||||||
|
'price' => $this->price,
|
||||||
|
'capacity_formatted' => format_gigabytes($this->features->first()->value),
|
||||||
|
'capacity' => $this->features->first()->value,
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ class UserResource extends JsonResource
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
'relationships' => [
|
'relationships' => [
|
||||||
'settings' => [
|
'settings' => [
|
||||||
'data' => [
|
'data' => [
|
||||||
'id' => (string)$this->settings->id,
|
'id' => (string)$this->settings->id,
|
||||||
'type' => 'settings',
|
'type' => 'settings',
|
||||||
@@ -48,13 +48,14 @@ class UserResource extends JsonResource
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'storage' => [
|
'storage' => [
|
||||||
'data' => [
|
'data' => [
|
||||||
'id' => '1',
|
'id' => '1',
|
||||||
'type' => 'storage',
|
'type' => 'storage',
|
||||||
'attributes' => $this->storage
|
'attributes' => $this->storage
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
'subscription' => $this->activeSubscriptions()->count() !== 0 ? new UserSubscription($this->subscription('main')) : null,
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,25 +23,25 @@ class UserStorageResource extends JsonResource
|
|||||||
// Get all images
|
// Get all images
|
||||||
$images = FileManagerFile::where('user_id', $this->id)
|
$images = FileManagerFile::where('user_id', $this->id)
|
||||||
->where('type', 'image')->get()->map(function ($item) {
|
->where('type', 'image')->get()->map(function ($item) {
|
||||||
return (int)$item->getOriginal('filesize');
|
return (int)$item->getRawOriginal('filesize');
|
||||||
})->sum();
|
})->sum();
|
||||||
|
|
||||||
// Get all audios
|
// Get all audios
|
||||||
$audios = FileManagerFile::where('user_id', $this->id)
|
$audios = FileManagerFile::where('user_id', $this->id)
|
||||||
->where('type', 'audio')->get()->map(function ($item) {
|
->where('type', 'audio')->get()->map(function ($item) {
|
||||||
return (int)$item->getOriginal('filesize');
|
return (int)$item->getRawOriginal('filesize');
|
||||||
})->sum();
|
})->sum();
|
||||||
|
|
||||||
// Get all videos
|
// Get all videos
|
||||||
$videos = FileManagerFile::where('user_id', $this->id)
|
$videos = FileManagerFile::where('user_id', $this->id)
|
||||||
->where('type', 'video')->get()->map(function ($item) {
|
->where('type', 'video')->get()->map(function ($item) {
|
||||||
return (int)$item->getOriginal('filesize');
|
return (int)$item->getRawOriginal('filesize');
|
||||||
})->sum();
|
})->sum();
|
||||||
|
|
||||||
// Get all documents
|
// Get all documents
|
||||||
$documents = FileManagerFile::where('user_id', $this->id)
|
$documents = FileManagerFile::where('user_id', $this->id)
|
||||||
->whereIn('mimetype', $document_mimetypes)->get()->map(function ($item) {
|
->whereIn('mimetype', $document_mimetypes)->get()->map(function ($item) {
|
||||||
return (int)$item->getOriginal('filesize');
|
return (int)$item->getRawOriginal('filesize');
|
||||||
})->sum();
|
})->sum();
|
||||||
|
|
||||||
// Get all other files
|
// Get all other files
|
||||||
@@ -49,7 +49,7 @@ class UserStorageResource extends JsonResource
|
|||||||
->whereNotIn('mimetype', $document_mimetypes)
|
->whereNotIn('mimetype', $document_mimetypes)
|
||||||
->whereNotIn('type', ['audio', 'video', 'image'])
|
->whereNotIn('type', ['audio', 'video', 'image'])
|
||||||
->get()->map(function ($item) {
|
->get()->map(function ($item) {
|
||||||
return (int)$item->getOriginal('filesize');
|
return (int)$item->getRawOriginal('filesize');
|
||||||
})->sum();
|
})->sum();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|||||||
30
app/Http/Resources/UserSubscription.php
Normal file
30
app/Http/Resources/UserSubscription.php
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class UserSubscription extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'data' => [
|
||||||
|
'id' => $this->id,
|
||||||
|
'type' => 'subscription',
|
||||||
|
'attributes' => [
|
||||||
|
'name' => $this->name,
|
||||||
|
'slug' => $this->slug,
|
||||||
|
'starts_at' => format_date($this->starts_at, '%d. %B. %Y'),
|
||||||
|
'ends_at' => format_date($this->ends_at, '%d. %B. %Y'),
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -124,7 +124,7 @@ class Editor
|
|||||||
Storage::delete('/file-manager/' . $file->basename);
|
Storage::delete('/file-manager/' . $file->basename);
|
||||||
|
|
||||||
// Delete thumbnail if exist
|
// Delete thumbnail if exist
|
||||||
if (!is_null($file->thumbnail)) Storage::delete('/file-manager/' . $file->getOriginal('thumbnail'));
|
if (!is_null($file->thumbnail)) Storage::delete('/file-manager/' . $file->getRawOriginal('thumbnail'));
|
||||||
|
|
||||||
// Delete file permanently
|
// Delete file permanently
|
||||||
$file->forceDelete();
|
$file->forceDelete();
|
||||||
@@ -138,7 +138,7 @@ class Editor
|
|||||||
if (!$request->force_delete) {
|
if (!$request->force_delete) {
|
||||||
|
|
||||||
// Remove folder from user favourites
|
// Remove folder from user favourites
|
||||||
$user->favourites()->detach($unique_id);
|
$user->favourite_folders()->detach($unique_id);
|
||||||
|
|
||||||
// Soft delete folder record
|
// Soft delete folder record
|
||||||
$folder->delete();
|
$folder->delete();
|
||||||
@@ -172,7 +172,7 @@ class Editor
|
|||||||
Storage::delete('/file-manager/' . $file->basename);
|
Storage::delete('/file-manager/' . $file->basename);
|
||||||
|
|
||||||
// Delete thumbnail if exist
|
// Delete thumbnail if exist
|
||||||
if ($file->thumbnail) Storage::delete('/file-manager/' . $file->getOriginal('thumbnail'));
|
if ($file->thumbnail) Storage::delete('/file-manager/' . $file->getRawOriginal('thumbnail'));
|
||||||
|
|
||||||
// Delete file permanently
|
// Delete file permanently
|
||||||
$file->forceDelete();
|
$file->forceDelete();
|
||||||
|
|||||||
@@ -11,12 +11,71 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Intervention\Image\ImageManagerStatic as Image;
|
use Intervention\Image\ImageManagerStatic as Image;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get invoice number
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function get_invoice_number()
|
||||||
|
{
|
||||||
|
$invoices = \App\Invoice::all();
|
||||||
|
|
||||||
|
if ($invoices->isEmpty()) {
|
||||||
|
return Carbon::now()->year . '00001';
|
||||||
|
} else {
|
||||||
|
return (int)$invoices->last()->order + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_invoice_data($user, $plan)
|
||||||
|
{
|
||||||
|
$subscription = $user->subscription('main');
|
||||||
|
$order_number = get_invoice_number();
|
||||||
|
$token = \Illuminate\Support\Str::random(22);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'token' => $token,
|
||||||
|
'order' => $order_number,
|
||||||
|
'user_id' => $user->id,
|
||||||
|
'plan_id' => $plan->id,
|
||||||
|
'total' => $plan->price,
|
||||||
|
'currency' => 'USD',
|
||||||
|
'bag' => [
|
||||||
|
[
|
||||||
|
'description' => 'Subscription - ' . $plan->name,
|
||||||
|
'date' => format_date($subscription->starts_at, '%d. %B. %Y') . ' - ' . format_date($subscription->ends_at, '%d. %B. %Y'),
|
||||||
|
'amount' => $plan->price,
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'seller' => [
|
||||||
|
'billing_name' => 'VueFileManager',
|
||||||
|
'billing_address' => 'Somewhere 32',
|
||||||
|
'billing_state' => 'Washington',
|
||||||
|
'billing_city' => 'Manchester',
|
||||||
|
'billing_postal_code' => '04001',
|
||||||
|
'billing_country' => 'The USA',
|
||||||
|
'billing_phone_number' => '490321-6354774',
|
||||||
|
'billing_vat_number' => '7354724626246',
|
||||||
|
],
|
||||||
|
'client' => [
|
||||||
|
'billing_name' => $user->settings->billing_name,
|
||||||
|
'billing_address' => $user->settings->billing_address,
|
||||||
|
'billing_state' => $user->settings->billing_state,
|
||||||
|
'billing_city' => $user->settings->billing_city,
|
||||||
|
'billing_postal_code' => $user->settings->billing_postal_code,
|
||||||
|
'billing_country' => $user->settings->billing_country,
|
||||||
|
'billing_phone_number' => $user->settings->billing_phone_number,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get app version from config
|
* Get app version from config
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Config\Repository|mixed
|
* @return \Illuminate\Config\Repository|mixed
|
||||||
*/
|
*/
|
||||||
function get_storage() {
|
function get_storage()
|
||||||
|
{
|
||||||
return env('FILESYSTEM_DRIVER');
|
return env('FILESYSTEM_DRIVER');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +84,8 @@ function get_storage() {
|
|||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function is_storage_driver($driver) {
|
function is_storage_driver($driver)
|
||||||
|
{
|
||||||
|
|
||||||
if (is_array($driver)) {
|
if (is_array($driver)) {
|
||||||
return in_array(env('FILESYSTEM_DRIVER'), $driver);
|
return in_array(env('FILESYSTEM_DRIVER'), $driver);
|
||||||
@@ -39,7 +99,8 @@ function is_storage_driver($driver) {
|
|||||||
*
|
*
|
||||||
* @return \Illuminate\Config\Repository|mixed
|
* @return \Illuminate\Config\Repository|mixed
|
||||||
*/
|
*/
|
||||||
function get_version() {
|
function get_version()
|
||||||
|
{
|
||||||
return config('vuefilemanager.version');
|
return config('vuefilemanager.version');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +109,8 @@ function get_version() {
|
|||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
function is_demo($user_id) {
|
function is_demo($user_id)
|
||||||
|
{
|
||||||
|
|
||||||
return env('APP_DEMO', false) && $user_id === 1;
|
return env('APP_DEMO', false) && $user_id === 1;
|
||||||
}
|
}
|
||||||
@@ -61,7 +123,8 @@ function is_demo($user_id) {
|
|||||||
* @param $user_id
|
* @param $user_id
|
||||||
* @return \Illuminate\Database\Eloquent\Builder|Model
|
* @return \Illuminate\Database\Eloquent\Builder|Model
|
||||||
*/
|
*/
|
||||||
function get_item($type, $unique_id, $user_id) {
|
function get_item($type, $unique_id, $user_id)
|
||||||
|
{
|
||||||
|
|
||||||
if ($type === 'folder') {
|
if ($type === 'folder') {
|
||||||
|
|
||||||
@@ -83,7 +146,8 @@ function get_item($type, $unique_id, $user_id) {
|
|||||||
* @param $token
|
* @param $token
|
||||||
* @return \Illuminate\Database\Eloquent\Builder|Model
|
* @return \Illuminate\Database\Eloquent\Builder|Model
|
||||||
*/
|
*/
|
||||||
function get_shared($token) {
|
function get_shared($token)
|
||||||
|
{
|
||||||
|
|
||||||
return Share::where(DB::raw('BINARY `token`'), $token)
|
return Share::where(DB::raw('BINARY `token`'), $token)
|
||||||
->firstOrFail();
|
->firstOrFail();
|
||||||
@@ -95,7 +159,8 @@ function get_shared($token) {
|
|||||||
* @param $shared
|
* @param $shared
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function is_editor($shared) {
|
function is_editor($shared)
|
||||||
|
{
|
||||||
|
|
||||||
return $shared->permission === 'editor';
|
return $shared->permission === 'editor';
|
||||||
}
|
}
|
||||||
@@ -190,7 +255,11 @@ function make_single_input($request)
|
|||||||
*/
|
*/
|
||||||
function format_gigabytes($gigabytes)
|
function format_gigabytes($gigabytes)
|
||||||
{
|
{
|
||||||
return Metric::gigabytes($gigabytes)->format();
|
if ($gigabytes >= 1000) {
|
||||||
|
return Metric::gigabytes($gigabytes)->format('Tb/');
|
||||||
|
} else {
|
||||||
|
return Metric::gigabytes($gigabytes)->format('GB/');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,12 +6,21 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
|
|
||||||
class Invoice extends Model
|
class Invoice extends Model
|
||||||
{
|
{
|
||||||
|
protected $guarded = [
|
||||||
|
'id'
|
||||||
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'seller' => 'array',
|
'seller' => 'array',
|
||||||
'client' => 'array',
|
'client' => 'array',
|
||||||
'bag' => 'array',
|
'bag' => 'array',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user instance
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
|
*/
|
||||||
public function user() {
|
public function user() {
|
||||||
return $this->hasOne(User::class, 'id', 'user_id');
|
return $this->hasOne(User::class, 'id', 'user_id');
|
||||||
}
|
}
|
||||||
|
|||||||
10
app/Plan.php
10
app/Plan.php
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
|
|
||||||
class Plan extends Model
|
|
||||||
{
|
|
||||||
protected $guarded = ['id'];
|
|
||||||
}
|
|
||||||
@@ -11,6 +11,7 @@ use Illuminate\Notifications\Notifiable;
|
|||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Facades\Notification;
|
use Illuminate\Support\Facades\Notification;
|
||||||
use Laravel\Passport\HasApiTokens;
|
use Laravel\Passport\HasApiTokens;
|
||||||
|
use Rinvex\Subscriptions\Traits\HasSubscriptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\User
|
* App\User
|
||||||
@@ -55,7 +56,7 @@ use Laravel\Passport\HasApiTokens;
|
|||||||
*/
|
*/
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
use HasApiTokens, Notifiable;
|
use HasApiTokens, Notifiable, HasSubscriptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
@@ -111,7 +112,7 @@ class User extends Authenticatable
|
|||||||
public function getUsedCapacityAttribute() {
|
public function getUsedCapacityAttribute() {
|
||||||
|
|
||||||
$user_capacity = $this->files_with_trashed->map(function ($item) {
|
$user_capacity = $this->files_with_trashed->map(function ($item) {
|
||||||
return $item->getOriginal();
|
return $item->getRawOriginal();
|
||||||
})->sum('filesize');
|
})->sum('filesize');
|
||||||
|
|
||||||
return $user_capacity;
|
return $user_capacity;
|
||||||
@@ -147,7 +148,7 @@ class User extends Authenticatable
|
|||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||||
*/
|
*/
|
||||||
public function favourites()
|
public function favourite_folders()
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(FileManagerFolder::class, 'favourite_folder', 'user_id', 'folder_unique_id', 'id', 'unique_id')->with('shared:token,id,item_id,permission,protected');
|
return $this->belongsToMany(FileManagerFolder::class, 'favourite_folder', 'user_id', 'folder_unique_id', 'id', 'unique_id')->with('shared:token,id,item_id,permission,protected');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,23 +13,23 @@
|
|||||||
"fideloper/proxy": "^4.0",
|
"fideloper/proxy": "^4.0",
|
||||||
"fruitcake/laravel-cors": "^1.0",
|
"fruitcake/laravel-cors": "^1.0",
|
||||||
"gabrielelana/byte-units": "^0.5.0",
|
"gabrielelana/byte-units": "^0.5.0",
|
||||||
"h4cc/wkhtmltopdf-amd64": "^0.12.4",
|
|
||||||
"intervention/image": "^2.5",
|
"intervention/image": "^2.5",
|
||||||
"laravel/framework": "^6.2",
|
"laravel/framework": "^7.0",
|
||||||
"laravel/passport": "^8.4",
|
"laravel/passport": "^8.4",
|
||||||
"laravel/scout": "^7.2",
|
"laravel/scout": "^7.2",
|
||||||
"laravel/tinker": "^2.0",
|
"laravel/tinker": "^2.0",
|
||||||
"league/flysystem-aws-s3-v3": "^1.0",
|
"league/flysystem-aws-s3-v3": "^1.0",
|
||||||
"league/flysystem-cached-adapter": "^1.0",
|
"league/flysystem-cached-adapter": "^1.0",
|
||||||
"teamtnt/laravel-scout-tntsearch-driver": "^7.2"
|
"rinvex/laravel-subscriptions": "^4.0",
|
||||||
|
"teamtnt/laravel-scout-tntsearch-driver": "^8.3"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"barryvdh/laravel-ide-helper": "^2.7",
|
"barryvdh/laravel-ide-helper": "^2.7",
|
||||||
"facade/ignition": "^1.4",
|
"facade/ignition": "^2.0",
|
||||||
"fzaninotto/faker": "^1.4",
|
"fzaninotto/faker": "^1.4",
|
||||||
"mockery/mockery": "^1.0",
|
"mockery/mockery": "^1.0",
|
||||||
"nunomaduro/collision": "^3.0",
|
"nunomaduro/collision": "^4.1",
|
||||||
"phpunit/phpunit": "^8.0"
|
"phpunit/phpunit": "^8.5"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"optimize-autoloader": true,
|
"optimize-autoloader": true,
|
||||||
|
|||||||
2174
composer.lock
generated
2174
composer.lock
generated
File diff suppressed because it is too large
Load Diff
30
config/rinvex.subscriptions.php
Normal file
30
config/rinvex.subscriptions.php
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
// Manage autoload migrations
|
||||||
|
'autoload_migrations' => true,
|
||||||
|
|
||||||
|
// Subscriptions Database Tables
|
||||||
|
'tables' => [
|
||||||
|
|
||||||
|
'plans' => 'plans',
|
||||||
|
'plan_features' => 'plan_features',
|
||||||
|
'plan_subscriptions' => 'plan_subscriptions',
|
||||||
|
'plan_subscription_usage' => 'plan_subscription_usage',
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
// Subscriptions Models
|
||||||
|
'models' => [
|
||||||
|
|
||||||
|
'plan' => \Rinvex\Subscriptions\Models\Plan::class,
|
||||||
|
'plan_feature' => \Rinvex\Subscriptions\Models\PlanFeature::class,
|
||||||
|
'plan_subscription' => \Rinvex\Subscriptions\Models\PlanSubscription::class,
|
||||||
|
'plan_subscription_usage' => \Rinvex\Subscriptions\Models\PlanSubscriptionUsage::class,
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
||||||
@@ -166,7 +166,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'secure' => env('SESSION_SECURE_COOKIE', false),
|
'secure' => env('SESSION_SECURE_COOKIE', null),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class CreatePlansTable extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::create('plans', function (Blueprint $table) {
|
|
||||||
$table->bigIncrements('id');
|
|
||||||
$table->boolean('status')->default(1);
|
|
||||||
$table->text('name');
|
|
||||||
$table->text('price');
|
|
||||||
$table->integer('capacity');
|
|
||||||
$table->longText('description')->nullable();
|
|
||||||
$table->timestamps();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('plans');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,7 +25,6 @@ class CreateInvoicesTable extends Migration
|
|||||||
$table->longText('notes')->nullable();
|
$table->longText('notes')->nullable();
|
||||||
$table->text('total');
|
$table->text('total');
|
||||||
$table->text('currency');
|
$table->text('currency');
|
||||||
$table->text('path');
|
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreatePlansTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create(config('rinvex.subscriptions.tables.plans'), function (Blueprint $table) {
|
||||||
|
// Columns
|
||||||
|
$table->increments('id');
|
||||||
|
$table->string('slug');
|
||||||
|
$table->{$this->jsonable()}('name');
|
||||||
|
$table->{$this->jsonable()}('description')->nullable();
|
||||||
|
$table->boolean('is_active')->default(true);
|
||||||
|
$table->decimal('price')->default('0.00');
|
||||||
|
$table->decimal('signup_fee')->default('0.00');
|
||||||
|
$table->string('currency', 3);
|
||||||
|
$table->smallInteger('trial_period')->unsigned()->default(0);
|
||||||
|
$table->string('trial_interval')->default('day');
|
||||||
|
$table->smallInteger('invoice_period')->unsigned()->default(0);
|
||||||
|
$table->string('invoice_interval')->default('month');
|
||||||
|
$table->smallInteger('grace_period')->unsigned()->default(0);
|
||||||
|
$table->string('grace_interval')->default('day');
|
||||||
|
$table->tinyInteger('prorate_day')->unsigned()->nullable();
|
||||||
|
$table->tinyInteger('prorate_period')->unsigned()->nullable();
|
||||||
|
$table->tinyInteger('prorate_extend_due')->unsigned()->nullable();
|
||||||
|
$table->smallInteger('active_subscribers_limit')->unsigned()->nullable();
|
||||||
|
$table->mediumInteger('sort_order')->unsigned()->default(0);
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
|
||||||
|
// Indexes
|
||||||
|
$table->unique('slug');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists(config('rinvex.subscriptions.tables.plans'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get jsonable column data type.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function jsonable(): string
|
||||||
|
{
|
||||||
|
$driverName = DB::connection()->getPdo()->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||||
|
$dbVersion = DB::connection()->getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||||
|
$isOldVersion = version_compare($dbVersion, '5.7.8', 'lt');
|
||||||
|
|
||||||
|
return $driverName === 'mysql' && $isOldVersion ? 'text' : 'json';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreatePlanFeaturesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create(config('rinvex.subscriptions.tables.plan_features'), function (Blueprint $table) {
|
||||||
|
// Columns
|
||||||
|
$table->increments('id');
|
||||||
|
$table->integer('plan_id')->unsigned();
|
||||||
|
$table->string('slug');
|
||||||
|
$table->{$this->jsonable()}('name');
|
||||||
|
$table->{$this->jsonable()}('description')->nullable();
|
||||||
|
$table->string('value');
|
||||||
|
$table->smallInteger('resettable_period')->unsigned()->default(0);
|
||||||
|
$table->string('resettable_interval')->default('month');
|
||||||
|
$table->mediumInteger('sort_order')->unsigned()->default(0);
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
|
||||||
|
// Indexes
|
||||||
|
$table->unique(['plan_id', 'slug']);
|
||||||
|
$table->foreign('plan_id')->references('id')->on(config('rinvex.subscriptions.tables.plans'))
|
||||||
|
->onDelete('cascade')->onUpdate('cascade');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists(config('rinvex.subscriptions.tables.plan_features'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get jsonable column data type.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function jsonable(): string
|
||||||
|
{
|
||||||
|
$driverName = DB::connection()->getPdo()->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||||
|
$dbVersion = DB::connection()->getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||||
|
$isOldVersion = version_compare($dbVersion, '5.7.8', 'lt');
|
||||||
|
|
||||||
|
return $driverName === 'mysql' && $isOldVersion ? 'text' : 'json';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreatePlanSubscriptionsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create(config('rinvex.subscriptions.tables.plan_subscriptions'), function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->morphs('user');
|
||||||
|
$table->integer('plan_id')->unsigned();
|
||||||
|
$table->string('slug');
|
||||||
|
$table->{$this->jsonable()}('name');
|
||||||
|
$table->{$this->jsonable()}('description')->nullable();
|
||||||
|
$table->dateTime('trial_ends_at')->nullable();
|
||||||
|
$table->dateTime('starts_at')->nullable();
|
||||||
|
$table->dateTime('ends_at')->nullable();
|
||||||
|
$table->dateTime('cancels_at')->nullable();
|
||||||
|
$table->dateTime('canceled_at')->nullable();
|
||||||
|
$table->string('timezone')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
|
||||||
|
// Indexes
|
||||||
|
$table->unique('slug');
|
||||||
|
$table->foreign('plan_id')->references('id')->on(config('rinvex.subscriptions.tables.plans'))
|
||||||
|
->onDelete('cascade')->onUpdate('cascade');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists(config('rinvex.subscriptions.tables.plan_subscriptions'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get jsonable column data type.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function jsonable(): string
|
||||||
|
{
|
||||||
|
$driverName = DB::connection()->getPdo()->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||||
|
$dbVersion = DB::connection()->getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||||
|
$isOldVersion = version_compare($dbVersion, '5.7.8', 'lt');
|
||||||
|
|
||||||
|
return $driverName === 'mysql' && $isOldVersion ? 'text' : 'json';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreatePlanSubscriptionUsageTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create(config('rinvex.subscriptions.tables.plan_subscription_usage'), function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->integer('subscription_id')->unsigned();
|
||||||
|
$table->integer('feature_id')->unsigned();
|
||||||
|
$table->smallInteger('used')->unsigned();
|
||||||
|
$table->dateTime('valid_until')->nullable();
|
||||||
|
$table->string('timezone')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
|
||||||
|
$table->unique(['subscription_id', 'feature_id']);
|
||||||
|
$table->foreign('subscription_id')->references('id')->on(config('rinvex.subscriptions.tables.plan_subscriptions'))
|
||||||
|
->onDelete('cascade')->onUpdate('cascade');
|
||||||
|
$table->foreign('feature_id')->references('id')->on(config('rinvex.subscriptions.tables.plan_features'))
|
||||||
|
->onDelete('cascade')->onUpdate('cascade');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists(config('rinvex.subscriptions.tables.plan_subscription_usage'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,353 @@
|
|||||||
{
|
{
|
||||||
"/js/main.js": "/js/main.js",
|
"/js/main.js": "/js/main.js",
|
||||||
"/css/app.css": "/css/app.css",
|
"/css/app.css": "/css/app.css",
|
||||||
"/js/main.a3a51ffe63e5ab8ad17b.hot-update.js": "/js/main.a3a51ffe63e5ab8ad17b.hot-update.js",
|
"/js/main.60a83cde6ee2f68824da.hot-update.js": "/js/main.60a83cde6ee2f68824da.hot-update.js",
|
||||||
"/js/main.255954174c5d7e9a08b3.hot-update.js": "/js/main.255954174c5d7e9a08b3.hot-update.js",
|
"/js/main.ef619783c500887ceffe.hot-update.js": "/js/main.ef619783c500887ceffe.hot-update.js",
|
||||||
"/js/main.99a451b0fd3dc3ce2f33.hot-update.js": "/js/main.99a451b0fd3dc3ce2f33.hot-update.js",
|
"/js/main.c013b62eccdba33a9f76.hot-update.js": "/js/main.c013b62eccdba33a9f76.hot-update.js",
|
||||||
"/js/main.53d3f8b1c2dd0e07b5b8.hot-update.js": "/js/main.53d3f8b1c2dd0e07b5b8.hot-update.js",
|
"/js/main.b69457f69553fafe8967.hot-update.js": "/js/main.b69457f69553fafe8967.hot-update.js",
|
||||||
"/js/main.e3be347086dcc417ba57.hot-update.js": "/js/main.e3be347086dcc417ba57.hot-update.js",
|
"/js/main.873e7877b5a7297e1c17.hot-update.js": "/js/main.873e7877b5a7297e1c17.hot-update.js",
|
||||||
"/js/main.85f332c95c7b4be8cd10.hot-update.js": "/js/main.85f332c95c7b4be8cd10.hot-update.js"
|
"/js/main.b9ddf454773dfc9a3cc4.hot-update.js": "/js/main.b9ddf454773dfc9a3cc4.hot-update.js",
|
||||||
|
"/js/main.02f346aa47ed2e2a0485.hot-update.js": "/js/main.02f346aa47ed2e2a0485.hot-update.js",
|
||||||
|
"/js/main.cc4e9ed6c16ce2b1299f.hot-update.js": "/js/main.cc4e9ed6c16ce2b1299f.hot-update.js",
|
||||||
|
"/js/main.7002551648c9c102b6ff.hot-update.js": "/js/main.7002551648c9c102b6ff.hot-update.js",
|
||||||
|
"/js/main.f5f21d04048492dbd747.hot-update.js": "/js/main.f5f21d04048492dbd747.hot-update.js",
|
||||||
|
"/js/main.0dbde133bdee5d63d609.hot-update.js": "/js/main.0dbde133bdee5d63d609.hot-update.js",
|
||||||
|
"/js/main.7261b8501bb32bb006f0.hot-update.js": "/js/main.7261b8501bb32bb006f0.hot-update.js",
|
||||||
|
"/js/main.27a706ad1b73d0697b2c.hot-update.js": "/js/main.27a706ad1b73d0697b2c.hot-update.js",
|
||||||
|
"/js/main.17b995f15aec112c8c5b.hot-update.js": "/js/main.17b995f15aec112c8c5b.hot-update.js",
|
||||||
|
"/js/main.8e55b60094bd1698c507.hot-update.js": "/js/main.8e55b60094bd1698c507.hot-update.js",
|
||||||
|
"/js/main.09e6bb0dc398c2959b26.hot-update.js": "/js/main.09e6bb0dc398c2959b26.hot-update.js",
|
||||||
|
"/js/main.fd71ac7e397883c5ad8b.hot-update.js": "/js/main.fd71ac7e397883c5ad8b.hot-update.js",
|
||||||
|
"/js/main.d370dc07147b907f62df.hot-update.js": "/js/main.d370dc07147b907f62df.hot-update.js",
|
||||||
|
"/js/main.c1b2482085d2dca6e959.hot-update.js": "/js/main.c1b2482085d2dca6e959.hot-update.js",
|
||||||
|
"/js/main.5e3ed25ff048539d7beb.hot-update.js": "/js/main.5e3ed25ff048539d7beb.hot-update.js",
|
||||||
|
"/js/main.a41a30032cd7c44f8961.hot-update.js": "/js/main.a41a30032cd7c44f8961.hot-update.js",
|
||||||
|
"/js/main.a9741a1d40de6f852246.hot-update.js": "/js/main.a9741a1d40de6f852246.hot-update.js",
|
||||||
|
"/js/main.be7b3011e661b4181e7a.hot-update.js": "/js/main.be7b3011e661b4181e7a.hot-update.js",
|
||||||
|
"/js/main.3db920f332bc3991dd5c.hot-update.js": "/js/main.3db920f332bc3991dd5c.hot-update.js",
|
||||||
|
"/js/main.5561ca4061079f16c0be.hot-update.js": "/js/main.5561ca4061079f16c0be.hot-update.js",
|
||||||
|
"/js/main.ffa5150f8c1cd7521dd2.hot-update.js": "/js/main.ffa5150f8c1cd7521dd2.hot-update.js",
|
||||||
|
"/js/main.5f28c31c15df2df73a2b.hot-update.js": "/js/main.5f28c31c15df2df73a2b.hot-update.js",
|
||||||
|
"/js/main.f9f3f6d9e87f5ecd0bb9.hot-update.js": "/js/main.f9f3f6d9e87f5ecd0bb9.hot-update.js",
|
||||||
|
"/js/main.44fecef6499fea67dc72.hot-update.js": "/js/main.44fecef6499fea67dc72.hot-update.js",
|
||||||
|
"/js/main.73c749e66d6c20809368.hot-update.js": "/js/main.73c749e66d6c20809368.hot-update.js",
|
||||||
|
"/js/main.7a6220ca40fd95b13a8b.hot-update.js": "/js/main.7a6220ca40fd95b13a8b.hot-update.js",
|
||||||
|
"/js/main.6be211db0853880da483.hot-update.js": "/js/main.6be211db0853880da483.hot-update.js",
|
||||||
|
"/js/main.ab94ff0b5c48f6a077dc.hot-update.js": "/js/main.ab94ff0b5c48f6a077dc.hot-update.js",
|
||||||
|
"/js/main.9afc512df05cd3a8ac58.hot-update.js": "/js/main.9afc512df05cd3a8ac58.hot-update.js",
|
||||||
|
"/js/main.43538fedff7023915e34.hot-update.js": "/js/main.43538fedff7023915e34.hot-update.js",
|
||||||
|
"/js/main.5f51a0e00cfd46bc8a1d.hot-update.js": "/js/main.5f51a0e00cfd46bc8a1d.hot-update.js",
|
||||||
|
"/js/main.126e706d99f33682b6d0.hot-update.js": "/js/main.126e706d99f33682b6d0.hot-update.js",
|
||||||
|
"/js/main.8daab36d29fdcdd8dc60.hot-update.js": "/js/main.8daab36d29fdcdd8dc60.hot-update.js",
|
||||||
|
"/js/main.7e2ebfecf4df5598079c.hot-update.js": "/js/main.7e2ebfecf4df5598079c.hot-update.js",
|
||||||
|
"/js/main.5ed6d6df0896b972a2f7.hot-update.js": "/js/main.5ed6d6df0896b972a2f7.hot-update.js",
|
||||||
|
"/js/main.2d2a1d857e6b40fba146.hot-update.js": "/js/main.2d2a1d857e6b40fba146.hot-update.js",
|
||||||
|
"/js/main.0ae791146f4cf6ddff27.hot-update.js": "/js/main.0ae791146f4cf6ddff27.hot-update.js",
|
||||||
|
"/js/main.0a07ef52e4609669974b.hot-update.js": "/js/main.0a07ef52e4609669974b.hot-update.js",
|
||||||
|
"/js/main.659024279a212defa9e5.hot-update.js": "/js/main.659024279a212defa9e5.hot-update.js",
|
||||||
|
"/js/main.f3d0eba7638f859fd680.hot-update.js": "/js/main.f3d0eba7638f859fd680.hot-update.js",
|
||||||
|
"/js/main.4d406bf1178f069aed95.hot-update.js": "/js/main.4d406bf1178f069aed95.hot-update.js",
|
||||||
|
"/js/main.8be8ab82ff63a98f578e.hot-update.js": "/js/main.8be8ab82ff63a98f578e.hot-update.js",
|
||||||
|
"/js/main.c0864b90fdd06b278c0a.hot-update.js": "/js/main.c0864b90fdd06b278c0a.hot-update.js",
|
||||||
|
"/js/main.bc7b433506f608a82a6b.hot-update.js": "/js/main.bc7b433506f608a82a6b.hot-update.js",
|
||||||
|
"/js/main.30d3b9977d3dc83ed57e.hot-update.js": "/js/main.30d3b9977d3dc83ed57e.hot-update.js",
|
||||||
|
"/js/main.ebec5f1efc4ff893de63.hot-update.js": "/js/main.ebec5f1efc4ff893de63.hot-update.js",
|
||||||
|
"/js/main.ebc12d34a4fba627c401.hot-update.js": "/js/main.ebc12d34a4fba627c401.hot-update.js",
|
||||||
|
"/js/main.ec5f3d6ea3f03f3bfe5d.hot-update.js": "/js/main.ec5f3d6ea3f03f3bfe5d.hot-update.js",
|
||||||
|
"/js/main.563f066659ae7a313dce.hot-update.js": "/js/main.563f066659ae7a313dce.hot-update.js",
|
||||||
|
"/js/main.2725f37a642b592af8c9.hot-update.js": "/js/main.2725f37a642b592af8c9.hot-update.js",
|
||||||
|
"/js/main.3a41edb1952f97e1cf0c.hot-update.js": "/js/main.3a41edb1952f97e1cf0c.hot-update.js",
|
||||||
|
"/js/main.4257072b4fa820520329.hot-update.js": "/js/main.4257072b4fa820520329.hot-update.js",
|
||||||
|
"/js/main.fd59b0473a4ddd58a231.hot-update.js": "/js/main.fd59b0473a4ddd58a231.hot-update.js",
|
||||||
|
"/js/main.40ce0c4e650274ca2e2e.hot-update.js": "/js/main.40ce0c4e650274ca2e2e.hot-update.js",
|
||||||
|
"/js/main.897246c769e983f3d989.hot-update.js": "/js/main.897246c769e983f3d989.hot-update.js",
|
||||||
|
"/js/main.521f0c97840da3481c94.hot-update.js": "/js/main.521f0c97840da3481c94.hot-update.js",
|
||||||
|
"/js/main.c154b9ae35a1f6a32e82.hot-update.js": "/js/main.c154b9ae35a1f6a32e82.hot-update.js",
|
||||||
|
"/js/main.8cf48f71db246ed8b9af.hot-update.js": "/js/main.8cf48f71db246ed8b9af.hot-update.js",
|
||||||
|
"/js/main.679e8b450323f00f16b1.hot-update.js": "/js/main.679e8b450323f00f16b1.hot-update.js",
|
||||||
|
"/js/main.0c75525a762b37a19ebb.hot-update.js": "/js/main.0c75525a762b37a19ebb.hot-update.js",
|
||||||
|
"/js/main.0a762f4b8d3e4ba3bf50.hot-update.js": "/js/main.0a762f4b8d3e4ba3bf50.hot-update.js",
|
||||||
|
"/js/main.8bb52c015cc5bf103a83.hot-update.js": "/js/main.8bb52c015cc5bf103a83.hot-update.js",
|
||||||
|
"/js/main.051c0994490dbf28d874.hot-update.js": "/js/main.051c0994490dbf28d874.hot-update.js",
|
||||||
|
"/js/main.c4fbb155df77a01cead2.hot-update.js": "/js/main.c4fbb155df77a01cead2.hot-update.js",
|
||||||
|
"/js/main.a89076bd7fc546c5bbba.hot-update.js": "/js/main.a89076bd7fc546c5bbba.hot-update.js",
|
||||||
|
"/js/main.469d258e2e2b007207e1.hot-update.js": "/js/main.469d258e2e2b007207e1.hot-update.js",
|
||||||
|
"/js/main.2fec9cd89f848ea0d839.hot-update.js": "/js/main.2fec9cd89f848ea0d839.hot-update.js",
|
||||||
|
"/js/main.5f0c685a4cd32095c161.hot-update.js": "/js/main.5f0c685a4cd32095c161.hot-update.js",
|
||||||
|
"/js/main.3ed4497a365f6d72dc7f.hot-update.js": "/js/main.3ed4497a365f6d72dc7f.hot-update.js",
|
||||||
|
"/js/main.0d3316553777396d8e49.hot-update.js": "/js/main.0d3316553777396d8e49.hot-update.js",
|
||||||
|
"/js/main.b967e5d0cd196a9cffe5.hot-update.js": "/js/main.b967e5d0cd196a9cffe5.hot-update.js",
|
||||||
|
"/js/main.7cb7cc650992de21a270.hot-update.js": "/js/main.7cb7cc650992de21a270.hot-update.js",
|
||||||
|
"/js/main.cbd0798033c61903982b.hot-update.js": "/js/main.cbd0798033c61903982b.hot-update.js",
|
||||||
|
"/js/main.f3cbf06b4bb700eed2ca.hot-update.js": "/js/main.f3cbf06b4bb700eed2ca.hot-update.js",
|
||||||
|
"/js/main.f23f1b2b13a97c24a12e.hot-update.js": "/js/main.f23f1b2b13a97c24a12e.hot-update.js",
|
||||||
|
"/js/main.260b86bb8c6137305d79.hot-update.js": "/js/main.260b86bb8c6137305d79.hot-update.js",
|
||||||
|
"/js/main.a64e08b37d0287f0fd3c.hot-update.js": "/js/main.a64e08b37d0287f0fd3c.hot-update.js",
|
||||||
|
"/js/main.5271952fd0528f004eb2.hot-update.js": "/js/main.5271952fd0528f004eb2.hot-update.js",
|
||||||
|
"/js/main.6bc1170583bfada6b03f.hot-update.js": "/js/main.6bc1170583bfada6b03f.hot-update.js",
|
||||||
|
"/js/main.97ce3d98957854961afa.hot-update.js": "/js/main.97ce3d98957854961afa.hot-update.js",
|
||||||
|
"/js/main.73536cf388d726112883.hot-update.js": "/js/main.73536cf388d726112883.hot-update.js",
|
||||||
|
"/js/main.443f226a178e6f696918.hot-update.js": "/js/main.443f226a178e6f696918.hot-update.js",
|
||||||
|
"/js/main.943771be6a55402c235f.hot-update.js": "/js/main.943771be6a55402c235f.hot-update.js",
|
||||||
|
"/js/main.38d64e59de4dac8d3a27.hot-update.js": "/js/main.38d64e59de4dac8d3a27.hot-update.js",
|
||||||
|
"/js/main.633ca2766892a4f86c06.hot-update.js": "/js/main.633ca2766892a4f86c06.hot-update.js",
|
||||||
|
"/js/main.7a1f97a5416bd2f7aa1d.hot-update.js": "/js/main.7a1f97a5416bd2f7aa1d.hot-update.js",
|
||||||
|
"/js/main.c94a5b2de6b87a0de111.hot-update.js": "/js/main.c94a5b2de6b87a0de111.hot-update.js",
|
||||||
|
"/js/main.23c164a13b2f0aa50f45.hot-update.js": "/js/main.23c164a13b2f0aa50f45.hot-update.js",
|
||||||
|
"/js/main.7acd02ffbc40e34b76b5.hot-update.js": "/js/main.7acd02ffbc40e34b76b5.hot-update.js",
|
||||||
|
"/js/main.e55585baebfa4ff40b96.hot-update.js": "/js/main.e55585baebfa4ff40b96.hot-update.js",
|
||||||
|
"/js/main.26f5e7e248e7a516fdeb.hot-update.js": "/js/main.26f5e7e248e7a516fdeb.hot-update.js",
|
||||||
|
"/js/main.a4354cf111d2f640de40.hot-update.js": "/js/main.a4354cf111d2f640de40.hot-update.js",
|
||||||
|
"/js/main.b7c598a2039ad757246c.hot-update.js": "/js/main.b7c598a2039ad757246c.hot-update.js",
|
||||||
|
"/js/main.76c1bb584af8d242650d.hot-update.js": "/js/main.76c1bb584af8d242650d.hot-update.js",
|
||||||
|
"/js/main.462992b527732ffaf011.hot-update.js": "/js/main.462992b527732ffaf011.hot-update.js",
|
||||||
|
"/js/main.c7aab6e1f0a415b086a2.hot-update.js": "/js/main.c7aab6e1f0a415b086a2.hot-update.js",
|
||||||
|
"/js/main.4f06914b44e0029a62f4.hot-update.js": "/js/main.4f06914b44e0029a62f4.hot-update.js",
|
||||||
|
"/js/main.1a3f610ba8ec3292f4dc.hot-update.js": "/js/main.1a3f610ba8ec3292f4dc.hot-update.js",
|
||||||
|
"/js/main.06895546a55022d7cc93.hot-update.js": "/js/main.06895546a55022d7cc93.hot-update.js",
|
||||||
|
"/js/main.40b86ee237657438cdaf.hot-update.js": "/js/main.40b86ee237657438cdaf.hot-update.js",
|
||||||
|
"/js/main.32e1f408e9b90f611a86.hot-update.js": "/js/main.32e1f408e9b90f611a86.hot-update.js",
|
||||||
|
"/js/main.67c28937753a28b1a5fe.hot-update.js": "/js/main.67c28937753a28b1a5fe.hot-update.js",
|
||||||
|
"/js/main.c77543d539285c1e543f.hot-update.js": "/js/main.c77543d539285c1e543f.hot-update.js",
|
||||||
|
"/js/main.87a307c96a03990ed2d2.hot-update.js": "/js/main.87a307c96a03990ed2d2.hot-update.js",
|
||||||
|
"/js/main.410431febebc49d899af.hot-update.js": "/js/main.410431febebc49d899af.hot-update.js",
|
||||||
|
"/js/main.bf80b81234310414d660.hot-update.js": "/js/main.bf80b81234310414d660.hot-update.js",
|
||||||
|
"/js/main.feafe99eed468b85dedf.hot-update.js": "/js/main.feafe99eed468b85dedf.hot-update.js",
|
||||||
|
"/js/main.aacf93c99eb8a3568989.hot-update.js": "/js/main.aacf93c99eb8a3568989.hot-update.js",
|
||||||
|
"/js/main.a65b1ed2d462cd1a763f.hot-update.js": "/js/main.a65b1ed2d462cd1a763f.hot-update.js",
|
||||||
|
"/js/main.fe60a69fef9957db3a1d.hot-update.js": "/js/main.fe60a69fef9957db3a1d.hot-update.js",
|
||||||
|
"/js/main.7b1a834a609da6a1b646.hot-update.js": "/js/main.7b1a834a609da6a1b646.hot-update.js",
|
||||||
|
"/js/main.242c7360b2a866a7a82d.hot-update.js": "/js/main.242c7360b2a866a7a82d.hot-update.js",
|
||||||
|
"/js/main.40b74c52c10319637483.hot-update.js": "/js/main.40b74c52c10319637483.hot-update.js",
|
||||||
|
"/js/main.c3b0523da3b9e289bafb.hot-update.js": "/js/main.c3b0523da3b9e289bafb.hot-update.js",
|
||||||
|
"/js/main.08be399733e6a3153176.hot-update.js": "/js/main.08be399733e6a3153176.hot-update.js",
|
||||||
|
"/js/main.0b308de86105413b8662.hot-update.js": "/js/main.0b308de86105413b8662.hot-update.js",
|
||||||
|
"/js/main.981f6f1ae8471e9ed315.hot-update.js": "/js/main.981f6f1ae8471e9ed315.hot-update.js",
|
||||||
|
"/js/main.53459c189d19f054afe7.hot-update.js": "/js/main.53459c189d19f054afe7.hot-update.js",
|
||||||
|
"/js/main.4169b15dfc28accd6d62.hot-update.js": "/js/main.4169b15dfc28accd6d62.hot-update.js",
|
||||||
|
"/js/main.c9200c7c0f92533c5873.hot-update.js": "/js/main.c9200c7c0f92533c5873.hot-update.js",
|
||||||
|
"/js/main.1c9488c999bafc17a89c.hot-update.js": "/js/main.1c9488c999bafc17a89c.hot-update.js",
|
||||||
|
"/js/main.045053c89e70c0acacf8.hot-update.js": "/js/main.045053c89e70c0acacf8.hot-update.js",
|
||||||
|
"/js/main.ba2e5630164a8646afdf.hot-update.js": "/js/main.ba2e5630164a8646afdf.hot-update.js",
|
||||||
|
"/js/main.46b19114682d5b1a735b.hot-update.js": "/js/main.46b19114682d5b1a735b.hot-update.js",
|
||||||
|
"/js/main.ec39e60cb391c413c34b.hot-update.js": "/js/main.ec39e60cb391c413c34b.hot-update.js",
|
||||||
|
"/js/main.da250e00235e15fd6f76.hot-update.js": "/js/main.da250e00235e15fd6f76.hot-update.js",
|
||||||
|
"/js/main.6dacc4854d335e05708d.hot-update.js": "/js/main.6dacc4854d335e05708d.hot-update.js",
|
||||||
|
"/js/main.dc90fa26fa365ecf5b2b.hot-update.js": "/js/main.dc90fa26fa365ecf5b2b.hot-update.js",
|
||||||
|
"/js/main.9502362a8afa7e2f5876.hot-update.js": "/js/main.9502362a8afa7e2f5876.hot-update.js",
|
||||||
|
"/js/main.802de52c0e8646bade98.hot-update.js": "/js/main.802de52c0e8646bade98.hot-update.js",
|
||||||
|
"/js/main.2934bf35e19f55ca56be.hot-update.js": "/js/main.2934bf35e19f55ca56be.hot-update.js",
|
||||||
|
"/js/main.bf13b7f4a625e248d25e.hot-update.js": "/js/main.bf13b7f4a625e248d25e.hot-update.js",
|
||||||
|
"/js/main.3c651f57e3b0e4962aed.hot-update.js": "/js/main.3c651f57e3b0e4962aed.hot-update.js",
|
||||||
|
"/js/main.fc3ac3dc56ed4c2b5a16.hot-update.js": "/js/main.fc3ac3dc56ed4c2b5a16.hot-update.js",
|
||||||
|
"/js/main.0ff8092f8d7ef902bdea.hot-update.js": "/js/main.0ff8092f8d7ef902bdea.hot-update.js",
|
||||||
|
"/js/main.99428fe036b8f1e6ec2a.hot-update.js": "/js/main.99428fe036b8f1e6ec2a.hot-update.js",
|
||||||
|
"/js/main.7af48b09abf42b1527d0.hot-update.js": "/js/main.7af48b09abf42b1527d0.hot-update.js",
|
||||||
|
"/js/main.7c2ec74ea1f2d2a64082.hot-update.js": "/js/main.7c2ec74ea1f2d2a64082.hot-update.js",
|
||||||
|
"/js/main.4b1af8e5fbdd42203bbd.hot-update.js": "/js/main.4b1af8e5fbdd42203bbd.hot-update.js",
|
||||||
|
"/js/main.6dfdd92d74d0221cb4cd.hot-update.js": "/js/main.6dfdd92d74d0221cb4cd.hot-update.js",
|
||||||
|
"/js/main.93c765fa5b5967778dbb.hot-update.js": "/js/main.93c765fa5b5967778dbb.hot-update.js",
|
||||||
|
"/js/main.145d13c9c0c8a48c8e21.hot-update.js": "/js/main.145d13c9c0c8a48c8e21.hot-update.js",
|
||||||
|
"/js/main.1ac11f50fac4ad096666.hot-update.js": "/js/main.1ac11f50fac4ad096666.hot-update.js",
|
||||||
|
"/js/main.cf5ad55fa219f6c47f6b.hot-update.js": "/js/main.cf5ad55fa219f6c47f6b.hot-update.js",
|
||||||
|
"/js/main.ddad7197a46610777620.hot-update.js": "/js/main.ddad7197a46610777620.hot-update.js",
|
||||||
|
"/js/main.e5b4b5c52b1117e66b89.hot-update.js": "/js/main.e5b4b5c52b1117e66b89.hot-update.js",
|
||||||
|
"/js/main.214828387e374ce49d4a.hot-update.js": "/js/main.214828387e374ce49d4a.hot-update.js",
|
||||||
|
"/js/main.be1180181c2d52cabd7a.hot-update.js": "/js/main.be1180181c2d52cabd7a.hot-update.js",
|
||||||
|
"/js/main.0ba2839f023a6d5c2d74.hot-update.js": "/js/main.0ba2839f023a6d5c2d74.hot-update.js",
|
||||||
|
"/js/main.d12911154ed30be00c3c.hot-update.js": "/js/main.d12911154ed30be00c3c.hot-update.js",
|
||||||
|
"/js/main.573ef61235e9257d0090.hot-update.js": "/js/main.573ef61235e9257d0090.hot-update.js",
|
||||||
|
"/js/main.45fec0e5951a53dbffac.hot-update.js": "/js/main.45fec0e5951a53dbffac.hot-update.js",
|
||||||
|
"/js/main.55f54baec0450f8de63b.hot-update.js": "/js/main.55f54baec0450f8de63b.hot-update.js",
|
||||||
|
"/js/main.6a353752cfa45cbaf1dd.hot-update.js": "/js/main.6a353752cfa45cbaf1dd.hot-update.js",
|
||||||
|
"/js/main.7b9038028478c4f76ffe.hot-update.js": "/js/main.7b9038028478c4f76ffe.hot-update.js",
|
||||||
|
"/js/main.23bd83f443e3593ecc35.hot-update.js": "/js/main.23bd83f443e3593ecc35.hot-update.js",
|
||||||
|
"/js/main.392dd076165cae4a780d.hot-update.js": "/js/main.392dd076165cae4a780d.hot-update.js",
|
||||||
|
"/js/main.49753cee6c18ab061e21.hot-update.js": "/js/main.49753cee6c18ab061e21.hot-update.js",
|
||||||
|
"/js/main.a73a514eb28a645adfea.hot-update.js": "/js/main.a73a514eb28a645adfea.hot-update.js",
|
||||||
|
"/js/main.6d18ebb5943b27562ba9.hot-update.js": "/js/main.6d18ebb5943b27562ba9.hot-update.js",
|
||||||
|
"/js/main.9d0d01b4e3c3fb47d4d5.hot-update.js": "/js/main.9d0d01b4e3c3fb47d4d5.hot-update.js",
|
||||||
|
"/js/main.7728e0d0bdca2c20f459.hot-update.js": "/js/main.7728e0d0bdca2c20f459.hot-update.js",
|
||||||
|
"/js/main.81d0db7b2f00813f74c7.hot-update.js": "/js/main.81d0db7b2f00813f74c7.hot-update.js",
|
||||||
|
"/js/main.a28cd765165d48725eca.hot-update.js": "/js/main.a28cd765165d48725eca.hot-update.js",
|
||||||
|
"/js/main.8de8c3e7c3b977cc6035.hot-update.js": "/js/main.8de8c3e7c3b977cc6035.hot-update.js",
|
||||||
|
"/js/main.782da6a66568bcd59743.hot-update.js": "/js/main.782da6a66568bcd59743.hot-update.js",
|
||||||
|
"/js/main.60b493308d7357839512.hot-update.js": "/js/main.60b493308d7357839512.hot-update.js",
|
||||||
|
"/js/main.33902c08d1e9836b964e.hot-update.js": "/js/main.33902c08d1e9836b964e.hot-update.js",
|
||||||
|
"/js/main.fe1d2a997ea2be557d9f.hot-update.js": "/js/main.fe1d2a997ea2be557d9f.hot-update.js",
|
||||||
|
"/js/main.766abe0541c6121e1924.hot-update.js": "/js/main.766abe0541c6121e1924.hot-update.js",
|
||||||
|
"/js/main.1bd0994d893a03186dfc.hot-update.js": "/js/main.1bd0994d893a03186dfc.hot-update.js",
|
||||||
|
"/js/main.b977ced9ab4081433316.hot-update.js": "/js/main.b977ced9ab4081433316.hot-update.js",
|
||||||
|
"/js/main.f80f8d4812f554d678ad.hot-update.js": "/js/main.f80f8d4812f554d678ad.hot-update.js",
|
||||||
|
"/js/main.113837549e4562048c31.hot-update.js": "/js/main.113837549e4562048c31.hot-update.js",
|
||||||
|
"/js/main.8efa86ec49d1abb3b1f9.hot-update.js": "/js/main.8efa86ec49d1abb3b1f9.hot-update.js",
|
||||||
|
"/js/main.4dc98433f633871bcc37.hot-update.js": "/js/main.4dc98433f633871bcc37.hot-update.js",
|
||||||
|
"/js/main.c1bdb95bec9f98ca3621.hot-update.js": "/js/main.c1bdb95bec9f98ca3621.hot-update.js",
|
||||||
|
"/js/main.4b537e8e13000cbe58a6.hot-update.js": "/js/main.4b537e8e13000cbe58a6.hot-update.js",
|
||||||
|
"/js/main.45c7868f8c1bcbd2447a.hot-update.js": "/js/main.45c7868f8c1bcbd2447a.hot-update.js",
|
||||||
|
"/js/main.71db541c42b4649a344d.hot-update.js": "/js/main.71db541c42b4649a344d.hot-update.js",
|
||||||
|
"/js/main.68624de1ade8d60b9e00.hot-update.js": "/js/main.68624de1ade8d60b9e00.hot-update.js",
|
||||||
|
"/js/main.aadae39c079f9b7a1ee6.hot-update.js": "/js/main.aadae39c079f9b7a1ee6.hot-update.js",
|
||||||
|
"/js/main.680573b5ab7f89edc08d.hot-update.js": "/js/main.680573b5ab7f89edc08d.hot-update.js",
|
||||||
|
"/js/main.43c573f053170ed1c62a.hot-update.js": "/js/main.43c573f053170ed1c62a.hot-update.js",
|
||||||
|
"/js/main.3953b45d826e1a49afcf.hot-update.js": "/js/main.3953b45d826e1a49afcf.hot-update.js",
|
||||||
|
"/js/main.5badeee6f9276e7b7c06.hot-update.js": "/js/main.5badeee6f9276e7b7c06.hot-update.js",
|
||||||
|
"/js/main.ddb99e8b37bc0e95411c.hot-update.js": "/js/main.ddb99e8b37bc0e95411c.hot-update.js",
|
||||||
|
"/js/main.f05d5a46f5caf1f2995d.hot-update.js": "/js/main.f05d5a46f5caf1f2995d.hot-update.js",
|
||||||
|
"/js/main.e32aaf5fb351a8406d51.hot-update.js": "/js/main.e32aaf5fb351a8406d51.hot-update.js",
|
||||||
|
"/js/main.f7a0069dfb0c28663a62.hot-update.js": "/js/main.f7a0069dfb0c28663a62.hot-update.js",
|
||||||
|
"/js/main.6d39e5cc8cb2e945d6b3.hot-update.js": "/js/main.6d39e5cc8cb2e945d6b3.hot-update.js",
|
||||||
|
"/js/main.24cc22fcf93008baf29d.hot-update.js": "/js/main.24cc22fcf93008baf29d.hot-update.js",
|
||||||
|
"/js/main.3516ce8b8eb43faf298c.hot-update.js": "/js/main.3516ce8b8eb43faf298c.hot-update.js",
|
||||||
|
"/js/main.b5292435a660203bf811.hot-update.js": "/js/main.b5292435a660203bf811.hot-update.js",
|
||||||
|
"/js/main.13989f10bc3239c4c41f.hot-update.js": "/js/main.13989f10bc3239c4c41f.hot-update.js",
|
||||||
|
"/js/main.8c3cab25947747b4b0b3.hot-update.js": "/js/main.8c3cab25947747b4b0b3.hot-update.js",
|
||||||
|
"/js/main.5c20da0efc58cc7ba8b3.hot-update.js": "/js/main.5c20da0efc58cc7ba8b3.hot-update.js",
|
||||||
|
"/js/main.66e5ed2e6cc14a0d36ae.hot-update.js": "/js/main.66e5ed2e6cc14a0d36ae.hot-update.js",
|
||||||
|
"/js/main.0c09a0e989bcc9758370.hot-update.js": "/js/main.0c09a0e989bcc9758370.hot-update.js",
|
||||||
|
"/js/main.ab58ad6e06d96cf8fa73.hot-update.js": "/js/main.ab58ad6e06d96cf8fa73.hot-update.js",
|
||||||
|
"/js/main.014ff3765c75eb61f1d4.hot-update.js": "/js/main.014ff3765c75eb61f1d4.hot-update.js",
|
||||||
|
"/js/main.bdeb8ceaa88f727f8fb6.hot-update.js": "/js/main.bdeb8ceaa88f727f8fb6.hot-update.js",
|
||||||
|
"/js/main.9973034b32ebdc63eb82.hot-update.js": "/js/main.9973034b32ebdc63eb82.hot-update.js",
|
||||||
|
"/js/main.9992685a6ae68c33b6c5.hot-update.js": "/js/main.9992685a6ae68c33b6c5.hot-update.js",
|
||||||
|
"/js/main.b760fcd3b586a00f06be.hot-update.js": "/js/main.b760fcd3b586a00f06be.hot-update.js",
|
||||||
|
"/js/main.9dc70b69960cc8fc63be.hot-update.js": "/js/main.9dc70b69960cc8fc63be.hot-update.js",
|
||||||
|
"/js/main.e54f1b41b0056df66ebe.hot-update.js": "/js/main.e54f1b41b0056df66ebe.hot-update.js",
|
||||||
|
"/js/main.b3d9c72543f1cc629eca.hot-update.js": "/js/main.b3d9c72543f1cc629eca.hot-update.js",
|
||||||
|
"/js/main.a6b5bc01c37b0b8c505a.hot-update.js": "/js/main.a6b5bc01c37b0b8c505a.hot-update.js",
|
||||||
|
"/js/main.37820b9541b87f46b5ab.hot-update.js": "/js/main.37820b9541b87f46b5ab.hot-update.js",
|
||||||
|
"/js/main.657bfe90614336953776.hot-update.js": "/js/main.657bfe90614336953776.hot-update.js",
|
||||||
|
"/js/main.c32cd8f6b2b69da9f69b.hot-update.js": "/js/main.c32cd8f6b2b69da9f69b.hot-update.js",
|
||||||
|
"/js/main.0f7a1e4328a6c4020b06.hot-update.js": "/js/main.0f7a1e4328a6c4020b06.hot-update.js",
|
||||||
|
"/js/main.6f7d46764921c16af0c3.hot-update.js": "/js/main.6f7d46764921c16af0c3.hot-update.js",
|
||||||
|
"/js/main.a640dda4a79379ab0d71.hot-update.js": "/js/main.a640dda4a79379ab0d71.hot-update.js",
|
||||||
|
"/js/main.9d51e284c5c6da62c608.hot-update.js": "/js/main.9d51e284c5c6da62c608.hot-update.js",
|
||||||
|
"/js/main.2175685495a1e1f69c7b.hot-update.js": "/js/main.2175685495a1e1f69c7b.hot-update.js",
|
||||||
|
"/js/main.2150d320284b6237889c.hot-update.js": "/js/main.2150d320284b6237889c.hot-update.js",
|
||||||
|
"/js/main.b8a254bed361a09ff366.hot-update.js": "/js/main.b8a254bed361a09ff366.hot-update.js",
|
||||||
|
"/js/main.0b3526ea8bfd5256691a.hot-update.js": "/js/main.0b3526ea8bfd5256691a.hot-update.js",
|
||||||
|
"/js/main.1cea96ea65fa4202ca3c.hot-update.js": "/js/main.1cea96ea65fa4202ca3c.hot-update.js",
|
||||||
|
"/js/main.8bad8f660e3c6f7bfc0f.hot-update.js": "/js/main.8bad8f660e3c6f7bfc0f.hot-update.js",
|
||||||
|
"/js/main.72b032a1aecb09cfe6a2.hot-update.js": "/js/main.72b032a1aecb09cfe6a2.hot-update.js",
|
||||||
|
"/js/main.02b3767fb3fe1ca0542e.hot-update.js": "/js/main.02b3767fb3fe1ca0542e.hot-update.js",
|
||||||
|
"/js/main.78cfd839671f52b65307.hot-update.js": "/js/main.78cfd839671f52b65307.hot-update.js",
|
||||||
|
"/js/main.d12832c9351968e74050.hot-update.js": "/js/main.d12832c9351968e74050.hot-update.js",
|
||||||
|
"/js/main.6d2c73ad0bf43e6bb5be.hot-update.js": "/js/main.6d2c73ad0bf43e6bb5be.hot-update.js",
|
||||||
|
"/js/main.9ad41591f7f3af3cecfe.hot-update.js": "/js/main.9ad41591f7f3af3cecfe.hot-update.js",
|
||||||
|
"/js/main.2215c5e36d89ce7a343e.hot-update.js": "/js/main.2215c5e36d89ce7a343e.hot-update.js",
|
||||||
|
"/js/main.6ff01a84a6d8c537ae38.hot-update.js": "/js/main.6ff01a84a6d8c537ae38.hot-update.js",
|
||||||
|
"/js/main.23840c43fe4cf577a15d.hot-update.js": "/js/main.23840c43fe4cf577a15d.hot-update.js",
|
||||||
|
"/js/main.5f0e5ecf4e8fe2ec096e.hot-update.js": "/js/main.5f0e5ecf4e8fe2ec096e.hot-update.js",
|
||||||
|
"/js/main.7131a1b0b9c7105ff539.hot-update.js": "/js/main.7131a1b0b9c7105ff539.hot-update.js",
|
||||||
|
"/js/main.d7309f447054aabfa409.hot-update.js": "/js/main.d7309f447054aabfa409.hot-update.js",
|
||||||
|
"/js/main.3ac39eb05bbd34bfac97.hot-update.js": "/js/main.3ac39eb05bbd34bfac97.hot-update.js",
|
||||||
|
"/js/main.b214f9b3b3ecc253ebf1.hot-update.js": "/js/main.b214f9b3b3ecc253ebf1.hot-update.js",
|
||||||
|
"/js/main.71a9533ff4ae330cccf3.hot-update.js": "/js/main.71a9533ff4ae330cccf3.hot-update.js",
|
||||||
|
"/js/main.ba1144e1135a00e461c7.hot-update.js": "/js/main.ba1144e1135a00e461c7.hot-update.js",
|
||||||
|
"/js/main.bf7c574279d8acce16aa.hot-update.js": "/js/main.bf7c574279d8acce16aa.hot-update.js",
|
||||||
|
"/js/main.2d291ea3de6f1da7058b.hot-update.js": "/js/main.2d291ea3de6f1da7058b.hot-update.js",
|
||||||
|
"/js/main.ba6d4d2a8857566c2ec5.hot-update.js": "/js/main.ba6d4d2a8857566c2ec5.hot-update.js",
|
||||||
|
"/js/main.5645b3eeecc1b560614b.hot-update.js": "/js/main.5645b3eeecc1b560614b.hot-update.js",
|
||||||
|
"/js/main.e84e10d63ed04fd272cc.hot-update.js": "/js/main.e84e10d63ed04fd272cc.hot-update.js",
|
||||||
|
"/js/main.f04fc23ca1938e02fecc.hot-update.js": "/js/main.f04fc23ca1938e02fecc.hot-update.js",
|
||||||
|
"/js/main.c8f623bc44d30e89ead8.hot-update.js": "/js/main.c8f623bc44d30e89ead8.hot-update.js",
|
||||||
|
"/js/main.0280d7a9b768ba9a2c93.hot-update.js": "/js/main.0280d7a9b768ba9a2c93.hot-update.js",
|
||||||
|
"/js/main.f8a594d8edfc9b0000f1.hot-update.js": "/js/main.f8a594d8edfc9b0000f1.hot-update.js",
|
||||||
|
"/js/main.ed950c2728a18e80ef97.hot-update.js": "/js/main.ed950c2728a18e80ef97.hot-update.js",
|
||||||
|
"/js/main.e5856a633b84a0158c7d.hot-update.js": "/js/main.e5856a633b84a0158c7d.hot-update.js",
|
||||||
|
"/js/main.0abc8a7cbdcf0be7da0e.hot-update.js": "/js/main.0abc8a7cbdcf0be7da0e.hot-update.js",
|
||||||
|
"/js/main.b2f5c2c22feadd2b4c0c.hot-update.js": "/js/main.b2f5c2c22feadd2b4c0c.hot-update.js",
|
||||||
|
"/js/main.4d8346cf984a588b6f13.hot-update.js": "/js/main.4d8346cf984a588b6f13.hot-update.js",
|
||||||
|
"/js/main.53c5573b85a9e73d1758.hot-update.js": "/js/main.53c5573b85a9e73d1758.hot-update.js",
|
||||||
|
"/js/main.95a3639e43650ef3faa5.hot-update.js": "/js/main.95a3639e43650ef3faa5.hot-update.js",
|
||||||
|
"/js/main.1d8220b4ab8ca4dc8a51.hot-update.js": "/js/main.1d8220b4ab8ca4dc8a51.hot-update.js",
|
||||||
|
"/js/main.7f9b84329de8111fae87.hot-update.js": "/js/main.7f9b84329de8111fae87.hot-update.js",
|
||||||
|
"/js/main.36b87f3da6ef386e6fc5.hot-update.js": "/js/main.36b87f3da6ef386e6fc5.hot-update.js",
|
||||||
|
"/js/main.71e32fb234f1fe2b8010.hot-update.js": "/js/main.71e32fb234f1fe2b8010.hot-update.js",
|
||||||
|
"/js/main.1b05b55650fcf1f390d3.hot-update.js": "/js/main.1b05b55650fcf1f390d3.hot-update.js",
|
||||||
|
"/js/main.fb5179244b436eaa3615.hot-update.js": "/js/main.fb5179244b436eaa3615.hot-update.js",
|
||||||
|
"/js/main.40fd3d4d2879012e29b8.hot-update.js": "/js/main.40fd3d4d2879012e29b8.hot-update.js",
|
||||||
|
"/js/main.4b9478fffdeba2a4b93b.hot-update.js": "/js/main.4b9478fffdeba2a4b93b.hot-update.js",
|
||||||
|
"/js/main.5af5027b0ae287a82f35.hot-update.js": "/js/main.5af5027b0ae287a82f35.hot-update.js",
|
||||||
|
"/js/main.52237080c7c31898ab5a.hot-update.js": "/js/main.52237080c7c31898ab5a.hot-update.js",
|
||||||
|
"/js/main.979c5eedc1444456464e.hot-update.js": "/js/main.979c5eedc1444456464e.hot-update.js",
|
||||||
|
"/js/main.9017fe0f3183ac0f365d.hot-update.js": "/js/main.9017fe0f3183ac0f365d.hot-update.js",
|
||||||
|
"/js/main.dfc8f8e1cd5a747133c9.hot-update.js": "/js/main.dfc8f8e1cd5a747133c9.hot-update.js",
|
||||||
|
"/js/main.054acdb0153a952d0c1b.hot-update.js": "/js/main.054acdb0153a952d0c1b.hot-update.js",
|
||||||
|
"/js/main.1b7b81d03c708864d83f.hot-update.js": "/js/main.1b7b81d03c708864d83f.hot-update.js",
|
||||||
|
"/js/main.0e1d7e4955c92a4a6433.hot-update.js": "/js/main.0e1d7e4955c92a4a6433.hot-update.js",
|
||||||
|
"/js/main.6d20f9f009d9fa3b6c33.hot-update.js": "/js/main.6d20f9f009d9fa3b6c33.hot-update.js",
|
||||||
|
"/js/main.29cb935e6d27bab5cc6f.hot-update.js": "/js/main.29cb935e6d27bab5cc6f.hot-update.js",
|
||||||
|
"/js/main.633978191e0ccd858642.hot-update.js": "/js/main.633978191e0ccd858642.hot-update.js",
|
||||||
|
"/js/main.faf763c5c889e90c24d3.hot-update.js": "/js/main.faf763c5c889e90c24d3.hot-update.js",
|
||||||
|
"/js/main.0ee392e693e07d2adc39.hot-update.js": "/js/main.0ee392e693e07d2adc39.hot-update.js",
|
||||||
|
"/js/main.f04167e5bde2e8ba1328.hot-update.js": "/js/main.f04167e5bde2e8ba1328.hot-update.js",
|
||||||
|
"/js/main.ad5ce2ace93bd4885e2d.hot-update.js": "/js/main.ad5ce2ace93bd4885e2d.hot-update.js",
|
||||||
|
"/js/main.0318bd00035642cab7dc.hot-update.js": "/js/main.0318bd00035642cab7dc.hot-update.js",
|
||||||
|
"/js/main.6f3d3c5df9f7de3bad94.hot-update.js": "/js/main.6f3d3c5df9f7de3bad94.hot-update.js",
|
||||||
|
"/js/main.cd07d28a55c157b257a0.hot-update.js": "/js/main.cd07d28a55c157b257a0.hot-update.js",
|
||||||
|
"/js/main.3ec8510bd27897443ad8.hot-update.js": "/js/main.3ec8510bd27897443ad8.hot-update.js",
|
||||||
|
"/js/main.b06803d15413598cf921.hot-update.js": "/js/main.b06803d15413598cf921.hot-update.js",
|
||||||
|
"/js/main.bb7669043d86cf1071be.hot-update.js": "/js/main.bb7669043d86cf1071be.hot-update.js",
|
||||||
|
"/js/main.7dfd9e155cee0aa2a655.hot-update.js": "/js/main.7dfd9e155cee0aa2a655.hot-update.js",
|
||||||
|
"/js/main.becd5b839417ba9cc61f.hot-update.js": "/js/main.becd5b839417ba9cc61f.hot-update.js",
|
||||||
|
"/js/main.3fa003535cf601923d82.hot-update.js": "/js/main.3fa003535cf601923d82.hot-update.js",
|
||||||
|
"/js/main.4a56e0b1dd3dbcc32341.hot-update.js": "/js/main.4a56e0b1dd3dbcc32341.hot-update.js",
|
||||||
|
"/js/main.0d7a61917a0a8974c35f.hot-update.js": "/js/main.0d7a61917a0a8974c35f.hot-update.js",
|
||||||
|
"/js/main.a091a3a1923781c21dc4.hot-update.js": "/js/main.a091a3a1923781c21dc4.hot-update.js",
|
||||||
|
"/js/main.38c7c1a4b64333d9f5c3.hot-update.js": "/js/main.38c7c1a4b64333d9f5c3.hot-update.js",
|
||||||
|
"/js/main.5aeb23d042dc02182f9d.hot-update.js": "/js/main.5aeb23d042dc02182f9d.hot-update.js",
|
||||||
|
"/js/main.626ffbf9740c4905f231.hot-update.js": "/js/main.626ffbf9740c4905f231.hot-update.js",
|
||||||
|
"/js/main.c7362f11fed7aafdb123.hot-update.js": "/js/main.c7362f11fed7aafdb123.hot-update.js",
|
||||||
|
"/js/main.b04a05c0843829183afe.hot-update.js": "/js/main.b04a05c0843829183afe.hot-update.js",
|
||||||
|
"/js/main.461fa5fdd23afe6d9fe6.hot-update.js": "/js/main.461fa5fdd23afe6d9fe6.hot-update.js",
|
||||||
|
"/js/main.e0a1840ae50bf07401a0.hot-update.js": "/js/main.e0a1840ae50bf07401a0.hot-update.js",
|
||||||
|
"/js/main.8b25371935db26e8c4b4.hot-update.js": "/js/main.8b25371935db26e8c4b4.hot-update.js",
|
||||||
|
"/js/main.b84c56a5501bf599ddef.hot-update.js": "/js/main.b84c56a5501bf599ddef.hot-update.js",
|
||||||
|
"/js/main.0ea41ac8e5a5b827183d.hot-update.js": "/js/main.0ea41ac8e5a5b827183d.hot-update.js",
|
||||||
|
"/js/main.328a6e59c166775f5876.hot-update.js": "/js/main.328a6e59c166775f5876.hot-update.js",
|
||||||
|
"/js/main.595a3d7a93987329ca5b.hot-update.js": "/js/main.595a3d7a93987329ca5b.hot-update.js",
|
||||||
|
"/js/main.ad79a5b7d119ed6c423d.hot-update.js": "/js/main.ad79a5b7d119ed6c423d.hot-update.js",
|
||||||
|
"/js/main.d08edda6d82bd9398e71.hot-update.js": "/js/main.d08edda6d82bd9398e71.hot-update.js",
|
||||||
|
"/js/main.66c83d5d6ff775619e6a.hot-update.js": "/js/main.66c83d5d6ff775619e6a.hot-update.js",
|
||||||
|
"/js/main.acc4d5e33a6f6db74e99.hot-update.js": "/js/main.acc4d5e33a6f6db74e99.hot-update.js",
|
||||||
|
"/js/main.c7608c4460d04dc68a7b.hot-update.js": "/js/main.c7608c4460d04dc68a7b.hot-update.js",
|
||||||
|
"/js/main.9560166479247c1360a4.hot-update.js": "/js/main.9560166479247c1360a4.hot-update.js",
|
||||||
|
"/js/main.2bfbfe88c7cbaa237cdf.hot-update.js": "/js/main.2bfbfe88c7cbaa237cdf.hot-update.js",
|
||||||
|
"/js/main.1727b96758d6ec12ec1a.hot-update.js": "/js/main.1727b96758d6ec12ec1a.hot-update.js",
|
||||||
|
"/js/main.18285ba868e3c2b26cdb.hot-update.js": "/js/main.18285ba868e3c2b26cdb.hot-update.js",
|
||||||
|
"/js/main.fca0118a70bd996c3a3a.hot-update.js": "/js/main.fca0118a70bd996c3a3a.hot-update.js",
|
||||||
|
"/js/main.adabd48fe18c1ed75a9f.hot-update.js": "/js/main.adabd48fe18c1ed75a9f.hot-update.js",
|
||||||
|
"/js/main.a86fbcc56fdd4977f174.hot-update.js": "/js/main.a86fbcc56fdd4977f174.hot-update.js",
|
||||||
|
"/js/main.9cd6b1916fdcf8b0e3e7.hot-update.js": "/js/main.9cd6b1916fdcf8b0e3e7.hot-update.js",
|
||||||
|
"/js/main.72419a76c9b4b47b6963.hot-update.js": "/js/main.72419a76c9b4b47b6963.hot-update.js",
|
||||||
|
"/js/main.4dea1104f50471aa6f64.hot-update.js": "/js/main.4dea1104f50471aa6f64.hot-update.js",
|
||||||
|
"/js/main.26154029797256dee15b.hot-update.js": "/js/main.26154029797256dee15b.hot-update.js",
|
||||||
|
"/js/main.f76525f7fe55e49591da.hot-update.js": "/js/main.f76525f7fe55e49591da.hot-update.js",
|
||||||
|
"/js/main.06e4485426b6a62d5fa2.hot-update.js": "/js/main.06e4485426b6a62d5fa2.hot-update.js",
|
||||||
|
"/js/main.e8d66784dbf3edfacc70.hot-update.js": "/js/main.e8d66784dbf3edfacc70.hot-update.js",
|
||||||
|
"/js/main.3d985e37671fe9bd3e0c.hot-update.js": "/js/main.3d985e37671fe9bd3e0c.hot-update.js",
|
||||||
|
"/js/main.44e26c8753354ab6eacc.hot-update.js": "/js/main.44e26c8753354ab6eacc.hot-update.js",
|
||||||
|
"/js/main.6aa622630357ff6b92bb.hot-update.js": "/js/main.6aa622630357ff6b92bb.hot-update.js",
|
||||||
|
"/js/main.36ee2cbe2e1cdf1d2db2.hot-update.js": "/js/main.36ee2cbe2e1cdf1d2db2.hot-update.js",
|
||||||
|
"/js/main.dff69ffc5c5136e8a59f.hot-update.js": "/js/main.dff69ffc5c5136e8a59f.hot-update.js",
|
||||||
|
"/js/main.74df9c1a881e7060c06a.hot-update.js": "/js/main.74df9c1a881e7060c06a.hot-update.js",
|
||||||
|
"/js/main.c71833bbfefbfa17deb0.hot-update.js": "/js/main.c71833bbfefbfa17deb0.hot-update.js",
|
||||||
|
"/js/main.ea3b3d11f5ba575cc1a9.hot-update.js": "/js/main.ea3b3d11f5ba575cc1a9.hot-update.js",
|
||||||
|
"/js/main.375a09e047f6de44b751.hot-update.js": "/js/main.375a09e047f6de44b751.hot-update.js",
|
||||||
|
"/js/main.b88e01086aff7e390931.hot-update.js": "/js/main.b88e01086aff7e390931.hot-update.js",
|
||||||
|
"/js/main.bdafae541f4950dfb102.hot-update.js": "/js/main.bdafae541f4950dfb102.hot-update.js",
|
||||||
|
"/js/main.2b4522ef2be08f9b6b2a.hot-update.js": "/js/main.2b4522ef2be08f9b6b2a.hot-update.js",
|
||||||
|
"/js/main.1cf0f751d686b23b4d9c.hot-update.js": "/js/main.1cf0f751d686b23b4d9c.hot-update.js",
|
||||||
|
"/js/main.7ad2beff93a3ccd5eecc.hot-update.js": "/js/main.7ad2beff93a3ccd5eecc.hot-update.js",
|
||||||
|
"/js/main.8d29944d11794f6008fc.hot-update.js": "/js/main.8d29944d11794f6008fc.hot-update.js",
|
||||||
|
"/js/main.14ac674beee1c96cc908.hot-update.js": "/js/main.14ac674beee1c96cc908.hot-update.js",
|
||||||
|
"/js/main.4df8db8fbc00f790b35f.hot-update.js": "/js/main.4df8db8fbc00f790b35f.hot-update.js",
|
||||||
|
"/js/main.83bd99ee8fab0305549a.hot-update.js": "/js/main.83bd99ee8fab0305549a.hot-update.js",
|
||||||
|
"/js/main.b98a50855de0e8b3f1d7.hot-update.js": "/js/main.b98a50855de0e8b3f1d7.hot-update.js",
|
||||||
|
"/js/main.f172526d87e5bcf4167f.hot-update.js": "/js/main.f172526d87e5bcf4167f.hot-update.js",
|
||||||
|
"/js/main.39f5347e2c133fadf7d9.hot-update.js": "/js/main.39f5347e2c133fadf7d9.hot-update.js",
|
||||||
|
"/js/main.294c300a035f6d93d7ee.hot-update.js": "/js/main.294c300a035f6d93d7ee.hot-update.js",
|
||||||
|
"/js/main.ebe948263e7b010f01c6.hot-update.js": "/js/main.ebe948263e7b010f01c6.hot-update.js",
|
||||||
|
"/js/main.2e664ac19e1847cd6cd4.hot-update.js": "/js/main.2e664ac19e1847cd6cd4.hot-update.js"
|
||||||
}
|
}
|
||||||
|
|||||||
2
public/sass/invoice.scss
vendored
2
public/sass/invoice.scss
vendored
@@ -1,7 +1,7 @@
|
|||||||
// Colors
|
// Colors
|
||||||
$text: #1c1d1f;
|
$text: #1c1d1f;
|
||||||
$text-muted: rgba($text, 0.7);
|
$text-muted: rgba($text, 0.7);
|
||||||
$light_background: #f6f6f6;
|
$light_background: #f4f6f6;
|
||||||
$light_mode_border: #F8F8F8;
|
$light_mode_border: #F8F8F8;
|
||||||
$theme: #00BC7E;
|
$theme: #00BC7E;
|
||||||
|
|
||||||
|
|||||||
@@ -125,6 +125,7 @@
|
|||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
color: #1b2539;
|
||||||
}
|
}
|
||||||
|
|
||||||
#auth {
|
#auth {
|
||||||
|
|||||||
@@ -38,6 +38,15 @@
|
|||||||
background: rgba($theme, .1);
|
background: rgba($theme, .1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.theme-solid {
|
||||||
|
color: white;
|
||||||
|
background: $theme;
|
||||||
|
|
||||||
|
path {
|
||||||
|
fill: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.danger {
|
&.danger {
|
||||||
color: $danger;
|
color: $danger;
|
||||||
background: rgba($danger, .1);
|
background: rgba($danger, .1);
|
||||||
|
|||||||
@@ -32,6 +32,11 @@
|
|||||||
color: $yellow;
|
color: $yellow;
|
||||||
background: rgba($yellow, 0.1);
|
background: rgba($yellow, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.green {
|
||||||
|
color: $theme;
|
||||||
|
background: rgba($theme, 0.1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 1024px) {
|
@media only screen and (max-width: 1024px) {
|
||||||
|
|||||||
145
resources/js/components/Others/PlanPricingTables.vue
Normal file
145
resources/js/components/Others/PlanPricingTables.vue
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
<template>
|
||||||
|
<div class="plans-wrapper">
|
||||||
|
<article class="plan" v-for="(plan, i) in plans" :key="i">
|
||||||
|
<div class="plan-wrapper">
|
||||||
|
<header class="plan-header">
|
||||||
|
<div class="icon">
|
||||||
|
<hard-drive-icon size="26"></hard-drive-icon>
|
||||||
|
</div>
|
||||||
|
<h1 class="title">{{ plan.data.attributes.name }}</h1>
|
||||||
|
<h2 class="description">{{ plan.data.attributes.description }}</h2>
|
||||||
|
</header>
|
||||||
|
<section class="plan-features">
|
||||||
|
<b class="storage-size">{{ plan.data.attributes.capacity_formatted }}</b>
|
||||||
|
<span class="storage-description">Of Storage Capacity</span>
|
||||||
|
</section>
|
||||||
|
<footer class="plan-footer">
|
||||||
|
<b class="price">
|
||||||
|
{{ plan.data.attributes.price }} USD/Mo.
|
||||||
|
</b>
|
||||||
|
<ButtonBase @click.native="selectPlan(plan)" type="submit" button-style="secondary" class="sign-in-button">
|
||||||
|
Sign Up
|
||||||
|
</ButtonBase>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ButtonBase from '@/components/FilesView/ButtonBase'
|
||||||
|
import {HardDriveIcon} from "vue-feather-icons"
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'PlanPricingTables',
|
||||||
|
components: {
|
||||||
|
HardDriveIcon,
|
||||||
|
ButtonBase,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
plans: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selectPlan(plan) {
|
||||||
|
this.$emit('selected-plan', plan)
|
||||||
|
this.$router.push({name: 'UpgradeBilling'})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
axios.get('/api/public/pricing')
|
||||||
|
.then(response => {
|
||||||
|
this.plans = response.data.data
|
||||||
|
this.$emit('load', false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.plan {
|
||||||
|
text-align: center;
|
||||||
|
flex: 0 0 33%;
|
||||||
|
padding: 0 25px;
|
||||||
|
|
||||||
|
.plan-wrapper {
|
||||||
|
box-shadow: 0 7px 20px 5px hsla(220, 36%, 16%, 0.03);
|
||||||
|
padding: 25px;
|
||||||
|
border-radius: 8px;
|
||||||
|
@include transition;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
@include transform(translateY(-20px) scale(1.05));
|
||||||
|
box-shadow: 0 15px 25px 5px hsla(220, 36%, 16%, 0.08);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-header {
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
color: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
@include font-size(22);
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
@include font-size(14);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-features {
|
||||||
|
margin: 65px 0;
|
||||||
|
|
||||||
|
.storage-size {
|
||||||
|
@include font-size(48);
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.storage-description {
|
||||||
|
display: block;
|
||||||
|
@include font-size(15);
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-footer {
|
||||||
|
|
||||||
|
.sign-in-button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
color: $theme;
|
||||||
|
@include font-size(18);
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.plans-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin: 0 -25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1024px) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -257,7 +257,7 @@
|
|||||||
|
|
||||||
span, a.page-link {
|
span, a.page-link {
|
||||||
@include font-size(15);
|
@include font-size(15);
|
||||||
font-weight: 600;
|
font-weight: 700;
|
||||||
padding: 10px 35px 10px 0;
|
padding: 10px 35px 10px 0;
|
||||||
display: block;
|
display: block;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
@import '@assets/vue-file-manager/_mixins';
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.content-sidebar {
|
.content-sidebar {
|
||||||
background: linear-gradient(0deg, rgba(246, 245, 241, 0.4) 0%, rgba(243, 244, 246, 0.4) 100%);
|
//background: linear-gradient(0deg, rgba(246, 245, 241, 0.4) 0%, rgba(243, 244, 246, 0.4) 100%);
|
||||||
|
background: rgba($light_background, 0.6);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|||||||
@@ -106,7 +106,8 @@
|
|||||||
@import '@assets/vue-file-manager/_mixins';
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.menu-bar {
|
.menu-bar {
|
||||||
background: linear-gradient(180deg, rgba(246, 245, 241, 0.8) 0%, rgba(243, 244, 246, 0.8) 100%);
|
//background: linear-gradient(180deg, rgba(246, 245, 241, 0.8) 0%, rgba(243, 244, 246, 0.8) 100%);
|
||||||
|
background: $light_background;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
78
resources/js/router.js
vendored
78
resources/js/router.js
vendored
@@ -10,14 +10,19 @@ import ForgottenPassword from './views/Auth/ForgottenPassword'
|
|||||||
import CreateNewPassword from './views/Auth/CreateNewPassword'
|
import CreateNewPassword from './views/Auth/CreateNewPassword'
|
||||||
|
|
||||||
import Settings from './views/Profile'
|
import Settings from './views/Profile'
|
||||||
import Profile from './views/User/Settings'
|
|
||||||
import Storage from './views/User/Storage'
|
import Storage from './views/User/Storage'
|
||||||
|
import Profile from './views/User/Settings'
|
||||||
import Invoice from './views/User/Invoices'
|
import Invoice from './views/User/Invoices'
|
||||||
|
import Password from './views/User/Password'
|
||||||
|
import Subscription from './views/User/Subscription'
|
||||||
|
|
||||||
import Trash from './views/FilePages/Trash'
|
import Trash from './views/FilePages/Trash'
|
||||||
import Files from './views/FilePages/Files'
|
import Files from './views/FilePages/Files'
|
||||||
import Password from './views/User/Password'
|
|
||||||
import SharedFiles from './views/FilePages/SharedFiles'
|
import SharedFiles from './views/FilePages/SharedFiles'
|
||||||
|
|
||||||
|
import UpgradePlan from './views/Upgrade/UpgradePlan'
|
||||||
|
import UpgradeBilling from './views/Upgrade/UpgradeBilling'
|
||||||
|
|
||||||
import AdminMobileMenu from './views/Mobile/AdminMobileMenu'
|
import AdminMobileMenu from './views/Mobile/AdminMobileMenu'
|
||||||
|
|
||||||
import Admin from './views/Admin'
|
import Admin from './views/Admin'
|
||||||
@@ -35,7 +40,7 @@ import Plan from './views/Admin/Plans/Plan'
|
|||||||
import PlanCreate from './views/Admin/Plans/PlanCreate'
|
import PlanCreate from './views/Admin/Plans/PlanCreate'
|
||||||
import PlanDelete from './views/Admin/Plans/PlanTabs/PlanDelete'
|
import PlanDelete from './views/Admin/Plans/PlanTabs/PlanDelete'
|
||||||
import PlanSettings from './views/Admin/Plans/PlanTabs/PlanSettings'
|
import PlanSettings from './views/Admin/Plans/PlanTabs/PlanSettings'
|
||||||
import PlanTransactions from './views/Admin/Plans/PlanTabs/PlanTransactions'
|
import PlanSubscribers from './views/Admin/Plans/PlanTabs/PlanSubscribers'
|
||||||
|
|
||||||
// Users
|
// Users
|
||||||
import Users from './views/Admin/Users'
|
import Users from './views/Admin/Users'
|
||||||
@@ -214,12 +219,12 @@ const routesAdmin = [
|
|||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
name: 'PlanTransactions',
|
name: 'PlanSubscribers',
|
||||||
path: '/admin/plan/:id/transactions',
|
path: '/admin/plan/:id/subscribers',
|
||||||
component: PlanTransactions,
|
component: PlanSubscribers,
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
title: 'Plan Transactions'
|
title: 'Plan Subscribers'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -271,14 +276,6 @@ const routesShared = [
|
|||||||
requiresAuth: false
|
requiresAuth: false
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'SharedFiles',
|
|
||||||
path: '/shared-files',
|
|
||||||
component: SharedFiles,
|
|
||||||
meta: {
|
|
||||||
requiresAuth: true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
const routesAuth = [
|
const routesAuth = [
|
||||||
{
|
{
|
||||||
@@ -315,6 +312,30 @@ const routesAuth = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
const routesUser = [
|
const routesUser = [
|
||||||
|
{
|
||||||
|
name: 'Files',
|
||||||
|
path: '/files',
|
||||||
|
component: Files,
|
||||||
|
meta: {
|
||||||
|
requiresAuth: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'SharedFiles',
|
||||||
|
path: '/shared-files',
|
||||||
|
component: SharedFiles,
|
||||||
|
meta: {
|
||||||
|
requiresAuth: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Trash',
|
||||||
|
path: '/trash',
|
||||||
|
component: Trash,
|
||||||
|
meta: {
|
||||||
|
requiresAuth: true
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Settings',
|
name: 'Settings',
|
||||||
path: '/settings',
|
path: '/settings',
|
||||||
@@ -359,22 +380,33 @@ const routesUser = [
|
|||||||
title: 'Invoices'
|
title: 'Invoices'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Subscription',
|
||||||
|
path: '/settings/subscription',
|
||||||
|
component: Subscription,
|
||||||
|
meta: {
|
||||||
|
requiresAuth: true,
|
||||||
|
title: 'Subscription'
|
||||||
|
},
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Files',
|
name: 'UpgradePlan',
|
||||||
path: '/files',
|
path: '/upgrade/plan',
|
||||||
component: Files,
|
component: UpgradePlan,
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true
|
requiresAuth: true,
|
||||||
|
title: 'Upgrade Plan'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Trash',
|
name: 'UpgradeBilling',
|
||||||
path: '/trash',
|
path: '/upgrade/billing',
|
||||||
component: Trash,
|
component: UpgradeBilling,
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true
|
requiresAuth: true,
|
||||||
|
title: 'Upgrade Billing'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
9
resources/js/store/modules/app.js
vendored
9
resources/js/store/modules/app.js
vendored
@@ -6,6 +6,7 @@ const defaultState = {
|
|||||||
config: undefined,
|
config: undefined,
|
||||||
authorized: undefined,
|
authorized: undefined,
|
||||||
homeDirectory: undefined,
|
homeDirectory: undefined,
|
||||||
|
requestedPlan: undefined,
|
||||||
roles: [
|
roles: [
|
||||||
{
|
{
|
||||||
label: i18n.t('roles.admin'),
|
label: i18n.t('roles.admin'),
|
||||||
@@ -57,14 +58,18 @@ const mutations = {
|
|||||||
CHANGE_PREVIEW(state, type) {
|
CHANGE_PREVIEW(state, type) {
|
||||||
state.FilePreviewType = type
|
state.FilePreviewType = type
|
||||||
},
|
},
|
||||||
|
STORE_REQUESTED_PLAN(state, plan) {
|
||||||
|
state.requestedPlan = plan
|
||||||
|
},
|
||||||
}
|
}
|
||||||
const getters = {
|
const getters = {
|
||||||
fileInfoVisible: state => state.fileInfoPanelVisible,
|
fileInfoVisible: state => state.fileInfoPanelVisible,
|
||||||
FilePreviewType: state => state.FilePreviewType,
|
FilePreviewType: state => state.FilePreviewType,
|
||||||
roles: state => state.roles,
|
homeDirectory: state => state.homeDirectory,
|
||||||
|
requestedPlan: state => state.requestedPlan,
|
||||||
api: state => state.config.api,
|
api: state => state.config.api,
|
||||||
config: state => state.config,
|
config: state => state.config,
|
||||||
homeDirectory: state => state.homeDirectory,
|
roles: state => state.roles,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="single-page">
|
<div id="single-page">
|
||||||
<div id="page-content" class="medium-width" v-if="! isLoading">
|
<div id="page-content" v-if="! isLoading">
|
||||||
<MobileHeader :title="$router.currentRoute.meta.title"/>
|
<MobileHeader :title="$router.currentRoute.meta.title"/>
|
||||||
<PageHeader :can-back="true" :title="$router.currentRoute.meta.title"/>
|
<PageHeader :can-back="true" :title="$router.currentRoute.meta.title"/>
|
||||||
|
|
||||||
|
|||||||
@@ -3,23 +3,26 @@
|
|||||||
<ValidationObserver v-if="gateway.attributes.slug === 'paypal'" ref="personalInformation" v-slot="{ invalid }" tag="form" class="form block-form">
|
<ValidationObserver v-if="gateway.attributes.slug === 'paypal'" ref="personalInformation" v-slot="{ invalid }" tag="form" class="form block-form">
|
||||||
|
|
||||||
<PageTabGroup>
|
<PageTabGroup>
|
||||||
<b class="form-group-label">Settings</b>
|
|
||||||
<div class="block-wrapper">
|
<div class="block-wrapper">
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
<div class="inline-wrapper">
|
<div class="inline-wrapper">
|
||||||
<label class="input-label">Status:</label>
|
<div class="switch-label">
|
||||||
|
<label class="input-label">Status:</label>
|
||||||
|
<small class="input-help">Status of your payment gateway on website.</small>
|
||||||
|
</div>
|
||||||
<SwitchInput @input="$updateText('/gateways/paypal', 'status', paymentGateway.attributes.status)" v-model="paymentGateway.attributes.status" class="switch" :state="paymentGateway.attributes.status"/>
|
<SwitchInput @input="$updateText('/gateways/paypal', 'status', paymentGateway.attributes.status)" v-model="paymentGateway.attributes.status" class="switch" :state="paymentGateway.attributes.status"/>
|
||||||
</div>
|
</div>
|
||||||
<small class="input-help">Status of your payment gateway on website.</small>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="block-wrapper">
|
<div class="block-wrapper">
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
<div class="inline-wrapper">
|
<div class="inline-wrapper">
|
||||||
<label class="input-label">Sandbox Mode:</label>
|
<div class="switch-label">
|
||||||
|
<label class="input-label">Sandbox Mode:</label>
|
||||||
|
<small class="input-help">With sandbox mode on, you can test your payment process on you website.</small>
|
||||||
|
</div>
|
||||||
<SwitchInput @input="$updateText('/gateways/paypal', 'sandbox', paymentGateway.attributes.sandbox)" v-model="paymentGateway.attributes.sandbox" class="switch" :state="paymentGateway.attributes.sandbox"/>
|
<SwitchInput @input="$updateText('/gateways/paypal', 'sandbox', paymentGateway.attributes.sandbox)" v-model="paymentGateway.attributes.sandbox" class="switch" :state="paymentGateway.attributes.sandbox"/>
|
||||||
</div>
|
</div>
|
||||||
<small class="input-help">With sandbox mode on, you can test your payment process on you website.</small>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PageTabGroup>
|
</PageTabGroup>
|
||||||
@@ -60,23 +63,26 @@
|
|||||||
|
|
||||||
<ValidationObserver v-if="gateway.attributes.slug === 'stripe'" ref="personalInformation" v-slot="{ invalid }" tag="form" class="form block-form">
|
<ValidationObserver v-if="gateway.attributes.slug === 'stripe'" ref="personalInformation" v-slot="{ invalid }" tag="form" class="form block-form">
|
||||||
<PageTabGroup>
|
<PageTabGroup>
|
||||||
<b class="form-group-label">Settings</b>
|
|
||||||
<div class="block-wrapper">
|
<div class="block-wrapper">
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
<div class="inline-wrapper">
|
<div class="inline-wrapper">
|
||||||
<label class="input-label">Status:</label>
|
<div class="switch-label">
|
||||||
|
<label class="input-label">Status:</label>
|
||||||
|
<small class="input-help">Status of your payment gateway on website.</small>
|
||||||
|
</div>
|
||||||
<SwitchInput @input="$updateText('/gateways/stripe', 'status', paymentGateway.attributes.status)" v-model="paymentGateway.attributes.status" class="switch" :state="paymentGateway.attributes.status"/>
|
<SwitchInput @input="$updateText('/gateways/stripe', 'status', paymentGateway.attributes.status)" v-model="paymentGateway.attributes.status" class="switch" :state="paymentGateway.attributes.status"/>
|
||||||
</div>
|
</div>
|
||||||
<small class="input-help">Status of your payment gateway on website.</small>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="block-wrapper">
|
<div class="block-wrapper">
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
<div class="inline-wrapper">
|
<div class="inline-wrapper">
|
||||||
<label class="input-label">Sandbox Mode:</label>
|
<div class="switch-label">
|
||||||
|
<label class="input-label">Sandbox Mode:</label>
|
||||||
|
<small class="input-help">With sandbox mode on, you can test your payment process on you website.</small>
|
||||||
|
</div>
|
||||||
<SwitchInput @input="$updateText('/gateways/stripe', 'sandbox', paymentGateway.attributes.sandbox)" v-model="paymentGateway.attributes.sandbox" class="switch" :state="paymentGateway.attributes.sandbox"/>
|
<SwitchInput @input="$updateText('/gateways/stripe', 'sandbox', paymentGateway.attributes.sandbox)" v-model="paymentGateway.attributes.sandbox" class="switch" :state="paymentGateway.attributes.sandbox"/>
|
||||||
</div>
|
</div>
|
||||||
<small class="input-help">With sandbox mode on, you can test your payment process on you website.</small>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PageTabGroup>
|
</PageTabGroup>
|
||||||
|
|||||||
@@ -134,7 +134,7 @@
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeStatus(val, id) {
|
changeStatus(val, id) {
|
||||||
this.$updateText('/plans/' + id + '/update', 'status', val)
|
this.$updateText('/plans/' + id + '/update', 'is_active', val)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="single-page">
|
<div id="single-page">
|
||||||
<div id="page-content" class="medium-width" v-if="! isLoading">
|
<div id="page-content" v-if="! isLoading">
|
||||||
<MobileHeader :title="$router.currentRoute.meta.title"/>
|
<MobileHeader :title="$router.currentRoute.meta.title"/>
|
||||||
<PageHeader :can-back="true" :title="$router.currentRoute.meta.title"/>
|
<PageHeader :can-back="true" :title="$router.currentRoute.meta.title"/>
|
||||||
|
|
||||||
@@ -18,13 +18,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
<router-link replace :to="{name: 'PlanTransactions', params: {id: plan.id}}"
|
<router-link replace :to="{name: 'PlanSubscribers', params: {id: plan.id}}"
|
||||||
class="menu-list-item link">
|
class="menu-list-item link">
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<credit-card-icon size="17"></credit-card-icon>
|
<users-icon size="17"></users-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="label">
|
<div class="label">
|
||||||
Transactions
|
Subscribers
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
@@ -50,20 +50,19 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {CreditCardIcon, SettingsIcon, Trash2Icon} from 'vue-feather-icons'
|
import {UsersIcon, SettingsIcon, Trash2Icon} from 'vue-feather-icons'
|
||||||
import MobileHeader from '@/components/Mobile/MobileHeader'
|
import MobileHeader from '@/components/Mobile/MobileHeader'
|
||||||
import SectionTitle from '@/components/Others/SectionTitle'
|
import SectionTitle from '@/components/Others/SectionTitle'
|
||||||
import PageHeader from '@/components/Others/PageHeader'
|
import PageHeader from '@/components/Others/PageHeader'
|
||||||
import Spinner from '@/components/FilesView/Spinner'
|
import Spinner from '@/components/FilesView/Spinner'
|
||||||
import {mapGetters} from 'vuex'
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Gateway',
|
name: 'Gateway',
|
||||||
components: {
|
components: {
|
||||||
|
UsersIcon,
|
||||||
Trash2Icon,
|
Trash2Icon,
|
||||||
SettingsIcon,
|
SettingsIcon,
|
||||||
CreditCardIcon,
|
|
||||||
SectionTitle,
|
SectionTitle,
|
||||||
MobileHeader,
|
MobileHeader,
|
||||||
PageHeader,
|
PageHeader,
|
||||||
|
|||||||
@@ -7,10 +7,12 @@
|
|||||||
<div class="block-wrapper">
|
<div class="block-wrapper">
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
<div class="inline-wrapper">
|
<div class="inline-wrapper">
|
||||||
<label class="input-label">Status:</label>
|
<div class="switch-label">
|
||||||
|
<label class="input-label">Status:</label>
|
||||||
|
<small class="input-help">Status of your payment gateway on website.</small>
|
||||||
|
</div>
|
||||||
<SwitchInput @input="changeStatus" class="switch" :state="plan.attributes.status"/>
|
<SwitchInput @input="changeStatus" class="switch" :state="plan.attributes.status"/>
|
||||||
</div>
|
</div>
|
||||||
<small class="input-help">Status of your payment gateway on website.</small>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -91,7 +93,7 @@
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeStatus(val) {
|
changeStatus(val) {
|
||||||
this.$updateText('/plans/' + this.$route.params.id + '/update', 'status', val)
|
this.$updateText('/plans/' + this.$route.params.id + '/update', 'is_active', val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
118
resources/js/views/Admin/Plans/PlanTabs/PlanSubscribers.vue
Normal file
118
resources/js/views/Admin/Plans/PlanTabs/PlanSubscribers.vue
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<template>
|
||||||
|
<PageTab v-if="subscribers">
|
||||||
|
<PageTabGroup>
|
||||||
|
<DatatableWrapper :paginator="true" :columns="columns" :data="subscribers" class="table">
|
||||||
|
<template scope="{ row }">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<router-link :to="{name: 'UserDetail', params: {id: row.data.id}}">
|
||||||
|
<DatatableCellImage
|
||||||
|
image-size="small"
|
||||||
|
:image="row.data.attributes.avatar"
|
||||||
|
:title="row.data.attributes.name"
|
||||||
|
/>
|
||||||
|
</router-link>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="cell-item">
|
||||||
|
{{ row.relationships.storage.data.attributes.used }}%
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="cell-item">
|
||||||
|
{{ row.relationships.subscription.data.attributes.ends_at }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="action-icons">
|
||||||
|
<router-link :to="{name: 'UserDetail', params: {id: row.data.id}}">
|
||||||
|
<edit-2-icon size="15" class="icon icon-edit"></edit-2-icon>
|
||||||
|
</router-link>
|
||||||
|
<router-link :to="{name: 'UserDelete', params: {id: row.data.id}}">
|
||||||
|
<trash2-icon size="15" class="icon icon-trash"></trash2-icon>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</DatatableWrapper>
|
||||||
|
</PageTabGroup>
|
||||||
|
</PageTab>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import DatatableCellImage from '@/components/Others/Tables/DatatableCellImage'
|
||||||
|
import DatatableWrapper from '@/components/Others/Tables/DatatableWrapper'
|
||||||
|
import PageTabGroup from '@/components/Others/Layout/PageTabGroup'
|
||||||
|
import PageTab from '@/components/Others/Layout/PageTab'
|
||||||
|
import {DownloadCloudIcon, Edit2Icon, Trash2Icon} from "vue-feather-icons";
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'PlanSubscribers',
|
||||||
|
components: {
|
||||||
|
DatatableCellImage,
|
||||||
|
DownloadCloudIcon,
|
||||||
|
DatatableWrapper,
|
||||||
|
PageTabGroup,
|
||||||
|
PageTab,
|
||||||
|
Edit2Icon,
|
||||||
|
Trash2Icon,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isLoading: false,
|
||||||
|
subscribers: undefined,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
label: 'User',
|
||||||
|
field: 'data.attributes.plan',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.storage_used'),
|
||||||
|
field: 'data.storage.attributes.storage.used',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Expire At',
|
||||||
|
field: 'data.subscription.data.attributes.ends_at',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('admin_page_user.table.action'),
|
||||||
|
field: 'data.action',
|
||||||
|
sortable: false
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
axios.get('/api/plans/' + this.$route.params.id + '/subscribers')
|
||||||
|
.then(response => {
|
||||||
|
this.subscribers = response.data.data
|
||||||
|
this.isLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
@import '@assets/vue-file-manager/_forms';
|
||||||
|
|
||||||
|
.block-form {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1,304 +0,0 @@
|
|||||||
<template>
|
|
||||||
<PageTab>
|
|
||||||
<PageTabGroup>
|
|
||||||
<DatatableWrapper :paginator="true" :columns="columns" :data="invoices" class="table">
|
|
||||||
<template scope="{ row }">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span class="cell-item">
|
|
||||||
${{ row.attributes.total }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<router-link :to="{name: 'UserInvoices', params: {id: row.relationships.user.data.id}}">
|
|
||||||
<DatatableCellImage
|
|
||||||
image-size="small"
|
|
||||||
:image="row.relationships.user.data.attributes.avatar"
|
|
||||||
:title="row.relationships.user.data.attributes.name"
|
|
||||||
/>
|
|
||||||
</router-link>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span class="cell-item">
|
|
||||||
{{ row.attributes.created_at_formatted }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="action-icons">
|
|
||||||
<download-cloud-icon size="15" class="icon"></download-cloud-icon>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
</DatatableWrapper>
|
|
||||||
</PageTabGroup>
|
|
||||||
</PageTab>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import DatatableCellImage from '@/components/Others/Tables/DatatableCellImage'
|
|
||||||
import DatatableWrapper from '@/components/Others/Tables/DatatableWrapper'
|
|
||||||
import PageTabGroup from '@/components/Others/Layout/PageTabGroup'
|
|
||||||
import PageTab from '@/components/Others/Layout/PageTab'
|
|
||||||
import {DownloadCloudIcon} from "vue-feather-icons";
|
|
||||||
import axios from 'axios'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'PlanTransactions',
|
|
||||||
components: {
|
|
||||||
DatatableCellImage,
|
|
||||||
DownloadCloudIcon,
|
|
||||||
DatatableWrapper,
|
|
||||||
PageTabGroup,
|
|
||||||
PageTab,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isLoading: false,
|
|
||||||
invoices: [
|
|
||||||
{
|
|
||||||
id: '1',
|
|
||||||
type: 'invoices',
|
|
||||||
attributes: {
|
|
||||||
total: 9.99,
|
|
||||||
plan: 'Starter Plan',
|
|
||||||
created_at: '30. April. 2020',
|
|
||||||
created_at_formatted: '30. April. 2020',
|
|
||||||
download: 'https://vuefilemanager.com/',
|
|
||||||
},
|
|
||||||
relationships: {
|
|
||||||
user: {
|
|
||||||
data: {
|
|
||||||
id: '1',
|
|
||||||
type: 'users',
|
|
||||||
attributes: {
|
|
||||||
avatar: '/avatars/6osmoXJo-avatar-01.png',
|
|
||||||
name: 'Jane Doe',
|
|
||||||
email: 'howdy@hi5ve.digital',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2',
|
|
||||||
type: 'invoices',
|
|
||||||
attributes: {
|
|
||||||
total: 9.99,
|
|
||||||
plan: 'Starter Plan',
|
|
||||||
created_at: '30. April. 2020',
|
|
||||||
created_at_formatted: '30. April. 2020',
|
|
||||||
download: 'https://vuefilemanager.com/',
|
|
||||||
},
|
|
||||||
relationships: {
|
|
||||||
user: {
|
|
||||||
data: {
|
|
||||||
id: '1',
|
|
||||||
type: 'users',
|
|
||||||
attributes: {
|
|
||||||
avatar: '/avatars/dSMRCbwF-69299654_2418248648259454_4545563304688353280_o.jpg',
|
|
||||||
name: 'Peter Papp',
|
|
||||||
email: 'peterpapp@makingcg.com',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3',
|
|
||||||
type: 'invoices',
|
|
||||||
attributes: {
|
|
||||||
total: 49.99,
|
|
||||||
plan: 'Business Plan',
|
|
||||||
created_at: '31. April. 2020',
|
|
||||||
created_at_formatted: '31. April. 2020',
|
|
||||||
download: 'https://vuefilemanager.com/',
|
|
||||||
},
|
|
||||||
relationships: {
|
|
||||||
user: {
|
|
||||||
data: {
|
|
||||||
id: '1',
|
|
||||||
type: 'users',
|
|
||||||
attributes: {
|
|
||||||
avatar: '/assets/images/default-avatar.png',
|
|
||||||
name: 'Pavel Svintsitskiy',
|
|
||||||
email: 'pashaUSA@gmail.com',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '4',
|
|
||||||
type: 'invoices',
|
|
||||||
attributes: {
|
|
||||||
total: 29.99,
|
|
||||||
plan: 'Professional Plan',
|
|
||||||
created_at: '31. April. 2020',
|
|
||||||
created_at_formatted: '31. April. 2020',
|
|
||||||
download: 'https://vuefilemanager.com/',
|
|
||||||
},
|
|
||||||
relationships: {
|
|
||||||
user: {
|
|
||||||
data: {
|
|
||||||
id: '1',
|
|
||||||
type: 'users',
|
|
||||||
attributes: {
|
|
||||||
avatar: '/avatars/lTksMdJM-6D3529EF-5D8C-4959-BEC2-4BDE80A051C2.jpeg',
|
|
||||||
name: 'Torsten',
|
|
||||||
email: 'torsten.hoegel@go-on-net.de',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '5',
|
|
||||||
type: 'invoices',
|
|
||||||
attributes: {
|
|
||||||
total: 9.99,
|
|
||||||
plan: 'Starter Plan',
|
|
||||||
created_at: '30. April. 2020',
|
|
||||||
created_at_formatted: '30. April. 2020',
|
|
||||||
download: 'https://vuefilemanager.com/',
|
|
||||||
},
|
|
||||||
relationships: {
|
|
||||||
user: {
|
|
||||||
data: {
|
|
||||||
id: '1',
|
|
||||||
type: 'users',
|
|
||||||
attributes: {
|
|
||||||
avatar: '/avatars/6osmoXJo-avatar-01.png',
|
|
||||||
name: 'Jane Doe',
|
|
||||||
email: 'howdy@hi5ve.digital',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '6',
|
|
||||||
type: 'invoices',
|
|
||||||
attributes: {
|
|
||||||
total: 9.99,
|
|
||||||
plan: 'Starter Plan',
|
|
||||||
created_at: '30. April. 2020',
|
|
||||||
created_at_formatted: '30. April. 2020',
|
|
||||||
download: 'https://vuefilemanager.com/',
|
|
||||||
},
|
|
||||||
relationships: {
|
|
||||||
user: {
|
|
||||||
data: {
|
|
||||||
id: '1',
|
|
||||||
type: 'users',
|
|
||||||
attributes: {
|
|
||||||
avatar: '/avatars/dSMRCbwF-69299654_2418248648259454_4545563304688353280_o.jpg',
|
|
||||||
name: 'Peter Papp',
|
|
||||||
email: 'peterpapp@makingcg.com',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '7',
|
|
||||||
type: 'invoices',
|
|
||||||
attributes: {
|
|
||||||
total: 49.99,
|
|
||||||
plan: 'Business Plan',
|
|
||||||
created_at: '31. April. 2020',
|
|
||||||
created_at_formatted: '31. April. 2020',
|
|
||||||
download: 'https://vuefilemanager.com/',
|
|
||||||
},
|
|
||||||
relationships: {
|
|
||||||
user: {
|
|
||||||
data: {
|
|
||||||
id: '1',
|
|
||||||
type: 'users',
|
|
||||||
attributes: {
|
|
||||||
avatar: '/assets/images/default-avatar.png',
|
|
||||||
name: 'Pavel Svintsitskiy',
|
|
||||||
email: 'pashaUSA@gmail.com',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '8',
|
|
||||||
type: 'invoices',
|
|
||||||
attributes: {
|
|
||||||
total: 29.99,
|
|
||||||
plan: 'Professional Plan',
|
|
||||||
created_at: '31. April. 2020',
|
|
||||||
created_at_formatted: '31. April. 2020',
|
|
||||||
download: 'https://vuefilemanager.com/',
|
|
||||||
},
|
|
||||||
relationships: {
|
|
||||||
user: {
|
|
||||||
data: {
|
|
||||||
id: '1',
|
|
||||||
type: 'users',
|
|
||||||
attributes: {
|
|
||||||
avatar: '/avatars/lTksMdJM-6D3529EF-5D8C-4959-BEC2-4BDE80A051C2.jpeg',
|
|
||||||
name: 'Torsten',
|
|
||||||
email: 'torsten.hoegel@go-on-net.de',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
label: 'Total',
|
|
||||||
field: 'attributes.total',
|
|
||||||
sortable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'User',
|
|
||||||
field: 'attributes.plan',
|
|
||||||
sortable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Payed',
|
|
||||||
field: 'relationships.user.data.attributes.name',
|
|
||||||
sortable: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('admin_page_user.table.action'),
|
|
||||||
field: 'data.action',
|
|
||||||
sortable: false
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
/*axios.get('/api/users/' + this.$route.params.id + '/storage')
|
|
||||||
.then(response => {
|
|
||||||
this.storage = response.data.data
|
|
||||||
this.isLoading = false
|
|
||||||
})*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import '@assets/vue-file-manager/_variables';
|
|
||||||
@import '@assets/vue-file-manager/_mixins';
|
|
||||||
@import '@assets/vue-file-manager/_forms';
|
|
||||||
|
|
||||||
.block-form {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@media only screen and (max-width: 960px) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -34,6 +34,14 @@
|
|||||||
{{ row.data.attributes.role }}
|
{{ row.data.attributes.role }}
|
||||||
</ColorLabel>
|
</ColorLabel>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="cell-item" v-if="row.relationships.subscription">
|
||||||
|
{{ row.relationships.subscription.data.attributes.name }}
|
||||||
|
</span>
|
||||||
|
<span class="cell-item" v-else>
|
||||||
|
Free
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="cell-item">
|
<span class="cell-item">
|
||||||
{{ row.relationships.storage.data.attributes.used }}%
|
{{ row.relationships.storage.data.attributes.used }}%
|
||||||
@@ -113,6 +121,11 @@
|
|||||||
field: 'data.attributes.role',
|
field: 'data.attributes.role',
|
||||||
sortable: true
|
sortable: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Subscription Plan',
|
||||||
|
field: 'data.attributes.role',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('admin_page_user.table.storage_used'),
|
label: this.$t('admin_page_user.table.storage_used'),
|
||||||
field: 'data.attributes.storage.used',
|
field: 'data.attributes.storage.used',
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="single-page" v-if="app">
|
<div id="single-page" v-if="app">
|
||||||
<div id="page-content" class="medium-width" v-if="! isLoading">
|
<div id="page-content" v-if="! isLoading">
|
||||||
<MobileHeader :title="$router.currentRoute.meta.title"/>
|
<MobileHeader :title="$router.currentRoute.meta.title"/>
|
||||||
<PageHeader :can-back="true" :title="$router.currentRoute.meta.title"/>
|
<PageHeader :can-back="true" :title="$router.currentRoute.meta.title"/>
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
<!--Avatar-->
|
<!--Avatar-->
|
||||||
<div class="block-wrapper">
|
<div class="block-wrapper">
|
||||||
|
<label>Avatar</label>
|
||||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="avatar" v-slot="{ errors }">
|
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="avatar" v-slot="{ errors }">
|
||||||
<ImageInput v-model="user.avatar" :error="errors[0]" />
|
<ImageInput v-model="user.avatar" :error="errors[0]" />
|
||||||
</ValidationProvider>
|
</ValidationProvider>
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
<ValidationObserver ref="deleteUser" @submit.prevent="deleteUser" v-slot="{ invalid }" tag="form"
|
<ValidationObserver ref="deleteUser" @submit.prevent="deleteUser" v-slot="{ invalid }" tag="form"
|
||||||
class="form block-form">
|
class="form block-form">
|
||||||
<ValidationProvider tag="div" class="block-wrapper" v-slot="{ errors }" mode="passive"
|
<ValidationProvider tag="div" class="block-wrapper" v-slot="{ errors }" mode="passive"
|
||||||
name="User name" :rules="'required|is:' + user.attributes.name">
|
name="User name" :rules="'required|is:' + user.data.attributes.name">
|
||||||
<label>{{ $t('admin_page_user.label_delete_user', {user: user.attributes.name}) }}:</label>
|
<label>{{ $t('admin_page_user.label_delete_user', {user: user.data.attributes.name}) }}:</label>
|
||||||
<div class="single-line-form">
|
<div class="single-line-form">
|
||||||
<input v-model="userName"
|
<input v-model="userName"
|
||||||
:placeholder="$t('admin_page_user.placeholder_delete_user')"
|
:placeholder="$t('admin_page_user.placeholder_delete_user')"
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -82,16 +82,16 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="wrapper-inline">
|
<div class="block-wrapper">
|
||||||
<div class="block-wrapper">
|
<label>State:</label>
|
||||||
<label>State:</label>
|
<div class="input-wrapper">
|
||||||
<div class="input-wrapper">
|
<input :value="user.relationships.settings.data.attributes.billing_state"
|
||||||
<input :value="user.relationships.settings.data.attributes.billing_state"
|
type="text"
|
||||||
type="text"
|
disabled
|
||||||
disabled
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wrapper-inline">
|
||||||
<div class="block-wrapper">
|
<div class="block-wrapper">
|
||||||
<label>City:</label>
|
<label>City:</label>
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
|
|||||||
@@ -7,16 +7,30 @@
|
|||||||
<div class="content-page">
|
<div class="content-page">
|
||||||
|
|
||||||
<!--User thumbnail-->
|
<!--User thumbnail-->
|
||||||
<div class="user-thumbnail">
|
<div class="page-detail-headline">
|
||||||
<div class="avatar">
|
<div class="user-thumbnail">
|
||||||
<UserImageInput
|
<div class="avatar">
|
||||||
v-model="avatar"
|
<UserImageInput
|
||||||
:avatar="profile.data.attributes.avatar"
|
v-model="avatar"
|
||||||
/>
|
:avatar="profile.data.attributes.avatar"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<b class="name">
|
||||||
|
{{ profile.data.attributes.name }}
|
||||||
|
<ColorLabel :color="subscriptionColor">
|
||||||
|
{{ subscriptionStatus }}
|
||||||
|
</ColorLabel>
|
||||||
|
</b>
|
||||||
|
<span class="email">{{ profile.data.attributes.email }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info">
|
<div class="headline-actions">
|
||||||
<b class="name">{{ profile.data.attributes.name }}</b>
|
<router-link :to="{name: 'UpgradePlan'}">
|
||||||
<span class="email">{{ profile.data.attributes.email }}</span>
|
<ButtonBase button-style="secondary" type="button">
|
||||||
|
Upgrade Plan
|
||||||
|
</ButtonBase>
|
||||||
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -40,6 +54,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
|
<router-link replace :to="{name: 'Invoice'}" class="menu-list-item link">
|
||||||
|
<div class="icon">
|
||||||
|
<credit-card-icon size="17"></credit-card-icon>
|
||||||
|
</div>
|
||||||
|
<div class="label">
|
||||||
|
Subscription
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
|
|
||||||
<router-link replace :to="{name: 'Invoice'}" class="menu-list-item link">
|
<router-link replace :to="{name: 'Invoice'}" class="menu-list-item link">
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<file-text-icon size="17"></file-text-icon>
|
<file-text-icon size="17"></file-text-icon>
|
||||||
@@ -81,11 +104,13 @@
|
|||||||
<script>
|
<script>
|
||||||
import UserImageInput from '@/components/Others/UserImageInput'
|
import UserImageInput from '@/components/Others/UserImageInput'
|
||||||
import MobileHeader from '@/components/Mobile/MobileHeader'
|
import MobileHeader from '@/components/Mobile/MobileHeader'
|
||||||
|
import ButtonBase from '@/components/FilesView/ButtonBase'
|
||||||
import PageHeader from '@/components/Others/PageHeader'
|
import PageHeader from '@/components/Others/PageHeader'
|
||||||
|
import ColorLabel from '@/components/Others/ColorLabel'
|
||||||
import Spinner from '@/components/FilesView/Spinner'
|
import Spinner from '@/components/FilesView/Spinner'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
CreditCardIcon,
|
||||||
HardDriveIcon,
|
HardDriveIcon,
|
||||||
FileTextIcon,
|
FileTextIcon,
|
||||||
UserIcon,
|
UserIcon,
|
||||||
@@ -95,15 +120,26 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'Settings',
|
name: 'Settings',
|
||||||
components: {
|
components: {
|
||||||
|
ButtonBase,
|
||||||
|
CreditCardIcon,
|
||||||
UserImageInput,
|
UserImageInput,
|
||||||
FileTextIcon,
|
FileTextIcon,
|
||||||
MobileHeader,
|
MobileHeader,
|
||||||
|
ColorLabel,
|
||||||
PageHeader,
|
PageHeader,
|
||||||
Spinner,
|
Spinner,
|
||||||
HardDriveIcon,
|
HardDriveIcon,
|
||||||
UserIcon,
|
UserIcon,
|
||||||
LockIcon,
|
LockIcon,
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
subscriptionStatus() {
|
||||||
|
return this.profile.relationships.subscription ? 'Subscription' : 'Free'
|
||||||
|
},
|
||||||
|
subscriptionColor() {
|
||||||
|
return this.profile.relationships.subscription ? 'green' : 'purple'
|
||||||
|
},
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
avatar: undefined,
|
avatar: undefined,
|
||||||
@@ -125,6 +161,11 @@
|
|||||||
@import '@assets/vue-file-manager/_variables';
|
@import '@assets/vue-file-manager/_variables';
|
||||||
@import '@assets/vue-file-manager/_mixins';
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.page-detail-headline {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
.user-thumbnail {
|
.user-thumbnail {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
360
resources/js/views/Upgrade/UpgradeBilling.vue
Normal file
360
resources/js/views/Upgrade/UpgradeBilling.vue
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
<template>
|
||||||
|
<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">
|
||||||
|
|
||||||
|
<div class="plan-title">
|
||||||
|
<credit-card-icon size="42" class="title-icon"></credit-card-icon>
|
||||||
|
<h1>Choose Payment Method</h1>
|
||||||
|
<h2>Choose plan witch perfect fit your needs. All plans is billed monthly automatically via your
|
||||||
|
credit card.</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="order">
|
||||||
|
<div class="billing" v-if="billing">
|
||||||
|
<b class="form-group-label">Billing Information:</b>
|
||||||
|
<ValidationObserver ref="order" v-slot="{ invalid }" tag="form" class="form block-form">
|
||||||
|
<div class="form block-form">
|
||||||
|
|
||||||
|
<div class="block-wrapper">
|
||||||
|
<label>Name:</label>
|
||||||
|
<ValidationProvider tag="div" mode="passive" class="input-wrapper" rules="required"
|
||||||
|
name="billing_name" v-slot="{ errors }">
|
||||||
|
<input v-model="billing.billing_name"
|
||||||
|
placeholder="Type your billing name"
|
||||||
|
type="text"
|
||||||
|
:class="{'is-error': errors[0]}"
|
||||||
|
/>
|
||||||
|
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||||
|
</ValidationProvider>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block-wrapper">
|
||||||
|
<label>Address:</label>
|
||||||
|
<ValidationProvider tag="div" mode="passive" class="input-wrapper" rules="required"
|
||||||
|
name="billing_address" v-slot="{ errors }">
|
||||||
|
<input v-model="billing.billing_address"
|
||||||
|
placeholder="Type your billing address"
|
||||||
|
type="text"
|
||||||
|
:class="{'is-error': errors[0]}"
|
||||||
|
/>
|
||||||
|
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||||
|
</ValidationProvider>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block-wrapper">
|
||||||
|
<label>State:</label>
|
||||||
|
<ValidationProvider tag="div" mode="passive" class="input-wrapper" rules="required"
|
||||||
|
name="billing_state" v-slot="{ errors }">
|
||||||
|
<input v-model="billing.billing_state"
|
||||||
|
placeholder="Type your billing state"
|
||||||
|
type="text"
|
||||||
|
:class="{'is-error': errors[0]}"
|
||||||
|
/>
|
||||||
|
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||||
|
</ValidationProvider>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wrapper-inline">
|
||||||
|
<div class="block-wrapper">
|
||||||
|
<label>City:</label>
|
||||||
|
<ValidationProvider tag="div" mode="passive" class="input-wrapper"
|
||||||
|
rules="required" name="billing_city" v-slot="{ errors }">
|
||||||
|
<input v-model="billing.billing_city"
|
||||||
|
placeholder="Type your billing city"
|
||||||
|
type="text"
|
||||||
|
:class="{'is-error': errors[0]}"
|
||||||
|
/>
|
||||||
|
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||||
|
</ValidationProvider>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block-wrapper">
|
||||||
|
<label>Postal Code:</label>
|
||||||
|
<ValidationProvider tag="div" mode="passive" class="input-wrapper"
|
||||||
|
rules="required" name="billing_postal_code"
|
||||||
|
v-slot="{ errors }">
|
||||||
|
<input v-model="billing.billing_postal_code"
|
||||||
|
placeholder="Type your billing postal code"
|
||||||
|
type="text"
|
||||||
|
:class="{'is-error': errors[0]}"
|
||||||
|
/>
|
||||||
|
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||||
|
</ValidationProvider>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block-wrapper">
|
||||||
|
<label>Country:</label>
|
||||||
|
<ValidationProvider tag="div" mode="passive" class="input-wrapper" rules="required"
|
||||||
|
name="billing_country" v-slot="{ errors }">
|
||||||
|
<input v-model="billing.billing_country"
|
||||||
|
placeholder="Type your billing country"
|
||||||
|
type="text"
|
||||||
|
:class="{'is-error': errors[0]}"
|
||||||
|
/>
|
||||||
|
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||||
|
</ValidationProvider>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block-wrapper">
|
||||||
|
<label>Phone Number:</label>
|
||||||
|
<ValidationProvider tag="div" mode="passive" class="input-wrapper" rules="required"
|
||||||
|
name="billing_phone_number" v-slot="{ errors }">
|
||||||
|
<input v-model="billing.billing_phone_number"
|
||||||
|
placeholder="Type your billing phone number"
|
||||||
|
type="text"
|
||||||
|
:class="{'is-error': errors[0]}"
|
||||||
|
/>
|
||||||
|
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||||
|
</ValidationProvider>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ValidationObserver>
|
||||||
|
</div>
|
||||||
|
<div class="summary">
|
||||||
|
<b class="form-group-label">Order Summary:</b>
|
||||||
|
|
||||||
|
<div class="summary-list" v-if="requestedPlan">
|
||||||
|
<div class="row">
|
||||||
|
<div class="cell">
|
||||||
|
<b>{{ requestedPlan.data.attributes.name }}</b>
|
||||||
|
<small>Billed monthly</small>
|
||||||
|
</div>
|
||||||
|
<div class="cell">
|
||||||
|
<b>{{ requestedPlan.data.attributes.price }} USD</b>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="cell">
|
||||||
|
<b>Total</b>
|
||||||
|
</div>
|
||||||
|
<div class="cell">
|
||||||
|
<b>{{ requestedPlan.data.attributes.price }} USD</b>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ButtonBase :disabled="isSubmitted" :loading="isSubmitted" @click.native="submitOrder"
|
||||||
|
type="submit" button-style="theme-solid" class="next-submit">
|
||||||
|
Pay Order
|
||||||
|
</ButtonBase>
|
||||||
|
|
||||||
|
<small class="disclaimer">
|
||||||
|
By submit form, you agree to save the payment method and billing information in your
|
||||||
|
VueFileManager account.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="loader" v-if="isLoading">
|
||||||
|
<Spinner></Spinner>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
|
||||||
|
import PlanPricingTables from '@/components/Others/PlanPricingTables'
|
||||||
|
import MobileHeader from '@/components/Mobile/MobileHeader'
|
||||||
|
import ButtonBase from '@/components/FilesView/ButtonBase'
|
||||||
|
import PageHeader from '@/components/Others/PageHeader'
|
||||||
|
import Spinner from '@/components/FilesView/Spinner'
|
||||||
|
import {CreditCardIcon} from 'vue-feather-icons'
|
||||||
|
import {required} from 'vee-validate/dist/rules'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import {events} from "@/bus"
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'UpgradePlan',
|
||||||
|
components: {
|
||||||
|
ValidationProvider,
|
||||||
|
ValidationObserver,
|
||||||
|
PlanPricingTables,
|
||||||
|
CreditCardIcon,
|
||||||
|
MobileHeader,
|
||||||
|
ButtonBase,
|
||||||
|
PageHeader,
|
||||||
|
required,
|
||||||
|
Spinner,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['requestedPlan']),
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isLoading: true,
|
||||||
|
isSubmitted: false,
|
||||||
|
billing: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async submitOrder() {
|
||||||
|
|
||||||
|
// Validate fields
|
||||||
|
const isValid = await this.$refs.order.validate();
|
||||||
|
|
||||||
|
if (!isValid) return;
|
||||||
|
|
||||||
|
// Start loading
|
||||||
|
this.isSubmitted = true
|
||||||
|
|
||||||
|
// Send order request
|
||||||
|
axios
|
||||||
|
.post('/api/upgrade', {
|
||||||
|
billing: this.billing,
|
||||||
|
plan: this.requestedPlan,
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
|
||||||
|
// End loading
|
||||||
|
this.isSubmitted = false
|
||||||
|
|
||||||
|
// Show toaster
|
||||||
|
events.$emit('toaster', {
|
||||||
|
type: 'success',
|
||||||
|
message: 'Your account was successfully upgraded.',
|
||||||
|
})
|
||||||
|
|
||||||
|
// Go to User page
|
||||||
|
this.$router.push({name: 'Storage'})
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
|
||||||
|
// End loading
|
||||||
|
this.isSubmitted = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
axios.get('/api/profile')
|
||||||
|
.then(response => {
|
||||||
|
|
||||||
|
if (! this.requestedPlan) {
|
||||||
|
this.$router.push({name: 'UpgradePlan'})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.billing = {
|
||||||
|
billing_name: response.data.relationships.settings.data.attributes.billing_name,
|
||||||
|
billing_address: response.data.relationships.settings.data.attributes.billing_address,
|
||||||
|
billing_state: response.data.relationships.settings.data.attributes.billing_state,
|
||||||
|
billing_city: response.data.relationships.settings.data.attributes.billing_city,
|
||||||
|
billing_postal_code: response.data.relationships.settings.data.attributes.billing_postal_code,
|
||||||
|
billing_country: response.data.relationships.settings.data.attributes.billing_country,
|
||||||
|
billing_phone_number: response.data.relationships.settings.data.attributes.billing_phone_number,
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
@import '@assets/vue-file-manager/_forms';
|
||||||
|
|
||||||
|
.summary-list {
|
||||||
|
box-shadow: 0 7px 20px 5px hsla(220, 36%, 16%, 0.06);
|
||||||
|
border-radius: 8px;
|
||||||
|
position: sticky;
|
||||||
|
padding: 25px;
|
||||||
|
top: 30px;
|
||||||
|
|
||||||
|
.next-submit {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disclaimer {
|
||||||
|
@include font-size(12);
|
||||||
|
line-height: 1.6;
|
||||||
|
display: block;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 15px 0;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-of-type {
|
||||||
|
border-top: 1px solid $light_mode_border;
|
||||||
|
padding-bottom: 0;
|
||||||
|
|
||||||
|
b {
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell {
|
||||||
|
b {
|
||||||
|
display: block;
|
||||||
|
@include font-size(18);
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
color: $text-muted;
|
||||||
|
@include font-size(12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.order {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.billing {
|
||||||
|
flex: 0 0 65%;
|
||||||
|
padding-right: 30px;
|
||||||
|
|
||||||
|
.form {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary {
|
||||||
|
flex: 0 0 34%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-title {
|
||||||
|
text-align: center;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto 80px;
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
color: $theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
@include font-size(38);
|
||||||
|
font-weight: 800;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
@include font-size(20);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
89
resources/js/views/Upgrade/UpgradePlan.vue
Normal file
89
resources/js/views/Upgrade/UpgradePlan.vue
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
<template>
|
||||||
|
<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">
|
||||||
|
<div class="plan-title">
|
||||||
|
<cloud-icon size="42" class="title-icon"></cloud-icon>
|
||||||
|
<h1>Choose Your Plan</h1>
|
||||||
|
<h2>Choose plan witch perfect fit your needs. All plans is billed monthly automatically via your credit card.</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<PlanPricingTables @load="onLoadPricingTables" @selected-plan="onSelectTable"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="loader" v-if="isLoading">
|
||||||
|
<Spinner></Spinner>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import PlanPricingTables from '@/components/Others/PlanPricingTables'
|
||||||
|
import MobileHeader from '@/components/Mobile/MobileHeader'
|
||||||
|
import PageHeader from '@/components/Others/PageHeader'
|
||||||
|
import Spinner from '@/components/FilesView/Spinner'
|
||||||
|
import { CloudIcon } from 'vue-feather-icons'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'UpgradePlan',
|
||||||
|
components: {
|
||||||
|
PlanPricingTables,
|
||||||
|
MobileHeader,
|
||||||
|
PageHeader,
|
||||||
|
CloudIcon,
|
||||||
|
Spinner,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isLoading: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onLoadPricingTables(state) {
|
||||||
|
this.isLoading = state
|
||||||
|
},
|
||||||
|
onSelectTable(plan) {
|
||||||
|
this.$store.commit('STORE_REQUESTED_PLAN', plan)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
@import '@assets/vue-file-manager/_forms';
|
||||||
|
|
||||||
|
.plan-title {
|
||||||
|
text-align: center;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto 80px;
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
color: $theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
@include font-size(38);
|
||||||
|
font-weight: 800;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
@include font-size(20);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
class="form block-form">
|
class="form block-form">
|
||||||
|
|
||||||
<div class="block-wrapper">
|
<div class="block-wrapper">
|
||||||
<b class="form-group-label">{{ $t('page_create_password.label_new_pass') }}:</b>
|
<label>{{ $t('page_create_password.label_new_pass') }}:</label>
|
||||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="New Password"
|
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="New Password"
|
||||||
rules="required" v-slot="{ errors }">
|
rules="required" v-slot="{ errors }">
|
||||||
<input v-model="newPassword" :placeholder="$t('page_create_password.label_new_pass')"
|
<input v-model="newPassword" :placeholder="$t('page_create_password.label_new_pass')"
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
<PageTab>
|
<PageTab>
|
||||||
<PageTabGroup v-if="userInfo">
|
<PageTabGroup v-if="userInfo">
|
||||||
<div class="form block-form">
|
<div class="form block-form">
|
||||||
<b class="form-group-label">{{ $t('admin_page_user.label_person_info') }}</b>
|
|
||||||
<div class="wrapper-inline">
|
<div class="wrapper-inline">
|
||||||
<div class="block-wrapper">
|
<div class="block-wrapper">
|
||||||
<label>{{ $t('page_registration.label_email') }}</label>
|
<label>{{ $t('page_registration.label_email') }}</label>
|
||||||
@@ -50,17 +49,17 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="wrapper-inline">
|
<div class="block-wrapper">
|
||||||
<div class="block-wrapper">
|
<label>State:</label>
|
||||||
<label>State:</label>
|
<div class="input-wrapper">
|
||||||
<div class="input-wrapper">
|
<input @keyup="$updateText('/user/relationships/settings', 'billing_state', billingInfo.billing_state)"
|
||||||
<input @keyup="$updateText('/user/relationships/settings', 'billing_state', billingInfo.billing_state)"
|
v-model="billingInfo.billing_state"
|
||||||
v-model="billingInfo.billing_state"
|
placeholder="Type your billing state"
|
||||||
placeholder="Type your billing state"
|
type="text"
|
||||||
type="text"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wrapper-inline">
|
||||||
<div class="block-wrapper">
|
<div class="block-wrapper">
|
||||||
<label>City:</label>
|
<label>City:</label>
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
@@ -135,13 +134,6 @@
|
|||||||
ThemeLabel,
|
ThemeLabel,
|
||||||
required,
|
required,
|
||||||
},
|
},
|
||||||
/* watch: {
|
|
||||||
'user.name': debounce(function (val) {
|
|
||||||
if (val === '') return
|
|
||||||
|
|
||||||
this.$store.commit('UPDATE_NAME', val)
|
|
||||||
}, 300),
|
|
||||||
},*/
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
userInfo: undefined,
|
userInfo: undefined,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<PageTab v-if="storage">
|
<PageTab v-if="storage">
|
||||||
<PageTabGroup>
|
<PageTabGroup>
|
||||||
<b class="form-group-label">{{ $t('storage.sec_capacity') }}</b>
|
|
||||||
<StorageItemDetail type="disk" :title="$t('storage.total_used', {used: storage.attributes.used})" :percentage="storage.attributes.percentage" :used="$t('storage.total_capacity', {capacity: storage.attributes.capacity})"/>
|
<StorageItemDetail type="disk" :title="$t('storage.total_used', {used: storage.attributes.used})" :percentage="storage.attributes.percentage" :used="$t('storage.total_capacity', {capacity: storage.attributes.capacity})"/>
|
||||||
</PageTabGroup>
|
</PageTabGroup>
|
||||||
<PageTabGroup>
|
<PageTabGroup>
|
||||||
|
|||||||
58
resources/js/views/User/Subscription.vue
Normal file
58
resources/js/views/User/Subscription.vue
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<PageTab>
|
||||||
|
<PageTabGroup>
|
||||||
|
|
||||||
|
</PageTabGroup>
|
||||||
|
</PageTab>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import PageTabGroup from '@/components/Others/Layout/PageTabGroup'
|
||||||
|
import PageTab from '@/components/Others/Layout/PageTab'
|
||||||
|
import DatatableWrapper from '@/components/Others/Tables/DatatableWrapper'
|
||||||
|
import {ExternalLinkIcon} from "vue-feather-icons";
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'UserSubscription',
|
||||||
|
components: {
|
||||||
|
PageTabGroup,
|
||||||
|
PageTab,
|
||||||
|
DatatableWrapper,
|
||||||
|
ExternalLinkIcon,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isLoading: true,
|
||||||
|
invoices: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
/* axios.get('/api/user/subscription')
|
||||||
|
.then(response => {
|
||||||
|
this.invoices = response.data.data
|
||||||
|
this.isLoading = false
|
||||||
|
})*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
@import '@assets/vue-file-manager/_forms';
|
||||||
|
|
||||||
|
.block-form {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
26
resources/sass/app.scss
vendored
26
resources/sass/app.scss
vendored
@@ -28,18 +28,36 @@
|
|||||||
|
|
||||||
#page-content {
|
#page-content {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
padding-bottom: 50px;
|
||||||
|
|
||||||
&.full-width {
|
&.full-width {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.medium-width {
|
&.medium-width {
|
||||||
max-width: 1024px;
|
max-width: 920px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.large-width {
|
||||||
|
max-width: 1190px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.small-width {
|
&.small-width {
|
||||||
max-width: 690px;
|
max-width: 690px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.center-page {
|
||||||
|
height: 100%;
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
display: grid;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.content-page {
|
||||||
|
margin: auto;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,8 +66,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form-group-label {
|
.form-group-label {
|
||||||
@include font-size(17);
|
@include font-size(18);
|
||||||
font-weight: 500;
|
font-weight: 800;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
margin-bottom: 25px;
|
margin-bottom: 25px;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@@ -249,6 +268,7 @@
|
|||||||
.cell-item {
|
.cell-item {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
color: $text;
|
color: $text;
|
||||||
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
27
resources/sass/vue-file-manager/_forms.scss
vendored
27
resources/sass/vue-file-manager/_forms.scss
vendored
@@ -33,14 +33,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.block-wrapper {
|
.block-wrapper {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 15px;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
@include font-size(14);
|
@include font-size(14);
|
||||||
color: $text-muted;
|
color: rgba($text, 0.7);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
@@ -57,6 +57,19 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.switch-label {
|
||||||
|
.input-help {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-label {
|
||||||
|
font-weight: 700;
|
||||||
|
color: $text;
|
||||||
|
@include font-size(16);
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-help {
|
.input-help {
|
||||||
@@ -85,16 +98,16 @@ input[type="password"],
|
|||||||
input[type="text"],
|
input[type="text"],
|
||||||
input[type="number"],
|
input[type="number"],
|
||||||
input[type="email"] {
|
input[type="email"] {
|
||||||
border: 1px solid #ebebeb;
|
border: 1px solid transparent;
|
||||||
@include transition(150ms);
|
@include transition(150ms);
|
||||||
@include font-size(14);
|
@include font-size(16);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 13px 20px;
|
padding: 13px 20px;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
font-weight: 600;
|
font-weight: 700;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: $light_mode_input_background;
|
background: hsla(210, 10%, 98%, 1);
|
||||||
|
|
||||||
&.is-error {
|
&.is-error {
|
||||||
border-color: $danger;
|
border-color: $danger;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// Colors
|
// Colors
|
||||||
$text: #1c1d1f;
|
$text: #1b2539;
|
||||||
$text-muted: rgba($text, 0.7);
|
$text-muted: rgba($text, 0.7);
|
||||||
|
|
||||||
$theme: #00BC7E;
|
$theme: #00BC7E;
|
||||||
@@ -13,11 +13,11 @@ $purple: #9D66FE;
|
|||||||
$light_mode_border: #F8F8F8;
|
$light_mode_border: #F8F8F8;
|
||||||
$danger: #fd397a;
|
$danger: #fd397a;
|
||||||
$light_text: #A4ADB6;
|
$light_text: #A4ADB6;
|
||||||
$light_background: #f6f6f6;
|
$light_background: #f4f5f6;
|
||||||
$dark_background: #EBEBEB;
|
$dark_background: #EBEBEB;
|
||||||
$shadow: 0 7px 25px 1px rgba(0, 0, 0, 0.12);
|
$shadow: 0 7px 25px 1px rgba(0, 0, 0, 0.12);
|
||||||
|
|
||||||
$light_mode_input_background: hsl(0, 0%, 98%);
|
$light_mode_input_background: #f4f5f6;
|
||||||
$light_mode_popup_shadow: 0 15px 50px 10px rgba(26,38,74,0.12);
|
$light_mode_popup_shadow: 0 15px 50px 10px rgba(26,38,74,0.12);
|
||||||
$light_mode_vignette: rgba(9, 8, 12, 0.35);
|
$light_mode_vignette: rgba(9, 8, 12, 0.35);
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,11 @@
|
|||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Plans
|
||||||
|
Route::group(['middleware' => ['api'], 'prefix' => 'public'], function () {
|
||||||
|
Route::get('/pricing', 'General\PricingController@index');
|
||||||
|
});
|
||||||
|
|
||||||
// Public routes
|
// Public routes
|
||||||
Route::group(['middleware' => ['api']], function () {
|
Route::group(['middleware' => ['api']], function () {
|
||||||
|
|
||||||
@@ -56,6 +61,9 @@ Route::group(['middleware' => ['auth:api', 'auth.master', 'scope:master']], func
|
|||||||
Route::get('/user', 'User\AccountController@user');
|
Route::get('/user', 'User\AccountController@user');
|
||||||
Route::get('/profile', 'User\AccountController@me');
|
Route::get('/profile', 'User\AccountController@me');
|
||||||
|
|
||||||
|
// Subscription
|
||||||
|
Route::post('/upgrade', 'User\SubscriptionController@upgrade');
|
||||||
|
|
||||||
// Browse
|
// Browse
|
||||||
Route::get('/participant-uploads', 'FileBrowser\BrowseController@participant_uploads');
|
Route::get('/participant-uploads', 'FileBrowser\BrowseController@participant_uploads');
|
||||||
Route::get('/file-detail/{unique_id}', 'FileBrowser\BrowseController@file_detail');
|
Route::get('/file-detail/{unique_id}', 'FileBrowser\BrowseController@file_detail');
|
||||||
@@ -109,13 +117,13 @@ Route::group(['middleware' => ['auth:api', 'auth.master', 'auth.admin', 'scope:m
|
|||||||
Route::get('/plans/{id}', 'Admin\PlanController@show');
|
Route::get('/plans/{id}', 'Admin\PlanController@show');
|
||||||
Route::post('/plans/store', 'Admin\PlanController@store');
|
Route::post('/plans/store', 'Admin\PlanController@store');
|
||||||
Route::patch('/plans/{id}/update', 'Admin\PlanController@update');
|
Route::patch('/plans/{id}/update', 'Admin\PlanController@update');
|
||||||
|
Route::get('/plans/{id}/subscribers', 'Admin\PlanController@subscribers');
|
||||||
|
|
||||||
// Invoices
|
// Invoices
|
||||||
Route::get('/invoices', 'Admin\InvoiceController@index');
|
Route::get('/invoices', 'Admin\InvoiceController@index');
|
||||||
Route::get('/invoices/{token}', 'Admin\InvoiceController@show');
|
Route::get('/invoices/{token}', 'Admin\InvoiceController@show');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Protected sharing routes for authenticated user
|
// Protected sharing routes for authenticated user
|
||||||
Route::group(['middleware' => ['auth:api', 'auth.shared', 'scope:visitor,editor']], function () {
|
Route::group(['middleware' => ['auth:api', 'auth.shared', 'scope:visitor,editor']], function () {
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,66 @@
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use App\User;
|
||||||
|
use Rinvex\Subscriptions\Models\PlanFeature;
|
||||||
|
|
||||||
|
Route::get('/debug', function () {
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Create plan
|
||||||
|
*/
|
||||||
|
/* $plan = app('rinvex.subscriptions.plan')->create([
|
||||||
|
'name' => 'Starter Pack',
|
||||||
|
'description' => 'The best for start with',
|
||||||
|
'price' => 9.99,
|
||||||
|
'signup_fee' => 0,
|
||||||
|
'invoice_period' => 1,
|
||||||
|
'invoice_interval' => 'month',
|
||||||
|
'trial_period' => 7,
|
||||||
|
'trial_interval' => 'day',
|
||||||
|
'sort_order' => 1,
|
||||||
|
'currency' => 'USD',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Create multiple plan features at once
|
||||||
|
$plan->features()->saveMany([
|
||||||
|
new PlanFeature(['name' => 'Storage capacity', 'value' => 200, 'sort_order' => 1]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $plan;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2. Get plan
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $plan = app('rinvex.subscriptions.plan')->find(6);
|
||||||
|
|
||||||
|
return $plan;
|
||||||
|
//return $plan->subscriptions;
|
||||||
|
|
||||||
|
$space = $plan->getFeatureBySlug('storage-capacity')->value;*/
|
||||||
|
|
||||||
|
//return $space;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 3. Create subscription
|
||||||
|
*/
|
||||||
|
|
||||||
|
$user = Auth::user();
|
||||||
|
//$plan = app('rinvex.subscriptions.plan')->find(6);
|
||||||
|
|
||||||
|
//return $user->activeSubscriptions();
|
||||||
|
|
||||||
|
return $user->subscription('Starter Pack')->cancel();
|
||||||
|
|
||||||
|
//$user->newSubscription('Starter Pack', $plan);
|
||||||
|
|
||||||
|
//return $plan->subscriptions;
|
||||||
|
//return $user->subscribedTo(5);
|
||||||
|
});
|
||||||
|
|
||||||
// Deployment Webhook URL
|
// Deployment Webhook URL
|
||||||
Route::post('/deploy/github', 'DeployController@github');
|
Route::post('/deploy/github', 'DeployController@github');
|
||||||
|
|
||||||
|
|||||||
6
webpack.mix.js
vendored
6
webpack.mix.js
vendored
@@ -23,10 +23,4 @@ mix.js('resources/js/main.js', 'public/js')
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
/* .options({
|
|
||||||
hmrOptions: {
|
|
||||||
host: '172.20.10.5',
|
|
||||||
port: '8080'
|
|
||||||
},
|
|
||||||
})*/
|
|
||||||
.disableNotifications();
|
.disableNotifications();
|
||||||
|
|||||||
Reference in New Issue
Block a user