Prechádzať zdrojové kódy

Merge pull request #262 from ControlPanel-gg/development

Development
AVMG 3 rokov pred
rodič
commit
93fdab5e76
40 zmenil súbory, kde vykonal 1126 pridanie a 642 odobranie
  1. 1 1
      app/Http/Controllers/Admin/ConfigurationController.php
  2. 4 4
      app/Http/Controllers/Admin/PaymentController.php
  3. 9 5
      app/Http/Controllers/Admin/ProductController.php
  4. 21 0
      app/Http/Controllers/Admin/UserController.php
  5. 28 2
      app/Http/Controllers/Admin/VoucherController.php
  6. 25 3
      app/Http/Controllers/Api/NotificationController.php
  7. 18 5
      app/Http/Controllers/Api/ServerController.php
  8. 94 21
      app/Http/Controllers/Api/UserController.php
  9. 27 12
      app/Http/Controllers/Api/VoucherController.php
  10. 83 5
      app/Http/Controllers/HomeController.php
  11. 20 9
      app/Http/Controllers/ServerController.php
  12. 4 2
      app/Http/Kernel.php
  13. 28 0
      app/Http/Middleware/CheckSuspended.php
  14. 4 4
      app/Models/Product.php
  15. 98 37
      app/Models/User.php
  16. 13 2
      app/Models/Voucher.php
  17. 23 1
      app/Notifications/WelcomeMessage.php
  18. 0 1
      app/Providers/AppServiceProvider.php
  19. 1 1
      composer.json
  20. 7 7
      composer.lock
  21. 1 1
      config/app.php
  22. 46 0
      config/query-builder.php
  23. 32 0
      database/migrations/2021_09_26_150114_add_suspended_to_users_table.php
  24. 32 0
      database/migrations/2021_10_01_200844_add_product_minimum_credits.php
  25. 16 1
      resources/views/admin/activitylogs/index.blade.php
  26. 12 3
      resources/views/admin/configurations/editModel.blade.php
  27. 103 87
      resources/views/admin/products/create.blade.php
  28. 105 90
      resources/views/admin/products/edit.blade.php
  29. 67 46
      resources/views/admin/products/show.blade.php
  30. 0 240
      resources/views/admin/vouchers/show.blade.php
  31. 93 0
      resources/views/admin/vouchers/users.blade.php
  32. 4 0
      resources/views/auth/login.blade.php
  33. 18 1
      resources/views/home.blade.php
  34. 8 8
      resources/views/mail/payment/confirmed.blade.php
  35. 17 0
      resources/views/profile/index.blade.php
  36. 49 39
      resources/views/servers/create.blade.php
  37. 8 0
      resources/views/servers/index.blade.php
  38. 2 2
      resources/views/store/checkout.blade.php
  39. 1 1
      routes/api.php
  40. 4 1
      routes/web.php

+ 1 - 1
app/Http/Controllers/Admin/ConfigurationController.php

