Browse Source

Merge branch 'development' into installer_script

Dennis 3 years ago
parent
commit
95bd093979
41 changed files with 1396 additions and 766 deletions
  1. 4 4
      app/Classes/Pterodactyl.php
  2. 6 10
      app/Classes/Settings/Invoices.php
  3. 22 9
      app/Classes/Settings/Language.php
  4. 41 24
      app/Classes/Settings/Misc.php
  5. 22 13
      app/Classes/Settings/Payments.php
  6. 73 0
      app/Classes/Settings/System.php
  7. 20 7
      app/Http/Controllers/Admin/PaymentController.php
  8. 2 4
      app/Http/Controllers/Admin/SettingsController.php
  9. 64 2
      app/Http/Controllers/Api/UserController.php
  10. 13 5
      app/Http/Controllers/Auth/LoginController.php
  11. 22 19
      app/Http/Controllers/Auth/RegisterController.php
  12. 46 11
      app/Http/Controllers/ProfileController.php
  13. 4 4
      app/Http/Controllers/ServerController.php
  14. 2 2
      app/Http/Middleware/GlobalNames.php
  15. 5 6
      app/Http/Middleware/SetLocale.php
  16. 18 18
      app/Notifications/WelcomeMessage.php
  17. 0 3
      app/Providers/AppServiceProvider.php
  18. 16 25
      config/mail.php
  19. 4 4
      database/migrations/2021_05_08_081218_create_paypal_products_table.php
  20. 33 0
      database/migrations/2021_05_08_164658_create_configurations_table.php
  21. 3 3
      database/migrations/2021_05_09_153742_add_display_to_paypal_products_table.php
  22. 34 0
      database/migrations/2022_01_14_234418_update_settings_table_allow_nullable.php
  23. 74 3
      database/seeders/Seeds/SettingsSeeder.php
  24. 11 4
      resources/lang/de.json
  25. 13 0
      resources/views/admin/settings/index.blade.php
  26. 0 121
      resources/views/admin/settings/tabs/configurations.blade.php
  27. 49 42
      resources/views/admin/settings/tabs/invoices.blade.php
  28. 64 59
      resources/views/admin/settings/tabs/language.blade.php
  29. 153 83
      resources/views/admin/settings/tabs/misc.blade.php
  30. 144 0
      resources/views/admin/settings/tabs/payment.blade.php
  31. 0 140
      resources/views/admin/settings/tabs/payments.blade.php
  32. 208 0
      resources/views/admin/settings/tabs/system.blade.php
  33. 7 0
      resources/views/auth/register.blade.php
  34. 24 15
      resources/views/layouts/app.blade.php
  35. 53 34
      resources/views/layouts/main.blade.php
  36. 109 82
      resources/views/profile/index.blade.php
  37. 3 3
      resources/views/servers/index.blade.php
  38. 2 2
      resources/views/store/checkout.blade.php
  39. 19 0
      resources/views/store/index.blade.php
  40. 2 0
      routes/api.php
  41. 7 5
      routes/web.php

+ 4 - 4
app/Classes/Pterodactyl.php

