Merge pull request #211 from j122j/minimum-credits

Add minimal credits per product
This commit is contained in:
LogischJo 2021-10-06 21:55:11 +02:00 committed by GitHub
commit e53a055bc2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 386 additions and 279 deletions

View file

@ -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.'"> <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> <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() : '';

View file

@ -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 (Configuration::getValueByKey('SERVER_CREATE_CHARGE_FIRST_HOUR', 'true') == 'true') {
if (Auth::user()->credits >= $server->product->getHourlyPrice()){ 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 // minimum credits
if (Auth::user()->credits <= Configuration::getValueByKey('MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)) { if (FacadesRequest::has("product_id")) {
return redirect()->route('servers.index')->with('error', "You do not have the required amount of ".CREDITS_DISPLAY_NAME." to create a new server!"); $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();

View file

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

View file

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

View file

@ -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('home') }}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{{route('admin.products.index')}}">Products</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 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"> <input type="checkbox" name="disabled"
<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> 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" <input value="{{ old('name') }}" id="name" name="name" type="text"
class="form-control @error('name') is-invalid @enderror" class="form-control @error('name') is-invalid @enderror"
required="required"> required="required">
@error('name') @error('name')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </div>
@enderror @enderror
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="price">Price in {{CREDITS_DISPLAY_NAME}}</label> <label for="price">Price in {{ CREDITS_DISPLAY_NAME }}</label>
<input value="{{old('price')}}" id="price" name="price" <input value="{{ old('price') }}" id="price" name="price" type="number"
type="number" class="form-control @error('price') is-invalid @enderror"
class="form-control @error('price') is-invalid @enderror" required="required">
required="required">
@error('price') @error('price')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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" <input value="{{ old('memory') }}" id="memory" name="memory" type="number"
type="number" class="form-control @error('memory') is-invalid @enderror"
class="form-control @error('memory') is-invalid @enderror" required="required">
required="required">
@error('memory') @error('memory')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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" <input value="{{ old('cpu') }}" id="cpu" name="cpu" type="number"
type="number" class="form-control @error('cpu') is-invalid @enderror" required="required">
class="form-control @error('cpu') is-invalid @enderror"
required="required">
@error('cpu') @error('cpu')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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" <input value="{{ old('swap') }}" id="swap" name="swap" type="number"
type="number" class="form-control @error('swap') is-invalid @enderror"
class="form-control @error('swap') is-invalid @enderror" required="required">
required="required">
@error('swap') @error('swap')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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> <label for="description">Description <i data-toggle="popover"
<textarea id="description" name="description" data-trigger="hover" data-content="This is what the users sees"
type="text" class="fas fa-info-circle"></i></label>
class="form-control @error('description') is-invalid @enderror" <textarea id="description" name="description" type="text"
required="required">{{old('description')}}</textarea> class="form-control @error('description') is-invalid @enderror"
required="required">{{ old('description') }}</textarea>
@error('description') @error('description')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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" <input value="{{ old('disk') ?? 1000 }}" id="disk" name="disk" type="number"
type="number" class="form-control @error('disk') is-invalid @enderror"
class="form-control @error('disk') is-invalid @enderror" required="required">
required="required">
@error('disk') @error('disk')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </div>
@enderror @enderror
</div> </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
</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" <input value="{{ old('io') ?? 500 }}" id="io" name="io" type="number"
type="number" class="form-control @error('io') is-invalid @enderror" required="required">
class="form-control @error('io') is-invalid @enderror"
required="required">
@error('io') @error('io')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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" <input value="{{ old('databases') ?? 1 }}" id="databases" name="databases"
name="databases" type="number" class="form-control @error('databases') is-invalid @enderror"
type="number" required="required">
class="form-control @error('databases') is-invalid @enderror"
required="required">
@error('databases') @error('databases')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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" <input value="{{ old('backups') ?? 1 }}" id="backups" name="backups"
name="backups" type="number" class="form-control @error('backups') is-invalid @enderror"
type="number" required="required">
class="form-control @error('backups') is-invalid @enderror"
required="required">
@error('backups') @error('backups')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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}}" <input value="{{ old('allocations') ?? 0 }}" id="allocations"
id="allocations" name="allocations" name="allocations" type="number"
type="number" class="form-control @error('allocations') is-invalid @enderror"
class="form-control @error('allocations') is-invalid @enderror" required="required">
required="required">
@error('allocations') @error('allocations')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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