@@ -112,7 +112,7 @@ class ConfigurationController extends Controller
 
 
         return datatables($query)
         return datatables($query)
             ->addColumn('actions', function (Configuration $configuration) {
             ->addColumn('actions', function (Configuration $configuration) {
-                return '<button data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top" onclick="configuration.parse(\'' . $configuration->key . '\',\'' . $configuration->value . '\')" data-content="Edit" data-trigger="hover" data-toggle="tooltip" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></button> ';
+                return '<button data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top" onclick="configuration.parse(\'' . $configuration->key . '\',\'' . $configuration->value . '\',\'' . $configuration->type . '\')" data-content="Edit" data-trigger="hover" data-toggle="tooltip" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></button> ';
             })
             })
             ->editColumn('created_at', function (Configuration $configuration) {
             ->editColumn('created_at', function (Configuration $configuration) {
                 return $configuration->created_at ? $configuration->created_at->diffForHumans() : '';
                 return $configuration->created_at ? $configuration->created_at->diffForHumans() : '';

+ 4 - 4
app/Http/Controllers/Admin/PaymentController.php

@@ -141,12 +141,12 @@ class PaymentController extends Controller
                 $user->increment('credits', $paypalProduct->quantity);
                 $user->increment('credits', $paypalProduct->quantity);
 
 
                 //update server limit
                 //update server limit
-                if (Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE', 10) !== 0) {
-                    if ($user->server_limit < Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE', 10)) {
-                        $user->update(['server_limit' => 10]);
+                if (Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) {
+                    if ($user->server_limit < Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE')) {
+                        $user->update(['server_limit' => Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE')]);
                     }
                     }
                 }
                 }
-
+                
                 //update role
                 //update role
                 if ($user->role == 'member') {
                 if ($user->role == 'member') {
                     $user->update(['role' => 'client']);
                     $user->update(['role' => 'client']);

+ 9 - 5
app/Http/Controllers/Admin/ProductController.php

@@ -3,6 +3,7 @@
 namespace App\Http\Controllers\Admin;
 namespace App\Http\Controllers\Admin;
 
 
 use App\Http\Controllers\Controller;
 use App\Http\Controllers\Controller;
+use App\Models\Configuration;
 use App\Models\Product;
 use App\Models\Product;
 use Exception;
 use Exception;
 use Illuminate\Contracts\Foundation\Application;
 use Illuminate\Contracts\Foundation\Application;
@@ -51,6 +52,7 @@ class ProductController extends Controller
             "swap" => "required|numeric|max:1000000|min:0",
             "swap" => "required|numeric|max:1000000|min:0",
             "description" => "required|string|max:191",
             "description" => "required|string|max:191",
             "disk" => "required|numeric|max:1000000|min:5",
             "disk" => "required|numeric|max:1000000|min:5",
+            "minimum_credits" => "required|numeric|max:1000000|min:-1",
             "io" => "required|numeric|max:1000000|min:0",
             "io" => "required|numeric|max:1000000|min:0",
             "databases" => "required|numeric|max:1000000|min:0",
             "databases" => "required|numeric|max:1000000|min:0",
             "backups" => "required|numeric|max:1000000|min:0",
             "backups" => "required|numeric|max:1000000|min:0",
@@ -73,7 +75,8 @@ class ProductController extends Controller
     public function show(Product $product)
     public function show(Product $product)
     {
     {
         return view('admin.products.show', [
         return view('admin.products.show', [
-            'product' => $product
+            'product' => $product,
+            'minimum_credits' => Configuration::getValueByKey("MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER"),
         ]);
         ]);
     }
     }
 
 
@@ -108,6 +111,7 @@ class ProductController extends Controller
             "description" => "required|string|max:191",
             "description" => "required|string|max:191",
             "disk" => "required|numeric|max:1000000|min:5",
             "disk" => "required|numeric|max:1000000|min:5",
             "io" => "required|numeric|max:1000000|min:0",
             "io" => "required|numeric|max:1000000|min:0",
+            "minimum_credits" => "required|numeric|max:1000000|min:-1",
             "databases" => "required|numeric|max:1000000|min:0",
             "databases" => "required|numeric|max:1000000|min:0",
             "backups" => "required|numeric|max:1000000|min:0",
             "backups" => "required|numeric|max:1000000|min:0",
             "allocations" => "required|numeric|max:1000000|min:0",
             "allocations" => "required|numeric|max:1000000|min:0",
@@ -125,7 +129,8 @@ class ProductController extends Controller
      * @param Product $product
      * @param Product $product
      * @return RedirectResponse
      * @return RedirectResponse
      */
      */
-    public function disable(Request $request, Product $product) {
+    public function disable(Request $request, Product $product)
+    {
         $product->update(['disabled' => !$product->disabled]);
         $product->update(['disabled' => !$product->disabled]);
 
 
         return redirect()->route('admin.products.index')->with('success', 'product has been updated!');
         return redirect()->route('admin.products.index')->with('success', 'product has been updated!');
@@ -181,12 +186,11 @@ class ProductController extends Controller
                             ' . csrf_field() . '
                             ' . csrf_field() . '
                             ' . method_field("PATCH") . '
                             ' . method_field("PATCH") . '
                             <div class="custom-control custom-switch">
                             <div class="custom-control custom-switch">
-                            <input '.$checked.' name="disabled" onchange="this.form.submit()" type="checkbox" class="custom-control-input" id="switch'.$product->id.'">
-                            <label class="custom-control-label" for="switch'.$product->id.'"></label>
+                            <input ' . $checked . ' name="disabled" onchange="this.form.submit()" type="checkbox" class="custom-control-input" id="switch' . $product->id . '">
+                            <label class="custom-control-label" for="switch' . $product->id . '"></label>
                           </div>
                           </div>
                        </form>
                        </form>
                 ';
                 ';
-
             })
             })
             ->editColumn('created_at', function (Product $product) {
             ->editColumn('created_at', function (Product $product) {
                 return $product->created_at ? $product->created_at->diffForHumans() : '';
                 return $product->created_at ? $product->created_at->diffForHumans() : '';

+ 21 - 0
app/Http/Controllers/Admin/UserController.php

@@ -221,6 +221,20 @@ class UserController extends Controller
         return redirect()->route('admin.users.notifications')->with('success', 'Notification sent!');
         return redirect()->route('admin.users.notifications')->with('success', 'Notification sent!');
     }
     }
 
 
+    /**
+     * @param User $user
+     * @return RedirectResponse
+     */
+    public function toggleSuspended(User $user){
+        try {
+            !$user->isSuspended() ? $user->suspend() : $user->unSuspend();
+        } catch (Exception $exception) {
+            return redirect()->back()->with('error', $exception->getMessage());
+        }
+
+        return redirect()->back()->with('success', 'User has been updated!');
+    }
+
     /**
     /**
      *
      *
      * @throws Exception
      * @throws Exception
@@ -252,10 +266,17 @@ class UserController extends Controller
                 return $user->last_seen ? $user->last_seen->diffForHumans() : '';
                 return $user->last_seen ? $user->last_seen->diffForHumans() : '';
             })
             })
             ->addColumn('actions', function (User $user) {
             ->addColumn('actions', function (User $user) {
+                $suspendColor = $user->isSuspended() ? "btn-success" : "btn-warning";
+                $suspendIcon = $user->isSuspended() ? "fa-play-circle" : "fa-pause-circle";
+                $suspendText = $user->isSuspended() ? "Unsuspend" : "Suspend";
                 return '
                 return '
                 <a data-content="Login as user" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.loginas', $user->id) . '" class="btn btn-sm btn-primary mr-1"><i class="fas fa-sign-in-alt"></i></a>
                 <a data-content="Login as user" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.loginas', $user->id) . '" class="btn btn-sm btn-primary mr-1"><i class="fas fa-sign-in-alt"></i></a>
                 <a data-content="Show" data-toggle="popover" data-trigger="hover" data-placement="top"  href="' . route('admin.users.show', $user->id) . '" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-eye"></i></a>
                 <a data-content="Show" data-toggle="popover" data-trigger="hover" data-placement="top"  href="' . route('admin.users.show', $user->id) . '" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-eye"></i></a>
                 <a data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top"  href="' . route('admin.users.edit', $user->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
                 <a data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top"  href="' . route('admin.users.edit', $user->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
+               <form class="d-inline" method="post" action="' . route('admin.users.togglesuspend', $user->id) . '">
+                            ' . csrf_field() . '
+                           <button data-content="'.$suspendText.'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm '.$suspendColor.' text-white mr-1"><i class="far '.$suspendIcon.'"></i></button>
+                       </form>
                 <form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.users.destroy', $user->id) . '">
                 <form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.users.destroy', $user->id) . '">
                             ' . csrf_field() . '
                             ' . csrf_field() . '
                             ' . method_field("DELETE") . '
                             ' . method_field("DELETE") . '

+ 28 - 2
app/Http/Controllers/Admin/VoucherController.php

@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin;
 
 
 use App\Events\UserUpdateCreditsEvent;
 use App\Events\UserUpdateCreditsEvent;
 use App\Http\Controllers\Controller;
 use App\Http\Controllers\Controller;
+use App\Models\User;
 use App\Models\Voucher;
 use App\Models\Voucher;
 use Illuminate\Contracts\Foundation\Application;
 use Illuminate\Contracts\Foundation\Application;
 use Illuminate\Contracts\View\Factory;
 use Illuminate\Contracts\View\Factory;
@@ -115,6 +116,13 @@ class VoucherController extends Controller
         return redirect()->back()->with('success', 'voucher has been removed!');
         return redirect()->back()->with('success', 'voucher has been removed!');
     }
     }
 
 
+    public function users(Voucher $voucher)
+    {
+        return view('admin.vouchers.users', [
+            'voucher' => $voucher
+        ]);
+    }
+
     /**
     /**
      * @param Request $request
      * @param Request $request
      * @return JsonResponse
      * @return JsonResponse
@@ -144,7 +152,7 @@ class VoucherController extends Controller
         ]);
         ]);
 
 
         if ($request->user()->credits + $voucher->credits >= 99999999) throw ValidationException::withMessages([
         if ($request->user()->credits + $voucher->credits >= 99999999) throw ValidationException::withMessages([
-            'code' => "You can't redeem this voucher because you would exceed the ".CREDITS_DISPLAY_NAME." limit"
+            'code' => "You can't redeem this voucher because you would exceed the " . CREDITS_DISPLAY_NAME . " limit"
         ]);
         ]);
 
 
         #redeem voucher
         #redeem voucher
@@ -153,10 +161,27 @@ class VoucherController extends Controller
         event(new UserUpdateCreditsEvent($request->user()));
         event(new UserUpdateCreditsEvent($request->user()));
 
 
         return response()->json([
         return response()->json([
-            'success' => "{$voucher->credits} ".CREDITS_DISPLAY_NAME." have been added to your balance!"
+            'success' => "{$voucher->credits} " . CREDITS_DISPLAY_NAME . " have been added to your balance!"
         ]);
         ]);
     }
     }
 
 
+    public function usersDataTable(Voucher $voucher)
+    {
+        $users = $voucher->users();
+
+        return datatables($users)
+            ->editColumn('name', function (User $user) {
+                return '<a class="text-info" target="_blank" href="' . route('admin.users.show', $user->id) . '">' . $user->name . '</a>';
+            })
+            ->addColumn('credits', function (User $user) {
+                return '<i class="fas fa-coins mr-2"></i> ' . $user->credits();
+            })
+            ->addColumn('last_seen', function (User $user) {
+                return $user->last_seen ? $user->last_seen->diffForHumans() : '';
+            })
+            ->rawColumns(['name', 'credits', 'last_seen'])
+            ->make();
+    }
     public function dataTable()
     public function dataTable()
     {
     {
         $query = Voucher::query();
         $query = Voucher::query();
@@ -164,6 +189,7 @@ class VoucherController extends Controller
         return datatables($query)
         return datatables($query)
             ->addColumn('actions', function (Voucher $voucher) {
             ->addColumn('actions', function (Voucher $voucher) {
                 return '
                 return '
+                            <a data-content="Users" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.vouchers.users', $voucher->id) . '" class="btn btn-sm btn-primary mr-1"><i class="fas fa-users"></i></a>
                             <a data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.vouchers.edit', $voucher->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
                             <a data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.vouchers.edit', $voucher->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
 
 
                            <form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.vouchers.destroy', $voucher->id) . '">
                            <form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.vouchers.destroy', $voucher->id) . '">

+ 25 - 3
app/Http/Controllers/Api/NotificationController.php

@@ -6,11 +6,13 @@ use App\Http\Controllers\Controller;
 use App\Models\DiscordUser;
 use App\Models\DiscordUser;
 use App\Models\User;
 use App\Models\User;
 use App\Notifications\DynamicNotification;
 use App\Notifications\DynamicNotification;
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
 use Illuminate\Notifications\Messages\MailMessage;
 use Illuminate\Notifications\Messages\MailMessage;
 use Illuminate\Support\Facades\Notification;
 use Illuminate\Support\Facades\Notification;
 use Illuminate\Support\HtmlString;
 use Illuminate\Support\HtmlString;
+use Illuminate\Validation\ValidationException;
 use Spatie\ValidationRules\Rules\Delimited;
 use Spatie\ValidationRules\Rules\Delimited;
 
 
 class NotificationController extends Controller
 class NotificationController extends Controller
@@ -55,19 +57,21 @@ class NotificationController extends Controller
      *
      *
      * @param Request $request
      * @param Request $request
      * @return JsonResponse
      * @return JsonResponse
+     * @throws ValidationException
      */
      */
     public function send(Request $request)
     public function send(Request $request)
     {
     {
         $data = $request->validate([
         $data = $request->validate([
             "via" => ["required", new Delimited("in:mail,database")],
             "via" => ["required", new Delimited("in:mail,database")],
             "all" => "required_without:users|boolean",
             "all" => "required_without:users|boolean",
-            "users" => ["required_without:all", new Delimited("exists:users,id")],
+            "users" => ["required_without:all"],
             "title" => "required|string|min:1",
             "title" => "required|string|min:1",
             "content" => "required|string|min:1"
             "content" => "required|string|min:1"
         ]);
         ]);
         $via = explode(",", $data["via"]);
         $via = explode(",", $data["via"]);
         $mail = null;
         $mail = null;
         $database = null;
         $database = null;
+
         if (in_array("database", $via)) {
         if (in_array("database", $via)) {
             $database = [
             $database = [
                 "title" => $data["title"],
                 "title" => $data["title"],
@@ -79,10 +83,28 @@ class NotificationController extends Controller
                 ->subject($data["title"])
                 ->subject($data["title"])
                 ->line(new HtmlString($data["content"]));
                 ->line(new HtmlString($data["content"]));
         }
         }
+
         $all = $data["all"] ?? false;
         $all = $data["all"] ?? false;
-        $users = $all ? User::all() : User::whereIn("id", explode(",", $data["users"]))->get();
+        if ($all) {
+            $users = User::all();
+        } else {
+            $userIds = explode(",", $data["users"]);
+            $users = User::query()
+                ->whereIn("id", $userIds)
+                ->orWhereHas('discordUser', function (Builder $builder) use ($userIds) {
+                    $builder->whereIn('id', $userIds);
+                })
+                ->get();
+        }
+
+        if ($users->count() == 0) {
+            throw ValidationException::withMessages([
+                'users' => ['No users found!'],
+            ]);
+        }
+
         Notification::send($users, new DynamicNotification($via, $database, $mail));
         Notification::send($users, new DynamicNotification($via, $database, $mail));
-        return response()->json(["message" => "Notification successfully sent."]);
+        return response()->json(["message" => "Notification successfully sent.", 'user_count' => $users->count()]);
     }
     }
 
 
     /**
     /**

+ 18 - 5
app/Http/Controllers/Api/ServerController.php

@@ -6,11 +6,17 @@ use App\Http\Controllers\Controller;
 use App\Models\Server;
 use App\Models\Server;
 use Exception;
 use Exception;
 use Illuminate\Contracts\Pagination\LengthAwarePaginator;
 use Illuminate\Contracts\Pagination\LengthAwarePaginator;
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Database\Eloquent\Model;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
+use Spatie\QueryBuilder\QueryBuilder;
 
 
 class ServerController extends Controller
 class ServerController extends Controller
 {
 {
+    public const ALLOWED_INCLUDES = ['product', 'user'];
+    public const ALLOWED_FILTERS = ['name', 'suspended', 'identifier', 'pterodactyl_id', 'user_id', 'product_id'];
+
     /**
     /**
      * Display a listing of the resource.
      * Display a listing of the resource.
      *
      *
@@ -19,21 +25,28 @@ class ServerController extends Controller
      */
      */
     public function index(Request $request)
     public function index(Request $request)
     {
     {
-        return Server::with('product')->paginate($request->query('per_page') ?? 50);
-    }
+        $query = QueryBuilder::for(Server::class)
+            ->allowedIncludes(self::ALLOWED_INCLUDES)
+            ->allowedFilters(self::ALLOWED_FILTERS);
 
 
+        return $query->paginate($request->input('per_page') ?? 50);
+    }
 
 
     /**
     /**
      * Display the specified resource.
      * Display the specified resource.
      *
      *
      * @param Server $server
      * @param Server $server
-     * @return Server
+     *
+     * @return Server|Collection|Model
      */
      */
     public function show(Server $server)
     public function show(Server $server)
     {
     {
-        return $server->load('product');
-    }
+        $query = QueryBuilder::for(Server::class)
+            ->where('id', '=', $server->id)
+            ->allowedIncludes(self::ALLOWED_INCLUDES);
 
 
+        return $query->firstOrFail();
+    }
 
 
     /**
     /**
      * Remove the specified resource from storage.
      * Remove the specified resource from storage.

+ 94 - 21
app/Http/Controllers/Api/UserController.php

@@ -2,28 +2,45 @@
 
 
 namespace App\Http\Controllers\Api;
 namespace App\Http\Controllers\Api;
 
 
+use App\Classes\Pterodactyl;
 use App\Events\UserUpdateCreditsEvent;
 use App\Events\UserUpdateCreditsEvent;
 use App\Http\Controllers\Controller;
 use App\Http\Controllers\Controller;
+use App\Models\Configuration;
 use App\Models\DiscordUser;
 use App\Models\DiscordUser;
 use App\Models\User;
 use App\Models\User;
 use Illuminate\Contracts\Foundation\Application;
 use Illuminate\Contracts\Foundation\Application;
+use Illuminate\Contracts\Pagination\LengthAwarePaginator;
 use Illuminate\Contracts\Routing\ResponseFactory;
 use Illuminate\Contracts\Routing\ResponseFactory;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Database\Eloquent\Model;
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Http\Response;
+use Illuminate\Support\Facades\App;
+use Illuminate\Support\Facades\Hash;
+use Illuminate\Support\Str;
 use Illuminate\Validation\Rule;
 use Illuminate\Validation\Rule;
 use Illuminate\Validation\ValidationException;
 use Illuminate\Validation\ValidationException;
+use Spatie\QueryBuilder\QueryBuilder;
 
 
 class UserController extends Controller
 class UserController extends Controller
 {
 {
+    const ALLOWED_INCLUDES = ['servers', 'notifications', 'payments', 'vouchers', 'discordUser'];
+    const ALLOWED_FILTERS = ['name', 'server_limit', 'email', 'pterodactyl_id', 'role', 'suspended'];
+
     /**
     /**
      * Display a listing of the resource.
      * Display a listing of the resource.
      *
      *
      * @param Request $request
      * @param Request $request
-     * @return Response
+     * @return LengthAwarePaginator
      */
      */
     public function index(Request $request)
     public function index(Request $request)
     {
     {
-        return User::paginate($request->query('per_page') ?? 50);
+        $query = QueryBuilder::for(User::class)
+            ->allowedIncludes(self::ALLOWED_INCLUDES)
+            ->allowedFilters(self::ALLOWED_FILTERS);
+
+        return $query->paginate($request->input('per_page') ?? 50);
     }
     }
 
 
 
 
@@ -31,12 +48,23 @@ class UserController extends Controller
      * Display the specified resource.
      * Display the specified resource.
      *
      *
      * @param int $id
      * @param int $id
-     * @return User
+     *
+     * @return User|Builder|Collection|Model
      */
      */
     public function show(int $id)
     public function show(int $id)
     {
     {
         $discordUser = DiscordUser::find($id);
         $discordUser = DiscordUser::find($id);
-        return $discordUser ? $discordUser->user : User::findOrFail($id);
+        $user = $discordUser ? $discordUser->user : User::findOrFail($id);
+
+        $query = QueryBuilder::for($user)
+            ->with('discordUser')
+            ->allowedIncludes(self::ALLOWED_INCLUDES)
+            ->where('users.id', '=', $id)
+            ->orWhereHas('discordUser', function (Builder $builder) use ($id) {
+                $builder->where('id', '=', $id);
+            });
+
+        return $query->firstOrFail();
     }
     }
 
 
 
 
@@ -53,11 +81,11 @@ class UserController extends Controller
         $user = $discordUser ? $discordUser->user : User::findOrFail($id);
         $user = $discordUser ? $discordUser->user : User::findOrFail($id);
 
 
         $request->validate([
         $request->validate([
-            "name"         => "sometimes|string|min:4|max:30",
-            "email"        => "sometimes|string|email",
-            "credits"      => "sometimes|numeric|min:0|max:1000000",
+            "name" => "sometimes|string|min:4|max:30",
+            "email" => "sometimes|string|email",
+            "credits" => "sometimes|numeric|min:0|max:1000000",
             "server_limit" => "sometimes|numeric|min:0|max:1000000",
             "server_limit" => "sometimes|numeric|min:0|max:1000000",
-            "role"         => ['sometimes', Rule::in(['admin', 'mod', 'client', 'member'])],
+            "role" => ['sometimes', Rule::in(['admin', 'mod', 'client', 'member'])],
         ]);
         ]);
 
 
         $user->update($request->all());
         $user->update($request->all());
@@ -81,23 +109,23 @@ class UserController extends Controller
         $user = $discordUser ? $discordUser->user : User::findOrFail($id);
         $user = $discordUser ? $discordUser->user : User::findOrFail($id);
 
 
         $request->validate([
         $request->validate([
-            "credits"      => "sometimes|numeric|min:0|max:1000000",
+            "credits" => "sometimes|numeric|min:0|max:1000000",
             "server_limit" => "sometimes|numeric|min:0|max:1000000",
             "server_limit" => "sometimes|numeric|min:0|max:1000000",
         ]);
         ]);
 
 
-        if($request->credits){
-             if ($user->credits + $request->credits >= 99999999) throw ValidationException::withMessages([
+        if ($request->credits) {
+            if ($user->credits + $request->credits >= 99999999) throw ValidationException::withMessages([
                 'credits' => "You can't add this amount of credits because you would exceed the credit limit"
                 'credits' => "You can't add this amount of credits because you would exceed the credit limit"
             ]);
             ]);
             event(new UserUpdateCreditsEvent($user));
             event(new UserUpdateCreditsEvent($user));
             $user->increment('credits', $request->credits);
             $user->increment('credits', $request->credits);
-         }
+        }
 
 
-        if($request->server_limit){
+        if ($request->server_limit) {
             if ($user->server_limit + $request->server_limit >= 2147483647) throw ValidationException::withMessages([
             if ($user->server_limit + $request->server_limit >= 2147483647) throw ValidationException::withMessages([
                 'server_limit' => "You cannot add this amount of servers because it would exceed the server limit."
                 'server_limit' => "You cannot add this amount of servers because it would exceed the server limit."
             ]);
             ]);
-           $user->increment('server_limit', $request->server_limit);
+            $user->increment('server_limit', $request->server_limit);
         }
         }
 
 
         return $user;
         return $user;
@@ -117,24 +145,69 @@ class UserController extends Controller
         $user = $discordUser ? $discordUser->user : User::findOrFail($id);
         $user = $discordUser ? $discordUser->user : User::findOrFail($id);
 
 
         $request->validate([
         $request->validate([
-            "credits"      => "sometimes|numeric|min:0|max:1000000",
+            "credits" => "sometimes|numeric|min:0|max:1000000",
             "server_limit" => "sometimes|numeric|min:0|max:1000000",
             "server_limit" => "sometimes|numeric|min:0|max:1000000",
         ]);
         ]);
 
 
-        if($request->credits){
-            if($user->credits - $request->credits < 0) throw ValidationException::withMessages([
+        if ($request->credits) {
+            if ($user->credits - $request->credits < 0) throw ValidationException::withMessages([
                 'credits' => "You can't remove this amount of credits because you would exceed the minimum credit limit"
                 'credits' => "You can't remove this amount of credits because you would exceed the minimum credit limit"
             ]);
             ]);
             $user->decrement('credits', $request->credits);
             $user->decrement('credits', $request->credits);
-         }
+        }
 
 
-        if($request->server_limit){
-            if($user->server_limit - $request->server_limit < 0) throw ValidationException::withMessages([
+        if ($request->server_limit) {
+            if ($user->server_limit - $request->server_limit < 0) throw ValidationException::withMessages([
                 'server_limit' => "You cannot remove this amount of servers because it would exceed the minimum server."
                 'server_limit' => "You cannot remove this amount of servers because it would exceed the minimum server."
             ]);
             ]);
-           $user->decrement('server_limit', $request->server_limit);
+            $user->decrement('server_limit', $request->server_limit);
+        }
+
+        return $user;
+    }
+
+    /**
+     * @throws ValidationException
+     */
+    public function store(Request $request)
+    {
+        $request->validate([
+            'name' => ['required', 'string', 'max:30', 'min:4', 'alpha_num', 'unique:users'],
+            'email' => ['required', 'string', 'email', 'max:64', 'unique:users'],
+            'password' => ['required', 'string', 'min:8', 'max:191'],
+        ]);
+
+        $user = User::create([
+            'name' => $request->input('name'),
+            'email' => $request->input('email'),
+            'credits' => Configuration::getValueByKey('INITIAL_CREDITS', 150),
+            'server_limit' => Configuration::getValueByKey('INITIAL_SERVER_LIMIT', 1),
+            'password' => Hash::make($request->input('password')),
+        ]);
+
+        $response = Pterodactyl::client()->post('/application/users', [
+            "external_id" => App::environment('local') ? Str::random(16) : (string)$user->id,
+            "username" => $user->name,
+            "email" => $user->email,
+            "first_name" => $user->name,
+            "last_name" => $user->name,
+            "password" => $request->input('password'),
+            "root_admin" => false,
+            "language" => "en"
+        ]);
+
+        if ($response->failed()) {
+            $user->delete();
+            throw ValidationException::withMessages([
+                'pterodactyl_error_message' => $response->toException()->getMessage(),
+                'pterodactyl_error_status' => $response->toException()->getCode()
+            ]);
         }
         }
 
 
+        $user->update([
+            'pterodactyl_id' => $response->json()['attributes']['id']
+        ]);
+
         return $user;
         return $user;
     }
     }
 
 

+ 27 - 12
app/Http/Controllers/Api/VoucherController.php

@@ -5,20 +5,30 @@ namespace App\Http\Controllers\Api;
 use App\Http\Controllers\Controller;
 use App\Http\Controllers\Controller;
 use App\Models\Voucher;
 use App\Models\Voucher;
 use Illuminate\Contracts\Pagination\LengthAwarePaginator;
 use Illuminate\Contracts\Pagination\LengthAwarePaginator;
+use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Database\Eloquent\Model;
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Http\Response;
 use Illuminate\Validation\Rule;
 use Illuminate\Validation\Rule;
+use Spatie\QueryBuilder\QueryBuilder;
 
 
 class VoucherController extends Controller
 class VoucherController extends Controller
 {
 {
+    const ALLOWED_INCLUDES = ['users'];
+    const ALLOWED_FILTERS = ['code', 'memo', 'credits', 'uses'];
+
     /**
     /**
      * Display a listing of the resource.
      * Display a listing of the resource.
      *
      *
-     * @return Response
+     * @return LengthAwarePaginator
      */
      */
     public function index(Request $request)
     public function index(Request $request)
     {
     {
-        return Voucher::paginate($request->query('per_page') ?? 50);
+        $query = QueryBuilder::for(Voucher::class)
+            ->allowedIncludes(self::ALLOWED_INCLUDES)
+            ->allowedFilters(self::ALLOWED_FILTERS);
+
+        return $query->paginate($request->input('per_page') ?? 50);
     }
     }
 
 
     /**
     /**
@@ -40,10 +50,10 @@ class VoucherController extends Controller
     public function store(Request $request)
     public function store(Request $request)
     {
     {
         $request->validate([
         $request->validate([
-            'memo'       => 'nullable|string|max:191',
-            'code'       => 'required|string|alpha_dash|max:36|min:4|unique:vouchers',
-            'uses'       => 'required|numeric|max:2147483647|min:1',
-            'credits'    => 'required|numeric|between:0,99999999',
+            'memo' => 'nullable|string|max:191',
+            'code' => 'required|string|alpha_dash|max:36|min:4|unique:vouchers',
+            'uses' => 'required|numeric|max:2147483647|min:1',
+            'credits' => 'required|numeric|between:0,99999999',
             'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years'
             'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years'
         ]);
         ]);
 
 
@@ -54,11 +64,16 @@ class VoucherController extends Controller
      * Display the specified resource.
      * Display the specified resource.
      *
      *
      * @param int $id
      * @param int $id
-     * @return Response
+     *
+     * @return Voucher|Collection|Model
      */
      */
     public function show(int $id)
     public function show(int $id)
     {
     {
-        return Voucher::findOrFail($id);
+        $query = QueryBuilder::for(Voucher::class)
+            ->where('id', '=', $id)
+            ->allowedIncludes(self::ALLOWED_INCLUDES);
+
+        return $query->firstOrFail();
     }
     }
 
 
     /**
     /**
@@ -84,10 +99,10 @@ class VoucherController extends Controller
         $voucher = Voucher::findOrFail($id);
         $voucher = Voucher::findOrFail($id);
 
 
         $request->validate([
         $request->validate([
-            'memo'       => 'nullable|string|max:191',
-            'code'       => "required|string|alpha_dash|max:36|min:4|unique:vouchers,code,{$voucher->id}",
-            'uses'       => 'required|numeric|max:2147483647|min:1',
-            'credits'    => 'required|numeric|between:0,99999999',
+            'memo' => 'nullable|string|max:191',
+            'code' => "required|string|alpha_dash|max:36|min:4|unique:vouchers,code,{$voucher->id}",
+            'uses' => 'required|numeric|max:2147483647|min:1',
+            'credits' => 'required|numeric|between:0,99999999',
             'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years'
             'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years'
         ]);
         ]);
 
 

+ 83 - 5
app/Http/Controllers/HomeController.php

@@ -1,30 +1,108 @@
 <?php
 <?php
-
 namespace App\Http\Controllers;
 namespace App\Http\Controllers;
 
 
 use App\Models\UsefulLink;
 use App\Models\UsefulLink;
+use App\Models\Configuration;
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Auth;
 
 
 class HomeController extends Controller
 class HomeController extends Controller
 {
 {
+    const TIME_LEFT_BG_SUCCESS          = "bg-success";
+    const TIME_LEFT_BG_WARNING          = "bg-warning";
+    const TIME_LEFT_BG_DANGER           = "bg-danger";
+    const TIME_LEFT_OUT_OF_CREDITS_TEXT = "You ran out of Credits";
+
     public function __construct()
     public function __construct()
     {
     {
         $this->middleware('auth');
         $this->middleware('auth');
     }
     }
 
 
+    /**
+    * @description Get the Background Color for the Days-Left-Box in HomeView
+    *
+    * @param  float  $days
+    *
+    * @return string
+    */
+    public function getTimeLeftBoxBackground(float $days)
+    {
+        switch ($days)
+        {
+            case ($days >= 15):
+                return $this::TIME_LEFT_BG_SUCCESS;
+            break;
+
+            case ($days >= 8 && $days <= 14):
+                return $this::TIME_LEFT_BG_WARNING;
+            break;
+
+            case ($days <= 7):
+                return $this::TIME_LEFT_BG_DANGER;
+            break;
+
+            default:
+                return $this::TIME_LEFT_BG_WARNING;
+        }
+    }
+
+    /**
+    * @description Get the Text for the Days-Left-Box in HomeView
+    *
+    * @param  float  $days
+    * @param  float  $hours
+    *
+    * @return string
+    */
+    public function getTimeLeftBoxText(float $days, float $hours)
+    {
+        if ($days < 1)
+        {
+            if ($hours < 1)
+            {
+                return $this::TIME_LEFT_OUT_OF_CREDITS_TEXT;
+            }
+            else
+            {
+                return strval($hours);
+            }
+        }
+        return strval(number_format($days, 0));
+    }
+
     /** Show the application dashboard. */
     /** Show the application dashboard. */
     public function index(Request $request)
     public function index(Request $request)
     {
     {
-        $usage = 0;
+        $usage = Auth::user()->creditUsage();
+        $credits = Auth::user()->Credits();
+        $bg = "";
+        $boxText = "";
+        $unit = "";
+
+        /** Build our Time-Left-Box */
+        if ($credits > 0.01 and $usage > 0)
+        {
+            $days = number_format(($credits * 30) / $usage, 2, '.', '');
+            $hours = number_format($credits / ($usage / 30 / 24) , 2, '.', '');
+
+            $bg = $this->getTimeLeftBoxBackground($days);
+            $boxText = $this->getTimeLeftBoxText($days, $hours);
+            $unit = $days < 1 ? 'hours' : 'days';
 
 
-        foreach (Auth::user()->servers as $server){
-            $usage += $server->product->price;
         }
         }
 
 
+
+
+        // RETURN ALL VALUES
         return view('home')->with([
         return view('home')->with([
             'useage' => $usage,
             'useage' => $usage,
-            'useful_links' => UsefulLink::all()->sortBy('id')
+            'credits' => $credits,
+            'useful_links' => UsefulLink::all()->sortBy('id'),
+            'bg' => $bg,
+            'boxText' => $boxText,
+            'unit' => $unit
         ]);
         ]);
     }
     }
+
 }
 }
+

+ 20 - 9
app/Http/Controllers/ServerController.php

@@ -16,7 +16,8 @@ use Illuminate\Http\Client\Response;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Auth;
-
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Request as FacadesRequest;
 
 
 class ServerController extends Controller
 class ServerController extends Controller
 {
 {
@@ -39,6 +40,7 @@ class ServerController extends Controller
                 $query->where('disabled', '=', false);
                 $query->where('disabled', '=', false);
             })->get(),
             })->get(),
             'nests' => Nest::where('disabled', '=', false)->get(),
             'nests' => Nest::where('disabled', '=', false)->get(),
+            'minimum_credits' => Configuration::getValueByKey('MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)
         ]);
         ]);
     }
     }
 
 
@@ -52,7 +54,7 @@ class ServerController extends Controller
             "description" => "nullable|max:191",
             "description" => "nullable|max:191",
             "node_id" => "required|exists:nodes,id",
             "node_id" => "required|exists:nodes,id",
             "egg_id" => "required|exists:eggs,id",
             "egg_id" => "required|exists:eggs,id",
-            "product_id" => "required|exists:products,id",
+            "product_id" => "required|exists:products,id"
         ]);
         ]);
 
 
         //get required resources
         //get required resources
