Remove files related to V2 admin panel
This commit is contained in:
@@ -1,80 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Alert;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\AlertRequest;
|
||||
|
||||
class AlertController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return inertia('Admin/Alerts/Index', [
|
||||
'alerts' => Alert::query()->latest()->paginate()
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return inertia('Admin/Alerts/Create');
|
||||
}
|
||||
|
||||
public function store(AlertRequest $request)
|
||||
{
|
||||
Alert::create($request->all());
|
||||
|
||||
return redirect()->route('admin.alerts.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
return inertia('Admin/Alerts/Edit', [
|
||||
'alert' => Alert::findOrFail($id)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(AlertRequest $request, $id)
|
||||
{
|
||||
Alert::findOrFail($id)->update($request->all());
|
||||
|
||||
return redirect()->route('admin.alerts.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
Alert::findOrFail($id)->delete();
|
||||
|
||||
return redirect()->route('admin.alerts.index');
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class ApplicationLogController extends Controller
|
||||
{
|
||||
protected $final = [];
|
||||
protected $config = [
|
||||
'date' => null
|
||||
];
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->config['date'] = date('Y-m-d');
|
||||
|
||||
if ($date = $request->input('date')) {
|
||||
$this->config['date'] = $date;
|
||||
} else {
|
||||
$request->merge(['date' => date('Y-m-d')]);
|
||||
}
|
||||
|
||||
return inertia('Admin/ApplicationLogs', [
|
||||
'logData' => $this->get(),
|
||||
'filters' => $request->all('date')
|
||||
]);
|
||||
}
|
||||
|
||||
public function getLogFileDates()
|
||||
{
|
||||
$dates = [];
|
||||
$files = glob(storage_path('logs/laravel-*.log'));
|
||||
$files = array_reverse($files);
|
||||
|
||||
foreach ($files as $path) {
|
||||
$fileName = basename($path);
|
||||
preg_match('/(?<=laravel-)(.*)(?=.log)/', $fileName, $dtMatch);
|
||||
$date = $dtMatch[0];
|
||||
array_push($dates, $date);
|
||||
}
|
||||
|
||||
return $dates;
|
||||
}
|
||||
|
||||
public function get()
|
||||
{
|
||||
$availableDates = $this->getLogFileDates();
|
||||
|
||||
if (count($availableDates) == 0) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'No log available'
|
||||
]);
|
||||
}
|
||||
|
||||
$configDate = $this->config['date'];
|
||||
if ($configDate == null) {
|
||||
$configDate = $availableDates[0];
|
||||
}
|
||||
|
||||
if (!in_array($configDate, $availableDates)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'No log file found with selected date ' . $configDate
|
||||
]);
|
||||
}
|
||||
|
||||
$pattern = "/^\[(?<date>.*)\]\s(?<env>\w+)\.(?<type>\w+):(?<message>.*)/m";
|
||||
|
||||
$fileName = 'laravel-' . $configDate . '.log';
|
||||
$content = file_get_contents(storage_path('logs/' . $fileName));
|
||||
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER, 0);
|
||||
|
||||
$logs = [];
|
||||
foreach ($matches as $match) {
|
||||
$logs[] = [
|
||||
'timestamp' => $match['date'],
|
||||
'env' => $match['env'],
|
||||
'type' => $match['type'],
|
||||
'message' => trim($match['message'])
|
||||
];
|
||||
}
|
||||
|
||||
preg_match('/(?<=laravel-)(.*)(?=.log)/', $fileName, $dtMatch);
|
||||
$date = $dtMatch[0];
|
||||
|
||||
$data = [
|
||||
'available_dates' => $availableDates,
|
||||
'date' => $date,
|
||||
'filename' => $fileName,
|
||||
'logs' => array_reverse($logs)
|
||||
];
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use App\Models\SystemLog;
|
||||
use App\Models\User;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
return inertia('Admin/Dashboard', [
|
||||
'servers' => Server::count(),
|
||||
'sites' => Site::count(),
|
||||
'users' => User::count(),
|
||||
'logs' => SystemLog::query()
|
||||
->latest()
|
||||
->with('model')
|
||||
->paginate(5)
|
||||
->through(function (SystemLog $systemLog) {
|
||||
return [
|
||||
'title' => __($systemLog->title, [
|
||||
'site' => $systemLog->model->domain ?? '-Unknown-',
|
||||
]),
|
||||
'description' => __($systemLog->description, [
|
||||
'site' => $systemLog->model->domain ?? '-Unknown-',
|
||||
]),
|
||||
'created_at_huma≥n' => $systemLog->created_at->diffForHumans(),
|
||||
];
|
||||
}),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\DocumentationItem;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\DocumentationCategory;
|
||||
use App\Http\Requests\Admin\DocumentationArticleRequest;
|
||||
|
||||
class DocumentationArticleController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$articles = DocumentationItem::query()->with('category:id,title')->latest()->paginate();
|
||||
|
||||
return inertia('Admin/Documentation/Articles/Index', [
|
||||
'articles' => $articles
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$categories = DocumentationCategory::pluck('title', 'id');
|
||||
|
||||
return inertia('Admin/Documentation/Articles/Create', [
|
||||
'categories' => $categories,
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(DocumentationArticleRequest $request)
|
||||
{
|
||||
$article = DocumentationItem::create([
|
||||
'title' => $request->input('title'),
|
||||
'content' => $request->input('content')
|
||||
]);
|
||||
|
||||
$article->documentation_category_id = $request->input('category_id');
|
||||
$article->save();
|
||||
|
||||
return redirect()->route('admin.documentation.articles.index')->with('success', __('Documentation article has been created'));
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$article = DocumentationItem::findOrFail($id);
|
||||
|
||||
$categories = DocumentationCategory::pluck('title', 'id');
|
||||
|
||||
return inertia('Admin/Documentation/Articles/Edit', [
|
||||
'article' => $article,
|
||||
'categories' => $categories
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(DocumentationArticleRequest $request, $id)
|
||||
{
|
||||
$article = DocumentationItem::findOrFail($id);
|
||||
|
||||
$article->update([
|
||||
'title' => $request->input('title'),
|
||||
'content' => $request->input('content')
|
||||
]);
|
||||
|
||||
$article->documentation_category_id = $request->input('category_id');
|
||||
$article->save();
|
||||
|
||||
return redirect()->route('admin.documentation.articles.index')->with('success', __('Documentation article has been updated'));
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\DocumentationCategory;
|
||||
use App\Http\Requests\Admin\DocumentationCategoryRequest;
|
||||
|
||||
class DocumentationController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$categories = DocumentationCategory::query()->latest()->paginate();
|
||||
|
||||
return inertia('Admin/Documentation/Index', [
|
||||
'categories' => $categories
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return inertia('Admin/Documentation/Create');
|
||||
}
|
||||
|
||||
public function store(DocumentationCategoryRequest $request)
|
||||
{
|
||||
DocumentationCategory::create([
|
||||
'title' => $request->input('title'),
|
||||
'description' => $request->input('description')
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.documentation.index')->with('success', __('Documentation category has been created'));
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$category = DocumentationCategory::findOrFail($id);
|
||||
|
||||
return inertia('Admin/Documentation/Edit', [
|
||||
'category' => $category
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(DocumentationCategoryRequest $request, $id)
|
||||
{
|
||||
$category = DocumentationCategory::findOrFail($id);
|
||||
|
||||
$category->update([
|
||||
'title' => $request->input('title'),
|
||||
'description' => $request->input('description'),
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.documentation.index')->with('success', __('Documentation category has been updated'));
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Package;
|
||||
use App\Models\Provider;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\PackageRequest;
|
||||
|
||||
class PackageController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$packages = Package::withCount('users')->latest()->get();
|
||||
|
||||
return inertia('Admin/Packages/Index', [
|
||||
'packages' => $packages,
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$providers = Provider::get(['name', 'label', 'id'])->pluck('nameWithLabel', 'id');
|
||||
|
||||
return inertia('Admin/Packages/Create', [
|
||||
'providers' => $providers
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(PackageRequest $request)
|
||||
{
|
||||
$package = Package::create($request->validated());
|
||||
|
||||
$package->providers()->sync($request->input('providers'));
|
||||
|
||||
return redirect()->route('admin.packages.index')->with('success', __('Package has been created'));
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$package = Package::with('providers:id')->findOrFail($id);
|
||||
|
||||
$providers = Provider::get(['name', 'label', 'id'])->pluck('nameWithLabel', 'id');
|
||||
|
||||
return inertia('Admin/Packages/Edit', [
|
||||
'package' => $package,
|
||||
'providers' => $providers,
|
||||
'syncedProviders' => $package->providers->pluck('id')
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(PackageRequest $request, $id)
|
||||
{
|
||||
$package = Package::findOrFail($id);
|
||||
|
||||
$package->update($request->validated());
|
||||
|
||||
$package->providers()->sync($request->input('providers'));
|
||||
|
||||
return redirect()->route('admin.packages.index')->with('success', __('Package has been updated'));
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$package = Package::findOrFail($id);
|
||||
|
||||
$package->delete();
|
||||
|
||||
return redirect()->route('admin.packages.index')->with('success', __('Package has been removed'));
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Provider;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\ProviderRequest;
|
||||
|
||||
class ProviderController extends Controller
|
||||
{
|
||||
public function edit($id)
|
||||
{
|
||||
$provider = Provider::findOrFail($id);
|
||||
|
||||
return inertia('Admin/Services/Provider/Edit', [
|
||||
'provider' => $provider,
|
||||
'availablePlans' => $provider->plans()->pluck('label', 'id'),
|
||||
'availableRegions' => $provider->regions()->pluck('label', 'id'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(ProviderRequest $request, $id)
|
||||
{
|
||||
$provider = Provider::findOrFail($id);
|
||||
|
||||
$provider->update($request->validated());
|
||||
|
||||
return redirect()->route('admin.services.index')->with('success', __('Provider has been updated'));
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$provider = Provider::findOrFail($id);
|
||||
|
||||
$provider->delete();
|
||||
|
||||
return redirect()->route('admin.services.index')->with('success', __('Provider has been deleted'));
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class ProviderPlanController extends Controller
|
||||
{
|
||||
//
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class ProviderRegionController extends Controller
|
||||
{
|
||||
//
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Resources\Admin\ServerResource;
|
||||
use App\Http\Requests\Admin\ServerAttachRequest;
|
||||
|
||||
class ServerController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return inertia('Admin/Servers/Index', [
|
||||
'filters' => request()->all('search'),
|
||||
'servers' => ServerResource::collection(
|
||||
Server::query()
|
||||
->when(request()->input('search'), function (Builder $query, $value) {
|
||||
return $query
|
||||
->where('name', 'like', '%' . $value . '%')
|
||||
->orWhere('ip', 'like', '%' . $value . '%')
|
||||
->orWhereHas('users', function (Builder $query) use ($value) {
|
||||
return $query
|
||||
->where('name', 'LIKE', '%' . $value . '%')
|
||||
->orWhere('email', 'LIKE', '%' . $value . '%');
|
||||
});
|
||||
})
|
||||
->with('users:id,name')
|
||||
->withCount('sites')
|
||||
->latest()
|
||||
->paginate(config('core.pagination.per_page'))
|
||||
->withQueryString()
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$server = Server::findOrFail($id);
|
||||
|
||||
$users = $server->users()->select('id', 'name', 'email')->get()->map(function ($user) {
|
||||
return [
|
||||
'id' => $user->id,
|
||||
'name' => $user->name,
|
||||
'email' => $user->email
|
||||
];
|
||||
});
|
||||
|
||||
return inertia('Admin/Services/Server/Edit', [
|
||||
'server' => $server,
|
||||
'users' => $users
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$server = Server::findOrFail($id);
|
||||
|
||||
$server->update($request->all());
|
||||
|
||||
return redirect()->route('admin.services.index')->with('success', __('Server has been updated'));
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$server = Server::findOrFail($id);
|
||||
|
||||
$server->delete();
|
||||
|
||||
return redirect()->route('admin.services.index')->with('success', __('Server has been deleted'));
|
||||
}
|
||||
|
||||
public function attach(ServerAttachRequest $request, $id)
|
||||
{
|
||||
/* @var $server \App\Models\Server */
|
||||
$server = Server::findOrFail($id);
|
||||
|
||||
$user = User::where('email', $request->input('email'))->first();
|
||||
|
||||
if ($server->users()->where('email', $request->input('email'))->count()) {
|
||||
return redirect()->back()->withErrors([
|
||||
'email' => __('This user is already attached to this server')
|
||||
]);
|
||||
}
|
||||
|
||||
$server->users()->attach($user);
|
||||
|
||||
return redirect()->route('admin.services.servers.edit', $id)->with('success', __('User has been attached'));
|
||||
}
|
||||
|
||||
public function detach($id, $userId)
|
||||
{
|
||||
$server = Server::findOrFail($id);
|
||||
|
||||
$server->users()->detach($userId);
|
||||
|
||||
return redirect()->route('admin.services.servers.edit', $server->id)->with('success', __('User has been detached'));
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Site;
|
||||
use App\Models\Server;
|
||||
use App\Models\Provider;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class ServiceController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return inertia('Admin/Services/Index', [
|
||||
'servers' => Server::query()->withCount('sites', 'users')->latest()->paginate(config('core.pagination.per_page'), ['*'], 'servers_per_page'),
|
||||
'sites' => Site::with('server:id,name')->withCount('users')->latest()->paginate(config('core.pagination.per_page'), ['*'], 'sites_per_page'),
|
||||
'providers' => Provider::query()
|
||||
->withCount('regions', 'plans', 'servers')
|
||||
->latest()
|
||||
->paginate(config('core.pagination.per_page'), ['*'], 'providers_per_page'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Package;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Http\Requests\Admin\SettingRequest;
|
||||
|
||||
class SettingController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$settings = [
|
||||
'name' => setting('name'),
|
||||
'email' => setting('email'),
|
||||
'support_emails' => setting('support_emails'),
|
||||
'support' => setting('support'),
|
||||
'documentation' => setting('documentation'),
|
||||
'allow_registration' => setting('allow_registration'),
|
||||
'default_package' => setting('default_package'),
|
||||
'receive_email_on_server_creation' => setting('receive_email_on_server_creation'),
|
||||
'receive_email_on_site_creation' => setting('receive_email_on_site_creation'),
|
||||
'isolate_per_site_per_user' => setting('isolate_per_site_per_user'),
|
||||
'enable_api' => setting('enable_api'),
|
||||
'api_token' => setting('api_token') ? decrypt(setting('api_token')) : null,
|
||||
'rotate_logs_after' => setting('rotate_logs_after') ? setting('rotate_logs_after') : null,
|
||||
'default_language' => setting('default_language', 'en'),
|
||||
'has_logo' => (bool)setting('logo'),
|
||||
'trial' => setting('trial'),
|
||||
'trial_package' => setting('trial_package'),
|
||||
];
|
||||
|
||||
$packages = Package::pluck('name', 'id');
|
||||
|
||||
return inertia('Admin/Settings', [
|
||||
'company_settings' => $settings,
|
||||
'packages' => $packages,
|
||||
'languages' => languages()
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(SettingRequest $request)
|
||||
{
|
||||
foreach ($request->only([
|
||||
'name',
|
||||
'email',
|
||||
'support',
|
||||
'support_emails',
|
||||
'allow_registration',
|
||||
'documentation',
|
||||
'default_package',
|
||||
'receive_email_on_server_creation',
|
||||
'receive_email_on_site_creation',
|
||||
'isolate_per_site_per_user',
|
||||
'enable_api',
|
||||
'api_token',
|
||||
'default_language',
|
||||
'rotate_logs_after',
|
||||
'trial',
|
||||
'trial_package'
|
||||
]) as $key => $value) {
|
||||
if ($key === 'api_token') {
|
||||
$value = encrypt($value);
|
||||
}
|
||||
|
||||
if ($key === 'default_package' && $value === 'false') {
|
||||
$value = null;
|
||||
}
|
||||
|
||||
if ($value === 'false') {
|
||||
$value = 0;
|
||||
}
|
||||
|
||||
if ($value === 'true') {
|
||||
$value = 1;
|
||||
}
|
||||
|
||||
setting([$key => $value]);
|
||||
}
|
||||
|
||||
if ($logo = $request->file('logo')) {
|
||||
// If we previously had a logo, rotate that
|
||||
if ($oldLogo = setting('logo')) {
|
||||
Storage::delete(str_replace('/storage/', '/public/', $oldLogo));
|
||||
}
|
||||
|
||||
$version = Str::random();
|
||||
|
||||
$request->file('logo')->storePubliclyAs('logo', 'logo-' . $version . '.' . $request->file('logo')->extension(), 'public');
|
||||
setting(['logo' => '/storage/logo/logo-' . $version . '.' . $request->file('logo')->extension()]);
|
||||
}
|
||||
|
||||
cache()->forget('core.settings');
|
||||
|
||||
return redirect()->route('admin.settings')->with('success', __('Settings have been updated'));
|
||||
}
|
||||
|
||||
public function terms()
|
||||
{
|
||||
return inertia('Admin/Terms', [
|
||||
'terms_settings' => [
|
||||
'logo' => setting('logo'),
|
||||
'name' => setting('name'),
|
||||
'terms_required' => setting('accept_terms_required'),
|
||||
'terms' => setting('terms'),
|
||||
'privacy' => setting('privacy')
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateTerms(Request $request)
|
||||
{
|
||||
setting(['accept_terms_required' => $request->input('terms_required'),]);
|
||||
setting(['terms' => $request->input('terms'),]);
|
||||
setting(['privacy' => $request->input('privacy'),]);
|
||||
|
||||
return redirect()->route('admin.settings.terms')->with('success', __('Terms have been updated'));
|
||||
}
|
||||
|
||||
public function termsTemplate(Request $request)
|
||||
{
|
||||
$template = file_get_contents(storage_path('templates/terms-of-service.md'));
|
||||
$template = str_replace([
|
||||
'{NAME}',
|
||||
'{WEBSITE}',
|
||||
'{DATE}'
|
||||
], [
|
||||
setting('name'),
|
||||
config('app.url'),
|
||||
date('Y-m-d')
|
||||
], $template);
|
||||
|
||||
return ['content' => $template];
|
||||
}
|
||||
|
||||
public function removeLogo(Request $request)
|
||||
{
|
||||
Storage::delete(setting('logo'));
|
||||
|
||||
setting(['logo' => null]);
|
||||
|
||||
return redirect()->back()->with('success', 'Logo has ben removed');
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\ServerAttachRequest;
|
||||
use App\Http\Resources\Admin\SiteResource;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SiteController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return inertia('Admin/Sites/Index', [
|
||||
'filters' => request()->all('search'),
|
||||
'sites' => SiteResource::collection(
|
||||
Site::query()
|
||||
->when(request()->input('search'), function ($query, $value) {
|
||||
return $query->where('domain', 'like', '%' . $value . '%');
|
||||
})
|
||||
->with('server:id,name', 'users:id,name')
|
||||
->latest()
|
||||
->paginate(config('core.pagination.per_page'))
|
||||
->withQueryString()
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$site = Site::findOrFail($id);
|
||||
|
||||
$users = $site->users()->select('id', 'name', 'email')->get()->map(function ($user) {
|
||||
return [
|
||||
'id' => $user->id,
|
||||
'name' => $user->name,
|
||||
'email' => $user->email,
|
||||
];
|
||||
});
|
||||
|
||||
return inertia('Admin/Services/Site/Edit', [
|
||||
'site' => $site,
|
||||
'users' => $users,
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$site = Site::findOrFail($id);
|
||||
|
||||
$site->update($request->all());
|
||||
|
||||
return redirect()->route('admin.services.index')->with('success', __('Site has been updated'));
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$site = Site::findOrFail($id);
|
||||
|
||||
$site->delete();
|
||||
|
||||
return redirect()->route('admin.services.index')->with('success', __('Site has been deleted'));
|
||||
}
|
||||
|
||||
public function attach(ServerAttachRequest $request, $id)
|
||||
{
|
||||
/* @var $site Server */
|
||||
$site = Site::findOrFail($id);
|
||||
|
||||
$user = User::where('email', $request->input('email'))->first();
|
||||
|
||||
if ( $site->users()->where('email', $request->input('email'))->count() ) {
|
||||
return redirect()->back()->withErrors([
|
||||
'email' => __('This user is already attached to this site'),
|
||||
]);
|
||||
}
|
||||
|
||||
$site->users()->attach($user);
|
||||
|
||||
return redirect()->route('admin.services.sites.edit', $id)->with('success', __('User has been attached'));
|
||||
}
|
||||
|
||||
public function detach($id, $userId)
|
||||
{
|
||||
$site = Site::findOrFail($id);
|
||||
|
||||
$site->users()->detach($userId);
|
||||
|
||||
return redirect()->route('admin.services.sites.edit', $site->id)->with('success', __('User has been detached'));
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class StatusController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return inertia('Admin/Status');
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\SupportTicket;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use App\Mail\Support\TicketRepliedToEmail;
|
||||
use App\Http\Requests\SupportTicketReplyRequest;
|
||||
|
||||
class SupportController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$tickets = SupportTicket::whereIn('status', [
|
||||
SupportTicket::STATUS_CUSTOMER_REPLY,
|
||||
SupportTicket::STATUS_OPEN
|
||||
])
|
||||
->withCount('replies')
|
||||
->latest()
|
||||
->get();
|
||||
|
||||
return inertia('Admin/Support/Index', [
|
||||
'tickets' => $tickets
|
||||
]);
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$ticket = SupportTicket::with('user:id,name,email')->findOrFail($id);
|
||||
|
||||
$replies = $ticket->replies()
|
||||
->with('user:id,name,email')
|
||||
->get();
|
||||
|
||||
return inertia('Admin/Support/Show', [
|
||||
'ticket' => $ticket,
|
||||
'replies' => $replies
|
||||
]);
|
||||
}
|
||||
|
||||
public function reply(SupportTicketReplyRequest $request, $id)
|
||||
{
|
||||
$ticket = SupportTicket::findOrFail($id);
|
||||
|
||||
$ticket->status = SupportTicket::STATUS_SUPPORT_REPLY;
|
||||
$ticket->save();
|
||||
|
||||
$reply = $ticket->replies()->create([
|
||||
'content' => $request->input('content')
|
||||
]);
|
||||
|
||||
$reply->user_id = $request->user()->id;
|
||||
$reply->save();
|
||||
|
||||
Mail::to($ticket->user)->send(new TicketRepliedToEmail($ticket));
|
||||
|
||||
return redirect()->route('admin.support.index');
|
||||
}
|
||||
|
||||
public function close(Request $request, $id)
|
||||
{
|
||||
$ticket = SupportTicket::findOrFail($id);
|
||||
|
||||
$ticket->status = SupportTicket::STATUS_CLOSED;
|
||||
$ticket->save();
|
||||
|
||||
return redirect()->route('admin.support.index')->with('success', __('Support ticket has been closed'));
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Provider;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class SynchronizeProviderController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if ($this->isDemo()) {
|
||||
return redirect('/')->with('info', __('This feature is not available in demo mode.'));
|
||||
}
|
||||
|
||||
$availableProviders = $this->getPloi()->user()->serverProviders()->getData();
|
||||
|
||||
$currentProviders = Provider::query()
|
||||
->whereNotIn('id', array_keys((array)$availableProviders))
|
||||
->get();
|
||||
|
||||
return inertia('Admin/Services/Providers', [
|
||||
'availableProviders' => $availableProviders,
|
||||
'currentProviders' => $currentProviders
|
||||
]);
|
||||
}
|
||||
|
||||
public function synchronize(Request $request, $providerId)
|
||||
{
|
||||
$ploiProvider = $this->getPloi()->user()->serverProviders($providerId)->getData();
|
||||
|
||||
$provider = Provider::updateOrCreate([
|
||||
'ploi_id' => $ploiProvider->id,
|
||||
], [
|
||||
'label' => $ploiProvider->label,
|
||||
'name' => $ploiProvider->name
|
||||
]);
|
||||
|
||||
foreach ($ploiProvider->provider->plans as $plan) {
|
||||
$provider->plans()->updateOrCreate([
|
||||
'plan_id' => $plan->id
|
||||
], [
|
||||
'label' => $plan->name,
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ($ploiProvider->provider->regions as $region) {
|
||||
$provider->regions()->updateOrCreate([
|
||||
'region_id' => $region->id
|
||||
], [
|
||||
'label' => $region->name,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SynchronizeServerController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if ( $this->isDemo() ) {
|
||||
return redirect('/')->with('info', __('This feature is not available in demo mode.'));
|
||||
}
|
||||
|
||||
$availableServers = $this->getPloi()->synchronize()->servers()->getData();
|
||||
|
||||
$currentServers = Server::query()
|
||||
->whereNotIn('id', array_keys((array) $availableServers))
|
||||
->get();
|
||||
|
||||
return inertia('Admin/Services/Servers', [
|
||||
'availableServers' => $availableServers,
|
||||
'currentServers' => $currentServers,
|
||||
]);
|
||||
}
|
||||
|
||||
public function synchronizeServer(Request $request)
|
||||
{
|
||||
$this->getPloi()->synchronize()->servers()->getData();
|
||||
Server::query()
|
||||
->updateOrCreate([
|
||||
'ploi_id' => $request->input('id'),
|
||||
], [
|
||||
'status' => $request->input('status'),
|
||||
'name' => $request->input('name'),
|
||||
'ip' => $request->input('ip_address'),
|
||||
'ssh_port' => $request->input('ssh_port', 22),
|
||||
'internal_ip' => $request->input('internal_ip'),
|
||||
'available_php_versions' => $request->input('installed_php_versions'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function synchronizeAll()
|
||||
{
|
||||
$availableServers = $this->getPloi()->synchronize()->servers()->getData();
|
||||
|
||||
foreach ($availableServers as $availableServer) {
|
||||
Server::query()
|
||||
->updateOrCreate([
|
||||
'ploi_id' => $availableServer->id,
|
||||
], [
|
||||
'status' => $availableServer->status,
|
||||
'name' => $availableServer->name,
|
||||
'ip' => $availableServer->ip_address,
|
||||
'ssh_port' => $availableServer->ssh_port,
|
||||
'internal_ip' => $availableServer->internal_ip,
|
||||
'available_php_versions' => $availableServer->installed_php_versions,
|
||||
]);
|
||||
}
|
||||
|
||||
return response('ok');
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Server;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SynchronizeSiteController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if ( $this->isDemo() ) {
|
||||
return redirect('/')->with('info', __('This feature is not available in demo mode.'));
|
||||
}
|
||||
|
||||
$availableSites = $this->getPloi()->synchronize()->sites()->getData();
|
||||
|
||||
$currentSites = Site::query()
|
||||
->whereNotIn('id', array_keys((array) $availableSites))
|
||||
->get();
|
||||
|
||||
return inertia('Admin/Services/Sites', [
|
||||
'availableSites' => $availableSites,
|
||||
'currentSites' => $currentSites,
|
||||
]);
|
||||
}
|
||||
|
||||
public function synchronizeSite(Request $request)
|
||||
{
|
||||
$server = Server::query()
|
||||
->where('ploi_id', $request->input('server_id'))
|
||||
->firstOrFail();
|
||||
|
||||
$site = Site::query()
|
||||
->updateOrCreate([
|
||||
'ploi_id' => $request->input('id'),
|
||||
], [
|
||||
'domain' => $request->input('domain'),
|
||||
'php_version' => $request->input('php_version'),
|
||||
'project' => $request->input('project_type'),
|
||||
]);
|
||||
|
||||
$site->status = $request->input('status');
|
||||
$site->server_id = $server->id;
|
||||
$site->save();
|
||||
|
||||
$certificates = $this->getPloi()->server($request->input('server_id'))->sites($request->input('id'))->certificates()->get()->getData();
|
||||
|
||||
if ( $certificates ) {
|
||||
foreach ($certificates as $certificate) {
|
||||
$site->certificates()->updateOrCreate([
|
||||
'ploi_id' => $certificate->id,
|
||||
], [
|
||||
'status' => $certificate->status,
|
||||
'ploi_id' => $certificate->id,
|
||||
'domain' => $certificate->domain,
|
||||
'type' => $certificate->type,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return response('ok');
|
||||
}
|
||||
|
||||
public function synchronizeAll(Request $request)
|
||||
{
|
||||
$availableSites = $this->getPloi()->synchronize()->sites()->getData();
|
||||
|
||||
foreach ($availableSites as $availableSite) {
|
||||
$server = Server::query()->where('ploi_id', $availableSite->server_id)->firstOrFail();
|
||||
|
||||
$site = Site::query()
|
||||
->updateOrCreate([
|
||||
'ploi_id' => $availableSite->id,
|
||||
], [
|
||||
'domain' => $availableSite->domain,
|
||||
'php_version' => $availableSite->php_version,
|
||||
]);
|
||||
|
||||
$site->status = $availableSite->status;
|
||||
$site->server_id = $server->id;
|
||||
$site->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use Inertia\Response;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Jobs\Core\UpdateSystem;
|
||||
use App\Services\VersionChecker;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Laravel\Horizon\Contracts\MasterSupervisorRepository;
|
||||
|
||||
class SystemController extends Controller
|
||||
{
|
||||
public function index(Request $request, MasterSupervisorRepository $masterSupervisorRepository): Response|RedirectResponse
|
||||
{
|
||||
if ($request->input('flush', false)) {
|
||||
app(VersionChecker::class)->flushVersionData();
|
||||
|
||||
return redirect()->route('admin.system')->with('success', __('Refreshed versions'));
|
||||
}
|
||||
|
||||
$version = app(VersionChecker::class)->getVersions();
|
||||
|
||||
return inertia('Admin/System', [
|
||||
'version' => [
|
||||
'out_of_date' => $version->isOutOfDate(),
|
||||
'current' => $version->currentVersion,
|
||||
'remote' => $version->remoteVersion
|
||||
],
|
||||
'horizonRunning' => (bool) $masterSupervisorRepository->all(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(Request $request): RedirectResponse
|
||||
{
|
||||
dispatch(new UpdateSystem);
|
||||
|
||||
return redirect()->route('admin.system')->with('success', __('System update has been dispatched, this could take around 2/3 minutes for it to complete'));
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\UserRequest;
|
||||
use App\Models\Package;
|
||||
use App\Models\User;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$users = User::query()
|
||||
->withCount('sites', 'servers')
|
||||
->with('package:id,name')
|
||||
->when(request()->input('search'), function ($query, $value) {
|
||||
return $query->where('name', 'like', '%' . $value . '%')->orWhere('email', 'like', '%' . $value . '%');
|
||||
})
|
||||
->latest()
|
||||
->paginate(config('core.pagination.per_page'));
|
||||
|
||||
return inertia('Admin/Users/Index', [
|
||||
'filters' => request()->all('search'),
|
||||
'users' => $users,
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$packages = Package::orderBy('name')
|
||||
->pluck('name', 'id');
|
||||
|
||||
return inertia('Admin/Users/Create', [
|
||||
'packages' => $packages,
|
||||
'languages' => languages(),
|
||||
'defaultPackage' => (string) setting('default_package'),
|
||||
'defaultLanguage' => (string) setting('default_language', 'en'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(UserRequest $request)
|
||||
{
|
||||
$user = User::create($request->all());
|
||||
|
||||
if ( $request->input('role') === User::ADMIN ) {
|
||||
$user->role = User::ADMIN;
|
||||
$user->save();
|
||||
}
|
||||
|
||||
if ( $request->input('package') && Package::find($request->input('package')) ) {
|
||||
$user->package_id = $request->input('package');
|
||||
$user->save();
|
||||
}
|
||||
|
||||
return redirect()->route('admin.users.index')->with('success', 'User ' . $user->name . ' has been created');
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$user = User::query()->findOrFail($id);
|
||||
|
||||
$servers = $user->servers()->withCount('sites')->latest()->paginate(config('core.pagination.per_page'), ['*'], 'page_servers');
|
||||
|
||||
$sites = $user->sites()->with('server:id,name')->latest()->paginate(config('core.pagination.per_page'), ['*'], 'page_sites');
|
||||
|
||||
return inertia('Admin/Users/Show', [
|
||||
'user' => $user,
|
||||
'sites' => $sites,
|
||||
'servers' => $servers,
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$packages = Package::orderBy('name')->pluck('name', 'id');
|
||||
|
||||
return inertia('Admin/Users/Edit', [
|
||||
'user' => User::findOrFail($id),
|
||||
'packages' => $packages,
|
||||
'languages' => languages(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(UserRequest $request, $id)
|
||||
{
|
||||
$user = User::findOrFail($id);
|
||||
|
||||
$user->update($request->all());
|
||||
|
||||
if ( $request->input('role') !== $user->role ) {
|
||||
$user->role = $request->input('role');
|
||||
$user->save();
|
||||
}
|
||||
|
||||
if ( $request->input('package') !== $user->package_id ) {
|
||||
$user->package_id = $request->input('package');
|
||||
$user->save();
|
||||
}
|
||||
|
||||
return redirect()->route('admin.users.index')->with('success', 'User ' . $user->name . ' has been updated');
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
User::findOrFail($id)->delete();
|
||||
|
||||
return redirect()->route('admin.users.index')->with('success', 'User has been deleted');
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use App\Models\Alert;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class AlertRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check() && auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'message' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:500'
|
||||
],
|
||||
'type' => [
|
||||
'required',
|
||||
'string',
|
||||
Rule::in([
|
||||
Alert::TYPE_INFO,
|
||||
Alert::TYPE_DANGER,
|
||||
Alert::TYPE_WARNING
|
||||
])
|
||||
],
|
||||
'expires_at' => [
|
||||
'nullable',
|
||||
'date',
|
||||
'date_format:Y-m-d H:i:s'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class DocumentationArticleRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check() && auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'title' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
'content' => [
|
||||
'required',
|
||||
'min:2'
|
||||
],
|
||||
'category_id' => [
|
||||
'required',
|
||||
'exists:documentation_categories,id'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class DocumentationCategoryRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check() && auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'title' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
'description' => [
|
||||
'nullable',
|
||||
'string'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use App\Models\Package;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class PackageRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check() && auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
'currency' => [
|
||||
'nullable',
|
||||
Rule::in([
|
||||
Package::CURRENCY_USD,
|
||||
Package::CURRENCY_EURO,
|
||||
Package::CURRENCY_NOK,
|
||||
Package::CURRENCY_AUD,
|
||||
Package::CURRENCY_CAD,
|
||||
Package::CURRENCY_GBP,
|
||||
Package::CURRENCY_INR,
|
||||
Package::CURRENCY_THB,
|
||||
Package::CURRENCY_BRL,
|
||||
])
|
||||
],
|
||||
'maximum_sites' => [
|
||||
'required',
|
||||
'numeric',
|
||||
'min:0',
|
||||
],
|
||||
'maximum_servers' => [
|
||||
'required',
|
||||
'numeric',
|
||||
'min:0',
|
||||
],
|
||||
'plan_id' => [
|
||||
'nullable',
|
||||
],
|
||||
'price_monthly' => [
|
||||
'nullable',
|
||||
'numeric',
|
||||
],
|
||||
'price_yearly' => [
|
||||
'nullable',
|
||||
'numeric',
|
||||
],
|
||||
'server_permissions' => [
|
||||
'array'
|
||||
],
|
||||
'site_permissions' => [
|
||||
'array'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$merge = [];
|
||||
|
||||
// If we don't have the monthly price filled in, merge a default
|
||||
if (!$this->price_monthly) {
|
||||
$merge['price_monthly'] = 0.000;
|
||||
}
|
||||
|
||||
if (!$this->price_yearly) {
|
||||
$merge['price_yearly'] = 0.000;
|
||||
}
|
||||
|
||||
// If we don't have the currency filled in, merge a default
|
||||
if (!$this->price_monthly || !$this->price_yearly) {
|
||||
$merge['currency'] = Package::CURRENCY_USD;
|
||||
}
|
||||
|
||||
$this->merge($merge);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ProviderRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check() && auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
'allowed_plans' => [
|
||||
'nullable',
|
||||
'array'
|
||||
],
|
||||
'allowed_regions' => [
|
||||
'nullable',
|
||||
'array'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ServerAttachRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check() && auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'email' => [
|
||||
'required',
|
||||
'email',
|
||||
'exists:users'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SettingRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check() && auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
|
||||
'email' => [
|
||||
'nullable',
|
||||
'email'
|
||||
],
|
||||
|
||||
'logo' => [
|
||||
'nullable',
|
||||
'image',
|
||||
'max:2000'
|
||||
],
|
||||
|
||||
'trial_package' => [
|
||||
'required_with:trial'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UserRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check() && auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
'email' => [
|
||||
'required',
|
||||
'email:rfc,filter',
|
||||
'max:255',
|
||||
],
|
||||
'role' => [
|
||||
'required',
|
||||
Rule::in([
|
||||
User::ADMIN,
|
||||
User::USER,
|
||||
])
|
||||
],
|
||||
'language' => [
|
||||
'required',
|
||||
'string',
|
||||
Rule::in(languages()),
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\Admin;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ServerResource extends JsonResource
|
||||
{
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'ip' => $this->ip,
|
||||
'users' => $this->users,
|
||||
'sites_count' => $this->sites_count,
|
||||
'maximum_sites' => $this->maximum_sites,
|
||||
'created_at' => $this->created_at->format('Y-m-d H:i:s')
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\Admin;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class SiteResource extends JsonResource
|
||||
{
|
||||
public function toArray($request)
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
@@ -48,12 +48,6 @@ class RouteServiceProvider extends ServiceProvider
|
||||
Route::middleware('web')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web.php'));
|
||||
//
|
||||
Route::middleware(['web', 'auth', 'role:admin'])
|
||||
->prefix('admin-v2')
|
||||
->as('admin.')
|
||||
->namespace($this->namespace . '\\Admin')
|
||||
->group(base_path('routes/admin.php'));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Create alert') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Create') }}</template>
|
||||
<template #subtitle>
|
||||
{{
|
||||
__('Create a new alert here to notify your end users about a specific event. This could be anything from server maintenance to panel updates.')
|
||||
}}
|
||||
</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormTextarea :label="__('Message')" :errors="$page.props.errors.message"
|
||||
v-model="form.message"/>
|
||||
<FormInput :label="__('Expires at')" placeholder="2020-01-01 00:00:00" :errors="$page.props.errors.expires_at" v-model="form.expires_at"/>
|
||||
|
||||
<FormSelect :errors="$page.props.errors.type" :label="__('Type')" v-model="form.type">
|
||||
<option value="info">{{ __('Informational') }}</option>
|
||||
<option value="warning">{{ __('Warning') }}</option>
|
||||
<option value="danger">{{ __('Danger') }}</option>
|
||||
</FormSelect>
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormTextarea from '@/components/forms/FormTextarea'
|
||||
import FormSelect from '@/components/forms/FormSelect'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import Tabs from './Tabs'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Create alert')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormSelect,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
FormTextarea,
|
||||
Tabs,
|
||||
},
|
||||
|
||||
props: {
|
||||
providers: Object
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
type: 'info',
|
||||
message: null,
|
||||
expires_at: null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.$inertia.post(this.route('admin.alerts.store'), this.form, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,145 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Edit alert') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Edit') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormTextarea :label="__('Message')" :errors="$page.props.errors.message"
|
||||
v-model="form.message"/>
|
||||
<FormInput :label="__('Expires at')" placeholder="2020-01-01 00:00:00" :errors="$page.props.errors.expires_at" v-model="form.expires_at"/>
|
||||
|
||||
<FormSelect :errors="$page.props.errors.type" :label="__('Type')" v-model="form.type">
|
||||
<option value="info">{{ __('Informational') }}</option>
|
||||
<option value="warning">{{ __('Warning') }}</option>
|
||||
<option value="danger">{{ __('Danger') }}</option>
|
||||
</FormSelect>
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
<Button variant="danger" type="button" @click="confirmDelete">
|
||||
{{ __('Delete') }}
|
||||
</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormTextarea from '@/components/forms/FormTextarea'
|
||||
import FormSelect from '@/components/forms/FormSelect'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import {useConfirm} from '@/hooks/confirm'
|
||||
import Tabs from './Tabs'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Edit alert')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormSelect,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormTextarea,
|
||||
FormActions,
|
||||
Tabs,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
type: this.alert.type,
|
||||
message: this.alert.message,
|
||||
expires_at: this.alert.expires_at,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
alert: Object,
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.$inertia.patch(this.route('admin.alerts.update', this.alert.id), this.form, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false
|
||||
})
|
||||
},
|
||||
|
||||
confirmDelete() {
|
||||
useConfirm({
|
||||
title: this.__('Are you sure?'),
|
||||
message: this.__('Are you sure you want to delete this alert?'),
|
||||
onConfirm: () => this.delete(),
|
||||
})
|
||||
},
|
||||
|
||||
delete() {
|
||||
this.$inertia.delete(this.route('admin.alerts.delete', this.alert.id), {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,120 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Alerts') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Overview') }}</template>
|
||||
<template #content>
|
||||
<Table caption="Alert list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Content') }}</TableHeader>
|
||||
<TableHeader>{{ __('Expires at') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="alert in alerts.data" :key="alert.id">
|
||||
<TableData>
|
||||
<div v-html="alert.message_html"></div>
|
||||
|
||||
<p class="text-medium-emphasis">{{ alert.type }}</p>
|
||||
</TableData>
|
||||
<TableData>{{ alert.expires_at ? alert.expires_at : '-No expire date-' }}</TableData>
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.alerts.edit', alert.id)"
|
||||
class="text-primary font-medium">
|
||||
{{ __('Edit') }}
|
||||
</inertia-link>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import Tabs from './Tabs';
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Alerts')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Pagination,
|
||||
Tabs,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
},
|
||||
|
||||
props: {
|
||||
alerts: Object
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,36 +0,0 @@
|
||||
<template>
|
||||
<ul class="-ml-4 space-y-1">
|
||||
<li v-for="item in items">
|
||||
<inertia-link
|
||||
class="flex items-center h-10 px-4 font-medium text-medium-emphasis"
|
||||
:class="{'rounded shadow text-primary bg-surface-3': item.active}"
|
||||
:href="item.to"
|
||||
v-html="item.title"
|
||||
></inertia-link>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
items: [
|
||||
{
|
||||
title: this.__('« Back'),
|
||||
to: this.route('admin.dashboard'),
|
||||
},
|
||||
{
|
||||
title: this.__('Overview'),
|
||||
to: this.route('admin.alerts.index'),
|
||||
active: this.route().current('admin.alerts.index')
|
||||
},
|
||||
{
|
||||
title: this.__('Create'),
|
||||
to: this.route('admin.alerts.create'),
|
||||
active: this.route().current('admin.alerts.create')
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,142 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Application logs') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
<div class="space-y-4">
|
||||
<FormSelect :label="__('Date')" v-model="searchFilters.date">
|
||||
<option :value="availableDate" v-for="availableDate in logData.available_dates">{{ availableDate }}</option>
|
||||
</FormSelect>
|
||||
|
||||
<div class="overflow-scroll">
|
||||
<Table caption="User list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Content') }}</TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="(log, index) in logData.logs" :key="index">
|
||||
<TableData>
|
||||
{{ log.message }}
|
||||
|
||||
<p class="text-medium-emphasis">{{ log.type }} at {{ log.timestamp }}</p>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from './components/TopBar.vue'
|
||||
import Container from '@/components/Container.vue'
|
||||
import Content from '@/components/Content.vue'
|
||||
import Page from '@/components/Page.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle.vue'
|
||||
import PageBody from '@/components/PageBody.vue'
|
||||
import Button from '@/components/Button.vue'
|
||||
import List from '@/components/List.vue'
|
||||
import ListItem from '@/components/ListItem.vue'
|
||||
import StatusBubble from '@/components/StatusBubble.vue'
|
||||
import NotificationBadge from '@/components/NotificationBadge.vue'
|
||||
import MainLayout from '@/Layouts/MainLayout.vue'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout.vue'
|
||||
import SettingsSegment from '@/components/SettingsSegment.vue'
|
||||
import FormInput from '@/components/forms/FormInput.vue'
|
||||
import FormSelect from '@/components/forms/FormSelect.vue'
|
||||
import Form from '@/components/Form.vue'
|
||||
import FormActions from '@/components/FormActions.vue'
|
||||
import Tabs from './Tabs.vue'
|
||||
import Table from '@/components/Table.vue'
|
||||
import TableHead from '@/components/TableHead.vue'
|
||||
import TableHeader from '@/components/TableHeader.vue'
|
||||
import TableRow from '@/components/TableRow.vue'
|
||||
import TableBody from '@/components/TableBody.vue'
|
||||
import TableData from '@/components/TableData.vue'
|
||||
import throttle from 'lodash/throttle'
|
||||
import pickBy from 'lodash/pickBy'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Application logs')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormSelect,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
},
|
||||
|
||||
props: {
|
||||
logData: Object,
|
||||
filters: Object
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
searchFilters: {
|
||||
date: this.filters.date,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
searchFilters: {
|
||||
handler: throttle(function() {
|
||||
let query = pickBy(this.searchFilters)
|
||||
this.$inertia.replace(this.route('admin.application-logs', Object.keys(query).length ? query : { remember: 'forget' }))
|
||||
}, 150),
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,148 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Administration') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout space="space-y-0">
|
||||
<template #nav>
|
||||
<Tabs class="mb-16" />
|
||||
</template>
|
||||
<template #segments>
|
||||
<div class="mb-16">
|
||||
<ul class="grid grid-cols-3 gap-4">
|
||||
<li class="p-6 rounded shadow bg-surface-3">
|
||||
<div class="flex space-x-4">
|
||||
<div>
|
||||
<IconHarddisk class="w-6 h-6"/>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-body" v-text="servers"></h3>
|
||||
<p class="text-medium-emphasis text-small">{{ __('Servers') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="p-6 rounded shadow bg-surface-3">
|
||||
<div class="flex space-x-4">
|
||||
<div>
|
||||
<IconGlobe class="w-6 h-6"/>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-body" v-text="sites"></h3>
|
||||
<p class="text-medium-emphasis text-small">{{ __('Sites') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="p-6 rounded shadow bg-surface-3">
|
||||
<div class="flex space-x-4">
|
||||
<div>
|
||||
<IconPerson class="w-6 h-6"/>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-body" v-text="users"></h3>
|
||||
<p class="text-medium-emphasis text-small">{{ __('Users') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="pb-4">
|
||||
<h2>{{ __('Recent logs') }}</h2>
|
||||
<List>
|
||||
<ListItem v-for="log in logs.data" :key="log.id">
|
||||
<template #title>
|
||||
{{ log.title }}
|
||||
</template>
|
||||
<template #subtitle>{{ log.description }}</template>
|
||||
<template #suffix>{{ log.created_at_human }}</template>
|
||||
</ListItem>
|
||||
</List>
|
||||
</div>
|
||||
<pagination :links="logs"/>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
|
||||
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from './components/TopBar.vue'
|
||||
import Container from '@/components/Container.vue'
|
||||
import Content from '@/components/Content.vue'
|
||||
import Page from '@/components/Page.vue'
|
||||
import Pagination from '@/components/Pagination.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle.vue'
|
||||
import PageBody from '@/components/PageBody.vue'
|
||||
import Button from '@/components/Button.vue'
|
||||
import List from '@/components/List.vue'
|
||||
import ListItem from '@/components/ListItem.vue'
|
||||
import StatusBubble from '@/components/StatusBubble.vue'
|
||||
import NotificationBadge from '@/components/NotificationBadge.vue'
|
||||
import MainLayout from '@/Layouts/MainLayout.vue'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout.vue'
|
||||
import SettingsSegment from '@/components/SettingsSegment.vue'
|
||||
import FormInput from '@/components/forms/FormInput.vue'
|
||||
import Form from '@/components/Form.vue'
|
||||
import FormActions from '@/components/FormActions.vue'
|
||||
import Tabs from './Tabs.vue'
|
||||
import IconPerson from '@/components/icons/IconPerson.vue'
|
||||
import IconGlobe from '@/components/icons/IconGlobe.vue'
|
||||
import IconStorage from '@/components/icons/IconStorage.vue'
|
||||
import IconHarddisk from '@/components/icons/IconHarddisk.vue'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Administration')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
Pagination,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
IconPerson,
|
||||
IconGlobe,
|
||||
IconStorage,
|
||||
IconHarddisk,
|
||||
},
|
||||
|
||||
props: {
|
||||
servers: Number,
|
||||
sites: Number,
|
||||
users: Number,
|
||||
logs: [Array, Object],
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,125 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Create article') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Create') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormInput :label="__('Title')" :errors="$page.props.errors.title"
|
||||
v-model="form.title"/>
|
||||
<FormSelect :label="__('Category')" :errors="$page.props.errors.category_id" v-model="form.category_id">
|
||||
<option v-for="(title, id) in categories" :value="id" v-text="title"></option>
|
||||
</FormSelect>
|
||||
<FormTextarea rows="10" :helper-text="__('You may use markdown in this field for markup')" :label="__('Content')"
|
||||
:errors="$page.props.errors.content" v-model="form.content"/>
|
||||
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormSelect from '@/components/forms/FormSelect'
|
||||
import FormTextarea from '@/components/forms/FormTextarea'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import Tabs from '../Tabs'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Create article')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormTextarea,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
FormSelect,
|
||||
},
|
||||
|
||||
props: {
|
||||
categories: Object
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
title: null,
|
||||
description: null,
|
||||
category_id: null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.$inertia.post(this.route('admin.documentation.articles.store'), this.form, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,126 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Edit article') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Edit') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormInput :label="__('Title')" :errors="$page.props.errors.title"
|
||||
v-model="form.title"/>
|
||||
<FormSelect :label="__('Category')" :errors="$page.props.errors.category_id" v-model="form.category_id">
|
||||
<option v-for="(title, id) in categories" :value="id" v-text="title"></option>
|
||||
</FormSelect>
|
||||
<FormTextarea rows="10" helper-text="You may use markdown in this field for markup" :label="__('Content')" :errors="$page.props.errors.content"
|
||||
v-model="form.content"/>
|
||||
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormSelect from '@/components/forms/FormSelect'
|
||||
import FormTextarea from '@/components/forms/FormTextarea'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import Tabs from '../Tabs'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Edit article')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormTextarea,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormSelect,
|
||||
FormActions,
|
||||
Tabs,
|
||||
},
|
||||
|
||||
props: {
|
||||
article: Object,
|
||||
categories: Object,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
title: this.article.title,
|
||||
content: this.article.content,
|
||||
category_id: this.article.documentation_category_id,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.$inertia.patch(this.route('admin.documentation.articles.update', this.article.id), this.form, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,133 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Articles') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Overview') }}</template>
|
||||
<template #content>
|
||||
<Table caption="Documentation category list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Title') }}</TableHeader>
|
||||
<TableHeader>{{ __('Category') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="article in articles.data" :key="article.id">
|
||||
<TableData>
|
||||
{{ article.title }}
|
||||
</TableData>
|
||||
<TableData>{{ article.category.title }}</TableData>
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.documentation.articles.edit', article.id)"
|
||||
class="text-primary font-medium">
|
||||
{{ __('Edit') }}
|
||||
</inertia-link>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import {useNotification} from '@/hooks/notification'
|
||||
import Tabs from '../Tabs';
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Articles')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Pagination,
|
||||
Tabs,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
},
|
||||
|
||||
props: {
|
||||
articles: Object
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
|
||||
},
|
||||
|
||||
methods: {
|
||||
useNotification,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,114 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Create category') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Create') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormInput :label="__('Title')" :errors="$page.props.errors.title"
|
||||
v-model="form.title"/>
|
||||
<FormTextarea :label="__('Description')" :helper-text="__('You may use markdown in this field for markup')" :errors="$page.props.errors.description" v-model="form.description" />
|
||||
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormTextarea from '@/components/forms/FormTextarea'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import Tabs from './Tabs'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Create category')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormTextarea,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
title: null,
|
||||
description: null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.$inertia.post(this.route('admin.documentation.store'), this.form, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,118 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Edit category') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Edit') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormInput :label="__('Title')" :errors="$page.props.errors.title"
|
||||
v-model="form.title"/>
|
||||
<FormTextarea :label="__('Description')" helper-text="You may use markdown in this field for markup" :errors="$page.props.errors.description" v-model="form.description" />
|
||||
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormTextarea from '@/components/forms/FormTextarea'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import Tabs from './Tabs'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Create category')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormTextarea,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
},
|
||||
|
||||
props: {
|
||||
category: Object
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
title: this.category.title,
|
||||
description: this.category.description,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.$inertia.patch(this.route('admin.documentation.update', this.category.id), this.form, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,131 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Documentation') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Overview') }}</template>
|
||||
<template #content>
|
||||
<Table caption="Documentation category list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Title') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="category in categories.data" :key="category.id">
|
||||
<TableData>
|
||||
{{ category.title }}
|
||||
</TableData>
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.documentation.edit', category.id)"
|
||||
class="text-primary font-medium">
|
||||
{{ __('Edit') }}
|
||||
</inertia-link>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import {useNotification} from '@/hooks/notification'
|
||||
import Tabs from './Tabs';
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Documentation')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Pagination,
|
||||
Tabs,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
},
|
||||
|
||||
props: {
|
||||
categories: Object
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
|
||||
},
|
||||
|
||||
methods: {
|
||||
useNotification,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,43 +0,0 @@
|
||||
<template>
|
||||
<ul class="-ml-4 space-y-1">
|
||||
<li v-for="item in items">
|
||||
<inertia-link
|
||||
class="flex items-center h-10 px-4 font-medium text-medium-emphasis"
|
||||
:class="{'rounded shadow text-primary bg-surface-3': item.active}"
|
||||
:href="item.to"
|
||||
>{{ item.title }} {{ item.route }}
|
||||
</inertia-link
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
items: [
|
||||
{
|
||||
title: this.__('Categories'),
|
||||
to: this.route('admin.documentation.index'),
|
||||
active: this.route().current('admin.documentation.index')
|
||||
},
|
||||
{
|
||||
title: this.__('Create category'),
|
||||
to: this.route('admin.documentation.create'),
|
||||
active: this.route().current('admin.documentation.create')
|
||||
},
|
||||
{
|
||||
title: this.__('Articles'),
|
||||
to: this.route('admin.documentation.articles.index'),
|
||||
active: this.route().current('admin.documentation.articles.index')
|
||||
},
|
||||
{
|
||||
title: this.__('Create article'),
|
||||
to: this.route('admin.documentation.articles.create'),
|
||||
active: this.route().current('admin.documentation.articles.create')
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,252 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Create package') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Create') }}</template>
|
||||
<template #subtitle>
|
||||
{{
|
||||
__('Create a new package here to attach to your users. You can create as many packages as you want, the advantage is that you are able to provide custom packages for your users.')
|
||||
}}
|
||||
</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormInput :label="__('Name')" :errors="$page.props.errors.name"
|
||||
v-model="form.name"/>
|
||||
<FormInput :label="__('Maximum sites')" type="number" min="0"
|
||||
:errors="$page.props.errors.maximum_sites"
|
||||
helper-text="Set to 0 for unlimited"
|
||||
v-model="form.maximum_sites"/>
|
||||
<FormInput :label="__('Maximum servers')" type="number" min="0"
|
||||
:errors="$page.props.errors.maximum_servers"
|
||||
helper-text="Set to 0 for unlimited"
|
||||
v-model="form.maximum_servers"/>
|
||||
<FormInput :label="__('Plan ID')" :errors="$page.props.errors.plan_id"
|
||||
helper-text="Enter the pricing ID from Stripe here"
|
||||
v-model="form.plan_id"/>
|
||||
<FormInput v-if="form.plan_id" :label="__('Monthly price')"
|
||||
helper-text="Fill this in if you want it to be monthly payments"
|
||||
:errors="$page.props.errors.price_monthly"
|
||||
v-model="form.price_monthly"/>
|
||||
<FormInput v-if="form.plan_id" :label="__('Yearly price')"
|
||||
helper-text="Fill this in if you want it to be yearly payments"
|
||||
:errors="$page.props.errors.price_yearly"
|
||||
v-model="form.price_yearly"/>
|
||||
<FormSelect :errors="$page.props.errors.currency" v-if="form.plan_id"
|
||||
:label="__('Currency')" v-model="form.currency">
|
||||
<option value="usd">{{ __('USD $') }}</option>
|
||||
<option value="eur">{{ __('Euro €') }}</option>
|
||||
<option value="gbp">{{ __('GBP £') }}</option>
|
||||
<option value="nok">{{ __('NOK (Norwegian Krone)') }}</option>
|
||||
<option value="aud">{{ __('AUD (Australian dollar)') }}</option>
|
||||
<option value="cad">{{ __('CAD (Canadian dollar)') }}</option>
|
||||
<option value="inr">{{ __('INR ₹ (Indian rupee)') }}</option>
|
||||
<option value="thb">{{ __('THB (Thai bath)') }}</option>
|
||||
<option value="brl">{{ __('BRL R$ (Brazilian Real)') }}</option>
|
||||
</FormSelect>
|
||||
|
||||
<div class="space-y-4">
|
||||
<h3 class="text-base leading-6 font-medium border-b border-dotted border-medium-emphasis pb-1">
|
||||
{{ __('Server permissions') }}</h3>
|
||||
|
||||
<div>
|
||||
<input id="server_create" class="form-checkbox" type="checkbox"
|
||||
v-model="form.server_permissions['create']">
|
||||
<label for="server_create"
|
||||
class="ml-2 text-sm">{{ __('Allow server creation') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow users to create servers') }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<input id="server_update" class="form-checkbox" type="checkbox"
|
||||
v-model="form.server_permissions['update']">
|
||||
<label for="server_update"
|
||||
class="ml-2 text-sm">{{ __('Allow server updating') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow users to update servers') }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<input id="server_delete" class="form-checkbox" type="checkbox"
|
||||
v-model="form.server_permissions['delete']">
|
||||
<label for="server_delete"
|
||||
class="ml-2 text-sm">{{ __('Allow server deletion') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow users to delete servers') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<h3 class="text-base leading-6 font-medium border-b border-dotted border-medium-emphasis pb-1">
|
||||
{{ __('Site permissions') }}</h3>
|
||||
|
||||
<div>
|
||||
<input id="site_create" class="form-checkbox" type="checkbox"
|
||||
v-model="form.site_permissions['create']">
|
||||
<label for="site_create"
|
||||
class="ml-2 text-sm">{{ __('Allow site creation') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow users to create sites') }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<input id="site_update" class="form-checkbox" type="checkbox"
|
||||
v-model="form.site_permissions['update']">
|
||||
<label for="site_update"
|
||||
class="ml-2 text-sm">{{ __('Allow site updating') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow users to update sites') }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<input id="site_delete" class="form-checkbox" type="checkbox"
|
||||
v-model="form.site_permissions['delete']">
|
||||
<label for="site_delete"
|
||||
class="ml-2 text-sm">{{ __('Allow site deletion') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow users to delete sites') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2" v-if="form.server_permissions['create']">
|
||||
<h3 class="text-base leading-6 font-medium border-b border-dotted border-medium-emphasis pb-1">
|
||||
{{ __('Available server providers') }}</h3>
|
||||
|
||||
<div v-if="!Object.keys(providers).length" class="bg-primary text-on-primary px-4 py-3 rounded relative space-y-2" role="alert">
|
||||
<p class="block">
|
||||
There are no server providers to select from. You can synchronize new server providers from the Services tab.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div v-for="(name, id) in providers">
|
||||
<input :id="`provider-${id}`" :value="id" v-model="form.providers"
|
||||
class="form-checkbox" type="checkbox">
|
||||
<label :for="`provider-${id}`" class="ml-2 text-sm">{{ name }}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormSelect from '@/components/forms/FormSelect'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import Tabs from './Tabs'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Create package')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormSelect,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
},
|
||||
|
||||
props: {
|
||||
providers: [Array, Object]
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
name: null,
|
||||
plan_id: null,
|
||||
currency: 'usd',
|
||||
maximum_sites: 10,
|
||||
maximum_servers: 1,
|
||||
server_permissions: {
|
||||
create: false,
|
||||
update: false,
|
||||
delete: false,
|
||||
},
|
||||
site_permissions: {
|
||||
create: false,
|
||||
update: false,
|
||||
delete: false
|
||||
},
|
||||
price_monthly: null,
|
||||
price_yearly: null,
|
||||
providers: []
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.$inertia.post(this.route('admin.packages.store'), this.form, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,255 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Edit package') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Edit') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormInput :label="__('Name')" :errors="$page.props.errors.name" v-model="form.name"/>
|
||||
<FormInput :label="__('Maximum sites')" type="number" min="0"
|
||||
helper-text="Set to 0 for unlimited"
|
||||
:errors="$page.props.errors.maximum_sites" v-model="form.maximum_sites"/>
|
||||
<FormInput :label="__('Maximum servers')" type="number" min="0"
|
||||
:errors="$page.props.errors.maximum_servers"
|
||||
helper-text="Set to 0 for unlimited"
|
||||
v-model="form.maximum_servers"/>
|
||||
<FormInput :label="__('Plan ID')" :errors="$page.props.errors.plan_id"
|
||||
helper-text="Enter the pricing ID from Stripe here"
|
||||
v-model="form.plan_id"/>
|
||||
<FormInput v-if="form.plan_id" :label="__('Monthly price')"
|
||||
helper-text="Fill this in if you want it to be monthly payments"
|
||||
:errors="$page.props.errors.price_monthly" v-model="form.price_monthly"/>
|
||||
<FormInput v-if="form.plan_id" :label="__('Yearly price')"
|
||||
helper-text="Fill this in if you want it to be yearly payments"
|
||||
:errors="$page.props.errors.price_yearly" v-model="form.price_yearly"/>
|
||||
<FormSelect :errors="$page.props.errors.currency" v-if="form.plan_id" :label="__('Currency')" v-model="form.currency">
|
||||
<option value="usd">{{ __('USD $') }}</option>
|
||||
<option value="eur">{{ __('Euro €') }}</option>
|
||||
<option value="gbp">{{ __('GBP £') }}</option>
|
||||
<option value="nok">{{ __('NOK (Norwegian Krone)') }}</option>
|
||||
<option value="aud">{{ __('AUD (Australian dollar)') }}</option>
|
||||
<option value="cad">{{ __('CAD (Canadian dollar)') }}</option>
|
||||
<option value="inr">{{ __('INR ₹ (Indian rupee)') }}</option>
|
||||
<option value="thb">{{ __('THB (Thai bath)') }}</option>
|
||||
<option value="brl">{{ __('BRL R$ (Brazilian Real)') }}</option>
|
||||
</FormSelect>
|
||||
|
||||
<div class="space-y-4">
|
||||
<h3 class="text-base leading-6 font-medium border-b border-dotted border-medium-emphasis pb-1">
|
||||
{{ __('Server permissions') }}</h3>
|
||||
|
||||
<div>
|
||||
<input id="server_create" class="form-checkbox" type="checkbox"
|
||||
v-model="form.server_permissions['create']">
|
||||
<label for="server_create"
|
||||
class="ml-2 text-sm">{{ __('Allow server creation') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow users to create servers') }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<input id="server_update" class="form-checkbox" type="checkbox"
|
||||
v-model="form.server_permissions['update']">
|
||||
<label for="server_update"
|
||||
class="ml-2 text-sm">{{ __('Allow server updating') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow users to update servers') }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<input id="server_delete" class="form-checkbox" type="checkbox"
|
||||
v-model="form.server_permissions['delete']">
|
||||
<label for="server_delete"
|
||||
class="ml-2 text-sm">{{ __('Allow server deletion') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow users to delete servers') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<h3 class="text-base leading-6 font-medium border-b border-dotted border-medium-emphasis pb-1">
|
||||
{{ __('Site permissions') }}</h3>
|
||||
|
||||
<div>
|
||||
<input id="site_create" class="form-checkbox" type="checkbox"
|
||||
v-model="form.site_permissions['create']">
|
||||
<label for="site_create"
|
||||
class="ml-2 text-sm">{{ __('Allow site creation') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow users to create sites') }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<input id="site_update" class="form-checkbox" type="checkbox"
|
||||
v-model="form.site_permissions['update']">
|
||||
<label for="site_update"
|
||||
class="ml-2 text-sm">{{ __('Allow site updating') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow users to update sites') }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<input id="site_delete" class="form-checkbox" type="checkbox"
|
||||
v-model="form.site_permissions['delete']">
|
||||
<label for="site_delete"
|
||||
class="ml-2 text-sm">{{ __('Allow site deletion') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow users to delete sites') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2" v-if="form.server_permissions['create']">
|
||||
<h3 class="text-base leading-6 font-medium border-b border-dotted border-medium-emphasis pb-1">
|
||||
{{ __('Available server providers') }}</h3>
|
||||
|
||||
<div v-if="!Object.keys(providers).length" class="bg-primary text-on-primary px-4 py-3 rounded relative space-y-2" role="alert">
|
||||
<p class="block">
|
||||
There are no server providers to select from. You can synchronize new server providers from the Services tab.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div v-for="(name, id) in providers">
|
||||
<input :id="`provider-${id}`" :value="id" v-model="form.providers"
|
||||
class="form-checkbox" type="checkbox">
|
||||
<label :for="`provider-${id}`" class="ml-2 text-sm">{{ name }}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
<Button variant="danger" type="button" @click="confirmDelete">
|
||||
{{ __('Delete') }}
|
||||
</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormSelect from '@/components/forms/FormSelect'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import {useConfirm} from '@/hooks/confirm'
|
||||
import Tabs from './Tabs'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Edit package')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormSelect,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
name: this.package.name,
|
||||
currency: this.package.currency,
|
||||
plan_id: this.package.plan_id,
|
||||
maximum_sites: this.package.maximum_sites,
|
||||
maximum_servers: this.package.maximum_servers,
|
||||
server_permissions: this.package.server_permissions ?? [],
|
||||
site_permissions: this.package.site_permissions ?? [],
|
||||
price_monthly: this.package.price_monthly,
|
||||
price_yearly: this.package.price_yearly,
|
||||
providers: this.syncedProviders ?? []
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
package: Object,
|
||||
providers: [Array, Object],
|
||||
syncedProviders: Array,
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.$inertia.patch(this.route('admin.packages.update', this.package.id), this.form, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false
|
||||
})
|
||||
},
|
||||
|
||||
confirmDelete() {
|
||||
useConfirm({
|
||||
title: this.__('Are you sure?'),
|
||||
message: this.__('Are you sure you want to delete this package? Everything associated with this package will be detached.'),
|
||||
onConfirm: () => this.delete(),
|
||||
})
|
||||
},
|
||||
|
||||
delete() {
|
||||
this.$inertia.delete(this.route('admin.packages.destroy', this.package.id), {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,139 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Packages') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Overview') }}</template>
|
||||
<template #content>
|
||||
<Table caption="Package list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>Max. sites</TableHeader>
|
||||
<TableHeader>Max. servers</TableHeader>
|
||||
<TableHeader>{{ __('Users') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="webPackage in packages" :key="webPackage.id">
|
||||
<TableData>
|
||||
{{ webPackage.name }}
|
||||
|
||||
<p class="text-medium-emphasis" v-if="webPackage.plan_id">Attached to stripe · {{ webPackage.price_monthly }} {{ webPackage.currency }}</p>
|
||||
</TableData>
|
||||
<TableData>{{ webPackage.maximum_sites === 0 ? 'Unlimited' : webPackage.maximum_sites }}</TableData>
|
||||
<TableData>{{ webPackage.maximum_servers === 0 ? 'Unlimited' : webPackage.maximum_servers }}</TableData>
|
||||
<TableData>{{ webPackage.users_count }}</TableData>
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.packages.edit', webPackage.id)"
|
||||
class="text-primary font-medium">
|
||||
{{ __('Edit') }}
|
||||
</inertia-link>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import Tabs from './Tabs';
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Packages')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Pagination,
|
||||
Tabs,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
},
|
||||
|
||||
props: {
|
||||
packages: Array
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
items: [
|
||||
{
|
||||
title: 'Overview',
|
||||
to: this.route('admin.users.index'),
|
||||
},
|
||||
{
|
||||
title: 'Create',
|
||||
to: this.route('admin.users.create'),
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,32 +0,0 @@
|
||||
<template>
|
||||
<ul class="-ml-4 space-y-1">
|
||||
<li v-for="item in items">
|
||||
<inertia-link
|
||||
class="flex items-center h-10 px-4 font-medium text-medium-emphasis"
|
||||
:class="{'rounded shadow text-primary bg-surface-3': item.active}"
|
||||
:href="item.to"
|
||||
>{{ item.title }} {{ item.route }}</inertia-link
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
items: [
|
||||
{
|
||||
title: this.__('Overview'),
|
||||
to: this.route('admin.packages.index'),
|
||||
active: this.route().current('admin.packages.index')
|
||||
},
|
||||
{
|
||||
title: this.__('Create'),
|
||||
to: this.route('admin.packages.create'),
|
||||
active: this.route().current('admin.packages.create')
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,174 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Servers') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout main-col-span="col-span-4">
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Servers') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4 pb-5 mb-5 border-b border-low-emphasis">
|
||||
<FormInput :label="__('Search')" :placeholder="__('Search on server name, or the name/email of the owner of the server')" v-model="form.search" />
|
||||
</form>
|
||||
</template>
|
||||
<template #content>
|
||||
<div>
|
||||
<Table caption="Server list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>{{ __('IP') }}</TableHeader>
|
||||
<TableHeader>{{ __('Users') }}</TableHeader>
|
||||
<TableHeader>{{ __('Max sites') }}</TableHeader>
|
||||
<TableHeader>{{ __('Date') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="server in servers.data" :key="server.id">
|
||||
<TableData>
|
||||
<div>{{ server.name }}</div>
|
||||
</TableData>
|
||||
<TableData>
|
||||
{{ server.ip }}
|
||||
</TableData>
|
||||
<TableData class="space-x-2">
|
||||
<span v-if="!server.users || !server.users.length">-</span>
|
||||
<inertia-link v-else class="text-primary" :href="route('admin.users.show', user.id)" :key="user.id" v-for="user in server.users">{{ user.name }}</inertia-link>
|
||||
</TableData>
|
||||
<TableData>
|
||||
{{ server.maximum_sites }} ({{ __('Current') }}: {{ server.sites_count}})
|
||||
</TableData>
|
||||
<TableData>
|
||||
{{ server.created_at }}
|
||||
</TableData>
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.services.servers.edit', server.id)" class="text-primary font-medium">
|
||||
{{ __('Edit') }}
|
||||
</inertia-link>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<pagination :links="servers"/>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import {useNotification} from '@/hooks/notification'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
import IconPhp from '@/components/icons/IconPhp'
|
||||
import throttle from "lodash/throttle";
|
||||
import pickBy from "lodash/pickBy";
|
||||
|
||||
export default {
|
||||
layout: MainLayout,
|
||||
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Servers')}`,
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Pagination,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
IconPhp,
|
||||
FormInput,
|
||||
},
|
||||
|
||||
props: {
|
||||
servers: Object,
|
||||
filters: Object,
|
||||
},
|
||||
|
||||
mounted() {
|
||||
},
|
||||
|
||||
methods: {
|
||||
useNotification,
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
form: {
|
||||
search: this.filters.search,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
form: {
|
||||
handler: throttle(function() {
|
||||
let query = pickBy(this.form)
|
||||
this.$inertia.get(this.route('admin.servers.index', Object.keys(query).length ? query : { remember: 'forget' }), {},{
|
||||
preserveScroll: true,
|
||||
preserveState: true,
|
||||
})
|
||||
}, 500),
|
||||
deep: true
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
@@ -1,211 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Services') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Servers') }}</template>
|
||||
<template #content>
|
||||
<div>
|
||||
<Table caption="Server list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>{{ __('Usage') }}</TableHeader>
|
||||
<TableHeader>{{ __('Users') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="server in servers.data" :key="server.id">
|
||||
<TableData>
|
||||
{{ server.name }}
|
||||
|
||||
<p class="text-medium-emphasis">{{ server.ip }}</p>
|
||||
|
||||
<Button class="text-small text-primary" is="a" size="sm" target="_blank" :href="`https://ploi.io/panel/servers/${server.ploi_id}`">
|
||||
{{ __('View in ploi.io') }}
|
||||
</Button>
|
||||
</TableData>
|
||||
<TableData>{{ server.sites_count }}/{{ server.maximum_sites }}</TableData>
|
||||
<TableData>{{ server.users_count }}</TableData>
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.services.servers.edit', server.id)" class="text-primary font-medium">
|
||||
{{ __('Edit') }}
|
||||
</inertia-link>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<pagination :links="servers"/>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Sites') }}</template>
|
||||
<template #content>
|
||||
<div>
|
||||
<Table caption="Site list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>{{ __('Server') }}</TableHeader>
|
||||
<TableHeader>{{ __('Users') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="site in sites.data" :key="site.id">
|
||||
<TableData>
|
||||
{{ site.domain }}
|
||||
</TableData>
|
||||
<TableData>
|
||||
{{ site.server ? site.server.name : '-' }}
|
||||
</TableData>
|
||||
<TableData>
|
||||
{{ site.users_count }}
|
||||
</TableData>
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.services.sites.edit', site.id)" class="text-primary font-medium">
|
||||
{{ __('Edit') }}
|
||||
</inertia-link>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<pagination :links="sites"/>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Providers') }}</template>
|
||||
<template #content>
|
||||
<div>
|
||||
<Table caption="Provider list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>{{ __('Regions') }}</TableHeader>
|
||||
<TableHeader>{{ __('Plans') }}</TableHeader>
|
||||
<TableHeader>{{ __('Attached servers') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="provider in providers.data" :key="provider.id">
|
||||
<TableData>{{ provider.name }}</TableData>
|
||||
<TableData>{{ provider.regions_count }}</TableData>
|
||||
<TableData>{{ provider.plans_count }}</TableData>
|
||||
<TableData>{{ provider.servers_count }}</TableData>
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.services.providers.edit', provider.id)" class="text-primary font-medium">
|
||||
{{ __('Edit') }}
|
||||
</inertia-link>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<pagination :links="providers"/>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import {useNotification} from '@/hooks/notification'
|
||||
import Tabs from './Tabs';
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
|
||||
export default {
|
||||
layout: MainLayout,
|
||||
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Services')}`,
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Pagination,
|
||||
Tabs,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
},
|
||||
|
||||
props: {
|
||||
servers: Object,
|
||||
sites: Object,
|
||||
providers: Object,
|
||||
},
|
||||
|
||||
mounted() {
|
||||
},
|
||||
|
||||
methods: {
|
||||
useNotification,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,186 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Edit provider') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Edit') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormInput :label="__('Name')" :errors="$page.props.errors.name" v-model="form.name" />
|
||||
|
||||
<div class="space-y-4">
|
||||
<h3 class="text-base leading-6 font-medium border-b border-dotted border-medium-emphasis pb-1">
|
||||
{{ __('Allowed plans') }}</h3>
|
||||
|
||||
<p class="text-medium-emphasis">
|
||||
Select the plans here that your users are allowed to use for this provider.
|
||||
If there are no plans selected, all will be available.
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<div class="space-y-1" v-for="(name, id) in availablePlans">
|
||||
<input :id="`plan-${id}`" :value="id" v-model="form.allowed_plans"
|
||||
class="form-checkbox" type="checkbox">
|
||||
<label :for="`plan-${id}`" class="ml-2 text-sm">{{ name }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-4">
|
||||
<h3 class="text-base leading-6 font-medium border-b border-dotted border-medium-emphasis pb-1">
|
||||
{{ __('Allowed regions') }}</h3>
|
||||
|
||||
<p class="text-medium-emphasis">
|
||||
Select the regions here that your users are allowed to use for this provider.
|
||||
If there are no regions selected, all will be available.
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<div class="space-y-1" v-for="(name, id) in availableRegions">
|
||||
<input :id="`region-${id}`" :value="id" v-model="form.allowed_regions"
|
||||
class="form-checkbox" type="checkbox">
|
||||
<label :for="`region-${id}`" class="ml-2 text-sm">{{ name }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
<Button variant="danger" type="button" @click="confirmDelete">{{ __('Delete') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormTextarea from '@/components/forms/FormTextarea'
|
||||
import FormSelect from '@/components/forms/FormSelect'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import {useConfirm} from '@/hooks/confirm'
|
||||
import Tabs from '../Tabs'
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
|
||||
export default {
|
||||
layout: MainLayout,
|
||||
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Edit provider')}`,
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormSelect,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
FormTextarea,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
name: this.provider.name,
|
||||
allowed_plans: this.provider.allowed_plans ?? [],
|
||||
allowed_regions: this.provider.allowed_regions ?? [],
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
provider: Object,
|
||||
availableRegions: [Object, Array],
|
||||
availablePlans: [Object, Array]
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.$inertia.patch(this.route('admin.services.providers.update', this.provider.id), this.form, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false
|
||||
});
|
||||
},
|
||||
|
||||
confirmDelete() {
|
||||
useConfirm({
|
||||
title: this.__('Are you sure?'),
|
||||
message: this.__('Are you sure you want to delete this provider?'),
|
||||
onConfirm: () => this.delete(),
|
||||
})
|
||||
},
|
||||
|
||||
delete() {
|
||||
this.$inertia.delete(this.route('admin.services.providers.delete', this.provider.id), {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,142 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Synchronize providers') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Overview') }}</template>
|
||||
<template #subtitle>{{ __('You can synchronize your server providers here. After that, you\'ll be able to set a default provider per package. So servers created by a user via a package will always be put on that selected provider.') }}</template>
|
||||
<template #content>
|
||||
<Table caption="Available providers overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>{{ __('Label') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="availableProvider in availableProviders" :key="availableProvider.id">
|
||||
<TableData class="space-y-2">
|
||||
<div>
|
||||
{{ availableProvider.name }}
|
||||
</div>
|
||||
|
||||
<div class="space-x-1 text-xs">
|
||||
<span class="text-medium-emphasis">{{ availableProvider.provider.plans.length }} plan(s)</span>
|
||||
<span>·</span>
|
||||
<span class="text-medium-emphasis">{{ availableProvider.provider.regions.length }} region(s)</span>
|
||||
</div>
|
||||
</TableData>
|
||||
<TableData>{{ availableProvider.label }}</TableData>
|
||||
<TableData class="text-right">
|
||||
<Button size="sm" v-on:click="syncProvider(availableProvider)">
|
||||
{{ __('Synchronize') }}
|
||||
</Button>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import {useNotification} from '@/hooks/notification'
|
||||
import Tabs from './Tabs';
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
|
||||
export default {
|
||||
layout: MainLayout,
|
||||
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Synchronize providers')}`,
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Pagination,
|
||||
Tabs,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
},
|
||||
|
||||
props: {
|
||||
availableProviders: Array,
|
||||
},
|
||||
|
||||
methods: {
|
||||
useNotification,
|
||||
|
||||
syncProvider (provider){
|
||||
window.axios.post(this.route('admin.services.providers.sync', provider.id))
|
||||
.then(() => {
|
||||
useNotification({
|
||||
variant: 'success',
|
||||
title: `Providers`,
|
||||
message: `Provider has been synchronized to this system`
|
||||
})
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,220 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Edit server') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Edit') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormInput :label="__('Name')" :errors="$page.props.errors.name"
|
||||
v-model="form.name"/>
|
||||
<FormInput :label="__('IP address')" :errors="$page.props.errors.ip"
|
||||
v-model="form.ip"/>
|
||||
<FormInput :label="__('Maximum sites')"
|
||||
:errors="$page.props.errors.maximum_sites"
|
||||
v-model="form.maximum_sites"/>
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
<Button variant="danger" type="button" @click="confirmDelete">
|
||||
{{ __('Delete') }}
|
||||
</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Attached users') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="attach">
|
||||
<FormInput :label="__('Email')" :errors="$page.props.errors.email"
|
||||
v-model="formAttach.email"/>
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
<template #content>
|
||||
<div>
|
||||
<Table caption="Attached users list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>{{ __('Email') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="user in users" :key="user.id">
|
||||
<TableData>{{ user.name }}</TableData>
|
||||
<TableData>{{ user.email }}</TableData>
|
||||
<TableData>
|
||||
<Button variant="danger" size="sm"
|
||||
@click="confirmDetach(user.id)">
|
||||
{{ __('Detach') }}
|
||||
</Button>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormTextarea from '@/components/forms/FormTextarea'
|
||||
import FormSelect from '@/components/forms/FormSelect'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import {useConfirm} from '@/hooks/confirm'
|
||||
import Tabs from '../Tabs'
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
|
||||
export default {
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormSelect,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
FormTextarea,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
name: this.server.name,
|
||||
ip: this.server.ip,
|
||||
maximum_sites: this.server.maximum_sites,
|
||||
},
|
||||
|
||||
formAttach: {
|
||||
email: null
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
server: Object,
|
||||
users: [Object, Array]
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.$inertia.patch(this.route('admin.services.servers.update', this.server.id), this.form, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false
|
||||
})
|
||||
},
|
||||
|
||||
confirmDelete() {
|
||||
useConfirm({
|
||||
title: this.__('Are you sure?'),
|
||||
message: this.__('Are you sure you want to delete this server? Everything associated with this server will be detached.'),
|
||||
onConfirm: () => this.delete(),
|
||||
})
|
||||
},
|
||||
|
||||
delete() {
|
||||
this.$inertia.delete(this.route('admin.services.servers.delete', this.server.id), {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false
|
||||
})
|
||||
},
|
||||
|
||||
attach() {
|
||||
this.$inertia.post(this.route('admin.services.servers.attach', this.server.id), this.formAttach, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => {
|
||||
this.sending = false
|
||||
|
||||
if (!Object.keys(this.$page.props.errors).length) {
|
||||
this.formAttach.email = null;
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
confirmDetach(userId) {
|
||||
useConfirm({
|
||||
title: this.__('Are you sure?'),
|
||||
message: this.__('Are you sure you want to detach this user from this server?'),
|
||||
onConfirm: () => this.detach(userId),
|
||||
})
|
||||
},
|
||||
|
||||
detach(userId) {
|
||||
this.$inertia.delete(this.route('admin.services.servers.detach', [this.server.id, userId]), {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,171 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Synchronize servers') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Overview') }}</template>
|
||||
<template #subtitle>{{
|
||||
__('You can synchronize your servers here. It is safe to synchronize already existing servers. If you have installed a extra PHP version for example, you can synchronize to update the versions here.')
|
||||
}}
|
||||
</template>
|
||||
<template #content>
|
||||
<Button size="sm" :disabled="loading" v-on:click="syncAll">
|
||||
{{ __('Synchronize all servers') }}
|
||||
</Button>
|
||||
|
||||
<Table caption="Available servers overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>{{ __('IP address') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="availableServer in availableServers"
|
||||
:key="availableServer.id">
|
||||
<TableData>{{ availableServer.name }}</TableData>
|
||||
<TableData>{{ availableServer.ip_address }}</TableData>
|
||||
<TableData class="flex justify-end">
|
||||
<Button :disabled="loading" size="sm"
|
||||
v-on:click="syncServer(availableServer)">
|
||||
{{ __('Synchronize') }}
|
||||
</Button>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import {useNotification} from '@/hooks/notification'
|
||||
import Tabs from './Tabs';
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
|
||||
export default {
|
||||
layout: MainLayout,
|
||||
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Synchronize servers')}`,
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Pagination,
|
||||
Tabs,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
},
|
||||
|
||||
props: {
|
||||
availableServers: Array,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
useNotification,
|
||||
|
||||
syncServer(server) {
|
||||
this.loading = true;
|
||||
|
||||
window.axios.post(this.route('admin.services.servers.sync'), server)
|
||||
.then(() => {
|
||||
this.loading = false;
|
||||
useNotification({
|
||||
variant: 'success',
|
||||
title: `Servers`,
|
||||
message: `Server ${server.name} has been synchronized to this system`
|
||||
})
|
||||
})
|
||||
.catch(error => {
|
||||
this.loading = false;
|
||||
})
|
||||
},
|
||||
|
||||
syncAll() {
|
||||
this.loading = true;
|
||||
|
||||
window.axios.post(this.route('admin.services.servers.sync.all'))
|
||||
.then(() => {
|
||||
this.loading = false;
|
||||
|
||||
useNotification({
|
||||
variant: 'success',
|
||||
title: `Servers`,
|
||||
message: `All servers have been synchronized to this system`
|
||||
})
|
||||
})
|
||||
.catch(error => {
|
||||
this.loading = false;
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,219 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Edit site') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Edit') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormInput :label="__('Domain')" :errors="$page.props.errors.domain" v-model="form.domain" />
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
<Button variant="danger" type="button" @click="confirmDelete">{{ __('Delete') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Attached users') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="attach">
|
||||
<FormInput :label="__('Email')" :errors="$page.props.errors.email" v-model="formAttach.email"/>
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
<template #content>
|
||||
<div>
|
||||
<Table caption="Attached users list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>{{ __('Email') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="user in users" :key="user.id">
|
||||
<TableData>{{ user.name }}</TableData>
|
||||
<TableData>{{ user.email }}</TableData>
|
||||
<TableData>
|
||||
<Button variant="danger" size="sm"
|
||||
@click="confirmDetach(user.id)">
|
||||
{{ __('Detach') }}
|
||||
</Button>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormTextarea from '@/components/forms/FormTextarea'
|
||||
import FormSelect from '@/components/forms/FormSelect'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import {useConfirm} from '@/hooks/confirm'
|
||||
import Tabs from '../Tabs'
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
|
||||
export default {
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormSelect,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
FormTextarea,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
domain: this.site.domain
|
||||
},
|
||||
|
||||
formAttach: {
|
||||
email: null
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
site: Object,
|
||||
users: [Object, Array]
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.sending = true
|
||||
|
||||
this.$inertia.patch(this.route('admin.services.sites.update', this.site.id), this.form, {
|
||||
onFinish: () => {
|
||||
this.sending = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
confirmDelete() {
|
||||
useConfirm({
|
||||
title: this.__('Are you sure?'),
|
||||
message: this.__('Are you sure you want to delete this site? Everything associated with this site will be detached.'),
|
||||
onConfirm: () => this.delete(),
|
||||
})
|
||||
},
|
||||
|
||||
delete() {
|
||||
this.sending = true
|
||||
|
||||
this.$inertia.delete(this.route('admin.services.sites.delete', this.site.id), {
|
||||
onFinish: () => {
|
||||
this.sending = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
attach() {
|
||||
this.sending = true
|
||||
|
||||
this.$inertia.post(this.route('admin.services.sites.attach', this.site.id), this.formAttach, {
|
||||
onFinish: () => {
|
||||
this.sending = false
|
||||
|
||||
if (!Object.keys(this.$page.props.errors).length) {
|
||||
this.formAttach.email = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
confirmDetach(userId) {
|
||||
useConfirm({
|
||||
title: this.__('Are you sure?'),
|
||||
message: this.__('Are you sure you want to detach this user from this site?'),
|
||||
onConfirm: () => this.detach(userId),
|
||||
})
|
||||
},
|
||||
|
||||
detach(userId) {
|
||||
this.sending = true
|
||||
|
||||
this.$inertia.delete(this.route('admin.services.sites.detach', [this.site.id, userId]), {
|
||||
onFinish: () => {
|
||||
this.sending = false;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,159 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>Synchronize sites</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Overview') }}</template>
|
||||
<template #subtitle>{{ __('You can synchronize your sites here. It is safe to synchronize already existing sites.') }}</template>
|
||||
<template #content>
|
||||
<Button size="sm" :disabled="loading" v-on:click="syncAll">
|
||||
{{ __('Synchronize all sites') }}
|
||||
</Button>
|
||||
|
||||
<Table caption="Available sites overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Domain') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="availableSite in availableSites" :key="availableSite.id">
|
||||
<TableData>{{ availableSite.domain }}</TableData>
|
||||
<TableData class="flex justify-end">
|
||||
<Button :disabled="loading" size="sm" v-on:click="syncSite(availableSite)">
|
||||
{{ __('Synchronize') }}
|
||||
</Button>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import {useNotification} from '@/hooks/notification'
|
||||
import Tabs from './Tabs';
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
|
||||
export default {
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Pagination,
|
||||
Tabs,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
},
|
||||
|
||||
props: {
|
||||
availableSites: Array,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
useNotification,
|
||||
|
||||
syncSite (site){
|
||||
this.loading = true;
|
||||
|
||||
window.axios.post(this.route('admin.services.sites.sync'), site)
|
||||
.then(() => {
|
||||
this.loading = false;
|
||||
|
||||
useNotification({
|
||||
variant: 'success',
|
||||
title: `Sites`,
|
||||
message: `Site ${site.domain} has been synchronized to this system`
|
||||
})
|
||||
})
|
||||
.catch(error => {
|
||||
this.loading = false;
|
||||
})
|
||||
},
|
||||
|
||||
syncAll() {
|
||||
this.loading = true;
|
||||
|
||||
window.axios.post(this.route('admin.services.sites.sync.all'))
|
||||
.then(() => {
|
||||
this.loading = false;
|
||||
|
||||
useNotification({
|
||||
variant: 'success',
|
||||
title: `Sites`,
|
||||
message: `All sites have been synchronized to this system`
|
||||
})
|
||||
})
|
||||
.catch(error => {
|
||||
this.loading = false;
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,42 +0,0 @@
|
||||
<template>
|
||||
<ul class="-ml-4 space-y-1">
|
||||
<li v-for="item in items">
|
||||
<inertia-link
|
||||
class="flex items-center h-10 px-4 font-medium text-medium-emphasis"
|
||||
:class="{'rounded shadow text-primary bg-surface-3': item.active}"
|
||||
:href="item.to"
|
||||
>{{ item.title }} {{ item.route }}</inertia-link
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
items: [
|
||||
{
|
||||
title: this.__('Overview'),
|
||||
to: this.route('admin.services.index'),
|
||||
active: this.route().current('admin.services.index')
|
||||
},
|
||||
{
|
||||
title: this.__('Synchronize servers'),
|
||||
to: this.route('admin.services.servers.index'),
|
||||
active: this.route().current('admin.services.servers.index')
|
||||
},
|
||||
{
|
||||
title: this.__('Synchronize sites'),
|
||||
to: this.route('admin.services.sites.index'),
|
||||
active: this.route().current('admin.services.sites.index')
|
||||
},
|
||||
{
|
||||
title: this.__('Synchronize providers'),
|
||||
to: this.route('admin.services.providers.index'),
|
||||
active: this.route().current('admin.services.providers.index')
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,345 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Settings') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Overview') }}</template>
|
||||
<template #subtitle>
|
||||
{{
|
||||
__('Change all the system settings here. All changes are in effect immediately.')
|
||||
}}
|
||||
</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormInput :label="__('Company name')" :errors="$page.props.errors.name"
|
||||
v-model="form.name"/>
|
||||
|
||||
<FormInput :label="__('E-mail address')" :errors="$page.props.errors.email"
|
||||
v-model="form.email"/>
|
||||
|
||||
<FormFileInput accept="image/*" :label="__('Logo')" type="file"
|
||||
:errors="$page.props.errors.logo"
|
||||
v-model="form.logo"/>
|
||||
|
||||
<Button v-if="company_settings.has_logo" variant="danger" type="button"
|
||||
class="ml-2 px-4 py-1 bg-red-500 hover:bg-red-700 rounded-sm text-xs font-medium text-white"
|
||||
@click="removeLogo">
|
||||
Remove logo
|
||||
</Button>
|
||||
|
||||
<FormInput :helper-text="__('Separate by comma to allow more email addresses')"
|
||||
:label="__('Support email addresses')"
|
||||
:errors="$page.props.errors.support_emails"
|
||||
v-model="form.support_emails"/>
|
||||
|
||||
<FormSelect
|
||||
:helper-text="__('Select the default package a user should get when you create or they register')"
|
||||
:label="__('Select default package')" v-model="form.default_package">
|
||||
<option v-for="(name, id) in packages" :value="id" v-text="name"></option>
|
||||
</FormSelect>
|
||||
|
||||
<FormSelect
|
||||
:helper-text="__('Select the default package a user should get when you create or they register')"
|
||||
:label="__('Select default language')" v-model="form.default_language">
|
||||
<option v-for="language in languages" :value="language"
|
||||
v-text="language"></option>
|
||||
</FormSelect>
|
||||
|
||||
<FormSelect
|
||||
:helper-text="__('This will rotate any logs older than selected, this helps cleanup your database')"
|
||||
:label="__('Rotate logs after')" v-model="form.rotate_logs_after">
|
||||
<option value="">Don't rotate logs</option>
|
||||
<option value="weeks-1">Older than 1 week</option>
|
||||
<option value="months-1">Older than 1 month</option>
|
||||
<option value="months-3">Older than 3 months</option>
|
||||
<option value="months-6">Older than 6 months</option>
|
||||
<option value="years-1">Older than 1 year</option>
|
||||
<option value="years-2">Older than 2 years</option>
|
||||
<option value="years-3">Older than 3 years</option>
|
||||
<option value="years-4">Older than 4 years</option>
|
||||
</FormSelect>
|
||||
|
||||
<div>
|
||||
<input id="trial" class="form-checkbox" type="checkbox"
|
||||
v-model="form.trialEnabled">
|
||||
<label for="trial" class="ml-2 text-sm">{{
|
||||
__('Enable trial')
|
||||
}}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow you to have users with trials.') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<FormInput v-if="form.trialEnabled" type="number" :label="__('Trial days')"
|
||||
:errors="$page.props.errors.trial"
|
||||
v-model="form.trial"/>
|
||||
|
||||
<FormSelect
|
||||
v-if="form.trialEnabled"
|
||||
:errors="$page.props.errors.trial_package"
|
||||
:helper-text="__('Select the trial package a user should get when they get their trial')"
|
||||
:label="__('Select trial package')" v-model="form.trial_package">
|
||||
<option v-for="(name, id) in packages" :value="id" v-text="name"></option>
|
||||
</FormSelect>
|
||||
|
||||
<div>
|
||||
<input id="support" class="form-checkbox" type="checkbox"
|
||||
v-model="form.support">
|
||||
<label for="support" class="ml-2 text-sm">{{
|
||||
__('Enable support platform')
|
||||
}}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{
|
||||
__('This will allow your customers to make support requests to you.')
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input id="documentation" class="form-checkbox" type="checkbox"
|
||||
v-model="form.documentation">
|
||||
<label for="documentation" class="ml-2 text-sm">{{
|
||||
__('Enable documentation platform')
|
||||
}}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{
|
||||
__('This will allow you to create articles for your users to look at.')
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input id="allow_registration" class="form-checkbox" type="checkbox"
|
||||
v-model="form.allow_registration">
|
||||
<label for="allow_registration"
|
||||
class="ml-2 text-sm">{{ __('Allow customer registration') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('This will allow public users to register on your platform.') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input id="receive_email_on_server_creation" class="form-checkbox"
|
||||
type="checkbox"
|
||||
v-model="form.receive_email_on_server_creation">
|
||||
<label for="receive_email_on_server_creation" class="ml-2 text-sm">{{
|
||||
__('Receive email when customers create server')
|
||||
}}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{
|
||||
__('This will send an email to all admins notifying them about a new server installation.')
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input id="receive_email_on_site_creation" class="form-checkbox"
|
||||
type="checkbox"
|
||||
v-model="form.receive_email_on_site_creation">
|
||||
<label for="receive_email_on_site_creation" class="ml-2 text-sm">{{
|
||||
__('Receive email when customers create site')
|
||||
}}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{
|
||||
__('This will send an email to all admins notifying them about a new site installation.')
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input id="enable_api" class="form-checkbox" type="checkbox"
|
||||
v-model="form.enable_api">
|
||||
<label for="enable_api" class="ml-2 text-sm">{{ __('Enable API') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{
|
||||
__('This will allow you to interact with your system via the API.')
|
||||
}} <a href="https://docs.ploi-core.io/core-api/introduction"
|
||||
class="text-primary"
|
||||
target="_blank">{{ __('More information') }}</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<FormInput v-if="form.enable_api" allow-random-string :label="__('API token')"
|
||||
:errors="$page.props.errors.api_token"
|
||||
v-model="form.api_token"/>
|
||||
|
||||
<div>
|
||||
<input id="isolate_per_site_per_user" class="form-checkbox" type="checkbox"
|
||||
v-model="form.isolate_per_site_per_user">
|
||||
<label for="isolate_per_site_per_user" class="ml-2 text-sm">{{
|
||||
__('Enable site isolation per site & user')
|
||||
}}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{
|
||||
__('This will make sure each site created by one user is always isolated from another.')
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from './components/TopBar.vue'
|
||||
import Container from '@/components/Container.vue'
|
||||
import Content from '@/components/Content.vue'
|
||||
import Page from '@/components/Page.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle.vue'
|
||||
import PageBody from '@/components/PageBody.vue'
|
||||
import Button from '@/components/Button.vue'
|
||||
import List from '@/components/List.vue'
|
||||
import ListItem from '@/components/ListItem.vue'
|
||||
import StatusBubble from '@/components/StatusBubble.vue'
|
||||
import NotificationBadge from '@/components/NotificationBadge.vue'
|
||||
import MainLayout from '@/Layouts/MainLayout.vue'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout.vue'
|
||||
import SettingsSegment from '@/components/SettingsSegment.vue'
|
||||
import FormInput from '@/components/forms/FormInput.vue'
|
||||
import FormFileInput from '@/components/forms/FormFileInput.vue'
|
||||
import FormSelect from '@/components/forms/FormSelect.vue'
|
||||
import Form from '@/components/Form.vue'
|
||||
import FormActions from '@/components/FormActions.vue'
|
||||
import {useNotification} from '@/hooks/notification'
|
||||
import Tabs from './Tabs.vue'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Settings')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormFileInput,
|
||||
FormSelect,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
name: this.company_settings.name,
|
||||
email: this.company_settings.email,
|
||||
support_emails: this.company_settings.support_emails,
|
||||
support: this.company_settings.support,
|
||||
enable_api: this.company_settings.enable_api,
|
||||
api_token: this.company_settings.api_token,
|
||||
documentation: this.company_settings.documentation,
|
||||
allow_registration: this.company_settings.allow_registration,
|
||||
receive_email_on_server_creation: this.company_settings.receive_email_on_server_creation,
|
||||
receive_email_on_site_creation: this.company_settings.receive_email_on_site_creation,
|
||||
default_package: this.company_settings.default_package,
|
||||
isolate_per_site_per_user: this.company_settings.isolate_per_site_per_user,
|
||||
default_language: this.company_settings.default_language,
|
||||
logo: null,
|
||||
rotate_logs_after: this.company_settings.rotate_logs_after,
|
||||
trialEnabled: false,
|
||||
trial: this.company_settings.trial,
|
||||
trial_package: this.company_settings.trial_package,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.form.trialEnabled = !!this.company_settings.trial;
|
||||
},
|
||||
|
||||
props: {
|
||||
company_settings: Object,
|
||||
packages: {},
|
||||
languages: {}
|
||||
},
|
||||
|
||||
methods: {
|
||||
useNotification,
|
||||
|
||||
submit() {
|
||||
var data = new FormData();
|
||||
data.append('name', this.form.name || '')
|
||||
data.append('email', this.form.email || '')
|
||||
data.append('support_emails', this.form.support_emails || '')
|
||||
data.append('support', this.form.support || false)
|
||||
data.append('enable_api', this.form.enable_api || false)
|
||||
data.append('api_token', this.form.api_token || '')
|
||||
data.append('documentation', this.form.documentation || false)
|
||||
data.append('allow_registration', this.form.allow_registration || false)
|
||||
data.append('receive_email_on_server_creation', this.form.receive_email_on_server_creation || false)
|
||||
data.append('receive_email_on_site_creation', this.form.receive_email_on_site_creation || false)
|
||||
data.append('default_package', this.form.default_package || '')
|
||||
data.append('isolate_per_site_per_user', this.form.isolate_per_site_per_user || false)
|
||||
data.append('default_language', this.form.default_language || 'en')
|
||||
data.append('logo', this.form.logo || '')
|
||||
data.append('rotate_logs_after', this.form.rotate_logs_after || '')
|
||||
data.append('trial', this.form.trial || '')
|
||||
data.append('trial_package', this.form.trial_package || '')
|
||||
data.append('_method', 'patch')
|
||||
|
||||
this.$inertia.post(this.route('admin.settings.update'), data, {
|
||||
preserveScroll: true,
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false,
|
||||
onSuccess: () => {
|
||||
if (Object.keys(this.$page.props.errors).length === 0) {
|
||||
this.form.logo = null
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
removeLogo() {
|
||||
this.$inertia.delete(this.route('admin.settings.remove-logo'), {
|
||||
preserveScroll: true,
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,180 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Sites') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout main-col-span="col-span-4">
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Sites') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4 pb-5 mb-5 border-b border-low-emphasis">
|
||||
<FormInput :label="__('Search')" :placeholder="__('Search on site domain, or the name/email of the owner of the site')" v-model="form.search" />
|
||||
</form>
|
||||
</template>
|
||||
<template #content>
|
||||
<div>
|
||||
<Table caption="Site list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>{{ __('Server') }}</TableHeader>
|
||||
<TableHeader>{{ __('Users') }}</TableHeader>
|
||||
<TableHeader>{{ __('Date') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="site in sites.data" :key="site.id">
|
||||
<TableData>
|
||||
<div>{{ site.domain }}</div>
|
||||
|
||||
<div class="flex items-center space-x-2 text-sm text-medium-emphasis">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span><icon-php /> </span>
|
||||
<span>{{ site.php_version }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="site.project === 'wordpress'">·</div>
|
||||
<div v-if="site.project === 'wordpress'">{{ __('WordPress installed') }}</div>
|
||||
</div>
|
||||
|
||||
</TableData>
|
||||
<TableData>
|
||||
{{ site.server ? site.server.name : '-' }}
|
||||
</TableData>
|
||||
<TableData class="space-x-2">
|
||||
<span v-if="!site.users || !site.users.length">-</span>
|
||||
<inertia-link v-else class="text-primary" :href="route('admin.users.show', user.id)" :key="user.id" v-for="user in site.users">{{ user.name }}</inertia-link>
|
||||
</TableData>
|
||||
<TableData>
|
||||
{{ site.created_at }}
|
||||
</TableData>
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.services.sites.edit', site.id)" class="text-primary font-medium">
|
||||
{{ __('Edit') }}
|
||||
</inertia-link>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<pagination :links="sites"/>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import {useNotification} from '@/hooks/notification'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
import IconPhp from '@/components/icons/IconPhp'
|
||||
import throttle from "lodash/throttle";
|
||||
import pickBy from "lodash/pickBy";
|
||||
|
||||
export default {
|
||||
layout: MainLayout,
|
||||
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Sites')}`,
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Pagination,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
IconPhp,
|
||||
FormInput
|
||||
},
|
||||
|
||||
props: {
|
||||
sites: Object,
|
||||
filters: Object,
|
||||
},
|
||||
|
||||
mounted() {
|
||||
},
|
||||
|
||||
methods: {
|
||||
useNotification,
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
form: {
|
||||
search: this.filters.search,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
form: {
|
||||
handler: throttle(function() {
|
||||
let query = pickBy(this.form)
|
||||
this.$inertia.get(this.route('admin.sites.index', Object.keys(query).length ? query : { remember: 'forget' }), {},{
|
||||
preserveScroll: true,
|
||||
preserveState: true,
|
||||
})
|
||||
}, 500),
|
||||
deep: true
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,87 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Status') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from './components/TopBar.vue'
|
||||
import Container from '@/components/Container.vue'
|
||||
import Content from '@/components/Content.vue'
|
||||
import Page from '@/components/Page.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle.vue'
|
||||
import PageBody from '@/components/PageBody.vue'
|
||||
import Button from '@/components/Button.vue'
|
||||
import List from '@/components/List.vue'
|
||||
import ListItem from '@/components/ListItem.vue'
|
||||
import StatusBubble from '@/components/StatusBubble.vue'
|
||||
import NotificationBadge from '@/components/NotificationBadge.vue'
|
||||
import MainLayout from '@/Layouts/MainLayout.vue'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout.vue'
|
||||
import SettingsSegment from '@/components/SettingsSegment.vue'
|
||||
import FormInput from '@/components/forms/FormInput.vue'
|
||||
import Form from '@/components/Form.vue'
|
||||
import FormActions from '@/components/FormActions.vue'
|
||||
import {useNotification} from '@/hooks/notification'
|
||||
import Tabs from './TabsStatus.vue'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Status')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs
|
||||
},
|
||||
|
||||
props: {
|
||||
},
|
||||
|
||||
methods: {
|
||||
useNotification,
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,119 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Support') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Overview') }}</template>
|
||||
<template #content>
|
||||
<Table caption="Support list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>{{ __('Replies') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="ticket in tickets" :key="ticket.id">
|
||||
<TableData>{{ ticket.title }}</TableData>
|
||||
<TableData>{{ ticket.replies_count }}</TableData>
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.support.show', ticket.id)"
|
||||
class="text-primary font-medium">
|
||||
{{ __('View') }}
|
||||
</inertia-link>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import Tabs from './Tabs';
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Support')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Pagination,
|
||||
Tabs,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
},
|
||||
|
||||
props: {
|
||||
tickets: Array
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,150 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ ticket.title }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<div class="space-y-6">
|
||||
<ul class="space-y-6">
|
||||
<li class="p-6 rounded shadow bg-surface-3">
|
||||
<div class="flex space-x-4">
|
||||
<div>
|
||||
<img :src="ticket.user.avatar" class="w-8 h-8 rounded-avatar bg-surface-2" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-small text-body">{{ ticket.user.name }}</h3>
|
||||
<p class="text-medium-emphasis">{{ ticket.content }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="p-6 rounded shadow bg-surface-3" v-for="reply in replies">
|
||||
<div class="flex space-x-4">
|
||||
<div>
|
||||
<img :src="reply.user.avatar" class="w-8 h-8 rounded-avatar bg-surface-2" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-small text-body">{{ reply.user.name }}</h3>
|
||||
<p class="text-medium-emphasis">
|
||||
{{ reply.content }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<form class="space-y-4" @submit.prevent="reply">
|
||||
<FormTextarea :label="__('Reply')" :errors="$page.props.errors.reply" v-model="form.content"/>
|
||||
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
<Button type="button" @click="close" variant="secondary">{{ __('Close') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import IconBox from '@/components/icons/IconBox'
|
||||
import IconGlobe from '@/components/icons/IconGlobe'
|
||||
import IconStorage from '@/components/icons/IconStorage'
|
||||
import Modal from '@/components/Modal'
|
||||
import ModalContainer from '@/components/ModalContainer'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormTextarea from '@/components/forms/FormTextarea'
|
||||
import FormActions from '@/components/FormActions'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.ticket.title}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
IconBox,
|
||||
IconGlobe,
|
||||
IconStorage,
|
||||
Modal,
|
||||
ModalContainer,
|
||||
FormInput,
|
||||
FormTextarea,
|
||||
FormActions
|
||||
},
|
||||
|
||||
props: {
|
||||
ticket: Object,
|
||||
replies: Array,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
content: null
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
reply() {
|
||||
this.loading = true;
|
||||
|
||||
this.$inertia.post(this.route('admin.support.reply', this.ticket.id), this.form, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => {
|
||||
this.loading = false;
|
||||
|
||||
if (!Object.keys(this.$page.props.errors).length) {
|
||||
this.form.content = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
close() {
|
||||
this.$inertia.post(this.route('admin.support.close', this.ticket.id), {
|
||||
onStart: () => this.loading = true,
|
||||
onFinish: () => this.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,27 +0,0 @@
|
||||
<template>
|
||||
<ul class="-ml-4 space-y-1">
|
||||
<li v-for="item in items">
|
||||
<inertia-link
|
||||
class="flex items-center h-10 px-4 font-medium text-medium-emphasis"
|
||||
:class="{'rounded shadow text-primary bg-surface-3': item.active}"
|
||||
:href="item.to"
|
||||
>{{ item.title }} {{ item.route }}</inertia-link
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
items: [
|
||||
{
|
||||
title: this.__('Overview'),
|
||||
to: this.route('admin.support.index'),
|
||||
active: this.route().current('admin.support.index')
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,137 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('System') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Overview') }}</template>
|
||||
<template #subtitle>
|
||||
Check your system's version here. If there's an update available you'll be able to
|
||||
press the update button to update your system.
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
<p>{{ __('Current version') }}: {{ version.current }}</p>
|
||||
<p>
|
||||
{{ __('Remote version') }}: {{ version.remote }}
|
||||
<button class="text-primary" type="button" v-on:click="refreshVersions">{{ 'Refresh' }}</button>
|
||||
</p>
|
||||
<p>Horizon worker status: <span v-if="horizonRunning" class="text-success">Active</span><span v-else class="text-danger">Inactive</span></p>
|
||||
|
||||
<div v-if="version.out_of_date && !updating" class="bg-primary text-on-primary px-4 py-3 rounded relative space-y-2" role="alert">
|
||||
<strong class="font-bold">Update available</strong>
|
||||
<p class="block">
|
||||
An update is available for your system, please upgrade.
|
||||
</p>
|
||||
|
||||
<a class="block font-bold underline" href="https://docs.ploi-core.io/digging-deeper/manual-update" target="_blank">Find out how to upgrade here</a>
|
||||
</div>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Information') }}</template>
|
||||
|
||||
<template #content>
|
||||
<ul class="list-disc list-inside">
|
||||
<li><a target="_blank" class="text-primary" href="https://docs.ploi-core.io">Ploi Core Docs</a></li>
|
||||
<li><a target="_blank" class="text-primary" href="https://ploi.io">Ploi Website</a></li>
|
||||
<li><a target="_blank" class="text-primary" href="https://ploi.io/panel">Ploi Panel</a></li>
|
||||
<li><a target="_blank" class="text-primary" href="https://github.com/ploi-deploy/ploi-core">Ploi Core Github Repository</a></li>
|
||||
</ul>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from './components/TopBar.vue'
|
||||
import Container from '@/components/Container.vue'
|
||||
import Content from '@/components/Content.vue'
|
||||
import Page from '@/components/Page.vue'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle.vue'
|
||||
import PageBody from '@/components/PageBody.vue'
|
||||
import Button from '@/components/Button.vue'
|
||||
import List from '@/components/List.vue'
|
||||
import ListItem from '@/components/ListItem.vue'
|
||||
import StatusBubble from '@/components/StatusBubble.vue'
|
||||
import NotificationBadge from '@/components/NotificationBadge.vue'
|
||||
import MainLayout from '@/Layouts/MainLayout.vue'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout.vue'
|
||||
import SettingsSegment from '@/components/SettingsSegment.vue'
|
||||
import FormInput from '@/components/forms/FormInput.vue'
|
||||
import Form from '@/components/Form.vue'
|
||||
import FormActions from '@/components/FormActions.vue'
|
||||
import {useNotification} from '@/hooks/notification'
|
||||
import Tabs from './Tabs.vue'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('System')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs
|
||||
},
|
||||
|
||||
props: {
|
||||
version: Object,
|
||||
horizonRunning: Boolean
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
updating: false,
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
useNotification,
|
||||
|
||||
refreshVersions() {
|
||||
this.$inertia.get(this.route('admin.system') + '?flush=true');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,52 +0,0 @@
|
||||
<template>
|
||||
<ul class="-ml-4 space-y-1">
|
||||
<li v-for="item in items">
|
||||
<inertia-link
|
||||
class="flex items-center h-10 px-4 font-medium text-medium-emphasis"
|
||||
:class="{'rounded shadow text-primary bg-surface-3': item.active}"
|
||||
:href="item.to"
|
||||
>{{ item.title }} {{ item.route }}</inertia-link
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
items: [
|
||||
{
|
||||
title: this.__('Overview'),
|
||||
to: this.route('admin.dashboard'),
|
||||
active: this.route().current('admin.dashboard')
|
||||
},
|
||||
{
|
||||
title: this.__('Settings'),
|
||||
to: this.route('admin.settings'),
|
||||
active: this.route().current('admin.settings')
|
||||
},
|
||||
{
|
||||
title: this.__('System'),
|
||||
to: this.route('admin.system'),
|
||||
active: this.route().current('admin.system')
|
||||
},
|
||||
{
|
||||
title: this.__('Terms'),
|
||||
to: this.route('admin.settings.terms'),
|
||||
active: this.route().current('admin.settings.terms')
|
||||
},
|
||||
{
|
||||
title: this.__('Alert messages'),
|
||||
to: this.route('admin.alerts.index'),
|
||||
active: this.route().current('admin.alerts.*')
|
||||
},
|
||||
{
|
||||
title: this.__('Application logs'),
|
||||
to: this.route('admin.application-logs'),
|
||||
active: this.route().current('admin.application-logs')
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,27 +0,0 @@
|
||||
<template>
|
||||
<ul class="-ml-4 space-y-1">
|
||||
<li v-for="item in items">
|
||||
<inertia-link
|
||||
class="flex items-center h-10 px-4 font-medium text-medium-emphasis"
|
||||
:class="{'rounded shadow text-primary bg-surface-3': item.active}"
|
||||
:href="item.to"
|
||||
>{{ item.title }} {{ item.route }}</inertia-link
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
items: [
|
||||
{
|
||||
title: this.__('Overview'),
|
||||
to: this.route('admin.status.index'),
|
||||
active: this.route().current('admin.status.index')
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,179 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Terms') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Overview') }}</template>
|
||||
<template #subtitle>
|
||||
{{
|
||||
__('Enter content for your terms of service and privacy policy here. You may use markdown.')
|
||||
}}
|
||||
</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<div>
|
||||
<input id="terms_required" class="form-checkbox" type="checkbox"
|
||||
v-model="form.terms_required">
|
||||
<label for="terms_required" class="ml-2 text-sm">{{
|
||||
__('Require users to accept terms of service on registration')
|
||||
}}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{
|
||||
__('This will require newly registered users to accept the terms of service.')
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Button type="button" size="sm" @click="getTemplate('terms')">
|
||||
Load Terms of Service template
|
||||
</Button>
|
||||
<FormCustom label="Content Terms Of Service">
|
||||
<vue-simplemde v-model="form.terms" ref="terms_of_service"/>
|
||||
</FormCustom>
|
||||
<FormCustom label="Content Privacy Policy">
|
||||
<vue-simplemde v-model="form.privacy"/>
|
||||
</FormCustom>
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from './components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormFileInput from '@/components/forms/FormFileInput'
|
||||
import FormSelect from '@/components/forms/FormSelect'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import FormCustom from '@/components/forms/FormCustom'
|
||||
import {useNotification} from '@/hooks/notification'
|
||||
import Tabs from './Tabs'
|
||||
import VueSimplemde from 'vue-simplemde'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Terms')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormFileInput,
|
||||
FormSelect,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
VueSimplemde,
|
||||
FormCustom
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: this.$inertia.form({
|
||||
terms: this.terms_settings.terms,
|
||||
terms_required: this.terms_settings.terms_required,
|
||||
privacy: this.terms_settings.privacy,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
terms_settings: Object,
|
||||
},
|
||||
|
||||
methods: {
|
||||
useNotification,
|
||||
|
||||
submit() {
|
||||
this.form.patch(this.route('admin.settings.terms.update'));
|
||||
},
|
||||
|
||||
getTemplate(type) {
|
||||
window.axios.get(this.route('admin.settings.terms.template'))
|
||||
.then(response => {
|
||||
this.$refs.terms_of_service.simplemde.value(response.data.content);
|
||||
this.form.terms = response.data.content;
|
||||
|
||||
useNotification({
|
||||
variant: 'success',
|
||||
title: this.__(`Terms`),
|
||||
message: 'Template has been loaded in, do not forget to save.',
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import '../../../node_modules/simplemde/dist/simplemde.min.css';
|
||||
|
||||
.editor-toolbar.fullscreen {
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.CodeMirror-fullscreen {
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.editor-preview-side {
|
||||
z-index: 50;
|
||||
}
|
||||
</style>
|
||||
@@ -1,152 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Create user') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Create') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormInput :label="__('Name')" :errors="$page.props.errors.name" v-model="form.name" />
|
||||
<FormInput label="Email address" :errors="$page.props.errors.email" type="email" v-model="form.email" />
|
||||
<FormTextarea label="Notes" :errors="$page.props.errors.notes" v-model="form.notes" />
|
||||
<FormSelect :label="__('Role')" v-model="form.role">
|
||||
<option value="user">{{ __('User') }}</option>
|
||||
<option value="admin">{{ __('Administrator') }}</option>
|
||||
</FormSelect>
|
||||
|
||||
<FormSelect :label="__('Package')" v-model="form.package">
|
||||
<option value="" v-text="__('None')"></option>
|
||||
<option v-for="(name, id) in packages" :value="id" v-text="name"></option>
|
||||
</FormSelect>
|
||||
|
||||
<FormSelect :label="__('Language')" v-model="form.language">
|
||||
<option v-for="language in languages" :value="language" v-text="language"></option>
|
||||
</FormSelect>
|
||||
<FormTextarea :label="__('Blocked')" :errors="$page.props.errors.blocked" rows="2" v-model="form.blocked" />
|
||||
<div>
|
||||
<input id="isolate_per_site_per_user" class="form-checkbox" type="checkbox"
|
||||
v-model="form.requires_password_for_ftp">
|
||||
<label for="isolate_per_site_per_user" class="ml-2 text-sm">{{ __('Require password to show FTP password') }}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{ __('Disabling this will allow this user to get the FTP password right away.') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormTextarea from '@/components/forms/FormTextarea'
|
||||
import FormSelect from '@/components/forms/FormSelect'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import Tabs from './Tabs'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Create user')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormSelect,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
FormTextarea
|
||||
},
|
||||
|
||||
props: {
|
||||
packages: Object,
|
||||
languages: Array,
|
||||
defaultPackage: {},
|
||||
defaultLanguage: {}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
name: null,
|
||||
email: null,
|
||||
password: null,
|
||||
role: 'user',
|
||||
package: this.defaultPackage ?? null,
|
||||
notes: null,
|
||||
language: this.defaultLanguage ?? 'en',
|
||||
blocked: null,
|
||||
requires_password_for_ftp: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.$inertia.post(this.route('admin.users.store'), this.form, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,180 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Edit user') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs/>
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Edit') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<FormInput :label="__('Name')" :errors="$page.props.errors.name"
|
||||
v-model="form.name"/>
|
||||
<FormInput :label="__('Email')" :errors="$page.props.errors.email" type="email"
|
||||
v-model="form.email"/>
|
||||
<FormTextarea :label="__('Notes')" :errors="$page.props.errors.notes"
|
||||
v-model="form.notes"/>
|
||||
<FormSelect :label="__('Role')" v-model="form.role">
|
||||
<option value="user">User</option>
|
||||
<option value="admin">Administrator</option>
|
||||
</FormSelect>
|
||||
<FormSelect :label="__('Package')" v-model="form.package">
|
||||
<option value="" v-text="__('None')"></option>
|
||||
<option v-for="(name, id) in packages" :value="id" v-text="name"></option>
|
||||
</FormSelect>
|
||||
<FormSelect :label="__('Language')" v-model="form.language">
|
||||
<option v-for="language in languages" :value="language"
|
||||
v-text="language"></option>
|
||||
</FormSelect>
|
||||
<FormTextarea :label="__('Blocked')" :errors="$page.props.errors.blocked"
|
||||
rows="2" v-model="form.blocked"/>
|
||||
|
||||
<div>
|
||||
<input id="isolate_per_site_per_user" class="form-checkbox" type="checkbox"
|
||||
v-model="form.requires_password_for_ftp">
|
||||
<label for="isolate_per_site_per_user" class="ml-2 text-sm">{{
|
||||
__('Require password to show FTP password')
|
||||
}}</label>
|
||||
<p class="text-small mt-1 text-medium-emphasis">
|
||||
{{
|
||||
__('Disabling this will allow this user to get the FTP password right away.')
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<FormActions>
|
||||
<Button>{{ __('Save') }}</Button>
|
||||
<Button variant="danger" type="button" @click="confirmDelete">
|
||||
{{ __('Delete') }}
|
||||
</Button>
|
||||
</FormActions>
|
||||
</form>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormTextarea from '@/components/forms/FormTextarea'
|
||||
import FormSelect from '@/components/forms/FormSelect'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import {useConfirm} from '@/hooks/confirm'
|
||||
import Tabs from './Tabs'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Edit user')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormSelect,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
FormTextarea
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
sending: false,
|
||||
|
||||
form: {
|
||||
name: this.user.name,
|
||||
email: this.user.email,
|
||||
role: this.user.role,
|
||||
package: this.user.package_id,
|
||||
notes: this.user.notes,
|
||||
language: this.user.language,
|
||||
blocked: this.user.blocked,
|
||||
requires_password_for_ftp: this.user.requires_password_for_ftp,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
user: Object,
|
||||
packages: Object,
|
||||
languages: Array,
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.$inertia.patch(this.route('admin.users.update', this.user.id), this.form, {
|
||||
onStart: () => this.sending = true,
|
||||
onFinish: () => this.sending = false
|
||||
})
|
||||
},
|
||||
|
||||
confirmDelete() {
|
||||
useConfirm({
|
||||
title: this.__('Are you sure?'),
|
||||
message: `Are you sure you want to delete this user? Everything associated with this user will be detached.`,
|
||||
onConfirm: () => this.delete(),
|
||||
})
|
||||
},
|
||||
|
||||
delete() {
|
||||
this.sending = true
|
||||
|
||||
this.$inertia.delete(this.route('admin.users.destroy', this.user.id), {
|
||||
onFinish: () => {
|
||||
this.sending = false;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,177 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>{{ __('Users') }}</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Overview') }}</template>
|
||||
<template #form>
|
||||
<form class="space-y-4 pb-5 mb-5 border-b border-low-emphasis">
|
||||
<FormInput :label="__('Search')" v-model="form.search" />
|
||||
</form>
|
||||
</template>
|
||||
<template #content>
|
||||
<div>
|
||||
<Table caption="User list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>{{ __('User name') }}</TableHeader>
|
||||
<TableHeader>{{ __('Role') }}</TableHeader>
|
||||
<TableHeader>{{ __('Package') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="user in users.data" :key="user.id">
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.users.show', user.id)">
|
||||
<span class="text-primary">{{ user.name }}</span>
|
||||
|
||||
<p class="text-medium-emphasis">{{ user.email }}</p>
|
||||
<p class="text-medium-emphasis">{{ user.sites_count }} {{ __choice('site|sites', user.sites_count) }} · {{ user.servers_count }} {{ __choice('server|servers', user.servers_count) }}</p>
|
||||
</inertia-link>
|
||||
|
||||
</TableData>
|
||||
<TableData>{{ user.user_name }}</TableData>
|
||||
<TableData>{{ user.role }}</TableData>
|
||||
<TableData>{{ user.package ? user.package.name : '-' }}</TableData>
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.users.edit', user.id)"
|
||||
class="text-primary font-medium">
|
||||
{{ __('Edit') }}
|
||||
</inertia-link>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<pagination :links="users"/>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import {useNotification} from '@/hooks/notification'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import Tabs from './Tabs';
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
import pickBy from 'lodash/pickBy'
|
||||
import throttle from 'lodash/throttle'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__('Users')}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Pagination,
|
||||
Tabs,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
FormInput,
|
||||
},
|
||||
|
||||
props: {
|
||||
users: Object,
|
||||
filters: Object,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
form:{
|
||||
search: this.filters.search,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
form: {
|
||||
handler: throttle(function() {
|
||||
let query = pickBy(this.form)
|
||||
this.$inertia.get(this.route('admin.users.index', Object.keys(query).length ? query : { remember: 'forget' }),{}, {
|
||||
preserveState: true,
|
||||
})
|
||||
}, 500),
|
||||
deep: true
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.$page.props.flash.success) {
|
||||
useNotification({
|
||||
variant: 'success',
|
||||
title: `Users`,
|
||||
message: this.$page.props.flash.success,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
useNotification,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,226 +0,0 @@
|
||||
<template>
|
||||
<Page>
|
||||
<TopBar/>
|
||||
|
||||
<Content>
|
||||
<Container>
|
||||
<PageHeader>
|
||||
<template #start>
|
||||
<PageHeaderTitle>Show user</PageHeaderTitle>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<PageBody>
|
||||
<SettingsLayout>
|
||||
<template #nav>
|
||||
<Tabs />
|
||||
</template>
|
||||
<template #segments>
|
||||
<SettingsSegment>
|
||||
<template #title>{{ user.name }}</template>
|
||||
|
||||
<template #content>
|
||||
<div>
|
||||
<Table caption="Database list overview">
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableData :border="false">
|
||||
{{ user.name }}
|
||||
</TableData>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Username') }}</TableHeader>
|
||||
<TableData :border="false">
|
||||
{{ user.user_name }}
|
||||
</TableData>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('E-mail address') }}</TableHeader>
|
||||
<TableData :border="false">
|
||||
{{ user.email }}
|
||||
</TableData>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Customer payment ID') }}</TableHeader>
|
||||
<TableData :border="false">
|
||||
{{ user.stripe_id || '-' }}
|
||||
</TableData>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Notes') }}</TableHeader>
|
||||
<TableData :border="false">
|
||||
{{ user.notes || '-' }}
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Sites') }}</template>
|
||||
<template #content>
|
||||
<div>
|
||||
<Table caption="Site list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>{{ __('Server') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="site in sites.data" :key="site.id">
|
||||
<TableData>
|
||||
{{ site.domain }}
|
||||
</TableData>
|
||||
<TableData>
|
||||
{{ site.server ? site.server.name : '-' }}
|
||||
</TableData>
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.services.sites.edit', site.id)" class="text-primary font-medium">
|
||||
{{ __('Edit') }}
|
||||
</inertia-link>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<pagination :links="sites" :preserve-scroll="true"/>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
|
||||
<SettingsSegment>
|
||||
<template #title>{{ __('Servers') }}</template>
|
||||
<template #content>
|
||||
<div>
|
||||
<Table caption="Server list overview">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>{{ __('Name') }}</TableHeader>
|
||||
<TableHeader>{{ __('Usage') }}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow v-for="server in servers.data" :key="server.id">
|
||||
<TableData>
|
||||
{{ server.name }}
|
||||
|
||||
<p class="text-medium-emphasis">{{ server.ip }}</p>
|
||||
|
||||
<Button class="text-small text-primary" is="a" size="sm" target="_blank" :href="`https://ploi.io/panel/servers/${server.ploi_id}`">
|
||||
{{ __('View in ploi.io') }}
|
||||
</Button>
|
||||
</TableData>
|
||||
<TableData>{{ server.sites_count }}/{{ server.maximum_sites }}</TableData>
|
||||
<TableData>
|
||||
<inertia-link :href="route('admin.services.servers.edit', server.id)" class="text-primary font-medium">
|
||||
{{ __('Edit') }}
|
||||
</inertia-link>
|
||||
</TableData>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<pagination :links="servers" :preserve-scroll="true"/>
|
||||
</template>
|
||||
</SettingsSegment>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</PageBody>
|
||||
</Container>
|
||||
</Content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '../components/TopBar'
|
||||
import Container from '@/components/Container'
|
||||
import Content from '@/components/Content'
|
||||
import Page from '@/components/Page'
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PageHeaderTitle from '@/components/PageHeaderTitle'
|
||||
import PageBody from '@/components/PageBody'
|
||||
import Button from '@/components/Button'
|
||||
import List from '@/components/List'
|
||||
import ListItem from '@/components/ListItem'
|
||||
import StatusBubble from '@/components/StatusBubble'
|
||||
import NotificationBadge from '@/components/NotificationBadge'
|
||||
import MainLayout from '@/Layouts/MainLayout'
|
||||
import SettingsLayout from '@/components/layouts/SettingsLayout'
|
||||
import SettingsSegment from '@/components/SettingsSegment'
|
||||
import FormInput from '@/components/forms/FormInput'
|
||||
import FormTextarea from '@/components/forms/FormTextarea'
|
||||
import FormSelect from '@/components/forms/FormSelect'
|
||||
import Form from '@/components/Form'
|
||||
import FormActions from '@/components/FormActions'
|
||||
import Table from '@/components/Table'
|
||||
import TableHead from '@/components/TableHead'
|
||||
import TableHeader from '@/components/TableHeader'
|
||||
import TableRow from '@/components/TableRow'
|
||||
import TableBody from '@/components/TableBody'
|
||||
import TableData from '@/components/TableData'
|
||||
import Tabs from './Tabs'
|
||||
import Pagination from '@/components/Pagination'
|
||||
|
||||
export default {
|
||||
metaInfo() {
|
||||
return {
|
||||
title: `${this.__(this.user.name)}`,
|
||||
}
|
||||
},
|
||||
|
||||
layout: MainLayout,
|
||||
|
||||
components: {
|
||||
TopBar,
|
||||
Container,
|
||||
Content,
|
||||
Page,
|
||||
PageHeader,
|
||||
PageHeaderTitle,
|
||||
PageBody,
|
||||
Button,
|
||||
List,
|
||||
ListItem,
|
||||
StatusBubble,
|
||||
NotificationBadge,
|
||||
FormInput,
|
||||
FormSelect,
|
||||
SettingsLayout,
|
||||
SettingsSegment,
|
||||
Form,
|
||||
FormActions,
|
||||
Tabs,
|
||||
FormTextarea,
|
||||
Table,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableBody,
|
||||
TableData,
|
||||
Pagination
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
user: Object,
|
||||
sites: Object,
|
||||
servers: Object,
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,32 +0,0 @@
|
||||
<template>
|
||||
<ul class="-ml-4 space-y-1">
|
||||
<li v-for="item in items">
|
||||
<inertia-link
|
||||
class="flex items-center h-10 px-4 font-medium text-medium-emphasis"
|
||||
:class="{'rounded shadow text-primary bg-surface-3': item.active}"
|
||||
:href="item.to"
|
||||
>{{ item.title }} {{ item.route }}</inertia-link
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
items: [
|
||||
{
|
||||
title: this.__('Overview'),
|
||||
to: this.route('admin.users.index'),
|
||||
active: this.route().current('admin.users.index')
|
||||
},
|
||||
{
|
||||
title: this.__('Create'),
|
||||
to: this.route('admin.users.create'),
|
||||
active: this.route().current('admin.users.create')
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,93 +0,0 @@
|
||||
<template>
|
||||
<TopBar>
|
||||
<template #breadcrumbs>
|
||||
<Breadcrumbs :items="breadcrumbs" />
|
||||
</template>
|
||||
<template #tab-bar>
|
||||
<TopBarTabBarContainer>
|
||||
<TabBar :items="tabBars" />
|
||||
</TopBarTabBarContainer>
|
||||
</template>
|
||||
</TopBar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TopBar from '@/components/TopBar.vue'
|
||||
import Breadcrumbs from '@/components/Breadcrumbs.vue'
|
||||
import TopBarTabBarContainer from '@/components/TopBarTabBarContainer.vue'
|
||||
import TabBar from "@/components/TabBar.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TopBar,
|
||||
Breadcrumbs,
|
||||
TabBar,
|
||||
TopBarTabBarContainer,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabBars: [
|
||||
{
|
||||
title: 'Dashboard',
|
||||
to: this.route('admin.dashboard'),
|
||||
active: (
|
||||
this.route().current('admin.dashboard') ||
|
||||
this.route().current('admin.settings') ||
|
||||
this.route().current('admin.system')
|
||||
)
|
||||
},
|
||||
{
|
||||
title: this.__('Users'),
|
||||
to: this.route('admin.users.index'),
|
||||
active: this.route().current('admin.users.*')
|
||||
},
|
||||
{
|
||||
title: this.__('Packages'),
|
||||
to: this.route('admin.packages.index'),
|
||||
active: this.route().current('admin.packages.*')
|
||||
},
|
||||
{
|
||||
title: this.__('Sites'),
|
||||
to: this.route('admin.sites.index'),
|
||||
active: this.route().current('admin.sites.*')
|
||||
},
|
||||
{
|
||||
title: this.__('Servers'),
|
||||
to: this.route('admin.servers.index'),
|
||||
active: this.route().current('admin.servers.*')
|
||||
},
|
||||
this.$page.props.settings.support ? {
|
||||
title: `${this.__('Support')} (${this.$page.props.openTickets})`,
|
||||
to: this.route('admin.support.index'),
|
||||
active: this.route().current('admin.support.*')
|
||||
} : null,
|
||||
this.$page.props.settings.documentation ? {
|
||||
title: this.__('Documentation'),
|
||||
to: this.route('admin.documentation.index'),
|
||||
active: this.route().current('admin.documentation.*')
|
||||
} : null,
|
||||
{
|
||||
title: 'Services',
|
||||
to: this.route('admin.services.index'),
|
||||
active: this.route().current('admin.services.*')
|
||||
},
|
||||
// {
|
||||
// title: 'Status',
|
||||
// to: this.route('admin.status.index'),
|
||||
// active: this.route().current('admin.status.*')
|
||||
// }
|
||||
],
|
||||
breadcrumbs: [
|
||||
{
|
||||
title: this.$page.props.settings.name,
|
||||
to: '/',
|
||||
},
|
||||
{
|
||||
title: this.__('Administration'),
|
||||
to: this.route('admin.dashboard'),
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
106
routes/admin.php
106
routes/admin.php
@@ -1,106 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('/', 'DashboardController')->name('dashboard');
|
||||
|
||||
Route::group(['prefix' => 'settings'], function () {
|
||||
Route::get('/', 'SettingController@index')->name('settings');
|
||||
Route::patch('/', 'SettingController@update')->name('settings.update');
|
||||
Route::get('terms', 'SettingController@terms')->name('settings.terms');
|
||||
Route::get('terms/template', 'SettingController@termsTemplate')->name('settings.terms.template');
|
||||
Route::patch('terms', 'SettingController@updateTerms')->name('settings.terms.update');
|
||||
Route::delete('remove-logo', 'SettingController@removeLogo')->name('settings.remove-logo');
|
||||
});
|
||||
|
||||
Route::get('system', 'SystemController@index')->name('system');
|
||||
Route::post('system/update', 'SystemController@update')->name('system.update');
|
||||
Route::get('status', 'StatusController@index')->name('status.index');
|
||||
|
||||
Route::get('application-logs', 'ApplicationLogController@index')->name('application-logs');
|
||||
|
||||
Route::group(['prefix' => 'support', 'as' => 'support.'], function () {
|
||||
Route::get('/', 'SupportController@index')->name('index');
|
||||
Route::get('{ticket}', 'SupportController@show')->name('show');
|
||||
Route::post('{ticket}/reply', 'SupportController@reply')->name('reply');
|
||||
Route::post('{ticket}/close', 'SupportController@close')->name('close');
|
||||
});
|
||||
|
||||
Route::group(['prefix' => 'alerts', 'as' => 'alerts.'], function () {
|
||||
Route::get('/', 'AlertController@index')->name('index');
|
||||
Route::get('create', 'AlertController@create')->name('create');
|
||||
Route::post('/', 'AlertController@store')->name('store');
|
||||
Route::get('{alert}/edit', 'AlertController@edit')->name('edit');
|
||||
Route::patch('{alert}', 'AlertController@update')->name('update');
|
||||
Route::delete('{alert}', 'AlertController@destroy')->name('delete');
|
||||
});
|
||||
|
||||
Route::group(['prefix' => 'documentation', 'as' => 'documentation.'], function () {
|
||||
Route::get('/', 'DocumentationController@index')->name('index');
|
||||
Route::get('create', 'DocumentationController@create')->name('create');
|
||||
Route::post('/', 'DocumentationController@store')->name('store');
|
||||
Route::get('{category}/edit', 'DocumentationController@edit')->name('edit');
|
||||
Route::patch('{category}', 'DocumentationController@update')->name('update');
|
||||
|
||||
Route::group(['prefix' => 'articles', 'as' => 'articles.'], function () {
|
||||
Route::get('/', 'DocumentationArticleController@index')->name('index');
|
||||
Route::get('create', 'DocumentationArticleController@create')->name('create');
|
||||
Route::post('/', 'DocumentationArticleController@store')->name('store');
|
||||
Route::get('{article}/edit', 'DocumentationArticleController@edit')->name('edit');
|
||||
Route::patch('{article}', 'DocumentationArticleController@update')->name('update');
|
||||
});
|
||||
});
|
||||
|
||||
Route::group(['prefix' => 'sites', 'as' => 'sites.'], function () {
|
||||
Route::get('/', 'SiteController@index')->name('index');
|
||||
});
|
||||
|
||||
Route::group(['prefix' => 'servers', 'as' => 'servers.'], function () {
|
||||
Route::get('/', 'ServerController@index')->name('index');
|
||||
});
|
||||
|
||||
Route::group(['prefix' => 'services', 'as' => 'services.'], function () {
|
||||
Route::get('/', 'ServiceController@index')->name('index');
|
||||
|
||||
// Server syncing
|
||||
Route::group(['prefix' => 'servers', 'as' => 'servers.'], function () {
|
||||
Route::get('/', 'SynchronizeServerController@index')->name('index');
|
||||
Route::post('/', 'SynchronizeServerController@synchronizeServer')->name('sync');
|
||||
Route::post('all', 'SynchronizeServerController@synchronizeAll')->name('sync.all');
|
||||
|
||||
Route::get('{server}/edit', 'ServerController@edit')->name('edit');
|
||||
Route::post('{server}/attach', 'ServerController@attach')->name('attach');
|
||||
Route::patch('{server}', 'ServerController@update')->name('update');
|
||||
Route::delete('{server}', 'ServerController@destroy')->name('delete');
|
||||
Route::delete('{server}/detach/{user}', 'ServerController@detach')->name('detach');
|
||||
});
|
||||
|
||||
// Provider syncing
|
||||
Route::group(['prefix' => 'providers', 'as' => 'providers.'], function () {
|
||||
Route::get('/', 'SynchronizeProviderController@index')->name('index');
|
||||
Route::post('{provider}', 'SynchronizeProviderController@synchronize')->name('sync');
|
||||
|
||||
Route::get('{provider}/edit', 'ProviderController@edit')->name('edit');
|
||||
Route::patch('{provider}', 'ProviderController@update')->name('update');
|
||||
Route::delete('{provider}', 'ProviderController@destroy')->name('delete');
|
||||
});
|
||||
|
||||
// Site syncing
|
||||
Route::group(['prefix' => 'sites', 'as' => 'sites.'], function () {
|
||||
Route::get('/', 'SynchronizeSiteController@index')->name('index');
|
||||
Route::post('/', 'SynchronizeSiteController@synchronizeSite')->name('sync');
|
||||
Route::post('all', 'SynchronizeSiteController@synchronizeAll')->name('sync.all');
|
||||
|
||||
Route::get('{site}/edit', 'SiteController@edit')->name('edit');
|
||||
Route::post('{site}/attach', 'SiteController@attach')->name('attach');
|
||||
Route::patch('{site}', 'SiteController@update')->name('update');
|
||||
Route::delete('{site}', 'SiteController@destroy')->name('delete');
|
||||
Route::delete('{site}/detach/{user}', 'SiteController@detach')->name('detach');
|
||||
});
|
||||
});
|
||||
|
||||
Route::resource('packages', 'PackageController');
|
||||
Route::resource('providers', 'ProviderController');
|
||||
Route::resource('plans', 'ProviderPlanController');
|
||||
Route::resource('regions', 'ProviderRegionController');
|
||||
Route::resource('users', 'UserController');
|
||||
Reference in New Issue
Block a user