index.blade.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. @extends('layouts.main')
  2. @section('content')
  3. <!-- CONTENT HEADER -->
  4. <section class="content-header">
  5. <div class="container-fluid">
  6. <div class="mb-2 row">
  7. <div class="col-sm-6">
  8. <h1>{{__('Admin Overview')}}</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('admin.overview.index')}}">{{__('Admin Overview')}}</a></li>
  15. </ol>
  16. </div>
  17. </div>
  18. </div>
  19. @if(Storage::get('latestVersion') && config("app.version") < Storage::get('latestVersion'))
  20. <div class="alert alert-danger" role="alert">
  21. <b><i class="fas fa-shield-alt"></i> {{__("Version Outdated:")}}</b></br>
  22. {{__("You are running on")}} v{{config("app.version")}}-{{config("BRANCHNAME")}}.
  23. {{__("The latest Version is")}} v{{Storage::get('latestVersion')}}</br>
  24. <a href="https://CtrlPanel.gg/docs/Installation/updating">{{__("Consider updating now")}}</a>
  25. </div>
  26. @endif
  27. </section>
  28. <!-- END CONTENT HEADER -->
  29. <!-- MAIN CONTENT -->
  30. <section class="content">
  31. <div class="container-fluid">
  32. <div class="mb-3 row">
  33. <div class="col-md-3">
  34. <a href="https://discord.gg/4Y6HjD2uyU" class="px-3 btn btn-dark btn-block"><i
  35. class="mr-2 fab fa-discord"></i> {{__('Support server')}}</a>
  36. </div>
  37. <div class="col-md-3">
  38. <a href="https://CtrlPanel.gg/docs/intro" class="px-3 btn btn-dark btn-block"><i
  39. class="mr-2 fas fa-link"></i> {{__('Documentation')}}</a>
  40. </div>
  41. <div class="col-md-3">
  42. <a href="https://github.com/Ctrlpanel-gg/panel" class="px-3 btn btn-dark btn-block"><i
  43. class="mr-2 fab fa-github"></i> {{__('Github')}}</a>
  44. </div>
  45. <div class="col-md-3">
  46. <a href="https://CtrlPanel.gg/docs/Contributing/donating" class="px-3 btn btn-dark btn-block"><i
  47. class="mr-2 fas fa-money-bill"></i> {{__('Support CtrlPanel')}}</a>
  48. </div>
  49. </div>
  50. <div class="row">
  51. <div class="col-12 col-sm-6 col-md-3">
  52. <div class="info-box">
  53. <span class="info-box-icon bg-info elevation-1"><i class="fas fa-server"></i></span>
  54. <div class="info-box-content">
  55. <span class="info-box-text">{{__('Servers')}}
  56. <i class="mr-4 fas fa-info-circle" data-toggle="popover"
  57. data-trigger="hover" data-placement="top"
  58. data-html="true"
  59. data-content="{{ __("This shows the total active servers and the total servers. Total active servers are all servers which are not suspended") }}"></i>
  60. </span>
  61. <span class="info-box-number">{{$counters['servers']->active}}/{{$counters['servers']->total}}</span>
  62. </div>
  63. <!-- /.info-box-content -->
  64. </div>
  65. <!-- /.info-box -->
  66. </div>
  67. <div class="col-12 col-sm-6 col-md-3">
  68. <div class="info-box">
  69. <span class="info-box-icon bg-primary elevation-1"><i class="fas fa-users"></i></span>
  70. <div class="info-box-content">
  71. <span class="info-box-text">{{__('Users')}}
  72. <i class="mr-4 fas fa-info-circle" data-toggle="popover"
  73. data-trigger="hover" data-placement="top"
  74. data-html="true"
  75. data-content="{{ __("This shows the total active Users and the total Users. Total active Users are all Users which are not suspended") }}"></i>
  76. </span>
  77. <span class="info-box-number">{{$counters['users']->active}}/{{$counters['users']->total}}</span>
  78. </div>
  79. <!-- /.info-box-content -->
  80. </div>
  81. <!-- /.info-box -->
  82. </div>
  83. <div class="col-12 col-sm-6 col-md-3">
  84. <div class="info-box">
  85. <span class="info-box-icon bg-warning elevation-1"><i
  86. class="text-white fas fa-coins"></i></span>
  87. <div class="info-box-content">
  88. <span class="info-box-text">{{__('Total')}} {{ $credits_display_name }}</span>
  89. <span class="info-box-number">{{$counters['credits']}}</span>
  90. </div>
  91. <!-- /.info-box-content -->
  92. </div>
  93. <!-- /.info-box -->
  94. </div>
  95. <div class="col-12 col-sm-6 col-md-3">
  96. <div class="info-box">
  97. <span class="info-box-icon bg-success elevation-1"><i class="fas fa-money-bill"></i></span>
  98. <div class="info-box-content">
  99. <span class="info-box-text">{{__('Payments')}}</span>
  100. <span class="info-box-number">{{$counters['payments']->total}}</span>
  101. </div>
  102. <!-- /.info-box-content -->
  103. </div>
  104. <!-- /.info-box -->
  105. </div>
  106. </div>
  107. <div class="row">
  108. <div class="col-md-6">
  109. <div class="card">
  110. <div class="card-header">
  111. <div class="d-flex justify-content-between">
  112. <div class="card-title ">
  113. <span><i class="mr-2 fas fa-kiwi-bird"></i>{{__('Pterodactyl')}}</span>
  114. </div>
  115. <a href="{{route('admin.overview.sync')}}" class="btn btn-primary btn-sm"><i
  116. class="mr-2 fas fa-sync"></i>{{__('Sync')}}</a>
  117. </div>
  118. </div>
  119. <div class="py-1 card-body">
  120. @if ($deletedNodesPresent)
  121. <div class="m-2 alert alert-danger">
  122. <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Warning!') }}</h5>
  123. <p class="mb-2">
  124. {{ __('Some nodes got deleted on pterodactyl only. Please click the sync button above.') }}
  125. </p>
  126. </div>
  127. @endif
  128. <table class="table">
  129. <thead>
  130. <tr>
  131. <th>{{__('Resources')}}</th>
  132. <th>{{__('Count')}}</th>
  133. </tr>
  134. </thead>
  135. <tbody>
  136. <tr>
  137. <td>{{__('Locations')}}</td>
  138. <td>{{$counters['locations']}}</td>
  139. </tr>
  140. <tr>
  141. <td>{{__('Nodes')}}</td>
  142. <td>{{$nodes->count()}}</td>
  143. </tr>
  144. <tr>
  145. <td>{{__('Nests')}}</td>
  146. <td>{{$counters['nests']}}</td>
  147. </tr>
  148. <tr>
  149. <td>{{__('Eggs')}}</td>
  150. <td>{{$counters['eggs']}}</td>
  151. </tr>
  152. </tbody>
  153. </table>
  154. </div>
  155. <div class="card-footer">
  156. <span><i class="mr-2 fas fa-sync"></i>{{__('Last updated :date', ['date' => $syncLastUpdate])}}</span>
  157. </div>
  158. </div>
  159. <div class="card">
  160. <div class="card-header">
  161. <div class="d-flex justify-content-between">
  162. <div class="card-title ">
  163. <span><i class="mr-2 fas fa-ticket-alt"></i>{{__('Latest tickets')}}</span>
  164. </div>
  165. </div>
  166. </div>
  167. <div class="py-1 card-body">
  168. @if(!$tickets->count())<span style="font-size: 16px; font-weight:700">{{__('There are no tickets')}}.</span>
  169. @else
  170. <div class="overflow-auto">
  171. <table class="table">
  172. <thead>
  173. <tr class="text-nowrap">
  174. <th>{{__('Title')}}</th>
  175. <th>{{__('User')}}</th>
  176. <th>{{__('Status')}}</th>
  177. <th>{{__('Last updated')}}</th>
  178. </tr>
  179. </thead>
  180. <tbody>
  181. @foreach($tickets as $ticket_id => $ticket)
  182. <tr class="text-nowrap">
  183. <td><a class="text-info" href="{{route('admin.ticket.show', ['ticket_id' => $ticket_id])}}">#{{$ticket_id}} - {{$ticket->title}}</td>
  184. <td><a href="{{route('admin.users.show', $ticket->user_id)}}">{{$ticket->user}}</a></td>
  185. <td><span class="badge {{$ticket->statusBadgeColor}}">{{$ticket->status}}</span></td>
  186. <td>{{$ticket->last_updated}}</td>
  187. </tr>
  188. @endforeach
  189. </tbody>
  190. </table>
  191. </div>
  192. @endif
  193. </div>
  194. </div>
  195. <div class="card">
  196. <div class="card-header">
  197. <div class="d-flex justify-content-between">
  198. <div class="card-title ">
  199. <span><i class="mr-2 fas fa-server"></i>{{__('CtrlPanel.gg')}}</span>
  200. </div>
  201. </div>
  202. <div class="py-1 card-body">
  203. </div>
  204. <div class="card-footer">
  205. <span><i class="mr-2 fas fa-info"></i>{{__("Version")}} {{config("app.version")}} - {{config("BRANCHNAME")}}</span>
  206. </div>
  207. </div>
  208. </div>
  209. </div>
  210. <div class="col-md-6">
  211. <div class="card">
  212. <div class="card-header">
  213. <div class="d-flex justify-content-between">
  214. <div class="card-title ">
  215. <span><i class="mr-2 fas fa-server"></i>{{__('Individual nodes')}}</span>
  216. </div>
  217. </div>
  218. </div>
  219. <div class="py-1 card-body">
  220. @if ($perPageLimit)
  221. <div class="m-2 alert alert-danger">
  222. <h5><i class="icon fas fa-exclamation-circle"></i>{{ __('Error!') }}</h5>
  223. <p class="mb-2">
  224. {{ __('You reached the Pterodactyl perPage limit. Please make sure to set it higher than your server count.') }}<br>
  225. {{ __('You can do that in settings.') }}<br><br>
  226. {{ __('Note') }}: {{ __('If this error persists even after changing the limit, it might mean a server was deleted on Pterodactyl, but not on CtrlPanel. Try clicking the button below.') }}
  227. </p>
  228. <a href="{{route('admin.servers.sync')}}" class="btn btn-primary btn-md"><i
  229. class="mr-2 fas fa-sync"></i>{{__('Sync servers')}}</a>
  230. </div>
  231. @endif
  232. <div class="overflow-auto">
  233. <table class="table">
  234. <thead>
  235. <tr class="text-nowrap">
  236. <th>{{__('ID')}}</th>
  237. <th>{{__('Node')}}</th>
  238. <th>{{__('Server count')}}</th>
  239. <th>{{__('Resource usage')}}</th>
  240. <th>{{ $credits_display_name . ' ' . __('Usage') ." (".__('per month').")"}}</th>
  241. </tr>
  242. </thead>
  243. <tbody>
  244. @foreach($nodes as $nodeID => $node)
  245. <tr>
  246. <td>{{$nodeID}}</td>
  247. <td>{{$node->name}}</td>
  248. <td>{{$node->activeServers}}/{{$node->totalServers}}</td>
  249. <td>{{$node->usagePercent}}%</td>
  250. <td>{{$node->activeEarnings}}/{{$node->totalEarnings}}</td>
  251. </tr>
  252. @endforeach
  253. </tbody>
  254. <tfoot>
  255. <tr>
  256. <td class="text-nowrap" colspan="2"><span style="float: right; font-weight: 700">{{__('Total')}} ({{__('active')}}/{{__('total')}}):</span></td>
  257. <td>{{$counters['servers']->active}}/{{$counters['servers']->total}}</td>
  258. <td>{{$counters['totalUsagePercent']}}%</td>
  259. <td>{{$counters['earnings']->active}}/{{$counters['earnings']->total}}</td>
  260. </tr>
  261. </tfoot>
  262. </table>
  263. </div>
  264. <hr style="width: 100%; height:2px; border-width:0; background-color:#6c757d; margin-top: 0px;">
  265. </div>
  266. </div>
  267. <div class="card">
  268. <div class="card-header">
  269. <div class="d-flex justify-content-between">
  270. <div class="card-title ">
  271. <span><i class="mr-2 fas fa-file-invoice-dollar"></i>{{__('Latest payments')}}</span>
  272. </div>
  273. </div>
  274. </div>
  275. <div class="py-1 card-body">
  276. <div class="row">
  277. @if($counters['payments']['lastMonth']->count())
  278. <div class="col-md-6" style="border-right:1px solid #6c757d">
  279. <span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('Last month')}}:
  280. <i data-toggle="popover" data-trigger="hover" data-html="true"
  281. data-content="{{ __('Payments in this time window') }}:<br>{{$counters['payments']['lastMonth']->timeStart}} - {{$counters['payments']['lastMonth']->timeEnd}}"
  282. class="fas fa-info-circle"></i>
  283. </span>
  284. <div class="overflow-auto">
  285. <table class="table">
  286. <thead>
  287. <tr class="text-nowrap">
  288. <th><b>{{__('Currency')}}</b></th>
  289. <th>{{__('Number of payments')}}</th>
  290. <th>{{__('Total amount')}}</th>
  291. </tr>
  292. </thead>
  293. <tbody>
  294. @foreach($counters['payments']['lastMonth'] as $currency => $income)
  295. <tr>
  296. <td>{{$currency}}</td>
  297. <td>{{$income->count}}</td>
  298. <td>{{$income->total}}</td>
  299. </tr>
  300. @endforeach
  301. </tbody>
  302. </table>
  303. </div>
  304. </div>
  305. @endif
  306. @if($counters['payments']['lastMonth']->count()) <div class="col-md-6">
  307. @else <div class="col-md-12"> @endif
  308. <span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('This month')}}:
  309. <i data-toggle="popover" data-trigger="hover" data-html="true"
  310. data-content="{{ __('Payments in this time window') }}:<br>{{$counters['payments']['thisMonth']->timeStart}} - {{$counters['payments']['thisMonth']->timeEnd}}"
  311. class="fas fa-info-circle"></i>
  312. </span>
  313. <div class="overflow-auto">
  314. <table class="table">
  315. <thead>
  316. <tr class="text-nowrap">
  317. <th><b>{{__('Currency')}}</b></th>
  318. <th>{{__('Number of payments')}}</th>
  319. <th>{{__('Total amount')}}</th>
  320. </tr>
  321. </thead>
  322. <tbody>
  323. @foreach($counters['payments']['thisMonth'] as $currency => $income)
  324. <tr>
  325. <td>{{$currency}}</td>
  326. <td>{{$income->count}}</td>
  327. <td>{{$income->total}}</td>
  328. </tr>
  329. @endforeach
  330. </tbody>
  331. </table>
  332. </div>
  333. </div>
  334. </div>
  335. </div>
  336. </div>
  337. <div class="card">
  338. <div class="card-header">
  339. <div class="d-flex justify-content-between">
  340. <div class="card-title ">
  341. <span><i class="mr-2 fas fa-hand-holding-usd"></i>{{__('Tax overview')}}</span>
  342. </div>
  343. </div>
  344. </div>
  345. <div class="py-1 card-body">
  346. @if($counters['taxPayments']['lastYear']->count())
  347. <span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('Last year')}}:
  348. <i data-toggle="popover" data-trigger="hover" data-html="true"
  349. data-content="{{ __('Payments in this time window') }}:<br>{{$counters['taxPayments']['lastYear']->timeStart}} - {{$counters['taxPayments']['lastYear']->timeEnd}}"
  350. class="fas fa-info-circle"></i>
  351. </span>
  352. <div class="overflow-auto">
  353. <table class="table">
  354. <thead>
  355. <tr class="text-nowrap">
  356. <th><b>{{__('Currency')}}</b></th>
  357. <th>{{__('Number of payments')}}</th>
  358. <th><b>{{__('Base amount')}}</b></th>
  359. <th><b>{{__('Total taxes')}}</b></th>
  360. <th>{{__('Total amount')}}</th>
  361. </tr>
  362. </thead>
  363. <tbody>
  364. @foreach($counters['taxPayments']['lastYear'] as $currency => $income)
  365. <tr>
  366. <td>{{$currency}}</td>
  367. <td>{{$income->count}}</td>
  368. <td>{{$income->price}}</td>
  369. <td>{{$income->taxes}}</td>
  370. <td>{{$income->total}}</td>
  371. </tr>
  372. @endforeach
  373. </tbody>
  374. </table>
  375. </div>
  376. <hr style="width: 100%; height:2px; border-width:0; background-color:#6c757d; margin-top: 0px; margin-bottom: 8px">
  377. @endif
  378. <span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('This year')}}:
  379. <i data-toggle="popover" data-trigger="hover" data-html="true"
  380. data-content="{{ __('Payments in this time window') }}:<br>{{$counters['taxPayments']['thisYear']->timeStart}} - {{$counters['taxPayments']['thisYear']->timeEnd}}"
  381. class="fas fa-info-circle"></i>
  382. </span>
  383. <div class="overflow-auto">
  384. <table class="table">
  385. <thead>
  386. <tr class="text-nowrap">
  387. <th><b>{{__('Currency')}}</b></th>
  388. <th>{{__('Number of payments')}}</th>
  389. <th><b>{{__('Base amount')}}</b></th>
  390. <th><b>{{__('Total taxes')}}</b></th>
  391. <th>{{__('Total amount')}}</th>
  392. </tr>
  393. </thead>
  394. <tbody>
  395. @foreach($counters['taxPayments']['thisYear'] as $currency => $income)
  396. <tr>
  397. <td>{{$currency}}</td>
  398. <td>{{$income->count}}</td>
  399. <td>{{$income->price}}</td>
  400. <td>{{$income->taxes}}</td>
  401. <td>{{$income->total}}</td>
  402. </tr>
  403. @endforeach
  404. </tbody>
  405. </table>
  406. </div>
  407. <hr style="width: 100%; height:2px; border-width:0; background-color:#6c757d; margin-top: 0px;">
  408. </div>
  409. </div>
  410. </div>
  411. </div>
  412. </div>
  413. <!-- END CUSTOM CONTENT -->
  414. </section>
  415. <!-- END CONTENT -->
  416. @endsection