Merge pull request #372 from ControlPanel-gg/settings_rewrite

Settings rewrite
This commit is contained in:
Dennis 2022-01-23 16:03:13 +01:00 committed by GitHub
commit 4ad5722e9c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
63 changed files with 2281 additions and 1402 deletions

View file

@ -8,18 +8,6 @@ APP_URL=http://localhost
APP_TIMEZONE=UTC APP_TIMEZONE=UTC
### --- App Settings End --- ### ### --- App Settings End --- ###
### --- Localization settings --- ###
# If set to true, Language is chosen automatically depending on the users browserlanguage.
DYNAMIC_LOCALE = false
# The language of the Dashboard. This is also the fallback if dynamic_locale is true but no translation is found
LOCALE=en
# You can grab the Language-Codes for the Datatables from this Website https://datatables.net/plug-ins/i18n/
DATATABLE_LOCALE=en-gb
#The languages you DO NOT want to support on your Controlpanel split by comma.
#Remove the language to make it available
UNSUPPORTED_LOCALES=german,italian,chinese
### --- Localization settings End --- ###
### --- DB Settings (required) --- ### ### --- DB Settings (required) --- ###
DB_CONNECTION=mysql DB_CONNECTION=mysql
DB_HOST=127.0.0.1 DB_HOST=127.0.0.1
@ -29,42 +17,6 @@ DB_USERNAME=dashboarduser
DB_PASSWORD= DB_PASSWORD=
### --- DB Settings End --- ### ### --- DB Settings End --- ###
### --- Payment Options (required for payments) --- ###
# Paypal API Credentials - https://developer.paypal.com/docs/integration/direct/rest/ - Sandbox credentials are being used when APP_ENV is set to local
PAYPAL_SANDBOX_SECRET=
PAYPAL_SANDBOX_CLIENT_ID=
PAYPAL_SECRET=
PAYPAL_CLIENT_ID=
# Stripe API Credentials - https://dashboard.stripe.com/account/apikeys - Test credentials are being used when APP_ENV is set to local
STRIPE_TEST_SECRET=
STRIPE_SECRET=
#https://dashboard.stripe.com/webhooks -> webhook route: <your.controlpanel.gg>/payment/StripeWebhooks
STRIPE_ENDPOINT_TEST_SECRET=
STRIPE_ENDPOINT_SECRET=
# Stripe payment methods - comma seperated list of payment methods that are enabled https://stripe.com/docs/payments/payment-methods/integration-options
STRIPE_METHODS=
### --- Payment Options End --- ###
### --- Discord Settings (optional) --- ###
# Discord API Credentials - https://discordapp.com/developers/applications/
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
# Bot Settings - will join users to your discord
DISCORD_BOT_TOKEN=
DISCORD_GUILD_ID=
# Discord role that will be assigned to users when they register
DISCORD_ROLE_ID=
### --- Discord Settings End --- ###
### --- Controlpanel Settings (required) --- ###
# Controlpanel URL Settings - URLs must not end with a slash!
PTERODACTYL_URL=https://panel.controlpanel.gg # required
PHPMYADMIN_URL=https://mysql.controlpanel.gg #optional. remove to remove database button
DISCORD_INVITE_URL=https://discord.gg/vrUYdxG4wZ #optional
# Admin API Token from Pterodactyl Panel - Nececary for the Panel to work
PTERODACTYL_TOKEN=
### --- Controlpanel Settings End --- ###
# Google Recaptcha API Credentials - https://www.google.com/recaptcha/admin - reCaptcha V2 (not v3) # Google Recaptcha API Credentials - https://www.google.com/recaptcha/admin - reCaptcha V2 (not v3)
RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI

View file

