Jelajahi Sumber

Merge pull request #520 from ControlPanel-gg/dev---upgradesystem

Dev   upgradesystem
Dennis 2 tahun lalu
induk
melakukan
1f9301ef0e

+ 19 - 0
app/Classes/Pterodactyl.php

@@ -6,6 +6,7 @@ use App\Models\Egg;
 use App\Models\Nest;
 use App\Models\Node;
 use App\Models\Server;
+use App\Models\Product;
 use Exception;
 use Illuminate\Http\Client\PendingRequest;
 use Illuminate\Http\Client\Response;
@@ -298,4 +299,22 @@ class Pterodactyl
         if ($response->failed()) throw self::getException("Failed to get server attributes from pterodactyl - ", $response->status());
         return $response->json()['attributes'];
     }
+
+    public static function updateServer(Server $server, Product $product)
+    {
+        return self::client()->patch("/application/servers/{$server->pterodactyl_id}/build", [
+            "allocation"      => $server->allocation,
+            "memory"          => $product->memory,
+            "swap"            => $product->swap,
+            "disk"            => $product->disk,
+            "io"              => $product->io,
+            "cpu"             => $product->cpu,
+            "threads"         => null,
+            "feature_limits"  => [
+                "databases"   => $product->databases,
+                "backups"     => $product->backups,
+                "allocations" => $product->allocations,
+            ]
+        ]);
+    }
 }

+ 61 - 0
app/Http/Controllers/ServerController.php

@@ -235,4 +235,65 @@ class ServerController extends Controller
             return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to remove a resource "') . $e->getMessage() . '"');
         }
     }
+
+    /** Show Server Settings */
+    public function show(Server $server)
+    {
+        $serverAttributes = Pterodactyl::getServerAttributes($server->pterodactyl_id);
+        $serverRelationships = $serverAttributes['relationships'];
+        $serverLocationAttributes = $serverRelationships['location']['attributes'];
+
+        //Set server infos
+        $server->location = $serverLocationAttributes['long'] ?
+            $serverLocationAttributes['long'] :
+            $serverLocationAttributes['short'];
+
+        $server->node = $serverRelationships['node']['attributes']['name'];
+        $server->name = $serverAttributes['name'];
+        $server->egg = $serverRelationships['egg']['attributes']['name'];
+        $products = Product::orderBy("created_at")->get();
+
+        // Set the each product eggs array to just contain the eggs name
+        foreach ($products as $product) {
+            $product->eggs = $product->eggs->pluck('name')->toArray();
+        }
+
+        return view('servers.settings')->with([
+            'server' => $server,
+            'products' => $products
+        ]);
+    }
+
+    public function upgrade(Server $server, Request $request)
+    {
+        if(!isset($request->product_upgrade))
+        {
+            return redirect()->route('servers.show', ['server' => $server->id])->with('error', __('this product is the only one'));
+        }
+        $user = Auth::user();
+        $oldProduct = Product::where('id', $server->product->id)->first();
+        $newProduct = Product::where('id', $request->product_upgrade)->first();
+        $serverAttributes = Pterodactyl::getServerAttributes($server->pterodactyl_id);
+        $priceupgrade = $newProduct->getHourlyPrice();
+
+        if ($priceupgrade < $oldProduct->getHourlyPrice()) {
+        $priceupgrade = 0;
+        }
+        if ($user->credits >= $priceupgrade)
+        {
+
+            $server->product_id = $request->product_upgrade;
+            $server->update();
+            $server->allocation = $serverAttributes['allocation'];
+            $response = Pterodactyl::updateServer($server, $newProduct);
+            if ($response->failed()) return $this->serverCreationFailed($response, $server);
+            //update user balance
+            $user->decrement('credits', $priceupgrade);
+            return redirect()->route('servers.show', ['server' => $server->id])->with('success', __('Server Successfully Upgraded'));
+        }
+        else
+        {
+            return redirect()->route('servers.show', ['server' => $server->id])->with('error', __('Not Enough Balance for Upgrade'));
+        }
+    }
 }

+ 4 - 43
resources/views/servers/index.blade.php

@@ -155,11 +155,10 @@
                                 <i class="fas fa-tools mr-2"></i>
                                 <span>{{ __('Manage') }}</span>
                             </a>
