QrRapido/Views/Home/Index.cshtml
Ricardo Carneiro 70fbdaa3c2
Some checks failed
Deploy QR Rapido / test (push) Successful in 3m34s
Deploy QR Rapido / build-and-push (push) Failing after 8s
Deploy QR Rapido / deploy-staging (push) Has been skipped
Deploy QR Rapido / deploy-production (push) Has been skipped
feat: opacidade enquanto não selecionar o tipo.
2025-08-04 19:45:46 -03:00

1042 lines
66 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@using QRRapidoApp.Services
@using Microsoft.Extensions.Localization
@inject AdDisplayService AdService
@inject IStringLocalizer<QRRapidoApp.Resources.SharedResource> Localizer
@{
ViewData["Title"] = "Home";
var userId = User?.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container">
<!-- Hidden input for JavaScript premium status check -->
@{
var statusValue = "anonymous";
if (User.Identity.IsAuthenticated)
{
var isPremium = await AdService.HasValidPremiumSubscription(userId);
statusValue = isPremium ? "premium" : "logged-in";
}
}
<input type="hidden" id="user-premium-status" value="@statusValue" />
<!-- Hidden localized strings for rate limiting -->
<div style="display: none;">
<span data-localized="RateLimitExceeded">@Localizer["RateLimitExceeded"]</span>
<span data-localized="QRCodesRemainingToday">@Localizer["QRCodesRemainingToday"]</span>
<span data-localized="UnlimitedToday">@Localizer["UnlimitedToday"]</span>
</div>
<div class="row">
<!-- QR Generator Form -->
<div class="col-lg-8">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h3 class="h5 mb-0">
<i class="fas fa-qrcode"></i> @Localizer["CreateQRCodeQuickly"]
</h3>
</div>
<div class="card-body">
@if (User.Identity.IsAuthenticated)
{
var isPremium = await AdService.HasValidPremiumSubscription(userId);
@if (isPremium)
{
<div class="alert alert-success border-0">
<i class="fas fa-crown text-warning"></i>
<strong>@Localizer["PremiumUserActive"]</strong>
<span class="badge bg-success">@Localizer["NoAdsHistoryUnlimitedQR"]</span>
</div>
}
}
<form id="qr-speed-form" class="needs-validation" novalidate>
<!-- Generation timer -->
<div class="row mb-3">
<div class="col-md-8">
<div class="d-flex align-items-center gap-3">
<div class="generation-timer d-none">
<i class="fas fa-stopwatch text-primary"></i>
<span class="fw-bold text-primary">0.0s</span>
</div>
<div class="speed-badge d-none">
<span class="badge bg-success">
<i class="fas fa-bolt"></i> @Localizer["UltraFastGeneration"]
</span>
</div>
</div>
</div>
<div class="col-md-4 text-end">
<small class="text-muted">
<span class="qr-counter">Carregando...</span>
</small>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label fw-semibold">
<i class="fas fa-list"></i> @Localizer["QRCodeType"]
</label>
<select id="qr-type" class="form-select qr-type-highlight" required>
<option value="">@Localizer["SelectType"]</option>
<option value="url">🌐 @Localizer["URLLink"]</option>
<option value="text">📝 @Localizer["SimpleText"]</option>
<option value="wifi">📶 @Localizer["WiFi"]</option>
<option value="vcard">👤 @Localizer["VCard"]</option>
<option value="sms">💬 @Localizer["SMS"]</option>
<option value="email">📧 @Localizer["Email"]</option>
</select>
<div class="type-selection-hint" id="type-selection-hint">
<i class="fas fa-hand-point-up"></i>
<span>@Localizer["ChooseTypeFirst"]</span>
</div>
<!-- Hidden localized guidance messages for JavaScript -->
<div style="display: none;">
<span data-type-guide-url>@Localizer["TypeGuideURL"]</span>
<span data-type-guide-vcard>@Localizer["TypeGuideVCard"]</span>
<span data-type-guide-wifi>@Localizer["TypeGuideWiFi"]</span>
<span data-type-guide-sms>@Localizer["TypeGuideSMS"]</span>
<span data-type-guide-email>@Localizer["TypeGuideEmail"]</span>
<span data-type-guide-text>@Localizer["TypeGuideText"]</span>
</div>
</div>
<div class="col-md-6 mb-3 opacity-controlled disabled-state" id="quick-style-group">
<label class="form-label fw-semibold">
<i class="fas fa-palette"></i> @Localizer["QuickStyle"]
</label>
<div class="btn-group w-100" role="group">
<input type="radio" class="btn-check" name="quick-style" id="style-classic" value="classic" checked>
<label class="btn btn-outline-secondary" for="style-classic">@Localizer["Classic"]</label>
<input type="radio" class="btn-check" name="quick-style" id="style-modern" value="modern">
<label class="btn btn-outline-secondary" for="style-modern">@Localizer["Modern"]</label>
<input type="radio" class="btn-check" name="quick-style" id="style-colorful" value="colorful">
<label class="btn btn-outline-secondary" for="style-colorful">@Localizer["Colorful"]</label>
</div>
</div>
</div>
<div class="mb-3 opacity-controlled disabled-state" id="content-group">
<label class="form-label fw-semibold">
<i class="fas fa-edit"></i> @Localizer["Content"]
</label>
<textarea id="qr-content"
class="form-control form-control-lg required-field"
rows="3"
placeholder="@Localizer["EnterQRCodeContent"]"
required></textarea>
<div class="invalid-feedback">Conteúdo deve ter pelo menos 3 caracteres</div>
<div class="form-text">
<span id="content-hints">@Localizer["ContentHints"]</span>
</div>
</div>
<!-- Dynamic QR Section (Premium) -->
<div id="dynamic-qr-section" style="display: none;" class="opacity-controlled disabled-state">
<div class="premium-feature-box">
<div class="d-flex align-items-center justify-content-between">
<div>
<h6 class="mb-1">
<i class="fas fa-chart-line text-warning"></i> QR Dinâmico - Premium
</h6>
<small class="text-muted">
QR Code com seu logotipo!
</small>
</div>
<div class="form-check form-switch">
@if (ViewBag.IsPremium == true)
{
<input class="form-check-input" type="checkbox" id="qr-dynamic-toggle" style="display: none;">
<label class="form-check-label" for="qr-dynamic-toggle">
Adicione o logotivo na Personalização avançada
</label>
}
else
{
<div class="premium-upgrade-prompt">
<input class="form-check-input" type="checkbox" disabled style="display: none;">
<label class="form-check-label" for="qr-dynamic-toggle">
Gerar QR Code com logotipo? Assine o plano premium!
</label>
<br>
<small>
<a href="/Pagamento/SelecaoPlano" class="text-warning">
Upgrade Premium
</a> QR Code com logotipo
</small>
</div>
}
</div>
</div>
</div>
</div>
<!-- URL Preview -->
<div id="url-preview" class="mt-3 opacity-controlled disabled-state" style="display: none;">
<h6><i class="fas fa-link"></i> Preview</h6>
<div id="url-preview-content" class="bg-light p-3 rounded">
<strong>URL Final:</strong> <span id="final-url-display"></span><br>
<strong>Tipo:</strong> <span id="qr-type-display">QR Code Estático</span>
</div>
</div>
<!-- VCard Interface (dynamic) -->
<div id="vcard-interface" class="mb-3 opacity-controlled disabled-state" style="display: none;">
<div class="alert alert-info">
<i class="fas fa-address-card"></i>
<strong>Cartão de Visita Digital</strong> - Este QR Code criará um cartão de visita digital.
Quando escaneado, oferecerá para salvar seus contatos automaticamente.
</div>
<!-- Campos Obrigatórios -->
<div class="required-fields mb-4">
<h6 class="fw-bold text-primary mb-3">
<i class="fas fa-user-check"></i> Informações Essenciais
</h6>
<div class="row">
<div class="col-md-12 mb-3">
<label class="form-label fw-semibold">Nome Completo *</label>
<input type="text" id="vcard-name" class="form-control required-field" placeholder="Seu Nome Completo" required>
<div class="invalid-feedback">Nome é obrigatório</div>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label fw-semibold">Telefone Celular *</label>
<input type="tel" id="vcard-mobile" class="form-control required-field" placeholder="11999998888" required>
<small class="form-text text-muted">Apenas números (DDD + número)</small>
<div class="invalid-feedback">Telefone celular é obrigatório</div>
</div>
<div class="col-md-6 mb-3">
<label class="form-label fw-semibold">Email *</label>
<input type="email" id="vcard-email" class="form-control required-field" placeholder="seu.email@exemplo.com" required>
<div class="invalid-feedback">Email válido é obrigatório</div>
</div>
</div>
</div>
<!-- Campos Opcionais -->
<div class="optional-fields mb-4">
<h6 class="fw-bold text-secondary mb-3">
<i class="fas fa-plus-circle"></i> Informações Adicionais (Opcionais)
</h6>
<!-- Empresa -->
<div class="mb-3">
<div class="form-check mb-2">
<input type="checkbox" id="enable-company" class="form-check-input">
<label for="enable-company" class="form-check-label fw-semibold">
<i class="fas fa-building"></i> Empresa
</label>
</div>
<div class="form-group" id="company-group" style="display: none;">
<input type="text" id="vcard-company" class="form-control" placeholder="Nome da Empresa">
</div>
</div>
<!-- Cargo -->
<div class="mb-3">
<div class="form-check mb-2">
<input type="checkbox" id="enable-title" class="form-check-input">
<label for="enable-title" class="form-check-label fw-semibold">
<i class="fas fa-id-badge"></i> Cargo/Título
</label>
</div>
<div class="form-group" id="title-group" style="display: none;">
<input type="text" id="vcard-title" class="form-control" placeholder="CEO, Gerente, Desenvolvedor, etc.">
</div>
</div>
<!-- Website -->
<div class="mb-3">
<div class="form-check mb-2">
<input type="checkbox" id="enable-website" class="form-check-input">
<label for="enable-website" class="form-check-label fw-semibold">
<i class="fas fa-globe"></i> Website
</label>
</div>
<div class="form-group" id="website-group" style="display: none;">
<input type="url" id="vcard-website" class="form-control" placeholder="https://seusite.com">
</div>
</div>
<!-- Telefone Fixo -->
<div class="mb-3">
<div class="form-check mb-2">
<input type="checkbox" id="enable-phone" class="form-check-input">
<label for="enable-phone" class="form-check-label fw-semibold">
<i class="fas fa-phone"></i> Telefone Fixo
</label>
</div>
<div class="form-group" id="phone-group" style="display: none;">
<input type="tel" id="vcard-phone" class="form-control" placeholder="1133334444">
<small class="form-text text-muted">Apenas números (DDD + número)</small>
</div>
</div>
<!-- Endereço -->
<div class="mb-3">
<div class="form-check mb-2">
<input type="checkbox" id="enable-address" class="form-check-input">
<label for="enable-address" class="form-check-label fw-semibold">
<i class="fas fa-map-marker-alt"></i> Endereço
</label>
</div>
<div id="address-group" style="display: none;">
<div class="form-group mb-2">
<input type="text" id="vcard-address" class="form-control" placeholder="Rua, número - Ex: Rua das Flores, 123">
</div>
<div class="row">
<div class="col-md-4">
<input type="text" id="vcard-city" class="form-control" placeholder="Cidade">
</div>
<div class="col-md-4">
<input type="text" id="vcard-state" class="form-control" placeholder="Estado">
</div>
<div class="col-md-4">
<input type="text" id="vcard-zip" class="form-control" placeholder="CEP">
</div>
</div>
</div>
</div>
</div>
<!-- Preview do VCard -->
<div class="vcard-preview mb-3">
<h6 class="fw-bold text-success mb-2">
<i class="fas fa-eye"></i> Preview do Cartão
</h6>
<div class="card bg-light">
<div class="card-body">
<pre id="vcard-preview-text" class="mb-0 small text-muted">BEGIN:VCARD
VERSION:3.0
CHARSET=UTF-8
Preencha os campos acima para ver o preview...
END:VCARD
</pre>
</div>
</div>
</div>
</div>
<!-- WiFi Interface (dynamic) -->
<div id="wifi-interface" class="mb-3 opacity-controlled disabled-state" style="display: none;">
<div class="alert alert-info">
<i class="fas fa-wifi"></i>
<strong>@Localizer["WiFiQRTitle"]</strong> - @Localizer["WiFiQRDescription"]
</div>
<div class="form-group mb-3">
<label class="form-label fw-semibold">@Localizer["NetworkName"] *</label>
<input type="text" id="wifi-ssid" name="wifi-ssid" class="form-control" placeholder="NomeDaSuaRede" required>
<div class="invalid-feedback">@Localizer["NetworkNameRequired"]</div>
</div>
<div class="form-group mb-3">
<label class="form-label fw-semibold">@Localizer["SecurityType"]</label>
<div class="form-check">
<input class="form-check-input" type="radio" name="wifi-security" id="wifi-security-wpa" value="WPA" checked>
<label class="form-check-label" for="wifi-security-wpa">@Localizer["WPARecommended"]</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="wifi-security" id="wifi-security-wep" value="WEP">
<label class="form-check-label" for="wifi-security-wep">@Localizer["WEPLegacy"]</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="wifi-security" id="wifi-security-nopass" value="nopass">
<label class="form-check-label" for="wifi-security-nopass">@Localizer["OpenNetwork"]</label>
</div>
</div>
<div class="form-group mb-3" id="wifi-password-group">
<label class="form-label fw-semibold">@Localizer["NetworkPassword"] *</label>
<div class="input-group">
<input type="password" id="wifi-password" name="wifi-password" class="form-control" placeholder="SenhaDaSuaRede" required>
<button class="btn btn-outline-secondary" type="button" id="toggle-password">
<i class="fas fa-eye"></i>
</button>
</div>
<div class="invalid-feedback">@Localizer["PasswordRequiredForSecure"]</div>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="wifi-hidden" name="wifi-hidden">
<label class="form-check-label" for="wifi-hidden">@Localizer["HiddenNetwork"]</label>
</div>
<div class="wifi-preview">
<h6 class="fw-bold text-success mb-2">
<i class="fas fa-eye"></i> @Localizer["WiFiPreviewTitle"]
</h6>
<div class="card bg-light">
<div class="card-body">
<pre id="wifi-preview-text" class="mb-0 small text-muted">WIFI:T:WPA;S:;P:;H:false;;</pre>
</div>
</div>
</div>
</div>
<!-- WiFi Interface (dynamic) -->
<div id="wifi-interface" class="mb-3" style="display: none;">
<div class="alert alert-info">
<i class="fas fa-wifi"></i>
<strong>@Localizer["WiFiQRTitle"]</strong> - @Localizer["WiFiQRDescription"]
</div>
<div class="form-group mb-3">
<label class="form-label fw-semibold">@Localizer["NetworkName"] *</label>
<input type="text" id="wifi-ssid2" class="form-control" placeholder="NomeDaSuaRede" required>
<div class="invalid-feedback">@Localizer["NetworkNameRequired"]</div>
</div>
<div class="form-group mb-3">
<label class="form-label fw-semibold">@Localizer["SecurityType"]</label>
<div class="form-check">
<input class="form-check-input" type="radio" name="wifi-security" id="wifi-security-wpa2" value="WPA" checked>
<label class="form-check-label" for="wifi-security-wpa">@Localizer["WPARecommended"]</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="wifi-security" id="wifi-security-wep2" value="WEP">
<label class="form-check-label" for="wifi-security-wep">@Localizer["WEPLegacy"]</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="wifi-security" id="wifi-security-nopass2" value="nopass">
<label class="form-check-label" for="wifi-security-nopass">@Localizer["OpenNetwork"]</label>
</div>
</div>
<div class="form-group mb-3" id="wifi-password-group">
<label class="form-label fw-semibold">@Localizer["NetworkPassword"] *</label>
<div class="input-group">
<input type="password" id="wifi-password2" class="form-control" placeholder="SenhaDaSuaRede" required>
<button class="btn btn-outline-secondary" type="button" id="toggle-password2">
<i class="fas fa-eye"></i>
</button>
</div>
<div class="invalid-feedback">@Localizer["PasswordRequiredForSecure"]</div>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="wifi-hidden2">
<label class="form-check-label" for="wifi-hidden">@Localizer["HiddenNetwork"]</label>
</div>
<div class="wifi-preview">
<h6 class="fw-bold text-success mb-2">
<i class="fas fa-eye"></i> @Localizer["WiFiPreviewTitle"]
</h6>
<div class="card bg-light">
<div class="card-body">
<pre id="wifi-preview-text" class="mb-0 small text-muted">WIFI:T:WPA;S:;P:;H:false;;</pre>
</div>
</div>
</div>
</div>
<!-- SMS Interface (dynamic) -->
<div id="sms-interface" class="mb-3" style="display: none;">
<div class="alert alert-info">
<strong>QR Code SMS:</strong> Permite enviar SMS automático com número e mensagem pré-definidos.
Compatível com Android, iOS e dispositivos modernos.
</div>
<div class="form-group mb-3">
<label class="form-label fw-semibold">Número do Celular *</label>
<input type="tel" id="sms-number" name="sms-number" class="form-control" placeholder="11999998888" required>
<small class="text-muted">Apenas números (DDD + número, sem espaços)</small>
</div>
<div class="form-group mb-3">
<label class="form-label fw-semibold">Mensagem *</label>
<textarea id="sms-message" name="sms-message" class="form-control" rows="3" placeholder="Sua mensagem aqui..." required></textarea>
<small class="text-muted">Mensagem que será pré-preenchida no SMS</small>
</div>
<div class="sms-preview">
<h6> Preview do SMS</h6>
<pre id="sms-preview-text" class="bg-light p-3 rounded">SMSTO::</pre>
</div>
</div>
<!-- Email Interface (dynamic) -->
<div id="email-interface" class="mb-3 opacity-controlled disabled-state" style="display: none;">
<div class="alert alert-info">
<strong>QR Code Email:</strong> Permite enviar email automático com destinatário, assunto e mensagem pré-definidos.
Compatível com Android, iOS e dispositivos modernos.
</div>
<div class="form-group mb-3">
<label class="form-label fw-semibold">Email Destinatário *</label>
<input type="email" id="email-to" name="email-to" class="form-control" placeholder="contato@empresa.com" required>
<small class="text-muted">Email que receberá a mensagem</small>
</div>
<div class="form-group mb-3">
<label class="form-label fw-semibold">Assunto *</label>
<input type="text" id="email-subject" name="email-subject" class="form-control" placeholder="Assunto do email" required>
<small class="text-muted">Linha de assunto do email</small>
</div>
<div class="form-group mb-3">
<label class="form-label fw-semibold">Mensagem</label>
<textarea id="email-body" name="email-body" class="form-control" rows="4" placeholder="Corpo da mensagem..."></textarea>
<small class="text-muted">Corpo da mensagem (opcional)</small>
</div>
<div class="email-preview">
<h6> Preview do Email</h6>
<pre id="email-preview-text" class="bg-light p-3 rounded">mailto:?subject=&body=</pre>
</div>
</div>
<!-- Advanced customization (collapsible) -->
<div class="accordion mb-3 opacity-controlled disabled-state" id="customization-accordion">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#customization-panel">
<i class="fas fa-sliders-h me-2"></i> @Localizer["AdvancedCustomization"]
</button>
</h2>
<div id="customization-panel" class="accordion-collapse collapse">
<div class="accordion-body">
<div class="row">
<div class="col-md-3 mb-3">
<label class="form-label">@Localizer["PrimaryColor"]</label>
<input type="color" id="primary-color" class="form-control form-control-color" value="#007BFF">
</div>
<div class="col-md-3 mb-3">
<label class="form-label">@Localizer["BackgroundColor"]</label>
<input type="color" id="bg-color" class="form-control form-control-color" value="#FFFFFF">
</div>
<div class="col-md-3 mb-3">
<label class="form-label">@Localizer["Size"]</label>
<select id="qr-size" class="form-select">
<option value="200">@Localizer["SmallSize200px"]</option>
<option value="300" selected>@Localizer["MediumSize300px"]</option>
<option value="500">@Localizer["LargeSize500px"]</option>
<option value="800">@Localizer["XLSize800px"]</option>
</select>
</div>
<div class="col-md-3 mb-3">
<label class="form-label">@Localizer["Margin"]</label>
<select id="qr-margin" class="form-select">
<option value="1">@Localizer["Minimal"]</option>
<option value="2" selected>@Localizer["Normal"]</option>
<option value="4">@Localizer["Large"]</option>
</select>
</div>
</div>
@if (User.Identity.IsAuthenticated)
{
<div class="row">
@{
var userService = Context.RequestServices.GetService<QRRapidoApp.Services.IUserService>();
var currentUserId = User?.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
var currentUser = currentUserId != null ? await userService.GetUserAsync(currentUserId) : null;
var isPremium = currentUser?.IsPremium == true;
}
@if (isPremium)
{
<!-- Seção de Logo Premium Aprimorada -->
<div class="col-md-12 mb-3">
<div class="premium-feature-box p-3 border rounded bg-light">
<h6 class="fw-bold mb-3">
<i class="fas fa-crown text-warning"></i>
Logo Personalizado - Premium
</h6>
<!-- Upload de Logo -->
<div class="row mb-3">
<div class="col-md-6">
<label class="form-label fw-semibold">
<i class="fas fa-image"></i> Upload do Logo
</label>
<input type="file" id="logo-upload" class="form-control" accept="image/png,image/jpeg,image/jpg">
<div class="form-text">PNG ou JPG, máximo 2MB, recomendado: formato quadrado</div>
<div id="logo-preview" class="mt-2 d-none">
<small class="text-success">
<i class="fas fa-check-circle"></i>
<span id="logo-filename"></span>
</small>
</div>
</div>
<!-- Preview Visual do Logo -->
<div class="col-md-6">
<div id="logo-visual-preview" style="display: none;">
<label class="form-label fw-semibold">
<i class="fas fa-eye"></i> Preview
</label>
<div class="d-flex align-items-center gap-3">
<div class="logo-preview-container border rounded p-2 bg-white" style="width: 60px; height: 60px; display: flex; align-items: center; justify-content: center;">
<img id="logo-preview-image" src="" alt="Preview" style="max-width: 100%; max-height: 100%; object-fit: contain;">
</div>
<div class="text-muted small">
<div>Tamanho: <span id="preview-size-text">20%</span></div>
<div>Colorização: <span id="preview-colorize-text">Desativada</span></div>
</div>
</div>
</div>
</div>
</div>
<!-- Controles Avançados -->
<div class="row mb-3">
<div class="col-md-6">
<label class="form-label fw-semibold">
<i class="fas fa-expand-arrows-alt"></i> Tamanho do Logo
</label>
<div class="d-flex align-items-center gap-2">
<input type="range" id="logo-size-slider" class="form-range flex-grow-1"
min="10" max="25" value="20" step="1">
<span class="badge bg-primary" id="logo-size-display">20%</span>
</div>
<div class="form-text">
<small>
<span class="text-muted">10% (Discreto)</span>
<span class="float-end text-muted">25% (Máximo seguro)</span>
</small>
</div>
</div>
<div class="col-md-6">
<label class="form-label fw-semibold">
<i class="fas fa-palette"></i> Colorização
</label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="logo-colorize-toggle">
<label class="form-check-label" for="logo-colorize-toggle">
Aplicar cor do QR Code no logo
</label>
</div>
<div class="form-text">
<small class="text-info">
<i class="fas fa-info-circle"></i>
Converte o logo para a cor selecionada
</small>
</div>
</div>
</div>
<!-- Dicas de Otimização -->
<div class="alert alert-info border-0 mb-0 small">
<div class="row">
<div class="col-md-6">
<strong><i class="fas fa-lightbulb"></i> Dicas para Melhor Resultado:</strong>
<ul class="mb-0 mt-1">
<li>Use logos com formato quadrado ou circular</li>
<li>Prefira fundos transparentes (PNG)</li>
<li>Evite logos com muito detalhe</li>
</ul>
</div>
<div class="col-md-6">
<strong><i class="fas fa-mobile-alt"></i> Garantia de Leitura:</strong>
<ul class="mb-0 mt-1">
<li>✅ Correção de erro de 30%</li>
<li>✅ Bordas de proteção automáticas</li>
<li>✅ Testado em todos os leitores</li>
</ul>
</div>
</div>
</div>
</div>
</div>
}
else
{
<div class="col-md-6 mb-3">
<div class="premium-upgrade-box p-3 border rounded bg-light">
<h6 class="fw-bold mb-2">
<i class="fas fa-crown text-warning"></i>
Logo Personalizado - Premium
</h6>
<p class="mb-2 small">Adicione sua marca aos QR Codes! Agora com tamanho configurável (10-25%) e colorização automática.</p>
<a href="/Pagamento/SelecaoPlano" class="btn btn-warning btn-sm">
<i class="fas fa-arrow-up"></i> Fazer Upgrade
</a>
</div>
</div>
}
<div class="col-md-6 mb-3">
<label class="form-label">@Localizer["BorderStyle"]</label>
<select id="corner-style" class="form-select @(isPremium ? "" : "border-warning")">
<option value="square">@Localizer["Square"] (Grátis)</option>
@if (isPremium)
{
<option value="rounded">@Localizer["Rounded"] 👑</option>
<option value="circle">Círculos 👑</option>
<option value="leaf">Folha 👑</option>
}
else
{
<option value="rounded" disabled>@Localizer["Rounded"] - Premium 👑</option>
<option value="circle" disabled>Círculos - Premium 👑</option>
<option value="leaf" disabled>Folha - Premium 👑</option>
}
</select>
@if (!isPremium)
{
<div class="form-text text-warning">
<i class="fas fa-crown"></i>
<a href="/Pagamento/SelecaoPlano" class="text-warning">Upgrade Premium</a> para estilos personalizados
</div>
}
</div>
</div>
}
</div>
</div>
</div>
</div>
<div class="d-grid opacity-controlled disabled-state" id="button-gerar-div">
<button type="submit" class="btn btn-primary btn-lg" id="generate-btn">
<i class="fas fa-bolt"></i> @Localizer["GenerateQRCodeQuickly"]
<div class="spinner-border spinner-border-sm ms-2 d-none" role="status">
<span class="visually-hidden">@Localizer["Generating"]</span>
</div>
</button>
</div>
</form>
</div>
</div>
<!-- Speed statistics -->
<div class="row mt-4">
<div class="col-md-4">
<div class="card text-center border-success">
<div class="card-body">
<h5 class="text-success">
<i class="fas fa-stopwatch"></i> 1.2s
</h5>
<small class="text-muted">@Localizer["AverageTime"]</small>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card text-center border-primary">
<div class="card-body">
<h5 class="text-primary">
<i class="fas fa-chart-line"></i> 99.9%
</h5>
<small class="text-muted">@Localizer["Availability"]</small>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card text-center border-warning">
<div class="card-body">
<h5 class="text-warning">
<i class="fas fa-users"></i> <span id="total-qrs">10.5K</span>
</h5>
<small class="text-muted">@Localizer["QRsGeneratedToday"]</small>
</div>
</div>
</div>
</div>
<!-- Ad Space Between Content (conditional) -->
@await Html.PartialAsync("_AdSpace", new { position = "content" })
</div>
<!-- Sidebar with preview and ads -->
<div class="col-lg-4">
<!-- Preview with timer -->
<div class="card shadow-sm mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">
<i class="fas fa-eye"></i> Preview
</h5>
<div class="generation-stats d-none">
<small class="text-success">
<i class="fas fa-check-circle"></i> Gerado em <span class="generation-time">0s</span>
</small>
</div>
</div>
<div class="card-body text-center">
<div id="qr-preview" class="mb-3">
<div class="placeholder-qr p-5">
<i class="fas fa-qrcode fa-4x text-muted mb-3"></i>
<p class="text-muted">@Localizer["YourQRCodeWillAppear"]</p>
<small class="text-muted">
<i class="fas fa-bolt"></i> @Localizer["UltraFastGenerationGuaranteed"]
</small>
</div>
</div>
<div id="download-section" style="display: none;">
<div class="btn-group-vertical w-100 mb-3">
<button id="download-png" class="btn btn-success">
<i class="fas fa-download"></i> @Localizer["DownloadPNG"]
</button>
<button id="download-svg" class="btn btn-outline-success">
<i class="fas fa-vector-square"></i> @Localizer["DownloadSVGVector"]
</button>
<button id="download-pdf" class="btn btn-outline-success">
<i class="fas fa-file-pdf"></i> @Localizer["DownloadPDF"]
</button>
</div>
<!-- Share Button with Dropdown (Temporarily Disabled) -->
<div class="dropdown w-100 mb-3">
<button class="btn btn-secondary dropdown-toggle w-100" type="button" id="share-qr-btn" disabled title="Em desenvolvimento">
<i class="fas fa-share-alt"></i> @Localizer["ShareQRCode"] (Em breve)
</button>
<ul class="dropdown-menu w-100" aria-labelledby="share-qr-btn" id="share-dropdown">
<!-- Native share option (mobile only) -->
<li class="d-none" id="native-share-option">
<a class="dropdown-item" href="#" id="native-share">
<i class="fas fa-mobile-alt text-primary"></i> @Localizer["ShareSystem"]
</a>
</li>
<!-- WhatsApp -->
<li>
<a class="dropdown-item" href="#" id="share-whatsapp">
<i class="fab fa-whatsapp text-success"></i> WhatsApp
</a>
</li>
<!-- Telegram -->
<li>
<a class="dropdown-item" href="#" id="share-telegram">
<i class="fab fa-telegram text-info"></i> Telegram
</a>
</li>
<!-- Email -->
<li>
<a class="dropdown-item" href="#" id="share-email">
<i class="fas fa-envelope text-warning"></i> Email
</a>
</li>
<!-- Copy to clipboard -->
<li>
<a class="dropdown-item" href="#" id="copy-qr-link">
<i class="fas fa-copy text-secondary"></i> Copiar Link
</a>
</li>
<!-- Save to gallery (mobile only) -->
<li class="d-none" id="save-gallery-option">
<a class="dropdown-item" href="#" id="save-to-gallery">
<i class="fas fa-images text-purple"></i> Salvar na Galeria
</a>
</li>
</ul>
</div>
@if (User.Identity.IsAuthenticated)
{
<button id="save-to-history" class="btn btn-outline-primary w-100">
<i class="fas fa-save"></i> @Localizer["SaveToHistory"]
</button>
}
else
{
<div class="text-center">
<small class="text-muted">
<a href="/Account/Login" class="text-primary">@Localizer["Login"]</a>
@Localizer["ToSaveToHistory"]
</small>
</div>
}
</div>
</div>
</div>
<!-- Premium Card for non-premium users -->
@if (User.Identity.IsAuthenticated && await AdService.ShouldShowAds(userId))
{
<div class="card border-warning mb-4">
<div class="card-header bg-warning text-dark">
<h6 class="mb-0">
<i class="fas fa-rocket"></i> QR Rapido Premium
</h6>
</div>
<div class="card-body">
<div class="text-center mb-3">
<div class="badge bg-success mb-2">@Localizer["ThreeTimesFaster"]</div>
</div>
<ul class="list-unstyled">
<li><i class="fas fa-check text-success"></i> @Localizer["NoAdsForever"]</li>
<li><i class="fas fa-check text-success"></i> @Localizer["UnlimitedQRCodes"]</li>
<li><i class="fas fa-check text-success"></i> @Localizer["PriorityGeneration"]</li>
<li><i class="fas fa-check text-success"></i> @Localizer["DynamicQRCodes"]</li>
<li><i class="fas fa-check text-success"></i> @Localizer["RealTimeAnalytics"]</li>
<li><i class="fas fa-check text-success"></i> @Localizer["DeveloperAPI"]</li>
</ul>
<div class="text-center">
<a href="/Premium/Upgrade" class="btn btn-warning w-100">
<i class="fas fa-bolt"></i> @Localizer["AcceleratePrice"]
</a>
<small class="text-muted d-block mt-1">@Localizer["CancelAnytime"]</small>
</div>
</div>
</div>
}
<!-- Speed Tips Card -->
<div class="card bg-light mb-4">
<div class="card-header">
<h6 class="mb-0">
<i class="fas fa-lightbulb text-warning"></i> @Localizer["TipsFasterQR"]
</h6>
</div>
<div class="card-body">
<ul class="list-unstyled small">
<li><i class="fas fa-arrow-right text-primary"></i> @Localizer["ShortURLsFaster"]</li>
<li><i class="fas fa-arrow-right text-primary"></i> @Localizer["LessTextMoreSpeed"]</li>
<li><i class="fas fa-arrow-right text-primary"></i> @Localizer["SolidColorsOptimize"]</li>
<li><i class="fas fa-arrow-right text-primary"></i> @Localizer["SmallerSizesAccelerate"]</li>
</ul>
</div>
</div>
<!-- Ad Space Sidebar (conditional) -->
@await Html.PartialAsync("_AdSpace", new { position = "sidebar" })
</div>
</div>
</div>
<!-- Speed Comparison Section -->
<section class="mt-5 mb-4">
<div class="container">
<div class="text-center mb-4">
<h3><i class="fas fa-tachometer-alt text-primary"></i> @Localizer["WhyQRRapidoFaster"]</h3>
<p class="text-muted">@Localizer["ComparisonOtherGenerators"]</p>
</div>
<div class="row">
<div class="col-md-3">
<div class="card h-100 border-success">
<div class="card-body text-center">
<h5 class="text-success">QR Rapido</h5>
<div class="display-4 text-success fw-bold">1.2s</div>
<p class="text-muted">@Localizer["OptimizedForSpeed"]</p>
<i class="fas fa-crown text-warning"></i>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card h-100">
<div class="card-body text-center">
<h5 class="text-muted">@Localizer["CompetitorA"]</h5>
<div class="display-4 text-muted">3.5s</div>
<p class="text-muted">@Localizer["TraditionalGenerator"]</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card h-100">
<div class="card-body text-center">
<h5 class="text-muted">@Localizer["CompetitorB"]</h5>
<div class="display-4 text-muted">4.8s</div>
<p class="text-muted">@Localizer["HeavyInterface"]</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card h-100">
<div class="card-body text-center">
<h5 class="text-muted">@Localizer["CompetitorC"]</h5>
<div class="display-4 text-muted">6.2s</div>
<p class="text-muted">@Localizer["ManyAds"]</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Ad Space Footer (conditional) -->
@await Html.PartialAsync("_AdSpace", new { position = "footer" })
<script src="~/js/simple-opcacity.js"></script>
<!-- Script para controles de logo aprimorados -->
<script>
// JavaScript para controles de logo aprimorados
document.addEventListener('DOMContentLoaded', function() {
const logoUpload = document.getElementById('logo-upload');
const logoSizeSlider = document.getElementById('logo-size-slider');
const logoSizeDisplay = document.getElementById('logo-size-display');
const logoColorizeToggle = document.getElementById('logo-colorize-toggle');
const logoVisualPreview = document.getElementById('logo-visual-preview');
const logoPreviewImage = document.getElementById('logo-preview-image');
const previewSizeText = document.getElementById('preview-size-text');
const previewColorizeText = document.getElementById('preview-colorize-text');
new SimpleOpacityController('#qr-type', '#quick-style-group');
new SimpleOpacityController('#qr-type', '#content-group');
new SimpleOpacityController('#qr-type', '#dynamic-qr-section');
new SimpleOpacityController('#qr-type', '#url-preview');
new SimpleOpacityController('#qr-type', '#vcard-interface');
new SimpleOpacityController('#qr-type', '#wifi-interface');
new SimpleOpacityController('#qr-type', '#sms-interface');
new SimpleOpacityController('#qr-type', '#email-interface');
new SimpleOpacityController('#qr-type', '#customization-accordion');
new SimpleOpacityController('#qr-type', '#button-gerar-div');
// Controle do slider de tamanho
logoSizeSlider?.addEventListener('input', function() {
const size = this.value;
logoSizeDisplay.textContent = size + '%';
previewSizeText.textContent = size + '%';
// Feedback visual baseado no tamanho
if (size <= 15) {
logoSizeDisplay.className = 'badge bg-info';
} else if (size <= 20) {
logoSizeDisplay.className = 'badge bg-success';
} else {
logoSizeDisplay.className = 'badge bg-warning';
}
});
// Controle do toggle de colorização
logoColorizeToggle?.addEventListener('change', function() {
previewColorizeText.textContent = this.checked ? 'Ativada' : 'Desativada';
previewColorizeText.className = this.checked ? 'text-primary' : 'text-muted';
// Simular preview da colorização (opcional)
if (logoPreviewImage.src && this.checked) {
logoPreviewImage.style.filter = 'hue-rotate(200deg) saturate(0.8)';
} else {
logoPreviewImage.style.filter = 'none';
}
});
// Melhorar o upload e preview do logo existente
logoUpload?.addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
// Validações já existem no handleLogoSelection
// Mostrar preview visual
const reader = new FileReader();
reader.onload = function(e) {
logoPreviewImage.src = e.target.result;
logoVisualPreview.style.display = 'block';
};
reader.readAsDataURL(file);
} else {
logoVisualPreview.style.display = 'none';
}
});
});
</script>