Several modifications, something already works

This commit is contained in:
Ferks-FK 2023-02-03 16:38:03 +00:00 committed by IceToast
parent 636d4e259e
commit 16ca760901
12 changed files with 328 additions and 212 deletions

View file

@ -2,46 +2,63 @@
namespace App\Classes;
use App\Models\Egg;
use App\Models\Nest;
use App\Models\Node;
use App\Models\Pterodactyl\Egg;
use App\Models\Pterodactyl\Nest;
use App\Models\Pterodactyl\Node;
use App\Models\Product;
use App\Models\Server;
use App\Models\User;
use Exception;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;
use App\Settings\PterodactylSettings;
class Pterodactyl
class PterodactylClient
{
//TODO: Extend error handling (maybe logger for more errors when debugging)
public int $per_page_limit = 200;
public PendingRequest $client;
public PendingRequest $client_admin;
public function __construct(PterodactylSettings $ptero_settings)
{
try {
$this->client = $this->client($ptero_settings);
$this->client_admin = $this->clientAdmin($ptero_settings);
$this->per_page_limit = $ptero_settings->per_page_limit;
}
catch (Exception $exception) {
logger('Failed to construct Pterodactyl client, Settings table not available?', ['exception' => $exception]);
}
}
/**
* @return PendingRequest
*/
public static function client()
public function client(PterodactylSettings $ptero_settings)
{
return Http::withHeaders([
'Authorization' => 'Bearer ' . config('SETTINGS::SYSTEM:PTERODACTYL:TOKEN'),
'Authorization' => 'Bearer ' . $ptero_settings->user_token,
'Content-type' => 'application/json',
'Accept' => 'Application/vnd.pterodactyl.v1+json',
])->baseUrl(config('SETTINGS::SYSTEM:PTERODACTYL:URL') . '/api');
])->baseUrl($ptero_settings->getUrl() . 'api' . '/');
}
public static function clientAdmin()
public function clientAdmin(PterodactylSettings $ptero_settings)
{
return Http::withHeaders([
'Authorization' => 'Bearer ' . config('SETTINGS::SYSTEM:PTERODACTYL:ADMIN_USER_TOKEN'),
'Authorization' => 'Bearer ' . $ptero_settings->admin_token,
'Content-type' => 'application/json',
'Accept' => 'Application/vnd.pterodactyl.v1+json',
])->baseUrl(config('SETTINGS::SYSTEM:PTERODACTYL:URL') . '/api');
])->baseUrl($ptero_settings->getUrl() . 'api' . '/');
}
/**
* @return Exception
*/
private static function getException(string $message = '', int $status = 0): Exception
private function getException(string $message = '', int $status = 0): Exception
{
if ($status == 404) {
return new Exception('Ressource does not exist on pterodactyl - ' . $message, 404);
@ -68,10 +85,10 @@ class Pterodactyl
*
* @throws Exception
*/
public static function getEggs(Nest $nest)
public function getEggs(Nest $nest)
{
try {
$response = self::client()->get("/application/nests/{$nest->id}/eggs?include=nest,variables&per_page=" . config('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT'));
$response = $this->client_admin->get("application/nests/{$nest->id}/eggs?include=nest,variables&per_page=" . $this->per_page_limit);
} catch (Exception $e) {
throw self::getException($e->getMessage());
}
@ -87,10 +104,10 @@ class Pterodactyl
*
* @throws Exception
*/
public static function getNodes()
public function getNodes()
{
try {
$response = self::client()->get('/application/nodes?per_page=' . config('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT'));
$response = $this->client_admin->get('application/nodes?per_page=' . $this->per_page_limit);
} catch (Exception $e) {
throw self::getException($e->getMessage());
}
@ -107,10 +124,10 @@ class Pterodactyl
* @throws Exception
* @description Returns the infos of a single node
*/
public static function getNode($id)
public function getNode($id)
{
try {
$response = self::client()->get('/application/nodes/' . $id);
$response = $this->client_admin->get('application/nodes/' . $id);
} catch (Exception $e) {
throw self::getException($e->getMessage());
}
@ -121,10 +138,10 @@ class Pterodactyl
return $response->json()['attributes'];
}
public static function getServers()
public function getServers()
{
try {
$response = self::client()->get('/application/servers?per_page=' . config('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT'));
$response = $this->client_admin->get('application/servers?per_page=' . $this->per_page_limit);
} catch (Exception $e) {
throw self::getException($e->getMessage());
}
@ -140,10 +157,10 @@ class Pterodactyl
*
* @throws Exception
*/
public static function getNests()
public function getNests()
{
try {
$response = self::client()->get('/application/nests?per_page=' . config('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT'));
$response = $this->client_admin->get('application/nests?per_page=' . $this->per_page_limit);
} catch (Exception $e) {
throw self::getException($e->getMessage());
}
@ -159,10 +176,10 @@ class Pterodactyl
*
* @throws Exception
*/
public static function getLocations()
public function getLocations()
{
try {
$response = self::client()->get('/application/locations?per_page=' . config('SETTINGS::SYSTEM:PTERODACTYL:PER_PAGE_LIMIT'));
$response = $this->client_admin->get('application/locations?per_page=' . $this->per_page_limit);
} catch (Exception $e) {
throw self::getException($e->getMessage());
}
@ -179,7 +196,7 @@ class Pterodactyl
*
* @throws Exception
*/
public static function getFreeAllocationId(Node $node)
public function getFreeAllocationId(Node $node)
{
return self::getFreeAllocations($node)[0]['attributes']['id'] ?? null;
}
@ -190,7 +207,7 @@ class Pterodactyl
*
* @throws Exception
*/
public static function getFreeAllocations(Node $node)
public function getFreeAllocations(Node $node)
{
$response = self::getAllocations($node);
$freeAllocations = [];
@ -214,11 +231,11 @@ class Pterodactyl
*
* @throws Exception
*/
public static function getAllocations(Node $node)
public function getAllocations(Node $node)
{
$per_page = config('SETTINGS::SERVER:ALLOCATION_LIMIT', 200);
try {
$response = self::client()->get("/application/nodes/{$node->id}/allocations?per_page={$per_page}");
$response = $this->client_admin->get("application/nodes/{$node->id}/allocations?per_page={$per_page}");
} catch (Exception $e) {
throw self::getException($e->getMessage());
}
@ -233,7 +250,7 @@ class Pterodactyl
* @param string $route
* @return string
*/
public static function url(string $route): string
public function url(string $route): string
{
return config('SETTINGS::SYSTEM:PTERODACTYL:URL') . $route;
}
@ -244,9 +261,9 @@ class Pterodactyl
* @param int $allocationId
* @return Response
*/
public static function createServer(Server $server, Egg $egg, int $allocationId)
public function createServer(Server $server, Egg $egg, int $allocationId)
{
return self::client()->post('/application/servers', [
return $this->client_admin->post('application/servers', [
'name' => $server->name,
'external_id' => $server->id,
'user' => $server->user->pterodactyl_id,
@ -272,10 +289,10 @@ class Pterodactyl
]);
}
public static function suspendServer(Server $server)
public function suspendServer(Server $server)
{
try {
$response = self::client()->post("/application/servers/$server->pterodactyl_id/suspend");
$response = $this->client_admin->post("application/servers/$server->pterodactyl_id/suspend");
} catch (Exception $e) {
throw self::getException($e->getMessage());
}
@ -286,10 +303,10 @@ class Pterodactyl
return $response;
}
public static function unSuspendServer(Server $server)
public function unSuspendServer(Server $server)
{
try {
$response = self::client()->post("/application/servers/$server->pterodactyl_id/unsuspend");
$response = $this->client_admin->post("application/servers/$server->pterodactyl_id/unsuspend");
} catch (Exception $e) {
throw self::getException($e->getMessage());
}
@ -309,7 +326,7 @@ class Pterodactyl
public function getUser(int $pterodactylId)
{
try {
$response = self::client()->get("/application/users/{$pterodactylId}");
$response = $this->client_admin->get("application/users/{$pterodactylId}");
} catch (Exception $e) {
throw self::getException($e->getMessage());
}
@ -326,10 +343,10 @@ class Pterodactyl
* @param int $pterodactylId
* @return mixed
*/
public static function getServerAttributes(int $pterodactylId, bool $deleteOn404 = false)
public function getServerAttributes(int $pterodactylId, bool $deleteOn404 = false)
{
try {
$response = self::client()->get("/application/servers/{$pterodactylId}?include=egg,node,nest,location");
$response = $this->client_admin->get("application/servers/{$pterodactylId}?include=egg,node,nest,location");
} catch (Exception $e) {
throw self::getException($e->getMessage());
}
@ -356,9 +373,9 @@ class Pterodactyl
* @param Product $product
* @return Response
*/
public static function updateServer(Server $server, Product $product)
public function updateServer(Server $server, Product $product)
{
return self::client()->patch("/application/servers/{$server->pterodactyl_id}/build", [
return $this->client_admin->patch("application/servers/{$server->pterodactyl_id}/build", [
'allocation' => $server->allocation,
'memory' => $product->memory,
'swap' => $product->swap,
@ -381,9 +398,9 @@ class Pterodactyl
* @param Server $server
* @return mixed
*/
public static function updateServerOwner(Server $server, int $userId)
public function updateServerOwner(Server $server, int $userId)
{
return self::client()->patch("/application/servers/{$server->pterodactyl_id}/details", [
return $this->client_admin->patch("application/servers/{$server->pterodactyl_id}/details", [
'name' => $server->name,
'user' => $userId,
]);
@ -396,9 +413,9 @@ class Pterodactyl
* @param string $action
* @return Response
*/
public static function powerAction(Server $server, $action)
public function powerAction(Server $server, $action)
{
return self::clientAdmin()->post("/client/servers/{$server->identifier}/power", [
return $this->client->post("client/servers/{$server->identifier}/power", [
'signal' => $action,
]);
}
@ -406,9 +423,9 @@ class Pterodactyl
/**
* Get info about user
*/
public static function getClientUser()
public function getClientUser()
{
return self::clientAdmin()->get('/client/account');
return $this->client->get('client/account');
}
/**
@ -419,10 +436,10 @@ class Pterodactyl
* @param int $requireDisk
* @return bool
*/
public static function checkNodeResources(Node $node, int $requireMemory, int $requireDisk)
public function checkNodeResources(Node $node, int $requireMemory, int $requireDisk)
{
try {
$response = self::client()->get("/application/nodes/{$node->id}");
$response = $this->client_admin->get("application/nodes/{$node->id}");
} catch (Exception $e) {
throw self::getException($e->getMessage());
}

View file

@ -2,12 +2,13 @@
namespace App\Http\Controllers\Admin;
use App\Classes\Pterodactyl;
use App\Classes\PterodactylClient;
use App\Settings\PterodactylSettings;
use App\Http\Controllers\Controller;
use App\Models\Egg;
use App\Models\Location;
use App\Models\Nest;
use App\Models\Node;
use App\Models\Pterodactyl\Egg;
use App\Models\Pterodactyl\Location;
use App\Models\Pterodactyl\Nest;
use App\Models\Pterodactyl\Node;
use App\Models\Payment;
use App\Models\Product;
use App\Models\Server;
@ -19,8 +20,10 @@ class OverViewController extends Controller
{
public const TTL = 86400;
public function index()
public function index(PterodactylSettings $ptero_settings)
{
//Prepare pterodactyl client
$pterodactyl_client = new PterodactylClient($ptero_settings);
//Get counters
$counters = collect();
//Set basic variables in the collection
@ -134,7 +137,7 @@ class OverViewController extends Controller
//Get node information and prepare collection
$pteroNodeIds = [];
foreach (Pterodactyl::getNodes() as $pteroNode) {
foreach ($pterodactyl_client->getNodes() as $pteroNode) {
array_push($pteroNodeIds, $pteroNode['attributes']['id']);
}
$nodes = collect();
@ -145,7 +148,7 @@ class OverViewController extends Controller
} //Check if node exists on pterodactyl too, if not, skip
$nodes->put($nodeId, collect());
$nodes[$nodeId]->name = $DBnode['name'];
$pteroNode = Pterodactyl::getNode($nodeId);
$pteroNode = $pterodactyl_client->getNode($nodeId);
$nodes[$nodeId]->usagePercent = round(max($pteroNode['allocated_resources']['memory'] / ($pteroNode['memory'] * ($pteroNode['memory_overallocate'] + 100) / 100), $pteroNode['allocated_resources']['disk'] / ($pteroNode['disk'] * ($pteroNode['disk_overallocate'] + 100) / 100)) * 100, 2);
$counters['totalUsagePercent'] += $nodes[$nodeId]->usagePercent;
@ -156,7 +159,7 @@ class OverViewController extends Controller
}
$counters['totalUsagePercent'] = ($DBnodes->count()) ? round($counters['totalUsagePercent'] / $DBnodes->count(), 2) : 0;
foreach (Pterodactyl::getServers() as $server) { //gets all servers from Pterodactyl and calculates total of credit usage for each node separately + total
foreach ($pterodactyl_client->getServers() as $server) { //gets all servers from Pterodactyl and calculates total of credit usage for each node separately + total
$nodeId = $server['attributes']['node'];
if ($CPServer = Server::query()->where('pterodactyl_id', $server['attributes']['id'])->first()) {

View file

@ -11,6 +11,9 @@ use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use App\Settings\GeneralSettings;
use App\Settings\WebsiteSettings;
use App\Settings\ReferralSettings;
class HomeController extends Controller
{
@ -87,7 +90,7 @@ class HomeController extends Controller
}
/** Show the application dashboard. */
public function index(Request $request)
public function index(GeneralSettings $general_settings, WebsiteSettings $website_settings, ReferralSettings $referral_settings)
{
$usage = Auth::user()->creditUsage();
$credits = Auth::user()->Credits();
@ -118,6 +121,9 @@ class HomeController extends Controller
'numberOfReferrals' => DB::table('user_referrals')->where('referral_id', '=', Auth::user()->id)->count(),
'partnerDiscount' => PartnerDiscount::where('user_id', Auth::user()->id)->first(),
'myDiscount' => PartnerDiscount::getDiscount(),
'general_settings' => $general_settings,
'website_settings' => $website_settings,
'referral_settings' => $referral_settings
]);
}
}

View file

@ -1,12 +1,13 @@
<?php
namespace App\Models;
namespace App\Models\Pterodactyl;
use App\Classes\Pterodactyl;
use App\Classes\PterodactylClient;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use App\Models\Pterodactyl\Nest;
class Egg extends Model
{
@ -37,9 +38,9 @@ class Egg extends Model
public static function syncEggs()
{
Nest::syncNests();
Nest::all()->each(function (Nest $nest) {
$eggs = Pterodactyl::getEggs($nest);
$client = app(PterodactylClient::class);
Nest::all()->each(function (Nest $nest) use ($client) {
$eggs = $client->getEggs($nest);
foreach ($eggs as $egg) {
$array = [];

View file

@ -1,8 +1,8 @@
<?php
namespace App\Models;
namespace App\Models\Pterodactyl;
use App\Classes\Pterodactyl;
use App\Classes\PterodactylClient;
use Exception;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
@ -33,7 +33,8 @@ class Location extends Model
*/
public static function syncLocations()
{
$locations = Pterodactyl::getLocations();
$client = app(PterodactylClient::class);
$locations = $client->getLocations();
//map response
$locations = array_map(function ($val) {

View file

@ -1,8 +1,8 @@
<?php
namespace App\Models;
namespace App\Models\Pterodactyl;
use App\Classes\Pterodactyl;
use App\Classes\PterodactylClient;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
@ -32,7 +32,8 @@ class Nest extends Model
public static function syncNests()
{
$nests = Pterodactyl::getNests();
$client = app(PterodactylClient::class);
$nests = $client->getNests();
//map response
$nests = array_map(function ($nest) {

View file

@ -1,8 +1,8 @@
<?php
namespace App\Models;
namespace App\Models\Pterodactyl;
use App\Classes\Pterodactyl;
use App\Classes\PterodactylClient;
use Exception;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
@ -32,7 +32,8 @@ class Node extends Model
public static function syncNodes()
{
Location::syncLocations();
$nodes = Pterodactyl::getNodes();
$client = app(PterodactylClient::class);
$nodes = $client->getNodes();
//map response
$nodes = array_map(function ($node) {

View file

@ -22,4 +22,13 @@ class DiscordSettings extends Settings
{
return 'discord';
}
public static function encrypted(): array
{
return [
'bot_token',
'client_id',
'client_secret'
];
}
}

View file

@ -6,24 +6,43 @@ use Spatie\LaravelSettings\Settings;
class GeneralSettings extends Settings
{
//instead of showing Credits, show something like example 'Emeralds'
public string $credits_display_name;
//url to the main site
public string $main_site;
//check the ip during register for dupes
public bool $register_ip_check;
public string $credits_display_name;
//the initial amount of credits given to the user on register
public float $initial_user_credits;
//the initial amount of credits given to the user on register
public float $initial_server_limit;
//the initial role given to the user on register
public int $initial_server_limit;
public string $recaptcha_site_key;
public string $recaptcha_secret_key;
public bool $recaptcha_enabled;
public string $phpmyadmin_url;
public bool $alert_enabled;
public string $alert_type;
public string $alert_message;
public string $theme;
//public int $initial_user_role; wait for Roles & Permissions PR.
public static function group(): string
{
return 'general';
}
public static function encrypted(): array
{
return [
'recaptcha_site_key',
'recaptcha_secret_key'
];
}
}

View file

@ -28,4 +28,11 @@ class MailSettings extends Settings
{
return 'mail';
}
public static function encrypted(): array
{
return [
'mail_password'
];
}
}

View file

@ -18,4 +18,22 @@ class PterodactylSettings extends Settings
{
return 'pterodactyl';
}
public static function encrypted(): array
{
return [
'admin_token',
'user_token'
];
}
/**
* Get url with ensured ending backslash
*
* @return string
*/
public function getUrl(): string
{
return str_ends_with($this->panel_url, '/') ? $this->panel_url : $this->panel_url . '/';
}
}

View file

@ -18,18 +18,19 @@
</section>
<!-- END CONTENT HEADER -->
@if(!file_exists(base_path()."/install.lock") && Auth::User()->role == "admin")
@if (!file_exists(base_path() . '/install.lock') && Auth::User()->role == 'admin')
<div class="callout callout-danger">
<h4>{{ __('The installer is not locked!') }}</h4>
<p>{{ __('please create a file called "install.lock" in your dashboard Root directory. Otherwise no settings will be loaded!') }}</p>
<a href="/install?step=7"><button class="btn btn-outline-danger">{{__('or click here')}}</button></a>
<p>{{ __('please create a file called "install.lock" in your dashboard Root directory. Otherwise no settings will be loaded!') }}
</p>
<a href="/install?step=7"><button class="btn btn-outline-danger">{{ __('or click here') }}</button></a>
</div>
@endif
@if(config("SETTINGS::SYSTEM:ALERT_ENABLED") && !empty(config("SETTINGS::SYSTEM:ALERT_MESSAGE")))
<div class="alert mt-4 alert-{{config("SETTINGS::SYSTEM:ALERT_TYPE")}}" role="alert">
{!! config("SETTINGS::SYSTEM:ALERT_MESSAGE") !!}
@if ($general_settings->alert_enabled && !empty($general_settings->alert_message))
<div class="alert mt-4 alert-{{ $general_settings->alert_type }}" role="alert">
{!! $general_settings->alert_message !!}
</div>
@endif
<!-- MAIN CONTENT -->
@ -55,7 +56,7 @@
<span class="info-box-icon bg-secondary elevation-1"><i class="fas fa-coins"></i></span>
<div class="info-box-content">
<span class="info-box-text">{{ CREDITS_DISPLAY_NAME }}</span>
<span class="info-box-text">{{ $general_settings->credits_display_name }}</span>
<span class="info-box-number">{{ Auth::user()->Credits() }}</span>
</div>
<!-- /.info-box-content -->
@ -72,7 +73,8 @@
<span class="info-box-icon bg-warning elevation-1"><i class="fas fa-chart-line"></i></span>
<div class="info-box-content">
<span class="info-box-text">{{ CREDITS_DISPLAY_NAME }} {{ __('Usage') }}</span>
<span class="info-box-text">{{ $general_settings->credits_display_name }}
{{ __('Usage') }}</span>
<span class="info-box-number">{{ number_format($usage, 2, '.', '') }}
<sup>{{ __('per month') }}</sup></span>
</div>
@ -82,14 +84,14 @@
</div>
<!-- /.col -->
@if ($credits > 0.01 and $usage > 0)
@if ($credits > 0.01 && $usage > 0)
<div class="col-12 col-sm-6 col-md-3">
<div class="info-box mb-3">
<span class="info-box-icon {{ $bg }} elevation-1">
<i class="fas fa-hourglass-half"></i></span>
<div class="info-box-content">
<span
class="info-box-text">{{ __('Out of Credits in', ['credits' => CREDITS_DISPLAY_NAME]) }}
class="info-box-text">{{ __('Out of Credits in', ['credits' => $general_settings->credits_display_name]) }}
</span>
<span class="info-box-number">{{ $boxText }}<sup>{{ $unit }}</sup></span>
</div>
@ -106,7 +108,7 @@
<div class="row">
<div class="col-md-6">
@if(config("SETTINGS::SYSTEM:MOTD_ENABLED") == "true")
@if ($website_settings->motd_enabled)
<div class="card card-default">
<div class="card-header">
<h3 class="card-title">
@ -116,27 +118,43 @@
</div>
<!-- /.card-header -->
<div class="card-body">
{!! config('SETTINGS::SYSTEM:MOTD_MESSAGE', '') !!}
{!! $website_settings->motd_message !!}
</div>
<!-- /.card-body -->
</div>
@endif
<!-- /.card -->
@if(config("SETTINGS::SYSTEM:USEFULLINKS_ENABLED") == "true")
<div class="card card-default">
<div class="card-header">
<h3 class="card-title">
<i class="fas fa-link mr-2"></i>
{{ __('Useful Links') }}
</h3>
@if ($website_settings->useful_links_enabled)
<div class="card card-default">
<div class="card-header">
<h3 class="card-title">
<i class="fas fa-link mr-2"></i>
{{ __('Useful Links') }}
</h3>
</div>
<!-- /.card-header -->
<div class="card-body">
@foreach ($useful_links as $useful_link)
<div class="alert alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h5>
<a class="alert-link text-decoration-none" target="__blank"
href="{{ $useful_link->link }}">
<i class="{{ $useful_link->icon }} mr-2"></i>{{ $useful_link->title }}
</a>
</h5>
{!! $useful_link->description !!}
</div>
@endforeach
</div>
<!-- /.card-body -->
</div>
<!-- /.card-header -->
<div class="card-body">
@foreach ($useful_links_dashboard as $useful_link)
<div class="alert alert-dismissible">
<button type="button" class="close" data-dismiss="alert"
aria-hidden="true">×</button>
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h5>
<a class="alert-link text-decoration-none" target="__blank"
href="{{ $useful_link->link }}">
@ -148,126 +166,138 @@
@endforeach
</div>
<!-- /.card-body -->
</div>
@endif
<!-- /.card -->
</div>
<!-- /.col -->
@endif
<!-- /.card -->
</div>
<!-- /.col -->
<div class="col-md-6">
<div class="col-md-6">
<div class="card card-default">
<div class="card-header">
<h3 class="card-title">
<i class="fas fa-history mr-2"></i>
{{ __('Activity Logs') }}
</h3>
</div>
<!-- /.card-header -->
<div class="card-body py-0 pb-2">
<ul class="list-group list-group-flush">
@foreach (Auth::user()->actions()->take(8)->orderBy('created_at', 'desc')->get() as $log)
<li class="list-group-item d-flex justify-content-between text-muted">
<span>
@if (str_starts_with($log->description, 'created'))
<small><i class="fas text-success fa-plus mr-2"></i></small>
@elseif(str_starts_with($log->description, 'redeemed'))
<small><i class="fas text-success fa-money-check-alt mr-2"></i></small>
@elseif(str_starts_with($log->description, 'deleted'))
<small><i class="fas text-danger fa-times mr-2"></i></small>
@elseif(str_starts_with($log->description, 'gained'))
<small><i class="fas text-success fa-money-bill mr-2"></i></small>
@elseif(str_starts_with($log->description, 'updated'))
<small><i class="fas text-info fa-pen mr-2"></i></small>
@endif
{{ explode('\\', $log->subject_type)[2] }}
{{ ucfirst($log->description) }}
</span>
<small>
{{ $log->created_at->diffForHumans() }}
</small>
</li>
@endforeach
</ul>
</div>
<!-- /.card-body -->
</div>
<!-- /.card -->
@if ($referral_settings->enabled)
<!--PartnerDiscount::getDiscount()--->
<div class="card card-default">
<div class="card-header">
<h3 class="card-title">
<i class="fas fa-history mr-2"></i>
{{ __('Activity Logs') }}
<i class="fas fa-handshake mr-2"></i>
{{ __('Partner program') }}
</h3>
</div>
<!-- /.card-header -->
<div class="card-body py-0 pb-2">
<ul class="list-group list-group-flush">
@foreach (Auth::user()->actions()->take(8)->orderBy('created_at', 'desc')->get() as $log)
<li class="list-group-item d-flex justify-content-between text-muted">
<span>
@if(str_starts_with($log->description,"created"))
<small><i class="fas text-success fa-plus mr-2"></i></small>
@elseif(str_starts_with($log->description,"redeemed"))
<small><i class="fas text-success fa-money-check-alt mr-2"></i></small>
@elseif(str_starts_with($log->description,"deleted"))
<small><i class="fas text-danger fa-times mr-2"></i></small>
@elseif(str_starts_with($log->description,"gained"))
<small><i class="fas text-success fa-money-bill mr-2"></i></small>
@elseif(str_starts_with($log->description,"updated"))
<small><i class="fas text-info fa-pen mr-2"></i></small>
@endif
{{ explode('\\', $log->subject_type)[2] }}
{{ ucfirst($log->description) }}
@if (
($referral_settings->allowed == 'client' && Auth::user()->role != 'member') ||
$referral_settings->allowed == 'everyone')
<div class="row">
<div class="mt-3 col-md-8">
<span class="badge badge-success" style="font-size: 14px">
<i class="fa fa-user-check mr-2"></i>
{{ __('Your referral URL') }}:
<span onmouseover="hoverIn()" onmouseout="hoverOut()" onclick="onClickCopy()"
id="RefLink" style="cursor: pointer;">
{{ __('Click to copy') }}
</span>
</span>
<small>
{{ $log->created_at->diffForHumans() }}
</small>
</li>
@endforeach
</ul>
</div>
<div class="mt-3 col-md-4">
<span class="badge badge-info"
style="font-size: 14px">{{ __('Number of referred users:') }}
{{ $numberOfReferrals }}</span>
</div>
</div>
@if ($partnerDiscount)
<hr
style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-bottom: 0px">
<table class="table">
<thead>
<tr>
<th>{{ __('Your discount') }}</th>
<th>{{ __('Discount for your new users') }}</th>
<th>{{ __('Reward per registered user') }}</th>
<th>{{ __('New user payment commision') }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ $partnerDiscount->partner_discount }}%</td>
<td>{{ $partnerDiscount->registered_user_discount }}%</td>
<td>{{ $referral_settings->reward }}
{{ $general_settings->credits_display_name }}</td>
<td>{{ $partnerDiscount->referral_system_commission == -1 ? $referral_settings->percentage : $partnerDiscount->referral_system_commission }}%
</td>
</tr>
</tbody>
</table>
<hr
style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-top: 0px">
@else
<hr
style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-bottom: 0px">
<table class="table">
<thead>
<tr>
<th>{{ __('Reward per registered user') }}</th>
<th>{{ __('New user payment commision') }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ $referral_settings->reward }}
{{ $general_settings->credits_display_name }}</td>
<td>{{ $referral_settings->percentage }}%</td>
</tr>
</tbody>
</table>
<hr
style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-top: 0px">
@endif
@else
<span class="badge badge-warning"><i class="fa fa-user-check mr-2"></i>
{{ __('Make a purchase to reveal your referral-URL') }}</span>
@endif
</div>
<!-- /.card-body -->
</div>
<!-- /.card -->
@if((config('SETTINGS::REFERRAL::ENABLED') ==true))<!--PartnerDiscount::getDiscount()--->
<div class="card card-default">
<div class="card-header">
<h3 class="card-title">
<i class="fas fa-handshake mr-2"></i>
{{ __('Partner program') }}
</h3>
</div>
<!-- /.card-header -->
<div class="card-body py-0 pb-2">
@if((config('SETTINGS::REFERRAL::ALLOWED') == "client" && Auth::user()->role != "member") || config('SETTINGS::REFERRAL::ALLOWED') == "everyone")
<div class="row">
<div class="mt-3 col-md-8">
<span class="badge badge-success" style="font-size: 14px">
<i class="fa fa-user-check mr-2"></i>
{{__("Your referral URL")}}:
<span onmouseover="hoverIn()" onmouseout="hoverOut()" onclick="onClickCopy()" id="RefLink" style="cursor: pointer;">
{{__('Click to copy')}}
</span>
</span>
</div>
<div class="mt-3 col-md-4">
<span class="badge badge-info" style="font-size: 14px">{{__("Number of referred users:")}} {{$numberOfReferrals}}</span>
</div>
</div>
@if($partnerDiscount)
<hr style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-bottom: 0px">
<table class="table">
<thead>
<tr>
<th>{{__('Your discount')}}</th>
<th>{{__('Discount for your new users')}}</th>
<th>{{__('Reward per registered user')}}</th>
<th>{{__('New user payment commision')}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{$partnerDiscount->partner_discount}}%</td>
<td>{{$partnerDiscount->registered_user_discount}}%</td>
<td>{{config('SETTINGS::REFERRAL::REWARD')}} {{config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME')}}</td>
<td>{{($partnerDiscount->referral_system_commission==-1)?config('SETTINGS::REFERRAL:PERCENTAGE'):($partnerDiscount->referral_system_commission)}}%</td>
</tr>
</tbody>
</table>
<hr style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-top: 0px">
@else
<hr style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-bottom: 0px">
<table class="table">
<thead>
<tr>
<th>{{__('Reward per registered user')}}</th>
<th>{{__('New user payment commision')}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{config('SETTINGS::REFERRAL::REWARD')}} {{config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME')}}</td>
<td>{{config('SETTINGS::REFERRAL:PERCENTAGE')}}%</td>
</tr>
</tbody>
</table>
<hr style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-top: 0px">
@endif
@else
<span class="badge badge-warning"><i
class="fa fa-user-check mr-2"></i>
{{__("Make a purchase to reveal your referral-URL")}}</span>
@endif
</div>
<!-- /.card-body -->
</div>
@endif
<!-- /.card -->
</div>
<!-- /.col -->
@endif
<!-- /.card -->
</div>
<!-- /.col -->
</div>
<!-- END CUSTOM CONTENT -->
@ -276,24 +306,27 @@
<!-- END CONTENT -->
<script>
var originalText = document.getElementById('RefLink').innerText;
var link = "<?php echo ((route("register")) . '?ref=' . (Auth::user()->referral_code));?>";
var link = "<?php echo route('register') . '?ref=' . Auth::user()->referral_code; ?>";
var timeoutID;
function hoverIn() {
document.getElementById('RefLink').innerText = link;
timeoutID = setTimeout(function() {
document.getElementById('RefLink').innerText = originalText;
}, 2000);
}
function hoverOut() {
document.getElementById('RefLink').innerText = originalText;
clearTimeout(timeoutID);
}
function onClickCopy() {
if(navigator.clipboard) {
if (navigator.clipboard) {
navigator.clipboard.writeText(link).then(() => {
Swal.fire({
icon: 'success',
title: '{{ __("URL copied to clipboard")}}',
title: '{{ __('URL copied to clipboard') }}',
position: 'top-middle',
showConfirmButton: false,
background: '#343a40',