-                            <button onclick="confirmSubmit('{{ $server->id }}', handleServerDelete);" target="__blank"
-                                class="btn btn-danger mx-3 w-100 align-items-center justify-content-center d-flex">
-                                <i class="fas fa-trash mr-2"></i>
-                                <span>{{ __('Delete') }}</span>
-                            </button>
+                            <a href="{{ route('servers.show', ['server' => $server->id])}}" class="btn btn-warning mx-3 w-100 align-items-center justify-content-center d-flex">
+                                <i class="fas fa-cog mr-2"></i>
+                                <span>{{ __('Settings') }}</span>
+                            </a>
                         </div>
                     </div>
                 @endforeach
@@ -168,42 +167,4 @@
         </div>
     </section>
     <!-- END CONTENT -->
-
-    <script>
-        const confirmSubmit = (serverId, handleServerDelete) => {
-            // Confirm delete submit with sweetalert
-            Swal.fire({
-                title: "{{ __('Are you sure?') }}",
-                text: "{{ __('This is an irreversible action, all files of this server will be removed.') }}",
-                icon: 'warning',
-                confirmButtonColor: '#d9534f',
-                showCancelButton: true,
-                confirmButtonText: "{{ __('Yes, delete it!') }}",
-                cancelButtonText: "{{ __('No, cancel!') }}",
-                reverseButtons: true
-            }).then((result) => {
-                if (result.value) {
-                    handleServerDelete(serverId);
-                    return
-                }
-                Swal.fire("{{ __('Canceled ...') }}", `{{ __('Deletion has been canceled.') }}`, 'info');
-            });
-        }
-
-        const handleServerDelete = (serverId) => {
-            // Delete server
-            fetch("{{ route('servers.destroy', '') }}" + '/' + serverId, {
-                method: 'DELETE',
-                headers: {
-                    'X-CSRF-TOKEN': '{{ csrf_token() }}'
-                }
-            }).then(() => {
-                window.location.reload();
-            });
-        }
-
-        document.addEventListener('DOMContentLoaded', () => {
-            $('[data-toggle="popover"]').popover();
-        });
-    </script>
 @endsection

+ 308 - 0
resources/views/servers/settings.blade.php

