🚀 Major improvements: Fix short URLs, separate public/admin views, and enhance UX

 Fixed Critical Issues:
- Fixed dynamic QR code short URL redirect functionality
- Resolved data consistency issues with multiple LinkPageManager instances
- Fixed worker concurrency problems in Gunicorn configuration

🎨 UI/UX Enhancements:
- Separated public page from admin statistics view
- Created clean public_page.html for QR code users (no admin info)
- Added comprehensive statistics_page.html for admin analytics
- Enhanced dashboard with separate 'Manage' and 'Stats' buttons
- Improved navigation flow throughout the application

🔧 Technical Improvements:
- Added URLShortener instance reloading for data consistency
- Reduced Gunicorn workers to 1 to prevent file conflicts
- Increased timeout to 60s for better performance
- Enhanced debug logging for troubleshooting
- Added proper error handling and 404 responses

📁 New Files:
- app/templates/public_page.html - Clean public interface
- app/templates/statistics_page.html - Admin analytics dashboard

�� Modified Files:
- app/routes/main.py - Added /stats route, improved short URL handling
- app/templates/edit_links.html - Added Statistics button
- app/templates/index.html - Added Stats button for QR codes
- app/utils/link_manager.py - Enhanced data reloading
- app/utils/url_shortener.py - Added debug logging
- gunicorn.conf.py - Optimized worker configuration

This update provides a professional separation between public content and admin functionality while ensuring reliable short URL operation.
This commit is contained in:
2025-07-18 09:21:36 -04:00
parent 1ae080df37
commit 53f5c513d4
11 changed files with 920 additions and 8 deletions

View File

@@ -751,6 +751,7 @@
<button class="btn btn-small btn-primary" onclick="downloadQRById('${qr.id}', 'png')" title="Download PNG">📥 PNG</button>
<button class="btn btn-small btn-success" onclick="downloadQRById('${qr.id}', 'svg')" title="Download SVG">🎨 SVG</button>
${qr.type === 'link_page' ? `<button class="btn btn-small" onclick="openLinkPage('${qr.id}')" style="background: #28a745;" title="Manage Links">📝 Manage</button>` : ''}
${qr.type === 'link_page' ? `<button class="btn btn-small" onclick="openStatistics('${qr.id}')" style="background: #17a2b8;" title="View Statistics">📊 Stats</button>` : ''}
<button class="btn btn-small btn-secondary" onclick="deleteQR('${qr.id}')" title="Delete QR Code">🗑️</button>
</div>
</div>
@@ -801,6 +802,21 @@
}
}
async function openStatistics(qrId) {
try {
const response = await fetch(`/api/qr_codes/${qrId}`);
const qrData = await response.json();
if (qrData.page_id) {
window.open(`/stats/${qrData.page_id}`, '_blank');
} else {
alert('Link page not found');
}
} catch (error) {
alert('Error opening statistics page: ' + error.message);
}
}
// Load history on page load
document.addEventListener('DOMContentLoaded', function() {
loadQRHistory();