@@ -27,10 +27,10 @@ class Pterodactyl
     public static function client()
     {
         return Http::withHeaders([
-            'Authorization' => 'Bearer ' . Settings::getValueByKey("SETTINGS::SYSTEM:PTERODACTYL:TOKEN"),
+            'Authorization' => 'Bearer ' . config("SETTINGS::SYSTEM:PTERODACTYL:TOKEN"),
             'Content-type'  => 'application/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)
     {
-        $per_page = Settings::getValueByKey('SETTINGS::SERVER:ALLOCATION_LIMIT', 200);
+        $per_page = config('SETTINGS::SERVER:ALLOCATION_LIMIT', 200);
         try {
             $response = self::client()->get("/application/nodes/{$node->id}/allocations?per_page={$per_page}");
         } catch (Exception $e) {
@@ -158,7 +158,7 @@ class Pterodactyl
      */
     public static function url(string $route): string
     {
-        return Settings::getValueByKey("SETTINGS::SYSTEM:PTERODACTYL:URL") . $route;
+        return config("SETTINGS::SYSTEM:PTERODACTYL:URL") . $route;
     }
 
     /**

+ 6 - 10
app/Classes/Settings/Invoices.php

@@ -8,16 +8,13 @@ use Illuminate\Support\Facades\Cache;
 
 class Invoices
 {
-    public $tabTitle = 'Invoice Settings';
-    public $invoiceSettings;
-
     public function __construct()
     {
         return;
     }
 
 
-    public function updateInvoiceSettings(Request $request)
+    public function updateSettings(Request $request)
     {
         $request->validate([
             'logo' => 'nullable|max:10000|mimes:jpg,png,jpeg',
@@ -31,15 +28,14 @@ class Invoices
             "SETTINGS::INVOICE:COMPANY_MAIL" => "company-mail",
             "SETTINGS::INVOICE:COMPANY_VAT" => "company-vat",
             "SETTINGS::INVOICE:COMPANY_WEBSITE" => "company-web",
-            "SETTINGS::INVOICE:PREFIX" => "invoice-prefix"
+            "SETTINGS::INVOICE:PREFIX" => "invoice-prefix",
+            "SETTINGS::INVOICE:ENABLED" => "enable-invoices",
         ];
 
         foreach ($values as $key => $value) {
             $param = $request->get($value);
-            if (!$param) {
-                $param = "";
-            }
-            Settings::where('key', $key)->update(['value' => $param]);
+
+            Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
             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!'));
     }
 }

+ 22 - 9
app/Classes/Settings/Language.php

@@ -6,20 +6,32 @@ use App\Models\Settings;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Session;
+use Illuminate\Support\Facades\Validator;
+
 
 class Language
 {
-    public $tabTitle = 'Language Settings';
-    public $languageSettings;
-
     public function __construct()
     {
         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 = [
             //SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
@@ -33,16 +45,17 @@ class Language
 
         foreach ($values as $key => $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);
             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!'));
     }
-
 }

+ 41 - 24
app/Classes/Settings/Misc.php

@@ -5,64 +5,81 @@ namespace App\Classes\Settings;
 use App\Models\Settings;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Cache;
-use Illuminate\Support\Facades\Config;
-use Illuminate\Support\Facades\Session;
+use Illuminate\Support\Facades\Validator;
+
 
 class Misc
 {
-    public $tabTitle = 'Misc Settings';
-    public $miscSettings;
-
     public function __construct()
     {
         return;
     }
 
-
-
-    public function updateMiscSettings(Request $request)
+    public function updateSettings(Request $request)
     {
-        $request->validate([
+        $validator = Validator::make($request->all(), [
             'icon' => 'nullable|max:10000|mimes:jpg,png,jpeg',
             'favicon' => 'nullable|max:10000|mimes:ico',
+            'discord-bot-token' => 'nullable|string',
+            'discord-client-id' => 'nullable|string',
+            'discord-client-secret' => 'nullable|string',
+            'discord-guild-id' => 'nullable|string',
+            'discord-invite-url' => 'nullable|string',
+            'discord-role-id' => 'nullable|string',
+            'recaptcha-site-key' => 'nullable|string',
+            'recaptcha-secret-key' => 'nullable|string',
+            'enable-recaptcha' => 'nullable|string',
+            'mailservice' => 'nullable|string',
+            'mailhost' => 'nullable|string',
+            'mailport' => 'nullable|string',
+            'mailusername' => 'nullable|string',
+            'mailpassword' => 'nullable|string',
+            'mailencryption' => 'nullable|string',
+            'mailfromadress' => 'nullable|string',
+            'mailfromname' => 'nullable|string',
         ]);
 
+        if ($validator->fails()) {
+            return redirect(route('admin.settings.index') . '#misc')->with('error', __('Misc settings have not been updated!'))->withErrors($validator)
+                ->withInput();
+        }
+
         if ($request->hasFile('icon')) {
             $request->file('icon')->storeAs('public', 'icon.png');
         }
-
         if ($request->hasFile('favicon')) {
             $request->file('favicon')->storeAs('public', 'favicon.ico');
         }
 
         $values = [
-            //SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
-            "SETTINGS::MISC:PHPMYADMIN:URL" => "phpmyadmin-url",
             "SETTINGS::DISCORD:BOT_TOKEN" => "discord-bot-token",
             "SETTINGS::DISCORD:CLIENT_ID" => "discord-client-id",
             "SETTINGS::DISCORD:CLIENT_SECRET" => "discord-client-secret",
             "SETTINGS::DISCORD:GUILD_ID" => "discord-guild-id",
             "SETTINGS::DISCORD:INVITE_URL" => "discord-invite-url",
-            "SETTINGS::DISCORD:ROLE_ID" => "discord-role-id"
+            "SETTINGS::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) {
             $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!'));
     }
-
 }

+ 22 - 13
app/Classes/Settings/Payments.php

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

+ 73 - 0
app/Classes/Settings/System.php

@@ -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!'));
+    }
+}

+ 20 - 7
app/Http/Controllers/Admin/PaymentController.php

@@ -197,7 +197,11 @@ class PaymentController extends Controller
 
                 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
                 return redirect()->route('home')->with('success', __('Your credit balance has been increased!'));
@@ -266,7 +270,7 @@ class PaymentController extends Controller
             ],
 
             '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}',
             'cancel_url' => route('payment.Cancel'),
         ]);
@@ -336,7 +340,10 @@ class PaymentController extends Controller
 
                 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
                 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,
                     ]);
 
-                    $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
                     return redirect()->route('home')->with('success', __('Your payment is being processed!'));
@@ -416,7 +426,10 @@ class PaymentController extends Controller
                 $user->notify(new ConfirmPaymentNotification($payment));
                 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) {
             abort(422);
@@ -521,7 +534,7 @@ class PaymentController extends Controller
             ->pricePerUnit($creditProduct->price);
 
         $notes = [
-            __("Payment method") .": ". $payment->payment_method,
+            __("Payment method") . ": " . $payment->payment_method,
         ];
         $notes = implode("<br>", $notes);
 
@@ -591,7 +604,7 @@ class PaymentController extends Controller
                 return $payment->created_at ? $payment->created_at->diffForHumans() : '';
             })
             ->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'])

+ 2 - 4
app/Http/Controllers/Admin/SettingsControllers/SettingsController.php → app/Http/Controllers/Admin/SettingsController.php

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

+ 64 - 2
app/Http/Controllers/Api/UserController.php

@@ -88,10 +88,25 @@ class UserController extends Controller
             "role" => ['sometimes', Rule::in(['admin', 'mod', 'client', 'member'])],
         ]);
 
-        $user->update($request->all());
-
         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;
     }
 
@@ -166,6 +181,53 @@ class UserController extends Controller
         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
      */

+ 13 - 5
app/Http/Controllers/Auth/LoginController.php

@@ -41,17 +41,25 @@ class LoginController extends Controller
 
     public function login(Request $request)
     {
-        $request->validate([
+
+        $validationRules = [
             $this->username()      => '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
         // 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.
-        if (method_exists($this, 'hasTooManyLoginAttempts') &&
-            $this->hasTooManyLoginAttempts($request)) {
+        if (
+            method_exists($this, 'hasTooManyLoginAttempts') &&
+            $this->hasTooManyLoginAttempts($request)
+        ) {
             $this->fireLockoutEvent($request);
 
             return $this->sendLockoutResponse($request);

+ 22 - 19
app/Http/Controllers/Auth/RegisterController.php

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

+ 46 - 11
app/Http/Controllers/ProfileController.php

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

+ 4 - 4
app/Http/Controllers/ServerController.php

@@ -107,7 +107,7 @@ class ServerController extends Controller
             if (
                 Auth::user()->credits <
                 ($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)
             ) {
                 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
-        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."));
         }
 
         //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."));
         }
 
@@ -168,7 +168,7 @@ class ServerController extends Controller
             '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()) {
                 $request->user()->decrement('credits', $server->product->getHourlyPrice());
             }

+ 2 - 2
app/Http/Middleware/GlobalNames.php

@@ -18,10 +18,10 @@ class GlobalNames
      */
     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 = array_map( 'strtolower', $unsupported_lang_array );
+        $unsupported_lang_array = array_map('strtolower', $unsupported_lang_array);
         define('UNSUPPORTED_LANGS', $unsupported_lang_array);
 
         return $next($request);

+ 5 - 6
app/Http/Middleware/SetLocale.php

@@ -22,17 +22,16 @@ class SetLocale
     public function handle($request, Closure $next)
     {
         if (Session::has('locale')) {
-            $locale = Session::get('locale', Settings::getValueByKey("SETTINGS::LOCALE:DEFAULT"));
+            $locale = Session::get('locale', config("SETTINGS::LOCALE:DEFAULT"));
         } else {
-            if (Settings::getValueByKey("SETTINGS::LOCALE:DYNAMIC")!=="true") {
-                $locale = Settings::getValueByKey("SETTINGS::LOCALE:DEFAULT");
+            if (config("SETTINGS::LOCALE:DYNAMIC") !== "true") {
+                $locale = config("SETTINGS::LOCALE:DEFAULT");
             } else {
                 $locale = substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2);
 
-                if (!in_array($locale, json_decode(Settings::getValueByKey("SETTINGS::LOCALE:AVAILABLE")))) {
-                    $locale = Settings::getValueByKey("SETTINGS::LOCALE:DEFAULT");
+                if (!in_array($locale, explode(',', config("SETTINGS::LOCALE:AVAILABLE")))) {
+                    $locale = config("SETTINGS::LOCALE:DEFAULT");
                 }
-
             }
         }
         App::setLocale($locale);

+ 18 - 18
app/Notifications/WelcomeMessage.php

@@ -38,25 +38,25 @@ class WelcomeMessage extends Notification implements ShouldQueue
         return ['database'];
     }
     public function AdditionalLines()
-        {
-
-            $AdditionalLine = "";
-            if(Settings::getValueByKey('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 />";
-            }
-            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;
+        $AdditionalLine = "";
+        if (config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL') != 0) {
+            $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 (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.
      *
@@ -72,7 +72,7 @@ class WelcomeMessage extends Notification implements ShouldQueue
                 <h5>Verification</h5>
                 <p>You can verify your e-mail address and link/verify your Discord account.</p>
                 <p>
-                  ".$this->AdditionalLines()."
+                  " . $this->AdditionalLines() . "
                 </p>
                 <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>

+ 0 - 3
app/Providers/AppServiceProvider.php

@@ -32,14 +32,11 @@ class AppServiceProvider extends ServiceProvider
         Schema::defaultStringLength(191);
 
         Validator::extend('multiple_date_format', function ($attribute, $value, $parameters, $validator) {
-
             $ok = true;
-
             $result = [];
 
             // iterate through all formats
             foreach ($parameters as $parameter) {
-
                 //validate with laravels standard date format validation
                 $result[] = $validator->validateDateFormat($attribute, $value, [$parameter]);
             }

+ 16 - 25
config/mail.php

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

+ 4 - 4
database/migrations/2021_05_08_081218_create_credit_products_table.php → database/migrations/2021_05_08_081218_create_paypal_products_table.php

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

+ 33 - 0
database/migrations/2021_05_08_164658_create_configurations_table.php

@@ -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');
+    }
+}

+ 3 - 3
database/migrations/2021_05_09_153742_add_display_to_credit_products_table.php → database/migrations/2021_05_09_153742_add_display_to_paypal_products_table.php

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

+ 34 - 0
database/migrations/2022_01_14_234418_update_settings_table_allow_nullable.php

@@ -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();
+        });
+    }
+}

+ 74 - 3
database/seeders/Seeds/SettingsSeeder.php

@@ -144,7 +144,14 @@ class SettingsSeeder extends Seeder
             'type'  => 'integer',
             'description'  => 'The %-value of tax that will be added to the product price on checkout'
         ]);
-
+        //Invoices enabled
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::INVOICE:ENABLED',
+        ], [
+            'value' => 'false',
+            'type'  => 'boolean',
+            'description'  => 'Enables or disables the invoice feature for payments'
+        ]);
         //Invoice company name
         Settings::firstOrCreate([
             'key'   => 'SETTINGS::INVOICE:COMPANY_NAME',
@@ -380,7 +387,7 @@ class SettingsSeeder extends Seeder
         ]);
 
         Settings::firstOrCreate([
-            'key'   => 'SETTINGS::SYSTEM:RECAPTCHA_SITE_KEY',
+            'key'   => 'SETTINGS::RECAPTCHA:SITE_KEY',
         ], [
             'value' => '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI',
             'type'  => 'string',
@@ -388,11 +395,75 @@ class SettingsSeeder extends Seeder
         ]);
 
         Settings::firstOrCreate([
-            'key'   => 'SETTINGS::SYSTEM:RECAPTCHA_SECRET_KEY',
+            'key'   => 'SETTINGS::RECAPTCHA:SECRET_KEY',
         ], [
             'value' => '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe',
             'type'  => 'string',
             'description'  => 'Google Recaptcha API Credentials - https://www.google.com/recaptcha/admin - reCaptcha V2 (not v3)'
         ]);
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::RECAPTCHA:ENABLED',
+        ], [
+            'value' => 'true',
+            'type'  => 'boolean',
+            'description'  => 'Enables or disables the ReCaptcha feature on the registration/login page'
+
+        ]);
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::MAIL:MAILER',
+        ], [
+            'value' => 'smtp',
+            'type'  => 'string',
+            'description'  => 'Selected Mailer (smtp, mailgun, sendgrid, mailtrap)'
+        ]);
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::MAIL:HOST',
+        ], [
+            'value' => 'localhost',
+            'type'  => 'string',
+            'description'  => 'Mailer Host Adress'
+        ]);
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::MAIL:PORT',
+        ], [
+            'value' => '1025',
+            'type'  => 'string',
+            'description'  => 'Mailer Server Port'
+        ]);
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::MAIL:USERNAME',
+        ], [
+            'value' => '',
+            'type'  => 'string',
+            'description'  => 'Mailer Username'
+        ]);
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::MAIL:PASSWORD',
+        ], [
+            'value' => '',
+            'type'  => 'string',
+            'description'  => 'Mailer Password'
+        ]);
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::MAIL:ENCRYPTION',
+        ], [
+            'value' => 'tls',
+            'type'  => 'string',
+            'description'  => 'Mailer Encryption (tls, ssl)'
+        ]);
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::MAIL:FROM_ADDRESS',
+        ], [
+            'value' => '',
+            'type'  => 'string',
+            'description'  => 'Mailer From Address'
+        ]);
+        Settings::firstOrCreate([
+            'key'   => 'SETTINGS::MAIL:FROM_NAME',
+        ], [
+            'value' => env('APP_NAME', 'Controlpanel'),
+            'type'  => 'string',
+            'description'  => 'Mailer From Name'
+        ]);
     }
 }