@@ -74,8 +76,8 @@ class ServerController extends Controller
             'identifier' => $response->json()['attributes']['identifier']
             'identifier' => $response->json()['attributes']['identifier']
         ]);
         ]);
 
 
-        if (Configuration::getValueByKey('SERVER_CREATE_CHARGE_FIRST_HOUR' , 'true') == 'true'){
-            if (Auth::user()->credits >= $server->product->getHourlyPrice()){
+        if (Configuration::getValueByKey('SERVER_CREATE_CHARGE_FIRST_HOUR', 'true') == 'true') {
+            if (Auth::user()->credits >= $server->product->getHourlyPrice()) {
                 Auth::user()->decrement('credits', $server->product->getHourlyPrice());
                 Auth::user()->decrement('credits', $server->product->getHourlyPrice());
             }
             }
         }
         }
@@ -86,15 +88,24 @@ class ServerController extends Controller
     /**
     /**
      * @return null|RedirectResponse
      * @return null|RedirectResponse
      */
      */
-    private function validateConfigurationRules(){
+    private function validateConfigurationRules()
+    {
         //limit validation
         //limit validation
         if (Auth::user()->servers()->count() >= Auth::user()->server_limit) {
         if (Auth::user()->servers()->count() >= Auth::user()->server_limit) {
             return redirect()->route('servers.index')->with('error', 'Server limit reached!');
             return redirect()->route('servers.index')->with('error', 'Server limit reached!');
         }
         }
 
 
-        //minimum credits
-        if (Auth::user()->credits <= Configuration::getValueByKey('MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)) {
-            return redirect()->route('servers.index')->with('error', "You do not have the required amount of ".CREDITS_DISPLAY_NAME." to create a new server!");
+        // minimum credits
+        if (FacadesRequest::has("product_id")) {
+            $product = Product::findOrFail(FacadesRequest::input("product_id"));
+            if (
+                Auth::user()->credits <
+                ($product->minimum_credits == -1
+                    ? Configuration::getValueByKey('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!");
+            }
         }
         }
 
 
         //Required Verification for creating an server
         //Required Verification for creating an server
@@ -141,7 +152,7 @@ class ServerController extends Controller
      * @param Server $server
      * @param Server $server
      * @return RedirectResponse
      * @return RedirectResponse
      */
      */
-    private function serverCreationFailed(Response $response , Server $server)
+    private function serverCreationFailed(Response $response, Server $server)
     {
     {
         $server->delete();
         $server->delete();
 
 

+ 4 - 2
app/Http/Kernel.php

@@ -3,6 +3,7 @@
 namespace App\Http;
 namespace App\Http;
 
 
 use App\Http\Middleware\ApiAuthToken;
 use App\Http\Middleware\ApiAuthToken;
+use App\Http\Middleware\CheckSuspended;
 use App\Http\Middleware\CreditsDisplayName;
 use App\Http\Middleware\CreditsDisplayName;
 use App\Http\Middleware\isAdmin;
 use App\Http\Middleware\isAdmin;
 use App\Http\Middleware\LastSeen;
 use App\Http\Middleware\LastSeen;
@@ -42,7 +43,7 @@ class Kernel extends HttpKernel
             \App\Http\Middleware\VerifyCsrfToken::class,
             \App\Http\Middleware\VerifyCsrfToken::class,
             \Illuminate\Routing\Middleware\SubstituteBindings::class,
             \Illuminate\Routing\Middleware\SubstituteBindings::class,
             LastSeen::class,
             LastSeen::class,
-            CreditsDisplayName::class
+            CreditsDisplayName::class,
         ],
         ],
 
 
         'api' => [
         'api' => [
@@ -70,6 +71,7 @@ class Kernel extends HttpKernel
         'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
         'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
         'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
         'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
         'admin' => isAdmin::class,
         'admin' => isAdmin::class,
-        'api.token' => ApiAuthToken::class
+        'api.token' => ApiAuthToken::class,
+        'checkSuspended' => CheckSuspended::class
     ];
     ];
 }
 }

+ 28 - 0
app/Http/Middleware/CheckSuspended.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Http\Request;
+
+class CheckSuspended
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @return mixed
+     */
+    public function handle(Request $request, Closure $next)
+    {
+        if (auth()->check() && auth()->user()->isSuspended()) {
+            auth()->logout();
+
+            $message = 'Your account has been suspended. Please contact our support team!';
+
+            return redirect()->route('login')->withMessage($message);
+        }
+        return $next($request);
+    }
+}

+ 4 - 4
app/Models/Product.php

@@ -6,7 +6,6 @@ use Hidehalo\Nanoid\Client;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 use Spatie\Activitylog\Traits\LogsActivity;
 use Spatie\Activitylog\Traits\LogsActivity;
 
 
 class Product extends Model
 class Product extends Model
@@ -17,10 +16,11 @@ class Product extends Model
 
 
     protected $guarded = ['id'];
     protected $guarded = ['id'];
 
 
-    public static function boot() {
+    public static function boot()
+    {
         parent::boot();
         parent::boot();
 
 
-        static::creating(function(Product $product) {
+        static::creating(function (Product $product) {
             $client = new Client();
             $client = new Client();
 
 
             $product->{$product->getKeyName()} = $client->generateId($size = 21);
             $product->{$product->getKeyName()} = $client->generateId($size = 21);
@@ -47,6 +47,6 @@ class Product extends Model
      */
      */
     public function servers(): BelongsTo
     public function servers(): BelongsTo
     {
     {
-        return $this->belongsTo(Server::class , 'id' , 'product_id');
+        return $this->belongsTo(Server::class, 'id', 'product_id');
     }
     }
 }
 }

+ 98 - 37
app/Models/User.php

@@ -59,7 +59,8 @@ class User extends Authenticatable implements MustVerifyEmail
         'password',
         'password',
         'pterodactyl_id',
         'pterodactyl_id',
         'discord_verified_at',
         'discord_verified_at',
-        'avatar'
+        'avatar',
+        'suspended'
     ];
     ];
 
 
     /**
     /**
@@ -79,7 +80,9 @@ class User extends Authenticatable implements MustVerifyEmail
      */
      */
     protected $casts = [
     protected $casts = [
         'email_verified_at' => 'datetime',
         'email_verified_at' => 'datetime',
-        'last_seen' => 'datetime',
+        'last_seen'         => 'datetime',
+        'credits'           => 'float',
+        'server_limit'      => 'float',
     ];
     ];
 
 
     /**
     /**
@@ -94,13 +97,13 @@ class User extends Authenticatable implements MustVerifyEmail
         });
         });
 
 
         static::deleting(function (User $user) {
         static::deleting(function (User $user) {
-            $user->servers()->chunk(10 , function ($servers) {
+            $user->servers()->chunk(10, function ($servers) {
                 foreach ($servers as $server) {
                 foreach ($servers as $server) {
                     $server->delete();
                     $server->delete();
                 }
                 }
             });
             });
 
 
-            $user->payments()->chunk(10 , function ($payments) {
+            $user->payments()->chunk(10, function ($payments) {
                 foreach ($payments as $payment) {
                 foreach ($payments as $payment) {
                     $payment->delete();
                     $payment->delete();
                 }
                 }
@@ -114,6 +117,38 @@ class User extends Authenticatable implements MustVerifyEmail
         });
         });
     }
     }
 
 
+    /**
+     * @return HasMany
+     */
+    public function servers()
+    {
+        return $this->hasMany(Server::class);
+    }
+
+    /**
+     * @return HasMany
+     */
+    public function payments()
+    {
+        return $this->hasMany(Payment::class);
+    }
+
+    /**
+     * @return BelongsToMany
+     */
+    public function vouchers()
+    {
+        return $this->belongsToMany(Voucher::class);
+    }
+
+    /**
+     * @return HasOne
+     */
+    public function discordUser()
+    {
+        return $this->hasOne(DiscordUser::class);
+    }
+
     /**
     /**
      *
      *
      */
      */
@@ -131,65 +166,91 @@ class User extends Authenticatable implements MustVerifyEmail
     }
     }
 
 
     /**
     /**
-     * @return string
+     * @return bool
      */
      */
-    public function getAvatar(){
-        return "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email)));
+    public function isSuspended()
+    {
+        return $this->suspended;
     }
     }
 
 
     /**
     /**
-     * @return string
+     *
+     * @throws Exception
      */
      */
-    public function creditUsage()
+    public function suspend()
     {
     {
-        $usage = 0;
-
-        foreach ($this->Servers as $server){
-            $usage += $server->product->price;
+        foreach ($this->servers as $server) {
+            $server->suspend();
         }
         }
 
 
-        return number_format($usage, 2, '.', '');
-    }
+        $this->update([
+            'suspended' => true
+        ]);
 
 
-    /**
-     * @return array|string|string[]
-     */
-    public function getVerifiedStatus(){
-        $status = '';
-        if ($this->hasVerifiedEmail()) $status .= 'email ';
-        if ($this->discordUser()->exists()) $status .= 'discord';
-        $status = str_replace(' ' , '/' , $status);
-        return $status;
+        return $this;
     }
     }
 
 
     /**
     /**
-     * @return BelongsToMany
+     * @throws Exception
      */
      */
-    public function vouchers(){
-        return $this->belongsToMany(Voucher::class);
+    public function unSuspend()
+    {
+        foreach ($this->servers as $server) {
+            if ($this->credits >= $server->product->getHourlyPrice()) {
+                $server->unSuspend();
+            }
+        }
+
+        $this->update([
+            'suspended' => false
+        ]);
+
+        return $this;
     }
     }
 
 
     /**
     /**
-     * @return HasOne
+     * @return string
      */
      */
-    public function discordUser(){
-        return $this->hasOne(DiscordUser::class);
+    public function getAvatar()
+    {
+        //TODO loading the images to confirm they exist is causing to much load time. alternative has to be found :) maybe onerror tag on the <img tags>
+//        if ($this->discordUser()->exists()) {
+//            if(@getimagesize($this->discordUser->getAvatar())) {
+//                $avatar = $this->discordUser->getAvatar();
+//            } else {
+//                $avatar = "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email)));
+//            }
+//        } else {
+//            $avatar = "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email)));
+//        }
+
+        return "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email)));
+
     }
     }
 
 
     /**
     /**
-     * @return HasMany
+     * @return string
      */
      */
-    public function servers()
+    public function creditUsage()
     {
     {
-        return $this->hasMany(Server::class);
+        $usage = 0;
+
+        foreach ($this->Servers as $server) {
+            $usage += $server->product->price;
+        }
+
+        return number_format($usage, 2, '.', '');
     }
     }
 
 
     /**
     /**
-     * @return HasMany
+     * @return array|string|string[]
      */
      */
-    public function payments()
+    public function getVerifiedStatus()
     {
     {
-        return $this->hasMany(Payment::class);
+        $status = '';
+        if ($this->hasVerifiedEmail()) $status .= 'email ';
+        if ($this->discordUser()->exists()) $status .= 'discord';
+        $status = str_replace(' ', '/', $status);
+        return $status;
     }
     }
-
 }
 }

