Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <meta name="theme-color" content="#0a192f"> | |
| <title>Detection History - DeepFake Detection</title> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"> | |
| <link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}"> | |
| <style> | |
| :root { | |
| --primary-color: #64ffda; | |
| --primary-dark: #4cd6b3; | |
| --bg-dark: #1a1a1a; | |
| --bg-darker: #111d40; | |
| --text-light: #8892b0; | |
| --border-color: rgba(100, 255, 218, 0.1); | |
| } | |
| /* Navbar Styling */ | |
| .navbar { | |
| background: var(--bg-dark); | |
| padding: 1rem 2rem; | |
| height: 70px; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | |
| position: sticky; | |
| top: 0; | |
| z-index: 1000; | |
| } | |
| .navbar-brand { | |
| color: var(--primary-color); | |
| font-size: 1.5rem; | |
| font-weight: bold; | |
| text-decoration: none; | |
| transition: color 0.3s ease; | |
| } | |
| .navbar-brand:hover { | |
| color: var(--primary-dark); | |
| } | |
| /* Hamburger Button */ | |
| .hamburger { | |
| display: none; | |
| background: none; | |
| border: none; | |
| color: #64ffda; | |
| font-size: 2rem; | |
| cursor: pointer; | |
| padding: 0; | |
| } | |
| .navbar-nav { | |
| display: flex; | |
| gap: 1rem; | |
| align-items: center; | |
| transition: all 0.3s ease; | |
| } | |
| .nav-link { | |
| color: #fff; | |
| text-decoration: none; | |
| padding: 0.5rem 1rem; | |
| border-radius: 4px; | |
| transition: all 0.3s ease; | |
| } | |
| .nav-link:hover, .nav-link.active { | |
| background: rgba(100, 255, 218, 0.1); | |
| color: var(--primary-color); | |
| } | |
| /* History Table Specific Styles */ | |
| .history-container { | |
| background: rgba(17, 34, 64, 0.3); | |
| border: 1px solid var(--border-color); | |
| border-radius: 12px; | |
| padding: 2rem; | |
| margin: 2rem auto; | |
| max-width: 1000px; | |
| overflow-x: auto; | |
| box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); | |
| } | |
| .history-table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| text-align: left; | |
| margin-top: 1rem; | |
| } | |
| .history-table th { | |
| color: var(--primary-color); | |
| padding: 1.2rem 1rem; | |
| border-bottom: 2px solid var(--border-color); | |
| font-weight: 600; | |
| letter-spacing: 0.5px; | |
| text-transform: uppercase; | |
| font-size: 0.9rem; | |
| } | |
| .history-table td { | |
| color: var(--text-light); | |
| padding: 1.2rem 1rem; | |
| border-bottom: 1px solid rgba(100, 255, 218, 0.05); | |
| vertical-align: middle; | |
| } | |
| .history-table tbody tr { | |
| transition: all 0.2s ease; | |
| } | |
| .history-table tbody tr:hover { | |
| background: rgba(100, 255, 218, 0.05); | |
| transform: scale(1.01); | |
| } | |
| .history-table tr:last-child td { | |
| border-bottom: none; | |
| } | |
| .badge { | |
| padding: 0.4rem 0.8rem; | |
| border-radius: 20px; | |
| font-size: 0.85rem; | |
| font-weight: bold; | |
| display: inline-block; | |
| } | |
| .badge-video { | |
| background: rgba(52, 152, 219, 0.2); | |
| color: #3498db; | |
| border: 1px solid #3498db; | |
| } | |
| .badge-image { | |
| background: rgba(155, 89, 182, 0.2); | |
| color: #9b59b6; | |
| border: 1px solid #9b59b6; | |
| } | |
| .result-fake { | |
| color: #ff4d4d; | |
| font-weight: bold; | |
| text-shadow: 0 0 10px rgba(255, 77, 77, 0.3); | |
| } | |
| .result-real { | |
| color: #4dff4d; | |
| font-weight: bold; | |
| text-shadow: 0 0 10px rgba(77, 255, 77, 0.3); | |
| } | |
| .empty-state { | |
| text-align: center; | |
| padding: 3rem; | |
| color: var(--text-light); | |
| } | |
| .empty-state p { | |
| font-size: 1.2rem; | |
| margin-bottom: 1.5rem; | |
| } | |
| .footer { | |
| margin-top: auto; | |
| padding: 3rem 0; | |
| background: var(--bg-darker); | |
| border-top: 1px solid var(--border-color); | |
| } | |
| .footer-content { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 0 2rem; | |
| display: flex; | |
| justify-content: space-between; | |
| gap: 2rem; | |
| } | |
| .footer-section h3 { color: var(--primary-color); margin-bottom: 1rem; } | |
| .footer-link { color: var(--text-light); text-decoration: none; display: block; margin: 0.5rem 0; transition: color 0.3s ease; } | |
| .footer-link:hover { color: var(--primary-color); } | |
| /* --- BULLETPROOF MOBILE TABLE FIXES --- */ | |
| @media (max-width: 768px) { | |
| body, html { | |
| overflow-x: hidden; /* STOPS the entire screen from swiping sideways */ | |
| width: 100%; | |
| -webkit-tap-highlight-color: transparent; | |
| -webkit-touch-callout: none; | |
| user-select: none; | |
| } | |
| .content { | |
| padding: 1rem 0; /* Remove side padding so table touches edges */ | |
| width: 100%; | |
| box-sizing: border-box; | |
| } | |
| .navbar { | |
| padding: 1rem 1.5rem; | |
| } | |
| .hamburger { | |
| display: block; | |
| } | |
| .navbar-nav { | |
| display: flex; | |
| flex-direction: column; | |
| position: absolute; | |
| top: 70px; | |
| left: 0; | |
| width: 100%; | |
| background: rgba(17, 29, 64, 0.98); | |
| padding: 0; | |
| box-shadow: 0 10px 20px rgba(0, 0, 0, 0.5); | |
| max-height: 0; | |
| overflow: hidden; | |
| opacity: 0; | |
| transition: all 0.3s ease; | |
| } | |
| .navbar-nav.active { | |
| max-height: 500px; | |
| padding: 1rem 0; | |
| opacity: 1; | |
| } | |
| .nav-link { | |
| width: 100%; | |
| text-align: center; | |
| padding: 1.2rem; | |
| border-radius: 0; | |
| } | |
| /* --- THE SCROLL FIX --- */ | |
| .history-container { | |
| width: 100%; | |
| margin: 1rem 0; | |
| padding: 0; | |
| border-radius: 0; | |
| border-left: none; | |
| border-right: none; | |
| overflow-x: auto; /* Allow ONLY the table to scroll */ | |
| -webkit-overflow-scrolling: touch; | |
| } | |
| .history-table { | |
| width: max-content; /* Forces table to ignore screen width limits */ | |
| min-width: 100%; | |
| margin: 0; | |
| } | |
| .history-table th, .history-table td { | |
| white-space: nowrap ; | |
| padding: 1rem; | |
| } | |
| /* --- THE FILENAME TRUNCATION FIX --- */ | |
| .history-table td:nth-child(2) { | |
| max-width: 150px; /* Limits filename width */ | |
| overflow: hidden; | |
| text-overflow: ellipsis; /* Adds '...' to the end of long names */ | |
| } | |
| .footer-content { | |
| flex-direction: column; | |
| text-align: center; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="root"> | |
| <nav class="navbar"> | |
| <a href="{{ url_for('homepage') }}" class="navbar-brand">DeepFake Detection</a> | |
| <button class="hamburger" id="hamburger-btn" aria-label="Toggle menu"> | |
| ☰ | |
| </button> | |
| <div class="navbar-nav" id="nav-links"> | |
| {% if current_user.is_authenticated %} | |
| <a href="{{ url_for('detect') }}" class="nav-link">Upload Video</a> | |
| <a href="{{ url_for('image_detect') }}" class="nav-link">Detect Image</a> | |
| <a href="{{ url_for('history') }}" class="nav-link active">History</a> | |
| <a href="{{ url_for('logout') }}" class="nav-link">Logout</a> | |
| {% endif %} | |
| </div> | |
| </nav> | |
| <main class="content" role="main"> | |
| <h1 class="heading" style="padding: 0 1rem;">Detection History</h1> | |
| <p class="para" style="padding: 0 1rem;">Review your past video and image analysis logs.</p> | |
| <div class="history-container"> | |
| {% if logs %} | |
| <table class="history-table"> | |
| <thead> | |
| <tr> | |
| <th>Date & Time</th> | |
| <th>File Name</th> | |
| <th>Media Type</th> | |
| <th>Result</th> | |
| <th>Confidence</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| {% for log in logs %} | |
| <tr> | |
| <td>{{ log.timestamp.strftime('%Y-%m-%d %H:%M') }}</td> | |
| <td style="color: #fff;" title="{{ log.filename }}">{{ log.filename }}</td> | |
| <td> | |
| <span class="badge {% if log.media_type == 'Video' %}badge-video{% else %}badge-image{% endif %}"> | |
| {{ log.media_type }} | |
| </span> | |
| </td> | |
| <td class="{% if log.prediction == 'FAKE' %}result-fake{% else %}result-real{% endif %}"> | |
| {{ log.prediction }} | |
| </td> | |
| <td>{{ "%.2f"|format(log.confidence) }}%</td> | |
| </tr> | |
| {% endfor %} | |
| </tbody> | |
| </table> | |
| {% else %} | |
| <div class="empty-state"> | |
| <p>You haven't scanned any files yet.</p> | |
| <a href="{{ url_for('detect') }}" class="cta-button" style="display: inline-block; padding: 0.8rem 1.5rem; background: #64ffda; color: #1a1a1a; text-decoration: none; border-radius: 4px; font-weight: bold;">Scan a Video Now</a> | |
| </div> | |
| {% endif %} | |
| </div> | |
| </main> | |
| <footer class="footer"> | |
| <div class="footer-content"> | |
| <div class="footer-section"> | |
| <h3>About Us</h3> | |
| <p>We are dedicated to detecting and preventing deepfake videos using advanced AI technology.</p> | |
| </div> | |
| <div class="footer-section"> | |
| <h3>Contact</h3> | |
| <a href="mailto:contact@deepfakedetect.ai" class="footer-link">contact@deepfakedetect.ai</a> | |
| <a href="https://github.com/deepfake-detect" class="footer-link">GitHub</a> | |
| </div> | |
| <div class="footer-section"> | |
| <h3>Legal</h3> | |
| <a href="{{ url_for('privacy') }}" class="footer-link">Privacy Policy</a> | |
| <a href="{{ url_for('terms') }}" class="footer-link">Terms of Service</a> | |
| <p>© 2025 DeepFake Detection</p> | |
| </div> | |
| </div> | |
| </footer> | |
| </div> | |
| <script> | |
| // Hamburger Menu Script | |
| document.addEventListener('DOMContentLoaded', () => { | |
| const hamburgerBtn = document.getElementById('hamburger-btn'); | |
| const navLinks = document.getElementById('nav-links'); | |
| hamburgerBtn.addEventListener('click', () => { | |
| navLinks.classList.toggle('active'); | |
| }); | |
| document.querySelectorAll('.nav-link').forEach(link => { | |
| link.addEventListener('click', () => { | |
| navLinks.classList.remove('active'); | |
| }); | |
| }); | |
| }); | |
| </script> | |
| </body> | |
| </html> |