View file

@ -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('home') }}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{{route('admin.products.index')}}">Products</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 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> <h4>Editing the resource options will not automatically update the servers on pterodactyl's
<p class="text-muted">Automatically updating resource options on pterodactyl side is on my todo list :)</p> 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"> <input type="checkbox" @if ($product->disabled) checked @endif name="disabled"
<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> 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" <input value="{{ $product->name }}" id="name" name="name" type="text"
class="form-control @error('name') is-invalid @enderror" class="form-control @error('name') is-invalid @enderror"
required="required"> required="required">
@error('name') @error('name')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </div>
@enderror @enderror
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="price">Price in {{CREDITS_DISPLAY_NAME}}</label> <label for="price">Price in {{ CREDITS_DISPLAY_NAME }}</label>
<input value="{{$product->price}}" id="price" name="price" <input value="{{ $product->price }}" id="price" name="price" type="number"
type="number" class="form-control @error('price') is-invalid @enderror"
class="form-control @error('price') is-invalid @enderror" required="required">
required="required">
@error('price') @error('price')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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" <input value="{{ $product->memory }}" id="memory" name="memory" type="number"
type="number" class="form-control @error('memory') is-invalid @enderror"
class="form-control @error('memory') is-invalid @enderror" required="required">
required="required">
@error('memory') @error('memory')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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" <input value="{{ $product->cpu }}" id="cpu" name="cpu" type="number"
type="number" class="form-control @error('cpu') is-invalid @enderror" required="required">
class="form-control @error('cpu') is-invalid @enderror"
required="required">
@error('cpu') @error('cpu')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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" <input value="{{ $product->swap }}" id="swap" name="swap" type="number"
type="number" class="form-control @error('swap') is-invalid @enderror"
class="form-control @error('swap') is-invalid @enderror" required="required">
required="required">
@error('swap') @error('swap')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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> <label for="description">Description <i data-toggle="popover"
<textarea id="description" name="description" data-trigger="hover" data-content="This is what the users sees"
type="text" class="fas fa-info-circle"></i></label>
class="form-control @error('description') is-invalid @enderror" <textarea id="description" name="description" type="text"
required="required">{{$product->description}}</textarea> class="form-control @error('description') is-invalid @enderror"
required="required">{{ $product->description }}</textarea>
@error('description') @error('description')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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" <input value="{{ $product->disk }}" id="disk" name="disk" type="number"
type="number" class="form-control @error('disk') is-invalid @enderror"
class="form-control @error('disk') is-invalid @enderror" required="required">
required="required">
@error('disk') @error('disk')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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" <input value="{{ $product->io }}" id="io" name="io" type="number"
type="number" class="form-control @error('io') is-invalid @enderror" required="required">
class="form-control @error('io') is-invalid @enderror"
required="required">
@error('io') @error('io')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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" <input value="{{ $product->databases }}" id="databases" name="databases"
name="databases" type="number" class="form-control @error('databases') is-invalid @enderror"
type="number" required="required">
class="form-control @error('databases') is-invalid @enderror"
required="required">
@error('databases') @error('databases')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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" <input value="{{ $product->backups }}" id="backups" name="backups"
name="backups" type="number" class="form-control @error('backups') is-invalid @enderror"
type="number" required="required">
class="form-control @error('backups') is-invalid @enderror"
required="required">
@error('backups') @error('backups')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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}}" <input value="{{ $product->allocations }}" id="allocations"
id="allocations" name="allocations" name="allocations" type="number"
type="number" class="form-control @error('allocations') is-invalid @enderror"
class="form-control @error('allocations') is-invalid @enderror" required="required">
required="required">
@error('allocations') @error('allocations')
<div class="invalid-feedback"> <div class="invalid-feedback">
{{$message}} {{ $message }}
</div> </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

View file