+ 13 - 2
app/Models/Voucher.php

@@ -31,7 +31,17 @@ class Voucher extends Model
         'expires_at'
         'expires_at'
     ];
     ];
 
 
-    protected $appends = ['used' , 'status'];
+    /**
+     * The attributes that should be cast to native types.
+     *
+     * @var array
+     */
+    protected $casts = [
+        'credits' => 'float',
+        'uses'    => 'integer'
+    ];
+
+    protected $appends = ['used', 'status'];
 
 
     /**
     /**
      * @return int
      * @return int
@@ -44,7 +54,8 @@ class Voucher extends Model
     /**
     /**
      * @return string
      * @return string
      */
      */
-    public function getStatusAttribute(){
+    public function getStatusAttribute()
+    {
         return $this->getStatus();
         return $this->getStatus();
     }
     }
 
 

+ 23 - 1
app/Notifications/WelcomeMessage.php

@@ -37,7 +37,26 @@ class WelcomeMessage extends Notification implements ShouldQueue
     {
     {
         return ['database'];
         return ['database'];
     }
     }
+    public function AdditionalLines()
+        {
 
 
+            $AdditionalLine = "";
+            if(Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_EMAIL') != 0) {
+                $AdditionalLine .= "Verifying your e-mail address will grant you ".Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_EMAIL')." additional " . Configuration::getValueByKey('CREDITS_DISPLAY_NAME') . ". <br />";
+            }
+            if(Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') != 0) {
+                $AdditionalLine .= "Verifying your e-mail will also increase your Server Limit by " . Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') . ". <br />";
+            }
+            $AdditionalLine .="<br />";
+            if(Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_DISCORD') != 0) {
+                $AdditionalLine .=  "You can also verify your discord account to get another " . Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_DISCORD') . " " . Configuration::getValueByKey('CREDITS_DISPLAY_NAME') . ". <br />";
+            }
+            if(Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') != 0) {
+                $AdditionalLine .=  "Verifying your Discord account will also increase your Server Limit by " . Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') . ". <br />";
+            }
+
+            return $AdditionalLine;
+        }
     /**
     /**
      * Get the array representation of the notification.
      * Get the array representation of the notification.
      *
      *
@@ -51,7 +70,10 @@ class WelcomeMessage extends Notification implements ShouldQueue
             'content' => "
             'content' => "
                <p>Hello <strong>{$this->user->name}</strong>, Welcome to our dashboard!</p>
                <p>Hello <strong>{$this->user->name}</strong>, Welcome to our dashboard!</p>
                 <h5>Verification</h5>
                 <h5>Verification</h5>
-                <p>Please verify your email address to get " . Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_EMAIL') . " extra credits and increase your server limit to " . Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') . "<br />You can also verify your discord account to get another " . Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_DISCORD') . " credits and to increase your server limit again with " . Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') . "</p>
+                <p>You can verify your e-mail address and link/verify your Discord account.</p>
+                <p>
+                  ".$this->AdditionalLines()."
+                </p>
                 <h5>Information</h5>
                 <h5>Information</h5>
                 <p>This dashboard can be used to create and delete servers.<br /> These servers can be used and managed on our pterodactyl panel.<br /> If you have any questions, please join our Discord server and #create-a-ticket.</p>
                 <p>This dashboard can be used to create and delete servers.<br /> These servers can be used and managed on our pterodactyl panel.<br /> If you have any questions, please join our Discord server and #create-a-ticket.</p>
                 <p>We hope you can enjoy this hosting experience and if you have any suggestions please let us know!</p>
                 <p>We hope you can enjoy this hosting experience and if you have any suggestions please let us know!</p>

+ 0 - 1
app/Providers/AppServiceProvider.php

@@ -29,7 +29,6 @@ class AppServiceProvider extends ServiceProvider
     {
     {
         Paginator::useBootstrap();
         Paginator::useBootstrap();
         Schema::defaultStringLength(191);
         Schema::defaultStringLength(191);
-        QueryBuilderRequest::setArrayValueDelimiter('|');
 
 
         Validator::extend('multiple_date_format', function ($attribute, $value, $parameters, $validator) {
         Validator::extend('multiple_date_format', function ($attribute, $value, $parameters, $validator) {
 
 

+ 1 - 1
composer.json

@@ -23,7 +23,7 @@
         "paypal/rest-api-sdk-php": "^1.14",
         "paypal/rest-api-sdk-php": "^1.14",
         "socialiteproviders/discord": "^4.1",
         "socialiteproviders/discord": "^4.1",
         "spatie/laravel-activitylog": "^3.16",
         "spatie/laravel-activitylog": "^3.16",
-        "spatie/laravel-query-builder": "^3.5",
+        "spatie/laravel-query-builder": "^3.6",
         "spatie/laravel-validation-rules": "^3.0",
         "spatie/laravel-validation-rules": "^3.0",
         "yajra/laravel-datatables-oracle": "~9.0"
         "yajra/laravel-datatables-oracle": "~9.0"
     },
     },

+ 7 - 7
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
         "This file is @generated automatically"
     ],
     ],
-    "content-hash": "b3b61a46d5d4d6560d052cfda863d12c",
+    "content-hash": "f7ba581ff6641d3ab79d558070e99f3c",
     "packages": [
     "packages": [
         {
         {
             "name": "asm89/stack-cors",
             "name": "asm89/stack-cors",
@@ -3462,16 +3462,16 @@
         },
         },
         {
         {
             "name": "spatie/laravel-query-builder",
             "name": "spatie/laravel-query-builder",
-            "version": "3.5.0",
+            "version": "3.6.0",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/spatie/laravel-query-builder.git",
                 "url": "https://github.com/spatie/laravel-query-builder.git",
-                "reference": "4e5257be24139836dc092f618d7c73bcb1c00302"
+                "reference": "03d8e1307dcb58b16fcc9c4947633fc60ae74802"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/laravel-query-builder/zipball/4e5257be24139836dc092f618d7c73bcb1c00302",
-                "reference": "4e5257be24139836dc092f618d7c73bcb1c00302",
+                "url": "https://api.github.com/repos/spatie/laravel-query-builder/zipball/03d8e1307dcb58b16fcc9c4947633fc60ae74802",
+                "reference": "03d8e1307dcb58b16fcc9c4947633fc60ae74802",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
@@ -3528,7 +3528,7 @@
                     "type": "custom"
                     "type": "custom"
                 }
                 }
             ],
             ],
-            "time": "2021-07-05T14:17:44+00:00"
+            "time": "2021-09-06T08:03:10+00:00"
         },
         },
         {
         {
             "name": "spatie/laravel-validation-rules",
             "name": "spatie/laravel-validation-rules",
@@ -8713,5 +8713,5 @@
         "ext-intl": "*"
         "ext-intl": "*"
     },
     },
     "platform-dev": [],
     "platform-dev": [],
-    "plugin-api-version": "2.0.0"
+    "plugin-api-version": "2.1.0"
 }
 }

+ 1 - 1
config/app.php

@@ -2,7 +2,7 @@
 
 
 return [
 return [
 
 
-    'version' => '0.5',
+    'version' => '0.6',
     /*
     /*
     |--------------------------------------------------------------------------
     |--------------------------------------------------------------------------
     | Application Name
     | Application Name

+ 46 - 0
config/query-builder.php

@@ -0,0 +1,46 @@
+<?php
+/**
+ * @see https://github.com/spatie/laravel-query-builder
+ */
+
+return [
+
+    /*
+     * By default the package will use the `include`, `filter`, `sort`
+     * and `fields` query parameters as described in the readme.
+     *
+     * You can customize these query string parameters here.
+     */
+    'parameters' => [
+        'include' => 'include',
+
+        'filter' => 'filter',
+
+        'sort' => 'sort',
+
+        'fields' => 'fields',
+
+        'append' => 'append',
+    ],
+
+    /*
+     * Related model counts are included using the relationship name suffixed with this string.
+     * For example: GET /users?include=postsCount
+     */
+    'count_suffix' => 'Count',
+
+    /*
+     * By default the package will throw an `InvalidFilterQuery` exception when a filter in the
+     * URL is not allowed in the `allowedFilters()` method.
+     */
+    'disable_invalid_filter_query_exception' => false,
+
+    /*
+     * By default the package inspects query string of request using $request->query().
+     * You can change this behavior to inspect the request body using $request->input()
+     * by setting this value to `body`.
+     *
+     * Possible values: `query_string`, `body`
+     */
+    'request_data_source' => 'query_string',
+];

