| 
									
										
										
										
											2025-07-15 11:43:28 +01:00
										 |  |  | {% extends "base.html" %} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {% block title %}Accounts - KTVManager{% endblock %} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {% block head_content %} | 
					
						
							| 
									
										
										
										
											2025-05-09 16:31:14 +01:00
										 |  |  |     <link rel="stylesheet" href="https://cdn.datatables.net/1.10.24/css/jquery.dataTables.min.css"> | 
					
						
							|  |  |  |     <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.9/css/responsive.dataTables.min.css"> | 
					
						
							| 
									
										
										
										
											2025-07-15 11:43:28 +01:00
										 |  |  | {% endblock %} | 
					
						
							| 
									
										
										
										
											2025-05-09 16:31:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 11:43:28 +01:00
										 |  |  | {% block sub_nav %} | 
					
						
							| 
									
										
										
										
											2025-05-09 16:31:14 +01:00
										 |  |  |     <!-- Sub-navigation for Accounts --> | 
					
						
							|  |  |  |     <div class="bg-light py-2"> | 
					
						
							|  |  |  |         <div class="container"> | 
					
						
							|  |  |  |             <ul class="nav nav-pills"> | 
					
						
							|  |  |  |                 <li class="nav-item"> | 
					
						
							|  |  |  |                     <a class="nav-link active" href="/accounts">List Accounts</a> | 
					
						
							|  |  |  |                 </li> | 
					
						
							|  |  |  |                 <li class="nav-item"> | 
					
						
							|  |  |  |                     <a class="nav-link" href="/accounts/add">Add Account</a> | 
					
						
							|  |  |  |                 </li> | 
					
						
							|  |  |  |             </ul> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2025-07-15 11:43:28 +01:00
										 |  |  | {% endblock %} | 
					
						
							| 
									
										
										
										
											2025-05-09 16:31:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 11:43:28 +01:00
										 |  |  | {% block content %} | 
					
						
							|  |  |  |     <h2>{{ username }}'s Accounts</h2> | 
					
						
							|  |  |  |     <div class="table-responsive"> | 
					
						
							|  |  |  |         <table class="table table-striped" id="accountsTable"> | 
					
						
							|  |  |  |             <thead> | 
					
						
							|  |  |  |                 <tr> | 
					
						
							|  |  |  |                     <!-- <th>#</th> --> | 
					
						
							|  |  |  |                     <th>Username</th> | 
					
						
							|  |  |  |                     <th>Stream</th> | 
					
						
							|  |  |  |                     <th>Stream URL</th> | 
					
						
							|  |  |  |                     <th>Expiry Date</th> | 
					
						
							|  |  |  |                     <th>Password</th> | 
					
						
							|  |  |  |                     <th>Actions</th> | 
					
						
							|  |  |  |                 </tr> | 
					
						
							|  |  |  |             </thead> | 
					
						
							|  |  |  |             <tbody> | 
					
						
							|  |  |  |                 {% for account in user_accounts %} | 
					
						
							|  |  |  |                 <tr> | 
					
						
							|  |  |  |                     <!-- <td>{{ loop.index }}</td> --> | 
					
						
							|  |  |  |                     <td>{{ account.username }}</td> | 
					
						
							|  |  |  |                     <td>{{ account.stream }}</td> | 
					
						
							| 
									
										
										
										
											2025-07-15 17:54:42 +01:00
										 |  |  |                     <td><a href="{{ account.streamURL }}" target="_blank">{{ account.streamURL }}</a> ({{ account.maxConnections }})</td> | 
					
						
							| 
									
										
										
										
											2025-07-15 11:43:28 +01:00
										 |  |  |                     <td>{{ account.expiaryDate_rendered }}</td> | 
					
						
							|  |  |  |                     <td>{{ account.password }}</td> | 
					
						
							|  |  |  |                     <td> | 
					
						
							| 
									
										
										
										
											2025-07-15 19:22:17 +01:00
										 |  |  |                         <button type="button" class="btn btn-info btn-validate" data-username="{{ account.username }}" data-password="{{ account.password }}" data-stream="{{ account.stream }}" data-stream-url="{{ account.streamURL }}" data-expiry-date="{{ account.expiaryDate }}" data-max-connections="{{ account.maxConnections }}" style="margin-right: 5px;"> | 
					
						
							| 
									
										
										
										
											2025-07-15 15:13:16 +01:00
										 |  |  |                             <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true" style="display: none;"></span> | 
					
						
							|  |  |  |                             <span class="button-text">Validate</span> | 
					
						
							|  |  |  |                         </button> | 
					
						
							| 
									
										
										
										
											2025-07-15 11:43:28 +01:00
										 |  |  |                         <form action="/accounts/delete" method="POST" style="display:inline;"> | 
					
						
							|  |  |  |                             <input type="hidden" name="stream" value="{{ account.stream }}"> | 
					
						
							|  |  |  |                             <input type="hidden" name="username" value="{{ account.username }}"> | 
					
						
							|  |  |  |                             <button type="submit" class="btn btn-danger" onclick="return confirm('Are you sure you want to delete this account?');"> | 
					
						
							|  |  |  |                                 Delete | 
					
						
							|  |  |  |                             </button> | 
					
						
							|  |  |  |                         </form> | 
					
						
							|  |  |  |                     </td> | 
					
						
							|  |  |  |                 </tr> | 
					
						
							|  |  |  |                 {% endfor %} | 
					
						
							|  |  |  |             </tbody> | 
					
						
							|  |  |  |         </table> | 
					
						
							| 
									
										
										
										
											2025-05-09 16:31:14 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2025-07-15 11:43:28 +01:00
										 |  |  | {% endblock %} | 
					
						
							| 
									
										
										
										
											2025-05-09 16:31:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 11:43:28 +01:00
										 |  |  | {% block scripts %} | 
					
						
							| 
									
										
										
										
											2025-05-09 16:31:14 +01:00
										 |  |  |     <script src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js"></script> | 
					
						
							|  |  |  |     <script src="https://cdn.datatables.net/responsive/2.2.9/js/dataTables.responsive.min.js"></script> | 
					
						
							|  |  |  |     <script> | 
					
						
							|  |  |  |         $(document).ready(function() { | 
					
						
							|  |  |  |             // Extend DataTables date sorting for DD/MM/YYYY format | 
					
						
							|  |  |  |             $.fn.dataTable.ext.type.order['date-eu-pre'] = function(data) { | 
					
						
							|  |  |  |                 const parts = data.split('/'); | 
					
						
							|  |  |  |                 // Check if the data is in the correct format before processing | 
					
						
							|  |  |  |                 if (parts.length === 3) { | 
					
						
							|  |  |  |                     return new Date(parts[2], parts[1] - 1, parts[0]).getTime(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return data; // return as is if the format is unexpected | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |             // Initialize DataTable with custom sorting and default ordering by Expiry Date | 
					
						
							|  |  |  |             $('#accountsTable').DataTable({ | 
					
						
							|  |  |  |                 "searching": true, | 
					
						
							|  |  |  |                 "ordering": true, | 
					
						
							|  |  |  |                 "responsive": true, | 
					
						
							|  |  |  |                 "order": [[3, 'asc']], // Default order by Expiry Date column in ascending order | 
					
						
							|  |  |  |                 "columnDefs": [ | 
					
						
							|  |  |  |                     { "type": "date-eu", "targets": 3 } // Use custom date-eu type for the date column | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2025-07-15 15:13:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 16:08:16 +01:00
										 |  |  |         $('#accountsTable tbody').on('click', '.btn-validate', function() { | 
					
						
							| 
									
										
										
										
											2025-07-15 15:13:16 +01:00
										 |  |  |             var button = $(this); | 
					
						
							|  |  |  |             var spinner = button.find('.spinner-border'); | 
					
						
							|  |  |  |             var buttonText = button.find('.button-text'); | 
					
						
							|  |  |  |             var username = button.data('username'); | 
					
						
							|  |  |  |             var password = button.data('password'); | 
					
						
							|  |  |  |             var stream = button.data('stream'); | 
					
						
							| 
									
										
										
										
											2025-07-15 19:22:17 +01:00
										 |  |  |             var streamURL = button.data('stream-url'); | 
					
						
							| 
									
										
										
										
											2025-07-15 16:56:43 +01:00
										 |  |  |             var expiryDate = button.data('expiry-date'); | 
					
						
							| 
									
										
										
										
											2025-07-15 17:54:42 +01:00
										 |  |  |             var maxConnections = button.data('max-connections'); | 
					
						
							| 
									
										
										
										
											2025-07-15 15:13:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             spinner.show(); | 
					
						
							|  |  |  |             buttonText.hide(); | 
					
						
							|  |  |  |             button.prop('disabled', true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             $.ajax({ | 
					
						
							|  |  |  |                 url: '/validateAccount', | 
					
						
							|  |  |  |                 type: 'POST', | 
					
						
							|  |  |  |                 contentType: 'application/json', | 
					
						
							|  |  |  |                 data: JSON.stringify({ | 
					
						
							|  |  |  |                     username: username, | 
					
						
							|  |  |  |                     password: password, | 
					
						
							| 
									
										
										
										
											2025-07-15 16:56:43 +01:00
										 |  |  |                     stream: stream, | 
					
						
							| 
									
										
										
										
											2025-07-15 19:22:17 +01:00
										 |  |  |                     streamURL: streamURL, | 
					
						
							| 
									
										
										
										
											2025-07-15 17:54:42 +01:00
										 |  |  |                     expiry_date: expiryDate, | 
					
						
							|  |  |  |                     max_connections: maxConnections | 
					
						
							| 
									
										
										
										
											2025-07-15 15:13:16 +01:00
										 |  |  |                 }), | 
					
						
							|  |  |  |                 success: function(response) { | 
					
						
							| 
									
										
										
										
											2025-07-16 09:09:05 +01:00
										 |  |  |                     spinner.hide(); | 
					
						
							|  |  |  |                     buttonText.show(); | 
					
						
							| 
									
										
										
										
											2025-07-15 17:22:23 +01:00
										 |  |  |                     if (response.message === 'Account is valid and updated') { | 
					
						
							| 
									
										
										
										
											2025-07-16 09:09:05 +01:00
										 |  |  |                         button.prop('disabled', false); | 
					
						
							|  |  |  |                         button.removeClass('btn-info').addClass('btn-success'); | 
					
						
							|  |  |  |                         buttonText.text('Valid & Updated'); | 
					
						
							|  |  |  |                         setTimeout(function() { | 
					
						
							|  |  |  |                             button.removeClass('btn-success').addClass('btn-info'); | 
					
						
							|  |  |  |                             buttonText.text('Validate'); | 
					
						
							|  |  |  |                         }, 3000); | 
					
						
							| 
									
										
										
										
											2025-07-15 17:22:23 +01:00
										 |  |  |                     } else { | 
					
						
							|  |  |  |                         button.prop('disabled', false); | 
					
						
							|  |  |  |                         button.removeClass('btn-info').addClass('btn-success'); | 
					
						
							|  |  |  |                         buttonText.text('Valid'); | 
					
						
							|  |  |  |                         setTimeout(function() { | 
					
						
							|  |  |  |                             button.removeClass('btn-success').addClass('btn-info'); | 
					
						
							|  |  |  |                             buttonText.text('Validate'); | 
					
						
							|  |  |  |                         }, 3000); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2025-07-15 15:13:16 +01:00
										 |  |  |                 }, | 
					
						
							|  |  |  |                 error: function(xhr, status, error) { | 
					
						
							|  |  |  |                     spinner.hide(); | 
					
						
							|  |  |  |                     buttonText.show(); | 
					
						
							|  |  |  |                     button.prop('disabled', false); | 
					
						
							|  |  |  |                     button.removeClass('btn-info').addClass('btn-danger'); | 
					
						
							|  |  |  |                     buttonText.text('Invalid'); | 
					
						
							|  |  |  |                     setTimeout(function() { | 
					
						
							|  |  |  |                         button.removeClass('btn-danger').addClass('btn-info'); | 
					
						
							|  |  |  |                         buttonText.text('Validate'); | 
					
						
							|  |  |  |                     }, 3000); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2025-05-09 16:31:14 +01:00
										 |  |  |     </script> | 
					
						
							| 
									
										
										
										
											2025-07-15 11:43:28 +01:00
										 |  |  | {% endblock %} |