@ -2,11 +2,11 @@
namespace App\Classes; namespace App\Classes;
use App\Models\Configuration;
use App\Models\Egg; use App\Models\Egg;
use App\Models\Nest; use App\Models\Nest;
use App\Models\Node; use App\Models\Node;
use App\Models\Server; use App\Models\Server;
use App\Models\Settings;
use Exception; use Exception;
use Illuminate\Http\Client\PendingRequest; use Illuminate\Http\Client\PendingRequest;
use Illuminate\Http\Client\Response; use Illuminate\Http\Client\Response;
@ -27,10 +27,10 @@ class Pterodactyl
public static function client() public static function client()
{ {
return Http::withHeaders([ return Http::withHeaders([
'Authorization' => 'Bearer ' . env('PTERODACTYL_TOKEN', false), 'Authorization' => 'Bearer ' . config("SETTINGS::SYSTEM:PTERODACTYL:TOKEN"),
'Content-type' => 'application/json', 'Content-type' => 'application/json',
'Accept' => 'Application/vnd.pterodactyl.v1+json', 'Accept' => 'Application/vnd.pterodactyl.v1+json',
])->baseUrl(env('PTERODACTYL_URL') . '/api'); ])->baseUrl(config("SETTINGS::SYSTEM:PTERODACTYL:URL") . '/api');
} }
/** /**
@ -141,7 +141,7 @@ class Pterodactyl
*/ */
public static function getAllocations(Node $node) public static function getAllocations(Node $node)
{ {
$per_page = Configuration::getValueByKey('ALLOCATION_LIMIT', 200); $per_page = config('SETTINGS::SERVER:ALLOCATION_LIMIT', 200);
try { try {
$response = self::client()->get("/application/nodes/{$node->id}/allocations?per_page={$per_page}"); $response = self::client()->get("/application/nodes/{$node->id}/allocations?per_page={$per_page}");
} catch (Exception $e) { } catch (Exception $e) {
@ -158,7 +158,7 @@ class Pterodactyl
*/ */
public static function url(string $route): string public static function url(string $route): string
{ {
return env('PTERODACTYL_URL') . $route; return config("SETTINGS::SYSTEM:PTERODACTYL:URL") . $route;
} }
/** /**

View file

@ -0,0 +1,50 @@
<?php
namespace App\Classes\Settings;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
class Invoices
{
public function __construct()
{
return;
}
public function updateSettings(Request $request)
{
$request->validate([
'logo' => 'nullable|max:10000|mimes:jpg,png,jpeg',
]);
$values = [
//SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
"SETTINGS::INVOICE:COMPANY_NAME" => "company-name",
"SETTINGS::INVOICE:COMPANY_ADDRESS" => "company-address",
"SETTINGS::INVOICE:COMPANY_PHONE" => "company-phone",
"SETTINGS::INVOICE:COMPANY_MAIL" => "company-mail",
"SETTINGS::INVOICE:COMPANY_VAT" => "company-vat",
"SETTINGS::INVOICE:COMPANY_WEBSITE" => "company-web",
"SETTINGS::INVOICE:PREFIX" => "invoice-prefix",
"SETTINGS::INVOICE:ENABLED" => "enable-invoices",
];
foreach ($values as $key => $value) {
$param = $request->get($value);
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
Cache::forget("setting" . ':' . $key);
}
if ($request->hasFile('logo')) {
$request->file('logo')->storeAs('public', 'logo.png');
}
return redirect(route('admin.settings.index') . '#invoices')->with('success', __('Invoice settings updated!'));
}
}

View file

@ -0,0 +1,61 @@
<?php
namespace App\Classes\Settings;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class Language
{
public function __construct()
{
return;
}
public function updateSettings(Request $request)
{
$validator = Validator::make($request->all(), [
'autotranslate' => 'string',
'canClientChangeLanguage' => 'string',
'defaultLanguage' => 'required|string',
'languages' => 'required|array',
'languages.*' => 'required|string',
'datatable-language' => 'required|string',
]);
if ($validator->fails()) {
return redirect(route('admin.settings.index') . '#language')->with('error', __('Language settings have not been updated!'))->withErrors($validator);
}
$values = [
//SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
"SETTINGS::LOCALE:DEFAULT" => "defaultLanguage",
"SETTINGS::LOCALE:DYNAMIC" => "autotranslate",
"SETTINGS::LOCALE:CLIENTS_CAN_CHANGE" => "canClientChangeLanguage",
"SETTINGS::LOCALE:AVAILABLE" => "languages",
"SETTINGS::LOCALE:DATATABLES" => "datatable-language"
];
foreach ($values as $key => $value) {
$param = $request->get($value);
if (is_array($param)) {
$param = implode(",", $param);
}
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
Cache::forget("setting" . ':' . $key);
Session::remove("locale");
}
return redirect(route('admin.settings.index') . '#language')->with('success', __('Language settings updated!'));
}
}

View file

@ -0,0 +1,85 @@
<?php
namespace App\Classes\Settings;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Validator;
class Misc
{
public function __construct()
{
return;
}
public function updateSettings(Request $request)
{
$validator = Validator::make($request->all(), [
'icon' => 'nullable|max:10000|mimes:jpg,png,jpeg',
'favicon' => 'nullable|max:10000|mimes:ico',
'discord-bot-token' => 'nullable|string',
'discord-client-id' => 'nullable|string',
'discord-client-secret' => 'nullable|string',
'discord-guild-id' => 'nullable|string',
'discord-invite-url' => 'nullable|string',
'discord-role-id' => 'nullable|string',
'recaptcha-site-key' => 'nullable|string',
'recaptcha-secret-key' => 'nullable|string',
'enable-recaptcha' => 'nullable|string',
'mailservice' => 'nullable|string',
'mailhost' => 'nullable|string',
'mailport' => 'nullable|string',
'mailusername' => 'nullable|string',
'mailpassword' => 'nullable|string',
'mailencryption' => 'nullable|string',
'mailfromadress' => 'nullable|string',
'mailfromname' => 'nullable|string',
]);
if ($validator->fails()) {
return redirect(route('admin.settings.index') . '#misc')->with('error', __('Misc settings have not been updated!'))->withErrors($validator)
->withInput();
}
if ($request->hasFile('icon')) {
$request->file('icon')->storeAs('public', 'icon.png');
}
if ($request->hasFile('favicon')) {
$request->file('favicon')->storeAs('public', 'favicon.ico');
}
$values = [
"SETTINGS::DISCORD:BOT_TOKEN" => "discord-bot-token",
"SETTINGS::DISCORD:CLIENT_ID" => "discord-client-id",
"SETTINGS::DISCORD:CLIENT_SECRET" => "discord-client-secret",
"SETTINGS::DISCORD:GUILD_ID" => "discord-guild-id",
"SETTINGS::DISCORD:INVITE_URL" => "discord-invite-url",
"SETTINGS::DISCORD:ROLE_ID" => "discord-role-id",
"SETTINGS::RECAPTCHA:SITE_KEY" => "recaptcha-site-key",
"SETTINGS::RECAPTCHA:SECRET_KEY" => "recaptcha-secret-key",
"SETTINGS::RECAPTCHA:ENABLED" => "enable-recaptcha",
"SETTINGS::MAIL:MAILER" => "mailservice",
"SETTINGS::MAIL:HOST" => "mailhost",
"SETTINGS::MAIL:PORT" => "mailport",
"SETTINGS::MAIL:USERNAME" => "mailusername",
"SETTINGS::MAIL:PASSWORD" => "mailpassword",
"SETTINGS::MAIL:ENCRYPTION" => "mailencryption",
"SETTINGS::MAIL:FROM_ADDRESS" => "mailfromadress",
"SETTINGS::MAIL:FROM_NAME" => "mailfromname",
];
foreach ($values as $key => $value) {
$param = $request->get($value);
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
Cache::forget("setting" . ':' . $key);
}
return redirect(route('admin.settings.index') . '#misc')->with('success', __('Misc settings updated!'));
}
}

View file

@ -0,0 +1,61 @@
<?php
namespace App\Classes\Settings;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Validator;
class Payments
{
public function __construct()
{
return;
}
public function updateSettings(Request $request)
{
$validator = Validator::make($request->all(), [
"paypal-client_id" => "nullable|string",
"paypal-client-secret" => "nullable|string",
"paypal-sandbox-secret" => "nullable|string",
"stripe-secret-key" => "nullable|string",
"stripe-endpoint-secret" => "nullable|string",
"stripe-test-secret-key" => "nullable|string",
"stripe-test-endpoint-secret" => "nullable|string",
"stripe-methods" => "nullable|string",
"sales-tax" => "nullable|numeric",
]);
if ($validator->fails()) {
return redirect(route('admin.settings.index') . '#payment')->with('error', __('Payment settings have not been updated!'))->withErrors($validator)
->withInput();
}
$values = [
//SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
"SETTINGS::PAYMENTS:PAYPAL:SECRET" => "paypal-client-secret",
"SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID" => "paypal-client-id",
"SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET" => "paypal-sandbox-secret",
"SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID" => "paypal-sandbox-id",
"SETTINGS::PAYMENTS:STRIPE:SECRET" => "stripe-secret",
"SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET" => "stripe-endpoint-secret",
"SETTINGS::PAYMENTS:STRIPE:TEST_SECRET" => "stripe-test-secret",
"SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET" => "stripe-endpoint-test-secret",
"SETTINGS::PAYMENTS:STRIPE:METHODS" => "stripe-methods",
"SETTINGS::PAYMENTS:SALES_TAX" => "sales-tax"
];
foreach ($values as $key => $value) {
$param = $request->get($value);
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
Cache::forget("setting" . ':' . $key);
}
return redirect(route('admin.settings.index') . '#payment')->with('success', __('Payment settings updated!'));
}
}

View file

@ -0,0 +1,73 @@
<?php
namespace App\Classes\Settings;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Validator;
class System
{
public function __construct()
{
return;
}
public function updateSettings(Request $request)
{
$validator = Validator::make($request->all(), [
"register-ip-check" => "string",
"server-create-charge-first-hour" => "string",
"credits-display-name" => "required|string",
"allocation-limit" => "required|min:0|integer",
"force-email-verification" => "string",
"force-discord-verification" => "string",
"initial-credits" => "required|min:0|integer",
"initial-server-limit" => "required|min:0|integer",
"credits-reward-amount-discord" => "required|min:0|integer",
"credits-reward-amount-email" => "required|min:0|integer",
"server-limit-discord" => "required|min:0|integer",
"server-limit-email" => "required|min:0|integer",
"pterodactyl-api-key" => "required|string",
"pterodactyl-url" => "required|string",
]);
if ($validator->fails()) {
return redirect(route('admin.settings.index') . '#system')->with('error', __('System settings have not been updated!'))->withErrors($validator)
->withInput();
}
$values = [
"SETTINGS::SYSTEM:REGISTER_IP_CHECK" => "register-ip-check",
"SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR" => "server-create-charge-first-hour",
"SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME" => "credits-display-name",
"SETTINGS::SERVER:ALLOCATION_LIMIT" => "allocation-limit",
"SETTINGS::USER:FORCE_DISCORD_VERIFICATION" => "force-discord-verification",
"SETTINGS::USER:FORCE_EMAIL_VERIFICATION" => "force-email-verification",
"SETTINGS::USER:INITIAL_CREDITS" => "initial-credits",
"SETTINGS::USER:INITIAL_SERVER_LIMIT" => "initial-server-limit",
"SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD" => "credits-reward-amount-discord",
"SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL" => "credits-reward-amount-email",
"SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD" => "server-limit-discord",
"SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL" => "server-limit-email",
"SETTINGS::MISC:PHPMYADMIN:URL" => "phpmyadmin-url",
"SETTINGS::SYSTEM:PTERODACTYL:URL" => "pterodactyl-url",
"SETTINGS::SYSTEM:PTERODACTYL:TOKEN" => "pterodactyl-api-key",
];
foreach ($values as $key => $value) {
$param = $request->get($value);
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
Cache::forget("setting" . ':' . $key);
}
return redirect(route('admin.settings.index') . '#system')->with('success', __('System settings updated!'));
}
}

View file

@ -1,123 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Configuration;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class ConfigurationController extends Controller
{
/**
* Display a listing of the resource.
*
* @return Application|Factory|View|Response
*/
public function index()
{
return view('admin.configurations.index');
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* @param Configuration $configuration
* @return Response
*/
public function show(Configuration $configuration)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param Configuration $configuration
* @return Response
*/
public function edit(Configuration $configuration)
{
//
}
/**
* Update the specified resource in storage.
*
* @param Request $request
* @param Configuration $configuration
* @return Response
*/
public function update(Request $request, Configuration $configuration)
{
//
}
/**
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function updatevalue(Request $request)
{
$configuration = Configuration::findOrFail($request->input('key'));
$request->validate([
'key' => 'required|string|max:191',
'value' => 'required|string|max:191',
]);
$configuration->update($request->all());
return redirect()->route('admin.configurations.index')->with('success', __('configuration has been updated!'));
}
/**
* Remove the specified resource from storage.
*
* @param Configuration $configuration
* @return Response
*/
public function destroy(Configuration $configuration)
{
//
}
public function datatable()
{
$query = Configuration::query();
return datatables($query)
->addColumn('actions', function (Configuration $configuration) {
return '<button data-content="'.__("Edit").'" data-toggle="popover" data-trigger="hover" data-placement="top" onclick="configuration.parse(\'' . $configuration->key . '\',\'' . $configuration->value . '\',\'' . $configuration->type . '\')" data-content="Edit" data-trigger="hover" data-toggle="tooltip" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></button> ';
})
->editColumn('created_at', function (Configuration $configuration) {
return $configuration->created_at ? $configuration->created_at->diffForHumans() : '';
})
->rawColumns(['actions'])
->make();
}
}

View file

@ -3,6 +3,7 @@
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin;
use App\Models\CreditProduct; use App\Models\CreditProduct;
use App\Models\Settings;
use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
@ -25,8 +26,8 @@ class CreditProductController extends Controller
if ( if (
env('APP_ENV') == 'local' || env('APP_ENV') == 'local' ||
env('PAYPAL_SECRET') && env('PAYPAL_CLIENT_ID') || Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:SECRET") && Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID") ||
env('STRIPE_SECRET') && env('STRIPE_ENDPOINT_SECRET') && env('STRIPE_METHODS') Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:SECRET") && Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET") && Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:METHODS")
) $isPaymentSetup = true; ) $isPaymentSetup = true;
return view('admin.store.index', [ return view('admin.store.index', [

View file

@ -0,0 +1,70 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Invoice;
use Illuminate\Http\Request;
use Throwable;
use ZipArchive;
class InvoiceController extends Controller
{
public function downloadAllInvoices()
{
$zip = new ZipArchive;
$zip_safe_path = storage_path('invoices.zip');
$res = $zip->open($zip_safe_path, ZipArchive::CREATE | ZipArchive::OVERWRITE);
$result = $dthis::rglob(storage_path('app/invoice/*'));
if ($res === TRUE) {
$zip->addFromString("1. Info.txt", __("Created at") . " " . now()->format("d.m.Y"));
foreach ($result as $file) {
if (file_exists($file) && is_file($file)) {
$zip->addFile($file, basename($file));
}
}
$zip->close();
}
return response()->download($zip_safe_path);
}
/**
* @param $pattern
* @param $flags
* @return array|false
*/
public function rglob($pattern, $flags = 0)
{
$files = glob($pattern, $flags);
foreach (glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
$files = array_merge($files, $this::rglob($dir . '/' . basename($pattern), $flags));
}
return $files;
}
/**
* @param $paymentID
* @param $date
*/
public function downloadSingleInvoice(Request $request)
{
$id = $request->id;
try {
$query = Invoice::where('payment_id', '=', $id)->firstOrFail();
} catch (Throwable $e) {
return redirect()->back()->with("error", __("Error!"));
}
$invoice_path = storage_path('app/invoice/' . $query->invoice_user . '/' . $query->created_at->format("Y") . '/' . $query->invoice_name . '.pdf');
if (!file_exists($invoice_path)) {
return redirect()->back()->with("error", __("Error!"));
}
return response()->download($invoice_path);
}
}

View file

@ -4,10 +4,10 @@ namespace App\Http\Controllers\Admin;
use App\Events\UserUpdateCreditsEvent; use App\Events\UserUpdateCreditsEvent;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Configuration;
use App\Models\InvoiceSettings; use App\Models\InvoiceSettings;
use App\Models\Payment; use App\Models\Payment;
use App\Models\CreditProduct; use App\Models\CreditProduct;
use App\Models\Settings;
use App\Models\User; use App\Models\User;
use App\Notifications\InvoiceNotification; use App\Notifications\InvoiceNotification;
use App\Notifications\ConfirmPaymentNotification; use App\Notifications\ConfirmPaymentNotification;
@ -134,7 +134,7 @@ class PaymentController extends Controller
*/ */
protected function getPaypalClientId() protected function getPaypalClientId()
{ {
return env('APP_ENV') == 'local' ? env('PAYPAL_SANDBOX_CLIENT_ID') : env('PAYPAL_CLIENT_ID'); return env('APP_ENV') == 'local' ? Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID") : Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID");
} }
/** /**
@ -142,7 +142,7 @@ class PaymentController extends Controller
*/ */
protected function getPaypalClientSecret() protected function getPaypalClientSecret()
{ {
return env('APP_ENV') == 'local' ? env('PAYPAL_SANDBOX_SECRET') : env('PAYPAL_SECRET'); return env('APP_ENV') == 'local' ? Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET") : Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:SECRET");
} }
/** /**
@ -167,9 +167,9 @@ class PaymentController extends Controller
$user->increment('credits', $creditProduct->quantity); $user->increment('credits', $creditProduct->quantity);
//update server limit //update server limit
if (Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) { if (Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) {
if ($user->server_limit < Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE')) { if ($user->server_limit < Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')) {
$user->update(['server_limit' => Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE')]); $user->update(['server_limit' => Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')]);
} }
} }
@ -197,7 +197,11 @@ class PaymentController extends Controller
event(new UserUpdateCreditsEvent($user)); event(new UserUpdateCreditsEvent($user));
$this->createInvoice($user, $payment, 'paid'); //only create invoice if SETTINGS::INVOICE:ENABLED is true
if (config('SETTINGS::INVOICE:ENABLED') == 'true') {
$this->createInvoice($user, $payment, 'paid');
}
//redirect back to home //redirect back to home
return redirect()->route('home')->with('success', __('Your credit balance has been increased!')); return redirect()->route('home')->with('success', __('Your credit balance has been increased!'));
@ -266,7 +270,7 @@ class PaymentController extends Controller
], ],
'mode' => 'payment', 'mode' => 'payment',
"payment_method_types" => str_getcsv(str_replace(' ', '', env('STRIPE_METHODS'))), "payment_method_types" => str_getcsv(config("SETTINGS::PAYMENTS:STRIPE:METHODS")),
'success_url' => route('payment.StripeSuccess', ['product' => $creditProduct->id]) . '&session_id={CHECKOUT_SESSION_ID}', 'success_url' => route('payment.StripeSuccess', ['product' => $creditProduct->id]) . '&session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => route('payment.Cancel'), 'cancel_url' => route('payment.Cancel'),
]); ]);
@ -304,9 +308,9 @@ class PaymentController extends Controller
$user->increment('credits', $creditProduct->quantity); $user->increment('credits', $creditProduct->quantity);
//update server limit //update server limit
if (Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) { if (Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) {
if ($user->server_limit < Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE')) { if ($user->server_limit < Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')) {
$user->update(['server_limit' => Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE')]); $user->update(['server_limit' => Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')]);
} }
} }
@ -336,7 +340,10 @@ class PaymentController extends Controller
event(new UserUpdateCreditsEvent($user)); event(new UserUpdateCreditsEvent($user));
$this->createInvoice($user, $payment, 'paid'); //only create invoice if SETTINGS::INVOICE:ENABLED is true
if (config('SETTINGS::INVOICE:ENABLED') == 'true') {
$this->createInvoice($user, $payment, 'paid');
}
//redirect back to home //redirect back to home
return redirect()->route('home')->with('success', __('Your credit balance has been increased!')); return redirect()->route('home')->with('success', __('Your credit balance has been increased!'));
@ -359,7 +366,10 @@ class PaymentController extends Controller
'credit_product_id' => $creditProduct->id, 'credit_product_id' => $creditProduct->id,
]); ]);
$this->createInvoice($user, $payment, 'processing'); //only create invoice if SETTINGS::INVOICE:ENABLED is true
if (config('SETTINGS::INVOICE:ENABLED') == 'true') {
$this->createInvoice($user, $payment, 'paid');
}
//redirect back to home //redirect back to home
return redirect()->route('home')->with('success', __('Your payment is being processed!')); return redirect()->route('home')->with('success', __('Your payment is being processed!'));
@ -398,9 +408,9 @@ class PaymentController extends Controller
$user->increment('credits', $payment->amount); $user->increment('credits', $payment->amount);
//update server limit //update server limit
if (Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) { if (Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) {
if ($user->server_limit < Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE')) { if ($user->server_limit < Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')) {
$user->update(['server_limit' => Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE')]); $user->update(['server_limit' => Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')]);
} }
} }
@ -416,7 +426,10 @@ class PaymentController extends Controller
$user->notify(new ConfirmPaymentNotification($payment)); $user->notify(new ConfirmPaymentNotification($payment));
event(new UserUpdateCreditsEvent($user)); event(new UserUpdateCreditsEvent($user));
$this->createInvoice($user, $payment, 'paid'); //only create invoice if SETTINGS::INVOICE:ENABLED is true
if (config('SETTINGS::INVOICE:ENABLED') == 'true') {
$this->createInvoice($user, $payment, 'paid');
}
} }
} catch (HttpException $ex) { } catch (HttpException $ex) {
abort(422); abort(422);
@ -474,8 +487,8 @@ class PaymentController extends Controller
protected function getStripeSecret() protected function getStripeSecret()
{ {
return env('APP_ENV') == 'local' return env('APP_ENV') == 'local'
? env('STRIPE_TEST_SECRET') ? Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:TEST_SECRET")
: env('STRIPE_SECRET'); : Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:SECRET");
} }
/** /**
@ -484,8 +497,8 @@ class PaymentController extends Controller
protected function getStripeEndpointSecret() protected function getStripeEndpointSecret()
{ {
return env('APP_ENV') == 'local' return env('APP_ENV') == 'local'
? env('STRIPE_ENDPOINT_TEST_SECRET') ? Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET")
: env('STRIPE_ENDPOINT_SECRET'); : Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET");
} }
@ -495,17 +508,16 @@ class PaymentController extends Controller
//create invoice //create invoice
$lastInvoiceID = \App\Models\Invoice::where("invoice_name", "like", "%" . now()->format('mY') . "%")->count("id"); $lastInvoiceID = \App\Models\Invoice::where("invoice_name", "like", "%" . now()->format('mY') . "%")->count("id");
$newInvoiceID = $lastInvoiceID + 1; $newInvoiceID = $lastInvoiceID + 1;
$InvoiceSettings = InvoiceSettings::query()->first();
$logoPath = storage_path('app/public/logo.png'); $logoPath = storage_path('app/public/logo.png');
$seller = new Party([ $seller = new Party([
'name' => $InvoiceSettings->company_name, 'name' => Settings::getValueByKey("SETTINGS::INVOICE:COMPANY_NAME"),
'phone' => $InvoiceSettings->company_phone, 'phone' => Settings::getValueByKey("SETTINGS::INVOICE:COMPANY_PHONE"),
'address' => $InvoiceSettings->company_adress, 'address' => Settings::getValueByKey("SETTINGS::INVOICE:COMPANY_ADDRESS"),
'vat' => $InvoiceSettings->company_vat, 'vat' => Settings::getValueByKey("SETTINGS::INVOICE:COMPANY_VAT"),
'custom_fields' => [ 'custom_fields' => [
'E-Mail' => $InvoiceSettings->company_mail, 'E-Mail' => Settings::getValueByKey("SETTINGS::INVOICE:COMPANY_MAIL"),
"Web" => $InvoiceSettings->company_web "Web" => Settings::getValueByKey("SETTINGS::INVOICE:COMPANY_WEBSITE")
], ],
]); ]);
@ -540,7 +552,7 @@ class PaymentController extends Controller
->series(now()->format('mY')) ->series(now()->format('mY'))
->delimiter("-") ->delimiter("-")
->sequence($newInvoiceID) ->sequence($newInvoiceID)
->serialNumberFormat($InvoiceSettings->invoice_prefix . '{DELIMITER}{SERIES}{SEQUENCE}') ->serialNumberFormat(Settings::getValueByKey("SETTINGS::INVOICE:PREFIX") . '{DELIMITER}{SERIES}{SEQUENCE}')
->notes($notes); ->notes($notes);
if (file_exists($logoPath)) { if (file_exists($logoPath)) {
@ -591,6 +603,11 @@ class PaymentController extends Controller
->editColumn('created_at', function (Payment $payment) { ->editColumn('created_at', function (Payment $payment) {
return $payment->created_at ? $payment->created_at->diffForHumans() : ''; return $payment->created_at ? $payment->created_at->diffForHumans() : '';
}) })
->make(); ->addColumn('actions', function (Payment $payment) {
return ' <a data-content="' . __("Download") . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.invoices.downloadSingleInvoice', "id=" . $payment->payment_id) . '" class="btn btn-sm text-white btn-info mr-1"><i class="fas fa-file-download"></i></a>
';
})
->rawColumns(['actions'])
->make(true);
} }
} }

View file

@ -3,12 +3,10 @@
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Egg;
use App\Models\Location; use App\Models\Location;
use App\Models\Nest; use App\Models\Nest;
use App\Models\Node;
use App\Models\Configuration;
use App\Models\Product; use App\Models\Product;
use App\Models\Settings;
use Exception; use Exception;
use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\Factory;
@ -16,7 +14,6 @@ use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Response;
class ProductController extends Controller class ProductController extends Controller
{ {
@ -97,7 +94,7 @@ class ProductController extends Controller
{ {
return view('admin.products.show', [ return view('admin.products.show', [
'product' => $product, 'product' => $product,
'minimum_credits' => Configuration::getValueByKey("MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER"), 'minimum_credits' => Settings::getValueByKey("SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER"),
]); ]);
} }

View file

@ -6,6 +6,7 @@ use App\Classes\Pterodactyl;
use App\Classes\PterodactylWrapper; use App\Classes\PterodactylWrapper;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Server; use App\Models\Server;
use App\Models\Settings;
use Exception; use Exception;
use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\Factory;
@ -161,7 +162,7 @@ class ServerController extends Controller
return $server->suspended ? $server->suspended->diffForHumans() : ''; return $server->suspended ? $server->suspended->diffForHumans() : '';
}) })
->editColumn('name', function (Server $server) { ->editColumn('name', function (Server $server) {
return '<a class="text-info" target="_blank" href="' . env('PTERODACTYL_URL', 'http://localhost') . '/admin/servers/view/' . $server->pterodactyl_id . '">' . $server->name . '</a>'; return '<a class="text-info" target="_blank" href="' . Settings::getValueByKey("SETTINGS::SYSTEM:PTERODACTYL:URL") . '/admin/servers/view/' . $server->pterodactyl_id . '">' . $server->name . '</a>';
}) })
->rawColumns(['user', 'actions', 'status', 'name']) ->rawColumns(['user', 'actions', 'status', 'name'])
->make(); ->make();

View file

@ -3,13 +3,12 @@
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\InvoiceSettings; use App\Models\Settings;
use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Response; use Illuminate\Http\Response;
use ZipArchive;
class SettingsController extends Controller class SettingsController extends Controller
{ {
@ -20,81 +19,68 @@ class SettingsController extends Controller
*/ */
public function index() public function index()
{ {
/** @var InvoiceSettings $invoiceSettings */ //Get all tabs as laravel view paths
$invoiceSettings = InvoiceSettings::first(); $tabs = [];
foreach (glob(resource_path('views/admin/settings/tabs/*.blade.php')) as $filename) {
$tabs[] = 'admin.settings.tabs.' . basename($filename, '.blade.php');
}
return view('admin.settings.index', $invoiceSettings->toArray()); //Generate a html list item for each tab based on tabs file basename, set first tab as active
$tabListItems = [];
foreach ($tabs as $tab) {
$tabName = str_replace('admin.settings.tabs.', '', $tab);
$tabListItems[] = '<li class="nav-item">
<a class="nav-link ' . (empty($tabListItems) ? 'active' : '') . '" data-toggle="pill" href="#' . $tabName . '">
' . __(ucfirst($tabName)) . '
</a></li>';
}
return view('admin.settings.index', [
'tabs' => $tabs,
'tabListItems' => $tabListItems,
]);
} }
public function updateIcons(Request $request)
public function updatevalue(Request $request)
{ {
$setting = Settings::findOrFail($request->input('key'));
$request->validate([ $request->validate([
'icon' => 'nullable|max:10000|mimes:jpg,png,jpeg', 'key' => 'required|string|max:191',
'favicon' => 'nullable|max:10000|mimes:ico', 'value' => 'required|string|max:191',
]); ]);
if ($request->hasFile('icon')) { $setting->update($request->all());
$request->file('icon')->storeAs('public', 'icon.png');
}
if ($request->hasFile('favicon')) { return redirect()->route('admin.settings.index')->with('success', __('configuration has been updated!'));
$request->file('favicon')->storeAs('public', 'favicon.ico');
}
return redirect()->route('admin.settings.index')->with('success', __('Icons updated!'));
} }
public function updateInvoiceSettings(Request $request) /**
* Remove the specified resource from storage.
*
* @param Settings $setting
* @return Response
*/
public function destroy(Settings $setting)
{ {
$request->validate([ //
'logo' => 'nullable|max:10000|mimes:jpg,png,jpeg',
]);
InvoiceSettings::updateOrCreate([
'id' => "1"
], [
'company_name' => $request->get('company-name'),
'company_adress' => $request->get('company-address'),
'company_phone' => $request->get('company-phone'),
'company_mail' => $request->get('company-mail'),
'company_vat' => $request->get('company-vat'),
'company_web' => $request->get('company-web'),
'invoice_prefix' => $request->get('invoice-prefix'),
]);
if ($request->hasFile('logo')) {
$request->file('logo')->storeAs('public', 'logo.png');
}
return redirect()->route('admin.settings.index')->with('success', 'Invoice settings updated!');
} }
public function downloadAllInvoices() public function datatable()
{ {
$zip = new ZipArchive; $query = Settings::where('key', 'like', '%SYSTEM%')
$zip_safe_path = storage_path('invoices.zip'); ->orWhere('key', 'like', '%USER%')
$res = $zip->open($zip_safe_path, ZipArchive::CREATE | ZipArchive::OVERWRITE); ->orWhere('key', 'like', '%SERVER%');
$result = $this::rglob(storage_path('app/invoice/*'));
if ($res === TRUE) {
$zip->addFromString("1. Info.txt", "This Archive contains all Invoices from all Users!\nIf there are no Invoices here, no Invoices have ever been created!");
foreach ($result as $file) {
if (file_exists($file) && is_file($file)) {
$zip->addFile($file, basename($file));
}
}
$zip->close();
}
return response()->download($zip_safe_path);
}
public function rglob($pattern, $flags = 0) return datatables($query)
{ ->addColumn('actions', function (Settings $setting) {
$files = glob($pattern, $flags); return '<button data-content="' . __("Edit") . '" data-toggle="popover" data-trigger="hover" data-placement="top" onclick="configuration.parse(\'' . $setting->key . '\',\'' . $setting->value . '\',\'' . $setting->type . '\')" data-content="Edit" data-trigger="hover" data-toggle="tooltip" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></button> ';
foreach (glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) { })
$files = array_merge($files, $this::rglob($dir . '/' . basename($pattern), $flags)); ->editColumn('created_at', function (Settings $setting) {
} return $setting->created_at ? $setting->created_at->diffForHumans() : '';
return $files; })
->rawColumns(['actions'])
->make();
} }
} }

View file

@ -5,6 +5,7 @@ namespace App\Http\Controllers\Admin;
use App\Classes\Pterodactyl; use App\Classes\Pterodactyl;
use App\Events\UserUpdateCreditsEvent; use App\Events\UserUpdateCreditsEvent;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Settings;
use App\Models\User; use App\Models\User;
use App\Notifications\DynamicNotification; use App\Notifications\DynamicNotification;
use Spatie\QueryBuilder\QueryBuilder; use Spatie\QueryBuilder\QueryBuilder;
@ -300,7 +301,7 @@ class UserController extends Controller
return '<span class="badge ' . $badgeColor . '">' . $user->role . '</span>'; return '<span class="badge ' . $badgeColor . '">' . $user->role . '</span>';
}) })
->editColumn('name', function (User $user) { ->editColumn('name', function (User $user) {
return '<a class="text-info" target="_blank" href="' . env('PTERODACTYL_URL', 'http://localhost') . '/admin/users/view/' . $user->pterodactyl_id . '">' . $user->name . '</a>'; return '<a class="text-info" target="_blank" href="' . Settings::getValueByKey("SETTINGS::SYSTEM:PTERODACTYL:URL") . '/admin/users/view/' . $user->pterodactyl_id . '">' . $user->name . '</a>';
}) })
->orderColumn('last_seen', function ($query, $order) { ->orderColumn('last_seen', function ($query, $order) {
$query->orderBy('last_seen', $order); $query->orderBy('last_seen', $order);

View file

@ -5,8 +5,8 @@ namespace App\Http\Controllers\Api;
use App\Classes\Pterodactyl; use App\Classes\Pterodactyl;
use App\Events\UserUpdateCreditsEvent; use App\Events\UserUpdateCreditsEvent;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Configuration;
use App\Models\DiscordUser; use App\Models\DiscordUser;
use App\Models\Settings;
use App\Models\User; use App\Models\User;
use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Contracts\Pagination\LengthAwarePaginator;
@ -242,8 +242,8 @@ class UserController extends Controller
$user = User::create([ $user = User::create([
'name' => $request->input('name'), 'name' => $request->input('name'),
'email' => $request->input('email'), 'email' => $request->input('email'),
'credits' => Configuration::getValueByKey('INITIAL_CREDITS', 150), 'credits' => Settings::getValueByKey('SETTINGS::USER:INITIAL_CREDITS', 150),
'server_limit' => Configuration::getValueByKey('INITIAL_SERVER_LIMIT', 1), 'server_limit' => Settings::getValueByKey('SETTINGS::USER:INITIAL_SERVER_LIMIT', 1),
'password' => Hash::make($request->input('password')), 'password' => Hash::make($request->input('password')),
]); ]);

View file

@ -41,17 +41,25 @@ class LoginController extends Controller
public function login(Request $request) public function login(Request $request)
{ {
$request->validate([
$validationRules = [
$this->username() => 'required|string', $this->username() => 'required|string',
'password' => 'required|string', 'password' => 'required|string',
'g-recaptcha-response' => ['required','recaptcha'], ];
]); if (config('SETTINGS::RECAPTCHA:ENABLED') == 'true') {
$validationRules['g-recaptcha-response'] = ['required', 'recaptcha'];
}
$request->validate($validationRules);
// If the class is using the ThrottlesLogins trait, we can automatically throttle // If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and // the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application. // the IP address of the client making these requests into this application.
if (method_exists($this, 'hasTooManyLoginAttempts') && if (
$this->hasTooManyLoginAttempts($request)) { method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)
) {
$this->fireLockoutEvent($request); $this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request); return $this->sendLockoutResponse($request);

View file

@ -4,7 +4,7 @@ namespace App\Http\Controllers\Auth;
use App\Classes\Pterodactyl; use App\Classes\Pterodactyl;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Configuration; use App\Models\Settings;
use App\Models\User; use App\Models\User;
use App\Providers\RouteServiceProvider; use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Foundation\Auth\RegistersUsers;
@ -54,30 +54,28 @@ class RegisterController extends Controller
*/ */
protected function validator(array $data) protected function validator(array $data)
{ {
if (Configuration::getValueByKey('REGISTER_IP_CHECK', 'true') == 'true') { $validationRules = [
'name' => ['required', 'string', 'max:30', 'min:4', 'alpha_num', 'unique:users'],
'email' => ['required', 'string', 'email', 'max:64', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
];
if (config('SETTINGS::RECAPTCHA:ENABLED') == 'true') {
$validationRules['g-recaptcha-response'] = ['required', 'recaptcha'];
}
if (config('SETTINGS::SYSTEM:REGISTER_IP_CHECK', 'true') == 'true') {
//check if ip has already made an account //check if ip has already made an account
$data['ip'] = session()->get('ip') ?? request()->ip(); $data['ip'] = session()->get('ip') ?? request()->ip();
if (User::where('ip', '=', request()->ip())->exists()) session()->put('ip', request()->ip()); if (User::where('ip', '=', request()->ip())->exists()) session()->put('ip', request()->ip());
$validationRules['ip'] = ['unique:users'];
return Validator::make($data, $validationRules, [
'ip.unique' => "You have already made an account! Please contact support if you think this is incorrect."
return Validator::make($data, [
'name' => ['required', 'string', 'max:30', 'min:4', 'alpha_num', 'unique:users'],
'email' => ['required', 'string', 'email', 'max:64', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
'g-recaptcha-response' => ['recaptcha'],
'ip' => ['unique:users'],
], [
'ip.unique' => __("You have already made an account with us! Please contact support if you think this is incorrect.")
]); ]);
} }
return Validator::make($data, [ return Validator::make($data, $validationRules);
'name' => ['required', 'string', 'max:30', 'min:4', 'alpha_num', 'unique:users'],
'email' => ['required', 'string', 'email', 'max:64', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
'g-recaptcha-response' => ['recaptcha'],
]);
} }
/** /**
@ -91,8 +89,8 @@ class RegisterController extends Controller
$user = User::create([ $user = User::create([
'name' => $data['name'], 'name' => $data['name'],
'email' => $data['email'], 'email' => $data['email'],
'credits' => Configuration::getValueByKey('INITIAL_CREDITS', 150), 'credits' => config('SETTINGS::USER:INITIAL_CREDITS', 150),
'server_limit' => Configuration::getValueByKey('INITIAL_SERVER_LIMIT', 1), 'server_limit' => config('SETTINGS::USER:INITIAL_SERVER_LIMIT', 1),
'password' => Hash::make($data['password']), 'password' => Hash::make($data['password']),
]); ]);

View file

@ -3,8 +3,8 @@
namespace App\Http\Controllers\Auth; namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Configuration;
use App\Models\DiscordUser; use App\Models\DiscordUser;
use App\Models\Settings;
use App\Models\User; use App\Models\User;
use App\Models\Voucher; use App\Models\Voucher;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
@ -15,7 +15,7 @@ class SocialiteController extends Controller
{ {
public function redirect() public function redirect()
{ {
$scopes = !empty(env('DISCORD_BOT_TOKEN')) && !empty(env('DISCORD_GUILD_ID')) ? ['guilds.join'] : []; $scopes = !empty(Settings::getValueByKey("SETTINGS::DISCORD:BOT_TOKEN")) && !empty(Settings::getValueByKey("SETTINGS::DISCORD:GUILD_ID")) ? ['guilds.join'] : [];
return Socialite::driver('discord') return Socialite::driver('discord')
->scopes($scopes) ->scopes($scopes)
@ -31,17 +31,17 @@ class SocialiteController extends Controller
/** @var User $user */ /** @var User $user */
$user = Auth::user(); $user = Auth::user();
$discord = Socialite::driver('discord')->user(); $discord = Socialite::driver('discord')->user();
$botToken = env('DISCORD_BOT_TOKEN'); $botToken = Settings::getValueByKey("SETTINGS::DISCORD:BOT_TOKEN");
$guildId = env('DISCORD_GUILD_ID'); $guildId = Settings::getValueByKey("SETTINGS::DISCORD:GUILD_ID");
$roleId = env('DISCORD_ROLE_ID'); $roleId = Settings::getValueByKey("SETTINGS::DISCORD:ROLE_ID");
//save / update discord_users //save / update discord_users
if (is_null($user->discordUser)) { if (is_null($user->discordUser)) {
//create discord user in db //create discord user in db
DiscordUser::create(array_merge($discord->user, ['user_id' => Auth::user()->id])); DiscordUser::create(array_merge($discord->user, ['user_id' => Auth::user()->id]));
//update user //update user
Auth::user()->increment('credits', Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_DISCORD')); Auth::user()->increment('credits', Settings::getValueByKey('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD'));
Auth::user()->increment('server_limit', Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD')); Auth::user()->increment('server_limit', Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD'));
Auth::user()->update(['discord_verified_at' => now()]); Auth::user()->update(['discord_verified_at' => now()]);
} else { } else {
$user->discordUser->update($discord->user); $user->discordUser->update($discord->user);

View file

@ -2,10 +2,7 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Egg;
use App\Models\Product;
use App\Models\UsefulLink; use App\Models\UsefulLink;
use App\Models\Configuration;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;

View file

@ -2,14 +2,11 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Classes\Pterodactyl; use App\Classes\Pterodactyl;
use App\Models\Configuration;
use App\Models\User; use App\Models\User;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
@ -21,9 +18,9 @@ class ProfileController extends Controller
{ {
return view('profile.index')->with([ return view('profile.index')->with([
'user' => Auth::user(), 'user' => Auth::user(),
'credits_reward_after_verify_discord' => Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_DISCORD'), 'credits_reward_after_verify_discord' => config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD'),
'force_email_verification' => Configuration::getValueByKey('FORCE_EMAIL_VERIFICATION'), 'force_email_verification' => config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION'),
'force_discord_verification' => Configuration::getValueByKey('FORCE_DISCORD_VERIFICATION'), 'force_discord_verification' => config('SETTINGS::USER:FORCE_DISCORD_VERIFICATION'),
]); ]);
} }
@ -39,15 +36,15 @@ class ProfileController extends Controller
$user = User::findOrFail($id); $user = User::findOrFail($id);
//update password if necessary //update password if necessary
if (!is_null($request->input('new_password'))){ if (!is_null($request->input('new_password'))) {
//validate password request //validate password request
$request->validate([ $request->validate([
'current_password' => [ 'current_password' => [
'required' , 'required',
function ($attribute, $value, $fail) use ($user) { function ($attribute, $value, $fail) use ($user) {
if (!Hash::check($value, $user->password)) { if (!Hash::check($value, $user->password)) {
$fail('The '.$attribute.' is invalid.'); $fail('The ' . $attribute . ' is invalid.');
} }
}, },
], ],
@ -80,13 +77,13 @@ class ProfileController extends Controller
//validate request //validate request
$request->validate([ $request->validate([
'name' => 'required|min:4|max:30|alpha_num|unique:users,name,'.$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', 'email' => 'required|email|max:64|unique:users,email,' . $id . ',id',
'avatar' => 'nullable' 'avatar' => 'nullable'
]); ]);
//update avatar //update avatar
if(!is_null($request->input('avatar'))){ if (!is_null($request->input('avatar'))) {
$avatar = json_decode($request->input('avatar')); $avatar = json_decode($request->input('avatar'));
if ($avatar->input->size > 3000000) abort(500); if ($avatar->input->size > 3000000) abort(500);
@ -121,6 +118,6 @@ class ProfileController extends Controller
]); ]);
$user->sendEmailVerificationNotification(); $user->sendEmailVerificationNotification();
return redirect()->route('profile.index')->with('success' , __('Profile updated')); return redirect()->route('profile.index')->with('success', __('Profile updated'));
} }
} }

View file

@ -3,13 +3,13 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Classes\Pterodactyl; use App\Classes\Pterodactyl;
use App\Models\Configuration;
use App\Models\Egg; use App\Models\Egg;
use App\Models\Location; use App\Models\Location;
use App\Models\Nest; use App\Models\Nest;
use App\Models\Node; use App\Models\Node;
use App\Models\Product; use App\Models\Product;
use App\Models\Server; use App\Models\Server;
use App\Models\Settings;
use App\Notifications\ServerCreationError; use App\Notifications\ServerCreationError;
use Exception; use Exception;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
@ -107,7 +107,7 @@ class ServerController extends Controller
if ( if (
Auth::user()->credits < Auth::user()->credits <
($product->minimum_credits == -1 ($product->minimum_credits == -1
? Configuration::getValueByKey('MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50) ? config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)
: $product->minimum_credits) : $product->minimum_credits)
) { ) {
return redirect()->route('servers.index')->with('error', "You do not have the required amount of " . CREDITS_DISPLAY_NAME . " to use this product!"); return redirect()->route('servers.index')->with('error', "You do not have the required amount of " . CREDITS_DISPLAY_NAME . " to use this product!");
@ -115,12 +115,12 @@ class ServerController extends Controller
} }
//Required Verification for creating an server //Required Verification for creating an server
if (Configuration::getValueByKey('FORCE_EMAIL_VERIFICATION', 'false') === 'true' && !Auth::user()->hasVerifiedEmail()) { if (config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION', 'false') === 'true' && !Auth::user()->hasVerifiedEmail()) {
return redirect()->route('profile.index')->with('error', __("You are required to verify your email address before you can create a server.")); return redirect()->route('profile.index')->with('error', __("You are required to verify your email address before you can create a server."));
} }
//Required Verification for creating an server //Required Verification for creating an server
if (Configuration::getValueByKey('FORCE_DISCORD_VERIFICATION', 'false') === 'true' && !Auth::user()->discordUser) { if (config('SETTINGS::USER:FORCE_DISCORD_VERIFICATION', 'false') === 'true' && !Auth::user()->discordUser) {
return redirect()->route('profile.index')->with('error', __("You are required to link your discord account before you can create a server.")); return redirect()->route('profile.index')->with('error', __("You are required to link your discord account before you can create a server."));
} }
@ -168,7 +168,7 @@ class ServerController extends Controller
'identifier' => $serverAttributes['identifier'] 'identifier' => $serverAttributes['identifier']
]); ]);
if (Configuration::getValueByKey('SERVER_CREATE_CHARGE_FIRST_HOUR', 'true') == 'true') { if (config('SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR', 'true') == 'true') {
if ($request->user()->credits >= $server->product->getHourlyPrice()) { if ($request->user()->credits >= $server->product->getHourlyPrice()) {
$request->user()->decrement('credits', $server->product->getHourlyPrice()); $request->user()->decrement('credits', $server->product->getHourlyPrice());
} }

View file

@ -2,8 +2,8 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Configuration;
use App\Models\CreditProduct; use App\Models\CreditProduct;
use App\Models\Settings;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
class StoreController extends Controller class StoreController extends Controller
@ -15,17 +15,17 @@ class StoreController extends Controller
if ( if (
env('APP_ENV') == 'local' || env('APP_ENV') == 'local' ||
env('PAYPAL_SECRET') && env('PAYPAL_CLIENT_ID') || Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:SECRET") && Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID") ||
env('STRIPE_SECRET') && env('STRIPE_ENDPOINT_SECRET') && env('STRIPE_METHODS') Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:SECRET") && Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET") && Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:METHODS")
) $isPaymentSetup = true; ) $isPaymentSetup = true;
//Required Verification for creating an server //Required Verification for creating an server
if (Configuration::getValueByKey('FORCE_EMAIL_VERIFICATION', false) === 'true' && !Auth::user()->hasVerifiedEmail()) { if (Settings::getValueByKey('SETTINGS::USER:FORCE_EMAIL_VERIFICATION', false) === 'true' && !Auth::user()->hasVerifiedEmail()) {
return redirect()->route('profile.index')->with('error', __("You are required to verify your email address before you can purchase credits.")); return redirect()->route('profile.index')->with('error', __("You are required to verify your email address before you can purchase credits."));
} }
//Required Verification for creating an server //Required Verification for creating an server
if (Configuration::getValueByKey('FORCE_DISCORD_VERIFICATION', false) === 'true' && !Auth::user()->discordUser) { if (Settings::getValueByKey('SETTINGS::USER:FORCE_DISCORD_VERIFICATION', false) === 'true' && !Auth::user()->discordUser) {
return redirect()->route('profile.index')->with('error', __("You are required to link your discord account before you can purchase Credits")); return redirect()->route('profile.index')->with('error', __("You are required to link your discord account before you can purchase Credits"));
} }

View file

@ -18,4 +18,6 @@ class TranslationController extends Controller
Session::put('locale', $request->inputLocale); Session::put('locale', $request->inputLocale);
return redirect()->back(); return redirect()->back();
} }
} }

View file

@ -3,6 +3,7 @@
namespace App\Http\Middleware; namespace App\Http\Middleware;
use App\Models\Configuration; use App\Models\Configuration;
use App\Models\Settings;
use Closure; use Closure;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@ -17,10 +18,10 @@ class GlobalNames
*/ */
public function handle(Request $request, Closure $next) public function handle(Request $request, Closure $next)
{ {
define('CREDITS_DISPLAY_NAME' , Configuration::getValueByKey('CREDITS_DISPLAY_NAME' , 'Credits')); define('CREDITS_DISPLAY_NAME', config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME', 'Credits'));
$unsupported_lang_array = explode(',', config("app.unsupported_locales")); $unsupported_lang_array = explode(',', config("app.unsupported_locales"));
$unsupported_lang_array = array_map( 'strtolower', $unsupported_lang_array ); $unsupported_lang_array = array_map('strtolower', $unsupported_lang_array);
define('UNSUPPORTED_LANGS', $unsupported_lang_array); define('UNSUPPORTED_LANGS', $unsupported_lang_array);
return $next($request); return $next($request);

View file

@ -2,6 +2,7 @@
namespace App\Http\Middleware; namespace App\Http\Middleware;
use App\Models\Settings;
use Closure; use Closure;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
@ -9,194 +10,6 @@ use Illuminate\Support\Facades\Session;
class SetLocale class SetLocale
{ {
function getLocaleCodeForDisplayLanguage($name){
$languageCodes = array(
"aa" => "Afar",
"ab" => "Abkhazian",
"ae" => "Avestan",
"af" => "Afrikaans",
"ak" => "Akan",
"am" => "Amharic",
"an" => "Aragonese",
"ar" => "Arabic",
"as" => "Assamese",
"av" => "Avaric",
"ay" => "Aymara",
"az" => "Azerbaijani",
"ba" => "Bashkir",
"be" => "Belarusian",
"bg" => "Bulgarian",
"bh" => "Bihari",
"bi" => "Bislama",
"bm" => "Bambara",
"bn" => "Bengali",
"bo" => "Tibetan",
"br" => "Breton",
"bs" => "Bosnian",
"ca" => "Catalan",
"ce" => "Chechen",
"ch" => "Chamorro",
"co" => "Corsican",
"cr" => "Cree",
"cs" => "Czech",
"cu" => "Church Slavic",
"cv" => "Chuvash",
"cy" => "Welsh",
"da" => "Danish",
"de" => "German",
"dv" => "Divehi",
"dz" => "Dzongkha",
"ee" => "Ewe",
"el" => "Greek",
"en" => "English",
"eo" => "Esperanto",
"es" => "Spanish",
"et" => "Estonian",
"eu" => "Basque",
"fa" => "Persian",
"ff" => "Fulah",
"fi" => "Finnish",
"fj" => "Fijian",
"fo" => "Faroese",
"fr" => "French",
"fy" => "Western Frisian",
"ga" => "Irish",
"gd" => "Scottish Gaelic",
"gl" => "Galician",
"gn" => "Guarani",
"gu" => "Gujarati",
"gv" => "Manx",
"ha" => "Hausa",
"he" => "Hebrew",
"hi" => "Hindi",
"ho" => "Hiri Motu",
"hr" => "Croatian",
"ht" => "Haitian",
"hu" => "Hungarian",
"hy" => "Armenian",
"hz" => "Herero",
"ia" => "Interlingua (International Auxiliary Language Association)",
"id" => "Indonesian",
"ie" => "Interlingue",
"ig" => "Igbo",
"ii" => "Sichuan Yi",
"ik" => "Inupiaq",
"io" => "Ido",
"is" => "Icelandic",
"it" => "Italian",
"iu" => "Inuktitut",
"ja" => "Japanese",
"jv" => "Javanese",
"ka" => "Georgian",
"kg" => "Kongo",
"ki" => "Kikuyu",
"kj" => "Kwanyama",
"kk" => "Kazakh",
"kl" => "Kalaallisut",
"km" => "Khmer",
"kn" => "Kannada",
"ko" => "Korean",
"kr" => "Kanuri",
"ks" => "Kashmiri",
"ku" => "Kurdish",
"kv" => "Komi",
"kw" => "Cornish",
"ky" => "Kirghiz",
"la" => "Latin",
"lb" => "Luxembourgish",
"lg" => "Ganda",
"li" => "Limburgish",
"ln" => "Lingala",
"lo" => "Lao",
"lt" => "Lithuanian",
"lu" => "Luba-Katanga",
"lv" => "Latvian",
"mg" => "Malagasy",
"mh" => "Marshallese",
"mi" => "Maori",
"mk" => "Macedonian",
"ml" => "Malayalam",
"mn" => "Mongolian",
"mr" => "Marathi",
"ms" => "Malay",
"mt" => "Maltese",
"my" => "Burmese",
"na" => "Nauru",
"nb" => "Norwegian Bokmal",
"nd" => "North Ndebele",
"ne" => "Nepali",
"ng" => "Ndonga",
"nl" => "Dutch",
"nn" => "Norwegian Nynorsk",
"no" => "Norwegian",
"nr" => "South Ndebele",
"nv" => "Navajo",
"ny" => "Chichewa",
"oc" => "Occitan",
"oj" => "Ojibwa",
"om" => "Oromo",
"or" => "Oriya",
"os" => "Ossetian",
"pa" => "Panjabi",
"pi" => "Pali",
"pl" => "Polish",
"ps" => "Pashto",
"pt" => "Portuguese",
"qu" => "Quechua",
"rm" => "Raeto-Romance",
"rn" => "Kirundi",
"ro" => "Romanian",
"ru" => "Russian",
"rw" => "Kinyarwanda",
"sa" => "Sanskrit",
"sc" => "Sardinian",
"sd" => "Sindhi",
"se" => "Northern Sami",
"sg" => "Sango",
"si" => "Sinhala",
"sk" => "Slovak",
"sl" => "Slovenian",
"sm" => "Samoan",
"so" => "Somali",
"sq" => "Albanian",
"sr" => "Serbian",
"ss" => "Swati",
"st" => "Southern Sotho",
"su" => "Sundanese",
"sv" => "Swedish",
"sw" => "Swahili",
"ta" => "Tamil",
"te" => "Telugu",
"tg" => "Tajik",
"th" => "Thai",
"ti" => "Tigrinya",
"tk" => "Turkmen",
"tl" => "Tagalog",
"tn" => "Tswana",
"to" => "Tonga",
"tr" => "Turkish",
"ts" => "Tsonga",
"tt" => "Tatar",
"tw" => "Twi",
"ty" => "Tahitian",
"ug" => "Uighur",
"uk" => "Ukrainian",
"ur" => "Urdu",
"uz" => "Uzbek",
"ve" => "Venda",
"vi" => "Vietnamese",
"vo" => "Volapuk",
"wa" => "Walloon",
"wo" => "Wolof",
"xh" => "Xhosa",
"yi" => "Yiddish",
"yo" => "Yoruba",
"za" => "Zhuang",
"zh" => "Chinese",
"zu" => "Zulu"
);
return array_search($name, array_flip($languageCodes));
}
/** /**
* *
@ -208,22 +21,19 @@ class SetLocale
*/ */
public function handle($request, Closure $next) public function handle($request, Closure $next)
{ {
if (Session::has('locale')) {
if (Session::has('locale')) { $locale = Session::get('locale', config("SETTINGS::LOCALE:DEFAULT"));
$locale = Session::get('locale', config('app.locale')); } else {
if (config("SETTINGS::LOCALE:DYNAMIC") !== "true") {
$locale = config("SETTINGS::LOCALE:DEFAULT");
} else { } else {
if (!config('app.dynamic_locale')) { $locale = substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2);
$locale = config('app.locale');
}else{
$locale = substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2);
if (!in_array($locale, config('app.available_locales'))
|| in_array(strtolower($this->getLocaleCodeForDisplayLanguage($locale)), UNSUPPORTED_LANGS)) {
$locale = config('app.locale');
}
if (!in_array($locale, explode(',', config("SETTINGS::LOCALE:AVAILABLE")))) {
$locale = config("SETTINGS::LOCALE:DEFAULT");
} }
} }
}
App::setLocale($locale); App::setLocale($locale);
return $next($request); return $next($request);

View file

@ -3,11 +3,10 @@
namespace App\Listeners; namespace App\Listeners;
use App\Events\UserUpdateCreditsEvent; use App\Events\UserUpdateCreditsEvent;
use App\Models\Configuration;
use App\Models\Server; use App\Models\Server;
use App\Models\Settings;
use Exception; use Exception;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class UnsuspendServers implements ShouldQueue class UnsuspendServers implements ShouldQueue
{ {
@ -20,7 +19,7 @@ class UnsuspendServers implements ShouldQueue
*/ */
public function handle(UserUpdateCreditsEvent $event) public function handle(UserUpdateCreditsEvent $event)
{ {
if ($event->user->credits > Configuration::getValueByKey('MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER' , 50)){ if ($event->user->credits > Settings::getValueByKey('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER' , 50)){
/** @var Server $server */ /** @var Server $server */
foreach ($event->user->servers as $server){ foreach ($event->user->servers as $server){
if ($server->isSuspended()) $server->unSuspend(); if ($server->isSuspended()) $server->unSuspend();

View file

@ -2,9 +2,7 @@
namespace App\Listeners; namespace App\Listeners;
use App\Models\Configuration; use App\Models\Settings;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class Verified class Verified
{ {
@ -26,7 +24,7 @@ class Verified
*/ */
public function handle($event) public function handle($event)
{ {
$event->user->increment('server_limit' , Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL')); $event->user->increment('server_limit' , Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL'));
$event->user->increment('credits' , Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_EMAIL')); $event->user->increment('credits' , Settings::getValueByKey('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL'));
} }
} }

View file

@ -59,7 +59,7 @@ class CreditProduct extends Model
*/ */
public function getTaxPercent() public function getTaxPercent()
{ {
$tax = Configuration::getValueByKey("SALES_TAX"); $tax = Settings::getValueByKey("SETTINGS::PAYMENTS:SALES_TAX");
return $tax < 0 ? 0 : $tax; return $tax < 0 ? 0 : $tax;
} }

View file

@ -1,23 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class InvoiceSettings extends Model
{
use HasFactory;
protected $table = 'invoice_settings';
protected $fillable = [
'company_name',
'company_adress',
'company_phone',
'company_mail',
'company_vat',
'company_web',
'invoice_prefix'
];
}

View file

@ -6,11 +6,13 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
class Configuration extends Model class Settings extends Model
{ {
use HasFactory; use HasFactory;
public const CACHE_TAG = 'configuration'; protected $table = 'settings';
public const CACHE_TAG = 'setting';
public $primaryKey = 'key'; public $primaryKey = 'key';
@ -28,8 +30,8 @@ class Configuration extends Model
{ {
parent::boot(); parent::boot();
static::updated(function (Configuration $configuration) { static::updated(function (Settings $settings) {
Cache::forget(self::CACHE_TAG .':'. $configuration->key); Cache::forget(self::CACHE_TAG .':'. $settings->key);
}); });
} }
@ -41,8 +43,8 @@ class Configuration extends Model
public static function getValueByKey(string $key, $default = null) public static function getValueByKey(string $key, $default = null)
{ {
return Cache::rememberForever(self::CACHE_TAG .':'. $key, function () use ($default, $key) { return Cache::rememberForever(self::CACHE_TAG .':'. $key, function () use ($default, $key) {
$configuration = self::find($key); $settings = self::find($key);
return $configuration ? $configuration->value : $default; return $settings ? $settings->value : $default;
}); });
} }
} }

View file

@ -2,7 +2,6 @@
namespace App\Notifications; namespace App\Notifications;
use App\Models\Configuration;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\MailMessage;

View file

@ -2,7 +2,7 @@
namespace App\Notifications; namespace App\Notifications;
use App\Models\Configuration; use App\Models\Settings;
use App\Models\User; use App\Models\User;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
@ -38,25 +38,25 @@ class WelcomeMessage extends Notification implements ShouldQueue
return ['database']; return ['database'];
} }
public function AdditionalLines() public function AdditionalLines()
{ {
$AdditionalLine = ""; $AdditionalLine = "";
if(Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_EMAIL') != 0) { if (config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL') != 0) {
$AdditionalLine .= "Verifying your e-mail address will grant you ".Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_EMAIL')." additional " . Configuration::getValueByKey('CREDITS_DISPLAY_NAME') . ". <br />"; $AdditionalLine .= "Verifying your e-mail address will grant you " . config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL') . " additional " . config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME') . ". <br />";
}
if(Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') != 0) {
$AdditionalLine .= "Verifying your e-mail will also increase your Server Limit by " . Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') . ". <br />";
}
$AdditionalLine .="<br />";
if(Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_DISCORD') != 0) {
$AdditionalLine .= "You can also verify your discord account to get another " . Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_DISCORD') . " " . Configuration::getValueByKey('CREDITS_DISPLAY_NAME') . ". <br />";
}
if(Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') != 0) {
$AdditionalLine .= "Verifying your Discord account will also increase your Server Limit by " . Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') . ". <br />";
}
return $AdditionalLine;
} }
if (config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') != 0) {
$AdditionalLine .= "Verifying your e-mail will also increase your Server Limit by " . config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') . ". <br />";
}
$AdditionalLine .= "<br />";
if (config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD') != 0) {
$AdditionalLine .= "You can also verify your discord account to get another " . config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD') . " " . config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME') . ". <br />";
}
if (config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') != 0) {
$AdditionalLine .= "Verifying your Discord account will also increase your Server Limit by " . config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') . ". <br />";
}
return $AdditionalLine;
}
/** /**
* Get the array representation of the notification. * Get the array representation of the notification.
* *
@ -72,7 +72,7 @@ class WelcomeMessage extends Notification implements ShouldQueue
<h5>Verification</h5> <h5>Verification</h5>
<p>You can verify your e-mail address and link/verify your Discord account.</p> <p>You can verify your e-mail address and link/verify your Discord account.</p>
<p> <p>
".$this->AdditionalLines()." " . $this->AdditionalLines() . "
</p> </p>
<h5>Information</h5> <h5>Information</h5>
<p>This dashboard can be used to create and delete servers.<br /> These servers can be used and managed on our pterodactyl panel.<br /> If you have any questions, please join our Discord server and #create-a-ticket.</p> <p>This dashboard can be used to create and delete servers.<br /> These servers can be used and managed on our pterodactyl panel.<br /> If you have any questions, please join our Discord server and #create-a-ticket.</p>

View file

@ -2,11 +2,13 @@
namespace App\Providers; namespace App\Providers;
use App\Models\Settings;
use Illuminate\Pagination\Paginator; use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Spatie\QueryBuilder\QueryBuilderRequest;
class AppServiceProvider extends ServiceProvider class AppServiceProvider extends ServiceProvider
{ {
@ -31,14 +33,11 @@ class AppServiceProvider extends ServiceProvider
Schema::defaultStringLength(191); Schema::defaultStringLength(191);
Validator::extend('multiple_date_format', function ($attribute, $value, $parameters, $validator) { Validator::extend('multiple_date_format', function ($attribute, $value, $parameters, $validator) {
$ok = true; $ok = true;
$result = []; $result = [];
// iterate through all formats // iterate through all formats
foreach ($parameters as $parameter) { foreach ($parameters as $parameter) {
//validate with laravels standard date format validation //validate with laravels standard date format validation
$result[] = $validator->validateDateFormat($attribute, $value, [$parameter]); $result[] = $validator->validateDateFormat($attribute, $value, [$parameter]);
} }
@ -51,5 +50,59 @@ class AppServiceProvider extends ServiceProvider
return $ok; return $ok;
}); });
// TODO: Check if Installer Lockfile exists instead of "running in console"
$settings = Settings::all();
// Set all configs from database
foreach ($settings as $setting) {
config([$setting->key => $setting->value]);
}
// Set Mail Config
//only update config if mail settings have changed in DB
if (
config('mail.default') != config('SETTINGS:MAIL:MAILER') ||
config('mail.mailers.smtp.host') != config('SETTINGS:MAIL:HOST') ||
config('mail.mailers.smtp.port') != config('SETTINGS:MAIL:PORT') ||
config('mail.mailers.smtp.username') != config('SETTINGS:MAIL:USERNAME') ||
config('mail.mailers.smtp.password') != config('SETTINGS:MAIL:PASSWORD') ||
config('mail.mailers.smtp.encryption') != config('SETTINGS:MAIL:ENCRYPTION') ||
config('mail.from.address') != config('SETTINGS:MAIL:FROM_ADDRESS') ||
config('mail.from.name') != config('SETTINGS:MAIL:FROM_NAME')
) {
config(['mail.default' => config('SETTINGS::MAIL:MAILER')]);
config(['mail.mailers.smtp' => [
'transport' => 'smtp',
'host' => config('SETTINGS::MAIL:HOST'),
'port' => config('SETTINGS::MAIL:PORT'),
'encryption' => config('SETTINGS::MAIL:ENCRYPTION'),
'username' => config('SETTINGS::MAIL:USERNAME'),
'password' => config('SETTINGS::MAIL:PASSWORD'),
'timeout' => null,
'auth_mode' => null,
]]);
config(['mail.from' => ['address' => config('SETTINGS::MAIL:FROM_ADDRESS'), 'name' => config('SETTINGS::MAIL:FROM_NAME')]]);
Artisan::call('queue:restart');
}
// Set Recaptcha API Config
//only update config if recaptcha settings have changed in DB
if (
config('recaptcha.api_site_key') != config('SETTINGS::RECAPTCHA:SITE_KEY') ||
config('recaptcha.api_secret_key') != config('SETTINGS::RECAPTCHA:SECRET_KEY')
) {
config(['recaptcha.api_site_key' => config('SETTINGS::RECAPTCHA:SITE_KEY')]);
config(['recaptcha.api_secret_key' => config('SETTINGS::RECAPTCHA:SECRET_KEY')]);
Artisan::call('config:clear');
Artisan::call('cache:clear');
}
// Set Discord-API Config
config(['services.discord.client_id' => config('SETTINGS::DISCORD:CLIENT_ID')]);
config(['services.discord.client_secret' => config('SETTINGS::DISCORD:CLIENT_SECRET')]);
} }
} }

View file

@ -1,5 +1,7 @@
<?php <?php
use App\Models\Settings;
return [ return [
'version' => '0.6.2', 'version' => '0.6.2',
@ -70,16 +72,6 @@ return [
'timezone' => env('APP_TIMEZONE', 'UTC'), 'timezone' => env('APP_TIMEZONE', 'UTC'),
/*
|--------------------------------------------------------------------------
| Dyamic Locales
|--------------------------------------------------------------------------
|
| Change the Locale depending on the Users Browserlanguage
| Can either be true or false
|
*/
'dynamic_locale' => env('DYNAMIC_LOCALE', false),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -92,47 +84,20 @@ return [
| |
*/ */
'locale' => env('LOCALE', 'en'), 'locale' =>"en",
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Available Locales | Available Languages
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| You should not change this | The application locale determines the default locale that will be used
| If the dashboard is 100% translated in a certain language, it will be added here | by the translation service provider. You are free to set this value
| | to any of the locales which will be supported by the application.
*/
'available_locales' => array('English'=>'en','German'=>'de','Italian'=>'it','Chinese'=>'zh', 'Czech'=>'cs', 'Spanish'=>'es', 'Polish'=>'pl'),
/*
|--------------------------------------------------------------------------
| Unsupported Locales
|--------------------------------------------------------------------------
|
| Locales the Owner of the Dashboard does not want to support
|
| |
*/ */
'unsupported_locales' => env("UNSUPPORTED_LOCALES", ""), 'available_locales' =>["en","cs","de","es","fr","hi","it","pl","zh"],
/*
|--------------------------------------------------------------------------
| Datatable Language Setting
|--------------------------------------------------------------------------
|
| This is the Language-Code used on the Datatables.
| You can grab the Language-Codes from this Website
| https://datatables.net/plug-ins/i18n/
|
*/
'datatable_locale' => env('DATATABLE_LOCALE', 'en-gb'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View file

@ -45,31 +45,22 @@ return [
'auth_mode' => null, 'auth_mode' => null,
], ],
'ses' => [ // 'ses' => [
'transport' => 'ses', // 'transport' => 'ses',
], // ],
//
'mailgun' => [ // 'mailgun' => [
'transport' => 'mailgun', // 'transport' => 'mailgun',
], // ],
//
'postmark' => [ // 'postmark' => [
'transport' => 'postmark', // 'transport' => 'postmark',
], // ],
//
'sendmail' => [ // 'sendmail' => [
'transport' => 'sendmail', // 'transport' => 'sendmail',
'path' => '/usr/sbin/sendmail -bs', // 'path' => '/usr/sbin/sendmail -bs',
], // ],
'log' => [
'transport' => 'log',
'channel' => env('MAIL_LOG_CHANNEL'),
],
'array' => [
'transport' => 'array',
],
], ],
/* /*

View file

@ -1,34 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateConfigurationsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('configurations', function (Blueprint $table) {
$table->string('key')->primary();
$table->string('value');
$table->string('type')->default('string');
$table->text('description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('configurations');
}
}

View file

@ -1,48 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class InvoiceSettings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('invoice_settings', function (Blueprint $table) {
$table->id();
$table->string('company_name')->nullable();
$table->string('company_adress')->nullable();
$table->string('company_phone')->nullable();
$table->string('company_vat')->nullable();
$table->string('company_mail')->nullable();
$table->string('company_web')->nullable()->default(env("APP_URL",""));
$table->string('invoice_prefix')->nullable();
$table->timestamps();
});
DB::table('invoice_settings')->insert(
array(
'company_name' => env("APP_NAME","MyCompany"),
'company_web' => env("APP_URL",""),
'invoice_prefix' => "INV"
)
);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('invoice_settings');
}
}

View file

@ -0,0 +1,61 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
class RenameConfigurationsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::rename('configurations', 'settings');
DB::table('settings')->where('key', 'INITIAL_CREDITS')->update(['key' => 'SETTINGS::USER:INITIAL_CREDITS']);
DB::table('settings')->where('key', 'INITIAL_SERVER_LIMIT')->update(['key' => 'SETTINGS::USER:INITIAL_SERVER_LIMIT']);
DB::table('settings')->where('key', 'CREDITS_REWARD_AFTER_VERIFY_EMAIL')->update(['key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL']);
DB::table('settings')->where('key', 'SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL')->update(['key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL']);
DB::table('settings')->where('key', 'CREDITS_REWARD_AFTER_VERIFY_DISCORD')->update(['key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD']);
DB::table('settings')->where('key', 'SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD')->update(['key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD']);
DB::table('settings')->where('key', 'MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER')->update(['key' => 'SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER']);
DB::table('settings')->where('key', 'SERVER_LIMIT_AFTER_IRL_PURCHASE')->update(['key' => 'SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE']);
DB::table('settings')->where('key', 'FORCE_EMAIL_VERIFICATION')->update(['key' => 'SETTINGS::USER:FORCE_EMAIL_VERIFICATION']);
DB::table('settings')->where('key', 'FORCE_DISCORD_VERIFICATION')->update(['key' => 'SETTINGS::USER:FORCE_DISCORD_VERIFICATION']);
DB::table('settings')->where('key', 'REGISTER_IP_CHECK')->update(['key' => 'SETTINGS::SYSTEM:REGISTER_IP_CHECK']);
DB::table('settings')->where('key', 'CREDITS_DISPLAY_NAME')->update(['key' => 'SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME']);
DB::table('settings')->where('key', 'ALLOCATION_LIMIT')->update(['key' => 'SETTINGS::SERVER:ALLOCATION_LIMIT']);
DB::table('settings')->where('key', 'SERVER_CREATE_CHARGE_FIRST_HOUR')->update(['key' => 'SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR']);
DB::table('settings')->where('key', 'SALES_TAX')->update(['key' => 'SETTINGS::PAYMENTS:SALES_TAX']);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::rename('settings', 'configurations');
DB::table('configurations')->where('key', 'SETTINGS::USER:INITIAL_CREDITS')->update(['key' => 'INITIAL_CREDITS']);
DB::table('configurations')->where('key', 'SETTINGS::USER:INITIAL_SERVER_LIMIT')->update(['key' => 'INITIAL_SERVER_LIMIT']);
DB::table('configurations')->where('key', 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL')->update(['key' => 'CREDITS_REWARD_AFTER_VERIFY_EMAIL']);
DB::table('configurations')->where('key', 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL')->update(['key' => 'SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL']);
DB::table('configurations')->where('key', 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD')->update(['key' => 'CREDITS_REWARD_AFTER_VERIFY_DISCORD']);
DB::table('configurations')->where('key', 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD')->update(['key' => 'SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD']);
DB::table('configurations')->where('key', 'SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER')->update(['key' => 'MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER']);
DB::table('configurations')->where('key', 'SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')->update(['key' => 'SERVER_LIMIT_AFTER_IRL_PURCHASE']);
DB::table('configurations')->where('key', 'SETTINGS::USER:FORCE_EMAIL_VERIFICATION')->update(['key' => 'FORCE_EMAIL_VERIFICATION']);
DB::table('configurations')->where('key', 'SETTINGS::USER:FORCE_DISCORD_VERIFICATION')->update(['key' => 'FORCE_DISCORD_VERIFICATION']);
DB::table('configurations')->where('key', 'SETTINGS::SYSTEM:REGISTER_IP_CHECK')->update(['key' => 'REGISTER_IP_CHECK']);
DB::table('configurations')->where('key', 'SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR')->update(['key' => 'SERVER_CREATE_CHARGE_FIRST_HOUR']);
DB::table('configurations')->where('key', 'SETTINGS::SERVER:ALLOCATION_LIMIT')->update(['key' => 'ALLOCATION_LIMIT']);
DB::table('configurations')->where('key', 'SETTINGS::SERVER:CREDITS_DISPLAY_NAME')->update(['key' => 'SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME']);
DB::table('configurations')->where('key', 'SETTINGS::PAYMENTS:SALES_TAX')->update(['key' => 'SALES_TAX']);
}
}

View file

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class UpdateSettingsTableAllowNullable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
//allow value column in settings table to be nullable
Schema::table('settings', function (Blueprint $table) {
$table->string('value')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//disallow value column in settings table to be nullable
Schema::table('settings', function (Blueprint $table) {
$table->string('value')->nullable(false)->change();
});
}
}

View file

@ -2,8 +2,7 @@
namespace Database\Seeders; namespace Database\Seeders;
use Database\Seeders\Seeds\ConfigurationSeeder; use Database\Seeders\Seeds\SettingsSeeder;
use Database\Seeders\Seeds\InvoiceSettingsSeeder;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder class DatabaseSeeder extends Seeder
@ -16,7 +15,7 @@ class DatabaseSeeder extends Seeder
public function run() public function run()
{ {
$this->call([ $this->call([
ConfigurationSeeder::class, SettingsSeeder::class,
]); ]);
} }

View file

@ -1,149 +0,0 @@
<?php
namespace Database\Seeders\Seeds;
use App\Models\Configuration;
use Illuminate\Database\Seeder;
class ConfigurationSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//initials
Configuration::firstOrCreate([
'key' => 'INITIAL_CREDITS',
], [
'value' => '250',
'type' => 'integer',
'description' => 'The initial amount of credits the user starts with.'
]);
Configuration::firstOrCreate([
'key' => 'INITIAL_SERVER_LIMIT',
], [
'value' => '1',
'type' => 'integer',
'description' => 'The initial server limit the user starts with.'
]);
//verify email event
Configuration::firstOrCreate([
'key' => 'CREDITS_REWARD_AFTER_VERIFY_EMAIL',
], [
'value' => '250',
'type' => 'integer',
'description' => 'Increase in credits after the user has verified their email account.'
]);
Configuration::firstOrCreate([
'key' => 'SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL',
], [
'value' => '2',
'type' => 'integer',
'description' => 'Increase in server limit after the user has verified their email account.'
]);
//verify discord event
Configuration::firstOrCreate([
'key' => 'CREDITS_REWARD_AFTER_VERIFY_DISCORD',
], [
'value' => '375',
'type' => 'integer',
'description' => 'Increase in credits after the user has verified their discord account.'
]);
Configuration::firstOrCreate([
'key' => 'SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD',
], [
'value' => '2',
'type' => 'integer',
'description' => 'Increase in server limit after the user has verified their discord account.'
]);
//other
Configuration::firstOrCreate([
'key' => 'MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER',
], [
'value' => '50',
'type' => 'integer',
'description' => 'The minimum amount of credits the user would need to make a server.'
]);
//purchasing
Configuration::firstOrCreate([
'key' => 'SERVER_LIMIT_AFTER_IRL_PURCHASE',
], [
'value' => '10',
'type' => 'integer',
'description' => 'updates the users server limit to this amount (unless the user already has a higher server limit) after making a purchase with real money, set to 0 to ignore this.',
]);
//force email and discord verification
Configuration::firstOrCreate([
'key' => 'FORCE_EMAIL_VERIFICATION',
], [
'value' => 'false',
'type' => 'boolean',
'description' => 'Force an user to verify the email adress before creating a server / buying credits.'
]);
Configuration::firstOrCreate([
'key' => 'FORCE_DISCORD_VERIFICATION',
], [
'value' => 'false',
'type' => 'boolean',
'description' => 'Force an user to link an Discord Account before creating a server / buying credits.'
]);
//disable ip check on register
Configuration::firstOrCreate([
'key' => 'REGISTER_IP_CHECK',
], [
'value' => 'true',
'type' => 'boolean',
'description' => 'Prevent users from making multiple accounts using the same IP address'
]);
//per_page on allocations request
Configuration::firstOrCreate([
'key' => 'ALLOCATION_LIMIT',
], [
'value' => '200',
'type' => 'integer',
'description' => 'The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created!'
]);
//credits display name
Configuration::firstOrCreate([
'key' => 'CREDITS_DISPLAY_NAME',
], [
'value' => 'Credits',
'type' => 'string',
'description' => 'Set the display name of your currency :)'
]);
//credits display name
Configuration::firstOrCreate([
'key' => 'SERVER_CREATE_CHARGE_FIRST_HOUR',
], [
'value' => 'true',
'type' => 'boolean',
'description' => 'Charges the first hour worth of credits upon creating a server.'
]);
//sales tax
Configuration::firstOrCreate([
'key' => 'SALES_TAX',
], [
'value' => '0',
'type' => 'integer',
'description' => 'The %-value of tax that will be added to the product price on checkout'
]);
}
}

View file

@ -0,0 +1,468 @@
<?php
namespace Database\Seeders\Seeds;
use App\Models\Settings;
use Illuminate\Database\Seeder;
class SettingsSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//initials
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:INITIAL_CREDITS',
], [
'value' => '250',
'type' => 'integer',
'description' => 'The initial amount of credits the user starts with.'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:NITIAL_SERVER_LIMIT',
], [
'value' => '1',
'type' => 'integer',
'description' => 'The initial server limit the user starts with.'
]);
//verify email event
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL',
], [
'value' => '250',
'type' => 'integer',
'description' => 'Increase in credits after the user has verified their email account.'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL',
], [
'value' => '2',
'type' => 'integer',
'description' => 'Increase in server limit after the user has verified their email account.'
]);
//verify discord event
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD',
], [
'value' => '375',
'type' => 'integer',
'description' => 'Increase in credits after the user has verified their discord account.'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD',
], [
'value' => '2',
'type' => 'integer',
'description' => 'Increase in server limit after the user has verified their discord account.'
]);
//other
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER',
], [
'value' => '50',
'type' => 'integer',
'description' => 'The minimum amount of credits the user would need to make a server.'
]);
//purchasing
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE',
], [
'value' => '10',
'type' => 'integer',
'description' => 'updates the users server limit to this amount (unless the user already has a higher server limit) after making a purchase with real money, set to 0 to ignore this.',
]);
//force email and discord verification
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:FORCE_EMAIL_VERIFICATION',
], [
'value' => 'false',
'type' => 'boolean',
'description' => 'Force an user to verify the email adress before creating a server / buying credits.'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:FORCE_DISCORD_VERIFICATION',
], [
'value' => 'false',
'type' => 'boolean',
'description' => 'Force an user to link an Discord Account before creating a server / buying credits.'
]);
//disable ip check on register
Settings::firstOrCreate([
'key' => 'SETTINGS::SYSTEM:REGISTER_IP_CHECK',
], [
'value' => 'true',
'type' => 'boolean',
'description' => 'Prevent users from making multiple accounts using the same IP address'
]);
//per_page on allocations request
Settings::firstOrCreate([
'key' => 'SETTINGS::SERVER:ALLOCATION_LIMIT',
], [
'value' => '200',
'type' => 'integer',
'description' => 'The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created!'
]);
//credits display name
Settings::firstOrCreate([
'key' => 'SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME',
], [
'value' => 'Credits',
'type' => 'string',
'description' => 'Set the display name of your currency :)'
]);
//credits display name
Settings::firstOrCreate([
'key' => 'SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR',
], [
'value' => 'true',
'type' => 'boolean',
'description' => 'Charges the first hour worth of credits upon creating a server.'
]);
//sales tax
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:SALES_TAX',
], [
'value' => '0',
'type' => 'integer',
'description' => 'The %-value of tax that will be added to the product price on checkout'
]);
//Invoices enabled
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:ENABLED',
], [
'value' => 'false',
'type' => 'boolean',
]);
//Invoice company name
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:COMPANY_NAME',
], [
'value' => '',
'type' => 'string',
'description' => 'The name of the Company on the Invoices'
]);
//Invoice company address
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:COMPANY_ADDRESS',
], [
'value' => '',
'type' => 'string',
'description' => 'The address of the Company on the Invoices'
]);
//Invoice company phone
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:COMPANY_PHONE',
], [
'value' => '',
'type' => 'string',
'description' => 'The phone number of the Company on the Invoices'
]);
//Invoice company mail
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:COMPANY_MAIL',
], [
'value' => '',
'type' => 'string',
'description' => 'The email address of the Company on the Invoices'
]);
//Invoice VAT
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:COMPANY_VAT',
], [
'value' => '',
'type' => 'string',
'description' => 'The VAT-Number of the Company on the Invoices'
]);
//Invoice Website
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:COMPANY_WEBSITE',
], [
'value' => '',
'type' => 'string',
'description' => 'The Website of the Company on the Invoices'
]);
//Invoice Website
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:PREFIX',
], [
'value' => 'INV',
'type' => 'string',
'description' => 'The invoice prefix'
]);
//Locale
Settings::firstOrCreate([
'key' => 'SETTINGS::LOCALE:DEFAULT',
], [
'value' => 'en',
'type' => 'string',
'description' => 'The default Language the dashboard will be shown in'
]);
//Dynamic locale
Settings::firstOrCreate([
'key' => 'SETTINGS::LOCALE:DYNAMIC',
], [
'value' => 'false',
'type' => 'boolean',
'description' => 'If this is true, the Language will change to the Clients browserlanguage or default.'
]);
//User can change Locale
Settings::firstOrCreate([
'key' => 'SETTINGS::LOCALE:CLIENTS_CAN_CHANGE',
], [
'value' => 'false',
'type' => 'boolean',
'description' => 'If this is true, the clients will be able to change their Locale.'
]);
//Locale
Settings::firstOrCreate([
'key' => 'SETTINGS::LOCALE:AVAILABLE',
], [
'value' => '',
'type' => 'string',
'description' => 'The available languages'
]);
//Locale
Settings::firstOrCreate([
'key' => 'SETTINGS::LOCALE:DATATABLES',
], [
'value' => 'en-gb',
'type' => 'string',
'description' => 'The Language of the Datatables. Grab the Language-Codes from here https://datatables.net/plug-ins/i18n/'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:PAYPAL:SECRET',
], [
'value' => '',
'type' => 'string',
'description' => 'Your PayPal Secret-Key ( https://developer.paypal.com/docs/integration/direct/rest/)'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID',
], [
'value' => '',
'type' => 'string',
'description' => 'Your PayPal Client_ID'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET',
], [
'value' => '',
'type' => 'string',
'description' => 'Your PayPal SANDBOX Secret-Key used for testing '
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID',
], [
'value' => '',
'type' => 'string',
'description' => 'Your PayPal SANDBOX Client-ID used for testing '
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:STRIPE:SECRET',
], [
'value' => '',
'type' => 'string',
'description' => 'Your Stripe Secret-Key ( https://dashboard.stripe.com/account/apikeys )'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET',
], [
'value' => '',
'type' => 'string',
'description' => 'Your Stripe endpoint secret-key'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:STRIPE:TEST_SECRET',
], [
'value' => '',
'type' => 'string',
'description' => 'Your Stripe test secret-key'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET',
], [
'value' => '',
'type' => 'string',
'description' => 'Your Stripe endpoint test secret-key'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:STRIPE:METHODS',
], [
'value' => '',
'type' => 'string',
'description' => 'Comma seperated list of payment methods that are enabled (https://stripe.com/docs/payments/payment-methods/integration-options)'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::DISCORD:CLIENT_ID',
], [
'value' => '',
'type' => 'string',
'description' => 'Discord API Credentials - https://discordapp.com/developers/applications/'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::DISCORD:CLIENT_SECRET',
], [
'value' => '',
'type' => 'string',
'description' => 'Discord API Credentials - https://discordapp.com/developers/applications/'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::DISCORD:BOT_TOKEN',
], [
'value' => '',
'type' => 'string',
'description' => 'Discord API Credentials - https://discordapp.com/developers/applications/'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::DISCORD:GUILD_ID',
], [
'value' => '',
'type' => 'string',
'description' => 'Discord API Credentials - https://discordapp.com/developers/applications/'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::DISCORD:ROLE_ID',
], [
'value' => '',
'type' => 'string',
'description' => 'Discord role that will be assigned to users when they register'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::DISCORD:INVITE_URL',
], [
'value' => '',
'type' => 'string',
'description' => 'The invite URL to your Discord Server'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::SYSTEM:PTERODACTYL:TOKEN',
], [
'value' => '',
'type' => 'string',
'description' => 'Admin API Token from Pterodactyl Panel - necessary for the Panel to work. The Key needs all read&write permissions!'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::SYSTEM:PTERODACTYL:URL',
], [
'value' => '',
'type' => 'string',
'description' => 'The URL to your Pterodactyl Panel. Must not end with a / '
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MISC:PHPMYADMIN:URL',
], [
'value' => '',
'type' => 'string',
'description' => 'The URL to your PHPMYADMIN Panel. Must not end with a /, remove to remove database button'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::RECAPTCHA:SITE_KEY',
], [
'value' => '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI',
'type' => 'string',
'description' => 'Google Recaptcha API Credentials - https://www.google.com/recaptcha/admin - reCaptcha V2 (not v3)'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::RECAPTCHA:SECRET_KEY',
], [
'value' => '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe',
'type' => 'string',
'description' => 'Google Recaptcha API Credentials - https://www.google.com/recaptcha/admin - reCaptcha V2 (not v3)'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::RECAPTCHA:ENABLED',
], [
'value' => 'true',
'type' => 'boolean',
'description' => 'Enables or disables the ReCaptcha feature on the registration/login page'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:MAILER',
], [
'value' => 'smtp',
'type' => 'string',
'description' => 'Selected Mailer (smtp, mailgun, sendgrid, mailtrap)'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:HOST',
], [
'value' => 'localhost',
'type' => 'string',
'description' => 'Mailer Host Adress'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:PORT',
], [
'value' => '1025',
'type' => 'string',
'description' => 'Mailer Server Port'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:USERNAME',
], [
'value' => '',
'type' => 'string',
'description' => 'Mailer Username'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:PASSWORD',
], [
'value' => '',
'type' => 'string',
'description' => 'Mailer Password'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:ENCRYPTION',
], [
'value' => 'tls',
'type' => 'string',
'description' => 'Mailer Encryption (tls, ssl)'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:FROM_ADDRESS',
], [
'value' => '',
'type' => 'string',
'description' => 'Mailer From Address'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:FROM_NAME',
], [
'value' => env('APP_NAME', 'Controlpanel'),
'type' => 'string',
'description' => 'Mailer From Name'
]);
}
}

2
package-lock.json generated
View file

@ -1,5 +1,5 @@
{ {
"name": "bitsec-dashboard", "name": "controllpanelgg",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -68,7 +68,7 @@
"User ID": "User-ID", "User ID": "User-ID",
"Server Creation Error": "Fehler beim erstellen des Servers", "Server Creation Error": "Fehler beim erstellen des Servers",
"Your servers have been suspended!": "Deine Server wurden pausiert", "Your servers have been suspended!": "Deine Server wurden pausiert",
"To automatically re-enable your server\/s, you need to purchase more credits.": "Um deine Server zu reaktivieren, musst du mehr Credits kaufen!", "To automatically re-enable your server/s, you need to purchase more credits.": "Um deine Server zu reaktivieren, musst du mehr Credits kaufen!",
"Purchase credits": "Credits kaufen", "Purchase credits": "Credits kaufen",
"If you have any questions please let us know.": "Solltest du weiter fragen haben, melde dich gerne beim Support!", "If you have any questions please let us know.": "Solltest du weiter fragen haben, melde dich gerne beim Support!",
"Regards": "mit freundlichen Grüßen", "Regards": "mit freundlichen Grüßen",
@ -217,7 +217,7 @@
"A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Ein Gutschein kann von einem User nur einmal eingelöst werden. \"Benutzungen\" setzt die Anzahl an Usern die diesen Gutschein einlösen können.", "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Ein Gutschein kann von einem User nur einmal eingelöst werden. \"Benutzungen\" setzt die Anzahl an Usern die diesen Gutschein einlösen können.",
"Max": "Max", "Max": "Max",
"Expires at": "Läuft ab am", "Expires at": "Läuft ab am",
"Used \/ Uses": "Benutzungen", "Used / Uses": "Benutzungen",
"Expires": "Ablauf", "Expires": "Ablauf",
"Sign in to start your session": "Melde dich an um das Dashboard zu benutzen", "Sign in to start your session": "Melde dich an um das Dashboard zu benutzen",
"Password": "Passwort", "Password": "Passwort",
@ -287,7 +287,7 @@
"No nodes have been linked!": "Es wurde keine Nodes verknüpft", "No nodes have been linked!": "Es wurde keine Nodes verknüpft",
"No nests available!": "Keine Nests verfügbar", "No nests available!": "Keine Nests verfügbar",
"No eggs have been linked!": "Es wurde keine Eggs verknüpft", "No eggs have been linked!": "Es wurde keine Eggs verknüpft",
"Software \/ Games": "Software \/ Spiele", "Software / Games": "Software / Spiele",
"Please select software ...": "Bitte Software auswählen", "Please select software ...": "Bitte Software auswählen",
"---": "---", "---": "---",
"Specification ": "Spezifikation", "Specification ": "Spezifikation",
@ -350,5 +350,14 @@
"Notes": "Notizen", "Notes": "Notizen",
"Amount in words": "Betrag in Worten", "Amount in words": "Betrag in Worten",
"Please pay until": "Zahlbar bis", "Please pay until": "Zahlbar bis",
"Account already exists on Pterodactyl. Please contact the Support!": "Der Account existiert bereits bei Pterodactyl. Kontaktiere den Support!" "Account already exists on Pterodactyl. Please contact the Support!": "Der Account existiert bereits bei Pterodactyl. Kontaktiere den Support!",
} "de": "Deutsch",
"en": "Englisch",
"fr": "Französisch",
"cs": "Tschechisch",
"es": "Spanisch",
"hi": "Hindi",
"it": "Italienisch",
"pl": "Polnisch",
"zh": "Chinesisch"
}

View file

@ -4,11 +4,12 @@
"api key has been removed!": "api key has been removed!", "api key has been removed!": "api key has been removed!",
"Edit": "Edit", "Edit": "Edit",
"Delete": "Delete", "Delete": "Delete",
"configuration has been updated!": "configuration has been updated!",
"Store item has been created!": "Store item has been created!", "Store item has been created!": "Store item has been created!",
"Store item has been updated!": "Store item has been updated!", "Store item has been updated!": "Store item has been updated!",
"Product has been updated!": "Product has been updated!", "Product has been updated!": "Product has been updated!",
"Store item has been removed!": "Store item has been removed!", "Store item has been removed!": "Store item has been removed!",
"Created at": "Created at",
"Error!": "Error!",
"unknown": "unknown", "unknown": "unknown",
"Pterodactyl synced": "Pterodactyl synced", "Pterodactyl synced": "Pterodactyl synced",
"Your credit balance has been increased!": "Your credit balance has been increased!", "Your credit balance has been increased!": "Your credit balance has been increased!",
@ -16,6 +17,7 @@
"Your payment has been canceled!": "Your payment has been canceled!", "Your payment has been canceled!": "Your payment has been canceled!",
"Payment method": "Payment method", "Payment method": "Payment method",
"Invoice": "Invoice", "Invoice": "Invoice",
"Download": "Download",
"Product has been created!": "Product has been created!", "Product has been created!": "Product has been created!",
"Product has been removed!": "Product has been removed!", "Product has been removed!": "Product has been removed!",
"Show": "Show", "Show": "Show",
@ -26,6 +28,7 @@
"Unsuspend": "Unsuspend", "Unsuspend": "Unsuspend",
"Suspend": "Suspend", "Suspend": "Suspend",
"Icons updated!": "Icons updated!", "Icons updated!": "Icons updated!",
"configuration has been updated!": "configuration has been updated!",
"link has been created!": "link has been created!", "link has been created!": "link has been created!",
"link has been updated!": "link has been updated!", "link has been updated!": "link has been updated!",
"product has been removed!": "product has been removed!", "product has been removed!": "product has been removed!",
@ -80,7 +83,6 @@
"Check the docs for it here": "Check the docs for it here", "Check the docs for it here": "Check the docs for it here",
"Causer": "Causer", "Causer": "Causer",
"Description": "Description", "Description": "Description",
"Created at": "Created at",
"Application API": "Application API", "Application API": "Application API",
"Create": "Create", "Create": "Create",
"Memo": "Memo", "Memo": "Memo",
@ -89,13 +91,6 @@
"Token": "Token", "Token": "Token",
"Last used": "Last used", "Last used": "Last used",
"Are you sure you wish to delete?": "Are you sure you wish to delete?", "Are you sure you wish to delete?": "Are you sure you wish to delete?",
"Edit Configuration": "Edit Configuration",
"Text Field": "Text Field",
"Cancel": "Cancel",
"Save": "Save",
"Configurations": "Configurations",
"Key": "Key",
"Value": "Value",
"Nests": "Nests", "Nests": "Nests",
"Sync": "Sync", "Sync": "Sync",
"Active": "Active", "Active": "Active",
@ -118,6 +113,7 @@
"Locations": "Locations", "Locations": "Locations",
"Eggs": "Eggs", "Eggs": "Eggs",
"Last updated :date": "Last updated :date", "Last updated :date": "Last updated :date",
"Download all Invoices": "Download all Invoices",
"Product Price": "Product Price", "Product Price": "Product Price",
"Tax Value": "Tax Value", "Tax Value": "Tax Value",
"Tax Percentage": "Tax Percentage", "Tax Percentage": "Tax Percentage",
@ -151,11 +147,15 @@
"Config": "Config", "Config": "Config",
"Suspended at": "Suspended at", "Suspended at": "Suspended at",
"Settings": "Settings", "Settings": "Settings",
"Dashboard icons": "Dashboard icons", "Key": "Key",
"Invoice Settings": "Invoice Settings", "Value": "Value",
"Edit Configuration": "Edit Configuration",
"Text Field": "Text Field",
"Cancel": "Cancel",
"Save": "Save",
"Select panel icon": "Select panel icon", "Select panel icon": "Select panel icon",
"Select panel favicon": "Select panel favicon", "Select panel favicon": "Select panel favicon",
"Download all Invoices": "Download all Invoices", "Images and Icons may be cached, reload without cache to see your changes appear": "Images and Icons may be cached, reload without cache to see your changes appear",
"Enter your companys name": "Enter your companys name", "Enter your companys name": "Enter your companys name",
"Enter your companys address": "Enter your companys address", "Enter your companys address": "Enter your companys address",
"Enter your companys phone number": "Enter your companys phone number", "Enter your companys phone number": "Enter your companys phone number",
@ -165,6 +165,15 @@
"Enter your custom invoice prefix": "Enter your custom invoice prefix", "Enter your custom invoice prefix": "Enter your custom invoice prefix",
"Logo": "Logo", "Logo": "Logo",
"Select Invoice Logo": "Select Invoice Logo", "Select Invoice Logo": "Select Invoice Logo",
"Available languages": "Available languages",
"Default language": "Default language",
"The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
"Datable language": "Datable language",
"The Language of the Datatables. Grab the Language-Codes from here": "The Language of the Datatables. Grab the Language-Codes from here",
"Auto-translate": "Auto-translate",
"If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
"Let the Client change the Language": "Let the Client change the Language",
"If this is checked, Clients will have the ability to manually change their Dashboard language": "If this is checked, Clients will have the ability to manually change their Dashboard language",
"Store": "Store", "Store": "Store",
"Currency code": "Currency code", "Currency code": "Currency code",
"Checkout the paypal docs to select the appropriate code": "Checkout the paypal docs to select the appropriate code", "Checkout the paypal docs to select the appropriate code": "Checkout the paypal docs to select the appropriate code",
@ -242,7 +251,7 @@
"per month": "per month", "per month": "per month",
"Out of Credits in": "Out of Credits in", "Out of Credits in": "Out of Credits in",
"Home": "Home", "Home": "Home",
"Languages": "Languages", "Language": "Language",
"See all Notifications": "See all Notifications", "See all Notifications": "See all Notifications",
"Redeem code": "Redeem code", "Redeem code": "Redeem code",
"Profile": "Profile", "Profile": "Profile",
@ -280,7 +289,6 @@
"Re-Sync Discord": "Re-Sync Discord", "Re-Sync Discord": "Re-Sync Discord",
"Save Changes": "Save Changes", "Save Changes": "Save Changes",
"Server configuration": "Server configuration", "Server configuration": "Server configuration",
"Error!": "Error!",
"Make sure to link your products to nodes and eggs.": "Make sure to link your products to nodes and eggs.", "Make sure to link your products to nodes and eggs.": "Make sure to link your products to nodes and eggs.",
"There has to be at least 1 valid product for server creation": "There has to be at least 1 valid product for server creation", "There has to be at least 1 valid product for server creation": "There has to be at least 1 valid product for server creation",
"No products available!": "No products available!", "No products available!": "No products available!",
@ -321,9 +329,6 @@
"Canceled ...": "Canceled ...", "Canceled ...": "Canceled ...",
"Deletion has been canceled.": "Deletion has been canceled.", "Deletion has been canceled.": "Deletion has been canceled.",
"Date": "Date", "Date": "Date",
"To": "To",
"From": "From",
"Pending": "Pending",
"Subtotal": "Subtotal", "Subtotal": "Subtotal",
"Payment Methods": "Payment Methods", "Payment Methods": "Payment Methods",
"Amount Due": "Amount Due", "Amount Due": "Amount Due",
@ -350,5 +355,13 @@
"Notes": "Notes", "Notes": "Notes",
"Amount in words": "Amount in words", "Amount in words": "Amount in words",
"Please pay until": "Please pay until", "Please pay until": "Please pay until",
"Account already exists on Pterodactyl. Please contact the Support!": "Account already exists on Pterodactyl. Please contact the Support!" "fr": "French",
} "cs": "Czech",
"en": "English",
"es": "Spanish",
"de": "German",
"hi": "Hindi",
"it": "Italian",
"pl": "Polish",
"zh": "Chinese"
}

View file

@ -1,63 +0,0 @@
<!-- The Modal -->
<div class="modal fade" id="editConfigurationModel">
<div class="modal-dialog">
<div class="modal-content ">
<form method="post" action="{{route('admin.configurations.updatevalue')}}">
@csrf
@method('PATCH')
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">{{__('Edit Configuration')}}</h4>
<button type="button" class="close" data-dismiss="modal">&times;</button>
</div>
<!-- Modal body -->
<div class="modal-body">
<div class="form-group">
<label id="keyLabel" for="value">{{__('Text Field')}}</label>
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">
<i class="fa fa-cog"></i>
</div>
</div>
</div>
</div>
<div class="form-group">
<input hidden id="key" name="key" type="text" class="form-control" required="required">
</div>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">{{__('Cancel')}}</button>
<button type="submit" class="btn btn-primary">{{__('Save')}}</button>
</div>
</form>
</div>
</div>
</div>
<script>
window.configuration = {
parse(key, value, type) {
$('#keyLabel').html(key)
$('#key').val(key)
$('#value').remove();
if (type === 'integer') {
$('.input-group').append('<input id="value" name="value" type="number" class="form-control" required="required">')
} else if (type === 'boolean') {
$('.input-group').append('<select id="value" name="value" class="form-control" required=required>' +
'<option value="true">true</option>' +
'<option value="false">false</option>' +
'</select>')
} else if (type === 'string') {
$('.input-group').append('<input id="value" name="value" type="text" class="form-control" required="required">')
}
$('#value').val(value)
$('#editConfigurationModel').modal('show')
}
}
</script>

View file

@ -1,91 +0,0 @@
@extends('layouts.main')
@section('content')
<!-- CONTENT HEADER -->
<section class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1>{{__('Configurations')}}</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.configurations.index')}}">{{__('Configurations')}}</a></li>
</ol>
</div>
</div>
</div>
</section>
<!-- END CONTENT HEADER -->
<!-- MAIN CONTENT -->
<section class="content">
<div class="container-fluid">
<div class="card">
<div class="card-header">
<div class="d-flex justify-content-between">
<h5 class="card-title"><i class="fas fa-cog mr-2"></i>{{__('Configurations')}}</h5>
</div>
</div>
<div class="card-body table-responsive">
<table id="datatable" class="table table-striped">
<thead>
<tr>
<th>{{__('Key')}}</th>
<th>{{__('Value')}}</th>
<th>{{__('Type')}}</th>
<th width="600">{{__('Description')}}</th>
<th>{{__('Created at')}}</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<!-- END CUSTOM CONTENT -->
</section>
<!-- END CONTENT -->
@include('admin.configurations.editModel')
<script>
document.addEventListener("DOMContentLoaded", function () {
$('#datatable').DataTable({
language: {
url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{config("app.datatable_locale")}}.json'
},
processing: true,
serverSide: true,
stateSave: true,
ajax: "{{route('admin.configurations.datatable')}}",
columns: [
{data: 'key'},
{data: 'value'},
{data: 'type'},
{data: 'description'},
{data: 'created_at'},
{data: 'actions', sortable: false},
],
fnDrawCallback: function( oSettings ) {
$('[data-toggle="popover"]').popover();
}
});
});
</script>
@endsection

View file

@ -27,6 +27,10 @@
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<h5 class="card-title"><i class="fas fa-money-bill-wave mr-2"></i>{{ __('Payments') }}</h5> <h5 class="card-title"><i class="fas fa-money-bill-wave mr-2"></i>{{ __('Payments') }}</h5>
<div class="float-right">
<a href="{{ route('admin.invoices.downloadAllInvoices') }}"><button
class="btn btn-info">{{ __('Download all Invoices') }}</button></a>
</div>
</div> </div>
<div class="card-body table-responsive"> <div class="card-body table-responsive">
@ -43,6 +47,7 @@
<th>{{ __('Payment ID') }}</th> <th>{{ __('Payment ID') }}</th>
<th>{{ __('Payment Method') }}</th> <th>{{ __('Payment Method') }}</th>
<th>{{ __('Created at') }}</th> <th>{{ __('Created at') }}</th>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -78,6 +83,7 @@
{data: 'payment_id'}, {data: 'payment_id'},
{data: 'payment_method'}, {data: 'payment_method'},
{data: 'created_at'}, {data: 'created_at'},
{data: 'actions' , sortable : false},
], ],
fnDrawCallback: function(oSettings) { fnDrawCallback: function(oSettings) {
$('[data-toggle="popover"]').popover(); $('[data-toggle="popover"]').popover();

View file

@ -6,13 +6,13 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row mb-2"> <div class="row mb-2">
<div class="col-sm-6"> <div class="col-sm-6">
<h1>{{__('Settings')}}</h1> <h1>{{ __('Settings') }}</h1>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<ol class="breadcrumb float-sm-right"> <ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li> <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
<li class="breadcrumb-item"><a class="text-muted" <li class="breadcrumb-item"><a class="text-muted"
href="{{route('admin.settings.index')}}">{{__('Settings')}}</a></li> href="{{ route('admin.settings.index') }}">{{ __('Settings') }}</a></li>
</ol> </ol>
</div> </div>
</div> </div>
@ -28,7 +28,7 @@
<div class="card-header"> <div class="card-header">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<h5 class="card-title"><i class="fas fa-tools mr-2"></i>{{__('Settings')}}</h5> <h5 class="card-title"><i class="fas fa-tools mr-2"></i>{{ __('Settings') }}</h5>
</div> </div>
</div> </div>
@ -36,169 +36,18 @@
<!-- Nav pills --> <!-- Nav pills -->
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" data-toggle="pill" href="#dashboard-icons">{{__('Dashboard icons')}}</a> @foreach ($tabListItems as $tabListItem)
</li> {!! $tabListItem !!}
<li class="nav-item"> @endforeach
<a class="nav-link" data-toggle="pill" href="#invoice-settings">{{__('Invoice Settings')}}</a>
</li>
</ul> </ul>
<!-- Tab panes --> <!-- Tab panes -->
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane mt-3 active" id="dashboard-icons">
<form method="POST" enctype="multipart/form-data" class="mb-3" @foreach ($tabs as $tab)
action="{{route('admin.settings.update.icons')}}"> @include($tab)
@csrf @endforeach
@method('PATCH')
<div class="row">
<div class="col-md-6 col-lg-4 col-12">
<div class="form-group">
<div class="custom-file mb-3 mt-3">
<input type="file" accept="image/png,image/jpeg,image/jpg"
class="custom-file-input" name="icon" id="icon">
<label class="custom-file-label selected"
for="icon">{{__('Select panel icon')}}</label>
</div>
@error('icon')
<span class="text-danger">
{{$message}}
</span>
@enderror
</div>
<div class="form-group">
<div class="custom-file mb-3">
<input type="file" accept="image/x-icon" class="custom-file-input"
name="favicon" id="favicon">
<label class="custom-file-label selected"
for="favicon">{{__('Select panel favicon')}}</label>
</div>
@error('favicon')
<span class="text-danger">
{{$message}}
</span>
@enderror
</div>
</div>
</div>
<button class="btn btn-primary">{{__('Submit')}}</button>
</form>
<p class="text-muted">Images and Icons may be cached, use <code>CNTRL + F5</code><sup>(google
chrome hotkey)</sup> to reload without cache to see your changes appear :)</p>
</div>
<div class="tab-pane mt-3" id="invoice-settings">
<div class="float-right">
<a href="{{route('admin.settings.downloadAllInvoices')}}"><button class="btn btn-success">{{__('Download all Invoices')}}</button></a>
</div>
<form method="POST" enctype="multipart/form-data" class="mb-3"
action="{{route('admin.settings.update.invoicesettings')}}">
@csrf
@method('PATCH')
<div class="row">
<div class="col-md-6 col-lg-4 col-12">
<!-- Name -->
<div class="form-group">
<div class="custom-control mb-3">
<label for="company-name">{{__('Enter your companys name' )}}</label>
<input x-model="company-name" id="company-name" name="company-name"
type="text" value="{{$company_name}}"
class="form-control @error('company-name') is-invalid @enderror">
</div>
</div>
<!-- address -->
<div class="form-group">
<div class="custom-control mb-3">
<label
for="company-address">{{__('Enter your companys address' )}}</label>
<input x-model="company-address" id="company-address"
name="company-address" type="text" value="{{$company_adress}}"
class="form-control @error('company-address') is-invalid @enderror">
</div>
</div>
<!-- Phone -->
<div class="form-group">
<div class="custom-control mb-3">
<label
for="company-phone">{{__('Enter your companys phone number' )}}</label>
<input x-model="company-phone" id="company-phone" name="company-phone"
type="text" value="{{$company_phone}}"
class="form-control @error('company-phone') is-invalid @enderror">
</div>
</div>
<!-- VAT -->
<div class="form-group">
<div class="custom-control mb-3">
<label for="company-vat">{{__('Enter your companys VAT id' )}}</label>
<input x-model="company-vat" id="company-vat" name="company-vat"
type="text" value="{{$company_vat}}"
class="form-control @error('company-vat') is-invalid @enderror">
</div>
</div>
<!-- email -->
<div class="form-group">
<div class="custom-control mb-3">
<label
for="company-mail">{{__('Enter your companys email address' )}}</label>
<input x-model="company-mail" id="company-mail" name="company-mail"
type="text" value="{{$company_mail}}"
class="form-control @error('company-mail') is-invalid @enderror">
</div>
</div>
<!-- website -->
<div class="form-group">
<div class="custom-control mb-3">
<label
for="company-web">{{__('Enter your companys website' )}}</label>
<input x-model="company-web" id="company-web" name="company-web"
type="text" value="{{$company_web}}"
class="form-control @error('company-web') is-invalid @enderror">
</div>
</div>
<!-- website -->
<div class="form-group">
<div class="custom-control mb-3">
<label
for="invoice-prefix">{{__('Enter your custom invoice prefix' )}}</label>
<input x-model="invoice-prefix" id="invoice-prefix" name="invoice-prefix"
type="text" value="{{$invoice_prefix}}"
class="form-control @error('invoice-prefix') is-invalid @enderror">
</div>
</div>
<!-- logo -->
<div class="form-group">
<div class="custom-control mb-3">
<label for="logo">{{__('Logo')}}</label>
<div class="custom-file mb-3">
<input type="file" accept="image/png,image/jpeg,image/jpg" class="custom-file-input"
name="logo" id="logo">
<label class="custom-file-label selected"
for="favicon">{{__('Select Invoice Logo')}}</label>
</div>
</div>
@error('logo')
<span class="text-danger">
{{$message}}
</span>
@enderror
</div>
</div>
</div>
<button class="btn btn-primary">{{__('Submit')}}</button>
<!-- end -->
</div>
</div> </div>
@ -218,12 +67,25 @@
<script> <script>
// Add the following code if you want the name of the file appear on select // Add the following code if you want the name of the file appear on select
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
$(".custom-file-input").on("change", function () { $(".custom-file-input").on("change", function() {
var fileName = $(this).val().split("\\").pop(); var fileName = $(this).val().split("\\").pop();
$(this).siblings(".custom-file-label").addClass("selected").html(fileName); $(this).siblings(".custom-file-label").addClass("selected").html(fileName);
}); });
}) })
const tabPaneHash = window.location.hash;
if (tabPaneHash) {
$('.nav-tabs a[href="' + tabPaneHash + '"]').tab('show');
}
$('.nav-tabs a').click(function(e) {
$(this).tab('show');
const scrollmem = $('body').scrollTop();
window.location.hash = this.hash;
$('html,body').scrollTop(scrollmem);
});
</script> </script>

View file

@ -0,0 +1,111 @@
<div class="tab-pane mt-3 active" id="invoices">
<form method="POST" enctype="multipart/form-data" class="mb-3"
action="{{ route('admin.settings.update.invoicesettings') }}">
@csrf
@method('PATCH')
<div class="row">
<div class="col-md-3 p-3">
<!-- Name -->
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="company-name">{{ __('Company Name') }}:</label>
<input x-model="company-name" id="company-name" name="company-name" type="text" required
value="{{ config('SETTINGS::INVOICE:COMPANY_NAME') }}"
class="form-control @error('company-name') is-invalid @enderror">
</div>
</div>
<!-- address -->
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="company-address">{{ __('Company Adress') }}:</label>
<input x-model="company-address" id="company-address" name="company-address" type="text"
value="{{ config('SETTINGS::INVOICE:COMPANY_ADDRESS') }}"
class="form-control @error('company-address') is-invalid @enderror">
</div>
</div>
<!-- Phone -->
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="company-phone">{{ __('Company Phonenumber') }}:</label>
<input x-model="company-phone" id="company-phone" name="company-phone" type="text"
value="{{ config('SETTINGS::INVOICE:COMPANY_PHONE') }}"
class="form-control @error('company-phone') is-invalid @enderror">
</div>
</div>
<!-- VAT -->
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="company-vat">{{ __('VAT ID') }}:</label>
<input x-model="company-vat" id="company-vat" name="company-vat" type="text"
value="{{ config('SETTINGS::INVOICE:COMPANY_VAT') }}"
class="form-control @error('company-vat') is-invalid @enderror">
</div>
</div>
</div>
<div class="col-md-3 p-3">
<!-- email -->
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="company-mail">{{ __('Company E-Mail Adress') }}:</label>
<input x-model="company-mail" id="company-mail" name="company-mail" type="text"
value="{{ config('SETTINGS::INVOICE:COMPANY_MAIL') }}"
class="form-control @error('company-mail') is-invalid @enderror">
</div>
</div>
<!-- website -->
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="company-web">{{ __('Company Website') }}:</label>
<input x-model="company-web" id="company-web" name="company-web" type="text"
value="{{ config('SETTINGS::INVOICE:COMPANY_WEBSITE') }}"
class="form-control @error('company-web') is-invalid @enderror">
</div>
</div>
<!-- prefix -->
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="invoice-prefix">{{ __('Invoice Prefix') }}:</label>
<input x-model="invoice-prefix" id="invoice-prefix" name="invoice-prefix" type="text" required
value="{{ config('SETTINGS::INVOICE:PREFIX') }}"
class="form-control @error('invoice-prefix') is-invalid @enderror">
</div>
</div>
</div>
<div class="col-md-3 p-3">
<div class="custom-control mb-3 p-0">
<div class="col m-0 p-0 d-flex justify-content-between align-items-center">
<div>
<input value="true" id="enable-invoices" name="enable-invoices"
{{ config('SETTINGS::INVOICE:ENABLED') == 'true' ? 'checked' : '' }} type="checkbox">
<label for="enable-invoices">{{ __('Enable Invoices') }} </label>
</div>
</div>
</div>
<!-- logo -->
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="logo">{{ __('Logo') }}:</label>
<div class="custom-file mb-3">
<input type="file" accept="image/png,image/jpeg,image/jpg" class="custom-file-input"
name="logo" id="logo">
<label class="custom-file-label selected"
for="favicon">{{ __('Select Invoice Logo') }}</label>
</div>
</div>
@error('logo')
<span class="text-danger">
</span>
@enderror
</div>
</div>
</div>
<div class="row">
<button class="btn btn-primary mt-3 ml-3">{{ __('Submit') }}</button>
</div>
</form>
</div>

View file

@ -0,0 +1,91 @@
<div class="tab-pane mt-3" id="language">
<form method="POST" enctype="multipart/form-data" class="mb-3"
action="{{ route('admin.settings.update.languagesettings') }}">
@csrf
@method('PATCH')
<div class="row">
<div class="col-md-3 p-3">
<div class="form-group">
<!-- AVAILABLE LANGUAGES -->
<div class="custom-control mb-3 p-0">
<label for="languages">{{ __('Available languages') }}:</label>
<select id="languages" style="width:100%" class="custom-select" name="languages[]" required
multiple="multiple" autocomplete="off" @error('defaultLanguage') is-invalid @enderror>
@foreach (config('app.available_locales') as $lang)
<option value="{{ $lang }}" @if (str_contains(config('SETTINGS::LOCALE:AVAILABLE'), $lang)) selected @endif>
{{ __($lang) }}
</option>
@endforeach
</select>
</div>
<!-- DEFAULT LANGUAGE -->
<div class="custom-control mb-3 p-0">
<label for="defaultLanguage">{{ __('Default language') }}:
<i data-toggle="popover" data-trigger="hover"
data-content="{{ __('The fallback Language, if something goes wrong') }}"
class="fas fa-info-circle"></i>
</label>
<select id="defaultLanguage" style="width:100%" class="custom-select" name="defaultLanguage"
required autocomplete="off" @error('defaultLanguage') is-invalid @enderror>
@foreach (config('app.available_locales') as $lang)
<option value="{{ $lang }}" @if (config('SETTINGS::LOCALE:DEFAULT') == $lang) selected
@endif>{{ __($lang) }}</option>
@endforeach
</select>
</div>
<div class="custom-control mb-3 p-0">
<!--DATATABLE LANGUAGE -->
<label for="datatable-language">{{ __('Datable language') }} <i data-toggle="popover"
data-trigger="hover" data-html="true"
data-content="{{ __('The datatables lang-code. <br><strong>Example:</strong> en-gb, fr_fr, de_de<br>More Information: ') }} https://datatables.net/plug-ins/i18n/"
class="fas fa-info-circle"></i></label>
<input x-model="datatable-language" id="datatable-language" name="datatable-language"
type="text" required value="{{ config('SETTINGS::LOCALE:DATATABLES') }}"
class="form-control @error('datatable-language') is-invalid @enderror">
</div>
</div>
</div>
<div class="col-md-3 p-3">
<!-- AUTO TRANSLATE -->
<div class="form-group">
<input value="true" id="autotranslate" name="autotranslate"
{{ config('SETTINGS::LOCALE:DYNAMIC') == 'true' ? 'checked' : '' }} type="checkbox">
<label for="autotranslate">{{ __('Auto-translate') }} <i data-toggle="popover"
data-trigger="hover"
data-content="{{ __('If this is checked, the Dashboard will translate itself to the Clients language, if available') }}"
class="fas fa-info-circle"></i></label>
<br />
<!-- CLIENTS CAN CHANGE -->
<input value="true" id="canClientChangeLanguage" name="canClientChangeLanguage"
{{ config('SETTINGS::LOCALE:CLIENTS_CAN_CHANGE') == 'true' ? 'checked' : '' }}
type="checkbox">
<label for="canClientChangeLanguage">{{ __('Client Language-Switch') }} <i data-toggle="popover"
data-trigger="hover"
data-content="{{ __('If this is checked, Clients will have the ability to manually change their Dashboard language') }}"
class="fas fa-info-circle"></i></label>
</div>
</div>
</div>
<div class="row">
<button class="btn btn-primary mt-3 ml-3">{{ __('Submit') }}</button>
</div>
</form>
</div>
<script>
document.addEventListener('DOMContentLoaded', (event) => {
$('.custom-select').select2();
})
</script>

View file

@ -0,0 +1,194 @@
<div class="tab-pane mt-3" id="misc">
<form method="POST" enctype="multipart/form-data" class="mb-3"
action="{{ route('admin.settings.update.miscsettings') }}">
@csrf
@method('PATCH')
<div class="row">
{{-- E-Mail --}}
<div class="col-md-3 px-3">
<div class="row mb-2">
<div class="col text-center">
<h1>E-Mail</h1>
</div>
</div>
<div class="custom-control mb-3 p-0">
<label for="mailservice">{{ __('Mail Service') }}:
<i data-toggle="popover" data-trigger="hover"
data-content="{{ __('The Mailer to send e-mails with') }}" class="fas fa-info-circle"></i>
</label>
<select id="mailservice" style="width:100%" class="custom-select" name="mailservice" required
autocomplete="off" @error('mailservice') is-invalid @enderror>
@foreach (array_keys(config('mail.mailers')) as $mailer)
<option value="{{ $mailer }}" @if (config('SETTINGS::MAIL:MAILER') == $mailer) selected
@endif>{{ __($mailer) }}</option>
@endforeach
</select>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="mailhost">{{ __('Mail Host') }}:</label>
<input x-model="mailhost" id="mailhost" name="mailhost" type="text"
value="{{ config('SETTINGS::MAIL:HOST') }}"
class="form-control @error('mailhost') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="mailport">{{ __('Mail Port') }}:</label>
<input x-model="mailhost" id="mailport" name="mailport" type="text"
value="{{ config('SETTINGS::MAIL:PORT') }}"
class="form-control @error('mailport') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="mailusername">{{ __('Mail Username') }}:</label>
<input x-model="mailusername" id="mailusername" name="mailusername" type="text"
value="{{ config('SETTINGS::MAIL:USERNAME') }}"
class="form-control @error('mailusername') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="mailpassword">{{ __('Mail Password') }}:</label>
<input x-model="mailpassword" id="mailpassword" name="mailpassword" type="text"
value="{{ config('SETTINGS::MAIL:PASSWORD') }}"
class="form-control @error('mailpassword') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="mailencryption">{{ __('Mail Encryption') }}:</label>
<input x-model="mailencryption" id="mailencryption" name="mailencryption" type="text"
value="{{ config('SETTINGS::MAIL:ENCRYPTION') }}"
class="form-control @error('mailencryption') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="mailfromadress">{{ __('Mail From Adress') }}:</label>
<input x-model="mailfromadress" id="mailfromadress" name="mailfromadress" type="text"
value="{{ config('SETTINGS::MAIL:FROM_ADDRESS') }}"
class="form-control @error('mailfromadress') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="mailfromname">{{ __('Mail From Name') }}:</label>
<input x-model="mailfromname" id="mailfromname" name="mailfromname" type="text"
value="{{ config('SETTINGS::MAIL:FROM_NAME') }}"
class="form-control @error('mailfromname') is-invalid @enderror">
</div>
</div>
</div>
<!-- DISCORD -->
<div class="col-md-3 px-3">
<div class="row mb-2">
<div class="col text-center">
<h1>Discord</h1>
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="discord-client-id">{{ __('Discord Client-ID') }}:</label>
<input x-model="discord-client-id" id="discord-client-id" name="discord-client-id" type="text"
value="{{ config('SETTINGS::DISCORD:CLIENT_ID') }}"
class="form-control @error('discord-client-id') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="discord-client-secret">{{ __('Discord Client-Secret') }}:</label>
<input x-model="discord-client-secret" id="discord-client-secret" name="discord-client-secret"
type="text" value="{{ config('SETTINGS::DISCORD:CLIENT_SECRET') }}"
class="form-control @error('discord-client-secret') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="discord-client-secret">{{ __('Discord Bot-Token') }}:</label>
<input x-model="discord-bot-token" id="discord-bot-token" name="discord-bot-token" type="text"
value="{{ config('SETTINGS::DISCORD:BOT_TOKEN') }}"
class="form-control @error('discord-bot-token') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="discord-client-secret">{{ __('Discord Guild-ID') }}:</label>
<input x-model="discord-guild-id" id="discord-guild-id" name="discord-guild-id" type="number"
value="{{ config('SETTINGS::DISCORD:GUILD_ID') }}"
class="form-control @error('discord-guild-id') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="discord-invite-url">{{ __('Discord Invite-URL') }}:</label>
<input x-model="discord-invite-url" id="discord-invite-url" name="discord-invite-url"
type="text" value="{{ config('SETTINGS::DISCORD:INVITE_URL') }}"
class="form-control @error('discord-invite-url') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="discord-role-id">{{ __('Discord Role-ID') }}:</label>
<input x-model="discord-role-id" id="discord-role-id" name="discord-role-id" type="number"
value="{{ config('SETTINGS::DISCORD:ROLE_ID') }}"
class="form-control @error('discord-role-id') is-invalid @enderror">
</div>
</div>
</div>
<div class="col-md-3 px-3">
<div class="row mb-2">
<div class="col text-center">
<h1>ReCaptcha</h1>
</div>
</div>
<div class="custom-control mb-3 p-0">
<div class="col m-0 p-0 d-flex justify-content-between align-items-center">
<div>
<input value="true" id="enable-recaptcha" name="enable-recaptcha"
{{ config('SETTINGS::RECAPTCHA:ENABLED') == 'true' ? 'checked' : '' }}
type="checkbox">
<label for="enable-recaptcha">{{ __('Enable ReCaptcha') }} </label>
</div>
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="recaptcha-site-key">{{ __('ReCaptcha Site-Key') }}:</label>
<input x-model="recaptcha-site-key" id="recaptcha-site-key" name="recaptcha-site-key"
type="text" value="{{ config('SETTINGS::RECAPTCHA:SITE_KEY') }}"
class="form-control @error('recaptcha-site-key') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="recaptcha-secret-key">{{ __('ReCaptcha Secret-Key') }}:</label>
<input x-model="recaptcha-secret-key" id="recaptcha-secret-key" name="recaptcha-secret-key"
type="text" value="{{ config('SETTINGS::RECAPTCHA:SECRET_KEY') }}"
class="form-control @error('recaptcha-secret-key') is-invalid @enderror">
</div>
</div>
</div>
</div>
<div class="row">
<button class="btn btn-primary mt-3 ml-3">{{ __('Submit') }}</button>
</div>
</form>
</div>

View file

@ -0,0 +1,144 @@
<div class="tab-pane mt-3" id="payment">
<form method="POST" enctype="multipart/form-data" class="mb-3"
action="{{ route('admin.settings.update.paymentsettings') }}">
@csrf
@method('PATCH')
<div class="row">
{{-- PayPal --}}
<div class="col-md-3 px-3">
<div class="row mb-2">
<div class="col text-center">
<h1>PayPal</h1>
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="paypal-client-id">{{ __('PayPal Client-ID') }}:</label>
<input x-model="paypal-client-id" id="paypal-client-id" name="paypal-client-id" type="text"
value="{{ config('SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID') }}"
class="form-control @error('paypal-client-id') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="paypal-client-secret">{{ __('PayPal Secret-Key') }}:</label>
<input x-model="paypal-client-secret" id="paypal-client-secret" name="paypal-client-secret"
type="text" value="{{ config('SETTINGS::PAYMENTS:PAYPAL:SECRET') }}"
class="form-control @error('paypal-client-secret') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="paypal-sandbox-id">{{ __('PayPal Sandbox Client-ID') }}:</label>
<small class="text-muted">({{ __('optional') }})</small>
<input x-model="paypal-sandbox-id" id="paypal-sandbox-id" name="paypal-sandbox-id" type="text"
value="{{ config('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID') }}"
class="form-control @error('paypal-sandbox-id') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="paypal-sandbox-secret">{{ __('PayPal Sandbox Secret-Key') }}:</label>
<small class="text-muted">({{ __('optional') }})</small>
<input x-model="paypal-sandbox-secret" id="paypal-sandbox-secret" name="paypal-sandbox-secret"
type="text" value="{{ config('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET') }}"
class="form-control @error('paypal-sandbox-secret') is-invalid @enderror">
</div>
</div>
</div>
{{-- Stripe --}}
<div class="col-md-3 px-3">
<div class="row mb-2">
<div class="col text-center">
<h1>Stripe</h1>
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="stripe-secret">{{ __('Stripe Secret-Key') }}:</label>
<input x-model="stripe-secret" id="stripe-secret" name="stripe-secret" type="text"
value="{{ config('SETTINGS::PAYMENTS:STRIPE:SECRET') }}"
class="form-control @error('stripe-secret') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="stripe-endpoint-secret">{{ __('Stripe Endpoint-Secret-Key') }}:</label>
<input x-model="stripe-endpoint-secret" id="stripe-endpoint-secret"
name="stripe-endpoint-secret" type="text"
value="{{ config('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET') }}"
class="form-control @error('stripe-endpoint-secret') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="stripe-test-secret">{{ __('Stripe Test Secret-Key') }}:</label>
<small class="text-muted">({{ __('optional') }})</small>
<input x-model="stripe-test-secret" id="stripe-test-secret" name="stripe-test-secret"
type="text" value="{{ config('SETTINGS::PAYMENTS:STRIPE:TEST_SECRET') }}"
class="form-control @error('stripe-test-secret') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<label for="stripe-endpoint-test-secret">{{ __('Stripe Test Endpoint-Secret-Key') }}:</label>
<small class="text-muted">({{ __('optional') }})</small>
<input x-model="stripe-endpoint-test-secret" id="stripe-endpoint-test-secret"
name="stripe-endpoint-test-secret" type="text"
value="{{ config('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET') }}"
class="form-control @error('stripe-endpoint-test-secret') is-invalid @enderror">
</div>
</div>
<div class="form-group mb-3">
<div class="custom-control p-0">
<div class="col m-0 p-0 d-flex justify-content-between align-items-center">
<label for="stripe-methods">{{ __('Payment Methods') }}:</label>
<i data-toggle="popover" data-trigger="hover" data-html="true"
data-content="Comma separated list of payment methods without whitespaces. <br><br> Example: card,klarna,sepa"
class="fas fa-info-circle"></i>
</div>
<input x-model="stripe-methods" id="stripe-methods" name="stripe-methods" type="text"
value="{{ config('SETTINGS::PAYMENTS:STRIPE:METHODS') }}"
class="form-control @error('stripe-methods') is-invalid @enderror">
</div>
</div>
</div>
{{-- Other --}}
<div class="col-md-3 px-3">
<div class="row mb-2">
<div class="col text-center">
<h1>Other</h1>
</div>
</div>
<!-- Tax -->
<div class="form-group mb-3">
<div class="custom-control p-0">
<div class="col m-0 p-0 d-flex justify-content-between align-items-center">
<label for="sales-tax">{{ __('Tax Value in %') }}:</label>
<i data-toggle="popover" data-trigger="hover" data-html="true"
data-content="Tax Value that will be added to the total price of the order. <br><br> Example: 19 results in (19%)"
class="fas fa-info-circle"></i>
</div>
<input x-model="sales-tax" id="sales-tax" name="sales-tax" type="number"
value="{{ config('SETTINGS::PAYMENTS:SALES_TAX') }}"
class="form-control @error('sales-tax') is-invalid @enderror">
</div>
</div>
</div>
</div>
<div class="row">
<button class="btn btn-primary ml-3 mt-3">{{ __('Submit') }}</button>
</div>
</form>
</div>

View file

@ -0,0 +1,208 @@
<div class="tab-pane mt-3" id="system">
<form method="POST" enctype="multipart/form-data" class="mb-3"
action="{{ route('admin.settings.update.systemsettings') }}">
@csrf
@method('PATCH')
<div class="row">
{{-- System --}}
<div class="col-md-3 px-3">
<div class="row mb-2">
<div class="col text-center">
<h1>{{ __('System') }}</h1>
</div>
</div>
<div class="form-group">
<div class="custom-control mb-1 p-0">
<div class="col m-0 p-0 d-flex justify-content-between align-items-center">
<div>
<input value="true" id="register-ip-check" name="register-ip-check"
{{ config('SETTINGS::SYSTEM:REGISTER_IP_CHECK') == 'true' ? 'checked' : '' }}
type="checkbox">
<label for="register-ip-check">{{ __('Register IP Check') }} </label>
</div>
<i data-toggle="popover" data-trigger="hover" data-html="true"
data-content="{{ __('Prevent users from making multiple accounts using the same IP address.') }}"
class="fas fa-info-circle"></i>
</div>
</div>
<div class="custom-control mb-3 p-0">
<div class="col m-0 p-0 d-flex justify-content-between align-items-center">
<div>
<input value="true" id="server-create-charge-first" name="server-create-charge-first"
{{ config('SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR') == 'true' ? 'checked' : '' }}
type="checkbox">
<label for="server-create-charge-first">{{ __('Charge first hour at creation') }}
</label>
</div>
<i data-toggle="popover" data-trigger="hover" data-html="true"
data-content="{{ __('Charges the first hour worth of credits upon creating a server.') }}"
class="fas fa-info-circle"></i>
</div>
</div>
<div class="custom-control mb-3 p-0">
<label for="credits-display-name">{{ __('Credits Display Name') }}</label>
<input x-model="credits-display-name" id="credits-display-name" name="credits-display-name"
type="text" value="{{ config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME', 'Credits') }}"
class="form-control @error('credits-display-name') is-invalid @enderror" required>
</div>
<div class="custom-control p-0 mb-3">
<div class="col m-0 p-0 d-flex justify-content-between align-items-center">
<label for="phpmyadmin-url">{{ __('PHPMyAdmin URL') }}</label>
<i data-toggle="popover" data-trigger="hover" data-html="true"
data-content="{{ __('Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!</strong>') }}"
class="fas fa-info-circle"></i>
</div>
<input x-model="phpmyadmin-url" id="phpmyadmin-url" name="phpmyadmin-url" type="text"
value="{{ config('SETTINGS::MISC:PHPMYADMIN:URL') }}"
class="form-control @error('phpmyadmin-url') is-invalid @enderror">
</div>
<div class="custom-control p-0 mb-3">
<div class="col m-0 p-0 d-flex justify-content-between align-items-center">
<label for="pterodactyl-url">{{ __('Pterodactyl URL') }}</label>
<i data-toggle="popover" data-trigger="hover" data-html="true"
data-content="{{ __('Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!</strong>') }}"
class="fas fa-info-circle"></i>
</div>
<input x-model="pterodactyl-url" id="pterodactyl-url" name="pterodactyl-url" type="text"
value="{{ config('SETTINGS::SYSTEM:PTERODACTYL:URL') }}"
class="form-control @error('pterodactyl-url') is-invalid @enderror" required>
</div>
<div class="custom-control p-0 mb-3">
<div class="col m-0 p-0 d-flex justify-content-between align-items-center">
<label for="pterodactyl-api-key">{{ __('Pterodactyl API Key') }}</label>
<i data-toggle="popover" data-trigger="hover" data-html="true"
data-content="{{ __('Enter the API Key to your Pterodactyl installation.') }}"
class="fas fa-info-circle"></i>
</div>
<input x-model="pterodactyl-api-key" id="pterodactyl-api-key" name="pterodactyl-api-key"
type="text" value="{{ config('SETTINGS::SYSTEM:PTERODACTYL:TOKEN') }}"
class="form-control @error('pterodactyl-api-key') is-invalid @enderror" required>
</div>
</div>
</div>
{{-- User --}}
<div class="col-md-3 px-3">
<div class="row mb-2">
<div class="col text-center">
<h1>{{ __('User') }}</h1>
</div>
</div>
<div class="form-group">
<div class="custom-control mb-1 p-0">
<input value="true" id="force-discord-verification" name="force-discord-verification"
{{ config('SETTINGS::USER:FORCE_DISCORD_VERIFICATION') == 'true' ? 'checked' : '' }}
type="checkbox">
<label for="force-discord-verification">{{ __('Force Discord verification') }}
</label>
</div>
<div class="custom-control mb-3 p-0">
<input value="true" id="force-email-verification" name="force-email-verification"
{{ config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION') == 'true' ? 'checked' : '' }}
type="checkbox">
<label for="force-email-verification">{{ __('Force E-Mail verification') }} </label>
</div>
<div class="custom-control mb-3 p-0">
<label for="initial-credits">{{ __('Initial Credits') }}</label>
<input x-model="initial-credits" id="initial-credits" name="initial-credits" type="number"
value="{{ config('SETTINGS::USER:INITIAL_CREDITS') }}"
class="form-control @error('initial-credits') is-invalid @enderror" required>
</div>
<div class="custom-control mb-3 p-0">
<label for="initial-server-limit">{{ __('Initial Server Limit') }}</label>
<input x-model="initial-server-limit" id="initial-server-limit" name="initial-server-limit"
type="number" value="{{ config('SETTINGS::USER:INITIAL_SERVER_LIMIT') }}"
class="form-control @error('initial-server-limit') is-invalid @enderror" required>
</div>
<div class="custom-control mb-3 p-0">
<label
for="credits-reward-amount-discord">{{ __('Credits Reward Amount - Discord') }}</label>
<input x-model="credits-reward-amount-discord" id="credits-reward-amount-discord"
name="credits-reward-amount-discord" type="number"
value="{{ config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD') }}"
class="form-control @error('credits-reward-amount-discord') is-invalid @enderror" required>
</div>
<div class="custom-control mb-3 p-0">
<label for="credits-reward-amount-email">{{ __('Credits Reward Amount - E-Mail') }}</label>
<input x-model="credits-reward-amount-email" id="credits-reward-amount-email"
name="credits-reward-amount-email" type="number"
value="{{ config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL') }}"
class="form-control @error('credits-reward-amount-email') is-invalid @enderror" required>
</div>
<div class="custom-control mb-3 p-0">
<label for="server-limit-discord">{{ __('Server Limit Increase - Discord') }}</label>
<input x-model="server-limit-discord" id="server-limit-discord" name="server-limit-discord"
type="number"
value="{{ config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') }}"
class="form-control @error('server-limit-discord') is-invalid @enderror" required>
</div>
<div class="custom-control mb-3 p-0">
<label for="server-limit-email">{{ __('Server Limit Increase - E-Mail') }}</label>
<input x-model="server-limit-email" id="server-limit-email" name="server-limit-email"
type="number"
value="{{ config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') }}"
class="form-control @error('server-limit-email') is-invalid @enderror" required>
</div>
</div>
</div>
{{-- Server --}}
<div class="col-md-3 px-3">
<div class="row mb-2">
<div class="col text-center">
<h1>{{ __('Server') }}</h1>
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3 p-0">
<div class="col m-0 p-0 d-flex justify-content-between align-items-center">
<label for="initial-credits">{{ __('Server Allocation Limit') }}</label>
<i data-toggle="popover" data-trigger="hover" data-html="true"
data-content="{{ __('The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created!') }}"
class="fas fa-info-circle"></i>
</div>
<input x-model="allocation-limit" id="allocation-limit" name="allocation-limit" type="number"
value="{{ config('SETTINGS::SERVER:ALLOCATION_LIMIT') }}"
class="form-control @error('allocation-limit') is-invalid @enderror" required>
</div>
</div>
<div class="form-group">
<div class="custom-file mb-3 mt-3">
<input type="file" accept="image/png,image/jpeg,image/jpg" class="custom-file-input" name="icon"
id="icon">
<label class="custom-file-label selected" for="icon">{{ __('Select panel icon') }}</label>
</div>
@error('icon')
<span class="text-danger">
{{ $message }}
</span>
@enderror
<div class="form-group">
<div class="custom-file mb-3">
<input type="file" accept="image/x-icon" class="custom-file-input" name="favicon"
id="favicon">
<label class="custom-file-label selected"
for="favicon">{{ __('Select panel favicon') }}</label>
</div>
@error('favicon')
<span class="text-danger">
{{ $message }}
</span>
@enderror
</div>
</div>
</div>
</div>
<div class="row">
<button class="btn btn-primary ml-3 mt-3">{{ __('Submit') }}</button>
</div>
</form>
</div>

View file

@ -1,5 +1,6 @@
<!doctype html> <!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
@ -8,7 +9,9 @@
<meta name="csrf-token" content="{{ csrf_token() }}"> <meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title> <title>{{ config('app.name', 'Laravel') }}</title>
<link rel="icon" href="{{\Illuminate\Support\Facades\Storage::disk('public')->exists('favicon.ico') ? \Illuminate\Support\Facades\Storage::disk('public')->url('favicon.ico') : asset('favicon.ico')}}" type="image/x-icon"> <link rel="icon"
href="{{ \Illuminate\Support\Facades\Storage::disk('public')->exists('favicon.ico') ? \Illuminate\Support\Facades\Storage::disk('public')->url('favicon.ico') : asset('favicon.ico') }}"
type="image/x-icon">
<!-- Scripts --> <!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script> <script src="{{ asset('js/app.js') }}" defer></script>
@ -17,27 +20,32 @@
<link rel="dns-prefetch" href="//fonts.gstatic.com"> <link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
<link rel="stylesheet" href="{{asset('css/app.css')}}"> <link rel="stylesheet" href="{{ asset('css/app.css') }}">
<link rel="preload" href="{{asset('plugins/fontawesome-free/css/all.min.css')}}" as="style" onload="this.onload=null;this.rel='stylesheet'"> <link rel="preload" href="{{ asset('plugins/fontawesome-free/css/all.min.css') }}" as="style"
<noscript><link rel="stylesheet" href="{{asset('plugins/fontawesome-free/css/all.min.css')}}"></noscript> onload="this.onload=null;this.rel='stylesheet'">
{!! htmlScriptTagJsApi() !!} <noscript>
<link rel="stylesheet" href="{{ asset('plugins/fontawesome-free/css/all.min.css') }}">
</noscript>
@if (config('SETTINGS::RECAPTCHA:ENABLED') == 'true')
{!! htmlScriptTagJsApi() !!}
@endif
</head> </head>
@yield('content') @yield('content')
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10.14.1/dist/sweetalert2.all.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@10.14.1/dist/sweetalert2.all.min.js"></script>
<script> <script>
@if(Session::has('error')) @if (Session::has('error'))
Swal.fire({ Swal.fire({
icon: 'error', icon: 'error',
title: 'Oops...', title: 'Oops...',
html: '{{Session::get('error')}}', html: '{{ Session::get('error') }}',
}) })
@endif @endif
@if(Session::has('success')) @if (Session::has('success'))
Swal.fire({ Swal.fire({
icon: 'success', icon: 'success',
title: '{{Session::get('success')}}', title: '{{ Session::get('success') }}',
position: 'top-end', position: 'top-end',
showConfirmButton: false, showConfirmButton: false,
background : '#343a40', background : '#343a40',
@ -45,10 +53,11 @@
timer: 3000, timer: 3000,
timerProgressBar: true, timerProgressBar: true,
didOpen: (toast) => { didOpen: (toast) => {
toast.addEventListener('mouseenter', Swal.stopTimer) toast.addEventListener('mouseenter', Swal.stopTimer)
toast.addEventListener('mouseleave', Swal.resumeTimer) toast.addEventListener('mouseleave', Swal.resumeTimer)
} }
}) })
@endif @endif
</script> </script>
</html> </html>

View file

@ -32,6 +32,7 @@
<noscript> <noscript>
<link rel="stylesheet" href="{{ asset('plugins/fontawesome-free/css/all.min.css') }}"> <link rel="stylesheet" href="{{ asset('plugins/fontawesome-free/css/all.min.css') }}">
</noscript> </noscript>
<script src="{{ asset('js/app.js') }}"></script>
</head> </head>
<body class="sidebar-mini layout-fixed dark-mode" style="height: auto;"> <body class="sidebar-mini layout-fixed dark-mode" style="height: auto;">
@ -53,7 +54,6 @@
<!-- Select2 --> <!-- Select2 -->
<script src={{ asset('plugins/select2/js/select2.min.js') }}></script> <script src={{ asset('plugins/select2/js/select2.min.js') }}></script>
<div class="wrapper"> <div class="wrapper">
<!-- Navbar --> <!-- Navbar -->
<nav class="main-header sticky-top navbar navbar-expand navbar-dark navbar-light"> <nav class="main-header sticky-top navbar navbar-expand navbar-dark navbar-light">
@ -68,34 +68,34 @@
class="fas fa-home mr-2"></i>{{ __('Home') }}</a> class="fas fa-home mr-2"></i>{{ __('Home') }}</a>
</li> </li>
<li class="nav-item d-none d-sm-inline-block"> <li class="nav-item d-none d-sm-inline-block">
<a href="{{ env('DISCORD_INVITE_URL') }}" class="nav-link" target="__blank"><i <a href="{{ config('SETTINGS::DISCORD:INVITE_URL') }}" class="nav-link" target="__blank"><i
class="fab fa-discord mr-2"></i>{{ __('Discord') }}</a> class="fab fa-discord mr-2"></i>{{ __('Discord') }}</a>
</li> </li>
<!-- Language Selection --> <!-- Language Selection -->
<li class="nav-item dropdown"> @if (config('SETTINGS::LOCALE:CLIENTS_CAN_CHANGE') == 'true')
<a class="nav-link" href="#" id="languageDropdown" role="button" data-toggle="dropdown" <li class="nav-item dropdown">
aria-haspopup="true" aria-expanded="false"> <a class="nav-link" href="#" id="languageDropdown" role="button" data-toggle="dropdown"
<span class="mr-1 d-lg-inline text-gray-600"> aria-haspopup="true" aria-expanded="false">
<small><i class="fa fa-language mr-2"></i></small>{{ __('Languages') }} <span class="mr-1 d-lg-inline text-gray-600">
</span> <small><i class="fa fa-language mr-2"></i></small>{{ __('Language') }}
</a> </span>
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" </a>
aria-labelledby="changeLocale"> <div class="dropdown-menu dropdown-menu-right shadow animated--grow-in"
<form method="post" action="{{ route('changeLocale') }}" class="nav-item text-center"> aria-labelledby="changeLocale">
@csrf <form method="post" action="{{ route('changeLocale') }}" class="nav-item text-center">
@foreach (config('app.available_locales') as $key => $value) @csrf
@if (!in_array(strtolower($key), UNSUPPORTED_LANGS)) @foreach (explode(',', config('SETTINGS::LOCALE:AVAILABLE')) as $key)
<button class="dropdown-item" name="inputLocale" value="{{ $value }}"> <button class="dropdown-item" name="inputLocale" value="{{ $key }}">
{{ $key }} {{ __($key) }}
</button> </button>
@endif
@endforeach @endforeach
</form> </form>
</div> </div>
</li> </li>
<!-- End Language Selection --> <!-- End Language Selection -->
@endif
</ul> </ul>
<!-- Right navbar links --> <!-- Right navbar links -->
@ -230,7 +230,7 @@
</a> </a>
</li> </li>
@if ((env('PAYPAL_SECRET') && env('PAYPAL_CLIENT_ID')) || env('APP_ENV', 'local') == 'local') @if ((config('SETTINGS::PAYMENTS:PAYPAL:SECRET') && config('SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID')) || env('APP_ENV', 'local') == 'local')
<li class="nav-item"> <li class="nav-item">
<a href="{{ route('store.index') }}" class="nav-link @if (Request::routeIs('store.*') || Request::routeIs('checkout')) active @endif"> <a href="{{ route('store.index') }}" class="nav-link @if (Request::routeIs('store.*') || Request::routeIs('checkout')) active @endif">
<i class="nav-icon fa fa-coins"></i> <i class="nav-icon fa fa-coins"></i>
@ -251,13 +251,6 @@
</a> </a>
</li> </li>
<li class="nav-item">
<a href="{{ route('admin.configurations.index') }}"
class="nav-link @if (Request::routeIs('admin.configurations.*')) active @endif">
<i class="nav-icon fas fa-cogs"></i>
<p>{{ __('Configurations') }}</p>
</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a href="{{ route('admin.settings.index') }}" <a href="{{ route('admin.settings.index') }}"
@ -300,8 +293,7 @@
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="{{ route('admin.store.index') }}" <a href="{{ route('admin.store.index') }}" class="nav-link @if (Request::routeIs('admin.store.*')) active @endif">
class="nav-link @if (Request::routeIs('admin.store.*')) active @endif">
<i class="nav-icon fas fa-shopping-basket"></i> <i class="nav-icon fas fa-shopping-basket"></i>
<p>{{ __('Store') }}</p> <p>{{ __('Store') }}</p>
</a> </a>
@ -411,6 +403,27 @@
</div> </div>
<!-- ./wrapper --> <!-- ./wrapper -->
<!-- Scripts -->
{{-- <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> --}}
{{-- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> --}}
{{-- <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> --}}
{{-- <script src="{{ asset('js/adminlte.min.js') }}"></script> --}}
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10.14.1/dist/sweetalert2.all.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.24/datatables.min.js"></script>
<!-- Summernote -->
<script src="{{ asset('plugins/summernote/summernote-bs4.min.js') }}"></script>
<!-- select2 -->
<script src="{{ asset('plugins/select2/js/select2.min.js') }}"></script>
<!-- Moment.js -->
<script src="{{ asset('plugins/moment/moment.min.js') }}"></script>
<!-- Datetimepicker -->
<script src="{{ asset('plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js') }}"></script>
<!-- Select2 -->
<script src={{ asset('plugins/select2/js/select2.min.js') }}></script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('[data-toggle="popover"]').popover(); $('[data-toggle="popover"]').popover();
@ -430,7 +443,6 @@
html: '{{ Session::get('error') }}', html: '{{ Session::get('error') }}',
}) })
@endif @endif
@if (Session::has('success')) @if (Session::has('success'))
Swal.fire({ Swal.fire({
icon: 'success', icon: 'success',

View file

@ -6,13 +6,13 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row mb-2"> <div class="row mb-2">
<div class="col-sm-6"> <div class="col-sm-6">
<h1>{{__('Profile')}}</h1> <h1>{{ __('Profile') }}</h1>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<ol class="breadcrumb float-sm-right"> <ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li> <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
<li class="breadcrumb-item"><a class="text-muted" <li class="breadcrumb-item"><a class="text-muted"
href="{{route('profile.index')}}">{{__('Profile')}}</a> href="{{ route('profile.index') }}">{{ __('Profile') }}</a>
</li> </li>
</ol> </ol>
</div> </div>
@ -27,36 +27,35 @@
<div class="row"> <div class="row">
<div class="col-lg-12 px-0"> <div class="col-lg-12 px-0">
@if(!Auth::user()->hasVerifiedEmail() && strtolower($force_email_verification) == 'true') @if (!Auth::user()->hasVerifiedEmail() && strtolower($force_email_verification) == 'true')
<div class="alert alert-warning p-2 m-2"> <div class="alert alert-warning p-2 m-2">
<h5><i class="icon fas fa-exclamation-circle"></i>{{__('Required Email verification!')}} <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Required Email verification!') }}
</h5> </h5>
{{__('You have not yet verified your email address')}} {{ __('You have not yet verified your email address') }}
<a class="text-primary" <a class="text-primary"
href="{{route('verification.send')}}">{{__('Click here to resend verification email')}}</a> href="{{ route('verification.send') }}">{{ __('Click here to resend verification email') }}</a>
<br> <br>
{{__('Please contact support If you didnt receive your verification email.')}} {{ __('Please contact support If you didnt receive your verification email.') }}
</div> </div>
@endif @endif
@if(is_null(Auth::user()->discordUser) && strtolower($force_discord_verification) == 'true') @if (is_null(Auth::user()->discordUser) && strtolower($force_discord_verification) == 'true')
@if(!empty(env('DISCORD_CLIENT_ID')) && !empty(env('DISCORD_CLIENT_SECRET'))) @if (!empty(config('SETTINGS::DISCORD:CLIENT_ID')) && !empty(config('SETTINGS::DISCORD:CLIENT_SECRET')))
<div class="alert alert-warning p-2 m-2"> <div class="alert alert-warning p-2 m-2">
<h5> <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Required Discord verification!') }}
<i class="icon fas fa-exclamation-circle"></i>{{__('Required Discord verification!')}}
</h5> </h5>
{{__('You have not yet verified your discord account')}} {{ __('You have not yet verified your discord account') }}
<a class="text-primary" <a class="text-primary"
href="{{route('auth.redirect')}}">{{__('Login with discord')}}</a> <br> href="{{ route('auth.redirect') }}">{{ __('Login with discord') }}</a> <br>
{{__('Please contact support If you face any issues.')}} {{ __('Please contact support If you face any issues.') }}
</div> </div>
@else @else
<div class="alert alert-danger p-2 m-2"> <div class="alert alert-danger p-2 m-2">
<h5> <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Required Discord verification!') }}
<i class="icon fas fa-exclamation-circle"></i>{{__('Required Discord verification!')}}
</h5> </h5>
{{__('Due to system settings you are required to verify your discord account!')}} <br> {{ __('Due to system settings you are required to verify your discord account!') }} <br>
{{__('It looks like this hasnt been set-up correctly! Please contact support.')}}' {{ __('It looks like this hasnt been set-up correctly! Please contact support.') }}'
</div> </div>
@endif @endif
@endif @endif
@ -64,7 +63,7 @@
</div> </div>
</div> </div>
<form class="form" action="{{route('profile.update' , Auth::user()->id)}}" method="post"> <form class="form" action="{{ route('profile.update', Auth::user()->id) }}" method="post">
@csrf @csrf
@method('PATCH') @method('PATCH')
<div class="card"> <div class="card">
@ -73,43 +72,42 @@
<div class="row"> <div class="row">
<div class="col-12 col-sm-auto mb-4"> <div class="col-12 col-sm-auto mb-4">
<div class="slim rounded-circle border-secondary border text-gray-dark" <div class="slim rounded-circle border-secondary border text-gray-dark"
data-label="Change your avatar" data-label="Change your avatar" data-max-file-size="3"
data-max-file-size="3" data-save-initial-image="true" style="width: 140px;height:140px; cursor: pointer"
data-save-initial-image="true" data-size="140,140">
style="width: 140px;height:140px; cursor: pointer" <img src="{{ $user->getAvatar() }}" alt="avatar">
data-size="140,140">
<img src="{{$user->getAvatar()}}" alt="avatar">
</div> </div>
</div> </div>
<div class="col d-flex flex-column flex-sm-row justify-content-between mb-3"> <div class="col d-flex flex-column flex-sm-row justify-content-between mb-3">
<div class="text-center text-sm-left mb-2 mb-sm-0"><h4 <div class="text-center text-sm-left mb-2 mb-sm-0">
class="pt-sm-2 pb-1 mb-0 text-nowrap">{{$user->name}}</h4> <h4 class="pt-sm-2 pb-1 mb-0 text-nowrap">{{ $user->name }}</h4>
<p class="mb-0">{{$user->email}} <p class="mb-0">{{ $user->email }}
@if($user->hasVerifiedEmail()) @if ($user->hasVerifiedEmail())
<i data-toggle="popover" data-trigger="hover" data-content="Verified" <i data-toggle="popover" data-trigger="hover" data-content="Verified"
class="text-success fas fa-check-circle"></i> class="text-success fas fa-check-circle"></i>
@else @else
<i data-toggle="popover" data-trigger="hover" <i data-toggle="popover" data-trigger="hover" data-content="Not verified"
data-content="Not verified" class="text-danger fas fa-exclamation-circle"></i>
class="text-danger fas fa-exclamation-circle"></i>
@endif @endif
</p> </p>
<div class="mt-1"> <div class="mt-1">
<span class="badge badge-primary"><i class="fa fa-coins mr-2"></i>{{$user->Credits()}}</span> <span class="badge badge-primary"><i
class="fa fa-coins mr-2"></i>{{ $user->Credits() }}</span>
</div> </div>
</div> </div>
<div class="text-center text-sm-right"><span <div class="text-center text-sm-right"><span
class="badge badge-secondary">{{$user->role}}</span> class="badge badge-secondary">{{ $user->role }}</span>
<div class="text-muted"><small>{{$user->created_at->isoFormat('LL')}}</small> <div class="text-muted">
<small>{{ $user->created_at->isoFormat('LL') }}</small>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="nav-item"><a href="javasript:void(0)" <li class="nav-item"><a href="javasript:void(0)"
class="active nav-link">{{__('Settings')}}</a> class="active nav-link">{{ __('Settings') }}</a>
</li> </li>
</ul> </ul>
<div class="tab-content pt-3"> <div class="tab-content pt-3">
@ -134,29 +132,28 @@
@endif @endif
<div class="form-group"><label>{{__('Name')}}</label> <input <div class="form-group"><label>{{__('Name')}}</label> <input
class="form-control @error('name') is-invalid @enderror" class="form-control @error('name') is-invalid @enderror"
type="text" name="name" type="text" name="name" placeholder="{{ $user->name }}"
placeholder="{{$user->name}}" value="{{$user->name}}"> value="{{ $user->name }}">
@error('name') @error('name')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </div>
@enderror @enderror
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="form-group"><label>{{__('Email')}}</label> <input <div class="form-group"><label>{{ __('Email') }}</label> <input
class="form-control @error('email') is-invalid @enderror" class="form-control @error('email') is-invalid @enderror"
type="text" type="text" placeholder="{{ $user->email }}" name="email"
placeholder="{{$user->email}}" name="email" value="{{ $user->email }}">
value="{{$user->email}}">
@error('email') @error('email')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </div>
@enderror @enderror
</div> </div>
</div> </div>
@ -165,33 +162,34 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-12 col-sm-6 mb-3"> <div class="col-12 col-sm-6 mb-3">
<div class="mb-3"><b>{{__('Change Password')}}</b></div> <div class="mb-3"><b>{{ __('Change Password') }}</b></div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="form-group"><label>{{__('Current Password')}}</label> <div class="form-group">
<label>{{ __('Current Password') }}</label>
<input <input
class="form-control @error('current_password') is-invalid @enderror" class="form-control @error('current_password') is-invalid @enderror"
name="current_password" type="password" name="current_password" type="password" placeholder="••••••">
placeholder="••••••">
@error('current_password') @error('current_password')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </div>
@enderror @enderror
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="form-group"><label>{{__('New Password')}}</label> <input <div class="form-group"><label>{{ __('New Password') }}</label>
<input
class="form-control @error('new_password') is-invalid @enderror" class="form-control @error('new_password') is-invalid @enderror"
name="new_password" type="password" placeholder="••••••"> name="new_password" type="password" placeholder="••••••">
@error('new_password') @error('new_password')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </div>
@enderror @enderror
</div> </div>
</div> </div>
@ -199,60 +197,62 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="form-group"> <div class="form-group">
<label>{{__('Confirm Password')}}</span></label> <label>{{ __('Confirm Password') }}</span></label>
<input <input
class="form-control @error('new_password_confirmation') is-invalid @enderror" class="form-control @error('new_password_confirmation') is-invalid @enderror"
name="new_password_confirmation" type="password" name="new_password_confirmation" type="password"
placeholder="••••••"> placeholder="••••••">
@error('new_password_confirmation') @error('new_password_confirmation')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </div>
@enderror @enderror
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@if(!empty(env('DISCORD_CLIENT_ID')) && !empty(env('DISCORD_CLIENT_SECRET'))) @if (!empty(config('SETTINGS::DISCORD:CLIENT_ID')) && !empty(config('SETTINGS::DISCORD:CLIENT_SECRET')))
<div class="col-12 col-sm-5 offset-sm-1 mb-3"> <div class="col-12 col-sm-5 offset-sm-1 mb-3">
@if(is_null(Auth::user()->discordUser)) @if (is_null(Auth::user()->discordUser))
<b>{{__('Link your discord account!')}}</b> <b>{{ __('Link your discord account!') }}</b>
<div class="verify-discord"> <div class="verify-discord">
<div class="mb-3"> <div class="mb-3">
@if($credits_reward_after_verify_discord) @if ($credits_reward_after_verify_discord)
<p>{{__('By verifying your discord account, you receive extra Credits and increased Server amounts')}} <p>{{ __('By verifying your discord account, you receive extra Credits and increased Server amounts') }}
</p> </p>
@endif @endif
</div> </div>
</div> </div>
<a class="btn btn-light" href="{{route('auth.redirect')}}"> <a class="btn btn-light" href="{{ route('auth.redirect') }}">
<i class="fab fa-discord mr-2"></i>{{__('Login with Discord')}} <i class="fab fa-discord mr-2"></i>{{ __('Login with Discord') }}
</a> </a>
@else @else
<div class="verified-discord"> <div class="verified-discord">
<div class="my-3 callout callout-info"> <div class="my-3 callout callout-info">
<p>{{__('You are verified!')}}</p> <p>{{ __('You are verified!') }}</p>
</div> </div>
</div> </div>
<div class="row pl-2"> <div class="row pl-2">
<div class="small-box bg-dark"> <div class="small-box bg-dark">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<div class="p-3"> <div class="p-3">
<h3>{{$user->discordUser->username}} <h3>{{ $user->discordUser->username }}
<sup>{{$user->discordUser->locale}}</sup></h3> <sup>{{ $user->discordUser->locale }}</sup>
<p>{{$user->discordUser->id}} </h3>
<p>{{ $user->discordUser->id }}
</p> </p>
</div> </div>
<div class="p-3"><img width="100px" height="100px" <div class="p-3"><img width="100px"
class="rounded-circle" height="100px" class="rounded-circle"
src="{{$user->discordUser->getAvatar()}}" src="{{ $user->discordUser->getAvatar() }}"
alt="avatar"></div> alt="avatar"></div>
</div> </div>
<div class="small-box-footer"> <div class="small-box-footer">
<a href="{{route('auth.redirect')}}"> <a href="{{ route('auth.redirect') }}">
<i class="fab fa-discord mr-1"></i>{{__('Re-Sync Discord')}} <i
class="fab fa-discord mr-1"></i>{{ __('Re-Sync Discord') }}
</a> </a>
</div> </div>
</div> </div>
@ -265,7 +265,7 @@
<div class="row"> <div class="row">
<div class="col d-flex justify-content-end"> <div class="col d-flex justify-content-end">
<button class="btn btn-primary" <button class="btn btn-primary"
type="submit">{{__('Save Changes')}}</button> type="submit">{{ __('Save Changes') }}</button>
</div> </div>
</div> </div>

View file

@ -42,7 +42,9 @@
@if (Auth::user()->role == 'admin') @if (Auth::user()->role == 'admin')
{{ __('Make sure to link your products to nodes and eggs.') }} <br> {{ __('Make sure to link your products to nodes and eggs.') }} <br>
{{ __('There has to be at least 1 valid product for server creation') }} {{ __('There has to be at least 1 valid product for server creation') }}
<a href="{{route('admin.overview.sync')}}">{{ __('Sync now') }}</a>
@endif @endif
</p> </p>
<ul> <ul>
@if ($productCount === 0) @if ($productCount === 0)

View file

@ -55,8 +55,8 @@
</a> </a>
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" <div class="dropdown-menu dropdown-menu-right shadow animated--fade-in"
aria-labelledby="dropdownMenuLink"> aria-labelledby="dropdownMenuLink">
@if (!empty(env('PHPMYADMIN_URL'))) @if (!empty(config('SETTINGS::MISC:PHPMYADMIN:URL')))
<a href="{{ env('PHPMYADMIN_URL', 'http://localhost') }}" <a href="{{ config('SETTINGS::MISC:PHPMYADMIN:URL') }}"
class="dropdown-item text-info" target="__blank"><i title="manage" class="dropdown-item text-info" target="__blank"><i title="manage"
class="fas fa-database mr-2"></i><span>{{ __('Database') }}</span></a> class="fas fa-database mr-2"></i><span>{{ __('Database') }}</span></a>
@endif @endif
@ -149,7 +149,7 @@
</div> </div>
<div class="card-footer d-flex align-items-center justify-content-between"> <div class="card-footer d-flex align-items-center justify-content-between">
<a href="{{ env('PTERODACTYL_URL', 'http://localhost') }}/server/{{ $server->identifier }}" <a href="{{ config('SETTINGS::SYSTEM:PTERODACTYL:URL') }}/server/{{ $server->identifier }}"
target="__blank" target="__blank"
class="btn btn-info mx-3 w-100 align-items-center justify-content-center d-flex"> class="btn btn-info mx-3 w-100 align-items-center justify-content-center d-flex">
<i class="fas fa-tools mr-2"></i> <i class="fas fa-tools mr-2"></i>

View file

@ -78,7 +78,7 @@
<p class="lead">{{ __('Payment Methods') }}:</p> <p class="lead">{{ __('Payment Methods') }}:</p>
<div> <div>
@if (env('PAYPAL_SANDBOX_SECRET') || env('PAYPAL_SECRET')) @if (config('SETTINGS::PAYMENTS:PAYPAL:SECRET') || config('SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET'))
<label class="text-center " for="paypal"> <label class="text-center " for="paypal">
<img class="mb-3" height="50" <img class="mb-3" height="50"
src="{{ url('/images/paypal_logo.png') }}"></br> src="{{ url('/images/paypal_logo.png') }}"></br>
@ -88,7 +88,7 @@
</input> </input>
</label> </label>
@endif @endif
@if (env('STRIPE_TEST_SECRET') || env('STRIPE_SECRET')) @if (config('SETTINGS::PAYMENTS:STRIPE:TEST_SECRET') || config('SETTINGS::PAYMENTS:STRIPE:SECRET'))
<label class="ml-5 text-center " for="stripe"> <label class="ml-5 text-center " for="stripe">
<img class="mb-3" height="50" <img class="mb-3" height="50"
src="{{ url('/images/stripe_logo.png') }}" /></br> src="{{ url('/images/stripe_logo.png') }}" /></br>

View file

@ -1,8 +1,10 @@
<?php <?php
use App\Classes\Settings\Misc;
use App\Classes\Settings\Payments;
use App\Http\Controllers\Admin\ActivityLogController; use App\Http\Controllers\Admin\ActivityLogController;
use App\Http\Controllers\Admin\ApplicationApiController; use App\Http\Controllers\Admin\ApplicationApiController;
use App\Http\Controllers\Admin\ConfigurationController; use App\Http\Controllers\Admin\InvoiceController;
use App\Http\Controllers\Admin\OverViewController; use App\Http\Controllers\Admin\OverViewController;
use App\Http\Controllers\Admin\PaymentController; use App\Http\Controllers\Admin\PaymentController;
use App\Http\Controllers\Admin\CreditProductController; use App\Http\Controllers\Admin\CreditProductController;
@ -23,6 +25,9 @@ use App\Http\Controllers\TranslationController;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use App\Classes\Settings\Language;
use App\Classes\Settings\Invoices;
use App\Classes\Settings\System;
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -72,8 +77,6 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () {
Route::get('payment/StripeSuccess', [PaymentController::class, 'StripeSuccess'])->name('payment.StripeSuccess'); Route::get('payment/StripeSuccess', [PaymentController::class, 'StripeSuccess'])->name('payment.StripeSuccess');
Route::get('payment/Cancel', [PaymentController::class, 'Cancel'])->name('payment.Cancel'); Route::get('payment/Cancel', [PaymentController::class, 'Cancel'])->name('payment.Cancel');
Route::get('users/logbackin', [UserController::class, 'logBackIn'])->name('users.logbackin'); Route::get('users/logbackin', [UserController::class, 'logBackIn'])->name('users.logbackin');
#discord #discord
@ -85,14 +88,18 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () {
#switch language #switch language
Route::post('changelocale', [TranslationController::class, 'changeLocale'])->name('changeLocale'); Route::post('changelocale', [TranslationController::class, 'changeLocale'])->name('changeLocale');
#admin #admin
Route::prefix('admin')->name('admin.')->middleware('admin')->group(function () { Route::prefix('admin')->name('admin.')->middleware('admin')->group(function () {
#overview
Route::get('overview', [OverViewController::class, 'index'])->name('overview.index'); Route::get('overview', [OverViewController::class, 'index'])->name('overview.index');
Route::get('overview/sync', [OverViewController::class, 'syncPterodactyl'])->name('overview.sync'); Route::get('overview/sync', [OverViewController::class, 'syncPterodactyl'])->name('overview.sync');
Route::resource('activitylogs', ActivityLogController::class); Route::resource('activitylogs', ActivityLogController::class);
#users
Route::get("users.json", [UserController::class, "json"])->name('users.json'); Route::get("users.json", [UserController::class, "json"])->name('users.json');
Route::get('users/loginas/{user}', [UserController::class, 'loginAs'])->name('users.loginas'); Route::get('users/loginas/{user}', [UserController::class, 'loginAs'])->name('users.loginas');
Route::get('users/datatable', [UserController::class, 'datatable'])->name('users.datatable'); Route::get('users/datatable', [UserController::class, 'datatable'])->name('users.datatable');
@ -101,50 +108,55 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () {
Route::post('users/togglesuspend/{user}', [UserController::class, 'toggleSuspended'])->name('users.togglesuspend'); Route::post('users/togglesuspend/{user}', [UserController::class, 'toggleSuspended'])->name('users.togglesuspend');
Route::resource('users', UserController::class); Route::resource('users', UserController::class);
#servers
Route::get('servers/datatable', [AdminServerController::class, 'datatable'])->name('servers.datatable'); Route::get('servers/datatable', [AdminServerController::class, 'datatable'])->name('servers.datatable');
Route::post('servers/togglesuspend/{server}', [AdminServerController::class, 'toggleSuspended'])->name('servers.togglesuspend'); Route::post('servers/togglesuspend/{server}', [AdminServerController::class, 'toggleSuspended'])->name('servers.togglesuspend');
Route::resource('servers', AdminServerController::class); Route::resource('servers', AdminServerController::class);
#products
Route::get('products/datatable', [ProductController::class, 'datatable'])->name('products.datatable'); Route::get('products/datatable', [ProductController::class, 'datatable'])->name('products.datatable');
Route::get('products/clone/{product}', [ProductController::class, 'clone'])->name('products.clone'); Route::get('products/clone/{product}', [ProductController::class, 'clone'])->name('products.clone');
Route::patch('products/disable/{product}', [ProductController::class, 'disable'])->name('products.disable'); Route::patch('products/disable/{product}', [ProductController::class, 'disable'])->name('products.disable');
Route::resource('products', ProductController::class); Route::resource('products', ProductController::class);
#store
Route::get('store/datatable', [CreditProductController::class, 'datatable'])->name('store.datatable'); Route::get('store/datatable', [CreditProductController::class, 'datatable'])->name('store.datatable');
Route::patch('store/disable/{creditProduct}', [CreditProductController::class, 'disable'])->name('store.disable'); Route::patch('store/disable/{creditProduct}', [CreditProductController::class, 'disable'])->name('store.disable');
Route::resource('store', CreditProductController::class)->parameters([ Route::resource('store', CreditProductController::class)->parameters([
'store' => 'creditProduct', 'store' => 'creditProduct',
]); ]);
#payments
Route::get('payments/datatable', [PaymentController::class, 'datatable'])->name('payments.datatable'); Route::get('payments/datatable', [PaymentController::class, 'datatable'])->name('payments.datatable');
Route::get('payments', [PaymentController::class, 'index'])->name('payments.index'); Route::get('payments', [PaymentController::class, 'index'])->name('payments.index');
// Route::get('nodes/datatable', [NodeController::class, 'datatable'])->name('nodes.datatable'); #settings
// Route::get('nodes/sync', [NodeController::class, 'sync'])->name('nodes.sync'); Route::get('settings/datatable', [SettingsController::class, 'datatable'])->name('settings.datatable');
// Route::resource('nodes', NodeController::class); Route::patch('settings/updatevalue', [SettingsController::class, 'updatevalue'])->name('settings.updatevalue');
//
// Route::get('nests/datatable', [NestsController::class, 'datatable'])->name('nests.datatable');
// Route::get('nests/sync', [NestsController::class, 'sync'])->name('nests.sync');
// Route::resource('nests', NestsController::class);
Route::get('configurations/datatable', [ConfigurationController::class, 'datatable'])->name('configurations.datatable'); #settings
Route::patch('configurations/updatevalue', [ConfigurationController::class, 'updatevalue'])->name('configurations.updatevalue'); Route::patch('settings/update/invoice-settings', [Invoices::class, 'updateSettings'])->name('settings.update.invoicesettings');
Route::resource('configurations', ConfigurationController::class); Route::patch('settings/update/language', [Language::class, 'updateSettings'])->name('settings.update.languagesettings');
Route::resource('configurations', ConfigurationController::class); Route::patch('settings/update/payment', [Payments::class, 'updateSettings'])->name('settings.update.paymentsettings');
Route::patch('settings/update/misc', [Misc::class, 'updateSettings'])->name('settings.update.miscsettings');
Route::patch('settings/update/icons', [SettingsController::class, 'updateIcons'])->name('settings.update.icons'); Route::patch('settings/update/system', [System::class, 'updateSettings'])->name('settings.update.systemsettings');
Route::patch('settings/update/invoice-settings', [SettingsController::class, 'updateInvoiceSettings'])->name('settings.update.invoicesettings');
Route::get('settings/download-invoices', [SettingsController::class, 'downloadAllInvoices'])->name('settings.downloadAllInvoices');;
Route::resource('settings', SettingsController::class)->only('index'); Route::resource('settings', SettingsController::class)->only('index');
#invoices
Route::get('invoices/download-invoices', [InvoiceController::class, 'downloadAllInvoices'])->name('invoices.downloadAllInvoices');;
Route::get('invoices/download-single-invoice', [InvoiceController::class, 'downloadSingleInvoice'])->name('invoices.downloadSingleInvoice');;
#usefullinks
Route::get('usefullinks/datatable', [UsefulLinkController::class, 'datatable'])->name('usefullinks.datatable'); Route::get('usefullinks/datatable', [UsefulLinkController::class, 'datatable'])->name('usefullinks.datatable');
Route::resource('usefullinks', UsefulLinkController::class); Route::resource('usefullinks', UsefulLinkController::class);
#vouchers
Route::get('vouchers/datatable', [VoucherController::class, 'datatable'])->name('vouchers.datatable'); Route::get('vouchers/datatable', [VoucherController::class, 'datatable'])->name('vouchers.datatable');
Route::get('vouchers/{voucher}/usersdatatable', [VoucherController::class, 'usersdatatable'])->name('vouchers.usersdatatable'); Route::get('vouchers/{voucher}/usersdatatable', [VoucherController::class, 'usersdatatable'])->name('vouchers.usersdatatable');
Route::get('vouchers/{voucher}/users', [VoucherController::class, 'users'])->name('vouchers.users'); Route::get('vouchers/{voucher}/users', [VoucherController::class, 'users'])->name('vouchers.users');
Route::resource('vouchers', VoucherController::class); Route::resource('vouchers', VoucherController::class);
#api-keys
Route::get('api/datatable', [ApplicationApiController::class, 'datatable'])->name('api.datatable'); Route::get('api/datatable', [ApplicationApiController::class, 'datatable'])->name('api.datatable');
Route::resource('api', ApplicationApiController::class)->parameters([ Route::resource('api', ApplicationApiController::class)->parameters([
'api' => 'applicationApi', 'api' => 'applicationApi',