feat: adsense
This commit is contained in:
parent
e172969996
commit
bcf9f659b4
@ -68,7 +68,7 @@ namespace QRRapidoApp.Middleware
|
|||||||
"favicon.ico", "robots.txt", "sitemap.xml",
|
"favicon.ico", "robots.txt", "sitemap.xml",
|
||||||
"signin-microsoft", "signin-google", "signout-callback-oidc",
|
"signin-microsoft", "signin-google", "signout-callback-oidc",
|
||||||
"Account/ExternalLoginCallback", "Account/Logout", "Pagamento/CreateCheckout",
|
"Account/ExternalLoginCallback", "Account/Logout", "Pagamento/CreateCheckout",
|
||||||
"Pagamento/StripeWebhook"
|
"Pagamento/StripeWebhook", "api/QR"
|
||||||
};
|
};
|
||||||
|
|
||||||
return specialRoutes.Any(route => path.StartsWith(route, StringComparison.OrdinalIgnoreCase));
|
return specialRoutes.Any(route => path.StartsWith(route, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|||||||
@ -681,6 +681,15 @@
|
|||||||
<data name="TypeGuideText" xml:space="preserve">
|
<data name="TypeGuideText" xml:space="preserve">
|
||||||
<value>📝 Para texto libre, ingresa cualquier contenido que desees</value>
|
<value>📝 Para texto libre, ingresa cualquier contenido que desees</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ContentAddedToastTitle" xml:space="preserve">
|
||||||
|
<value>✅ ¡Contenido ñemboguapy! (Contenido agregado!)</value>
|
||||||
|
</data>
|
||||||
|
<data name="ContentAddedToastMessage" xml:space="preserve">
|
||||||
|
<value>Opciones avanzadas ojeporukuaa guýpe. Eity "Generar QR Code" emoĩmbyre jave.</value>
|
||||||
|
</data>
|
||||||
|
<data name="GenerateButtonReady" xml:space="preserve">
|
||||||
|
<value>✨ ¡Emoĩmbyma! (¡Listo para generar!)</value>
|
||||||
|
</data>
|
||||||
<data name="TipsFasterQR" xml:space="preserve">
|
<data name="TipsFasterQR" xml:space="preserve">
|
||||||
<value>Ñe'ẽ pya'épe ha porãve (Consejos para QR Más Rápidos)</value>
|
<value>Ñe'ẽ pya'épe ha porãve (Consejos para QR Más Rápidos)</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@ -681,6 +681,15 @@
|
|||||||
<data name="TypeGuideText" xml:space="preserve">
|
<data name="TypeGuideText" xml:space="preserve">
|
||||||
<value>📝 Para texto livre, digite qualquer conteúdo que desejar</value>
|
<value>📝 Para texto livre, digite qualquer conteúdo que desejar</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ContentAddedToastTitle" xml:space="preserve">
|
||||||
|
<value>✅ Conteúdo adicionado!</value>
|
||||||
|
</data>
|
||||||
|
<data name="ContentAddedToastMessage" xml:space="preserve">
|
||||||
|
<value>Opções avançadas disponíveis abaixo. Clique em "Gerar QR Code" quando estiver pronto.</value>
|
||||||
|
</data>
|
||||||
|
<data name="GenerateButtonReady" xml:space="preserve">
|
||||||
|
<value>✨ Pronto para gerar!</value>
|
||||||
|
</data>
|
||||||
<data name="TipsFasterQR" xml:space="preserve">
|
<data name="TipsFasterQR" xml:space="preserve">
|
||||||
<value>Dicas para QR Mais Rápidos</value>
|
<value>Dicas para QR Mais Rápidos</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@ -24,8 +24,10 @@ namespace QRRapidoApp.Services
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_context.Users == null) return null; // Development mode without MongoDB
|
if (_context.Users == null) return null; // Development mode without MongoDB
|
||||||
|
|
||||||
return await _context.Users.Find(u => u.Id == userId).FirstOrDefaultAsync();
|
var userData = await _context.Users.Find(u => u.Id == userId).FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
return userData ?? new User();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -151,7 +151,10 @@
|
|||||||
validationContentMinLength: '@Localizer["ValidationContentMinLength"]',
|
validationContentMinLength: '@Localizer["ValidationContentMinLength"]',
|
||||||
errorSavingHistory: '@Localizer["ErrorSavingHistory"]',
|
errorSavingHistory: '@Localizer["ErrorSavingHistory"]',
|
||||||
rateLimitReached: '@Localizer["RateLimitReached"]',
|
rateLimitReached: '@Localizer["RateLimitReached"]',
|
||||||
premiumLogoRequired: '@Localizer["PremiumLogoRequired"]'
|
premiumLogoRequired: '@Localizer["PremiumLogoRequired"]',
|
||||||
|
contentAddedToastTitle: '@Localizer["ContentAddedToastTitle"]',
|
||||||
|
contentAddedToastMessage: '@Localizer["ContentAddedToastMessage"]',
|
||||||
|
generateButtonReady: '@Localizer["GenerateButtonReady"]'
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"ApplicationName": "QRRapido-Prod",
|
"ApplicationName": "QRRapido-Prod",
|
||||||
"Environment": "Prod",
|
"Environment": "Prod",
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"MongoDB": "mongodb://admin:c4rn31r0@129.146.116.218:27017,141.148.162.114:27017/seu_banco?replicaSet=rs0&authSource=admin"
|
"MongoDB": "mongodb://admin:c4rn31r0@129.146.116.218:27017,141.148.162.114:27017/QrRapido?replicaSet=rs0&authSource=admin"
|
||||||
},
|
},
|
||||||
"Serilog": {
|
"Serilog": {
|
||||||
"SeqUrl": "http://localhost:5341",
|
"SeqUrl": "http://localhost:5341",
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
"PriceId": "prod_SnfQTxwE3i8r5L"
|
"PriceId": "prod_SnfQTxwE3i8r5L"
|
||||||
},
|
},
|
||||||
"AdSense": {
|
"AdSense": {
|
||||||
"ClientId": "ca-pub-XXXXXXXXXX",
|
"ClientId": "ca-pub-3475956393038764",
|
||||||
"Enabled": true
|
"Enabled": true
|
||||||
},
|
},
|
||||||
"Performance": {
|
"Performance": {
|
||||||
|
|||||||
@ -1122,4 +1122,76 @@ html[data-theme="dark"] .required-field:valid,
|
|||||||
html[data-theme="dark"] .form-control:valid {
|
html[data-theme="dark"] .form-control:valid {
|
||||||
border-color: #22c55e !important;
|
border-color: #22c55e !important;
|
||||||
box-shadow: 0 0 0 0.25rem rgba(34, 197, 94, 0.25) !important;
|
box-shadow: 0 0 0 0.25rem rgba(34, 197, 94, 0.25) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =================================
|
||||||
|
UX IMPROVEMENTS - BUTTON READY STATES
|
||||||
|
================================= */
|
||||||
|
|
||||||
|
.btn-pulse {
|
||||||
|
animation: buttonPulse 1.5s ease-in-out infinite;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 123, 255, 0.4) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-ready {
|
||||||
|
background: linear-gradient(45deg, #007bff, #00d4ff) !important;
|
||||||
|
border-color: #007bff !important;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transform: scale(1.02);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-ready::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: -100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||||
|
transition: left 0.6s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-ready:hover::before {
|
||||||
|
left: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes buttonPulse {
|
||||||
|
0% {
|
||||||
|
transform: scale(1.02);
|
||||||
|
box-shadow: 0 0 10px rgba(0, 123, 255, 0.4);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 0 20px rgba(0, 123, 255, 0.6);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1.02);
|
||||||
|
box-shadow: 0 0 10px rgba(0, 123, 255, 0.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark mode adjustments for button ready states */
|
||||||
|
html[data-theme="dark"] .btn-pulse {
|
||||||
|
box-shadow: 0 0 10px rgba(96, 165, 250, 0.4) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-theme="dark"] .btn-ready {
|
||||||
|
background: linear-gradient(45deg, #3b82f6, #60a5fa) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-theme="dark"] @keyframes buttonPulse {
|
||||||
|
0% {
|
||||||
|
transform: scale(1.02);
|
||||||
|
box-shadow: 0 0 10px rgba(96, 165, 250, 0.4);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 0 20px rgba(96, 165, 250, 0.6);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1.02);
|
||||||
|
box-shadow: 0 0 10px rgba(96, 165, 250, 0.4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -45,6 +45,11 @@ class QRRapidoGenerator {
|
|||||||
this.selectedStyle = 'classic'; // Estilo padrão
|
this.selectedStyle = 'classic'; // Estilo padrão
|
||||||
this.contentValid = false;
|
this.contentValid = false;
|
||||||
|
|
||||||
|
// UX Improvements - Intelligent delay system
|
||||||
|
this.contentDelayTimer = null;
|
||||||
|
this.hasShownContentToast = false;
|
||||||
|
this.buttonReadyState = false;
|
||||||
|
|
||||||
this.initializeEvents();
|
this.initializeEvents();
|
||||||
this.checkAdFreeStatus();
|
this.checkAdFreeStatus();
|
||||||
this.updateLanguage();
|
this.updateLanguage();
|
||||||
@ -111,9 +116,25 @@ class QRRapidoGenerator {
|
|||||||
let timer;
|
let timer;
|
||||||
qrContent.addEventListener('input', (e) => {
|
qrContent.addEventListener('input', (e) => {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
|
// Clear URL validation timeout if exists
|
||||||
|
if (qrContent.validationTimeout) {
|
||||||
|
clearTimeout(qrContent.validationTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
timer = setTimeout(() => {
|
timer = setTimeout(() => {
|
||||||
this.handleContentChange(e.target.value);
|
this.handleContentChange(e.target.value);
|
||||||
this.updateGenerateButton();
|
this.updateGenerateButton();
|
||||||
|
|
||||||
|
// Handle URL-specific validation
|
||||||
|
const type = document.getElementById('qr-type')?.value;
|
||||||
|
if (type === 'url') {
|
||||||
|
qrContent.validationTimeout = setTimeout(() => {
|
||||||
|
this.updateGenerateButton();
|
||||||
|
}, 200); // Additional URL validation delay
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger UX improvements with delay
|
||||||
|
this.handleContentInputWithDelay(e.target.value);
|
||||||
}, 300);
|
}, 300);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -391,7 +412,6 @@ class QRRapidoGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sending request to backend
|
// Sending request to backend
|
||||||
|
|
||||||
const response = await fetch(requestData.endpoint, fetchOptions);
|
const response = await fetch(requestData.endpoint, fetchOptions);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
@ -1057,7 +1077,9 @@ class QRRapidoGenerator {
|
|||||||
console.log('Calling showUnlimitedCounter directly for logged user');
|
console.log('Calling showUnlimitedCounter directly for logged user');
|
||||||
this.showUnlimitedCounter();
|
this.showUnlimitedCounter();
|
||||||
} else {
|
} else {
|
||||||
console.log('GetUserStats response not ok:', response.status);
|
if (response.status !== 401) {
|
||||||
|
console.log('GetUserStats response not ok:', response.status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// If not authenticated or error, keep the default "Carregando..." text
|
// If not authenticated or error, keep the default "Carregando..." text
|
||||||
@ -1200,9 +1222,9 @@ class QRRapidoGenerator {
|
|||||||
|
|
||||||
// Create SVG with embedded base64 image
|
// Create SVG with embedded base64 image
|
||||||
const svgData = `<?xml version="1.0" encoding="UTF-8"?>
|
const svgData = `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<svg width="${img.width}" height="${img.height}" xmlns="http://www.w3.org/2000/svg">
|
<svg width="${img.width}" height="${img.height}" xmlns="http://www.w3.org/2000/svg">
|
||||||
<image width="${img.width}" height="${img.height}" href="data:image/png;base64,${base64Data}"/>
|
<image width="${img.width}" height="${img.height}" href="data:image/png;base64,${base64Data}"/>
|
||||||
</svg>`;
|
</svg>`;
|
||||||
resolve(svgData);
|
resolve(svgData);
|
||||||
};
|
};
|
||||||
img.src = `data:image/png;base64,${base64Data}`;
|
img.src = `data:image/png;base64,${base64Data}`;
|
||||||
@ -1581,42 +1603,41 @@ class QRRapidoGenerator {
|
|||||||
setupURLValidationListeners() {
|
setupURLValidationListeners() {
|
||||||
const contentField = document.getElementById('qr-content');
|
const contentField = document.getElementById('qr-content');
|
||||||
if (!contentField) return;
|
if (!contentField) return;
|
||||||
|
|
||||||
|
//const contentField = document.getElementById('qr-content');
|
||||||
|
//if (!contentField) return;
|
||||||
|
|
||||||
// Auto-fix URL on blur (when user leaves the field)
|
//// Auto-fix URL on blur (when user leaves the field)
|
||||||
contentField.addEventListener('blur', () => {
|
//contentField.addEventListener('blur', () => {
|
||||||
const type = document.getElementById('qr-type')?.value;
|
// const type = document.getElementById('qr-type')?.value;
|
||||||
|
|
||||||
if (type === 'url' && contentField.value.trim()) {
|
// if (type === 'url' && contentField.value.trim()) {
|
||||||
const originalValue = contentField.value.trim();
|
// const originalValue = contentField.value.trim();
|
||||||
const fixedValue = this.autoFixURL(originalValue);
|
// const fixedValue = this.autoFixURL(originalValue);
|
||||||
|
|
||||||
if (originalValue !== fixedValue) {
|
// if (originalValue !== fixedValue) {
|
||||||
contentField.value = fixedValue;
|
// contentField.value = fixedValue;
|
||||||
console.log('🔧 URL auto-corrigida:', originalValue, '→', fixedValue);
|
// console.log('🔧 URL auto-corrigida:', originalValue, '→', fixedValue);
|
||||||
|
|
||||||
// Revalidar após correção
|
// // Revalidar após correção
|
||||||
this.updateGenerateButton();
|
// this.updateGenerateButton();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
});
|
//});
|
||||||
|
|
||||||
// Real-time validation with debounce
|
// Note: Real-time validation is now handled in initializeEvents() to avoid duplicate listeners
|
||||||
contentField.addEventListener('input', () => {
|
|
||||||
const type = document.getElementById('qr-type')?.value;
|
|
||||||
|
|
||||||
if (type === 'url') {
|
|
||||||
// Debounce para não validar a cada caractere
|
|
||||||
clearTimeout(contentField.validationTimeout);
|
|
||||||
contentField.validationTimeout = setTimeout(() => {
|
|
||||||
this.updateGenerateButton();
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTypeSelection(type) {
|
handleTypeSelection(type) {
|
||||||
this.selectedType = type;
|
this.selectedType = type;
|
||||||
|
|
||||||
|
// Reset UX improvements flags for new type selection
|
||||||
|
this.hasShownContentToast = false;
|
||||||
|
if (this.contentDelayTimer) {
|
||||||
|
clearTimeout(this.contentDelayTimer);
|
||||||
|
}
|
||||||
|
this.removeButtonReadyState();
|
||||||
|
|
||||||
if (type) {
|
if (type) {
|
||||||
this.removeInitialHighlight();
|
this.removeInitialHighlight();
|
||||||
// Sempre habilitar campos de conteúdo após selecionar tipo
|
// Sempre habilitar campos de conteúdo após selecionar tipo
|
||||||
@ -1647,6 +1668,139 @@ class QRRapidoGenerator {
|
|||||||
this.updateGenerateButton();
|
this.updateGenerateButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UX Improvements - Intelligent delay system
|
||||||
|
handleContentInputWithDelay(content) {
|
||||||
|
// Clear existing timer
|
||||||
|
if (this.contentDelayTimer) {
|
||||||
|
clearTimeout(this.contentDelayTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only proceed with delay logic if we have valid content and selected type
|
||||||
|
if (this.selectedType && this.validateContent(content) && !this.hasShownContentToast) {
|
||||||
|
this.contentDelayTimer = setTimeout(() => {
|
||||||
|
this.triggerContentReadyUX();
|
||||||
|
}, 2000); // 2 seconds delay after the initial 300ms debounce
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerContentReadyUX() {
|
||||||
|
if (this.selectedType && this.contentValid && !this.hasShownContentToast) {
|
||||||
|
// Mark as shown to prevent multiple toasts
|
||||||
|
this.hasShownContentToast = true;
|
||||||
|
|
||||||
|
const contentField = document.getElementById('qr-content');
|
||||||
|
const originalValue = contentField.value.trim();
|
||||||
|
const fixedValue = this.autoFixURL(originalValue);
|
||||||
|
if (originalValue !== fixedValue) {
|
||||||
|
contentField.value = fixedValue;
|
||||||
|
this.updateGenerateButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show educational toast
|
||||||
|
this.showContentAddedToast();
|
||||||
|
|
||||||
|
// Update button state with ready indicator
|
||||||
|
this.updateGenerateButtonToReady();
|
||||||
|
|
||||||
|
// Auto scroll to QR generation area
|
||||||
|
this.smoothScrollToQRArea();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showContentAddedToast() {
|
||||||
|
const toastTitle = window.QRRapidoTranslations?.contentAddedToastTitle || '✅ Conteúdo adicionado!';
|
||||||
|
const toastMessage = window.QRRapidoTranslations?.contentAddedToastMessage ||
|
||||||
|
'Use as avançadas abaixo para personalizar o QR. \n Clique em "Gerar QR Code" quando estiver pronto.';
|
||||||
|
|
||||||
|
const fullMessage = `<strong>${toastTitle}</strong><br/>${toastMessage}`;
|
||||||
|
|
||||||
|
// Create educational toast similar to existing system but with longer duration
|
||||||
|
const toast = this.createEducationalToast(fullMessage);
|
||||||
|
this.showGuidanceToast(toast, 10000); // 10 seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
createEducationalToast(message) {
|
||||||
|
const toast = document.createElement('div');
|
||||||
|
toast.className = 'toast align-items-center text-bg-success border-0';
|
||||||
|
toast.setAttribute('role', 'alert');
|
||||||
|
toast.style.minWidth = '400px';
|
||||||
|
toast.id = 'content-added-toast';
|
||||||
|
toast.innerHTML = `
|
||||||
|
<div class="d-flex">
|
||||||
|
<div class="toast-body fw-medium">
|
||||||
|
${message}
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
return toast;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateGenerateButtonToReady() {
|
||||||
|
const generateBtn = document.getElementById('generate-btn');
|
||||||
|
if (generateBtn && this.contentValid) {
|
||||||
|
this.buttonReadyState = true;
|
||||||
|
|
||||||
|
// Add visual ready state
|
||||||
|
generateBtn.classList.add('btn-pulse', 'btn-ready');
|
||||||
|
|
||||||
|
// Update button text with ready indicator
|
||||||
|
const readyText = window.QRRapidoTranslations?.generateButtonReady || '✨ Pronto para gerar!';
|
||||||
|
const originalHtml = generateBtn.innerHTML;
|
||||||
|
|
||||||
|
// Store original for restoration
|
||||||
|
if (!generateBtn.dataset.originalHtml) {
|
||||||
|
generateBtn.dataset.originalHtml = originalHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
generateBtn.innerHTML = `<i class="fas fa-bolt"></i> ${readyText}`;
|
||||||
|
|
||||||
|
// Remove ready state after 5 seconds
|
||||||
|
setTimeout(() => {
|
||||||
|
this.removeButtonReadyState();
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removeButtonReadyState() {
|
||||||
|
const generateBtn = document.getElementById('generate-btn');
|
||||||
|
if (generateBtn && generateBtn.dataset.originalHtml) {
|
||||||
|
generateBtn.classList.remove('btn-pulse', 'btn-ready');
|
||||||
|
generateBtn.innerHTML = generateBtn.dataset.originalHtml;
|
||||||
|
this.buttonReadyState = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
smoothScrollToQRArea() {
|
||||||
|
// Wait a bit for the toast to appear, then scroll
|
||||||
|
setTimeout(() => {
|
||||||
|
let targetElement;
|
||||||
|
|
||||||
|
// Find the QR preview area or advanced options
|
||||||
|
const qrPreview = document.getElementById('qr-result');
|
||||||
|
const advancedSection = document.querySelector('.advanced-options');
|
||||||
|
const generateBtn = document.getElementById('generate-btn');
|
||||||
|
const toast = document.getElementById('content-added-toast');
|
||||||
|
|
||||||
|
// Priority: QR result > Advanced options > Generate button
|
||||||
|
targetElement = qrPreview || advancedSection || toast || generateBtn;
|
||||||
|
|
||||||
|
if (targetElement) {
|
||||||
|
// Calculate offset - less aggressive on mobile
|
||||||
|
const isMobile = window.innerWidth <= 768;
|
||||||
|
const offset = isMobile ? 20 : 100;
|
||||||
|
|
||||||
|
const elementPosition = targetElement.getBoundingClientRect().top + window.pageYOffset;
|
||||||
|
const offsetPosition = elementPosition - offset;
|
||||||
|
|
||||||
|
window.scrollTo({
|
||||||
|
top: offsetPosition,
|
||||||
|
behavior: 'smooth'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000); // 1 second delay to let toast show first
|
||||||
|
}
|
||||||
|
|
||||||
enableContentFields(type) {
|
enableContentFields(type) {
|
||||||
const contentGroup = document.getElementById('content-group');
|
const contentGroup = document.getElementById('content-group');
|
||||||
const vcardInterface = document.getElementById('vcard-interface');
|
const vcardInterface = document.getElementById('vcard-interface');
|
||||||
@ -1966,7 +2120,7 @@ class QRRapidoGenerator {
|
|||||||
// In a real implementation, these would come from server-side localization
|
// In a real implementation, these would come from server-side localization
|
||||||
// For now, we'll use the JavaScript language strings or fallback to Portuguese
|
// For now, we'll use the JavaScript language strings or fallback to Portuguese
|
||||||
return {
|
return {
|
||||||
'url': document.querySelector('[data-type-guide-url]')?.textContent || '🌐 Para gerar QR de URL, digite o endereço completo (ex: https://google.com)',
|
//'url': document.querySelector('[data-type-guide-url]')?.textContent || '🌐 Para gerar QR de URL, digite o endereço completo (ex: https://google.com)',
|
||||||
'vcard': document.querySelector('[data-type-guide-vcard]')?.textContent || '👤 Para cartão de visita, preencha nome, telefone e email nos campos abaixo',
|
'vcard': document.querySelector('[data-type-guide-vcard]')?.textContent || '👤 Para cartão de visita, preencha nome, telefone e email nos campos abaixo',
|
||||||
'wifi': document.querySelector('[data-type-guide-wifi]')?.textContent || '📶 Para WiFi, informe nome da rede, senha e tipo de segurança',
|
'wifi': document.querySelector('[data-type-guide-wifi]')?.textContent || '📶 Para WiFi, informe nome da rede, senha e tipo de segurança',
|
||||||
'sms': document.querySelector('[data-type-guide-sms]')?.textContent || '💬 Para SMS, digite o número do destinatário e a mensagem',
|
'sms': document.querySelector('[data-type-guide-sms]')?.textContent || '💬 Para SMS, digite o número do destinatário e a mensagem',
|
||||||
@ -2007,7 +2161,9 @@ class QRRapidoGenerator {
|
|||||||
toastContainer = existingContainer;
|
toastContainer = existingContainer;
|
||||||
} else {
|
} else {
|
||||||
// Find the main content area and insert after hero section
|
// Find the main content area and insert after hero section
|
||||||
const mainElement = document.querySelector('main[role="main"]');
|
// const mainElement = document.querySelector('main[role="main"]');
|
||||||
|
const mainElement = document.getElementById('customization-accordion');
|
||||||
|
|
||||||
if (mainElement) {
|
if (mainElement) {
|
||||||
// Insert at the beginning of main content
|
// Insert at the beginning of main content
|
||||||
mainElement.insertBefore(toastContainer, mainElement.firstChild);
|
mainElement.insertBefore(toastContainer, mainElement.firstChild);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user