vpn-management.blade.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. <!-- resources/views/livewire/vpn-management.blade.php -->
  2. <div>
  3. <!-- Content Header -->
  4. <div class="content-header">
  5. <div class="container-fluid">
  6. <div class="row mb-2">
  7. <div class="col-sm-6">
  8. <h1 class="m-0">Gestione Connessione VPN</h1>
  9. </div>
  10. <div class="col-sm-6">
  11. <ol class="breadcrumb float-sm-right">
  12. <li class="breadcrumb-item"><a href="/dashboard">Home</a></li>
  13. <li class="breadcrumb-item active">VPN</li>
  14. </ol>
  15. </div>
  16. </div>
  17. </div>
  18. </div>
  19. <!-- Main content -->
  20. <div class="row">
  21. <!-- Stato VPN -->
  22. <div class="col-md-6">
  23. <div class="card card-primary">
  24. <div class="card-header">
  25. <h3 class="card-title">
  26. <i class="fas fa-shield-alt"></i> Stato Connessione VPN
  27. </h3>
  28. <div class="card-tools">
  29. <button type="button" class="btn btn-tool" wire:click="refreshStatus">
  30. <i class="fas fa-sync"></i>
  31. </button>
  32. </div>
  33. </div>
  34. <div class="card-body">
  35. <div class="row">
  36. <div class="col-md-6">
  37. <div class="info-box">
  38. <span class="{{ $this->getStatusIconClass() }}">
  39. <i class="{{ $this->getStatusIcon() }}"></i>
  40. </span>
  41. <div class="info-box-content">
  42. <span class="info-box-text">Stato VPN</span>
  43. <span class="info-box-number">{{ $this->getStatusText() }}</span>
  44. <span class="info-box-more">
  45. @if($lastUpdate)
  46. Ultimo aggiornamento: {{ \Carbon\Carbon::parse($lastUpdate)->format('d/m/Y H:i:s') }}
  47. @else
  48. Nessun aggiornamento disponibile
  49. @endif
  50. </span>
  51. </div>
  52. </div>
  53. </div>
  54. <div class="col-md-6">
  55. <div class="text-center">
  56. <button type="button"
  57. class="btn btn-success btn-lg"
  58. wire:click="connectVpn"
  59. wire:loading.attr="disabled"
  60. wire:target="connectVpn">
  61. <span wire:loading.remove wire:target="connectVpn">
  62. <i class="fas fa-play"></i> Connetti VPN
  63. </span>
  64. <span wire:loading wire:target="connectVpn">
  65. <i class="fas fa-spinner fa-spin"></i> Connettendo...
  66. </span>
  67. </button>
  68. <br><br>
  69. <button type="button"
  70. class="btn btn-warning btn-lg"
  71. wire:click="disconnectVpn"
  72. wire:loading.attr="disabled"
  73. wire:target="disconnectVpn">
  74. <span wire:loading.remove wire:target="disconnectVpn">
  75. <i class="fas fa-stop"></i> Disconnetti VPN
  76. </span>
  77. <span wire:loading wire:target="disconnectVpn">
  78. <i class="fas fa-spinner fa-spin"></i> Disconnettendo...
  79. </span>
  80. </button>
  81. </div>
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. </div>
  87. <!-- Configurazione Credenziali -->
  88. <div class="col-md-6">
  89. <div class="card card-warning">
  90. <div class="card-header">
  91. <h3 class="card-title">
  92. <i class="fas fa-cog"></i> Configurazione Credenziali
  93. </h3>
  94. </div>
  95. <div class="card-body">
  96. @if($successMessage)
  97. <div class="alert alert-success alert-dismissible">
  98. <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
  99. {{ $successMessage }}
  100. </div>
  101. @endif
  102. @if($errorMessage)
  103. <div class="alert alert-danger alert-dismissible">
  104. <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
  105. {{ $errorMessage }}
  106. </div>
  107. @endif
  108. <form wire:submit.prevent="updateCredentials">
  109. <div class="form-group">
  110. <label for="username">Username</label>
  111. <input type="text"
  112. class="form-control @error('username') is-invalid @enderror"
  113. wire:model="username"
  114. required>
  115. @error('username')
  116. <div class="invalid-feedback">{{ $message }}</div>
  117. @enderror
  118. </div>
  119. <div class="form-group">
  120. <label for="password">Password</label>
  121. <input type="password"
  122. class="form-control @error('password') is-invalid @enderror"
  123. wire:model="password"
  124. placeholder="Inserisci la password"
  125. required>
  126. @error('password')
  127. <div class="invalid-feedback">{{ $message }}</div>
  128. @enderror
  129. </div>
  130. <div class="form-group">
  131. <label for="server">Server VPN</label>
  132. <input type="text"
  133. class="form-control @error('server') is-invalid @enderror"
  134. wire:model="server"
  135. required>
  136. @error('server')
  137. <div class="invalid-feedback">{{ $message }}</div>
  138. @enderror
  139. </div>
  140. <button type="submit"
  141. class="btn btn-primary"
  142. wire:loading.attr="disabled"
  143. wire:target="updateCredentials">
  144. <span wire:loading.remove wire:target="updateCredentials">
  145. <i class="fas fa-save"></i> Salva Credenziali
  146. </span>
  147. <span wire:loading wire:target="updateCredentials">
  148. <i class="fas fa-spinner fa-spin"></i> Salvando...
  149. </span>
  150. </button>
  151. </form>
  152. </div>
  153. </div>
  154. </div>
  155. </div>
  156. <!-- Log VPN -->
  157. <div class="row mt-4">
  158. <div class="col-md-12">
  159. <div class="card card-info">
  160. <div class="card-header">
  161. <h3 class="card-title">
  162. <i class="fas fa-file-alt"></i> Informazioni VPN
  163. </h3>
  164. </div>
  165. <div class="card-body">
  166. <div class="table-responsive">
  167. <table class="table table-striped">
  168. <thead>
  169. <tr>
  170. <th>Proprietà</th>
  171. <th>Valore</th>
  172. </tr>
  173. </thead>
  174. <tbody>
  175. <tr>
  176. <td><strong>Stato Attuale</strong></td>
  177. <td>
  178. <span class="{{ $this->getStatusBadgeClass() }}">
  179. {{ $this->getStatusBadgeText() }}
  180. </span>
  181. {{ $this->getStatusText() }}
  182. </td>
  183. </tr>
  184. <tr>
  185. <td><strong>Server Configurato</strong></td>
  186. <td>{{ $server }}</td>
  187. </tr>
  188. <tr>
  189. <td><strong>Username Configurato</strong></td>
  190. <td>{{ $username }}</td>
  191. </tr>
  192. <tr>
  193. <td><strong>Ultimo Aggiornamento</strong></td>
  194. <td>
  195. @if($lastUpdate)
  196. {{ \Carbon\Carbon::parse($lastUpdate)->format('d/m/Y H:i:s') }}
  197. @else
  198. Non disponibile
  199. @endif
  200. </td>
  201. </tr>
  202. </tbody>
  203. </table>
  204. </div>
  205. </div>
  206. </div>
  207. </div>
  208. </div>
  209. </div>
  210. @push('css')
  211. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css">
  212. @endpush
  213. @push('scripts')
  214. <script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
  215. <script>
  216. // Listen for Livewire events
  217. document.addEventListener('livewire:load', function () {
  218. // Auto-refresh status every 30 seconds
  219. setInterval(function() {
  220. @this.call('refreshStatus');
  221. }, 30000);
  222. // Update sidebar badge when status changes
  223. Livewire.on('vpnStatusUpdated', status => {
  224. updateSidebarBadge(status);
  225. });
  226. // Show toast notifications
  227. Livewire.on('showToast', (type, message) => {
  228. if (typeof toastr !== 'undefined') {
  229. toastr[type](message);
  230. }
  231. });
  232. // Refresh status with delay (after connect/disconnect commands)
  233. Livewire.on('refreshStatusDelayed', () => {
  234. setTimeout(function() {
  235. @this.call('refreshStatus');
  236. }, 3000);
  237. });
  238. });
  239. function updateSidebarBadge(status) {
  240. const badge = document.getElementById('vpn-status-badge');
  241. if (badge) {
  242. badge.className = ''; // Clear existing classes
  243. if (status === 'connected') {
  244. badge.className = 'badge badge-success right';
  245. badge.textContent = 'ON';
  246. } else if (status === 'disconnected') {
  247. badge.className = 'badge badge-danger right';
  248. badge.textContent = 'OFF';
  249. } else if (status === 'error') {
  250. badge.className = 'badge badge-danger right';
  251. badge.textContent = 'ERR';
  252. } else {
  253. badge.className = 'badge badge-warning right';
  254. badge.textContent = '?';
  255. }
  256. }
  257. }
  258. </script>
  259. @endpush