media-page.php 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. <?php
  2. /**
  3. * Admin Media Page for QDR Temporary Shared Storage
  4. *
  5. * @package QDR_Temporary_Shared_Storage
  6. */
  7. // If this file is called directly, abort.
  8. if (!defined('WPINC')) {
  9. die;
  10. }
  11. /**
  12. * Render the Media | Shared Storage admin page
  13. */
  14. function qdr_tss_render_media_page() {
  15. // Get current settings
  16. $settings = get_option('qdr_tss_settings', array(
  17. 'api_key' => '',
  18. 'media_category' => 'shared-storage',
  19. 'max_upload_size' => 1073741824, // 1GB default
  20. ));
  21. // Get total storage usage
  22. global $wpdb;
  23. $table_name = $wpdb->prefix . QDR_TSS_PLUGIN_TABLE;
  24. $total_size = $wpdb->get_var("SELECT SUM(file_size) FROM $table_name");
  25. $total_size = $total_size ? intval($total_size) : 0;
  26. $max_size = isset($settings['max_upload_size']) ? intval($settings['max_upload_size']) : 1073741824;
  27. $usage_percent = ($max_size > 0) ? min(100, ($total_size / $max_size) * 100) : 0;
  28. ?>
  29. <div class="wrap qdr-tss-admin">
  30. <h1><?php esc_html_e('Shared Storage', 'qdr-temporary-shared-storage'); ?></h1>
  31. <div class="qdr-tss-storage-summary">
  32. <h2><?php esc_html_e('Storage Usage', 'qdr-temporary-shared-storage'); ?></h2>
  33. <div class="qdr-tss-storage-bar">
  34. <div class="qdr-tss-storage-used" style="width: <?php echo esc_attr($usage_percent); ?>%"></div>
  35. </div>
  36. <p>
  37. <?php echo esc_html(qdr_tss_format_bytes($total_size)); ?> / <?php echo esc_html(qdr_tss_format_bytes($max_size)); ?>
  38. (<?php echo number_format($usage_percent, 1); ?>%)
  39. </p>
  40. </div>
  41. <div class="qdr-tss-toolbar">
  42. <div class="qdr-tss-search">
  43. <input type="text" id="qdr-tss-search-filename" placeholder="<?php esc_attr_e('Search by filename', 'qdr-temporary-shared-storage'); ?>">
  44. <input type="text" id="qdr-tss-search-reference" placeholder="<?php esc_attr_e('Search by reference', 'qdr-temporary-shared-storage'); ?>">
  45. <button class="button" id="qdr-tss-search-button">
  46. <span class="dashicons dashicons-search"></span> <?php esc_html_e('Search', 'qdr-temporary-shared-storage'); ?>
  47. </button>
  48. <button class="button" id="qdr-tss-reset-search">
  49. <span class="dashicons dashicons-dismiss"></span> <?php esc_html_e('Reset', 'qdr-temporary-shared-storage'); ?>
  50. </button>
  51. </div>
  52. <div class="qdr-tss-actions">
  53. <button class="button button-primary" id="qdr-tss-refresh">
  54. <span class="dashicons dashicons-update"></span> <?php esc_html_e('Refresh', 'qdr-temporary-shared-storage'); ?>
  55. </button>
  56. </div>
  57. </div>
  58. <div class="qdr-tss-table-container">
  59. <table class="wp-list-table widefat fixed striped qdr-tss-table">
  60. <thead>
  61. <tr>
  62. <th class="column-media-id sortable" data-sort="media_id"><?php esc_html_e('Media ID', 'qdr-temporary-shared-storage'); ?> <span class="sorting-indicator"></span></th>
  63. <th class="column-filename sortable" data-sort="original_file_name"><?php esc_html_e('File Name', 'qdr-temporary-shared-storage'); ?> <span class="sorting-indicator"></span></th>
  64. <th class="column-description"><?php esc_html_e('Description', 'qdr-temporary-shared-storage'); ?></th>
  65. <th class="column-message"><?php esc_html_e('Message', 'qdr-temporary-shared-storage'); ?></th>
  66. <th class="column-active-from sortable" data-sort="active_from"><?php esc_html_e('Active From', 'qdr-temporary-shared-storage'); ?> <span class="sorting-indicator"></span></th>
  67. <th class="column-active-to sortable" data-sort="active_to"><?php esc_html_e('Active To', 'qdr-temporary-shared-storage'); ?> <span class="sorting-indicator"></span></th>
  68. <th class="column-reference sortable" data-sort="reference"><?php esc_html_e('Reference', 'qdr-temporary-shared-storage'); ?> <span class="sorting-indicator"></span></th>
  69. <th class="column-upload-date sortable" data-sort="upload_date"><?php esc_html_e('Upload Date', 'qdr-temporary-shared-storage'); ?> <span class="sorting-indicator"></span></th>
  70. <th class="column-download-count sortable" data-sort="download_count"><?php esc_html_e('Downloads', 'qdr-temporary-shared-storage'); ?> <span class="sorting-indicator"></span></th>
  71. <th class="column-last-download sortable" data-sort="last_download"><?php esc_html_e('Last Download', 'qdr-temporary-shared-storage'); ?> <span class="sorting-indicator"></span></th>
  72. <th class="column-actions"><?php esc_html_e('Actions', 'qdr-temporary-shared-storage'); ?></th>
  73. </tr>
  74. </thead>
  75. <tbody id="qdr-tss-items-list">
  76. <tr>
  77. <td colspan="11" class="qdr-tss-loading">
  78. <span class="spinner is-active"></span> <?php esc_html_e('Loading...', 'qdr-temporary-shared-storage'); ?>
  79. </td>
  80. </tr>
  81. </tbody>
  82. </table>
  83. </div>
  84. <div class="qdr-tss-pagination">
  85. <div class="qdr-tss-pagination-info"></div>
  86. <div class="qdr-tss-pagination-controls"></div>
  87. </div>
  88. </div>
  89. <!-- Edit Item Modal -->
  90. <div id="qdr-tss-edit-modal" class="qdr-tss-modal">
  91. <div class="qdr-tss-modal-content">
  92. <span class="qdr-tss-modal-close">&times;</span>
  93. <h2><?php esc_html_e('Edit Shared File', 'qdr-temporary-shared-storage'); ?></h2>
  94. <form id="qdr-tss-edit-form">
  95. <input type="hidden" id="qdr-tss-edit-id" name="id">
  96. <div class="qdr-tss-form-row">
  97. <label for="qdr-tss-edit-description"><?php esc_html_e('Description', 'qdr-temporary-shared-storage'); ?></label>
  98. <textarea id="qdr-tss-edit-description" name="description" rows="3"></textarea>
  99. </div>
  100. <div class="qdr-tss-form-row">
  101. <label for="qdr-tss-edit-message"><?php esc_html_e('Message', 'qdr-temporary-shared-storage'); ?></label>
  102. <textarea id="qdr-tss-edit-message" name="message" rows="3"></textarea>
  103. </div>
  104. <div class="qdr-tss-form-row">
  105. <label for="qdr-tss-edit-active-from"><?php esc_html_e('Active From', 'qdr-temporary-shared-storage'); ?></label>
  106. <input type="text" id="qdr-tss-edit-active-from" name="active_from" class="qdr-tss-datepicker" autocomplete="off">
  107. </div>
  108. <div class="qdr-tss-form-row">
  109. <label for="qdr-tss-edit-active-to"><?php esc_html_e('Active To', 'qdr-temporary-shared-storage'); ?></label>
  110. <input type="text" id="qdr-tss-edit-active-to" name="active_to" class="qdr-tss-datepicker" autocomplete="off">
  111. </div>
  112. <div class="qdr-tss-form-row">
  113. <label for="qdr-tss-edit-reference"><?php esc_html_e('Reference', 'qdr-temporary-shared-storage'); ?></label>
  114. <input type="text" id="qdr-tss-edit-reference" name="reference">
  115. </div>
  116. <div class="qdr-tss-form-actions">
  117. <button type="submit" class="button button-primary"><?php esc_html_e('Save Changes', 'qdr-temporary-shared-storage'); ?></button>
  118. <button type="button" class="button qdr-tss-modal-cancel"><?php esc_html_e('Cancel', 'qdr-temporary-shared-storage'); ?></button>
  119. </div>
  120. </form>
  121. <div id="qdr-tss-edit-status"></div>
  122. </div>
  123. </div>
  124. <!-- View Details Modal -->
  125. <div id="qdr-tss-details-modal" class="qdr-tss-modal">
  126. <div class="qdr-tss-modal-content">
  127. <span class="qdr-tss-modal-close">&times;</span>
  128. <h2><?php esc_html_e('File Details', 'qdr-temporary-shared-storage'); ?></h2>
  129. <div class="qdr-tss-details-content">
  130. <table class="widefat striped">
  131. <tr>
  132. <th><?php esc_html_e('Media ID', 'qdr-temporary-shared-storage'); ?></th>
  133. <td id="qdr-tss-details-media-id"></td>
  134. </tr>
  135. <tr>
  136. <th><?php esc_html_e('File Name', 'qdr-temporary-shared-storage'); ?></th>
  137. <td id="qdr-tss-details-filename"></td>
  138. </tr>
  139. <tr>
  140. <th><?php esc_html_e('Description', 'qdr-temporary-shared-storage'); ?></th>
  141. <td id="qdr-tss-details-description"></td>
  142. </tr>
  143. <tr>
  144. <th><?php esc_html_e('Message', 'qdr-temporary-shared-storage'); ?></th>
  145. <td id="qdr-tss-details-message"></td>
  146. </tr>
  147. <tr>
  148. <th><?php esc_html_e('Reference', 'qdr-temporary-shared-storage'); ?></th>
  149. <td id="qdr-tss-details-reference"></td>
  150. </tr>
  151. <tr>
  152. <th><?php esc_html_e('Active Period', 'qdr-temporary-shared-storage'); ?></th>
  153. <td id="qdr-tss-details-active-period"></td>
  154. </tr>
  155. <tr>
  156. <th><?php esc_html_e('File Size', 'qdr-temporary-shared-storage'); ?></th>
  157. <td id="qdr-tss-details-filesize"></td>
  158. </tr>
  159. <tr>
  160. <th><?php esc_html_e('Download Count', 'qdr-temporary-shared-storage'); ?></th>
  161. <td id="qdr-tss-details-download-count"></td>
  162. </tr>
  163. <tr>
  164. <th><?php esc_html_e('Last Download', 'qdr-temporary-shared-storage'); ?></th>
  165. <td id="qdr-tss-details-last-download"></td>
  166. </tr>
  167. <tr>
  168. <th><?php esc_html_e('Permalink', 'qdr-temporary-shared-storage'); ?></th>
  169. <td id="qdr-tss-details-permalink"></td>
  170. </tr>
  171. <tr>
  172. <th><?php esc_html_e('Shortcode', 'qdr-temporary-shared-storage'); ?></th>
  173. <td id="qdr-tss-details-shortcode"></td>
  174. </tr>
  175. </table>
  176. </div>
  177. <div class="qdr-tss-form-actions">
  178. <button type="button" class="button button-secondary qdr-tss-copy-shortcode"><?php esc_html_e('Copy Shortcode', 'qdr-temporary-shared-storage'); ?></button>
  179. <button type="button" class="button button-secondary qdr-tss-copy-permalink"><?php esc_html_e('Copy Permalink', 'qdr-temporary-shared-storage'); ?></button>
  180. <button type="button" class="button qdr-tss-modal-cancel"><?php esc_html_e('Close', 'qdr-temporary-shared-storage'); ?></button>
  181. </div>
  182. </div>
  183. </div>
  184. <!-- Confirm Delete Modal -->
  185. <div id="qdr-tss-confirm-delete-modal" class="qdr-tss-modal">
  186. <div class="qdr-tss-modal-content qdr-tss-modal-sm">
  187. <span class="qdr-tss-modal-close">&times;</span>
  188. <h2><?php esc_html_e('Confirm Delete', 'qdr-temporary-shared-storage'); ?></h2>
  189. <p><?php esc_html_e('Are you sure you want to delete this file? This action cannot be undone.', 'qdr-temporary-shared-storage'); ?></p>
  190. <div class="qdr-tss-form-actions">
  191. <button type="button" class="button button-primary qdr-tss-confirm-delete-button"><?php esc_html_e('Delete', 'qdr-temporary-shared-storage'); ?></button>
  192. <button type="button" class="button qdr-tss-modal-cancel"><?php esc_html_e('Cancel', 'qdr-temporary-shared-storage'); ?></button>
  193. </div>
  194. <input type="hidden" id="qdr-tss-delete-id">
  195. </div>
  196. </div>
  197. <script type="text/javascript">
  198. jQuery(document).ready(function($) {
  199. var currentPage = 1;
  200. var perPage = 10;
  201. var totalPages = 1;
  202. var currentOrderBy = 'upload_date';
  203. var currentOrder = 'DESC';
  204. var currentSearchFilename = '';
  205. var currentSearchReference = '';
  206. // Load items
  207. function loadItems() {
  208. var data = {
  209. action: 'qdr_tss_get_items',
  210. nonce: qdr_tss.nonce,
  211. page: currentPage,
  212. per_page: perPage,
  213. orderby: currentOrderBy,
  214. order: currentOrder,
  215. original_file_name: currentSearchFilename,
  216. reference: currentSearchReference
  217. };
  218. // Show loading indicator
  219. $('#qdr-tss-items-list').html('<tr><td colspan="11" class="qdr-tss-loading"><span class="spinner is-active"></span> <?php esc_html_e('Loading...', 'qdr-temporary-shared-storage'); ?></td></tr>');
  220. $.post(ajaxurl, data, function(response) {
  221. if (response.success) {
  222. renderItems(response.data.items);
  223. renderPagination(response.data.total, response.data.total_pages);
  224. } else {
  225. alert(response.data.message || '<?php esc_html_e('Error loading items.', 'qdr-temporary-shared-storage'); ?>');
  226. }
  227. }).fail(function() {
  228. $('#qdr-tss-items-list').html('<tr><td colspan="11"><?php esc_html_e('Error loading items. Please try again.', 'qdr-temporary-shared-storage'); ?></td></tr>');
  229. });
  230. }
  231. // Render items
  232. function renderItems(items) {
  233. var $tbody = $('#qdr-tss-items-list');
  234. $tbody.empty();
  235. if (!items || items.length === 0) {
  236. $tbody.append('<tr><td colspan="11"><?php esc_html_e('No items found.', 'qdr-temporary-shared-storage'); ?></td></tr>');
  237. return;
  238. }
  239. $.each(items, function(index, item) {
  240. var statusClass = '';
  241. var now = new Date();
  242. var activeFrom = new Date(item.active_from);
  243. var activeTo = new Date(item.active_to);
  244. if (now < activeFrom) {
  245. statusClass = 'qdr-tss-status-pending';
  246. } else if (now > activeTo) {
  247. statusClass = 'qdr-tss-status-expired';
  248. } else {
  249. statusClass = 'qdr-tss-status-active';
  250. }
  251. var row = '<tr data-id="' + item.id + '" class="' + statusClass + '">';
  252. row += '<td>' + item.media_id + '</td>';
  253. row += '<td>' + escapeHtml(item.original_file_name) + '</td>';
  254. row += '<td>' + escapeHtml(item.description || '') + '</td>';
  255. row += '<td>' + escapeHtml(item.message || '') + '</td>';
  256. row += '<td>' + formatDate(item.active_from) + '</td>';
  257. row += '<td>' + formatDate(item.active_to) + '</td>';
  258. row += '<td>' + escapeHtml(item.reference || '') + '</td>';
  259. row += '<td>' + formatDate(item.upload_date) + '</td>';
  260. row += '<td>' + item.download_count + '</td>';
  261. row += '<td>' + (item.last_download ? formatDate(item.last_download) : '-') + '</td>';
  262. row += '<td class="column-actions">';
  263. row += '<div class="qdr-tss-action-buttons">';
  264. row += '<button class="button qdr-tss-view-button" data-id="' + item.id + '" title="<?php esc_attr_e('View Details', 'qdr-temporary-shared-storage'); ?>"><span class="dashicons dashicons-visibility"></span></button>';
  265. row += '<button class="button qdr-tss-edit-button" data-id="' + item.id + '" title="<?php esc_attr_e('Edit', 'qdr-temporary-shared-storage'); ?>"><span class="dashicons dashicons-edit"></span></button>';
  266. row += '<button class="button qdr-tss-delete-button" data-id="' + item.id + '" title="<?php esc_attr_e('Delete', 'qdr-temporary-shared-storage'); ?>"><span class="dashicons dashicons-trash"></span></button>';
  267. row += '</div>';
  268. row += '</td>';
  269. row += '</tr>';
  270. $tbody.append(row);
  271. });
  272. // Initialize action buttons
  273. initActionButtons();
  274. // Update sorting indicators
  275. updateSortIndicators();
  276. }
  277. // Initialize action buttons
  278. function initActionButtons() {
  279. // View button
  280. $('.qdr-tss-view-button').on('click', function() {
  281. var id = $(this).data('id');
  282. viewItem(id);
  283. });
  284. // Edit button
  285. $('.qdr-tss-edit-button').on('click', function() {
  286. var id = $(this).data('id');
  287. editItem(id);
  288. });
  289. // Delete button
  290. $('.qdr-tss-delete-button').on('click', function() {
  291. var id = $(this).data('id');
  292. showDeleteConfirmation(id);
  293. });
  294. }
  295. // Format date
  296. function formatDate(dateString) {
  297. if (!dateString || dateString === '0000-00-00 00:00:00') {
  298. return '-';
  299. }
  300. var date = new Date(dateString);
  301. // Check if date is valid
  302. if (isNaN(date.getTime())) {
  303. return dateString;
  304. }
  305. return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
  306. }
  307. // Format file size
  308. function formatFileSize(bytes) {
  309. if (bytes === 0) return '0 Bytes';
  310. var k = 1024;
  311. var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
  312. var i = Math.floor(Math.log(bytes) / Math.log(k));
  313. return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
  314. }
  315. // Escape HTML
  316. function escapeHtml(text) {
  317. if (!text) return '';
  318. var map = {
  319. '&': '&amp;',
  320. '<': '&lt;',
  321. '>': '&gt;',
  322. '"': '&quot;',
  323. "'": '&#039;'
  324. };
  325. return text.toString().replace(/[&<>"']/g, function(m) { return map[m]; });
  326. }
  327. // Render pagination
  328. function renderPagination(total, totalPages) {
  329. var $info = $('.qdr-tss-pagination-info');
  330. var $controls = $('.qdr-tss-pagination-controls');
  331. // Update info
  332. var startItem = (currentPage - 1) * perPage + 1;
  333. var endItem = Math.min(currentPage * perPage, total);
  334. if (total === 0) {
  335. $info.html('<?php esc_html_e('No items', 'qdr-temporary-shared-storage'); ?>');
  336. $controls.empty();
  337. return;
  338. }
  339. $info.html('<?php esc_html_e('Showing', 'qdr-temporary-shared-storage'); ?> ' + startItem + ' - ' + endItem + ' <?php esc_html_e('of', 'qdr-temporary-shared-storage'); ?> ' + total);
  340. // Update controls
  341. $controls.empty();
  342. if (totalPages <= 1) {
  343. return;
  344. }
  345. // First page
  346. if (currentPage > 1) {
  347. $controls.append('<button class="button qdr-tss-page-button" data-page="1" title="<?php esc_attr_e('First Page', 'qdr-temporary-shared-storage'); ?>">&laquo;</button>');
  348. }
  349. // Previous page
  350. if (currentPage > 1) {
  351. $controls.append('<button class="button qdr-tss-page-button" data-page="' + (currentPage - 1) + '" title="<?php esc_attr_e('Previous Page', 'qdr-temporary-shared-storage'); ?>">&lsaquo;</button>');
  352. }
  353. // Page numbers
  354. var startPage = Math.max(1, currentPage - 2);
  355. var endPage = Math.min(totalPages, startPage + 4);
  356. if (endPage - startPage < 4) {
  357. startPage = Math.max(1, endPage - 4);
  358. }
  359. for (var i = startPage; i <= endPage; i++) {
  360. var activeClass = i === currentPage ? 'button-primary' : '';
  361. $controls.append('<button class="button qdr-tss-page-button ' + activeClass + '" data-page="' + i + '">' + i + '</button>');
  362. }
  363. // Next page
  364. if (currentPage < totalPages) {
  365. $controls.append('<button class="button qdr-tss-page-button" data-page="' + (currentPage + 1) + '" title="<?php esc_attr_e('Next Page', 'qdr-temporary-shared-storage'); ?>">&rsaquo;</button>');
  366. }
  367. // Last page
  368. if (currentPage < totalPages) {
  369. $controls.append('<button class="button qdr-tss-page-button" data-page="' + totalPages + '" title="<?php esc_attr_e('Last Page', 'qdr-temporary-shared-storage'); ?>">&raquo;</button>');
  370. }
  371. // Bind click event to page buttons
  372. $('.qdr-tss-page-button').on('click', function() {
  373. currentPage = parseInt($(this).data('page'));
  374. loadItems();
  375. });
  376. }
  377. // Update sort indicators
  378. function updateSortIndicators() {
  379. // Remove all indicators
  380. $('.qdr-tss-table th').removeClass('sorted asc desc');
  381. // Add indicator to current sort column
  382. var $th = $('.qdr-tss-table th[data-sort="' + currentOrderBy + '"]');
  383. $th.addClass('sorted ' + currentOrder.toLowerCase());
  384. }
  385. // View item details
  386. function viewItem(id) {
  387. // Find item in the table
  388. var $row = $('tr[data-id="' + id + '"]');
  389. if ($row.length === 0) return;
  390. var $cells = $row.find('td');
  391. var mediaId = $cells.eq(0).text();
  392. var fileName = $cells.eq(1).text();
  393. var description = $cells.eq(2).text();
  394. var message = $cells.eq(3).text();
  395. var activeFrom = $cells.eq(4).text();
  396. var activeTo = $cells.eq(5).text();
  397. var reference = $cells.eq(6).text();
  398. var uploadDate = $cells.eq(7).text();
  399. var downloadCount = $cells.eq(8).text();
  400. var lastDownload = $cells.eq(9).text();
  401. // Get additional data via AJAX
  402. var data = {
  403. action: 'qdr_tss_get_item_details',
  404. nonce: qdr_tss.nonce,
  405. id: id,
  406. media_id: mediaId
  407. };
  408. $.post(ajaxurl, data, function(response) {
  409. if (response.success) {
  410. var item = response.data.item;
  411. // Populate details
  412. $('#qdr-tss-details-media-id').text(mediaId);
  413. $('#qdr-tss-details-filename').text(fileName);
  414. $('#qdr-tss-details-description').text(description || '-');
  415. $('#qdr-tss-details-message').text(message || '-');
  416. $('#qdr-tss-details-reference').text(reference || '-');
  417. $('#qdr-tss-details-active-period').text(activeFrom + ' - ' + activeTo);
  418. $('#qdr-tss-details-filesize').text(formatFileSize(item.file_size));
  419. $('#qdr-tss-details-download-count').text(downloadCount);
  420. $('#qdr-tss-details-last-download').text(lastDownload);
  421. // Permalink and shortcode
  422. var permalink = '<?php echo esc_url(site_url('shared-file-download/')); ?>' + mediaId;
  423. var shortcode = '[qdr_tss_download id="' + mediaId + '"]';
  424. $('#qdr-tss-details-permalink').html('<a href="' + permalink + '" target="_blank">' + permalink + '</a>');
  425. $('#qdr-tss-details-shortcode').html('<code>' + shortcode + '</code>');
  426. // Show modal
  427. $('#qdr-tss-details-modal').show();
  428. } else {
  429. alert(response.data.message || '<?php esc_html_e('Error loading item details.', 'qdr-temporary-shared-storage'); ?>');
  430. }
  431. }).fail(function() {
  432. alert('<?php esc_html_e('Error loading item details. Please try again.', 'qdr-temporary-shared-storage'); ?>');
  433. });
  434. }
  435. // Edit item
  436. function editItem(id) {
  437. // Find item in the table
  438. var $row = $('tr[data-id="' + id + '"]');
  439. if ($row.length === 0) return;
  440. var $cells = $row.find('td');
  441. // Populate form fields
  442. $('#qdr-tss-edit-id').val(id);
  443. $('#qdr-tss-edit-description').val($cells.eq(2).text());
  444. $('#qdr-tss-edit-message').val($cells.eq(3).text());
  445. // Parse dates for datepicker
  446. var activeFrom = $cells.eq(4).text();
  447. var activeTo = $cells.eq(5).text();
  448. $('#qdr-tss-edit-active-from').val(activeFrom !== '-' ? activeFrom : '');
  449. $('#qdr-tss-edit-active-to').val(activeTo !== '-' ? activeTo : '');
  450. $('#qdr-tss-edit-reference').val($cells.eq(6).text());
  451. // Clear status
  452. $('#qdr-tss-edit-status').html('');
  453. // Show modal
  454. $('#qdr-tss-edit-modal').show();
  455. // Initialize datepickers
  456. $('.qdr-tss-datepicker').datepicker({
  457. dateFormat: 'yy-mm-dd',
  458. changeMonth: true,
  459. changeYear: true
  460. });
  461. }
  462. // Show delete confirmation
  463. function showDeleteConfirmation(id) {
  464. $('#qdr-tss-delete-id').val(id);
  465. $('#qdr-tss-confirm-delete-modal').show();
  466. }
  467. // Delete item
  468. function deleteItem(id) {
  469. var data = {
  470. action: 'qdr_tss_delete_item',
  471. nonce: qdr_tss.nonce,
  472. id: id
  473. };
  474. $.post(ajaxurl, data, function(response) {
  475. if (response.success) {
  476. // Hide modal
  477. $('#qdr-tss-confirm-delete-modal').hide();
  478. // Show success message
  479. alert(response.data.message || '<?php esc_html_e('File deleted successfully.', 'qdr-temporary-shared-storage'); ?>');
  480. // Reload items
  481. loadItems();
  482. } else {
  483. alert(response.data.message || '<?php esc_html_e('Error deleting file.', 'qdr-temporary-shared-storage'); ?>');
  484. }
  485. }).fail(function() {
  486. alert('<?php esc_html_e('Error deleting file. Please try again.', 'qdr-temporary-shared-storage'); ?>');
  487. });
  488. }
  489. // Copy text to clipboard
  490. function copyToClipboard(text) {
  491. var $temp = $('<input>');
  492. $('body').append($temp);
  493. $temp.val(text).select();
  494. document.execCommand('copy');
  495. $temp.remove();
  496. }
  497. // Handle form submission
  498. $('#qdr-tss-edit-form').on('submit', function(e) {
  499. e.preventDefault();
  500. // Show loading status
  501. $('#qdr-tss-edit-status').html('<div class="qdr-tss-loading"><span class="spinner is-active"></span> <?php esc_html_e('Saving...', 'qdr-temporary-shared-storage'); ?></div>');
  502. var data = {
  503. action: 'qdr_tss_edit_item',
  504. nonce: qdr_tss.nonce,
  505. id: $('#qdr-tss-edit-id').val(),
  506. description: $('#qdr-tss-edit-description').val(),
  507. message: $('#qdr-tss-edit-message').val(),
  508. active_from: $('#qdr-tss-edit-active-from').val(),
  509. active_to: $('#qdr-tss-edit-active-to').val(),
  510. reference: $('#qdr-tss-edit-reference').val()
  511. };
  512. $.post(ajaxurl, data, function(response) {
  513. if (response.success) {
  514. // Show success status
  515. $('#qdr-tss-edit-status').html('<div class="notice notice-success inline"><p>' + (response.data.message || '<?php esc_html_e('Changes saved successfully.', 'qdr-temporary-shared-storage'); ?>') + '</p></div>');
  516. // Hide modal after a delay
  517. setTimeout(function() {
  518. $('#qdr-tss-edit-modal').hide();
  519. // Reload items
  520. loadItems();
  521. }, 1000);
  522. } else {
  523. // Show error status
  524. $('#qdr-tss-edit-status').html('<div class="notice notice-error inline"><p>' + (response.data.message || '<?php esc_html_e('Error saving changes.', 'qdr-temporary-shared-storage'); ?>') + '</p></div>');
  525. }
  526. }).fail(function() {
  527. // Show error status
  528. $('#qdr-tss-edit-status').html('<div class="notice notice-error inline"><p><?php esc_html_e('Error saving changes. Please try again.', 'qdr-temporary-shared-storage'); ?></p></div>');
  529. });
  530. });
  531. // Handle sorting
  532. $('.qdr-tss-table th.sortable').on('click', function() {
  533. var column = $(this).data('sort');
  534. if (currentOrderBy === column) {
  535. currentOrder = currentOrder === 'ASC' ? 'DESC' : 'ASC';
  536. } else {
  537. currentOrderBy = column;
  538. currentOrder = 'ASC';
  539. }
  540. loadItems();
  541. });
  542. // Handle search
  543. $('#qdr-tss-search-button').on('click', function() {
  544. currentSearchFilename = $('#qdr-tss-search-filename').val();
  545. currentSearchReference = $('#qdr-tss-search-reference').val();
  546. currentPage = 1;
  547. loadItems();
  548. });
  549. // Handle search reset
  550. $('#qdr-tss-reset-search').on('click', function() {
  551. $('#qdr-tss-search-filename').val('');
  552. $('#qdr-tss-search-reference').val('');
  553. currentSearchFilename = '';
  554. currentSearchReference = '';
  555. currentPage = 1;
  556. loadItems();
  557. });
  558. // Handle refresh button
  559. $('#qdr-tss-refresh').on('click', function() {
  560. loadItems();
  561. });
  562. // Handle modal close
  563. $('.qdr-tss-modal-close, .qdr-tss-modal-cancel').on('click', function() {
  564. $('.qdr-tss-modal').hide();
  565. });
  566. // Close modal when clicking outside
  567. $(window).on('click', function(e) {
  568. if ($(e.target).hasClass('qdr-tss-modal')) {
  569. $('.qdr-tss-modal').hide();
  570. }
  571. });
  572. // Handle copy shortcode
  573. $('.qdr-tss-copy-shortcode').on('click', function() {
  574. var shortcode = $('#qdr-tss-details-shortcode code').text();
  575. copyToClipboard(shortcode);
  576. alert('<?php esc_html_e('Shortcode copied to clipboard.', 'qdr-temporary-shared-storage'); ?>');
  577. });
  578. // Handle copy permalink
  579. $('.qdr-tss-copy-permalink').on('click', function() {
  580. var permalink = $('#qdr-tss-details-permalink a').attr('href');
  581. copyToClipboard(permalink);
  582. alert('<?php esc_html_e('Permalink copied to clipboard.', 'qdr-temporary-shared-storage'); ?>');
  583. });
  584. // Handle confirm delete
  585. $('.qdr-tss-confirm-delete-button').on('click', function() {
  586. var id = $('#qdr-tss-delete-id').val();
  587. deleteItem(id);
  588. });
  589. // Initial load
  590. loadItems();
  591. });
  592. </script>
  593. <?php
  594. }