+ 11 - 4
resources/lang/de.json

@@ -68,7 +68,7 @@
     "User ID": "User-ID",
     "Server Creation Error": "Fehler beim erstellen des Servers",
     "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",
     "If you have any questions please let us know.": "Solltest du weiter fragen haben, melde dich gerne beim Support!",
     "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.",
     "Max": "Max",
     "Expires at": "Läuft ab am",
-    "Used \/ Uses": "Benutzungen",
+    "Used / Uses": "Benutzungen",
     "Expires": "Ablauf",
     "Sign in to start your session": "Melde dich an um das Dashboard zu benutzen",
     "Password": "Passwort",
@@ -287,7 +287,7 @@
     "No nodes have been linked!": "Es wurde keine Nodes verknüpft",
     "No nests available!": "Keine Nests verfügbar",
     "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",
     "---": "---",
     "Specification ": "Spezifikation",
@@ -352,5 +352,12 @@
     "Please pay until": "Zahlbar bis",
     "Account already exists on Pterodactyl. Please contact the Support!": "Der Account existiert bereits bei Pterodactyl. Kontaktiere den Support!",
     "de": "Deutsch",
-    "en": "Englisch"
+    "en": "Englisch",
+    "fr": "Französisch",
+    "cs": "Tschechisch",
+    "es": "Spanisch",
+    "hi": "Hindi",
+    "it": "Italienisch",
+    "pl": "Polnisch",
+    "zh": "Chinesisch"
 }

