nodeList.blade.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. @extends('user.layouts')
  2. @section('css')
  3. <link href="/assets/global/fonts/font-awesome/css/all.min.css" rel="stylesheet">
  4. <link href="/assets/global/vendor/webui-popover/webui-popover.min.css" type="text/css" rel="stylesheet">
  5. <link href="/assets/global/vendor/jvectormap/jquery-jvectormap.min.css" type="text/css" rel="stylesheet">
  6. @endsection
  7. @section('content')
  8. <!-- BEGIN CONTENT BODY -->
  9. <div class="page-content container-fluid">
  10. <div class="row">
  11. <div class="col-md-9">
  12. <div class="card card-inverse card-shadow bg-white map">
  13. <div class="card-block h-450">
  14. <div class="h-p100" id="world-map"></div>
  15. </div>
  16. </div>
  17. </div>
  18. <div class="col-md-3">
  19. <div class="row map">
  20. <div class="col-md-12">
  21. <div class="card card-block p-20 bg-indigo-500">
  22. <div class="counter counter-lg counter-inverse">
  23. <div class="counter-label text-uppercase font-size-16">{{trans('user.account.level')}}</div>
  24. <div class="counter-number-group">
  25. <span class="counter-icon"><i class="icon wb-user-circle" aria-hidden="true"></i></span>
  26. <span class="counter-number ml-10">{{Auth::getUser()->level}}</span>
  27. </div>
  28. <div class="counter-label text-uppercase font-size-16">{{Auth::getUser()->level_name}}</div>
  29. </div>
  30. </div>
  31. </div>
  32. @if(Auth::getUser()->user_group_id)
  33. <div class="col-md-12">
  34. <div class="card card-block p-20 bg-indigo-500">
  35. <div class="counter counter-lg counter-inverse">
  36. <div class="counter-label text-uppercase font-size-16">{{trans('user.account.group')}}</div>
  37. <div class="counter-number-group">
  38. <span class="counter-icon"><i class="icon wb-globe" aria-hidden="true"></i></span>
  39. <span class="counter-number ml-10">{{Auth::getUser()->userGroup->name}}</span>
  40. </div>
  41. </div>
  42. </div>
  43. </div>
  44. @endif
  45. <div class="col-md-12">
  46. <div class="card card-block p-20 bg-indigo-500">
  47. <div class="counter counter-lg counter-inverse">
  48. <div class="counter-label text-uppercase font-size-16">{{trans('user.account.speed_limit')}}</div>
  49. <div class="counter-number-group">
  50. <span class="counter-icon"><i class="icon wb-signal" aria-hidden="true"></i></span>
  51. <span class="counter-number ml-10">{{Auth::getUser()->speed_limit ?? trans('common.unlimited')}}</span>
  52. </div>
  53. <div class="counter-label font-size-16">Mbps</div>
  54. </div>
  55. </div>
  56. </div>
  57. </div>
  58. </div>
  59. @foreach($nodeList as $node)
  60. <div class="col-xxl-3 col-xl-4 col-sm-6">
  61. <div class="card card-inverse card-shadow bg-white node">
  62. <div class="card-block p-30 row">
  63. <div class="col-4">
  64. <i class="fi fis fi-{{$node->country_code}} h-p100 w-p100" style="border-radius: 25px" aria-hidden="true"></i>
  65. </div>
  66. <div class="col-8 text-break text-right">
  67. <p class="font-size-20 blue-600">
  68. <span class="float-left badge badge-round badge-default">{{$node->level_table->name}}</span>
  69. @if($node->offline && !$node->relay_node_id)
  70. <i class="red-600 icon wb-warning" data-content="{{trans('user.node.unstable')}}"
  71. data-trigger="hover" data-toggle="popover" data-placement="top"></i>
  72. @endif
  73. @if($node->traffic_rate !== 1.0)
  74. <i class="green-600 icon wb-info-circle" data-content="{{trans('user.node.rate', ['ratio' => $node->traffic_rate])}}"
  75. data-trigger="hover" data-toggle="popover" data-placement="top"></i>
  76. @endif
  77. {{$node->name}}
  78. </p>
  79. <blockquote>
  80. @foreach($node->labels as $label)
  81. <span class="badge badge-round badge-info">{{$label->name}}</span>
  82. @endforeach
  83. <br>
  84. {{$node->description}}
  85. </blockquote>
  86. <p class="font-size-14">
  87. <button class="btn btn-sm btn-outline-info" onclick="getInfo('{{$node->id}}','code')">
  88. <i id="code{{$node->id}}" class="fa-solid fa-code"></i>
  89. </button>
  90. <button class="btn btn-sm btn-outline-info" onclick="getInfo('{{$node->id}}','qrcode')">
  91. <i id="qrcode{{$node->id}}" class="fa-solid fa-qrcode"></i>
  92. </button>
  93. <button class="btn btn-sm btn-outline-info" onclick="getInfo('{{$node->id}}','text')">
  94. <i id="text{{$node->id}}" class="fa-solid fa-list"></i>
  95. </button>
  96. </p>
  97. </div>
  98. </div>
  99. </div>
  100. </div>
  101. @endforeach
  102. </div>
  103. </div>
  104. @endsection
  105. @section('javascript')
  106. <script src="/assets/global/vendor/matchheight/jquery.matchHeight-min.js" type="text/javascript"></script>
  107. <script src="/assets/global/js/Plugin/matchheight.js" type="text/javascript"></script>
  108. <script src="/assets/custom/jquery-qrcode/jquery.qrcode.min.js" type="text/javascript"></script>
  109. <script src="/assets/global/js/Plugin/webui-popover.js" type="text/javascript"></script>
  110. <script src="/assets/global/vendor/jvectormap/jquery-jvectormap.min.js"></script>
  111. <script src="/assets/custom/maps/jquery-jvectormap-world-mill-cn.js"></script>
  112. <script type="text/javascript">
  113. $(function() {
  114. $('#world-map').vectorMap({
  115. map: 'world_mill',
  116. scaleColors: ['#C8EEFF', '#0071A4'],
  117. normalizeFunction: 'polynomial',
  118. zoomAnimate: true,
  119. hoverOpacity: 0.7,
  120. hoverColor: false,
  121. regionStyle: {
  122. initial: {
  123. fill: '#3E8EF7',
  124. },
  125. hover: {
  126. fill: '#589FFC',
  127. },
  128. selected: {
  129. fill: '#0B69E3',
  130. },
  131. selectedHover: {
  132. fill: '#589FFC',
  133. },
  134. },
  135. markerStyle: {
  136. initial: {
  137. r: 3,
  138. fill: '#FF4C52',
  139. 'stroke-width': 0,
  140. },
  141. hover: {
  142. r: 6,
  143. stroke: '#FF4C52',
  144. 'stroke-width': 0,
  145. },
  146. },
  147. backgroundColor: '#fff',
  148. markers: [
  149. @foreach($nodesGeo as $name => $geo)
  150. {
  151. latLng: [{{$name}}], name: '{{$geo}}',
  152. },
  153. @endforeach
  154. ],
  155. });
  156. $('.node').matchHeight();
  157. $('.map').matchHeight();
  158. });
  159. function getInfo(id, type) {
  160. const oldClass = $('#' + type + id).attr('class');
  161. $.ajax({
  162. method: 'POST',
  163. url: '{{route('node')}}',
  164. data: {_token: '{{csrf_token()}}', id: id, type: type},
  165. beforeSend: function() {
  166. $('#' + type + id).removeAttr('class').addClass('icon wb-loop icon-spin');
  167. },
  168. success: function(ret) {
  169. if (ret.status === 'success') {
  170. switch (type) {
  171. case 'code':
  172. swal.fire({
  173. html: '<textarea class="form-control" rows="8" readonly="readonly">' + ret.data + '</textarea>' +
  174. '<a href="' + ret.data + '" class="btn btn-danger btn-block mt-10">{{trans('common.open')}}' + ret.title + '</a>',
  175. showConfirmButton: false,
  176. });
  177. break;
  178. case 'qrcode':
  179. swal.fire({
  180. title: '{{trans('user.scan_qrcode')}}',
  181. html: '<div id="qrcode"></div>',
  182. onBeforeOpen: () => {
  183. $('#qrcode').qrcode({text: ret.data});
  184. },
  185. showConfirmButton: false,
  186. });
  187. break;
  188. case 'text':
  189. swal.fire({
  190. title: '{{trans('user.node.info')}}',
  191. html: '<textarea class="form-control" rows="12" readonly="readonly">' + ret.data + '</textarea>',
  192. showConfirmButton: false,
  193. });
  194. break;
  195. default:
  196. swal.fire({title: ret.title, text: ret.data, icon: 'error'});
  197. }
  198. }
  199. },
  200. complete: function() {
  201. $('#' + type + id).removeAttr('class').addClass(oldClass);
  202. },
  203. });
  204. }
  205. </script>
  206. @endsection