+ 32 - 0
database/migrations/2021_09_26_150114_add_suspended_to_users_table.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddSuspendedToUsersTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->boolean('suspended')->default(false);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->dropColumn('suspended');
+        });
+    }
+}

+ 32 - 0
database/migrations/2021_10_01_200844_add_product_minimum_credits.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddProductMinimumCredits extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('products', function (Blueprint $table) {
+            $table->float('minimum_credits')->default(-1);
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('products', function (Blueprint $table) {
+            $table->dropColumn('minimum_credits');
+        });
+    }
+}

+ 16 - 1
resources/views/admin/activitylogs/index.blade.php

@@ -71,7 +71,10 @@
                         <tbody>
                         <tbody>
                         @foreach($logs as $log)
                         @foreach($logs as $log)
                             <tr>
                             <tr>
-                                <td>{{$log->causer ? json_decode($log->causer)->name : 'system'}}</td>
+        <td> @if($log->causer) <a href='/admin/users/{{$log->causer_id}}'> {{json_decode($log->causer)->name}} 
+		@else 
+			System
+		@endif</td>
                                 <td>
                                 <td>
                                         <span>
                                         <span>
                                             @switch($log->description)
                                             @switch($log->description)
@@ -90,6 +93,18 @@
                                             @endswitch
                                             @endswitch
                                             {{ucfirst($log->description)}}
                                             {{ucfirst($log->description)}}
                                             {{ explode("\\" , $log->subject_type)[2]}}
                                             {{ explode("\\" , $log->subject_type)[2]}}
+				            @php $first=true @endphp
+					    @foreach(json_decode($log->properties, true) as $properties)
+						@if($first)
+						    @if(isset($properties['name']))
+					    	       " {{$properties['name']}} "
+						    @endif
+						    @if(isset($properties['email']))
+						       < {{$properties['email']}} >
+						    @endif
+						    @php $first=false @endphp
+						@endif
+					    @endforeach
                                         </span>
                                         </span>
                                 </td>
                                 </td>
 
 

+ 12 - 3
resources/views/admin/configurations/editModel.blade.php

@@ -22,7 +22,6 @@
                                     <i class="fa fa-cog"></i>
                                     <i class="fa fa-cog"></i>
                                 </div>
                                 </div>
                             </div>
                             </div>
-                            <input id="value" name="value" type="text" class="form-control" required="required">
                         </div>
                         </div>
                     </div>
                     </div>
 
 
@@ -37,16 +36,26 @@
                     <button type="submit" class="btn btn-primary">Save</button>
                     <button type="submit" class="btn btn-primary">Save</button>
                 </div>
                 </div>
             </form>
             </form>
-
         </div>
         </div>
     </div>
     </div>
 </div>
 </div>
 
 
 <script>
 <script>
     window.configuration = {
     window.configuration = {
-        parse(key, value){
+        parse(key, value, type) {
             $('#keyLabel').html(key)
             $('#keyLabel').html(key)
             $('#key').val(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)
             $('#value').val(value)
             $('#editConfigurationModel').modal('show')
             $('#editConfigurationModel').modal('show')
         }
         }

+ 103 - 87
resources/views/admin/products/create.blade.php

@@ -10,9 +10,10 @@
                 </div>
                 </div>
                 <div class="col-sm-6">
                 <div class="col-sm-6">
                     <ol class="breadcrumb float-sm-right">
                     <ol class="breadcrumb float-sm-right">
-                        <li class="breadcrumb-item"><a href="{{route('home')}}">Dashboard</a></li>
-                        <li class="breadcrumb-item"><a href="{{route('admin.products.index')}}">Products</a></li>
-                        <li class="breadcrumb-item"><a class="text-muted" href="{{route('admin.products.create')}}">Create</a>
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">Dashboard</a></li>
+                        <li class="breadcrumb-item"><a href="{{ route('admin.products.index') }}">Products</a></li>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                href="{{ route('admin.products.create') }}">Create</a>
                         </li>
                         </li>
                     </ol>
                     </ol>
                 </div>
                 </div>
@@ -29,12 +30,16 @@
                 <div class="col-lg-6">
                 <div class="col-lg-6">
                     <div class="card">
                     <div class="card">
                         <div class="card-body">
                         <div class="card-body">
-                            <form action="{{route('admin.products.store')}}" method="POST">
+                            <form action="{{ route('admin.products.store') }}" method="POST">
                                 @csrf
                                 @csrf
                                 <div class="d-flex flex-row-reverse">
                                 <div class="d-flex flex-row-reverse">
                                     <div class="custom-control custom-switch">
                                     <div class="custom-control custom-switch">
-                                        <input type="checkbox" name="disabled" class="custom-control-input custom-control-input-danger" id="switch1">
-                                        <label class="custom-control-label" for="switch1">Disabled <i data-toggle="popover" data-trigger="hover" data-content="Will hide this option from being selected" class="fas fa-info-circle"></i></label>
+                                        <input type="checkbox" name="disabled"
+                                            class="custom-control-input custom-control-input-danger" id="switch1">
+                                        <label class="custom-control-label" for="switch1">Disabled <i data-toggle="popover"
+                                                data-trigger="hover"
+                                                data-content="Will hide this option from being selected"
+                                                class="fas fa-info-circle"></i></label>
                                     </div>
                                     </div>
                                 </div>
                                 </div>
 
 
@@ -42,78 +47,75 @@
                                     <div class="col-lg-6">
                                     <div class="col-lg-6">
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="name">Name</label>
                                             <label for="name">Name</label>
-                                            <input value="{{old('name')}}" id="name" name="name" type="text"
-                                                   class="form-control @error('name') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ old('name') }}" id="name" name="name" type="text"
+                                                class="form-control @error('name') is-invalid @enderror"
+                                                required="required">
                                             @error('name')
                                             @error('name')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
 
 
                                         <div class="form-group">
                                         <div class="form-group">
-                                            <label for="price">Price in {{CREDITS_DISPLAY_NAME}}</label>
-                                            <input value="{{old('price')}}" id="price" name="price"
-                                                   type="number"
-                                                   class="form-control @error('price') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="price">Price in {{ CREDITS_DISPLAY_NAME }}</label>
+                                            <input value="{{ old('price') }}" id="price" name="price" type="number"
+                                                class="form-control @error('price') is-invalid @enderror"
+                                                required="required">
                                             @error('price')
                                             @error('price')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
 
 
+
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="memory">Memory</label>
                                             <label for="memory">Memory</label>
-                                            <input value="{{old('memory')}}" id="memory" name="memory"
-                                                   type="number"
-                                                   class="form-control @error('memory') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ old('memory') }}" id="memory" name="memory" type="number"
+                                                class="form-control @error('memory') is-invalid @enderror"
+                                                required="required">
                                             @error('memory')
                                             @error('memory')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
 
 
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="cpu">Cpu</label>
                                             <label for="cpu">Cpu</label>
-                                            <input value="{{old('cpu')}}" id="cpu" name="cpu"
-                                                   type="number"
-                                                   class="form-control @error('cpu') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ old('cpu') }}" id="cpu" name="cpu" type="number"
+                                                class="form-control @error('cpu') is-invalid @enderror" required="required">
                                             @error('cpu')
                                             @error('cpu')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
 
 
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="swap">Swap</label>
                                             <label for="swap">Swap</label>
-                                            <input value="{{old('swap')}}" id="swap" name="swap"
-                                                   type="number"
-                                                   class="form-control @error('swap') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ old('swap') }}" id="swap" name="swap" type="number"
+                                                class="form-control @error('swap') is-invalid @enderror"
+                                                required="required">
                                             @error('swap')
                                             @error('swap')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
 
 
                                         <div class="form-group">
                                         <div class="form-group">
-                                            <label for="description">Description <i data-toggle="popover" data-trigger="hover" data-content="This is what the users sees" class="fas fa-info-circle"></i></label>
-                                            <textarea id="description" name="description"
-                                                      type="text"
-                                                      class="form-control @error('description') is-invalid @enderror"
-                                                      required="required">{{old('description')}}</textarea>
+                                            <label for="description">Description <i data-toggle="popover"
+                                                    data-trigger="hover" data-content="This is what the users sees"
+                                                    class="fas fa-info-circle"></i></label>
+                                            <textarea id="description" name="description" type="text"
+                                                class="form-control @error('description') is-invalid @enderror"
+                                                required="required">{{ old('description') }}</textarea>
                                             @error('description')
                                             @error('description')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
 
 
@@ -121,65 +123,74 @@
                                     <div class="col-lg-6">
                                     <div class="col-lg-6">
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="disk">Disk</label>
                                             <label for="disk">Disk</label>
-                                            <input value="{{old('disk') ?? 1000}}" id="disk" name="disk"
-                                                   type="number"
-                                                   class="form-control @error('disk') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ old('disk') ?? 1000 }}" id="disk" name="disk" type="number"
+                                                class="form-control @error('disk') is-invalid @enderror"
+                                                required="required">
                                             @error('disk')
                                             @error('disk')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
+                                            @enderror
+                                        </div>
+
+                                        <div class="form-group">
+                                            <label for="minimum_credits">Minimum {{ CREDITS_DISPLAY_NAME }} <i
+                                                    data-toggle="popover" data-trigger="hover"
+                                                    data-content="Setting to -1 will use the value from configuration."
+                                                    class="fas fa-info-circle"></i></label>
+                                            <input value="{{ old('minimum_credits') ?? -1 }}" id="minimum_credits"
+                                                name="minimum_credits" type="number"
+                                                class="form-control @error('minimum_credits') is-invalid @enderror"
+                                                required="required">
+                                            @error('minimum_credits')
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
+
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="io">IO</label>
                                             <label for="io">IO</label>
-                                            <input value="{{old('io') ?? 500}}" id="io" name="io"
-                                                   type="number"
-                                                   class="form-control @error('io') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ old('io') ?? 500 }}" id="io" name="io" type="number"
+                                                class="form-control @error('io') is-invalid @enderror" required="required">
                                             @error('io')
                                             @error('io')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="databases">Databases</label>
                                             <label for="databases">Databases</label>
-                                            <input value="{{old('databases') ?? 1}}" id="databases"
-                                                   name="databases"
-                                                   type="number"
-                                                   class="form-control @error('databases') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ old('databases') ?? 1 }}" id="databases" name="databases"
+                                                type="number" class="form-control @error('databases') is-invalid @enderror"
+                                                required="required">
                                             @error('databases')
                                             @error('databases')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="backups">Backups</label>
                                             <label for="backups">Backups</label>
-                                            <input value="{{old('backups') ?? 1}}" id="backups"
-                                                   name="backups"
-                                                   type="number"
-                                                   class="form-control @error('backups') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ old('backups') ?? 1 }}" id="backups" name="backups"
+                                                type="number" class="form-control @error('backups') is-invalid @enderror"
+                                                required="required">
                                             @error('backups')
                                             @error('backups')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="allocations">Allocations</label>
                                             <label for="allocations">Allocations</label>
-                                            <input value="{{old('allocations') ?? 0}}"
-                                                   id="allocations" name="allocations"
-                                                   type="number"
-                                                   class="form-control @error('allocations') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ old('allocations') ?? 0 }}" id="allocations"
+                                                name="allocations" type="number"
+                                                class="form-control @error('allocations') is-invalid @enderror"
+                                                required="required">
                                             @error('allocations')
                                             @error('allocations')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
                                     </div>
                                     </div>
@@ -200,6 +211,11 @@
     </section>
     </section>
     <!-- END CONTENT -->
     <!-- END CONTENT -->
 
 
+    <script>
+        document.addEventListener('DOMContentLoaded', function() {
+            $('[data-toggle="popover"]').popover();
+        });
+    </script>
 
 
 
 
 @endsection
 @endsection

+ 105 - 90
resources/views/admin/products/edit.blade.php

@@ -10,9 +10,10 @@
                 </div>
                 </div>
                 <div class="col-sm-6">
                 <div class="col-sm-6">
                     <ol class="breadcrumb float-sm-right">
                     <ol class="breadcrumb float-sm-right">
-                        <li class="breadcrumb-item"><a href="{{route('home')}}">Dashboard</a></li>
-                        <li class="breadcrumb-item"><a href="{{route('admin.products.index')}}">Products</a></li>
-                        <li class="breadcrumb-item"><a class="text-muted" href="{{route('admin.products.edit' , $product->id)}}">Edit</a>
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">Dashboard</a></li>
+                        <li class="breadcrumb-item"><a href="{{ route('admin.products.index') }}">Products</a></li>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                href="{{ route('admin.products.edit', $product->id) }}">Edit</a>
                         </li>
                         </li>
                     </ol>
                     </ol>
                 </div>
                 </div>
@@ -29,22 +30,28 @@
             <div class="row">
             <div class="row">
                 <div class="col-lg-6">
                 <div class="col-lg-6">
 
 
-                    @if($product->servers()->count() > 0)
+                    @if ($product->servers()->count() > 0)
                         <div class="callout callout-danger">
                         <div class="callout callout-danger">
-                            <h4>Editing the resource options will not automatically update the servers on pterodactyl's side!</h4>
-                            <p class="text-muted">Automatically updating resource options on pterodactyl side is on my todo list :)</p>
+                            <h4>Editing the resource options will not automatically update the servers on pterodactyl's
+                                side!</h4>
+                            <p class="text-muted">Automatically updating resource options on pterodactyl side is on my
+                                todo list :)</p>
                         </div>
                         </div>
                     @endif
                     @endif
 
 
                     <div class="card">
                     <div class="card">
                         <div class="card-body">
                         <div class="card-body">