@ -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('home') }}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{{route('admin.users.index')}}">Products</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> <a data-content="Edit" data-trigger="hover" data-toggle="tooltip"
<form class="d-inline" onsubmit="return submitResult();" method="post" action="{{ route('admin.products.destroy', $product->id) }}"> 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") }} {{ 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> <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"> <span style="max-width: 250px;" class="d-inline-block text-truncate">
{{$product->id}} {{ $product->id }}
</span> </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"> <span style="max-width: 250px;" class="d-inline-block text-truncate">
{{$product->name}} {{ $product->name }}
</span> </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"> <span style="max-width: 250px;" class="d-inline-block text-truncate">
<i class="fas fa-coins mr-1"></i>{{$product->price}} <i class="fas fa-coins mr-1"></i>{{ $product->price }}
</span> </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"> <span style="max-width: 250px;" class="d-inline-block text-truncate">
{{$product->memory}} {{ $product->memory }}
</span> </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"> <span style="max-width: 250px;" class="d-inline-block text-truncate">
{{$product->cpu}} {{ $product->cpu }}
</span> </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"> <span style="max-width: 250px;" class="d-inline-block text-truncate">
{{$product->swap}} {{ $product->swap }}
</span> </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"> <span style="max-width: 250px;" class="d-inline-block text-truncate">
{{$product->disk}} {{ $product->disk }}
</span> </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"> <span style="max-width: 250px;" class="d-inline-block text-truncate">
{{$product->io}} {{ $product->io }}
</span> </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"> <span style="max-width: 250px;" class="d-inline-block text-truncate">
{{$product->databases}} {{ $product->databases }}
</span> </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"> <span style="max-width: 250px;" class="d-inline-block text-truncate">
{{$product->allocations}} {{ $product->allocations }}
</span> </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"> <span style="max-width: 250px;" class="d-inline-block text-truncate">
{{$product->created_at ? $product->created_at->diffForHumans() : ''}} {{ $product->created_at ? $product->created_at->diffForHumans() : '' }}
</span> </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"> <span class="d-inline-block text-truncate">
{{$product->description}} {{ $product->description }}
</span> </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"> <span style="max-width: 250px;" class="d-inline-block text-truncate">
{{$product->updated_at ? $product->updated_at->diffForHumans() : ''}} {{ $product->updated_at ? $product->updated_at->diffForHumans() : '' }}
</span> </span>
</div> </div>
</div> </div>
</div> </div>

View file

@ -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('home') }}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{{route('servers.index')}}">Servers</a> <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 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"> <div class="invalid-feedback">
Please fill out this field. Please fill out this field.
</div> </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"> <div class="invalid-feedback">
Please fill out this field. Please fill out this field.
</div> </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"> class="custom-select @error('node_id') is-invalid @enderror">
@foreach($locations as $location) @foreach ($locations as $location)
<optgroup label="{{$location->name}}"> <optgroup label="{{ $location->name }}">
@foreach($location->nodes as $node) @foreach ($location->nodes as $node)
@if(!$node->disabled) @if (!$node->disabled)
<option value="{{$node->id}}">{{$node->name}}</option> <option value="{{ $node->id }}">{{ $node->name }}</option>
@endif @endif
@endforeach @endforeach
</optgroup> </optgroup>
@ -79,20 +80,20 @@
</div> </div>
@error('node_id') @error('node_id')
<div class="invalid-feedback"> <div class="invalid-feedback">
Please fill out this field. Please fill out this field.
</div> </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"> class="custom-select @error('egg_id') is-invalid @enderror">
@foreach($nests as $nest) @foreach ($nests as $nest)
<optgroup label="{{$nest->name}}"> <optgroup label="{{ $nest->name }}">
@foreach($nest->eggs as $egg) @foreach ($nest->eggs as $egg)
<option value="{{$egg->id}}">{{$egg->name}}</option> <option value="{{ $egg->id }}">{{ $egg->name }}</option>
@endforeach @endforeach
</optgroup> </optgroup>
@endforeach @endforeach
@ -100,32 +101,39 @@
</div> </div>
@error('egg_id') @error('egg_id')
<div class="invalid-feedback"> <div class="invalid-feedback">
Please fill out this field. Please fill out this field.
</div> </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"> class="custom-select @error('product_id') is-invalid @enderror">
@foreach($products as $product) @foreach ($products as $product)
<option value="{{$product->id}}">{{$product->name}} <option value="{{ $product->id }}" @if ($product->minimum_credits == -1 && Auth::user()->credits >= $minimum_credits)
({{$product->description}}) @elseif ($product->minimum_credits != -1 && Auth::user()->credits >=
</option> $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"> <div class="invalid-feedback">
Please fill out this field. Please fill out this field.
</div> </div>
@enderror @enderror
</div> </div>
<div class="form-group text-right"> <div class="form-group text-right">
<input type="submit" class="btn btn-primary mt-3" value="Submit" onclick="this.disabled=true;this.value='Creating, please wait...';this.form.submit();" <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>