fix: ajustes de toast e msg de erro
This commit is contained in:
parent
83e46a5782
commit
3e84e8d7a6
@ -172,7 +172,7 @@ function regenerateQR(qrId) {
|
|||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('Error regenerating QR:', 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') {
|
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
|
// Create toast element
|
||||||
const toast = document.createElement('div');
|
const toastElement = document.createElement('div');
|
||||||
toast.className = `alert alert-${type === 'success' ? 'success' : 'danger'} alert-dismissible fade show position-fixed`;
|
toastElement.innerHTML = `
|
||||||
toast.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px;';
|
<div class="toast align-items-center text-white bg-${type === 'success' ? 'success' : 'danger'} border-0" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
toast.innerHTML = `
|
<div class="d-flex">
|
||||||
${message}
|
<div class="toast-body">${message}</div>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
document.body.appendChild(toast);
|
toastContainer.appendChild(toastElement);
|
||||||
|
const toast = new bootstrap.Toast(toastElement.querySelector('.toast'), { delay: 5000 });
|
||||||
// Auto remove after 5 seconds
|
toast.show();
|
||||||
setTimeout(() => {
|
|
||||||
if (toast.parentNode) {
|
// Remove toast element after it's hidden
|
||||||
toast.remove();
|
toastElement.querySelector('.toast').addEventListener('hidden.bs.toast', function() {
|
||||||
}
|
toastElement.remove();
|
||||||
}, 5000);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event listeners
|
// Event listeners
|
||||||
|
|||||||
@ -267,6 +267,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group" id="website-group" style="display: none;">
|
<div class="form-group" id="website-group" style="display: none;">
|
||||||
<input type="url" id="vcard-website" class="form-control" placeholder="https://seusite.com">
|
<input type="url" id="vcard-website" class="form-control" placeholder="https://seusite.com">
|
||||||
|
<div class="invalid-feedback" id="website-error"></div>
|
||||||
|
<small class="form-text text-muted">
|
||||||
|
<i class="fas fa-info-circle"></i> O protocolo https:// será adicionado automaticamente
|
||||||
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -1337,5 +1341,124 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
logoVisualPreview.style.display = 'none';
|
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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Toast positioning improvements */
|
||||||
|
#toast-container {
|
||||||
|
max-width: 350px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive toast positioning */
|
||||||
|
@@media (max-width: 768px) {
|
||||||
|
#toast-container {
|
||||||
|
left: 50% !important;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
top: 70px !important;
|
||||||
|
margin-top: 0 !important;
|
||||||
|
padding: 0.5rem !important;
|
||||||
|
max-width: calc(100vw - 1rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@media (min-width: 769px) {
|
||||||
|
#toast-container {
|
||||||
|
margin-top: 85px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toast style improvements */
|
||||||
|
.toast {
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||||
|
border-radius: 8px;
|
||||||
|
min-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Website field validation improvements */
|
||||||
|
#vcard-website.is-valid {
|
||||||
|
border-color: #28a745;
|
||||||
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='m2.3 6.73.13-.07.44-.44a.34.34 0 0 1 .48 0l.44.44.13.07a.33.33 0 0 1 0 .59.33.33 0 0 1-.59 0l-.44-.44-.44.44a.33.33 0 0 1-.59 0 .33.33 0 0 1 0-.59z'/%3e%3c/svg%3e");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: right calc(0.375em + 0.1875rem) center;
|
||||||
|
background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
#vcard-website.is-invalid {
|
||||||
|
border-color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Smooth transitions for validation states */
|
||||||
|
#vcard-website {
|
||||||
|
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -101,17 +101,52 @@
|
|||||||
if (result.success) {
|
if (result.success) {
|
||||||
window.location.href = result.url;
|
window.location.href = result.url;
|
||||||
} else {
|
} else {
|
||||||
alert('@Localizer["Error"] ' + result.error);
|
showToast('@Localizer["Error"] ' + result.error, 'danger');
|
||||||
this.disabled = false;
|
this.disabled = false;
|
||||||
this.innerHTML = '@Localizer["SubscribeNow"]'; // Reset button text
|
this.innerHTML = '@Localizer["SubscribeNow"]'; // Reset button text
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Checkout error:', error);
|
console.error('Checkout error:', error);
|
||||||
alert('@Localizer["PaymentInitializationError"]');
|
showToast('@Localizer["PaymentInitializationError"]', 'danger');
|
||||||
this.disabled = false;
|
this.disabled = false;
|
||||||
this.innerHTML = 'Assinar Agora'; // Reset button text
|
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 = `
|
||||||
|
<div class="toast align-items-center text-white bg-${type} border-0" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="d-flex">
|
||||||
|
<div class="toast-body">${message}</div>
|
||||||
|
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -286,11 +286,11 @@
|
|||||||
|
|
||||||
window.location.href = result.url;
|
window.location.href = result.url;
|
||||||
} else {
|
} else {
|
||||||
alert('@Localizer["PaymentProcessingError"]' + result.error);
|
showToast('@Localizer["PaymentProcessingError"]' + result.error, 'danger');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Erro:', error);
|
console.error('Erro:', error);
|
||||||
alert('@Localizer["PaymentErrorTryAgain"]');
|
showToast('@Localizer["PaymentErrorTryAgain"]', 'danger');
|
||||||
} finally {
|
} finally {
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
spinner.classList.add('d-none');
|
spinner.classList.add('d-none');
|
||||||
@ -304,5 +304,40 @@
|
|||||||
'page_location': window.location.href
|
'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 = `
|
||||||
|
<div class="toast align-items-center text-white bg-${type} border-0" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="d-flex">
|
||||||
|
<div class="toast-body">${message}</div>
|
||||||
|
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
}
|
}
|
||||||
@ -1448,8 +1448,9 @@ class QRRapidoGenerator {
|
|||||||
if (!toastContainer) {
|
if (!toastContainer) {
|
||||||
toastContainer = document.createElement('div');
|
toastContainer = document.createElement('div');
|
||||||
toastContainer.id = 'toast-container';
|
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.zIndex = '1060';
|
||||||
|
toastContainer.style.marginTop = '80px'; // Avoid covering logo/header
|
||||||
document.body.appendChild(toastContainer);
|
document.body.appendChild(toastContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2452,7 +2453,7 @@ class QRRapidoGenerator {
|
|||||||
|
|
||||||
// Initialize when DOM loads
|
// Initialize when DOM loads
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
window.qrGenerator = new QRRapidoGenerator();
|
window.qrGenerator = new QRRapidoGenerator();
|
||||||
window.vcardGenerator = new VCardGenerator();
|
window.vcardGenerator = new VCardGenerator();
|
||||||
window.wifiGenerator = new WiFiQRGenerator();
|
window.wifiGenerator = new WiFiQRGenerator();
|
||||||
window.smsGenerator = new SMSQRGenerator();
|
window.smsGenerator = new SMSQRGenerator();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user