From 3e84e8d7a682bd11a4ea3ad758f019807d2c0dbf Mon Sep 17 00:00:00 2001 From: Ricardo Carneiro Date: Tue, 12 Aug 2025 18:23:56 -0300 Subject: [PATCH] fix: ajustes de toast e msg de erro --- Views/Account/History.cshtml | 45 ++++++---- Views/Home/Index.cshtml | 125 +++++++++++++++++++++++++++- Views/Pagamento/SelecaoPlano.cshtml | 39 ++++++++- Views/Premium/Upgrade.cshtml | 39 ++++++++- wwwroot/js/qr-speed-generator.js | 5 +- 5 files changed, 230 insertions(+), 23 deletions(-) diff --git a/Views/Account/History.cshtml b/Views/Account/History.cshtml index 3a3d034..68d419e 100644 --- a/Views/Account/History.cshtml +++ b/Views/Account/History.cshtml @@ -172,7 +172,7 @@ function regenerateQR(qrId) { }) .catch(error => { console.error('Error regenerating QR:', error); - alert('@Localizer["ErrorRegeneratingQR"]'); + showToast('@Localizer["ErrorRegeneratingQR"]', 'danger'); }); } @@ -236,23 +236,36 @@ function deleteQR(qrId) { } function showToast(message, type = 'info') { + // Create toast container if doesn't exist + let toastContainer = document.getElementById('toast-container'); + if (!toastContainer) { + toastContainer = document.createElement('div'); + toastContainer.id = 'toast-container'; + toastContainer.className = 'toast-container position-fixed top-0 start-0 p-3'; + toastContainer.style.zIndex = '1060'; + toastContainer.style.marginTop = '80px'; + document.body.appendChild(toastContainer); + } + // Create toast element - const toast = document.createElement('div'); - toast.className = `alert alert-${type === 'success' ? 'success' : 'danger'} alert-dismissible fade show position-fixed`; - toast.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px;'; - toast.innerHTML = ` - ${message} - + const toastElement = document.createElement('div'); + toastElement.innerHTML = ` + `; - - document.body.appendChild(toast); - - // Auto remove after 5 seconds - setTimeout(() => { - if (toast.parentNode) { - toast.remove(); - } - }, 5000); + + toastContainer.appendChild(toastElement); + const toast = new bootstrap.Toast(toastElement.querySelector('.toast'), { delay: 5000 }); + toast.show(); + + // Remove toast element after it's hidden + toastElement.querySelector('.toast').addEventListener('hidden.bs.toast', function() { + toastElement.remove(); + }); } // Event listeners diff --git a/Views/Home/Index.cshtml b/Views/Home/Index.cshtml index 9c3c559..3639918 100644 --- a/Views/Home/Index.cshtml +++ b/Views/Home/Index.cshtml @@ -267,6 +267,10 @@ @@ -1337,5 +1341,124 @@ document.addEventListener('DOMContentLoaded', function() { logoVisualPreview.style.display = 'none'; } }); + + // Website field auto-complete functionality + const websiteField = document.getElementById('vcard-website'); + if (websiteField) { + // Auto-add https:// on focus if field is empty + websiteField.addEventListener('focus', function() { + if (this.value.trim() === '') { + this.value = 'https://'; + // Position cursor after https:// + setTimeout(() => { + this.setSelectionRange(8, 8); + }, 10); + } + }); + + // Validate and auto-correct on blur + websiteField.addEventListener('blur', function() { + const value = this.value.trim(); + + // If empty, clear the field + if (value === '' || value === 'https://') { + this.value = ''; + this.classList.remove('is-invalid'); + return; + } + + // Check if URL has protocol + if (value && !value.match(/^https?:\/\//i)) { + // Auto-add https:// if missing + this.value = 'https://' + value; + } + + // Validate URL format + try { + const url = new URL(this.value); + // Valid URL + this.classList.remove('is-invalid'); + this.classList.add('is-valid'); + } catch (e) { + // Invalid URL + this.classList.remove('is-valid'); + this.classList.add('is-invalid'); + document.getElementById('website-error').textContent = 'Por favor, insira uma URL válida (ex: https://seusite.com)'; + } + }); + + // Real-time validation as user types + websiteField.addEventListener('input', function() { + const value = this.value.trim(); + + // Reset validation if empty + if (value === '' || value === 'https://') { + this.classList.remove('is-invalid', 'is-valid'); + return; + } + + // Check if it looks like a valid URL structure + if (value.match(/^https?:\/\/.+\..+/i)) { + try { + new URL(value); + this.classList.remove('is-invalid'); + this.classList.add('is-valid'); + } catch (e) { + this.classList.remove('is-valid'); + this.classList.add('is-invalid'); + } + } + }); + } }); - \ No newline at end of file + + + \ No newline at end of file diff --git a/Views/Pagamento/SelecaoPlano.cshtml b/Views/Pagamento/SelecaoPlano.cshtml index 850f0f4..1df6c69 100644 --- a/Views/Pagamento/SelecaoPlano.cshtml +++ b/Views/Pagamento/SelecaoPlano.cshtml @@ -101,17 +101,52 @@ if (result.success) { window.location.href = result.url; } else { - alert('@Localizer["Error"] ' + result.error); + showToast('@Localizer["Error"] ' + result.error, 'danger'); this.disabled = false; this.innerHTML = '@Localizer["SubscribeNow"]'; // Reset button text } } catch (error) { console.error('Checkout error:', error); - alert('@Localizer["PaymentInitializationError"]'); + showToast('@Localizer["PaymentInitializationError"]', 'danger'); this.disabled = false; this.innerHTML = 'Assinar Agora'; // Reset button text } }); }); + + // Toast notification function + function showToast(message, type) { + // Create toast container if doesn't exist + let toastContainer = document.getElementById('toast-container'); + if (!toastContainer) { + toastContainer = document.createElement('div'); + toastContainer.id = 'toast-container'; + toastContainer.className = 'toast-container position-fixed top-0 start-0 p-3'; + toastContainer.style.zIndex = '1060'; + toastContainer.style.marginTop = '80px'; + document.body.appendChild(toastContainer); + } + + // Create toast element + const toastId = 'toast-' + Date.now(); + const toastElement = document.createElement('div'); + toastElement.innerHTML = ` + + `; + + toastContainer.appendChild(toastElement); + const toast = new bootstrap.Toast(toastElement.querySelector('.toast'), { delay: 5000 }); + toast.show(); + + // Remove toast element after it's hidden + toastElement.querySelector('.toast').addEventListener('hidden.bs.toast', function() { + toastElement.remove(); + }); + } } diff --git a/Views/Premium/Upgrade.cshtml b/Views/Premium/Upgrade.cshtml index 10998ff..9e73637 100644 --- a/Views/Premium/Upgrade.cshtml +++ b/Views/Premium/Upgrade.cshtml @@ -286,11 +286,11 @@ window.location.href = result.url; } else { - alert('@Localizer["PaymentProcessingError"]' + result.error); + showToast('@Localizer["PaymentProcessingError"]' + result.error, 'danger'); } } catch (error) { console.error('Erro:', error); - alert('@Localizer["PaymentErrorTryAgain"]'); + showToast('@Localizer["PaymentErrorTryAgain"]', 'danger'); } finally { btn.disabled = false; spinner.classList.add('d-none'); @@ -304,5 +304,40 @@ 'page_location': window.location.href }); } + + // Toast notification function + function showToast(message, type) { + // Create toast container if doesn't exist + let toastContainer = document.getElementById('toast-container'); + if (!toastContainer) { + toastContainer = document.createElement('div'); + toastContainer.id = 'toast-container'; + toastContainer.className = 'toast-container position-fixed top-0 start-0 p-3'; + toastContainer.style.zIndex = '1060'; + toastContainer.style.marginTop = '80px'; + document.body.appendChild(toastContainer); + } + + // Create toast element + const toastId = 'toast-' + Date.now(); + const toastElement = document.createElement('div'); + toastElement.innerHTML = ` + + `; + + toastContainer.appendChild(toastElement); + const toast = new bootstrap.Toast(toastElement.querySelector('.toast'), { delay: 5000 }); + toast.show(); + + // Remove toast element after it's hidden + toastElement.querySelector('.toast').addEventListener('hidden.bs.toast', function() { + toastElement.remove(); + }); + } } \ No newline at end of file diff --git a/wwwroot/js/qr-speed-generator.js b/wwwroot/js/qr-speed-generator.js index 06398da..3aee81b 100644 --- a/wwwroot/js/qr-speed-generator.js +++ b/wwwroot/js/qr-speed-generator.js @@ -1448,8 +1448,9 @@ class QRRapidoGenerator { if (!toastContainer) { toastContainer = document.createElement('div'); toastContainer.id = 'toast-container'; - toastContainer.className = 'toast-container position-fixed top-0 end-0 p-3'; + toastContainer.className = 'toast-container position-fixed top-0 start-0 p-3'; toastContainer.style.zIndex = '1060'; + toastContainer.style.marginTop = '80px'; // Avoid covering logo/header document.body.appendChild(toastContainer); } @@ -2452,7 +2453,7 @@ class QRRapidoGenerator { // Initialize when DOM loads document.addEventListener('DOMContentLoaded', () => { - window.qrGenerator = new QRRapidoGenerator(); + window.qrGenerator = new QRRapidoGenerator(); window.vcardGenerator = new VCardGenerator(); window.wifiGenerator = new WiFiQRGenerator(); window.smsGenerator = new SMSQRGenerator();