Merge branch 'development' into installer_script

This commit is contained in:
Dennis 2022-01-24 12:40:55 +01:00 committed by GitHub
commit 95bd093979
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 1398 additions and 768 deletions

View file

@ -27,10 +27,10 @@ class Pterodactyl
public static function client() public static function client()
{ {
return Http::withHeaders([ return Http::withHeaders([
'Authorization' => 'Bearer ' . Settings::getValueByKey("SETTINGS::SYSTEM:PTERODACTYL:TOKEN"), '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(Settings::getValueByKey("SETTINGS::SYSTEM: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 = Settings::getValueByKey('SETTINGS::SERVER: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 Settings::getValueByKey("SETTINGS::SYSTEM:PTERODACTYL:URL") . $route; return config("SETTINGS::SYSTEM:PTERODACTYL:URL") . $route;
} }
/** /**

View file

@ -8,16 +8,13 @@ use Illuminate\Support\Facades\Cache;
class Invoices class Invoices
{ {
public $tabTitle = 'Invoice Settings';
public $invoiceSettings;
public function __construct() public function __construct()
{ {
return; return;
} }
public function updateInvoiceSettings(Request $request) public function updateSettings(Request $request)
{ {
$request->validate([ $request->validate([
'logo' => 'nullable|max:10000|mimes:jpg,png,jpeg', 'logo' => 'nullable|max:10000|mimes:jpg,png,jpeg',
@ -31,15 +28,14 @@ class Invoices
"SETTINGS::INVOICE:COMPANY_MAIL" => "company-mail", "SETTINGS::INVOICE:COMPANY_MAIL" => "company-mail",
"SETTINGS::INVOICE:COMPANY_VAT" => "company-vat", "SETTINGS::INVOICE:COMPANY_VAT" => "company-vat",
"SETTINGS::INVOICE:COMPANY_WEBSITE" => "company-web", "SETTINGS::INVOICE:COMPANY_WEBSITE" => "company-web",
"SETTINGS::INVOICE:PREFIX" => "invoice-prefix" "SETTINGS::INVOICE:PREFIX" => "invoice-prefix",
"SETTINGS::INVOICE:ENABLED" => "enable-invoices",
]; ];
foreach ($values as $key => $value) { foreach ($values as $key => $value) {
$param = $request->get($value); $param = $request->get($value);
if (!$param) {
$param = ""; Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
}
Settings::where('key', $key)->update(['value' => $param]);
Cache::forget("setting" . ':' . $key); Cache::forget("setting" . ':' . $key);
} }
@ -49,6 +45,6 @@ class Invoices
} }
return redirect()->route('admin.settings.index')->with('success', 'Invoice settings updated!'); return redirect(route('admin.settings.index') . '#invoices')->with('success', __('Invoice settings updated!'));
} }
} }

View file

@ -6,20 +6,32 @@ use App\Models\Settings;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class Language class Language
{ {
public $tabTitle = 'Language Settings';
public $languageSettings;
public function __construct() public function __construct()
{ {
return; return;
} }
public function updateLanguageSettings(Request $request) 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 = [ $values = [
//SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form) //SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
@ -33,16 +45,17 @@ class Language
foreach ($values as $key => $value) { foreach ($values as $key => $value) {
$param = $request->get($value); $param = $request->get($value);
if (!$param) {
$param = "false"; if (is_array($param)) {
$param = implode(",", $param);
} }
Settings::where('key', $key)->update(['value' => $param]);
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
Cache::forget("setting" . ':' . $key); Cache::forget("setting" . ':' . $key);
Session::remove("locale"); Session::remove("locale");
} }
return redirect()->route('admin.settings.index')->with('success', 'Language settings updated!'); return redirect(route('admin.settings.index') . '#language')->with('success', __('Language settings updated!'));
} }
} }

View file

@ -5,64 +5,81 @@ namespace App\Classes\Settings;
use App\Models\Settings; use App\Models\Settings;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Session;
class Misc class Misc
{ {
public $tabTitle = 'Misc Settings';
public $miscSettings;
public function __construct() public function __construct()
{ {
return; return;
} }
public function updateSettings(Request $request)
public function updateMiscSettings(Request $request)
{ {
$request->validate([ $validator = Validator::make($request->all(), [
'icon' => 'nullable|max:10000|mimes:jpg,png,jpeg', 'icon' => 'nullable|max:10000|mimes:jpg,png,jpeg',
'favicon' => 'nullable|max:10000|mimes:ico', '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')) { if ($request->hasFile('icon')) {
$request->file('icon')->storeAs('public', 'icon.png'); $request->file('icon')->storeAs('public', 'icon.png');
} }
if ($request->hasFile('favicon')) { if ($request->hasFile('favicon')) {
$request->file('favicon')->storeAs('public', 'favicon.ico'); $request->file('favicon')->storeAs('public', 'favicon.ico');
} }
$values = [ $values = [
//SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
"SETTINGS::MISC:PHPMYADMIN:URL" => "phpmyadmin-url",
"SETTINGS::DISCORD:BOT_TOKEN" => "discord-bot-token", "SETTINGS::DISCORD:BOT_TOKEN" => "discord-bot-token",
"SETTINGS::DISCORD:CLIENT_ID" => "discord-client-id", "SETTINGS::DISCORD:CLIENT_ID" => "discord-client-id",
"SETTINGS::DISCORD:CLIENT_SECRET" => "discord-client-secret", "SETTINGS::DISCORD:CLIENT_SECRET" => "discord-client-secret",
"SETTINGS::DISCORD:GUILD_ID" => "discord-guild-id", "SETTINGS::DISCORD:GUILD_ID" => "discord-guild-id",
"SETTINGS::DISCORD:INVITE_URL" => "discord-invite-url", "SETTINGS::DISCORD:INVITE_URL" => "discord-invite-url",
"SETTINGS::DISCORD:ROLE_ID" => "discord-role-id" "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",
]; ];
Config::set('services.discord.client_id', $request->get("discord-client-id"));
Config::set('services.discord.client_secret', $request->get("discord-client-secret"));
foreach ($values as $key => $value) { foreach ($values as $key => $value) {
$param = $request->get($value); $param = $request->get($value);
if (!$param) {
$param = "";
}
Settings::where('key', $key)->update(['value' => $param]);
Cache::forget("setting" . ':' . $key);
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
Cache::forget("setting" . ':' . $key);
} }
return redirect()->route('admin.settings.index')->with('success', 'Misc settings updated!'); return redirect(route('admin.settings.index') . '#misc')->with('success', __('Misc settings updated!'));
} }
} }

View file

@ -5,21 +5,34 @@ namespace App\Classes\Settings;
use App\Models\Settings; use App\Models\Settings;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Validator;
class Payments class Payments
{ {
public $tabTitle = 'Payment Settings';
public $paymentSettings;
public function __construct() public function __construct()
{ {
return; return;
} }
public function updatePaymentSettings(Request $request) 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 = [ $values = [
//SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form) //SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
@ -32,21 +45,17 @@ class Payments
"SETTINGS::PAYMENTS:STRIPE:TEST_SECRET" => "stripe-test-secret", "SETTINGS::PAYMENTS:STRIPE:TEST_SECRET" => "stripe-test-secret",
"SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET" => "stripe-endpoint-test-secret", "SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET" => "stripe-endpoint-test-secret",
"SETTINGS::PAYMENTS:STRIPE:METHODS" => "stripe-methods", "SETTINGS::PAYMENTS:STRIPE:METHODS" => "stripe-methods",
"SETTINGS::PAYMENTS:SALES_TAX" => "sales_tax" "SETTINGS::PAYMENTS:SALES_TAX" => "sales-tax"
]; ];
foreach ($values as $key => $value) { foreach ($values as $key => $value) {
$param = $request->get($value); $param = $request->get($value);
if (!$param) {
$param = ""; Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
}
Settings::where('key', $key)->update(['value' => $param]);
Cache::forget("setting" . ':' . $key); Cache::forget("setting" . ':' . $key);
} }
return redirect(route('admin.settings.index') . '#payment')->with('success', __('Payment settings updated!'));
return redirect()->route('admin.settings.index')->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

@ -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(Settings::getValueByKey("SETTINGS::PAYMENTS: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'),
]); ]);
@ -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!'));
@ -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);
@ -521,7 +534,7 @@ class PaymentController extends Controller
->pricePerUnit($creditProduct->price); ->pricePerUnit($creditProduct->price);
$notes = [ $notes = [
__("Payment method") .": ". $payment->payment_method, __("Payment method") . ": " . $payment->payment_method,
]; ];
$notes = implode("<br>", $notes); $notes = implode("<br>", $notes);
@ -591,7 +604,7 @@ class PaymentController extends Controller
return $payment->created_at ? $payment->created_at->diffForHumans() : ''; return $payment->created_at ? $payment->created_at->diffForHumans() : '';
}) })
->addColumn('actions', function (Payment $payment) { ->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> 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']) ->rawColumns(['actions'])

View file

@ -1,6 +1,6 @@
<?php <?php
namespace App\Http\Controllers\Admin\SettingsControllers; namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Settings; use App\Models\Settings;
@ -69,8 +69,7 @@ class SettingsController extends Controller
public function datatable() public function datatable()
{ {
$query = Settings:: $query = Settings::where('key', 'like', '%SYSTEM%')
where('key', 'like', '%SYSTEM%')
->orWhere('key', 'like', '%USER%') ->orWhere('key', 'like', '%USER%')
->orWhere('key', 'like', '%SERVER%'); ->orWhere('key', 'like', '%SERVER%');
@ -84,5 +83,4 @@ class SettingsController extends Controller
->rawColumns(['actions']) ->rawColumns(['actions'])
->make(); ->make();
} }
} }

View file

@ -88,10 +88,25 @@ class UserController extends Controller
"role" => ['sometimes', Rule::in(['admin', 'mod', 'client', 'member'])], "role" => ['sometimes', Rule::in(['admin', 'mod', 'client', 'member'])],
]); ]);
$user->update($request->all());
event(new UserUpdateCreditsEvent($user)); event(new UserUpdateCreditsEvent($user));
//Update Users Password on Pterodactyl
//Username,Mail,First and Lastname are required aswell
$response = Pterodactyl::client()->patch('/application/users/'.$user->pterodactyl_id, [
"username" => $request->name,
"first_name" => $request->name,
"last_name" => $request->name,
"email" => $request->email,
]);
if ($response->failed()) {
throw ValidationException::withMessages([
'pterodactyl_error_message' => $response->toException()->getMessage(),
'pterodactyl_error_status' => $response->toException()->getCode()
]);
}
$user->update($request->all());
return $user; return $user;
} }
@ -166,6 +181,53 @@ class UserController extends Controller
return $user; return $user;
} }
/**
* Suspends the user
*
* @param Request $request
* @param int $id
* @return bool
* @throws ValidationException
*/
public function suspend(Request $request, int $id)
{
$discordUser = DiscordUser::find($id);
$user = $discordUser ? $discordUser->user : User::findOrFail($id);
if ($user->isSuspended()) {
throw ValidationException::withMessages([
'error' => 'The user is already suspended',
]);
}
$user->suspend();
return $user;
}
/**
* Unsuspend the user
*
* @param Request $request
* @param int $id
* @return bool
* @throws ValidationException
*/
public function unsuspend(Request $request, int $id)
{
$discordUser = DiscordUser::find($id);
$user = $discordUser ? $discordUser->user : User::findOrFail($id);
if (!$user->isSuspended()) {
throw ValidationException::withMessages([
'error' => "You cannot unsuspend an User who is not suspended."
]);
}
$user->unSuspend();
return $user;
}
/** /**
* @throws ValidationException * @throws ValidationException
*/ */

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

@ -12,6 +12,7 @@ use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
class RegisterController extends Controller class RegisterController extends Controller
{ {
@ -53,30 +54,28 @@ class RegisterController extends Controller
*/ */
protected function validator(array $data) protected function validator(array $data)
{ {
if (Settings::getValueByKey('SETTINGS::SYSTEM: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'],
]);
} }
/** /**
@ -90,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' => Settings::getValueByKey('SETTINGS::USER:INITIAL_CREDITS', 150), 'credits' => config('SETTINGS::USER:INITIAL_CREDITS', 150),
'server_limit' => Settings::getValueByKey('SETTINGS::USER:INITIAL_SERVER_LIMIT', 1), 'server_limit' => config('SETTINGS::USER:INITIAL_SERVER_LIMIT', 1),
'password' => Hash::make($data['password']), 'password' => Hash::make($data['password']),
]); ]);
@ -108,13 +107,17 @@ class RegisterController extends Controller
if ($response->failed()) { if ($response->failed()) {
$user->delete(); $user->delete();
return $user; throw ValidationException::withMessages([
'ptero_registration_error' => [__('Account already exists on Pterodactyl. Please contact the Support!')],
]);
} }
$user->update([ $user->update([
'pterodactyl_id' => $response->json()['attributes']['id'] 'pterodactyl_id' => $response->json()['attributes']['id']
]); ]);
return $user; return $user;
} }
} }

View file

@ -2,12 +2,14 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Settings;
use App\Classes\Pterodactyl;
use App\Models\User; use App\Models\User;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
class ProfileController extends Controller class ProfileController extends Controller
{ {
@ -16,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' => Settings::getValueByKey('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD'), 'credits_reward_after_verify_discord' => config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD'),
'force_email_verification' => Settings::getValueByKey('SETTINGS::USER:FORCE_EMAIL_VERIFICATION'), 'force_email_verification' => config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION'),
'force_discord_verification' => Settings::getValueByKey('SETTINGS::USER:FORCE_DISCORD_VERIFICATION'), 'force_discord_verification' => config('SETTINGS::USER:FORCE_DISCORD_VERIFICATION'),
]); ]);
} }
@ -34,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.');
} }
}, },
], ],
@ -50,21 +52,38 @@ class ProfileController extends Controller
'new_password_confirmation' => 'required|same:new_password' 'new_password_confirmation' => 'required|same:new_password'
]); ]);
//Update Users Password on Pterodactyl
//Username,Mail,First and Lastname are required aswell
$response = Pterodactyl::client()->patch('/application/users/'.$user->pterodactyl_id, [
"password" => $request->input('new_password'),
"username" => $request->input('name'),
"first_name" => $request->input('name'),
"last_name" => $request->input('name'),
"email" => $request->input('email'),
]);
if ($response->failed()) {
throw ValidationException::withMessages([
'pterodactyl_error_message' => $response->toException()->getMessage(),
'pterodactyl_error_status' => $response->toException()->getCode()
]);
}
//update password //update password
$user->update([ $user->update([
'password' => Hash::make($request->input('new_password')), 'password' => Hash::make($request->input('new_password')),
]); ]);
} }
//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);
@ -77,12 +96,28 @@ class ProfileController extends Controller
]); ]);
} }
//update name and email on Pterodactyl
$response = Pterodactyl::client()->patch('/application/users/'.$user->pterodactyl_id, [
"username" => $request->input('name'),
"first_name" => $request->input('name'),
"last_name" => $request->input('name'),
"email" => $request->input('email'),
]);
if ($response->failed()) {
throw ValidationException::withMessages([
'pterodactyl_error_message' => $response->toException()->getMessage(),
'pterodactyl_error_status' => $response->toException()->getCode()
]);
}
//update name and email //update name and email
$user->update([ $user->update([
'name' => $request->input('name'), 'name' => $request->input('name'),
'email' => $request->input('email'), 'email' => $request->input('email'),
]); ]);
$user->sendEmailVerificationNotification();
return redirect()->route('profile.index')->with('success' , __('Profile updated')); return redirect()->route('profile.index')->with('success', __('Profile updated'));
} }
} }

View file

@ -107,7 +107,7 @@ class ServerController extends Controller
if ( if (
Auth::user()->credits < Auth::user()->credits <
($product->minimum_credits == -1 ($product->minimum_credits == -1
? Settings::getValueByKey('SETTINGS::USER: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 (Settings::getValueByKey('SETTINGS::USER: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 (Settings::getValueByKey('SETTINGS::USER: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 (Settings::getValueByKey('SETTINGS::SYSTEM: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

@ -18,10 +18,10 @@ class GlobalNames
*/ */
public function handle(Request $request, Closure $next) public function handle(Request $request, Closure $next)
{ {
define('CREDITS_DISPLAY_NAME' , Settings::getValueByKey('SETTINGS::SYSTEM: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

@ -22,17 +22,16 @@ 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', Settings::getValueByKey("SETTINGS::LOCALE:DEFAULT")); $locale = Session::get('locale', config("SETTINGS::LOCALE:DEFAULT"));
} else { } else {
if (Settings::getValueByKey("SETTINGS::LOCALE:DYNAMIC")!=="true") { if (config("SETTINGS::LOCALE:DYNAMIC") !== "true") {
$locale = Settings::getValueByKey("SETTINGS::LOCALE:DEFAULT"); $locale = config("SETTINGS::LOCALE:DEFAULT");
} else { } else {
$locale = substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2); $locale = substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2);
if (!in_array($locale, json_decode(Settings::getValueByKey("SETTINGS::LOCALE:AVAILABLE")))) { if (!in_array($locale, explode(',', config("SETTINGS::LOCALE:AVAILABLE")))) {
$locale = Settings::getValueByKey("SETTINGS::LOCALE:DEFAULT"); $locale = config("SETTINGS::LOCALE:DEFAULT");
} }
} }
} }
App::setLocale($locale); App::setLocale($locale);

View file

@ -38,25 +38,25 @@ class WelcomeMessage extends Notification implements ShouldQueue
return ['database']; return ['database'];
} }
public function AdditionalLines() public function AdditionalLines()
{ {
$AdditionalLine = ""; $AdditionalLine = "";
if(Settings::getValueByKey('SETTINGS::USER: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 ".Settings::getValueByKey('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL')." additional " . Settings::getValueByKey('SETTINGS::SYSTEM: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(Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') != 0) {
$AdditionalLine .= "Verifying your e-mail will also increase your Server Limit by " . Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') . ". <br />";
}
$AdditionalLine .="<br />";
if(Settings::getValueByKey('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD') != 0) {
$AdditionalLine .= "You can also verify your discord account to get another " . Settings::getValueByKey('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD') . " " . Settings::getValueByKey('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME') . ". <br />";
}
if(Settings::getValueByKey('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') != 0) {
$AdditionalLine .= "Verifying your Discord account will also increase your Server Limit by " . Settings::getValueByKey('SETTINGS::USER: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

@ -32,14 +32,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]);
} }

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

@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
class CreateCreditProductsTable extends Migration class CreatePaypalProductsTable extends Migration
{ {
/** /**
* Run the migrations. * Run the migrations.
@ -13,13 +13,13 @@ class CreateCreditProductsTable extends Migration
*/ */
public function up() public function up()
{ {
Schema::create('credit_products', function (Blueprint $table) { Schema::create('paypal_products', function (Blueprint $table) {
$table->uuid('id')->primary(); $table->uuid('id')->primary();
$table->string('type'); $table->string('type');
$table->decimal('price')->default(0); $table->decimal('price')->default(0);
$table->unsignedInteger('quantity'); $table->unsignedInteger('quantity');
$table->string('description'); $table->string('description');
$table->string('currency_code' , 3); $table->string('currency_code', 3);
$table->boolean('disabled')->default(true); $table->boolean('disabled')->default(true);
$table->timestamps(); $table->timestamps();
}); });
@ -32,6 +32,6 @@ class CreateCreditProductsTable extends Migration
*/ */
public function down() public function down()
{ {
Schema::dropIfExists('credit_products'); Schema::dropIfExists('paypal_products');
} }
} }

View file

@ -0,0 +1,33 @@
<?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

@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
class AddDisplayToCreditProductsTable extends Migration class AddDisplayToPayPalProductsTable extends Migration
{ {
/** /**
* Run the migrations. * Run the migrations.
@ -13,7 +13,7 @@ class AddDisplayToCreditProductsTable extends Migration
*/ */
public function up() public function up()
{ {
Schema::table('credit_products', function (Blueprint $table) { Schema::table('paypal_products', function (Blueprint $table) {
$table->string('display'); $table->string('display');
}); });
} }
@ -25,7 +25,7 @@ class AddDisplayToCreditProductsTable extends Migration
*/ */
public function down() public function down()
{ {
Schema::table('credit_products', function (Blueprint $table) { Schema::table('paypal_products', function (Blueprint $table) {
$table->dropColumn('display'); $table->dropColumn('display');
}); });
} }

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

@ -144,7 +144,14 @@ class SettingsSeeder extends Seeder
'type' => 'integer', 'type' => 'integer',
'description' => 'The %-value of tax that will be added to the product price on checkout' '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',
'description' => 'Enables or disables the invoice feature for payments'
]);
//Invoice company name //Invoice company name
Settings::firstOrCreate([ Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:COMPANY_NAME', 'key' => 'SETTINGS::INVOICE:COMPANY_NAME',
@ -380,7 +387,7 @@ class SettingsSeeder extends Seeder
]); ]);
Settings::firstOrCreate([ Settings::firstOrCreate([
'key' => 'SETTINGS::SYSTEM:RECAPTCHA_SITE_KEY', 'key' => 'SETTINGS::RECAPTCHA:SITE_KEY',
], [ ], [
'value' => '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI', 'value' => '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI',
'type' => 'string', 'type' => 'string',
@ -388,11 +395,75 @@ class SettingsSeeder extends Seeder
]); ]);
Settings::firstOrCreate([ Settings::firstOrCreate([
'key' => 'SETTINGS::SYSTEM:RECAPTCHA_SECRET_KEY', 'key' => 'SETTINGS::RECAPTCHA:SECRET_KEY',
], [ ], [
'value' => '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe', 'value' => '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe',
'type' => 'string', 'type' => 'string',
'description' => 'Google Recaptcha API Credentials - https://www.google.com/recaptcha/admin - reCaptcha V2 (not v3)' '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'
]);
} }
} }

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",
@ -352,5 +352,12 @@
"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", "de": "Deutsch",
"en": "Englisch" "en": "Englisch",
"fr": "Französisch",
"cs": "Tschechisch",
"es": "Spanisch",
"hi": "Hindi",
"it": "Italienisch",
"pl": "Polnisch",
"zh": "Chinesisch"
} }

View file

@ -66,12 +66,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

@ -1,121 +0,0 @@
<div class="tab-pane mt-3 active" id="configurations">
<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>
<!-- The Modal -->
<div class="modal fade" id="editConfigurationModel">
<div class="modal-dialog">
<div class="modal-content ">
<form method="post" action="{{ route('admin.settings.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>
<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.settings.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>

View file

@ -1,85 +1,94 @@
@inject('Invoices', 'App\Classes\Settings\Invoices') <div class="tab-pane mt-3 active" id="invoices">
<div class="tab-pane mt-3" id="invoices">
<form method="POST" enctype="multipart/form-data" class="mb-3" <form method="POST" enctype="multipart/form-data" class="mb-3"
action="{{ route('admin.settings.update.invoicesettings') }}"> action="{{ route('admin.settings.update.invoicesettings') }}">
@csrf @csrf
@method('PATCH') @method('PATCH')
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-3 p-3">
<!-- Name --> <!-- Name -->
<div class="form-group"> <div class="form-group mb-3">
<div class="custom-control mb-3"> <div class="custom-control p-0">
<label for="company-name">{{ __('Enter your companys name') }}</label> <label for="company-name">{{ __('Company Name') }}:</label>
<input x-model="company-name" id="company-name" name="company-name" type="text" required <input x-model="company-name" id="company-name" name="company-name" type="text" required
value="{{ App\Models\Settings::getValueByKey("SETTINGS::INVOICE:COMPANY_NAME") }}" value="{{ config('SETTINGS::INVOICE:COMPANY_NAME') }}"
class="form-control @error('company-name') is-invalid @enderror"> class="form-control @error('company-name') is-invalid @enderror">
</div> </div>
</div> </div>
<!-- address --> <!-- address -->
<div class="form-group"> <div class="form-group mb-3">
<div class="custom-control mb-3"> <div class="custom-control p-0">
<label for="company-address">{{ __('Enter your companys address') }}</label> <label for="company-address">{{ __('Company Adress') }}:</label>
<input x-model="company-address" id="company-address" name="company-address" type="text" <input x-model="company-address" id="company-address" name="company-address" type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::INVOICE:COMPANY_ADDRESS") }}" value="{{ config('SETTINGS::INVOICE:COMPANY_ADDRESS') }}"
class="form-control @error('company-address') is-invalid @enderror"> class="form-control @error('company-address') is-invalid @enderror">
</div> </div>
</div> </div>
<!-- Phone --> <!-- Phone -->
<div class="form-group"> <div class="form-group mb-3">
<div class="custom-control mb-3"> <div class="custom-control p-0">
<label for="company-phone">{{ __('Enter your companys phone number') }}</label> <label for="company-phone">{{ __('Company Phonenumber') }}:</label>
<input x-model="company-phone" id="company-phone" name="company-phone" type="text" <input x-model="company-phone" id="company-phone" name="company-phone" type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::INVOICE:COMPANY_PHONE") }}" value="{{ config('SETTINGS::INVOICE:COMPANY_PHONE') }}"
class="form-control @error('company-phone') is-invalid @enderror"> class="form-control @error('company-phone') is-invalid @enderror">
</div> </div>
</div> </div>
<!-- VAT --> <!-- VAT -->
<div class="form-group"> <div class="form-group mb-3">
<div class="custom-control mb-3"> <div class="custom-control p-0">
<label for="company-vat">{{ __('Enter your companys VAT id') }}</label> <label for="company-vat">{{ __('VAT ID') }}:</label>
<input x-model="company-vat" id="company-vat" name="company-vat" type="text" <input x-model="company-vat" id="company-vat" name="company-vat" type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::INVOICE:COMPANY_VAT") }}" value="{{ config('SETTINGS::INVOICE:COMPANY_VAT') }}"
class="form-control @error('company-vat') is-invalid @enderror"> class="form-control @error('company-vat') is-invalid @enderror">
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-6">
<div class="col-md-3 p-3">
<!-- email --> <!-- email -->
<div class="form-group"> <div class="form-group mb-3">
<div class="custom-control mb-3"> <div class="custom-control p-0">
<label for="company-mail">{{ __('Enter your companys email address') }}</label> <label for="company-mail">{{ __('Company E-Mail Adress') }}:</label>
<input x-model="company-mail" id="company-mail" name="company-mail" type="text" <input x-model="company-mail" id="company-mail" name="company-mail" type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::INVOICE:COMPANY_MAIL") }}" value="{{ config('SETTINGS::INVOICE:COMPANY_MAIL') }}"
class="form-control @error('company-mail') is-invalid @enderror"> class="form-control @error('company-mail') is-invalid @enderror">
</div> </div>
</div> </div>
<!-- website --> <!-- website -->
<div class="form-group"> <div class="form-group mb-3">
<div class="custom-control mb-3"> <div class="custom-control p-0">
<label for="company-web">{{ __('Enter your companys website') }}</label> <label for="company-web">{{ __('Company Website') }}:</label>
<input x-model="company-web" id="company-web" name="company-web" type="text" <input x-model="company-web" id="company-web" name="company-web" type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::INVOICE:COMPANY_WEBSITE") }}" value="{{ config('SETTINGS::INVOICE:COMPANY_WEBSITE') }}"
class="form-control @error('company-web') is-invalid @enderror"> class="form-control @error('company-web') is-invalid @enderror">
</div> </div>
</div> </div>
<!-- prefix --> <!-- prefix -->
<div class="form-group"> <div class="form-group mb-3">
<div class="custom-control mb-3"> <div class="custom-control p-0">
<label for="invoice-prefix">{{ __('Enter your custom invoice prefix') }}</label> <label for="invoice-prefix">{{ __('Invoice Prefix') }}:</label>
<input x-model="invoice-prefix" id="invoice-prefix" name="invoice-prefix" type="text" required <input x-model="invoice-prefix" id="invoice-prefix" name="invoice-prefix" type="text" required
value="{{ App\Models\Settings::getValueByKey("SETTINGS::INVOICE:PREFIX") }}" value="{{ config('SETTINGS::INVOICE:PREFIX') }}"
class="form-control @error('invoice-prefix') is-invalid @enderror"> class="form-control @error('invoice-prefix') is-invalid @enderror">
</div> </div>
</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 --> <!-- logo -->
<div class="form-group"> <div class="form-group mb-3">
<div class="custom-control mb-3"> <div class="custom-control p-0">
<label for="logo">{{ __('Logo') }}</label> <label for="logo">{{ __('Logo') }}:</label>
<div class="custom-file mb-3"> <div class="custom-file mb-3">
<input type="file" accept="image/png,image/jpeg,image/jpg" class="custom-file-input" <input type="file" accept="image/png,image/jpeg,image/jpg" class="custom-file-input"
name="logo" id="logo"> name="logo" id="logo">
@ -92,13 +101,11 @@
</span> </span>
@enderror @enderror
</div> </div>
</div> </div>
</div> </div>
<button class="btn btn-primary">{{ __('Submit') }}</button>
<!-- end -->
<div class="row">
<button class="btn btn-primary mt-3 ml-3">{{ __('Submit') }}</button>
</div>
</form> </form>
</div> </div>

View file

@ -1,81 +1,86 @@
<div class="tab-pane mt-3" id="language"> <div class="tab-pane mt-3" id="language">
<form method="POST" enctype="multipart/form-data" class="mb-3" <form method="POST" enctype="multipart/form-data" class="mb-3"
action="{{ route('admin.settings.update.languagesettings') }}"> action="{{ route('admin.settings.update.languagesettings') }}">
@csrf @csrf
@method('PATCH') @method('PATCH')
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-3 p-3">
<div class="form-group"> <div class="form-group">
<!-- AVAILABLE LANGUAGES --> <!-- AVAILABLE LANGUAGES -->
<label for="languages">{{__("Available languages")}}:</label> <div class="custom-control mb-3 p-0">
<label for="languages">{{ __('Available languages') }}:</label>
<select id="languages" style="width:100%" <select id="languages" style="width:100%" class="custom-select" name="languages[]" required
class="custom-select" name="languages[]" multiple="multiple" autocomplete="off" @error('defaultLanguage') is-invalid @enderror>
required
multiple="multiple" autocomplete="off">
@foreach(config("app.available_locales") as $lang)
<option value="{{$lang}}">{{__($lang)}}</option>
@endforeach
</select>
@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 --> <!-- DEFAULT LANGUAGE -->
<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%" <div class="custom-control mb-3 p-0">
class="custom-select" name="defaultLanguage" <label for="defaultLanguage">{{ __('Default language') }}:
required <i data-toggle="popover" data-trigger="hover"
autocomplete="off"> data-content="{{ __('The fallback Language, if something goes wrong') }}"
<option class="fas fa-info-circle"></i>
value="{{\App\Models\Settings::getValueByKey("SETTINGS::LOCALE:DEFAULT")}}" </label>
selected>
{{__(\App\Models\Settings::getValueByKey("SETTINGS::LOCALE:DEFAULT"))}}</option> <select id="defaultLanguage" style="width:100%" class="custom-select" name="defaultLanguage"
@foreach(config("app.available_locales") as $lang) required autocomplete="off" @error('defaultLanguage') is-invalid @enderror>
<option value="{{$lang}}">{{__($lang)}}</option> @foreach (config('app.available_locales') as $lang)
@endforeach <option value="{{ $lang }}" @if (config('SETTINGS::LOCALE:DEFAULT') == $lang) selected
</select> @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>
<!--DATATABLE LANGUAGE -->
<label for="datatable-language">{{__('Datable language')}} <i data-toggle="popover" <div class="col-md-3 p-3">
data-trigger="hover"
data-content="{{__('The Language of the Datatables. Grab the Language-Codes from here')}} https://datatables.net/plug-ins/i18n/" <!-- AUTO TRANSLATE -->
class="fas fa-info-circle"></i></label> <div class="form-group">
<input x-model="datatable-language" id="datatable-language" name="datatable-language" type="text" <input value="true" id="autotranslate" name="autotranslate"
required {{ config('SETTINGS::LOCALE:DYNAMIC') == 'true' ? 'checked' : '' }} type="checkbox">
value="{{ App\Models\Settings::getValueByKey("SETTINGS::LOCALE:DATATABLES") }}" <label for="autotranslate">{{ __('Auto-translate') }} <i data-toggle="popover"
class="form-control @error('datatable-language') is-invalid @enderror"> 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> </div>
<div class="row">
<!-- AUTO TRANSLATE --> <button class="btn btn-primary mt-3 ml-3">{{ __('Submit') }}</button>
<div class="form-group">
<input value="true" id="autotranslate" name="autotranslate"
{{(\App\Models\Settings::getValueByKey("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"
{{(\App\Models\Settings::getValueByKey("SETTINGS::LOCALE:CLIENTS_CAN_CHANGE")=="true"?"checked":"")}}
type="checkbox">
<label for="canClientChangeLanguage">{{__('Let the Client change the Language')}} <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>
<button class="btn btn-primary">{{ __('Save') }}</button>
</form> </form>
</div> </div>

View file

@ -1,124 +1,194 @@
<div class="tab-pane mt-3" id="misc"> <div class="tab-pane mt-3" id="misc">
<form method="POST" enctype="multipart/form-data" class="mb-3" <form method="POST" enctype="multipart/form-data" class="mb-3"
action="{{ route('admin.settings.update.miscsettings') }}"> action="{{ route('admin.settings.update.miscsettings') }}">
@csrf @csrf
@method('PATCH') @method('PATCH')
<div class="row"> <div class="row">
<div class="col-md-6 col-lg-4 col-12">
<!-- PHPMYADMIN --> {{-- E-Mail --}}
<div class="col-md-3 px-3">
<!-- Icetoast das sieht auch kacke aus... --> <div class="row mb-2">
<div class="col text-center">
<div class="form-group"> <h1>E-Mail</h1>
<div class="custom-control mb-3">
<label
for="phpmyadmin-url">{{ __('The URL to your PHPMYADMIN Panel. Must not end with a /, leave blank to remove database button') }}</label>
<input x-model="phpmyadmin-url" id="phpmyadmin-url" name="phpmyadmin-url" type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::MISC:PHPMYADMIN:URL") }}"
class="form-control @error('phpmyadmin-url') is-invalid @enderror">
</div> </div>
</div> </div>
<div class="form-group"> <div class="custom-control mb-3 p-0">
<div class="custom-file mb-3 mt-3"> <label for="mailservice">{{ __('Mail Service') }}:
<input type="file" accept="image/png,image/jpeg,image/jpg" class="custom-file-input" name="icon" <i data-toggle="popover" data-trigger="hover"
id="icon"> data-content="{{ __('The Mailer to send e-mails with') }}" class="fas fa-info-circle"></i>
<label class="custom-file-label selected" for="icon">{{ __('Select panel icon') }}</label> </label>
</div> <select id="mailservice" style="width:100%" class="custom-select" name="mailservice" required
@error('icon') autocomplete="off" @error('mailservice') is-invalid @enderror>
<span class="text-danger"> @foreach (array_keys(config('mail.mailers')) as $mailer)
{{ $message }} <option value="{{ $mailer }}" @if (config('SETTINGS::MAIL:MAILER') == $mailer) selected
</span> @endif>{{ __($mailer) }}</option>
@enderror @endforeach
</select>
</div> </div>
<div class="form-group"> <div class="form-group mb-3">
<div class="custom-file mb-3"> <div class="custom-control p-0">
<input type="file" accept="image/x-icon" class="custom-file-input" name="favicon" id="favicon"> <label for="mailhost">{{ __('Mail Host') }}:</label>
<label class="custom-file-label selected" <input x-model="mailhost" id="mailhost" name="mailhost" type="text"
for="favicon">{{ __('Select panel favicon') }}</label> 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>
@error('favicon')
<span class="text-danger">
{{ $message }}
</span>
@enderror
</div> </div>
</div> </div>
<div class="col-md-3">
<img class="mb-3" height="50"
src="{{ url('/images/discord_logo.png') }}">
<!-- DISCORD --> <!-- DISCORD -->
<div class="form-group"> <div class="col-md-3 px-3">
<div class="custom-control mb-3"> <div class="row mb-2">
<label for="discord-client-id">{{ __('Your Discord client-id')}} ( Discord API Credentials - <div class="col text-center">
https://discordapp.com/developers/applications/ ) </label> <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" <input x-model="discord-client-id" id="discord-client-id" name="discord-client-id" type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::DISCORD:CLIENT_ID") }}" value="{{ config('SETTINGS::DISCORD:CLIENT_ID') }}"
class="form-control @error('discord-client-id') is-invalid @enderror"> class="form-control @error('discord-client-id') is-invalid @enderror">
</div> </div>
</div> </div>
<div class="form-group">
<div class="custom-control mb-3"> <div class="form-group mb-3">
<label for="discord-client-secret">{{ __('Your Discord client-secret')}} </label> <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" <input x-model="discord-client-secret" id="discord-client-secret" name="discord-client-secret"
type="text" type="text" value="{{ config('SETTINGS::DISCORD:CLIENT_SECRET') }}"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::DISCORD:CLIENT_SECRET") }}" class="form-control @error('discord-client-secret') is-invalid @enderror">
class="form-control @error('discord-client-secret') is-invalid @enderror">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group mb-3">
<div class="custom-control mb-3"> <div class="custom-control p-0">
<label for="discord-client-secret">{{ __('Your Discord Bot-token')}} </label> <label for="discord-client-secret">{{ __('Discord Bot-Token') }}:</label>
<input x-model="discord-bot-token" id="discord-bot-token" name="discord-bot-token" <input x-model="discord-bot-token" id="discord-bot-token" name="discord-bot-token" type="text"
type="text" value="{{ config('SETTINGS::DISCORD:BOT_TOKEN') }}"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::DISCORD:BOT_TOKEN") }}" class="form-control @error('discord-bot-token') is-invalid @enderror">
class="form-control @error('discord-bot-token') is-invalid @enderror">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group mb-3">
<div class="custom-control mb-3"> <div class="custom-control p-0">
<label for="discord-client-secret">{{ __('Your Discord Guild-ID')}} </label> <label for="discord-client-secret">{{ __('Discord Guild-ID') }}:</label>
<input x-model="discord-guild-id" id="discord-guild-id" name="discord-guild-id" <input x-model="discord-guild-id" id="discord-guild-id" name="discord-guild-id" type="number"
type="number" value="{{ config('SETTINGS::DISCORD:GUILD_ID') }}"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::DISCORD:GUILD_ID") }}" class="form-control @error('discord-guild-id') is-invalid @enderror">
class="form-control @error('discord-guild-id') is-invalid @enderror">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group mb-3">
<div class="custom-control mb-3"> <div class="custom-control p-0">
<label for="discord-invite-url">{{ __('Your Discord Server iniviation url')}} </label> <label for="discord-invite-url">{{ __('Discord Invite-URL') }}:</label>
<input x-model="discord-invite-url" id="discord-invite-url" name="discord-invite-url" <input x-model="discord-invite-url" id="discord-invite-url" name="discord-invite-url"
type="text" type="text" value="{{ config('SETTINGS::DISCORD:INVITE_URL') }}"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::DISCORD:INVITE_URL") }}" class="form-control @error('discord-invite-url') is-invalid @enderror">
class="form-control @error('discord-invite-url') is-invalid @enderror">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group mb-3">
<div class="custom-control mb-3"> <div class="custom-control p-0">
<label for="discord-role-id">{{ __('Discord role that will be assigned to users when they register (optional)')}} </label> <label for="discord-role-id">{{ __('Discord Role-ID') }}:</label>
<input x-model="discord-role-id" id="discord-role-id" name="discord-role-id" <input x-model="discord-role-id" id="discord-role-id" name="discord-role-id" type="number"
type="number" value="{{ config('SETTINGS::DISCORD:ROLE_ID') }}"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::DISCORD:ROLE_ID") }}" class="form-control @error('discord-role-id') is-invalid @enderror">
class="form-control @error('discord-role-id') is-invalid @enderror">
</div> </div>
</div> </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>
<div class="row">
<button class="btn btn-primary">{{ __('Submit') }}</button> <button class="btn btn-primary mt-3 ml-3">{{ __('Submit') }}</button>
</div>
</form> </form>
<p class="text-muted">
{{ __('Images and Icons may be cached, reload without cache to see your changes appear') }}
</p>
</div> </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

@ -1,140 +0,0 @@
<div class="tab-pane mt-3" id="payments">
<form method="POST" enctype="multipart/form-data" class="mb-3"
action="{{ route('admin.settings.update.paymentsettings') }}">
@csrf
@method('PATCH')
<div class="row">
<div class="col-md-6">
<img class="mb-3" height="50"
src="{{ url('/images/paypal_logo.png') }}">
<!-- PAYPAL -->
<div class="form-group">
<div class="custom-control mb-3">
<label for="paypal-client-id">{{ __('Enter your PayPal Client_ID') }}</label>
<input x-model="paypal-client-id" id="paypal-client-id" name="paypal-client-id" type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID") }}"
class="form-control @error('paypal-client-id') is-invalid @enderror">
</div>
</div>
<!-- PAYPAL -->
<div class="form-group">
<div class="custom-control mb-3">
<label for="paypal-client-secret">{{ __('Your PayPal Secret-Key')}} (
https://developer.paypal.com/docs/integration/direct/rest/ ) </label>
<input x-model="paypal-client-secret" id="paypal-client-secret" name="paypal-client-secret"
type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:SECRET") }}"
class="form-control @error('paypal-client-secret') is-invalid @enderror">
</div>
</div>
<!-- PAYPAL -->
<div class="form-group">
<div class="custom-control mb-3">
<label
for="paypal-sandbox-id">{{ __('Your PayPal SANDBOX Client-ID used for testing') }}</label>
<input x-model="paypal-sandbox-id" id="paypal-sandbox-id" name="paypal-sandbox-id" type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID") }}"
class="form-control @error('paypal-sandbox-id') is-invalid @enderror">
</div>
</div>
<!-- PAYPAL -->
<div class="form-group">
<div class="custom-control mb-3">
<label
for="paypal-sandbox-secret">{{ __('Your PayPal SANDBOX Secret-Key used for testing ') }}</label>
<input x-model="paypal-sandbox-secret" id="paypal-sandbox-secret" name="paypal-sandbox-secret"
type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET") }}"
class="form-control @error('paypal-sandbox-secret') is-invalid @enderror">
</div>
</div>
</div>
<div class="col-md-6">
<img class="mb-3" height="50"
src="{{ url('/images/stripe_logo.png') }}">
<!-- STRIPE -->
<div class="form-group">
<div class="custom-control mb-3">
<label for="stripe-secret">{{ __('Your Stripe Secret-Key')}} (
https://dashboard.stripe.com/account/apikeys )</label>
<input x-model="stripe-secret" id="stripe-secret" name="stripe-secret" type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:SECRET") }}"
class="form-control @error('stripe-secret') is-invalid @enderror">
</div>
</div>
<!-- STRIPE -->
<div class="form-group">
<div class="custom-control mb-3">
<label for="stripe-endpoint-secret">{{ __('Enter your Stripe endpoint-secret-key') }}</label>
<input x-model="stripe-endpoint-secret" id="stripe-endpoint-secret"
name="stripe-endpoint-secret" type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET") }}"
class="form-control @error('stripe-endpoint-secret') is-invalid @enderror">
</div>
</div>
<!-- STRIPE -->
<div class="form-group">
<div class="custom-control mb-3">
<label for="stripe-test-secret">{{ __('Enter your Stripe test-secret-key') }}</label>
<input x-model="stripe-test-secret" id="stripe-test-secret" name="stripe-test-secret"
type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:TEST_SECRET") }}"
class="form-control @error('stripe-test-secret') is-invalid @enderror">
</div>
</div>
<!-- STRIPE -->
<div class="form-group">
<div class="custom-control mb-3">
<label
for="stripe-endpoint-test-secret">{{ __('Enter your Stripe endpoint-test-secret-key') }}</label>
<input x-model="stripe-endpoint-test-secret" id="stripe-endpoint-test-secret"
name="stripe-endpoint-test-secret" type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET") }}"
class="form-control @error('stripe-endpoint-test-secret') is-invalid @enderror">
</div>
</div>
<!-- STRIPE -->
<div class="form-group">
<div class="custom-control mb-3">
<label for="stripe-methods">{{ __('Comma seperated list of payment methods that are enabled')}}
(https://stripe.com/docs/payments/payment-methods/integration-options)</label>
<input x-model="stripe-methods" id="stripe-methods" name="stripe-methods" type="text"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:METHODS") }}"
class="form-control @error('stripe-methods') is-invalid @enderror">
</div>
</div>
</div>
<!-- Sorry IceToast, aber kein plan wie man das hier schön gestalten soll.... -->
<div class="row">
<div class="col-md-6">
<!-- Tax -->
<div class="form-group">
<div class="custom-control mb-3">
<label
for="sales_tax">{{ __('The %-value of tax that will be added to the product price on checkout')}}</label>
<input x-model="sales_tax" id="sales_tax" name="sales_tax" type="number"
value="{{ App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:SALES_TAX") }}"
class="form-control @error('sales_tax') is-invalid @enderror">
</div>
</div>
</div>
</div>
</div>
<button class="btn btn-primary">{{ __('Submit') }}</button>
<!-- end -->
</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

@ -23,6 +23,13 @@
<small><strong>{{ $message }}</strong></small> <small><strong>{{ $message }}</strong></small>
</span> </span>
@enderror @enderror
@if( $errors->has('ptero_registration_error') )
@foreach( $errors->get('ptero_registration_error') as $err )
<span class="text-danger" role="alert">
<small><strong>{{ $err }}</strong></small>
</span>
@endforeach
@endif
@csrf @csrf
<div class="form-group"> <div class="form-group">

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,9 +32,28 @@
<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;">
<!-- Scripts -->
<script src="{{ asset('js/app.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>
<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">
@ -49,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="{{ \App\Models\Settings::getValueByKey("SETTINGS::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 -->
@if (\App\Models\Settings::getValueByKey("SETTINGS::LOCALE:CLIENTS_CAN_CHANGE")=='true') @if (config('SETTINGS::LOCALE:CLIENTS_CAN_CHANGE') == 'true')
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link" href="#" id="languageDropdown" role="button" data-toggle="dropdown" <a class="nav-link" href="#" id="languageDropdown" role="button" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false"> aria-haspopup="true" aria-expanded="false">
<span class="mr-1 d-lg-inline text-gray-600"> <span class="mr-1 d-lg-inline text-gray-600">
<small><i class="fa fa-language mr-2"></i></small>{{ __('Language') }} <small><i class="fa fa-language mr-2"></i></small>{{ __('Language') }}
</span> </span>
</a> </a>
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" <div class="dropdown-menu dropdown-menu-right shadow animated--grow-in"
aria-labelledby="changeLocale"> aria-labelledby="changeLocale">
<form method="post" action="{{ route('changeLocale') }}" class="nav-item text-center"> <form method="post" action="{{ route('changeLocale') }}" class="nav-item text-center">
@csrf @csrf
@foreach (json_decode(\App\Models\Settings::getValueByKey("SETTINGS::LOCALE:AVAILABLE")) as $key) @foreach (explode(',', config('SETTINGS::LOCALE:AVAILABLE')) as $key)
<button class="dropdown-item" name="inputLocale" value="{{ $key }}"> <button class="dropdown-item" name="inputLocale" value="{{ $key }}">
{{ __($key) }} {{ __($key) }}
</button> </button>
@endforeach @endforeach
</form> </form>
</div> </div>
</li> </li>
<!-- End Language Selection --> <!-- End Language Selection -->
@endif @endif
</ul> </ul>
<!-- Right navbar links --> <!-- Right navbar links -->
@ -211,7 +230,7 @@
</a> </a>
</li> </li>
@if ((\App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:SECRET") && \App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS: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>
@ -258,7 +277,8 @@
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="{{ route('admin.servers.index') }}" class="nav-link @if (Request::routeIs('admin.servers.*')) active @endif"> <a href="{{ route('admin.servers.index') }}"
class="nav-link @if (Request::routeIs('admin.servers.*')) active @endif">
<i class="nav-icon fas fa-server"></i> <i class="nav-icon fas fa-server"></i>
<p>{{ __('Servers') }}</p> <p>{{ __('Servers') }}</p>
</a> </a>
@ -389,7 +409,7 @@
{{-- <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" 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="{{ asset('js/adminlte.min.js') }}"></script> --}}
<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 src="{{ asset('js/app.js') }}"></script>
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.24/datatables.min.js"></script> <script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.24/datatables.min.js"></script>
<!-- Summernote --> <!-- Summernote -->
<script src="{{ asset('plugins/summernote/summernote-bs4.min.js') }}"></script> <script src="{{ asset('plugins/summernote/summernote-bs4.min.js') }}"></script>
@ -403,17 +423,17 @@
<script src="{{ asset('plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js') }}"></script> <script src="{{ asset('plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js') }}"></script>
<!-- Select2 --> <!-- Select2 -->
<script src={{ asset('plugins/select2/js/select2.min.js') }}> <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();
$.ajaxSetup({ $.ajaxSetup({
headers: { headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
} }
});
}); });
});
</script> </script>
<script> <script>
@if (Session::has('error')) @if (Session::has('error'))
@ -423,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,12 +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" href="{{route('profile.index')}}">{{__('Profile')}}</a> <li class="breadcrumb-item"><a class="text-muted"
href="{{ route('profile.index') }}">{{ __('Profile') }}</a>
</li> </li>
</ol> </ol>
</div> </div>
@ -26,28 +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> <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Required Email verification!') }}
{{__('You have not yet verified your email address')}} </h5>
<a class="text-primary" href="{{route('verification.send')}}">{{__('Click here to resend verification email')}}</a> <br> {{ __('You have not yet verified your email address') }}
{{__('Please contact support If you didnt receive your verification email.')}} <a class="text-primary"
href="{{ route('verification.send') }}">{{ __('Click here to resend verification email') }}</a>
<br>
{{ __('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(\App\Models\Settings::getValueByKey("SETTINGS::DISCORD:CLIENT_ID")) && !empty(\App\Models\Settings::getValueByKey("SETTINGS::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><i class="icon fas fa-exclamation-circle"></i>{{__('Required Discord verification!')}}</h5> <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Required Discord verification!') }}
{{__('You have not yet verified your discord account')}} </h5>
<a class="text-primary" href="{{route('auth.redirect')}}">{{__('Login with discord')}}</a> <br> {{ __('You have not yet verified your discord account') }}
{{__('Please contact support If you face any issues.')}} <a class="text-primary"
href="{{ route('auth.redirect') }}">{{ __('Login with discord') }}</a> <br>
{{ __('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><i class="icon fas fa-exclamation-circle"></i>{{__('Required Discord verification!')}}</h5> <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Required Discord verification!') }}
{{__('Due to system settings you are required to verify your discord account!')}} <br> </h5>
{{__('It looks like this hasnt been set-up correctly! Please contact support.')}}' {{ __('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.') }}'
</div> </div>
@endif @endif
@endif @endif
@ -55,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">
@ -64,42 +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)" class="active nav-link">{{__('Settings')}}</a> <li class="nav-item"><a href="javasript:void(0)"
class="active nav-link">{{ __('Settings') }}</a>
</li> </li>
</ul> </ul>
<div class="tab-content pt-3"> <div class="tab-content pt-3">
@ -108,31 +116,44 @@
<div class="col"> <div class="col">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
@if( $errors->has('pterodactyl_error_message') )
@foreach( $errors->get('pterodactyl_error_message') as $err )
<span class="text-danger" role="alert">
<small><strong>{{ $err }}</strong></small>
</span>
@endforeach
@endif
@if( $errors->has('pterodactyl_error_status') )
@foreach( $errors->get('pterodactyl_error_status') as $err )
<span class="text-danger" role="alert">
<small><strong>{{ $err }}</strong></small>
</span>
@endforeach
@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>
@ -141,92 +162,97 @@
</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> <input <div class="form-group">
<label>{{ __('Current Password') }}</label>
<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>
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="form-group"><label>{{__('Confirm Password')}}</span></label> <div class="form-group">
<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(\App\Models\Settings::getValueByKey("SETTINGS::DISCORD:CLIENT_ID")) && !empty(\App\Models\Settings::getValueByKey("SETTINGS::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>
@ -238,7 +264,8 @@
</div> </div>
<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" type="submit">{{__('Save Changes')}}</button> <button class="btn btn-primary"
type="submit">{{ __('Save Changes') }}</button>
</div> </div>
</div> </div>

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(\App\Models\Settings::getValueByKey("SETTINGS::MISC:PHPMYADMIN:URL"))) @if (!empty(config('SETTINGS::MISC:PHPMYADMIN:URL')))
<a href="{{\App\Models\Settings::getValueByKey("SETTINGS::MISC:PHPMYADMIN:URL") }}" <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="{{ \App\Models\Settings::getValueByKey("SETTINGS::SYSTEM:PTERODACTYL:URL") }}/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 (\App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:SECRET")|| \App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:PAYPAL:SANDBOX_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 (\App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS:STRIPE:TEST_SECRET") || \App\Models\Settings::getValueByKey("SETTINGS::PAYMENTS: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

@ -81,4 +81,23 @@
</section> </section>
<!-- END CONTENT --> <!-- END CONTENT -->
<script>
const getUrlParameter = (param) => {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
return urlParams.get(param);
}
const voucherCode = getUrlParameter('voucher');
//if voucherCode not empty, open the modal and fill the input
if (voucherCode) {
$(function() {
$('#redeemVoucherModal').modal('show');
$('#redeemVoucherCode').val(voucherCode);
});
}
</script>
@endsection @endsection

View file

@ -20,6 +20,8 @@ use Illuminate\Support\Facades\Route;
Route::middleware('api.token')->group(function () { Route::middleware('api.token')->group(function () {
Route::patch('/users/{user}/increment', [UserController::class, 'increment']); Route::patch('/users/{user}/increment', [UserController::class, 'increment']);
Route::patch('/users/{user}/decrement', [UserController::class, 'decrement']); Route::patch('/users/{user}/decrement', [UserController::class, 'decrement']);
Route::patch('/users/{user}/suspend', [UserController::class, 'suspend']);
Route::patch('/users/{user}/unsuspend', [UserController::class, 'unsuspend']);
Route::resource('users', UserController::class)->except(['create']); Route::resource('users', UserController::class)->except(['create']);
Route::patch('/servers/{server}/suspend', [ServerController::class, 'suspend']); Route::patch('/servers/{server}/suspend', [ServerController::class, 'suspend']);

View file

@ -10,7 +10,7 @@ use App\Http\Controllers\Admin\PaymentController;
use App\Http\Controllers\Admin\CreditProductController; use App\Http\Controllers\Admin\CreditProductController;
use App\Http\Controllers\Admin\ProductController; use App\Http\Controllers\Admin\ProductController;
use App\Http\Controllers\Admin\ServerController as AdminServerController; use App\Http\Controllers\Admin\ServerController as AdminServerController;
use App\Http\Controllers\Admin\SettingsControllers\SettingsController; use App\Http\Controllers\Admin\SettingsController;
use App\Http\Controllers\Admin\UsefulLinkController; use App\Http\Controllers\Admin\UsefulLinkController;
use App\Http\Controllers\Admin\UserController; use App\Http\Controllers\Admin\UserController;
use App\Http\Controllers\Admin\VoucherController; use App\Http\Controllers\Admin\VoucherController;
@ -27,6 +27,7 @@ use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use App\Classes\Settings\Language; use App\Classes\Settings\Language;
use App\Classes\Settings\Invoices; use App\Classes\Settings\Invoices;
use App\Classes\Settings\System;
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -134,10 +135,11 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () {
Route::patch('settings/updatevalue', [SettingsController::class, 'updatevalue'])->name('settings.updatevalue'); Route::patch('settings/updatevalue', [SettingsController::class, 'updatevalue'])->name('settings.updatevalue');
#settings #settings
Route::patch('settings/update/invoice-settings', [Invoices::class, 'updateInvoiceSettings'])->name('settings.update.invoicesettings'); Route::patch('settings/update/invoice-settings', [Invoices::class, 'updateSettings'])->name('settings.update.invoicesettings');
Route::patch('settings/update/language', [Language::class, 'updateLanguageSettings'])->name('settings.update.languagesettings'); Route::patch('settings/update/language', [Language::class, 'updateSettings'])->name('settings.update.languagesettings');
Route::patch('settings/update/payment', [Payments::class, 'updatePaymentSettings'])->name('settings.update.paymentsettings'); Route::patch('settings/update/payment', [Payments::class, 'updateSettings'])->name('settings.update.paymentsettings');
Route::patch('settings/update/misc', [Misc::class, 'updateMiscSettings'])->name('settings.update.miscsettings'); Route::patch('settings/update/misc', [Misc::class, 'updateSettings'])->name('settings.update.miscsettings');
Route::patch('settings/update/system', [System::class, 'updateSettings'])->name('settings.update.systemsettings');
Route::resource('settings', SettingsController::class)->only('index'); Route::resource('settings', SettingsController::class)->only('index');
#invoices #invoices