mark36236/firebase-data-copier
0
1<!DOCTYPE html>2<html lang="en">3<head>4 <meta charset="UTF-8">5 <meta name="viewport" content="width=device-width, initial-scale=1.0">6 <title>Firebase Data Viewer</title>7 <script src="https://cdn.tailwindcss.com"></script>8 <script src="https://unpkg.com/feather-icons"></script>9 <script src="https://www.gstatic.com/firebasejs/9.22.0/firebase-app-compat.js"></script>10 <script src="https://www.gstatic.com/firebasejs/9.22.0/firebase-database-compat.js"></script>11 <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">12 <script>13 tailwind.config = {14 theme: {15 extend: {16 colors: {17 primary: '#3b82f6',18 secondary: '#8b5cf6',19 dark: '#0f172a'20 }21 }22 }23 }24 </script>25 <style>26 body {27 font-family: 'Inter', sans-serif;28 background-color: #f1f5f9;29 }30 .data-card {31 transition: all 0.3s ease;32 box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);33 }34 .data-card:hover {35 transform: translateY(-5px);36 box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);37 }38 .key-highlight {39 background-color: #dbeafe;40 padding: 0.25rem 0.5rem;41 border-radius: 0.375rem;42 font-weight: 600;43 }44 .toast {45 position: fixed;46 bottom: 20px;47 right: 20px;48 padding: 12px 20px;49 border-radius: 6px;50 background: #333;51 color: white;52 opacity: 0;53 transform: translateY(20px);54 transition: all 0.3s ease;55 z-index: 1000;56 }57 .toast.show {58 opacity: 1;59 transform: translateY(0);60 }61 </style>62</head>63<body class="bg-gray-100 min-h-screen">64 <div class="container mx-auto px-4 py-8">65 <header class="mb-10 text-center">66 <h1 class="text-4xl font-bold text-gray-800 mb-2">Firebase Data Viewer</h1>67 <p class="text-gray-600 max-w-2xl mx-auto">Visualizing real-time data from Firebase database with a clean, modern interface</p>68 <div class="w-24 h-1 bg-primary mx-auto mt-4 rounded-full"></div>69 </header>70 71 <div class="bg-white rounded-xl shadow-lg p-6 mb-8">72 <div class="flex items-center justify-between mb-6">73 <h2 class="text-2xl font-semibold text-gray-800">Real-time Data Feed</h2>74 <div class="flex items-center space-x-2">75 <div class="w-3 h-3 bg-green-500 rounded-full animate-pulse"></div>76 <span class="text-sm text-gray-600">Live Updates</span>77 </div>78 </div>79 80 <div id="status-indicator" class="mb-6 p-4 rounded-lg bg-blue-50 text-blue-700 flex items-center">81 <i data-feather="loader" class="mr-2 animate-spin"></i>82 <span>Connecting to Firebase database...</span>83 </div>84 85 <div id="data-container" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">86 <!-- Data will be populated here -->87 </div>88 </div>89 90 <div class="text-center text-gray-500 text-sm">91 <p>Data is updated in real-time from Firebase database</p>92 </div>93 </div>94 95 <!-- Toast Notification -->96 <div id="toast" class="toast"></div>97 98 <script>99 // Initialize Feather Icons100 feather.replace();101 102 // Firebase configuration103 const firebaseConfig = {104 apiKey: "AIzaSyDfJR_bSBHKB7Wh4UYj7tyOQeoh0tUsKEo",105 106 authDomain: "eminentsociosdeportes.firebaseapp.com",107 108 databaseURL: "https://eminentsociosdeportes-default-rtdb.firebaseio.com",109 110 projectId: "eminentsociosdeportes",111 112 storageBucket: "eminentsociosdeportes.firebasestorage.app",113 114 messagingSenderId: "410047792239",115 116 appId: "1:410047792239:web:fba108ac086f47bd80799a"117 118 119 };120 121 // Initialize Firebase122 firebase.initializeApp(firebaseConfig);123 const database = firebase.database();124 125 // Reference to the database location126 const dataRef = database.ref('verifications');127 128 // DOM elements129 const dataContainer = document.getElementById('data-container');130 const statusIndicator = document.getElementById('status-indicator');131 const toast = document.getElementById('toast');132 133 // Listen for real-time updates134 dataRef.on('value', (snapshot) => {135 const data = snapshot.val();136 displayData(data);137 updateStatus('Connected to Firebase database', 'text-green-700 bg-green-50');138 }, (error) => {139 console.error('Error:', error);140 updateStatus(`Error: ${error.message}`, 'text-red-700 bg-red-50');141 });142 143 function updateStatus(message, classes) {144 statusIndicator.className = `mb-6 p-4 rounded-lg flex items-center ${classes}`;145 statusIndicator.innerHTML = `146 <i data-feather="info" class="mr-2"></i>147 <span>${message}</span>148 `;149 feather.replace();150 }151 152 function showToast(message) {153 toast.textContent = message;154 toast.classList.add('show');155 setTimeout(() => {156 toast.classList.remove('show');157 }, 3000);158 }159 160 function displayData(data) {161 dataContainer.innerHTML = '';162 163 if (!data) {164 dataContainer.innerHTML = `165 <div class="col-span-full text-center py-12">166 <i data-feather="database" class="w-16 h-16 text-gray-300 mx-auto mb-4"></i>167 <h3 class="text-xl font-medium text-gray-700">No data available</h3>168 <p class="text-gray-500 mt-2">There is no data in the Firebase database at this time</p>169 </div>170 `;171 feather.replace();172 return;173 }174 175 Object.keys(data).forEach(key => {176 const item = data[key];177 const card = document.createElement('div');178 card.className = 'data-card bg-white rounded-lg border border-gray-200 p-5';179 180 // Format the data for display181 const formattedData = formatDataForDisplay(item, key);182 183 card.innerHTML = `184 <div class="mb-3">185 <span class="key-highlight text-primary">${key}</span>186 </div>187 <div class="text-gray-700 text-sm">188 ${formattedData}189 </div>190 <div class="mt-4 pt-3 border-t border-gray-100 flex justify-between items-center">191 <span class="text-xs text-gray-500">ID: ${key.substring(0, 8)}...</span>192 <span class="inline-flex items-center text-xs font-medium px-2.5 py-0.5 rounded-full bg-blue-100 text-blue-800">193 <span class="w-2 h-2 mr-1 rounded-full bg-blue-600"></span>194 Active195 </span>196 </div>197 `;198 199 dataContainer.appendChild(card);200 });201 }202 203 function formatDataForDisplay(item, key) {204 if (typeof item === 'object' && item !== null) {205 let html = '<ul class="space-y-2">';206 Object.keys(item).forEach(subKey => {207 html += `208 <li class="flex">209 <span class="font-medium text-gray-600 w-24 truncate">${subKey}:</span>210 <span class="text-gray-800 flex-1">${formatValue(item[subKey])}</span>211 </li>212 `;213 });214 html += '</ul>';215 216 // Add action buttons if there's a 'code' field217 if (item.code) {218 html += `219 <div class="mt-4 flex space-x-2">220 <button onclick="copyToClipboard('${item.code}')" class="flex-1 flex items-center justify-center px-3 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 transition-colors">221 <i data-feather="copy" class="w-4 h-4 mr-1"></i> Copy Code222 </button>223 <button onclick="deleteItem('${key}')" class="flex items-center justify-center px-3 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 transition-colors">224 <i data-feather="trash-2" class="w-4 h-4"></i>225 </button>226 </div>227 `;228 }229 230 return html;231 } else {232 return `<p>${formatValue(item)}</p>`;233 }234 }235 236 function formatValue(value) {237 if (typeof value === 'string' && value.length > 50) {238 return `<span class="tooltip" title="${value}">${value.substring(0, 50)}...</span>`;239 }240 if (typeof value === 'boolean') {241 return value ? 242 '<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800">True</span>' : 243 '<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-red-100 text-red-800">False</span>';244 }245 return value;246 }247 248 function copyToClipboard(text) {249 navigator.clipboard.writeText(text).then(() => {250 showToast('Code copied to clipboard!');251 }).catch(err => {252 showToast('Failed to copy code');253 console.error('Failed to copy: ', err);254 });255 feather.replace();256 }257 258 function deleteItem(key) {259 if (confirm('Are you sure you want to delete this item?')) {260 dataRef.child(key).remove()261 .then(() => {262 showToast('Item deleted successfully');263 })264 .catch((error) => {265 showToast('Error deleting item');266 console.error('Error deleting item:', error);267 });268 }269 }270 </script>271</body>272</html>273 