+ 13 - 0
resources/views/admin/settings/index.blade.php

@@ -66,12 +66,25 @@
 
     <script>
         // Add the following code if you want the name of the file appear on select
+
         document.addEventListener('DOMContentLoaded', () => {
             $(".custom-file-input").on("change", function() {
                 var fileName = $(this).val().split("\\").pop();
                 $(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>
 
 

+ 0 - 121
resources/views/admin/settings/tabs/configurations.blade.php

@@ -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>

+ 49 - 42
resources/views/admin/settings/tabs/invoices.blade.php

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

+ 64 - 59
resources/views/admin/settings/tabs/language.blade.php

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

+ 153 - 83
resources/views/admin/settings/tabs/misc.blade.php

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

+ 144 - 0
resources/views/admin/settings/tabs/payment.blade.php

@@ -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>

+ 0 - 140
resources/views/admin/settings/tabs/payments.blade.php

@@ -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>
-

+ 208 - 0
resources/views/admin/settings/tabs/system.blade.php

@@ -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>

+ 7 - 0
resources/views/auth/register.blade.php

@@ -23,6 +23,13 @@
                                 <small><strong>{{ $message }}</strong></small>
                             </span>
                     @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
                     <div class="form-group">

+ 24 - 15
resources/views/layouts/app.blade.php

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

+ 53 - 34
resources/views/layouts/main.blade.php

@@ -32,9 +32,28 @@
     <noscript>
         <link rel="stylesheet" href="{{ asset('plugins/fontawesome-free/css/all.min.css') }}">
     </noscript>
+    <script src="{{ asset('js/app.js') }}"></script>
 </head>
 
 <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">
         <!-- Navbar -->
         <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>
                 </li>
                 <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>
                 </li>
                 <!-- Language Selection -->
-                @if (\App\Models\Settings::getValueByKey("SETTINGS::LOCALE:CLIENTS_CAN_CHANGE")=='true')
-                <li class="nav-item dropdown">
-                    <a class="nav-link" href="#" id="languageDropdown" role="button" data-toggle="dropdown"
-                        aria-haspopup="true" aria-expanded="false">
-                        <span class="mr-1 d-lg-inline text-gray-600">
-                            <small><i class="fa fa-language mr-2"></i></small>{{ __('Language') }}
-                        </span>
-                    </a>
-                    <div class="dropdown-menu dropdown-menu-right shadow animated--grow-in"
-                        aria-labelledby="changeLocale">
-                        <form method="post" action="{{ route('changeLocale') }}" class="nav-item text-center">
-                            @csrf
-                            @foreach (json_decode(\App\Models\Settings::getValueByKey("SETTINGS::LOCALE:AVAILABLE")) as $key)
+                @if (config('SETTINGS::LOCALE:CLIENTS_CAN_CHANGE') == 'true')
+                    <li class="nav-item dropdown">
+                        <a class="nav-link" href="#" id="languageDropdown" role="button" data-toggle="dropdown"
+                            aria-haspopup="true" aria-expanded="false">
+                            <span class="mr-1 d-lg-inline text-gray-600">
+                                <small><i class="fa fa-language mr-2"></i></small>{{ __('Language') }}
+                            </span>
+                        </a>
+                        <div class="dropdown-menu dropdown-menu-right shadow animated--grow-in"
+                            aria-labelledby="changeLocale">
+                            <form method="post" action="{{ route('changeLocale') }}" class="nav-item text-center">
+                                @csrf
+                                @foreach (explode(',', config('SETTINGS::LOCALE:AVAILABLE')) as $key)
                                     <button class="dropdown-item" name="inputLocale" value="{{ $key }}">
                                         {{ __($key) }}
                                     </button>
 
-                            @endforeach
+                                @endforeach
 
-                        </form>
-                    </div>
-                </li>
-                <!-- End Language Selection -->
-            @endif
+                            </form>
+                        </div>
+                    </li>
+                    <!-- End Language Selection -->
+                @endif
             </ul>
 
             <!-- Right navbar links -->
@@ -211,7 +230,7 @@
                             </a>
                         </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">
                                 <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>
@@ -258,7 +277,8 @@
                             </li>
 
                             <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>
                                     <p>{{ __('Servers') }}</p>
                                 </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="{{ 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="{{ asset('js/app.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>
@@ -403,17 +423,17 @@
     <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 >
-            $(document).ready(function() {
-                $('[data-toggle="popover"]').popover();
-
-                $.ajaxSetup({
-                    headers: {
-                        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
-                    }
-                });
+    <script src={{ asset('plugins/select2/js/select2.min.js') }}></script>
+    <script>
+        $(document).ready(function() {
+            $('[data-toggle="popover"]').popover();
+
+            $.ajaxSetup({
+                headers: {
+                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
+                }
             });
+        });
     </script>
     <script>
         @if (Session::has('error'))
@@ -423,7 +443,6 @@
             html: '{{ Session::get('error') }}',
             })
         @endif
-
         @if (Session::has('success'))
             Swal.fire({
             icon: 'success',

+ 109 - 82
resources/views/profile/index.blade.php

@@ -6,12 +6,13 @@
         <div class="container-fluid">
             <div class="row mb-2">
                 <div class="col-sm-6">
-                    <h1>{{__('Profile')}}</h1>
+                    <h1>{{ __('Profile') }}</h1>
                 </div>
                 <div class="col-sm-6">
                     <ol class="breadcrumb float-sm-right">
-                        <li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
-                        <li class="breadcrumb-item"><a class="text-muted" href="{{route('profile.index')}}">{{__('Profile')}}</a>
+                        <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>
                     </ol>
                 </div>
@@ -26,28 +27,35 @@
 
             <div class="row">
                 <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">
-                            <h5><i class="icon fas fa-exclamation-circle"></i>{{__('Required Email verification!')}}</h5>
-                            {{__('You have not yet verified your email address')}}
-                            <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.')}}
+                            <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Required Email verification!') }}
+                            </h5>
+                            {{ __('You have not yet verified your email address') }}
+                            <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>
                     @endif
 
-                    @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 (is_null(Auth::user()->discordUser) && strtolower($force_discord_verification) == 'true')
+                        @if (!empty(config('SETTINGS::DISCORD:CLIENT_ID')) && !empty(config('SETTINGS::DISCORD:CLIENT_SECRET')))
                             <div class="alert alert-warning p-2 m-2">
-                                <h5><i class="icon fas fa-exclamation-circle"></i>{{__('Required Discord verification!')}}</h5>
-                                {{__('You have not yet verified your discord account')}}
-                                <a class="text-primary" href="{{route('auth.redirect')}}">{{__('Login with discord')}}</a> <br>
-                                {{__('Please contact support If you face any issues.')}}
+                                <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Required Discord verification!') }}
+                                </h5>
+                                {{ __('You have not yet verified your discord account') }}
+                                <a class="text-primary"
+                                    href="{{ route('auth.redirect') }}">{{ __('Login with discord') }}</a> <br>
+                                {{ __('Please contact support If you face any issues.') }}
                             </div>
                         @else
                             <div class="alert alert-danger p-2 m-2">
-                                <h5><i class="icon fas fa-exclamation-circle"></i>{{__('Required Discord verification!')}}</h5>
-                                {{__('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.')}}'
+                                <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Required Discord verification!') }}
+                                </h5>
+                                {{ __('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>
                         @endif
                     @endif
@@ -55,7 +63,7 @@
                 </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
                 @method('PATCH')
                 <div class="card">
@@ -64,42 +72,42 @@
                             <div class="row">
                                 <div class="col-12 col-sm-auto mb-4">
                                     <div class="slim rounded-circle  border-secondary border text-gray-dark"
-                                         data-label="Change your avatar"
-                                         data-max-file-size="3"
-                                         data-save-initial-image="true"
-                                         style="width: 140px;height:140px; cursor: pointer"
-                                         data-size="140,140">
-                                        <img src="{{$user->getAvatar()}}" alt="avatar">
+                                        data-label="Change your avatar" data-max-file-size="3"
+                                        data-save-initial-image="true" style="width: 140px;height:140px; cursor: pointer"
+                                        data-size="140,140">
+                                        <img src="{{ $user->getAvatar() }}" alt="avatar">
                                     </div>
                                 </div>
                                 <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
-                                            class="pt-sm-2 pb-1 mb-0 text-nowrap">{{$user->name}}</h4>
-                                        <p class="mb-0">{{$user->email}}
-                                            @if($user->hasVerifiedEmail())
+                                    <div class="text-center text-sm-left mb-2 mb-sm-0">
+                                        <h4 class="pt-sm-2 pb-1 mb-0 text-nowrap">{{ $user->name }}</h4>
+                                        <p class="mb-0">{{ $user->email }}
+                                            @if ($user->hasVerifiedEmail())
                                                 <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
-                                                <i data-toggle="popover" data-trigger="hover"
-                                                   data-content="Not verified"
-                                                   class="text-danger fas fa-exclamation-circle"></i>
+                                                <i data-toggle="popover" data-trigger="hover" data-content="Not verified"
+                                                    class="text-danger fas fa-exclamation-circle"></i>
                                             @endif
 
                                         </p>
                                         <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 class="text-center text-sm-right"><span
-                                            class="badge badge-secondary">{{$user->role}}</span>
-                                        <div class="text-muted"><small>{{$user->created_at->isoFormat('LL')}}</small>
+                                            class="badge badge-secondary">{{ $user->role }}</span>
+                                        <div class="text-muted">
+                                            <small>{{ $user->created_at->isoFormat('LL') }}</small>
                                         </div>
                                     </div>
                                 </div>
                             </div>
                             <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>
                             </ul>
                             <div class="tab-content pt-3">
@@ -108,31 +116,44 @@
                                         <div class="col">
                                             <div class="row">
                                                 <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
                                                             class="form-control @error('name') is-invalid @enderror"
-                                                            type="text" name="name"
-                                                            placeholder="{{$user->name}}" value="{{$user->name}}">
+                                                            type="text" name="name" placeholder="{{ $user->name }}"
+                                                            value="{{ $user->name }}">
 
                                                         @error('name')
-                                                        <div class="invalid-feedback">
-                                                            {{$message}}
-                                                        </div>
+                                                            <div class="invalid-feedback">
+                                                                {{ $message }}
+                                                            </div>
                                                         @enderror
                                                     </div>
                                                 </div>
                                             </div>
                                             <div class="row">
                                                 <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"
-                                                            type="text"
-                                                            placeholder="{{$user->email}}" name="email"
-                                                            value="{{$user->email}}">
+                                                            type="text" placeholder="{{ $user->email }}" name="email"
+                                                            value="{{ $user->email }}">
 
                                                         @error('email')
-                                                        <div class="invalid-feedback">
-                                                            {{$message}}
-                                                        </div>
+                                                            <div class="invalid-feedback">
+                                                                {{ $message }}
+                                                            </div>
                                                         @enderror
                                                     </div>
                                                 </div>
@@ -141,92 +162,97 @@
                                     </div>
                                     <div class="row">
                                         <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="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"
-                                                            name="current_password" type="password"
-                                                            placeholder="••••••">
+                                                            name="current_password" type="password" placeholder="••••••">
 
                                                         @error('current_password')
-                                                        <div class="invalid-feedback">
-                                                            {{$message}}
-                                                        </div>
+                                                            <div class="invalid-feedback">
+                                                                {{ $message }}
+                                                            </div>
                                                         @enderror
                                                     </div>
                                                 </div>
                                             </div>
                                             <div class="row">
                                                 <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"
                                                             name="new_password" type="password" placeholder="••••••">
 
                                                         @error('new_password')
-                                                        <div class="invalid-feedback">
-                                                            {{$message}}
-                                                        </div>
+                                                            <div class="invalid-feedback">
+                                                                {{ $message }}
+                                                            </div>
                                                         @enderror
                                                     </div>
                                                 </div>
                                             </div>
                                             <div class="row">
                                                 <div class="col">
-                                                    <div class="form-group"><label>{{__('Confirm Password')}}</span></label>
+                                                    <div class="form-group">
+                                                        <label>{{ __('Confirm Password') }}</span></label>
                                                         <input
                                                             class="form-control @error('new_password_confirmation') is-invalid @enderror"
                                                             name="new_password_confirmation" type="password"
                                                             placeholder="••••••">
 
                                                         @error('new_password_confirmation')
-                                                        <div class="invalid-feedback">
-                                                            {{$message}}
-                                                        </div>
+                                                            <div class="invalid-feedback">
+                                                                {{ $message }}
+                                                            </div>
                                                         @enderror
                                                     </div>
                                                 </div>
                                             </div>
                                         </div>
-                                        @if(!empty(\App\Models\Settings::getValueByKey("SETTINGS::DISCORD:CLIENT_ID")) && !empty(\App\Models\Settings::getValueByKey("SETTINGS::DISCORD:CLIENT_SECRET")))
-                                        <div class="col-12 col-sm-5 offset-sm-1 mb-3">
-                                                @if(is_null(Auth::user()->discordUser))
-                                                    <b>{{__('Link your discord account!')}}</b>
+                                        @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">
+                                                @if (is_null(Auth::user()->discordUser))
+                                                    <b>{{ __('Link your discord account!') }}</b>
                                                     <div class="verify-discord">
                                                         <div class="mb-3">
-                                                            @if($credits_reward_after_verify_discord)
-                                                                <p>{{__('By verifying your discord account, you receive extra Credits and increased Server amounts')}}
+                                                            @if ($credits_reward_after_verify_discord)
+                                                                <p>{{ __('By verifying your discord account, you receive extra Credits and increased Server amounts') }}
                                                                 </p>
                                                             @endif
                                                         </div>
                                                     </div>
 
-                                                    <a class="btn btn-light" href="{{route('auth.redirect')}}">
-                                                        <i class="fab fa-discord mr-2"></i>{{__('Login with Discord')}}
+                                                    <a class="btn btn-light" href="{{ route('auth.redirect') }}">
+                                                        <i class="fab fa-discord mr-2"></i>{{ __('Login with Discord') }}
                                                     </a>
                                                 @else
                                                     <div class="verified-discord">
                                                         <div class="my-3 callout callout-info">
-                                                            <p>{{__('You are verified!')}}</p>
+                                                            <p>{{ __('You are verified!') }}</p>
                                                         </div>
                                                     </div>
                                                     <div class="row pl-2">
                                                         <div class="small-box bg-dark">
                                                             <div class="d-flex justify-content-between">
                                                                 <div class="p-3">
-                                                                    <h3>{{$user->discordUser->username}}
-                                                                        <sup>{{$user->discordUser->locale}}</sup></h3>
-                                                                    <p>{{$user->discordUser->id}}
+                                                                    <h3>{{ $user->discordUser->username }}
+                                                                        <sup>{{ $user->discordUser->locale }}</sup>
+                                                                    </h3>
+                                                                    <p>{{ $user->discordUser->id }}
                                                                     </p>
                                                                 </div>
-                                                                <div class="p-3"><img width="100px" height="100px"
-                                                                                      class="rounded-circle"
-                                                                                      src="{{$user->discordUser->getAvatar()}}"
-                                                                                      alt="avatar"></div>
+                                                                <div class="p-3"><img width="100px"
+                                                                        height="100px" class="rounded-circle"
+                                                                        src="{{ $user->discordUser->getAvatar() }}"
+                                                                        alt="avatar"></div>
                                                             </div>
                                                             <div class="small-box-footer">
-                                                                <a href="{{route('auth.redirect')}}">
-                                                                    <i class="fab fa-discord mr-1"></i>{{__('Re-Sync Discord')}}
+                                                                <a href="{{ route('auth.redirect') }}">
+                                                                    <i
+                                                                        class="fab fa-discord mr-1"></i>{{ __('Re-Sync Discord') }}
                                                                 </a>
                                                             </div>
                                                         </div>
@@ -238,7 +264,8 @@
                                     </div>
                                     <div class="row">
                                         <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>
 

+ 3 - 3
resources/views/servers/index.blade.php

@@ -55,8 +55,8 @@
                                         </a>
                                         <div class="dropdown-menu dropdown-menu-right shadow animated--fade-in"
                                             aria-labelledby="dropdownMenuLink">
-                                            @if (!empty(\App\Models\Settings::getValueByKey("SETTINGS::MISC:PHPMYADMIN:URL")))
-                                                <a href="{{\App\Models\Settings::getValueByKey("SETTINGS::MISC:PHPMYADMIN:URL") }}"
+                                            @if (!empty(config('SETTINGS::MISC:PHPMYADMIN:URL')))
+                                                <a href="{{ config('SETTINGS::MISC:PHPMYADMIN:URL') }}"
                                                     class="dropdown-item text-info" target="__blank"><i title="manage"
                                                         class="fas fa-database mr-2"></i><span>{{ __('Database') }}</span></a>
                                             @endif
@@ -149,7 +149,7 @@
                         </div>
 
                         <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"
                                 class="btn btn-info mx-3 w-100 align-items-center justify-content-center d-flex">
                                 <i class="fas fa-tools mr-2"></i>

+ 2 - 2
resources/views/store/checkout.blade.php

@@ -78,7 +78,7 @@
                                 <p class="lead">{{ __('Payment Methods') }}:</p>
 
                                 <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">
                                             <img class="mb-3" height="50"
                                                 src="{{ url('/images/paypal_logo.png') }}"></br>
@@ -88,7 +88,7 @@
                                             </input>
                                         </label>
                                     @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">
                                             <img class="mb-3" height="50"
                                                 src="{{ url('/images/stripe_logo.png') }}" /></br>

+ 19 - 0
resources/views/store/index.blade.php

@@ -81,4 +81,23 @@
     </section>
     <!-- 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

+ 2 - 0
routes/api.php

@@ -20,6 +20,8 @@ use Illuminate\Support\Facades\Route;
 Route::middleware('api.token')->group(function () {
     Route::patch('/users/{user}/increment', [UserController::class, 'increment']);
     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::patch('/servers/{server}/suspend', [ServerController::class, 'suspend']);

+ 7 - 5
routes/web.php

@@ -10,7 +10,7 @@ use App\Http\Controllers\Admin\PaymentController;
 use App\Http\Controllers\Admin\CreditProductController;
 use App\Http\Controllers\Admin\ProductController;
 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\UserController;
 use App\Http\Controllers\Admin\VoucherController;
@@ -27,6 +27,7 @@ use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Route;
 use App\Classes\Settings\Language;
 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');
 
         #settings
-        Route::patch('settings/update/invoice-settings', [Invoices::class, 'updateInvoiceSettings'])->name('settings.update.invoicesettings');
-        Route::patch('settings/update/language', [Language::class, 'updateLanguageSettings'])->name('settings.update.languagesettings');
-        Route::patch('settings/update/payment', [Payments::class, 'updatePaymentSettings'])->name('settings.update.paymentsettings');
-        Route::patch('settings/update/misc', [Misc::class, 'updateMiscSettings'])->name('settings.update.miscsettings');
+        Route::patch('settings/update/invoice-settings', [Invoices::class, 'updateSettings'])->name('settings.update.invoicesettings');
+        Route::patch('settings/update/language', [Language::class, 'updateSettings'])->name('settings.update.languagesettings');
+        Route::patch('settings/update/payment', [Payments::class, 'updateSettings'])->name('settings.update.paymentsettings');
+        Route::patch('settings/update/misc', [Misc::class, 'updateSettings'])->name('settings.update.miscsettings');
+        Route::patch('settings/update/system', [System::class, 'updateSettings'])->name('settings.update.systemsettings');
         Route::resource('settings', SettingsController::class)->only('index');
 
         #invoices