view.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // HokoriTemp - JavaScript para la página de vista
  2. // DOM Elements
  3. const linksContainer = document.getElementById('linksContainer');
  4. const emptyState = document.getElementById('emptyState');
  5. const loadingState = document.getElementById('loadingState');
  6. // Load links on page load
  7. document.addEventListener('DOMContentLoaded', loadLinks);
  8. function loadLinks() {
  9. const links = JSON.parse(localStorage.getItem('tempFileLinks') || '[]');
  10. // Filter expired links
  11. const currentTime = new Date();
  12. const validLinks = links.filter(link => {
  13. const expiresAt = new Date(link.expiresAt);
  14. return expiresAt > currentTime;
  15. });
  16. // Update localStorage with only valid links
  17. localStorage.setItem('tempFileLinks', JSON.stringify(validLinks));
  18. // Hide loading
  19. loadingState.classList.add('hidden');
  20. if (validLinks.length === 0) {
  21. showEmptyState();
  22. } else {
  23. showLinks(validLinks);
  24. }
  25. }
  26. function showEmptyState() {
  27. emptyState.classList.remove('hidden');
  28. }
  29. function showLinks(links) {
  30. const linksHTML = links.map(link => createLinkCard(link)).join('');
  31. linksContainer.innerHTML = linksHTML;
  32. }
  33. function createLinkCard(link) {
  34. const createdAt = new Date(link.createdAt);
  35. const expiresAt = new Date(link.expiresAt);
  36. const timeLeft = getTimeLeft(expiresAt);
  37. const isExpired = expiresAt <= new Date();
  38. return `
  39. <div class="bg-white rounded-lg shadow-lg p-6 mb-4 ${isExpired ? 'opacity-50' : ''}">
  40. <div class="flex items-start justify-between">
  41. <div class="flex-1">
  42. <div class="flex items-center space-x-3">
  43. <svg class="h-8 w-8 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  44. <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
  45. </svg>
  46. <div>
  47. <h3 class="text-lg font-medium text-gray-900">${link.filename}</h3>
  48. <p class="text-sm text-gray-500">Creado: ${formatDate(createdAt)}</p>
  49. </div>
  50. </div>
  51. <div class="mt-4">
  52. <div class="flex items-center space-x-2">
  53. <span class="text-sm text-gray-500">Enlace:</span>
  54. <input type="text" value="${link.url}" class="flex-1 px-3 py-1 text-sm border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500" readonly>
  55. <button onclick="copyLink('${link.url}')" class="px-3 py-1 text-sm bg-blue-600 text-white rounded hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
  56. Copiar
  57. </button>
  58. </div>
  59. </div>
  60. <div class="mt-3 flex items-center justify-between">
  61. <div class="flex items-center space-x-4">
  62. <span class="text-sm text-gray-500">
  63. ${isExpired ? 'Expirado' : `Expira en: ${timeLeft}`}
  64. </span>
  65. ${isExpired ? '' : `
  66. <button onclick="openLink('${link.url}')" class="text-sm text-blue-600 hover:text-blue-800 underline">
  67. Abrir enlace
  68. </button>
  69. `}
  70. </div>
  71. <button onclick="removeLink('${link.id}')" class="text-sm text-red-600 hover:text-red-800 underline">
  72. Eliminar
  73. </button>
  74. </div>
  75. </div>
  76. </div>
  77. </div>
  78. `;
  79. }
  80. function getTimeLeft(expiresAt) {
  81. const now = new Date();
  82. const diff = expiresAt - now;
  83. if (diff <= 0) return 'Expirado';
  84. const hours = Math.floor(diff / (1000 * 60 * 60));
  85. const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
  86. if (hours > 0) {
  87. return `${hours}h ${minutes}m`;
  88. } else {
  89. return `${minutes}m`;
  90. }
  91. }
  92. function formatDate(date) {
  93. return date.toLocaleString('es-ES', {
  94. year: 'numeric',
  95. month: 'short',
  96. day: 'numeric',
  97. hour: '2-digit',
  98. minute: '2-digit'
  99. });
  100. }
  101. function copyLink(url) {
  102. navigator.clipboard.writeText(url).then(() => {
  103. // Show feedback
  104. const button = event.target;
  105. const originalText = button.textContent;
  106. button.textContent = '¡Copiado!';
  107. setTimeout(() => {
  108. button.textContent = originalText;
  109. }, 2000);
  110. // Show notification
  111. showNotification('Enlace copiado al portapapeles', 'success');
  112. }).catch(() => {
  113. // Fallback for older browsers
  114. const textArea = document.createElement('textarea');
  115. textArea.value = url;
  116. document.body.appendChild(textArea);
  117. textArea.select();
  118. document.execCommand('copy');
  119. document.body.removeChild(textArea);
  120. const button = event.target;
  121. const originalText = button.textContent;
  122. button.textContent = '¡Copiado!';
  123. setTimeout(() => {
  124. button.textContent = originalText;
  125. }, 2000);
  126. showNotification('Enlace copiado al portapapeles', 'success');
  127. });
  128. }
  129. function openLink(url) {
  130. window.open(url, '_blank');
  131. }
  132. function removeLink(linkId) {
  133. const links = JSON.parse(localStorage.getItem('tempFileLinks') || '[]');
  134. const updatedLinks = links.filter(link => link.id !== linkId);
  135. localStorage.setItem('tempFileLinks', JSON.stringify(updatedLinks));
  136. // Reload the page to update the display
  137. location.reload();
  138. }
  139. // Función para mostrar notificaciones
  140. function showNotification(message, type = 'info') {
  141. // Crear elemento de notificación
  142. const notification = document.createElement('div');
  143. notification.className = `notification ${type}`;
  144. notification.textContent = message;
  145. // Agregar al DOM
  146. document.body.appendChild(notification);
  147. // Mostrar con animación
  148. setTimeout(() => {
  149. notification.classList.add('show');
  150. }, 100);
  151. // Ocultar después de 3 segundos
  152. setTimeout(() => {
  153. notification.classList.remove('show');
  154. setTimeout(() => {
  155. document.body.removeChild(notification);
  156. }, 300);
  157. }, 3000);
  158. }
  159. // Auto-refresh every minute to update expiration times
  160. setInterval(() => {
  161. const links = document.querySelectorAll('[data-expires-at]');
  162. links.forEach(linkElement => {
  163. const expiresAt = new Date(linkElement.dataset.expiresAt);
  164. const timeLeftElement = linkElement.querySelector('.time-left');
  165. if (timeLeftElement) {
  166. timeLeftElement.textContent = getTimeLeft(expiresAt);
  167. }
  168. });
  169. }, 60000);