-                            <form action="{{route('admin.products.update' , $product->id)}}" method="POST">
+                            <form action="{{ route('admin.products.update', $product->id) }}" method="POST">
                                 @csrf
                                 @csrf
                                 @method('PATCH')
                                 @method('PATCH')
                                 <div class="d-flex flex-row-reverse">
                                 <div class="d-flex flex-row-reverse">
                                     <div class="custom-control custom-switch">
                                     <div class="custom-control custom-switch">
-                                        <input type="checkbox" @if($product->disabled) checked @endif name="disabled" class="custom-control-input custom-control-input-danger" id="switch1">
-                                        <label class="custom-control-label" for="switch1">Disabled <i data-toggle="popover" data-trigger="hover" data-content="Will hide this option from being selected" class="fas fa-info-circle"></i></label>
+                                        <input type="checkbox" @if ($product->disabled) checked @endif name="disabled"
+                                            class="custom-control-input custom-control-input-danger" id="switch1">
+                                        <label class="custom-control-label" for="switch1">Disabled <i data-toggle="popover"
+                                                data-trigger="hover"
+                                                data-content="Will hide this option from being selected"
+                                                class="fas fa-info-circle"></i></label>
                                     </div>
                                     </div>
                                 </div>
                                 </div>
 
 
@@ -52,78 +59,74 @@
                                     <div class="col-lg-6">
                                     <div class="col-lg-6">
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="name">Name</label>
                                             <label for="name">Name</label>
-                                            <input value="{{$product->name}}" id="name" name="name" type="text"
-                                                   class="form-control @error('name') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ $product->name }}" id="name" name="name" type="text"
+                                                class="form-control @error('name') is-invalid @enderror"
+                                                required="required">
                                             @error('name')
                                             @error('name')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
 
 
                                         <div class="form-group">
                                         <div class="form-group">
-                                            <label for="price">Price in {{CREDITS_DISPLAY_NAME}}</label>
-                                            <input value="{{$product->price}}" id="price" name="price"
-                                                   type="number"
-                                                   class="form-control @error('price') is-invalid @enderror"
-                                                   required="required">
+                                            <label for="price">Price in {{ CREDITS_DISPLAY_NAME }}</label>
+                                            <input value="{{ $product->price }}" id="price" name="price" type="number"
+                                                class="form-control @error('price') is-invalid @enderror"
+                                                required="required">
                                             @error('price')
                                             @error('price')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
 
 
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="memory">Memory</label>
                                             <label for="memory">Memory</label>
-                                            <input value="{{$product->memory}}" id="memory" name="memory"
-                                                   type="number"
-                                                   class="form-control @error('memory') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ $product->memory }}" id="memory" name="memory" type="number"
+                                                class="form-control @error('memory') is-invalid @enderror"
+                                                required="required">
                                             @error('memory')
                                             @error('memory')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
 
 
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="cpu">Cpu</label>
                                             <label for="cpu">Cpu</label>
-                                            <input value="{{$product->cpu}}" id="cpu" name="cpu"
-                                                   type="number"
-                                                   class="form-control @error('cpu') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ $product->cpu }}" id="cpu" name="cpu" type="number"
+                                                class="form-control @error('cpu') is-invalid @enderror" required="required">
                                             @error('cpu')
                                             @error('cpu')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
 
 
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="swap">Swap</label>
                                             <label for="swap">Swap</label>
-                                            <input value="{{$product->swap}}" id="swap" name="swap"
-                                                   type="number"
-                                                   class="form-control @error('swap') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ $product->swap }}" id="swap" name="swap" type="number"
+                                                class="form-control @error('swap') is-invalid @enderror"
+                                                required="required">
                                             @error('swap')
                                             @error('swap')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
 
 
                                         <div class="form-group">
                                         <div class="form-group">
-                                            <label for="description">Description <i data-toggle="popover" data-trigger="hover" data-content="This is what the users sees" class="fas fa-info-circle"></i></label>
-                                            <textarea id="description" name="description"
-                                                      type="text"
-                                                      class="form-control @error('description') is-invalid @enderror"
-                                                      required="required">{{$product->description}}</textarea>
+                                            <label for="description">Description <i data-toggle="popover"
+                                                    data-trigger="hover" data-content="This is what the users sees"
+                                                    class="fas fa-info-circle"></i></label>
+                                            <textarea id="description" name="description" type="text"
+                                                class="form-control @error('description') is-invalid @enderror"
+                                                required="required">{{ $product->description }}</textarea>
                                             @error('description')
                                             @error('description')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
 
 
@@ -131,65 +134,72 @@
                                     <div class="col-lg-6">
                                     <div class="col-lg-6">
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="disk">Disk</label>
                                             <label for="disk">Disk</label>
-                                            <input value="{{$product->disk}}" id="disk" name="disk"
-                                                   type="number"
-                                                   class="form-control @error('disk') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ $product->disk }}" id="disk" name="disk" type="number"
+                                                class="form-control @error('disk') is-invalid @enderror"
+                                                required="required">
                                             @error('disk')
                                             @error('disk')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
+                                            @enderror
+                                        </div>
+                                        <div class="form-group">
+                                            <label for="minimum_credits">Minimum {{ CREDITS_DISPLAY_NAME }} <i
+                                                    data-toggle="popover" data-trigger="hover"
+                                                    data-content="Setting to -1 will use the value from configuration."
+                                                    class="fas fa-info-circle"></i></label>
+                                            <input value="{{ $product->minimum_credits }}" id="minimum_credits"
+                                                name="minimum_credits" type="number"
+                                                class="form-control @error('minimum_credits') is-invalid @enderror"
+                                                required="required">
+                                            @error('minimum_credits')
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="io">IO</label>
                                             <label for="io">IO</label>
-                                            <input value="{{$product->io}}" id="io" name="io"
-                                                   type="number"
-                                                   class="form-control @error('io') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ $product->io }}" id="io" name="io" type="number"
+                                                class="form-control @error('io') is-invalid @enderror" required="required">
                                             @error('io')
                                             @error('io')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="databases">Databases</label>
                                             <label for="databases">Databases</label>
-                                            <input value="{{$product->databases}}" id="databases"
-                                                   name="databases"
-                                                   type="number"
-                                                   class="form-control @error('databases') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ $product->databases }}" id="databases" name="databases"
+                                                type="number" class="form-control @error('databases') is-invalid @enderror"
+                                                required="required">
                                             @error('databases')
                                             @error('databases')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="backups">Backups</label>
                                             <label for="backups">Backups</label>
-                                            <input value="{{$product->backups}}" id="backups"
-                                                   name="backups"
-                                                   type="number"
-                                                   class="form-control @error('backups') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ $product->backups }}" id="backups" name="backups"
+                                                type="number" class="form-control @error('backups') is-invalid @enderror"
+                                                required="required">
                                             @error('backups')
                                             @error('backups')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
                                         <div class="form-group">
                                         <div class="form-group">
                                             <label for="allocations">Allocations</label>
                                             <label for="allocations">Allocations</label>
-                                            <input value="{{$product->allocations}}"
-                                                   id="allocations" name="allocations"
-                                                   type="number"
-                                                   class="form-control @error('allocations') is-invalid @enderror"
-                                                   required="required">
+                                            <input value="{{ $product->allocations }}" id="allocations"
+                                                name="allocations" type="number"
+                                                class="form-control @error('allocations') is-invalid @enderror"
+                                                required="required">
                                             @error('allocations')
                                             @error('allocations')
-                                            <div class="invalid-feedback">
-                                                {{$message}}
-                                            </div>
+                                                <div class="invalid-feedback">
+                                                    {{ $message }}
+                                                </div>
                                             @enderror
                                             @enderror
                                         </div>
                                         </div>
                                     </div>
                                     </div>
@@ -210,6 +220,11 @@
     </section>
     </section>
     <!-- END CONTENT -->
     <!-- END CONTENT -->
 
 
+    <script>
+        document.addEventListener('DOMContentLoaded', function() {
+            $('[data-toggle="popover"]').popover();
+        });
+    </script>
 
 
 
 
 @endsection
 @endsection

+ 67 - 46
resources/views/admin/products/show.blade.php

@@ -10,10 +10,10 @@
                 </div>
                 </div>
                 <div class="col-sm-6">
                 <div class="col-sm-6">
                     <ol class="breadcrumb float-sm-right">
                     <ol class="breadcrumb float-sm-right">
-                        <li class="breadcrumb-item"><a href="{{route('home')}}">Dashboard</a></li>
-                        <li class="breadcrumb-item"><a href="{{route('admin.users.index')}}">Products</a></li>
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">Dashboard</a></li>
+                        <li class="breadcrumb-item"><a href="{{ route('admin.users.index') }}">Products</a></li>
                         <li class="breadcrumb-item"><a class="text-muted"
                         <li class="breadcrumb-item"><a class="text-muted"
-                                                       href="{{route('admin.products.show' , $product->id)}}">Show</a>
+                                href="{{ route('admin.products.show', $product->id) }}">Show</a>
                         </li>
                         </li>
                     </ol>
                     </ol>
                 </div>
                 </div>
@@ -30,11 +30,15 @@
                 <div class="card-header d-flex justify-content-between">
                 <div class="card-header d-flex justify-content-between">
                     <h5 class="card-title"><i class="fas fa-sliders-h mr-2"></i>Product</h5>
                     <h5 class="card-title"><i class="fas fa-sliders-h mr-2"></i>Product</h5>
                     <div class="ml-auto">
                     <div class="ml-auto">
-                        <a data-content="Edit" data-trigger="hover" data-toggle="tooltip" href="{{ route('admin.products.edit', $product->id) }}" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
-                        <form class="d-inline" onsubmit="return submitResult();" method="post" action="{{ route('admin.products.destroy', $product->id) }}">
+                        <a data-content="Edit" data-trigger="hover" data-toggle="tooltip"
+                            href="{{ route('admin.products.edit', $product->id) }}" class="btn btn-sm btn-info mr-1"><i
+                                class="fas fa-pen"></i></a>
+                        <form class="d-inline" onsubmit="return submitResult();" method="post"
+                            action="{{ route('admin.products.destroy', $product->id) }}">
                             {{ csrf_field() }}
                             {{ csrf_field() }}
-                            {{ method_field("DELETE") }}
-                            <button data-content="Delete" data-trigger="hover" data-toggle="tooltip" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
+                            {{ method_field('DELETE') }}
+                            <button data-content="Delete" data-trigger="hover" data-toggle="tooltip"
+                                class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
                         </form>
                         </form>
                     </div>
                     </div>
                 </div>
                 </div>