@@ -0,0 +1,308 @@
+@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>{{__('Server Settings')}}</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('servers.index') }}">{{__('Server')}}</a></li>
+                        <li class="breadcrumb-item"><a class="text-muted"
+                                href="{{ route('servers.show', $server->id) }}">{{__('Settings')}}</a>
+                        </li>
+                    </ol>
+                </div>
+            </div>
+        </div>
+
+    </section>
+    <!-- END CONTENT HEADER --> 
+
+    <!-- MAIN CONTENT -->
+    <section class="content">
+        <div class="container-fluid">
+            <div class="row pt-3">
+                <div class="col-xl-3 col-sm-6 mb-xl-0 mb-4">
+                  <div class="card">
+                    <div class="card-body p-3">
+                      <div class="row">
+                        <div class="col-8">
+                          <div class="numbers">
+                            <p class="text-sm mb-0 text-uppercase font-weight-bold">SERVER NAME</p>
+                            <h5 class="font-weight-bolder" id="domain_text">
+                              <span class="text-success text-sm font-weight-bolder">{{ $server->name }}</span>
+                            </h5>
+                          </div>
+                        </div>
+                        <div class="col-4 text-end">
+                          <div class="icon icon-shape bg-gradient-primary shadow-primary text-center rounded-circle">
+                            <i class='bx bx-fingerprint' style="color: white;"></i>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <div class="col-xl-3 col-sm-6 mb-xl-0 mb-4">
+                  <div class="card">
+                    <div class="card-body p-3">
+                      <div class="row">
+                        <div class="col-8">
+                          <div class="numbers">
+                            <p class="text-sm mb-0 text-uppercase font-weight-bold">CPU</p>
+                            <h5 class="font-weight-bolder">
+                              <span class="text-success text-sm font-weight-bolder">@if($server->product->cpu == 0)Unlimited @else {{$server->product->cpu}} % @endif</span>
+                            </h5>
+                          </div>
+                        </div>
+                        <div class="col-4 text-end">
+                          <div class="icon icon-shape bg-gradient-danger shadow-danger text-center rounded-circle">
+                            <i class='bx bxs-chip' style="color: white;"></i>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <div class="col-xl-3 col-sm-6 mb-xl-0 mb-4">
+                  <div class="card">
+                    <div class="card-body p-3">
+                      <div class="row">
+                        <div class="col-8">
+                          <div class="numbers">
+                            <p class="text-sm mb-0 text-uppercase font-weight-bold">Memory</p>
+                            <h5 class="font-weight-bolder">
+                              <span class="text-success text-sm font-weight-bolder">@if($server->product->memory == 0)Unlimited @else {{$server->product->memory}}MB @endif</span>
+                            </h5>
+                          </div>
+                        </div>
+                        <div class="col-4 text-end">
+                          <div class="icon icon-shape bg-gradient-success shadow-success text-center rounded-circle">
+                            <i class='bx bxs-memory-card' style="color: white;"></i>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <div class="col-xl-3 col-sm-6">
+                  <div class="card">
+                    <div class="card-body p-3">
+                      <div class="row">
+                        <div class="col-8">
+                          <div class="numbers">
+                            <p class="text-sm mb-0 text-uppercase font-weight-bold">STORAGE</p>
+                            <h5 class="font-weight-bolder">
+                              <span class="text-success text-sm font-weight-bolder">@if($server->product->disk == 0)Unlimited @else {{$server->product->disk}}MB @endif</span>
+                            </h5>
+                          </div>
+                        </div>
+                        <div class="col-4 text-end">
+                          <div class="icon icon-shape bg-gradient-warning shadow-warning text-center rounded-circle">
+                            <i class='bx bxs-hdd' style="color: white;"></i>                
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+            </div>
+            <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>{{__('Server Information')}}</h5>
+                </div>
+                <div class="card-body">
+                    <div class="row">
+
+                        <div class="col-lg-6">
+                            <div class="row">
+                                <div class="col-lg-4">
+                                    <label>{{__('Server ID')}}</label>
+                                </div>
+                                <div class="col-lg-8">
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $server->id }}
+                                    </span>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-6">
+                            <div class="row">
+                                <div class="col-lg-4">
+                                    <label>{{__('Pterodactyl ID')}}</label>
+                                </div>
+                                <div class="col-lg-8">
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $server->identifier }}
+                                    </span>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-6">
+                            <div class="row">
+                                <div class="col-lg-4">
+                                    <label>{{__('Hourly Price')}}</label>
+                                </div>
+                                <div class="col-lg-8">
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                      {{ number_format($server->product->getHourlyPrice(), 2, '.', '') }}
+                                    </span>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-6">
+                            <div class="row">
+                                <div class="col-lg-4">
+                                    <label>{{__('Monthly Price')}}</label>
+                                </div>
+                                <div class="col-lg-8">
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                      {{ $server->product->getHourlyPrice() * 24 * 30 }}
+                                    </span>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-6">
+                            <div class="row">
+                                <div class="col-lg-4">
+                                    <label>{{__('Location')}}</label>
+                                </div>
+                                <div class="col-lg-8">
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $server->location }}
+                                    </span>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-6">
+                            <div class="row">
+                                <div class="col-lg-4">
+                                    <label>{{__('Node')}}</label>
+                                </div>
+                                <div class="col-lg-8">
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $server->node }}
+                                    </span>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-6">
+                            <div class="row">
+                                <div class="col-lg-4">
+                                    <label>{{__('Backups')}}</label>
+                                </div>
+                                <div class="col-lg-8">
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $server->product->backups }}
+                                    </span>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-lg-6">
+                            <div class="row">
+                                <div class="col-lg-4">
+                                    <label>{{__('MySQL Database')}}</label>
+                                </div>
+                                <div class="col-lg-8">
+                                    <span style="max-width: 250px;" class="d-inline-block text-truncate">
+                                        {{ $server->product->databases }}
+                                    </span>
+                                </div>
+                            </div>
+                        </div>
+
+                    </div>
+                </div>
+                <div class="card-footer">
+                    <div class="col-md-12 text-center">
+                        <!-- Upgrade Button trigger modal -->
+                        <button type="button" data-toggle="modal" data-target="#UpgradeModal{{ $server->id }}" target="__blank"
+                            class="btn btn-info btn-md">
+                            <i class="fas fa-upload mr-2"></i>
+                            <span>{{ __('Upgrade') }}</span>
+                        </button>
+                        <!-- Upgrade Modal -->
+                        <div style="width: 100%; margin-block-start: 100px;" class="modal fade" id="UpgradeModal{{ $server->id }}" tabindex="-1">
+                            <div class="modal-dialog">
+                                <div class="modal-content">
+                                    <div class="modal-header card-header">
+                                        <h5 class="modal-title">UPGRADE SERVER</h5>
+                                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                                            <span aria-hidden="true">&times;</span>
+                                        </button>
+                                    </div>
+                                    <div class="modal-body card-body">
+                                        <strong>FOR DOWNGRADE PLEASE CHOOSE A PLAN BELOW YOUR PLAN</strong>
+                                        <br>
+                                        <br>
+                                        <strong>YOUR PRODUCT : </strong> {{ $server->product->name }}
+                                        <br>
+                                        <br>
+                                    <form action="{{ route('servers.upgrade', ['server' => $server->id]) }}" method="POST">
+                                      @csrf
+                                          <select name="product_upgrade" id="product_upgrade" class="form-input2 form-control">
+                                            <option value="">Select the product</option>
+                                              @foreach($products as $product)
+                                                  @if(in_array($server->egg, $product->eggs) && $product->id != $server->product->id)
+                                                    <option value="{{ $product->id }}">{{ $product->name }} [ {{ CREDITS_DISPLAY_NAME }} {{ $product->price }} ]</option>
+                                                  @endif
+                                              @endforeach
+                                          </select> 
+                                          <br> Once the Upgrade button is pressed, we will automatically deduct the amount for the first hour according to the new product from your credits. <br>
+                                    </div>
+                                    <div class="modal-footer card-body">
+                                        <button type="submit" class="btn btn-primary" style="width: 100%"><strong>Upgrade</strong></button>
+                                    </div>
+                                    </form>
+                                </div>
+                            </div>
+                        </div>
+                        <!-- Delete Button trigger modal -->
+                        <button type="button" data-toggle="modal" data-target="#DeleteModal" target="__blank"
+                            class="btn btn-danger btn-md">
+                            <i class="fas fa-trash mr-2"></i>
+                            <span>{{ __('Delete') }}</span>
+                        </button>
+                        <!-- Delete Modal -->
+                        <div class="modal fade" id="DeleteModal" tabindex="-1" role="dialog" aria-labelledby="DeleteModalLabel" aria-hidden="true">
+                          <div class="modal-dialog" role="document">
+                            <div class="modal-content">
+                              <div class="modal-header">
+                                <h5 class="modal-title" id="DeleteModalLabel">Delete Server</h5>
+                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                                  <span aria-hidden="true">&times;</span>
+                                </button>
+                              </div>
+                              <div class="modal-body">
+                                This is an irreversible action, all files of this server will be removed.!!!
+                              </div>
+                              <div class="modal-footer">
+                                <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
+                                <form class="d-inline" method="post" action="{{ route('servers.destroy', ['server' => $server->id]) }}">
+                                  @csrf
+                                  @method('DELETE')
+                                  <button data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-danger mr-1">Delete</button>
+                                </form>
+                              </div>
+                            </div>
+                          </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+
+
+        </div>
+        <!-- END CUSTOM CONTENT -->
+        </div>
+    </section>
+    <!-- END CONTENT -->
+
+
+@endsection

+ 1 - 0
routes/web.php

@@ -63,6 +63,7 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () {
     Route::get('notifications/readAll',[NotificationController::class,'readAll'])->name('notifications.readAll');
     Route::resource('notifications', NotificationController::class);
     Route::resource('servers', ServerController::class);
+    Route::post('servers/{server}/upgrade', [ServerController::class,'upgrade'])->name('servers.upgrade');
     Route::resource('profile', ProfileController::class);
     Route::resource('store', StoreController::class);