index.blade.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. @extends('layouts.main')
  2. @section('content')
  3. <!-- CONTENT HEADER -->
  4. <section class="content-header">
  5. <div class="container-fluid">
  6. <div class="row mb-2">
  7. <div class="col-sm-6">
  8. <h1>{{ __('Servers') }}</h1>
  9. </div>
  10. <div class="col-sm-6">
  11. <ol class="breadcrumb float-sm-right">
  12. <li class="breadcrumb-item"><a href="{{ route('home') }}">{{ __('Dashboard') }}</a></li>
  13. <li class="breadcrumb-item"><a class="text-muted"
  14. href="{{ route('servers.index') }}">{{ __('Servers') }}</a>
  15. </li>
  16. </ol>
  17. </div>
  18. </div>
  19. </div>
  20. </section>
  21. <!-- END CONTENT HEADER -->
  22. <!-- MAIN CONTENT -->
  23. <section class="content">
  24. <div class="container-fluid">
  25. <!-- CUSTOM CONTENT -->
  26. <div class="d-flex justify-content-md-start justify-content-center mb-3 ">
  27. <a @if (Auth::user()->Servers->count() >= Auth::user()->server_limit) disabled="disabled" title="Server limit reached!" @endif
  28. @cannot("user.server.create") disabled="disabled" title="No Permission!" @endcannot
  29. href="{{ route('servers.create') }}" class="btn
  30. @if (Auth::user()->Servers->count() >= Auth::user()->server_limit) disabled @endif
  31. @cannot("user.server.create") disabled @endcannot
  32. btn-primary">
  33. <i class="fa fa-plus mr-2"></i>
  34. {{ __('Create Server') }}
  35. </a>
  36. @if (Auth::user()->Servers->count() > 0 && !empty($phpmyadmin_url))
  37. <a
  38. href="{{ $phpmyadmin_url }}" target="_blank"
  39. class="btn btn-secondary ml-2"><i title="manage"
  40. class="fas fa-database mr-2"></i><span>{{ __('Database') }}</span>
  41. </a>
  42. @endif
  43. </div>
  44. <div class="row d-flex flex-row justify-content-center justify-content-md-start">
  45. @foreach ($servers as $server)
  46. @if($server->location && $server->node && $server->nest && $server->egg)
  47. <div class="col-xl-3 col-lg-5 col-md-6 col-sm-6 col-xs-12 card pr-0 pl-0 ml-sm-2 mr-sm-3"
  48. style="max-width: 350px">
  49. <div class="card-header">
  50. <div class="d-flex justify-content-between align-items-center">
  51. <h5 class="card-title mt-1">{{ $server->name }}</h5>
  52. </div>
  53. </div>
  54. <div class="card-body">
  55. <div class="container mt-1">
  56. <div class="row mb-3">
  57. <div class="col my-auto">{{ __('Status') }}:</div>
  58. <div class="col-7 my-auto">
  59. @if($server->suspended)
  60. <span class="badge badge-danger">{{ __('Suspended') }}</span>
  61. @elseif($server->canceled)
  62. <span class="badge badge-warning">{{ __('Canceled') }}</span>
  63. @else
  64. <span class="badge badge-success">{{ __('Active') }}</span>
  65. @endif
  66. </div>
  67. </div>
  68. <div class="row mb-2">
  69. <div class="col-5">
  70. {{ __('Location') }}:
  71. </div>
  72. <div class="col-7 d-flex justify-content-between align-items-center">
  73. <span class="">{{ $server->location }}</span>
  74. <i data-toggle="popover" data-trigger="hover"
  75. data-content="{{ __('Node') }}: {{ $server->node }}"
  76. class="fas fa-info-circle"></i>
  77. </div>
  78. </div>
  79. <div class="row mb-2">
  80. <div class="col-5 ">
  81. {{ __('Software') }}:
  82. </div>
  83. <div class="col-7 text-wrap">
  84. <span>{{ $server->nest }}</span>
  85. </div>
  86. </div>
  87. <div class="row mb-2">
  88. <div class="col-5 ">
  89. {{ __('Specification') }}:
  90. </div>
  91. <div class="col-7 text-wrap">
  92. <span>{{ $server->egg }}</span>
  93. </div>
  94. </div>
  95. <div class="row mb-2">
  96. <div class="col-5 ">
  97. {{ __('Resource plan') }}:
  98. </div>
  99. <div class="col-7 text-wrap d-flex justify-content-between align-items-center">
  100. <span>{{ $server->product->name }}
  101. </span>
  102. <i data-toggle="popover" data-trigger="hover" data-html="true"
  103. data-content="{{ __('CPU') }}: {{ $server->product->cpu / 100 }} {{ __('vCores') }} <br/>{{ __('RAM') }}: {{ $server->product->memory }} MB <br/>{{ __('Disk') }}: {{ $server->product->disk }} MB <br/>{{ __('Backups') }}: {{ $server->product->backups }} <br/> {{ __('MySQL Databases') }}: {{ $server->product->databases }} <br/> {{ __('Allocations') }}: {{ $server->product->allocations }} <br/>{{ __('OOM Killer') }}: {{ $server->product->oom_killer ? __("enabled") : __("disabled") }} <br/> {{ __('Billing Period') }}: {{$server->product->billing_period}}"
  104. class="fas fa-info-circle"></i>
  105. </div>
  106. </div>
  107. <div class="row mb-4 ">
  108. <div class="col-5 word-break" style="hyphens: auto">
  109. {{ __('Next Billing Cycle') }}:
  110. </div>
  111. <div class="col-7 d-flex text-wrap align-items-center">
  112. <span>
  113. @if ($server->suspended)
  114. -
  115. @else
  116. @switch($server->product->billing_period)
  117. @case('monthly')
  118. {{ \Carbon\Carbon::parse($server->last_billed)->addMonth()->toDayDateTimeString(); }}
  119. @break
  120. @case('weekly')
  121. {{ \Carbon\Carbon::parse($server->last_billed)->addWeek()->toDayDateTimeString(); }}
  122. @break
  123. @case('daily')
  124. {{ \Carbon\Carbon::parse($server->last_billed)->addDay()->toDayDateTimeString(); }}
  125. @break
  126. @case('hourly')
  127. {{ \Carbon\Carbon::parse($server->last_billed)->addHour()->toDayDateTimeString(); }}
  128. @break
  129. @case('quarterly')
  130. {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(3)->toDayDateTimeString(); }}
  131. @break
  132. @case('half-annually')
  133. {{ \Carbon\Carbon::parse($server->last_billed)->addMonths(6)->toDayDateTimeString(); }}
  134. @break
  135. @case('annually')
  136. {{ \Carbon\Carbon::parse($server->last_billed)->addYear()->toDayDateTimeString(); }}
  137. @break
  138. @default
  139. {{ __('Unknown') }}
  140. @endswitch
  141. @endif
  142. </span>
  143. </div>
  144. </div>
  145. <div class="row mb-2">
  146. <div class="col-4">
  147. {{ __('Price') }}:
  148. <span class="text-muted">
  149. ({{ $credits_display_name }})
  150. </span>
  151. </div>
  152. <div class="col-8 text-center">
  153. <div class="text-muted">
  154. @if($server->product->billing_period == 'monthly')
  155. {{ __('per Month') }}
  156. @elseif($server->product->billing_period == 'half-annually')
  157. {{ __('per 6 Months') }}
  158. @elseif($server->product->billing_period == 'quarterly')
  159. {{ __('per 3 Months') }}
  160. @elseif($server->product->billing_period == 'annually')
  161. {{ __('per Year') }}
  162. @elseif($server->product->billing_period == 'weekly')
  163. {{ __('per Week') }}
  164. @elseif($server->product->billing_period == 'daily')
  165. {{ __('per Day') }}
  166. @elseif($server->product->billing_period == 'hourly')
  167. {{ __('per Hour') }}
  168. @endif
  169. <i data-toggle="popover" data-trigger="hover"
  170. data-content="{{ __('Your') ." " . $credits_display_name . " ". __('are reduced') ." ". $server->product->billing_period . ". " . __("This however calculates to ") . number_format($server->product->getMonthlyPrice(),2,",",".") . " ". $credits_display_name . " ". __('per Month')}}"
  171. class="fas fa-info-circle"></i>
  172. </div>
  173. <span>
  174. {{ $server->product->price == round($server->product->price) ? round($server->product->price) : $server->product->price }}
  175. </span>
  176. </div>
  177. </div>
  178. </div>
  179. </div>
  180. <div class="card-footer text-center">
  181. <a href="{{ $pterodactyl_url }}/server/{{ $server->identifier }}"
  182. target="__blank"
  183. class="btn btn-info text-center float-left ml-2"
  184. data-toggle="tooltip" data-placement="bottom" title="{{ __('Manage Server') }}">
  185. <i class="fas fa-tools mx-2"></i>
  186. </a>
  187. <a href="{{ route('servers.show', ['server' => $server->id])}}"
  188. class="btn btn-info text-center mr-3"
  189. data-toggle="tooltip" data-placement="bottom" title="{{ __('Server Settings') }}">
  190. <i class="fas fa-cog mx-2"></i>
  191. </a>
  192. <button onclick="handleServerCancel('{{ $server->id }}');" target="__blank"
  193. class="btn btn-warning text-center"
  194. {{ $server->suspended || $server->canceled ? "disabled" : "" }}
  195. data-toggle="tooltip" data-placement="bottom" title="{{ __('Cancel Server') }}">
  196. <i class="fas fa-ban mx-2"></i>
  197. </button>
  198. <button onclick="handleServerDelete('{{ $server->id }}');" target="__blank"
  199. class="btn btn-danger text-center float-right mr-2"
  200. data-toggle="tooltip" data-placement="bottom" title="{{ __('Delete Server') }}">
  201. <i class="fas fa-trash mx-2"></i>
  202. </button>
  203. </div>
  204. </div>
  205. @endif
  206. @endforeach
  207. </div>
  208. <!-- END CUSTOM CONTENT -->
  209. </div>
  210. </section>
  211. <!-- END CONTENT -->
  212. <script>
  213. const handleServerCancel = (serverId) => {
  214. // Handle server cancel with sweetalert
  215. Swal.fire({
  216. title: "{{ __('Cancel Server?') }}",
  217. text: "{{ __('This will cancel your current server to the next billing period. It will get suspended when the current period runs out.') }}",
  218. icon: 'warning',
  219. confirmButtonColor: '#d9534f',
  220. showCancelButton: true,
  221. confirmButtonText: "{{ __('Yes, cancel it!') }}",
  222. cancelButtonText: "{{ __('No, abort!') }}",
  223. reverseButtons: true
  224. }).then((result) => {
  225. if (result.value) {
  226. // Delete server
  227. fetch("{{ route('servers.cancel', '') }}" + '/' + serverId, {
  228. method: 'PATCH',
  229. headers: {
  230. 'X-CSRF-TOKEN': '{{ csrf_token() }}'
  231. }
  232. }).then(() => {
  233. window.location.reload();
  234. }).catch((error) => {
  235. Swal.fire({
  236. title: "{{ __('Error') }}",
  237. text: "{{ __('Something went wrong, please try again later.') }}",
  238. icon: 'error',
  239. confirmButtonColor: '#d9534f',
  240. })
  241. })
  242. return
  243. }
  244. })
  245. }
  246. const handleServerDelete = (serverId) => {
  247. Swal.fire({
  248. title: "{{ __('Delete Server?') }}",
  249. html: "{!! __('This is an irreversible action, all files of this server will be removed. <strong>No funds will get refunded</strong>. We recommend deleting the server when server is suspended.') !!}",
  250. icon: 'warning',
  251. confirmButtonColor: '#d9534f',
  252. showCancelButton: true,
  253. confirmButtonText: "{{ __('Yes, delete it!') }}",
  254. cancelButtonText: "{{ __('No, abort!') }}",
  255. reverseButtons: true
  256. }).then((result) => {
  257. if (result.value) {
  258. // Delete server
  259. fetch("{{ route('servers.destroy', '') }}" + '/' + serverId, {
  260. method: 'DELETE',
  261. headers: {
  262. 'X-CSRF-TOKEN': '{{ csrf_token() }}'
  263. }
  264. }).then(() => {
  265. window.location.reload();
  266. }).catch((error) => {
  267. Swal.fire({
  268. title: "{{ __('Error') }}",
  269. text: "{{ __('Something went wrong, please try again later.') }}",
  270. icon: 'error',
  271. confirmButtonColor: '#d9534f',
  272. })
  273. })
  274. return
  275. }
  276. });
  277. }
  278. document.addEventListener('DOMContentLoaded', () => {
  279. $('[data-toggle="popover"]').popover();
  280. });
  281. $(function () {
  282. $('[data-toggle="tooltip"]').tooltip()
  283. })
  284. </script>
  285. @endsection