@@ -47,9 +51,9 @@
                                     <label>ID</label>
                                     <label>ID</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->id}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $product->id }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -60,9 +64,9 @@
                                     <label>Name</label>
                                     <label>Name</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->name}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $product->name }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -73,9 +77,26 @@
                                     <label>Price</label>
                                     <label>Price</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           <i class="fas fa-coins mr-1"></i>{{$product->price}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        <i class="fas fa-coins mr-1"></i>{{ $product->price }}
+                                    </span>
+                                </div>
+                            </div>
+                        </div>
+
+                        <div class="col-lg-6">
+                            <div class="row">
+                                <div class="col-lg-4">
+                                    <label>Minimum {{ CREDITS_DISPLAY_NAME }}</label>
+                                </div>
+                                <div class="col-lg-8">
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        @if ($product->minimum_credits == -1)
+                                            <i class="fas fa-coins mr-1"></i>{{ $minimum_credits }}
+                                        @else
+                                            <i class="fas fa-coins mr-1"></i>{{ $product->minimum_credits }}
+                                        @endif
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -87,9 +108,9 @@
                                     <label>Memory</label>
                                     <label>Memory</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->memory}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $product->memory }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -100,9 +121,9 @@
                                     <label>CPU</label>
                                     <label>CPU</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->cpu}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $product->cpu }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -113,9 +134,9 @@
                                     <label>Swap</label>
                                     <label>Swap</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->swap}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $product->swap }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -126,9 +147,9 @@
                                     <label>Disk</label>
                                     <label>Disk</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->disk}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $product->disk }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -139,9 +160,9 @@
                                     <label>IO</label>
                                     <label>IO</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->io}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $product->io }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -152,9 +173,9 @@
                                     <label>Databases</label>
                                     <label>Databases</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->databases}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $product->databases }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -165,9 +186,9 @@
                                     <label>Allocations</label>
                                     <label>Allocations</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->allocations}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $product->allocations }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -178,9 +199,9 @@
                                     <label>Created At</label>
                                     <label>Created At</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->created_at ? $product->created_at->diffForHumans() : ''}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $product->created_at ? $product->created_at->diffForHumans() : '' }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -192,9 +213,9 @@
                                     <label>Description</label>
                                     <label>Description</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span class="d-inline-block text-truncate">
-                                           {{$product->description}}
-                                       </span>
+                                    <span class="d-inline-block text-truncate">
+                                        {{ $product->description }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -206,9 +227,9 @@
                                     <label>Updated At</label>
                                     <label>Updated At</label>
                                 </div>
                                 </div>
                                 <div class="col-lg-8">
                                 <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->updated_at ? $product->updated_at->diffForHumans() : ''}}
-                                       </span>
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $product->updated_at ? $product->updated_at->diffForHumans() : '' }}
+                                    </span>
                                 </div>
                                 </div>
                             </div>
                             </div>
                         </div>
                         </div>

+ 0 - 240
resources/views/admin/vouchers/show.blade.php

@@ -1,240 +0,0 @@
-@extends('layouts.main')
-
-@section('content')
-    <!-- CONTENT HEADER -->
-    <section class="content-header">
-        <div class="container-fluid">
-            <div class="row mb-2">
-                <div class="col-sm-6">
-                    <h1>Products</h1>
-                </div>
-                <div class="col-sm-6">
-                    <ol class="breadcrumb float-sm-right">
-                        <li class="breadcrumb-item"><a href="{{route('home')}}">Dashboard</a></li>
-                        <li class="breadcrumb-item"><a href="{{route('admin.users.index')}}">Products</a></li>
-                        <li class="breadcrumb-item"><a class="text-muted"
-                                                       href="{{route('admin.products.show' , $product->id)}}">Show</a>
-                        </li>
-                    </ol>
-                </div>
-            </div>
-        </div>
-    </section>
-    <!-- END CONTENT HEADER -->
-
-    <!-- MAIN CONTENT -->
-    <section class="content">
-        <div class="container-fluid">
-
-            <div class="card">
-                <div class="card-header d-flex justify-content-between">
-                    <h5 class="card-title"><i class="fas fa-sliders-h mr-2"></i>Product</h5>
-                    <div class="ml-auto">
-                        <a data-content="Edit" data-trigger="hover" data-toggle="tooltip" href="{{ route('admin.products.edit', $product->id) }}" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
-                        <form class="d-inline" onsubmit="return submitResult();" method="post" action="{{ route('admin.products.destroy', $product->id) }}">
-                            {{ csrf_field() }}
-                            {{ method_field("DELETE") }}
-                            <button data-content="Delete" data-trigger="hover" data-toggle="tooltip" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
-                        </form>
-                    </div>
-                </div>
-                <div class="card-body">
-                    <div class="row">
-
-                        <div class="col-lg-6">
-                            <div class="row">
-                                <div class="col-lg-4">
-                                    <label>ID</label>
-                                </div>
-                                <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->id}}
-                                       </span>
-                                </div>
-                            </div>
-                        </div>
-
-                        <div class="col-lg-6">
-                            <div class="row">
-                                <div class="col-lg-4">
-                                    <label>Name</label>
-                                </div>
-                                <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->name}}
-                                       </span>
-                                </div>
-                            </div>
-                        </div>
-
-                        <div class="col-lg-6">
-                            <div class="row">
-                                <div class="col-lg-4">
-                                    <label>Price</label>
-                                </div>
-                                <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           <i class="fas fa-coins mr-1"></i>{{$product->price}}
-                                       </span>
-                                </div>
-                            </div>
-                        </div>
-
-
-                        <div class="col-lg-6">
-                            <div class="row">
-                                <div class="col-lg-4">
-                                    <label>Memory</label>
-                                </div>
-                                <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->memory}}
-                                       </span>
-                                </div>
-                            </div>
-                        </div>
-
-                        <div class="col-lg-6">
-                            <div class="row">
-                                <div class="col-lg-4">
-                                    <label>CPU</label>
-                                </div>
-                                <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->cpu}}
-                                       </span>
-                                </div>
-                            </div>
-                        </div>
-
-                        <div class="col-lg-6">
-                            <div class="row">
-                                <div class="col-lg-4">
-                                    <label>Swap</label>
-                                </div>
-                                <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->swap}}
-                                       </span>
-                                </div>
-                            </div>
-                        </div>
-
-                        <div class="col-lg-6">
-                            <div class="row">
-                                <div class="col-lg-4">
-                                    <label>Disk</label>
-                                </div>
-                                <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->disk}}
-                                       </span>
-                                </div>
-                            </div>
-                        </div>
-
-                        <div class="col-lg-6">
-                            <div class="row">
-                                <div class="col-lg-4">
-                                    <label>IO</label>
-                                </div>
-                                <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->io}}
-                                       </span>
-                                </div>
-                            </div>
-                        </div>
-
-                        <div class="col-lg-6">
-                            <div class="row">
-                                <div class="col-lg-4">
-                                    <label>Databases</label>
-                                </div>
-                                <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->databases}}
-                                       </span>
-                                </div>
-                            </div>
-                        </div>
-
-                        <div class="col-lg-6">
-                            <div class="row">
-                                <div class="col-lg-4">
-                                    <label>Allocations</label>
-                                </div>
-                                <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->allocations}}
-                                       </span>
-                                </div>
-                            </div>
-                        </div>
-
-                        <div class="col-lg-6">
-                            <div class="row">
-                                <div class="col-lg-4">
-                                    <label>Created At</label>
-                                </div>
-                                <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->created_at ? $product->created_at->diffForHumans() : ''}}
-                                       </span>
-                                </div>
-                            </div>
-                        </div>
-
-
-                        <div class="col-lg-6">
-                            <div class="row">
-                                <div class="col-lg-4">
-                                    <label>Description</label>
-                                </div>
-                                <div class="col-lg-8">
-                                       <span class="d-inline-block text-truncate">
-                                           {{$product->description}}
-                                       </span>
-                                </div>
-                            </div>
-                        </div>
-
-
-                        <div class="col-lg-6">
-                            <div class="row">
-                                <div class="col-lg-4">
-                                    <label>Updated At</label>
-                                </div>
-                                <div class="col-lg-8">
-                                       <span style="max-width: 250px;" class="d-inline-block text-truncate">
-                                           {{$product->updated_at ? $product->updated_at->diffForHumans() : ''}}
-                                       </span>
-                                </div>
-                            </div>
-                        </div>
-
-                    </div>
-                </div>
-            </div>
-
-            <div class="card">
-                <div class="card-header">
-                    <h5 class="card-title"><i class="fas fa-server mr-2"></i>Servers</h5>
-                </div>
-                <div class="card-body table-responsive">
-
-                    @include('admin.servers.table' , ['filter' => '?product=' . $product->id])
-
-                </div>
-            </div>
-
-
-        </div>
-        <!-- END CUSTOM CONTENT -->
-        </div>
-    </section>
-    <!-- END CONTENT -->
-
-
-
-@endsection

+ 93 - 0
resources/views/admin/vouchers/users.blade.php

@@ -0,0 +1,93 @@
+@extends('layouts.main')
+
+@section('content')
+    <!-- CONTENT HEADER -->
+    <section class="content-header">
+        <div class="container-fluid">
+            <div class="row mb-2">
+                <div class="col-sm-6">
+                    <h1>Vouchers</h1>
+                </div>
+                <div class="col-sm-6">
+                    <ol class="breadcrumb float-sm-right">
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">Dashboard</a></li>
+                        <li class="breadcrumb-item"><a href="{{ route('admin.vouchers.index') }}">Vouchers</a></li>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                href="{{ route('admin.vouchers.users', $voucher->id) }}">Users</a>
+                    </ol>
+                </div>
+            </div>
+        </div>
+    </section>
+    <!-- END CONTENT HEADER -->
+
+    <!-- MAIN CONTENT -->
+    <section class="content">
+        <div class="container-fluid">
+
+            <div class="card">
+
+                <div class="card-header">
+                    <div class="d-flex justify-content-between">
+                        <h5 class="card-title"><i class="fas fa-users mr-2"></i>Users</h5>
+                    </div>
+                </div>
+
+                <div class="card-body table-responsive">
+
+                    <table id="datatable" class="table table-striped">
+                        <thead>
+                            <tr>
+                                <th>ID</th>
+                                <th>Name</th>
+                                <th>Email</th>
+                                <th>{{ CREDITS_DISPLAY_NAME }}</th>
+                                <th>Last Seen</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                        </tbody>
+                    </table>
+
+                </div>
+            </div>
+
+
+        </div>
+        <!-- END CUSTOM CONTENT -->
+
+    </section>
+    <!-- END CONTENT -->
+
+    <script>
+        document.addEventListener("DOMContentLoaded", function() {
+            $('#datatable').DataTable({
+                processing: true,
+                serverSide: true,
+                stateSave: true,
+                ajax: "{{ route('admin.vouchers.usersdatatable', $voucher->id) }}",
+                columns: [{
+                        data: 'id'
+                    }, {
+                        data: 'name'
+                    },
+                    {
+                        data: 'email'
+                    },
+                    {
+                        data: 'credits'
+                    },
+                    {
+                        data: 'last_seen'
+                    },
+                ],
+                fnDrawCallback: function(oSettings) {
+                    $('[data-toggle="popover"]').popover();
+                }
+            });
+        });
+    </script>
+
+
+
+@endsection

+ 4 - 0
resources/views/auth/login.blade.php

@@ -11,6 +11,10 @@
             <div class="card-body">
             <div class="card-body">
                 <p class="login-box-msg">Sign in to start your session</p>
                 <p class="login-box-msg">Sign in to start your session</p>
 
 
+                @if (session('message'))
+                    <div class="alert alert-danger">{{ session('message') }}</div>
+                @endif
+
                 <form action="{{route('login')}}" method="post">
                 <form action="{{route('login')}}" method="post">
                     @csrf
                     @csrf
                     @if(Session::has('error'))
                     @if(Session::has('error'))

+ 18 - 1
resources/views/home.blade.php

@@ -38,7 +38,7 @@
                 <!-- /.col -->
                 <!-- /.col -->
                 <div class="col-12 col-sm-6 col-md-3">
                 <div class="col-12 col-sm-6 col-md-3">
                     <div class="info-box mb-3">
                     <div class="info-box mb-3">
-                        <span class="info-box-icon bg-danger elevation-1"><i class="fas fa-coins"></i></span>
+                        <span class="info-box-icon bg-secondary elevation-1"><i class="fas fa-coins"></i></span>
 
 
                         <div class="info-box-content">
                         <div class="info-box-content">
                             <span class="info-box-text">{{CREDITS_DISPLAY_NAME}}</span>
                             <span class="info-box-text">{{CREDITS_DISPLAY_NAME}}</span>
@@ -65,11 +65,28 @@
                     </div>
                     </div>
                     <!-- /.info-box -->
                     <!-- /.info-box -->
                 </div>
                 </div>
+
+                <!-- /.col -->
+                @if($credits > 0.01 and $useage > 0)
+                     <div class="col-12 col-sm-6 col-md-3">
+                        <div class="info-box mb-3">
+                        <span class="info-box-icon {{$bg}} elevation-1">
+                        <i class="fas fa-hourglass-half"></i></span>
+                            <div class="info-box-content">
+                                <span class="info-box-text">Out of {{CREDITS_DISPLAY_NAME}} in </span>
+                                <span class="info-box-number">{{$boxText}}<sup>{{$unit}}</sup></span>
+                            </div>
+                        </div>
+                    <!-- /.info-box -->
+                @endif
+                </div>
                 <!-- /.col -->
                 <!-- /.col -->
 
 
             </div>
             </div>
 
 
 
 
+
+
             <div class="row">
             <div class="row">
                 <div class="col-md-6">
                 <div class="col-md-6">
                     <div class="card card-default">
                     <div class="card card-default">

+ 8 - 8
resources/views/mail/payment/confirmed.blade.php

@@ -1,16 +1,16 @@
 @component('mail::message')
 @component('mail::message')
 # Thank you for your purchase!
 # Thank you for your purchase!
-Your payment has been confirmed; Your credit balance has been updated.
+Your payment has been confirmed; Your credit balance has been updated.<br>
 
 
 # Details
 # Details
 ___
 ___
