Merge branch 'development' into improve/installer-ui
This commit is contained in:
commit
b20a2d24e4
14 changed files with 290 additions and 221 deletions
app
database/migrations
public/install
themes/default/views/admin
|
@ -24,19 +24,18 @@ class PterodactylClient
|
|||
|
||||
public PendingRequest $client;
|
||||
|
||||
public PendingRequest $client_admin;
|
||||
|
||||
public PendingRequest $application;
|
||||
|
||||
public function __construct(PterodactylSettings $ptero_settings)
|
||||
{
|
||||
$server_settings = new ServerSettings();
|
||||
|
||||
|
||||
try {
|
||||
$this->client = $this->client($ptero_settings);
|
||||
$this->client_admin = $this->clientAdmin($ptero_settings);
|
||||
$this->application = $this->clientAdmin($ptero_settings);
|
||||
$this->per_page_limit = $ptero_settings->per_page_limit;
|
||||
$this->allocation_limit = $server_settings->allocation_limit;
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
} catch (Exception $exception) {
|
||||
logger('Failed to construct Pterodactyl client, Settings table not available?', ['exception' => $exception]);
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +93,7 @@ class PterodactylClient
|
|||
public function getEggs(Nest $nest)
|
||||
{
|
||||
try {
|
||||
$response = $this->client_admin->get("application/nests/{$nest->id}/eggs?include=nest,variables&per_page=" . $this->per_page_limit);
|
||||
$response = $this->application->get("application/nests/{$nest->id}/eggs?include=nest,variables&per_page=" . $this->per_page_limit);
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -113,7 +112,7 @@ class PterodactylClient
|
|||
public function getNodes()
|
||||
{
|
||||
try {
|
||||
$response = $this->client_admin->get('application/nodes?per_page=' . $this->per_page_limit);
|
||||
$response = $this->application->get('application/nodes?per_page=' . $this->per_page_limit);
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -133,7 +132,7 @@ class PterodactylClient
|
|||
public function getNode($id)
|
||||
{
|
||||
try {
|
||||
$response = $this->client_admin->get('application/nodes/' . $id);
|
||||
$response = $this->application->get('application/nodes/' . $id);
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -147,7 +146,7 @@ class PterodactylClient
|
|||
public function getServers()
|
||||
{
|
||||
try {
|
||||
$response = $this->client_admin->get('application/servers?per_page=' . $this->per_page_limit);
|
||||
$response = $this->application->get('application/servers?per_page=' . $this->per_page_limit);
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -166,7 +165,7 @@ class PterodactylClient
|
|||
public function getNests()
|
||||
{
|
||||
try {
|
||||
$response = $this->client_admin->get('application/nests?per_page=' . $this->per_page_limit);
|
||||
$response = $this->application->get('application/nests?per_page=' . $this->per_page_limit);
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -185,7 +184,7 @@ class PterodactylClient
|
|||
public function getLocations()
|
||||
{
|
||||
try {
|
||||
$response = $this->client_admin->get('application/locations?per_page=' . $this->per_page_limit);
|
||||
$response = $this->application->get('application/locations?per_page=' . $this->per_page_limit);
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -240,7 +239,7 @@ class PterodactylClient
|
|||
public function getAllocations(Node $node)
|
||||
{
|
||||
try {
|
||||
$response = $this->client_admin->get("application/nodes/{$node->id}/allocations?per_page={$this->allocation_limit}");
|
||||
$response = $this->application->get("application/nodes/{$node->id}/allocations?per_page={$this->allocation_limit}");
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -259,7 +258,7 @@ class PterodactylClient
|
|||
*/
|
||||
public function createServer(Server $server, Egg $egg, int $allocationId)
|
||||
{
|
||||
return $this->client_admin->post('application/servers', [
|
||||
return $this->application->post('application/servers', [
|
||||
'name' => $server->name,
|
||||
'external_id' => $server->id,
|
||||
'user' => $server->user->pterodactyl_id,
|
||||
|
@ -288,7 +287,7 @@ class PterodactylClient
|
|||
public function suspendServer(Server $server)
|
||||
{
|
||||
try {
|
||||
$response = $this->client_admin->post("application/servers/$server->pterodactyl_id/suspend");
|
||||
$response = $this->application->post("application/servers/$server->pterodactyl_id/suspend");
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -302,7 +301,7 @@ class PterodactylClient
|
|||
public function unSuspendServer(Server $server)
|
||||
{
|
||||
try {
|
||||
$response = $this->client_admin->post("application/servers/$server->pterodactyl_id/unsuspend");
|
||||
$response = $this->application->post("application/servers/$server->pterodactyl_id/unsuspend");
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -322,7 +321,7 @@ class PterodactylClient
|
|||
public function getUser(int $pterodactylId)
|
||||
{
|
||||
try {
|
||||
$response = $this->client_admin->get("application/users/{$pterodactylId}");
|
||||
$response = $this->application->get("application/users/{$pterodactylId}");
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -342,7 +341,7 @@ class PterodactylClient
|
|||
public function getServerAttributes(int $pterodactylId, bool $deleteOn404 = false)
|
||||
{
|
||||
try {
|
||||
$response = $this->client_admin->get("application/servers/{$pterodactylId}?include=egg,node,nest,location");
|
||||
$response = $this->application->get("application/servers/{$pterodactylId}?include=egg,node,nest,location");
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
@ -371,7 +370,7 @@ class PterodactylClient
|
|||
*/
|
||||
public function updateServer(Server $server, Product $product)
|
||||
{
|
||||
return $this->client_admin->patch("application/servers/{$server->pterodactyl_id}/build", [
|
||||
return $this->application->patch("application/servers/{$server->pterodactyl_id}/build", [
|
||||
'allocation' => $server->allocation,
|
||||
'memory' => $product->memory,
|
||||
'swap' => $product->swap,
|
||||
|
@ -396,7 +395,7 @@ class PterodactylClient
|
|||
*/
|
||||
public function updateServerOwner(Server $server, int $userId)
|
||||
{
|
||||
return $this->client_admin->patch("application/servers/{$server->pterodactyl_id}/details", [
|
||||
return $this->application->patch("application/servers/{$server->pterodactyl_id}/details", [
|
||||
'name' => $server->name,
|
||||
'user' => $userId,
|
||||
]);
|
||||
|
@ -435,7 +434,7 @@ class PterodactylClient
|
|||
public function checkNodeResources(Node $node, int $requireMemory, int $requireDisk)
|
||||
{
|
||||
try {
|
||||
$response = $this->client_admin->get("application/nodes/{$node->id}");
|
||||
$response = $this->application->get("application/nodes/{$node->id}");
|
||||
} catch (Exception $e) {
|
||||
throw self::getException($e->getMessage());
|
||||
}
|
||||
|
|
|
@ -109,26 +109,18 @@ class SettingsController extends Controller
|
|||
$settingsClass = new $settings_class();
|
||||
|
||||
foreach ($settingsClass->toArray() as $key => $value) {
|
||||
switch (gettype($request->input($key))) {
|
||||
case 'boolean':
|
||||
$settingsClass->$key = $request->has($key);
|
||||
break;
|
||||
case 'string':
|
||||
$settingsClass->$key = $request->input($key) ?? '';
|
||||
break;
|
||||
case 'integer':
|
||||
$settingsClass->$key = $request->input($key) ?? 0;
|
||||
break;
|
||||
case 'array':
|
||||
$settingsClass->$key = $request->input($key) ?? [];
|
||||
break;
|
||||
case 'double':
|
||||
$settingsClass->$key = $request->input($key) ?? 0.0;
|
||||
break;
|
||||
case 'NULL':
|
||||
$settingsClass->$key = null;
|
||||
break;
|
||||
// Get the type of the settingsclass property
|
||||
$rp = new \ReflectionProperty($settingsClass, $key);
|
||||
$rpType = $rp->getType();
|
||||
|
||||
if ($rpType == 'bool') {
|
||||
$settingsClass->$key = $request->has($key);
|
||||
continue;
|
||||
}
|
||||
|
||||
$nullable = $rpType->allowsNull();
|
||||
if ($nullable) $settingsClass->$key = $request->input($key) ?? null;
|
||||
else $settingsClass->$key = $request->input($key);
|
||||
}
|
||||
|
||||
$settingsClass->save();
|
||||
|
|
|
@ -35,7 +35,7 @@ class UserController extends Controller
|
|||
{
|
||||
$this->pterodactyl = new PterodactylClient($ptero_settings);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
@ -166,6 +166,10 @@ class UserController extends Controller
|
|||
*/
|
||||
public function destroy(User $user)
|
||||
{
|
||||
if ($user->role === 'admin' && User::query()->where('role', 'admin')->count() === 1) {
|
||||
return redirect()->back()->with('error', __('You can not delete the last admin!'));
|
||||
}
|
||||
|
||||
$user->delete();
|
||||
|
||||
return redirect()->back()->with('success', __('user has been removed!'));
|
||||
|
@ -258,8 +262,7 @@ class UserController extends Controller
|
|||
$users = $all ? User::all() : User::whereIn('id', $data['users'])->get();
|
||||
try {
|
||||
Notification::send($users, new DynamicNotification($data['via'], $database, $mail));
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
return redirect()->route('admin.users.notifications')->with('error', __('The attempt to send the email failed with the error: ' . $e->getMessage()));
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ class UserController extends Controller
|
|||
{
|
||||
$this->pterodactyl = new PterodactylClient($ptero_settings);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
@ -105,7 +105,7 @@ class UserController extends Controller
|
|||
|
||||
//Update Users Password on Pterodactyl
|
||||
//Username,Mail,First and Lastname are required aswell
|
||||
$response = $this->pterodactyl->client_admin->patch('/application/users/' . $user->pterodactyl_id, [
|
||||
$response = $this->pterodactyl->application->patch('/application/users/' . $user->pterodactyl_id, [
|
||||
'username' => $request->name,
|
||||
'first_name' => $request->name,
|
||||
'last_name' => $request->name,
|
||||
|
@ -280,7 +280,7 @@ class UserController extends Controller
|
|||
'referral_code' => $this->createReferralCode(),
|
||||
]);
|
||||
|
||||
$response = $this->pterodactyl->client_admin->post('/application/users', [
|
||||
$response = $this->pterodactyl->application->post('/application/users', [
|
||||
'external_id' => App::environment('local') ? Str::random(16) : (string) $user->id,
|
||||
'username' => $user->name,
|
||||
'email' => $user->email,
|
||||
|
|
|
@ -135,11 +135,12 @@ class RegisterController extends Controller
|
|||
'server_limit' => $this->initial_server_limit,
|
||||
'password' => Hash::make($data['password']),
|
||||
'referral_code' => $this->createReferralCode(),
|
||||
'pterodactyl_id' => Str::uuid(),
|
||||
|
||||
]);
|
||||
|
||||
$response = $this->pterodactyl->client_admin->post('/application/users', [
|
||||
'external_id' => App::environment('local') ? Str::random(16) : (string) $user->id,
|
||||
$response = $this->pterodactyl->application->post('/application/users', [
|
||||
'external_id' => $user->pterodactyl_id,
|
||||
'username' => $user->name,
|
||||
'email' => $user->email,
|
||||
'first_name' => $user->name,
|
||||
|
@ -157,9 +158,8 @@ class RegisterController extends Controller
|
|||
]);
|
||||
}
|
||||
|
||||
$user->update([
|
||||
'pterodactyl_id' => $response->json()['attributes']['id'],
|
||||
]);
|
||||
// delete activity log for user creation where description = 'created' or 'deleted' and subject_id = user_id
|
||||
DB::table('activity_log')->where('description', 'created')->orWhere('description', 'deleted')->where('subject_id', $user->id)->delete();
|
||||
|
||||
//INCREMENT REFERRAL-USER CREDITS
|
||||
if (!empty($data['referral_code'])) {
|
||||
|
|
|
@ -78,15 +78,15 @@ class ProfileController extends Controller
|
|||
$user = User::findOrFail($id);
|
||||
|
||||
//update password if necessary
|
||||
if (! is_null($request->input('new_password'))) {
|
||||
if (!is_null($request->input('new_password'))) {
|
||||
|
||||
//validate password request
|
||||
$request->validate([
|
||||
'current_password' => [
|
||||
'required',
|
||||
function ($attribute, $value, $fail) use ($user) {
|
||||
if (! Hash::check($value, $user->password)) {
|
||||
$fail('The '.$attribute.' is invalid.');
|
||||
if (!Hash::check($value, $user->password)) {
|
||||
$fail('The ' . $attribute . ' is invalid.');
|
||||
}
|
||||
},
|
||||
],
|
||||
|
@ -96,7 +96,7 @@ class ProfileController extends Controller
|
|||
|
||||
//Update Users Password on Pterodactyl
|
||||
//Username,Mail,First and Lastname are required aswell
|
||||
$response = $this->pterodactyl->client_admin->patch('/application/users/' . $user->pterodactyl_id, [
|
||||
$response = $this->pterodactyl->application->patch('/application/users/' . $user->pterodactyl_id, [
|
||||
'password' => $request->input('new_password'),
|
||||
'username' => $request->input('name'),
|
||||
'first_name' => $request->input('name'),
|
||||
|
@ -118,13 +118,13 @@ class ProfileController extends Controller
|
|||
|
||||
//validate request
|
||||
$request->validate([
|
||||
'name' => 'required|min:4|max:30|alpha_num|unique:users,name,'.$id.',id',
|
||||
'email' => 'required|email|max:64|unique:users,email,'.$id.',id',
|
||||
'name' => 'required|min:4|max:30|alpha_num|unique:users,name,' . $id . ',id',
|
||||
'email' => 'required|email|max:64|unique:users,email,' . $id . ',id',
|
||||
'avatar' => 'nullable',
|
||||
]);
|
||||
|
||||
//update avatar
|
||||
if (! is_null($request->input('avatar'))) {
|
||||
if (!is_null($request->input('avatar'))) {
|
||||
$avatar = json_decode($request->input('avatar'));
|
||||
if ($avatar->input->size > 3000000) {
|
||||
abort(500);
|
||||
|
@ -140,7 +140,7 @@ class ProfileController extends Controller
|
|||
}
|
||||
|
||||
//update name and email on Pterodactyl
|
||||
$response = $this->pterodactyl->client_admin->patch('/application/users/' . $user->pterodactyl_id, [
|
||||
$response = $this->pterodactyl->application->patch('/application/users/' . $user->pterodactyl_id, [
|
||||
'username' => $request->input('name'),
|
||||
'first_name' => $request->input('name'),
|
||||
'last_name' => $request->input('name'),
|
||||
|
|
|
@ -28,9 +28,9 @@ class Server extends Model
|
|||
public function getActivitylogOptions(): LogOptions
|
||||
{
|
||||
return LogOptions::defaults()
|
||||
-> logOnlyDirty()
|
||||
-> logOnly(['*'])
|
||||
-> dontSubmitEmptyLogs();
|
||||
->logOnlyDirty()
|
||||
->logOnly(['*'])
|
||||
->dontSubmitEmptyLogs();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,8 +84,8 @@ class Server extends Model
|
|||
});
|
||||
|
||||
static::deleting(function (Server $server) {
|
||||
$response = $server->pterodactyl->client_admin->delete("/application/servers/{$server->pterodactyl_id}");
|
||||
if ($response->failed() && ! is_null($server->pterodactyl_id)) {
|
||||
$response = $server->pterodactyl->application->delete("/application/servers/{$server->pterodactyl_id}");
|
||||
if ($response->failed() && !is_null($server->pterodactyl_id)) {
|
||||
//only return error when it's not a 404 error
|
||||
if ($response['errors'][0]['status'] != '404') {
|
||||
throw new Exception($response['errors'][0]['code']);
|
||||
|
@ -99,7 +99,7 @@ class Server extends Model
|
|||
*/
|
||||
public function isSuspended()
|
||||
{
|
||||
return ! is_null($this->suspended);
|
||||
return !is_null($this->suspended);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,7 +107,7 @@ class Server extends Model
|
|||
*/
|
||||
public function getPterodactylServer()
|
||||
{
|
||||
return $this->pterodactyl->client_admin->get("/application/servers/{$this->pterodactyl_id}");
|
||||
return $this->pterodactyl->application->get("/application/servers/{$this->pterodactyl_id}");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -122,7 +122,7 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||
|
||||
$user->discordUser()->delete();
|
||||
|
||||
$user->pterodactyl->client_admin->delete("/application/users/{$user->pterodactyl_id}");
|
||||
$user->pterodactyl->application->delete("/application/users/{$user->pterodactyl_id}");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -195,9 +195,6 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||
return $this->suspended;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function suspend()
|
||||
{
|
||||
foreach ($this->servers as $server) {
|
||||
|
@ -211,9 +208,6 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function unSuspend()
|
||||
{
|
||||
foreach ($this->getServersWithProduct() as $server) {
|
||||
|
@ -241,23 +235,9 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||
*/
|
||||
public function getAvatar()
|
||||
{
|
||||
//TODO loading the images to confirm they exist is causing to much load time. alternative has to be found :) maybe onerror tag on the <img tags>
|
||||
// if ($this->discordUser()->exists()) {
|
||||
// if(@getimagesize($this->discordUser->getAvatar())) {
|
||||
// $avatar = $this->discordUser->getAvatar();
|
||||
// } else {
|
||||
// $avatar = "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email)));
|
||||
// }
|
||||
// } else {
|
||||
// $avatar = "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email)));
|
||||
// }
|
||||
|
||||
return 'https://www.gravatar.com/avatar/' . md5(strtolower(trim($this->email)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function creditUsage()
|
||||
{
|
||||
$usage = 0;
|
||||
|
|
|
@ -9,6 +9,7 @@ use Exception;
|
|||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
|
@ -54,6 +55,14 @@ class AppServiceProvider extends ServiceProvider
|
|||
return $ok;
|
||||
});
|
||||
|
||||
// Force HTTPS if APP_URL is set to https
|
||||
if (config('app.url') && parse_url(config('app.url'), PHP_URL_SCHEME) === 'https') {
|
||||
URL::forceScheme('https');
|
||||
}
|
||||
|
||||
// Do not run this code if no APP_KEY is set
|
||||
if (config('app.key') == null) return;
|
||||
|
||||
try {
|
||||
if (Schema::hasColumn('useful_links', 'position')) {
|
||||
$useful_links = UsefulLink::where("position", "like", "%topbar%")->get()->sortby("id");
|
||||
|
@ -63,6 +72,7 @@ class AppServiceProvider extends ServiceProvider
|
|||
Log::error("Couldnt find useful_links. Probably the installation is not completet. " . $e);
|
||||
}
|
||||
|
||||
|
||||
$settings = $this->app->make(MailSettings::class);
|
||||
$settings->setConfig();
|
||||
}
|
||||
|
|
|
@ -25,11 +25,11 @@ class ReferralSettings extends Settings
|
|||
public static function getValidations()
|
||||
{
|
||||
return [
|
||||
'allowed' => 'required|in:everyone,clients',
|
||||
'allowed' => 'required|in:Everyone,Clients',
|
||||
'always_give_commission' => 'nullable|boolean',
|
||||
'enabled' => 'nullable|boolean',
|
||||
'reward' => 'nullable|numeric',
|
||||
'mode' => 'required|in:commission,percentage,both',
|
||||
'mode' => 'required|in:Commission,Sign-Up,Both',
|
||||
'percentage' => 'nullable|numeric',
|
||||
];
|
||||
}
|
||||
|
|
32
database/migrations/2023_04_03_231829_update_users_table.php
Normal file
32
database/migrations/2023_04_03_231829_update_users_table.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->string('pterodactyl_id')->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->integer('pterodactyl_id')->nullable->change();
|
||||
});
|
||||
}
|
||||
};
|
|
@ -9,6 +9,10 @@ use Monolog\Formatter\LineFormatter;
|
|||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Logger;
|
||||
|
||||
if (!file_exists('../../.env')) {
|
||||
echo run_console('cp .env.example .env');
|
||||
}
|
||||
|
||||
(new DotEnv(dirname(__FILE__, 3) . '/.env'))->load();
|
||||
|
||||
$required_extensions = ['openssl', 'gd', 'mysql', 'PDO', 'mbstring', 'tokenizer', 'bcmath', 'xml', 'curl', 'zip', 'intl'];
|
||||
|
|
|
@ -6,12 +6,13 @@
|
|||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1>{{__('Servers')}}</h1>
|
||||
<h1>{{ __('Servers') }}</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
|
||||
<li class="breadcrumb-item"><a class="text-muted" href="{{route('admin.servers.index')}}">{{__('Servers')}}</a></li>
|
||||
<li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
|
||||
<li class="breadcrumb-item"><a class="text-muted"
|
||||
href="{{ route('admin.servers.index') }}">{{ __('Servers') }}</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -27,25 +28,25 @@
|
|||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="card-title ">
|
||||
<span><i class="fas fa-server mr-2"></i>{{__('Servers')}}</span>
|
||||
<span><i class="fas fa-server mr-2"></i>{{ __('Servers') }}</span>
|
||||
</div>
|
||||
<a href="{{route('admin.servers.sync')}}" class="btn btn-primary btn-sm"><i
|
||||
class="fas fa-sync mr-2"></i>{{__('Sync')}}</a>
|
||||
<a href="{{ route('admin.servers.sync') }}" class="btn btn-primary btn-sm"><i
|
||||
class="fas fa-sync mr-2"></i>{{ __('Sync') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body table-responsive">
|
||||
<table id="datatable" class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="20">{{ __('Status') }}</th>
|
||||
<th>{{__('Name')}}</th>
|
||||
<th>{{__('User')}}</th>
|
||||
<th>{{__('Server id')}}</th>
|
||||
<th>{{__('Config')}}</th>
|
||||
<th>{{__('Suspended at')}}</th>
|
||||
<th>{{__('Created at')}}</th>
|
||||
<th>{{ __('Actions') }}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th width="20">{{ __('Status') }}</th>
|
||||
<th>{{ __('Name') }}</th>
|
||||
<th>{{ __('User') }}</th>
|
||||
<th>{{ __('Server id') }}</th>
|
||||
<th>{{ __('Product') }}</th>
|
||||
<th>{{ __('Suspended at') }}</th>
|
||||
<th>{{ __('Created at') }}</th>
|
||||
<th>{{ __('Actions') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
|
@ -61,10 +62,10 @@
|
|||
|
||||
<script>
|
||||
function submitResult() {
|
||||
return confirm("{{__('Are you sure you wish to delete?')}}") !== false;
|
||||
return confirm("{{ __('Are you sure you wish to delete?') }}") !== false;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
$('#datatable').DataTable({
|
||||
language: {
|
||||
url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{ $locale_datatables }}.json'
|
||||
|
@ -72,19 +73,40 @@
|
|||
processing: true,
|
||||
serverSide: true,
|
||||
stateSave: true,
|
||||
ajax: "{{route('admin.servers.datatable')}}{{$filter ?? ''}}",
|
||||
order: [[ 5, "desc" ]],
|
||||
columns: [
|
||||
{data: 'status' , name : 'servers.suspended'},
|
||||
{data: 'name'},
|
||||
{data: 'user' , name : 'user.name'},
|
||||
{data: 'identifier'},
|
||||
{data: 'resources' , name : 'product.name'},
|
||||
{data: 'suspended'},
|
||||
{data: 'created_at'},
|
||||
{data: 'actions' , sortable : false},
|
||||
ajax: "{{ route('admin.servers.datatable') }}{{ $filter ?? '' }}",
|
||||
order: [
|
||||
[5, "desc"]
|
||||
],
|
||||
fnDrawCallback: function( oSettings ) {
|
||||
columns: [{
|
||||
data: 'status',
|
||||
name: 'servers.suspended'
|
||||
},
|
||||
{
|
||||
data: 'name'
|
||||
},
|
||||
{
|
||||
data: 'user',
|
||||
name: 'user.name'
|
||||
},
|
||||
{
|
||||
data: 'identifier'
|
||||
},
|
||||
{
|
||||
data: 'product.name',
|
||||
sortable: false
|
||||
},
|
||||
{
|
||||
data: 'suspended'
|
||||
},
|
||||
{
|
||||
data: 'created_at'
|
||||
},
|
||||
{
|
||||
data: 'actions',
|
||||
sortable: false
|
||||
},
|
||||
],
|
||||
fnDrawCallback: function(oSettings) {
|
||||
$('[data-toggle="popover"]').popover();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1>{{__('Users')}}</h1>
|
||||
<h1>{{ __('Users') }}</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
|
||||
<li class="breadcrumb-item"><a href="{{route('admin.users.index')}}">{{__('Users')}}</a></li>
|
||||
<li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
|
||||
<li class="breadcrumb-item"><a href="{{ route('admin.users.index') }}">{{ __('Users') }}</a></li>
|
||||
<li class="breadcrumb-item"><a class="text-muted"
|
||||
href="{{route('admin.users.show' , $user->id)}}">{{__('Show')}}</a>
|
||||
href="{{ route('admin.users.show', $user->id) }}">{{ __('Show') }}</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
@ -26,18 +26,18 @@
|
|||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
|
||||
@if($user->discordUser)
|
||||
@if ($user->discordUser)
|
||||
<div class="row">
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="small-box bg-dark">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="p-3">
|
||||
<h3>{{$user->discordUser->username}} <sup>{{$user->discordUser->locale}}</sup></h3>
|
||||
<p>{{$user->discordUser->id}}
|
||||
<h3>{{ $user->discordUser->username }} <sup>{{ $user->discordUser->locale }}</sup></h3>
|
||||
<p>{{ $user->discordUser->id }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-3"><img width="100px" height="100px" class="rounded-circle"
|
||||
src="{{$user->discordUser->getAvatar()}}" alt="avatar"></div>
|
||||
src="{{ $user->discordUser->getAvatar() }}" alt="avatar"></div>
|
||||
</div>
|
||||
<div class="small-box-footer">
|
||||
<i class="fab fa-discord mr-1"></i>Discord
|
||||
|
@ -50,7 +50,7 @@
|
|||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fas fa-users mr-2"></i>{{__('Users')}}</h5>
|
||||
<h5 class="card-title"><i class="fas fa-users mr-2"></i>{{ __('Users') }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
|
@ -58,12 +58,12 @@
|
|||
<div class="col-lg-6">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<label>{{__('ID')}}</label>
|
||||
<label>{{ __('ID') }}</label>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{$user->id}}
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{ $user->id }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -71,13 +71,21 @@
|
|||
<div class="col-lg-6">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<label>{{__('Role')}}</label>
|
||||
<label>{{ __('Role') }}</label>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<span style="max-width: 250px;"
|
||||
class="d-inline-block text-truncate badge {{$user->role == 'admin' || $user->role == 'mod' ? 'badge-info' : 'badge-secondary'}}">
|
||||
{{$user->role}}
|
||||
</span>
|
||||
<span style="max-width: 250px;"
|
||||
class="d-inline-block text-truncate badge
|
||||
@if ($user->role == 'admin') badge-danger
|
||||
@elseif ($user->role == 'moderator')
|
||||
badge-info
|
||||
@elseif ($user->role == 'client')
|
||||
badge-success
|
||||
@else
|
||||
badge-secondary @endif
|
||||
">
|
||||
{{ $user->role }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -85,12 +93,12 @@
|
|||
<div class="col-lg-6">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<label>{{__('Pterodactyl ID')}}</label>
|
||||
<label>{{ __('Pterodactyl ID') }}</label>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{$user->pterodactyl_id}}
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{ $user->pterodactyl_id }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -98,12 +106,12 @@
|
|||
<div class="col-lg-6">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<label>{{__('Email')}}</label>
|
||||
<label>{{ __('Email') }}</label>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{$user->email}}
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{ $user->email }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -112,12 +120,12 @@
|
|||
<div class="col-lg-6">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<label>{{__('Server limit')}}</label>
|
||||
<label>{{ __('Server limit') }}</label>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{$user->Servers()->count()}} / {{$user->server_limit}}
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{ $user->Servers()->count() }} / {{ $user->server_limit }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -125,12 +133,12 @@
|
|||
<div class="col-lg-6">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<label>{{__('Name')}}</label>
|
||||
<label>{{ __('Name') }}</label>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{$user->name}}
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{ $user->name }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -138,12 +146,12 @@
|
|||
<div class="col-lg-6">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<label>{{__('Verified')}} {{__('Email')}}</label>
|
||||
<label>{{ __('Verified') }} {{ __('Email') }}</label>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{$user->email_verified_at ? 'True' : 'False'}}
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{ $user->email_verified_at ? 'True' : 'False' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -154,9 +162,9 @@
|
|||
<label>{{ $credits_display_name }}</label>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
<i class="fas fa-coins mr-2"></i>{{$user->Credits()}}
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
<i class="fas fa-coins mr-2"></i>{{ $user->Credits() }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -164,12 +172,12 @@
|
|||
<div class="col-lg-6">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<label>{{__('Verified')}} {{__('Discord')}}</label>
|
||||
<label>{{ __('Verified') }} {{ __('Discord') }}</label>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{$user->discordUser ? 'True' : 'False'}}
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{ $user->discordUser ? 'True' : 'False' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -177,12 +185,12 @@
|
|||
<div class="col-lg-6">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<label>{{__('Usage')}}</label>
|
||||
<label>{{ __('Usage') }}</label>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
<i class="fas fa-coins mr-2"></i>{{$user->CreditUsage()}}
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
<i class="fas fa-coins mr-2"></i>{{ $user->CreditUsage() }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -191,12 +199,12 @@
|
|||
<div class="col-lg-6">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<label>{{__('IP')}}</label>
|
||||
<label>{{ __('IP') }}</label>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{$user->ip}}
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{ $user->ip }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -204,12 +212,12 @@
|
|||
<div class="col-lg-6">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<label>{{__('Created at')}}</label>
|
||||
<label>{{ __('Created at') }}</label>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{$user->created_at->diffForHumans()}}
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
{{ $user->created_at->diffForHumans() }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -220,17 +228,16 @@
|
|||
<div class="col-lg-6">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<label>{{__('Last seen')}}</label>
|
||||
<label>{{ __('Last seen') }}</label>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
@if($user->last_seen)
|
||||
{{$user->last_seen->diffForHumans()}}
|
||||
@else
|
||||
<small
|
||||
class="text-muted">Null</small>
|
||||
@endif
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
@if ($user->last_seen)
|
||||
{{ $user->last_seen->diffForHumans() }}
|
||||
@else
|
||||
<small class="text-muted">Null</small>
|
||||
@endif
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -243,21 +250,21 @@
|
|||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fas fa-server mr-2"></i>{{__('Servers')}}</h5>
|
||||
<h5 class="card-title"><i class="fas fa-server mr-2"></i>{{ __('Servers') }}</h5>
|
||||
</div>
|
||||
<div class="card-body table-responsive">
|
||||
<table id="datatable" class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="20"></th>
|
||||
<th>{{__('Name')}}</th>
|
||||
<th>{{__('User')}}</th>
|
||||
<th>{{__('Server id')}}</th>
|
||||
<th>{{__('Config')}}</th>
|
||||
<th>{{__('Suspended at')}}</th>
|
||||
<th>{{__('Created at')}}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th width="20"></th>
|
||||
<th>{{ __('Name') }}</th>
|
||||
<th>{{ __('User') }}</th>
|
||||
<th>{{ __('Server id') }}</th>
|
||||
<th>{{ __('Config') }}</th>
|
||||
<th>{{ __('Suspended at') }}</th>
|
||||
<th>{{ __('Created at') }}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
|
@ -267,28 +274,28 @@
|
|||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fas fa-user-check mr-2"></i>{{__('Referals')}}
|
||||
({{__("referral-code")}}: {{$user->referral_code}})</h5>
|
||||
<h5 class="card-title"><i class="fas fa-user-check mr-2"></i>{{ __('Referals') }}
|
||||
({{ __('referral-code') }}: {{ $user->referral_code }})</h5>
|
||||
</div>
|
||||
<div class="card-body table-responsive">
|
||||
|
||||
|
||||
@foreach($referrals as $referral)
|
||||
@foreach ($referrals as $referral)
|
||||
<div class="col-lg-6">
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<label>User ID: {{$referral->id}}</label>
|
||||
<label>User ID: {{ $referral->id }}</label>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
<i class="fas fa-user-check mr-2"></i><a
|
||||
href="{{route("admin.users.show",$referral->id)}}">{{$referral->name}}</a>
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
<i class="fas fa-user-check mr-2"></i><a
|
||||
href="{{ route('admin.users.show', $referral->id) }}">{{ $referral->name }}</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
<i class="fas fa-clock mr-2"></i>{{$referral->created_at->diffForHumans()}}
|
||||
</span>
|
||||
<span style="max-width: 250px;" class="d-inline-block text-truncate">
|
||||
<i class="fas fa-clock mr-2"></i>{{ $referral->created_at->diffForHumans() }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -302,11 +309,10 @@
|
|||
</div>
|
||||
</section>
|
||||
<!-- END CONTENT -->
|
||||
|
||||
@endsection
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
$('#datatable').DataTable({
|
||||
language: {
|
||||
url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{ $locale_datatables }}.json'
|
||||
|
@ -314,19 +320,40 @@
|
|||
processing: true,
|
||||
serverSide: true,
|
||||
stateSave: true,
|
||||
ajax: "{{route('admin.servers.datatable')}}?user={{ $user->id }}",
|
||||
order: [[ 5, "desc" ]],
|
||||
columns: [
|
||||
{data: 'status' , name : 'servers.suspended'},
|
||||
{data: 'name'},
|
||||
{data: 'user' , name : 'user.name'},
|
||||
{data: 'identifier'},
|
||||
{data: 'resources' , name : 'product.name'},
|
||||
{data: 'suspended'},
|
||||
{data: 'created_at'},
|
||||
{data: 'actions' , sortable : false},
|
||||
ajax: "{{ route('admin.servers.datatable') }}?user={{ $user->id }}",
|
||||
order: [
|
||||
[5, "desc"]
|
||||
],
|
||||
fnDrawCallback: function( oSettings ) {
|
||||
columns: [{
|
||||
data: 'status',
|
||||
name: 'servers.suspended'
|
||||
},
|
||||
{
|
||||
data: 'name'
|
||||
},
|
||||
{
|
||||
data: 'user',
|
||||
name: 'user.name'
|
||||
},
|
||||
{
|
||||
data: 'identifier'
|
||||
},
|
||||
{
|
||||
data: 'resources',
|
||||
name: 'product.name'
|
||||
},
|
||||
{
|
||||
data: 'suspended'
|
||||
},
|
||||
{
|
||||
data: 'created_at'
|
||||
},
|
||||
{
|
||||
data: 'actions',
|
||||
sortable: false
|
||||
},
|
||||
],
|
||||
fnDrawCallback: function(oSettings) {
|
||||
$('[data-toggle="popover"]').popover();
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue