Enhanced statistics page with QR code preview and download options

🎨 New Features:
- Added QR code preview section in statistics page
- Integrated PNG and SVG download buttons
- Responsive design for mobile devices
- Automatic QR code loading for the current page

🔧 Technical Details:
- Added QR preview container with loading states
- Implemented downloadQRCode() function for both formats
- Enhanced mobile responsiveness for QR preview section
- Connected to existing /api/download endpoints

📱 UI Improvements:
- Clean preview with bordered QR code image
- Intuitive download buttons with icons
- Loading indicator while fetching QR code
- Error handling for missing QR codes

This completes the admin statistics dashboard with full QR code management capabilities.
This commit is contained in:
2025-07-18 09:29:17 -04:00
parent 53f5c513d4
commit ccf8b49f95

View File

@@ -262,6 +262,78 @@
border: 1px solid #b8daff;
}
.qr-preview-section {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 20px;
margin-top: 20px;
text-align: center;
}
.qr-preview-section h4 {
color: #495057;
margin-bottom: 15px;
font-size: 1.1em;
}
.qr-preview-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 15px;
}
.qr-preview-image {
max-width: 200px;
max-height: 200px;
border: 2px solid #dee2e6;
border-radius: 8px;
background: white;
padding: 10px;
}
.qr-download-actions {
display: flex;
gap: 10px;
flex-wrap: wrap;
justify-content: center;
}
.btn-download {
padding: 8px 16px;
border: none;
border-radius: 6px;
cursor: pointer;
text-decoration: none;
font-weight: 500;
font-size: 0.9em;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 6px;
}
.btn-download-png {
background: #007bff;
color: white;
}
.btn-download-svg {
background: #28a745;
color: white;
}
.btn-download:hover {
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
.qr-loading {
color: #666;
font-style: italic;
}
/* Responsive design */
@media (max-width: 768px) {
body {
@@ -308,6 +380,21 @@
.link-title {
font-size: 1.1em;
}
.qr-preview-image {
max-width: 150px;
max-height: 150px;
}
.qr-download-actions {
flex-direction: column;
width: 100%;
}
.btn-download {
width: 100%;
justify-content: center;
}
}
@media (max-width: 480px) {
@@ -379,6 +466,22 @@
<h3>🔗 Public QR Code URL</h3>
<p>This is the URL that your QR code points to (public page without statistics):</p>
<div class="qr-url">{{ request.url_root }}links/{{ page.id }}</div>
<div class="qr-preview-section">
<h4>📱 QR Code Preview</h4>
<div class="qr-preview-container">
<div id="qr-preview-loading" class="qr-loading">Loading QR code...</div>
<img id="qr-preview-image" class="qr-preview-image" style="display: none;" alt="QR Code">
<div class="qr-download-actions" id="qr-download-actions" style="display: none;">
<button class="btn-download btn-download-png" onclick="downloadQRCode('png')">
📥 Download PNG
</button>
<button class="btn-download btn-download-svg" onclick="downloadQRCode('svg')">
🎨 Download SVG
</button>
</div>
</div>
</div>
</div>
</div>
@@ -495,7 +598,55 @@
}
// Initialize logos when page loads
document.addEventListener('DOMContentLoaded', setLogosForLinks);
document.addEventListener('DOMContentLoaded', function() {
setLogosForLinks();
loadQRCodePreview();
});
// QR Code functionality
let currentQRId = null;
async function loadQRCodePreview() {
try {
const pageId = '{{ page.id }}';
// Find the QR code for this page
const response = await fetch('/api/qr_codes');
const qrCodes = await response.json();
const pageQR = qrCodes.find(qr => qr.type === 'link_page' && qr.page_id === pageId);
if (pageQR) {
currentQRId = pageQR.id;
const previewImage = document.getElementById('qr-preview-image');
const loadingText = document.getElementById('qr-preview-loading');
const downloadActions = document.getElementById('qr-download-actions');
previewImage.src = pageQR.preview;
previewImage.style.display = 'block';
loadingText.style.display = 'none';
downloadActions.style.display = 'flex';
} else {
document.getElementById('qr-preview-loading').textContent = 'QR code not found';
}
} catch (error) {
console.error('Failed to load QR code preview:', error);
document.getElementById('qr-preview-loading').textContent = 'Failed to load QR code';
}
}
function downloadQRCode(format) {
if (!currentQRId) {
alert('QR code not found');
return;
}
if (format === 'svg') {
window.open(`/api/download/${currentQRId}/svg`, '_blank');
} else {
window.open(`/api/download/${currentQRId}`, '_blank');
}
}
</script>
</body>
</html>