-### Payment ID: **{{$payment->id}}**
-### Status:     **{{$payment->status}}**
-### Price:      **{{$payment->formatCurrency()}}**
-### Type:       **{{$payment->type}}**
-### Amount:     **{{$payment->amount}}**
-### Balance:    **{{$payment->user->credits}}**
-### User ID:    **{{$payment->user_id}}**
+### Payment ID: **{{$payment->id}}**<br>
+### Status:     **{{$payment->status}}**<br>
+### Price:      **{{$payment->formatCurrency()}}**<br>
+### Type:       **{{$payment->type}}**<br>
+### Amount:     **{{$payment->amount}}**<br>
+### Balance:    **{{$payment->user->credits}}**<br>
+### User ID:    **{{$payment->user_id}}**<br>
 
 
 <br>
 <br>
 Thanks,<br>
 Thanks,<br>

+ 17 - 0
resources/views/profile/index.blade.php

@@ -213,6 +213,23 @@
                                                             <p>You are verified!</p>
                                                             <p>You are verified!</p>
                                                         </div>
                                                         </div>
                                                     </div>
                                                     </div>
+                                                    <div class="row">
+                                                            <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}}
+                                                                        </p>
+                                                                    </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>
+                                                                </div>
+                                                        </div>
+                                                    </div>
                                                 @endif
                                                 @endif
 
 
                                             </div>
                                             </div>

+ 49 - 39
resources/views/servers/create.blade.php

@@ -10,9 +10,10 @@
                 </div>
                 </div>
                 <div class="col-sm-6">
                 <div class="col-sm-6">
                     <ol class="breadcrumb float-sm-right">
                     <ol class="breadcrumb float-sm-right">
-                        <li class="breadcrumb-item"><a href="{{route('home')}}">Dashboard</a></li>
-                        <li class="breadcrumb-item"><a href="{{route('servers.index')}}">Servers</a>
-                        <li class="breadcrumb-item"><a class="text-muted" href="{{route('servers.create')}}">Create</a>
+                        <li class="breadcrumb-item"><a href="{{ route('home') }}">Dashboard</a></li>
+                        <li class="breadcrumb-item"><a href="{{ route('servers.index') }}">Servers</a>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                href="{{ route('servers.create') }}">Create</a>
                         </li>
                         </li>
                     </ol>
                     </ol>
                 </div>
                 </div>
@@ -32,29 +33,29 @@
                         <h5 class="card-title"><i class="fa fa-server mr-2"></i>Create Server</h5>
                         <h5 class="card-title"><i class="fa fa-server mr-2"></i>Create Server</h5>
                     </div>
                     </div>
                     <div class="card-body">
                     <div class="card-body">
-                        <form method="post" action="{{route('servers.store')}}">
+                        <form method="post" action="{{ route('servers.store') }}">
                             @csrf
                             @csrf
                             <div class="form-group">
                             <div class="form-group">
                                 <label for="name">* Name</label>
                                 <label for="name">* Name</label>
                                 <input id="name" name="name" type="text" required="required"
                                 <input id="name" name="name" type="text" required="required"
-                                       class="form-control @error('name') is-invalid @enderror">
+                                    class="form-control @error('name') is-invalid @enderror">
 
 
                                 @error('name')
                                 @error('name')
-                                <div class="invalid-feedback">
-                                    Please fill out this field.
-                                </div>
+                                    <div class="invalid-feedback">
+                                        Please fill out this field.
+                                    </div>
                                 @enderror
                                 @enderror
 
 
                             </div>
                             </div>
                             <div class="form-group">
                             <div class="form-group">
                                 <label for="description">Description</label>
                                 <label for="description">Description</label>
                                 <input id="description" name="description" type="text"
                                 <input id="description" name="description" type="text"
-                                       class="form-control @error('description') is-invalid @enderror">
+                                    class="form-control @error('description') is-invalid @enderror">
 
 
                                 @error('description')
                                 @error('description')
-                                <div class="invalid-feedback">
-                                    Please fill out this field.
-                                </div>
+                                    <div class="invalid-feedback">
+                                        Please fill out this field.
+                                    </div>
                                 @enderror
                                 @enderror
 
 
                             </div>
                             </div>
@@ -63,13 +64,13 @@
                                 <div>
                                 <div>
 
 
                                     <select id="node_id" name="node_id" required="required"
                                     <select id="node_id" name="node_id" required="required"
-                                            class="custom-select @error('node_id') is-invalid @enderror">
-
-                                        @foreach($locations as $location)
-                                            <optgroup label="{{$location->name}}">
-                                                @foreach($location->nodes as $node)
-                                                    @if(!$node->disabled)
-                                                        <option value="{{$node->id}}">{{$node->name}}</option>
+                                        class="custom-select @error('node_id') is-invalid @enderror">
+                                        <option selected disabled hidden value="">Please Select ...</option>    
+                                        @foreach ($locations as $location)
+                                            <optgroup label="{{ $location->name }}">
+                                                @foreach ($location->nodes as $node)
+                                                    @if (!$node->disabled)
+                                                        <option value="{{ $node->id }}">{{ $node->name }}</option>
                                                     @endif
                                                     @endif
                                                 @endforeach
                                                 @endforeach
                                             </optgroup>
                                             </optgroup>
@@ -79,20 +80,21 @@
                                 </div>
                                 </div>
 
 
                                 @error('node_id')
                                 @error('node_id')
-                                <div class="invalid-feedback">
-                                    Please fill out this field.
-                                </div>
+                                    <div class="invalid-feedback">
+                                        Please fill out this field.
+                                    </div>
                                 @enderror
                                 @enderror
                             </div>
                             </div>
                             <div class="form-group">
                             <div class="form-group">
                                 <label for="egg_id">* Server configuration</label>
                                 <label for="egg_id">* Server configuration</label>
                                 <div>
                                 <div>
                                     <select id="egg_id" name="egg_id" required="required"
                                     <select id="egg_id" name="egg_id" required="required"
-                                            class="custom-select @error('egg_id') is-invalid @enderror">
-                                        @foreach($nests as $nest)
-                                            <optgroup label="{{$nest->name}}">
-                                                @foreach($nest->eggs as $egg)
-                                                    <option value="{{$egg->id}}">{{$egg->name}}</option>
+                                        class="custom-select @error('egg_id') is-invalid @enderror">
+                                       <option selected disabled hidden value="">Please Select ...</option>    
+                                        @foreach ($nests as $nest)
+                                            <optgroup label="{{ $nest->name }}">
+                                                @foreach ($nest->eggs as $egg)
+                                                    <option value="{{ $egg->id }}">{{ $egg->name }}</option>
                                                 @endforeach
                                                 @endforeach
                                             </optgroup>
                                             </optgroup>
                                         @endforeach
                                         @endforeach
@@ -100,32 +102,40 @@
                                 </div>
                                 </div>
 
 
                                 @error('egg_id')
                                 @error('egg_id')
-                                <div class="invalid-feedback">
-                                    Please fill out this field.
-                                </div>
+                                    <div class="invalid-feedback">
+                                        Please fill out this field.
+                                    </div>
                                 @enderror
                                 @enderror
                             </div>
                             </div>
                             <div class="form-group">
                             <div class="form-group">
                                 <label for="product_id">* Resource Configuration</label>
                                 <label for="product_id">* Resource Configuration</label>
                                 <div>
                                 <div>
                                     <select id="product_id" name="product_id" required="required"
                                     <select id="product_id" name="product_id" required="required"
-                                            class="custom-select @error('product_id') is-invalid @enderror">
-                                        @foreach($products as $product)
-                                            <option value="{{$product->id}}">{{$product->name}}
-                                                ({{$product->description}})
-                                            </option>
+                                        class="custom-select @error('product_id') is-invalid @enderror">
+                                        <option selected disabled hidden value="">Please Select...</option>    
+                                        @foreach ($products as $product)
+                                            <option value="{{ $product->id }}" @if ($product->minimum_credits == -1 && Auth::user()->credits >= $minimum_credits)
+                                            @elseif ($product->minimum_credits != -1 && Auth::user()->credits >=
+                                                $product->minimum_credits)
+                                            @else
+                                                disabled
+                                        @endif
+                                        >{{ $product->name }}
+                                        ({{ $product->description }})
+                                        </option>
                                         @endforeach
                                         @endforeach
                                     </select>
                                     </select>
                                 </div>
                                 </div>
 
 
                                 @error('product_id')
                                 @error('product_id')
-                                <div class="invalid-feedback">
-                                    Please fill out this field.
-                                </div>
+                                    <div class="invalid-feedback">
+                                        Please fill out this field.
+                                    </div>
                                 @enderror
                                 @enderror
                             </div>
                             </div>
                             <div class="form-group text-right">
                             <div class="form-group text-right">
-                                <button type="submit" class="btn btn-primary mt-3">Submit</button>
+                                <input type="submit" class="btn btn-primary mt-3" value="Submit"
+                                    onclick="this.disabled=true;this.value='Creating, please wait...';this.form.submit();">
                             </div>
                             </div>
                         </form>
                         </form>
 
 

+ 8 - 0
resources/views/servers/index.blade.php

@@ -83,6 +83,14 @@
                                         <td>Backups</td>
                                         <td>Backups</td>
                                         <td>{{$server->product->backups}}</td>
                                         <td>{{$server->product->backups}}</td>
                                     </tr>
                                     </tr>
+                                    <tr>
+                                        <td>Price per Hour</td>
+                                        <td>{{number_format($server->product->getHourlyPrice(),2,".", "")}} {{CREDITS_DISPLAY_NAME}}</td>
+                                    </tr>
+                                    <tr>
+                                        <td>Price per Month</td>
+                                        <td>{{$server->product->getHourlyPrice()*24*30}} {{CREDITS_DISPLAY_NAME}}</td>
+                                    </tr>
                                 </table>
                                 </table>
                             </div>
                             </div>
 
 

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

@@ -42,7 +42,7 @@
                         <!-- info row -->
                         <!-- info row -->
                         <div class="row invoice-info">
                         <div class="row invoice-info">
                             <div class="col-sm-4 invoice-col">
                             <div class="col-sm-4 invoice-col">
-                                From
+                                To
                                 <address>
                                 <address>
                                     <strong>{{config('app.name' , 'Laravel')}}</strong><br>
                                     <strong>{{config('app.name' , 'Laravel')}}</strong><br>
                                     Email: {{env('PAYPAL_EMAIL' , env('MAIL_FROM_NAME'))}}
                                     Email: {{env('PAYPAL_EMAIL' , env('MAIL_FROM_NAME'))}}
@@ -50,7 +50,7 @@
                             </div>
                             </div>
                             <!-- /.col -->
                             <!-- /.col -->
                             <div class="col-sm-4 invoice-col">
                             <div class="col-sm-4 invoice-col">
-                                To
+                                From
                                 <address>
                                 <address>
                                     <strong>{{Auth::user()->name}}</strong><br>
                                     <strong>{{Auth::user()->name}}</strong><br>
                                     Email: {{Auth::user()->email}}
                                     Email: {{Auth::user()->email}}

+ 1 - 1
routes/api.php

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

+ 4 - 1
routes/web.php

@@ -40,7 +40,7 @@ Route::middleware('guest')->get('/', function () {
 
 
 Auth::routes(['verify' => true]);
 Auth::routes(['verify' => true]);
 
 
-Route::middleware('auth')->group(function () {
+Route::middleware(['auth', 'checkSuspended'])->group(function () {
     #resend verification email
     #resend verification email
     Route::get('/email/verification-notification', function (Request $request) {
     Route::get('/email/verification-notification', function (Request $request) {
         $request->user()->sendEmailVerificationNotification();
         $request->user()->sendEmailVerificationNotification();
@@ -79,6 +79,7 @@ Route::middleware('auth')->group(function () {
         Route::get('users/datatable', [UserController::class, 'datatable'])->name('users.datatable');
         Route::get('users/datatable', [UserController::class, 'datatable'])->name('users.datatable');
         Route::get('users/notifications', [UserController::class, 'notifications'])->name('users.notifications');
         Route::get('users/notifications', [UserController::class, 'notifications'])->name('users.notifications');
         Route::post('users/notifications', [UserController::class, 'notify'])->name('users.notifications');
         Route::post('users/notifications', [UserController::class, 'notify'])->name('users.notifications');
+        Route::post('users/togglesuspend/{user}', [UserController::class, 'toggleSuspended'])->name('users.togglesuspend');
         Route::resource('users', UserController::class);
         Route::resource('users', UserController::class);
 
 
         Route::get('servers/datatable', [AdminServerController::class, 'datatable'])->name('servers.datatable');
         Route::get('servers/datatable', [AdminServerController::class, 'datatable'])->name('servers.datatable');
@@ -118,6 +119,8 @@ Route::middleware('auth')->group(function () {
         Route::resource('usefullinks', UsefulLinkController::class);
         Route::resource('usefullinks', UsefulLinkController::class);
 
 
         Route::get('vouchers/datatable', [VoucherController::class, 'datatable'])->name('vouchers.datatable');
         Route::get('vouchers/datatable', [VoucherController::class, 'datatable'])->name('vouchers.datatable');
+        Route::get('vouchers/{voucher}/usersdatatable', [VoucherController::class, 'usersdatatable'])->name('vouchers.usersdatatable');
+        Route::get('vouchers/{voucher}/users', [VoucherController::class, 'users'])->name('vouchers.users');
         Route::resource('vouchers', VoucherController::class);
         Route::resource('vouchers', VoucherController::class);
 
 
         Route::get('api/datatable', [ApplicationApiController::class, 'datatable'])->name('api.datatable');
         Route::get('api/datatable', [ApplicationApiController::class, 'datatable'])->name('api.datatable');