feat: opacidade enquanto não selecionar o tipo.
This commit is contained in:
parent
8ab0b913e2
commit
70fbdaa3c2
@ -121,7 +121,7 @@ builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationSc
|
||||
// ADICIONE ESTAS LINHAS:
|
||||
options.Events.OnRedirectToAuthorizationEndpoint = context =>
|
||||
{
|
||||
context.Response.Redirect(context.RedirectUri + "&prompt=select_account");
|
||||
context.Response.Redirect(context.RedirectUri);
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
|
||||
|
||||
@ -35,7 +35,6 @@
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\images\" />
|
||||
<Folder Include="wwwroot\css\" />
|
||||
<Folder Include="wwwroot\js\" />
|
||||
<Folder Include="Data\" />
|
||||
<Folder Include="Services\" />
|
||||
<Folder Include="Models\" />
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
- 👑 **Sistema Premium**: Stripe integrado com recursos avançados
|
||||
- 📱 **PWA Ready**: Funciona como aplicativo móvel
|
||||
- 🎨 **UI Moderna**: Bootstrap 5 com design focado em velocidade
|
||||
- 📊 **Analytics**: Google Analytics 4 integrado
|
||||
- 🏗️ **Escalável**: MongoDB + Redis para alta performance
|
||||
|
||||
## 🎯 Funcionalidades por Usuário
|
||||
@ -36,7 +35,6 @@
|
||||
- ✅ **Sem anúncios permanentemente**
|
||||
- ✅ Geração prioritária (0.4s)
|
||||
- ✅ QR codes dinâmicos (editáveis)
|
||||
- ✅ Analytics avançados
|
||||
- ✅ Suporte prioritário
|
||||
- ✅ API access
|
||||
|
||||
|
||||
2
Resources/SharedResource.Designer.cs
generated
2
Resources/SharedResource.Designer.cs
generated
@ -304,7 +304,7 @@ namespace QRRapidoApp.Resources {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Remove ads, access detailed analytics and much more for only $12.90/month or $129.00/year. Login and subscribe now!.
|
||||
/// Looks up a localized string similar to Remove ads, access advanced customization and much more for only $12.90/month or $129.00/year. Login and subscribe now!.
|
||||
/// </summary>
|
||||
public static string LoginBenefits {
|
||||
get {
|
||||
|
||||
@ -250,7 +250,7 @@
|
||||
<value>Premium Offer!</value>
|
||||
</data>
|
||||
<data name="LoginBenefits" xml:space="preserve">
|
||||
<value>Remove ads, access detailed analytics and much more for only $12.90/month or $129.00/year. Login and subscribe now!</value>
|
||||
<value>Remove ads, access advanced customization and much more for only $12.90/month or $129.00/year. Login and subscribe now!</value>
|
||||
</data>
|
||||
<data name="Privacy" xml:space="preserve">
|
||||
<value>Privacy Policy</value>
|
||||
|
||||
262
Views/Account/Profile.cshtml
Normal file
262
Views/Account/Profile.cshtml
Normal file
@ -0,0 +1,262 @@
|
||||
@model QRRapidoApp.Models.User
|
||||
@{
|
||||
ViewData["Title"] = "Perfil do Usuário";
|
||||
var isPremium = ViewBag.IsPremium as bool? ?? false;
|
||||
var monthlyQRCount = ViewBag.MonthlyQRCount as int? ?? 0;
|
||||
var qrHistory = ViewBag.QRHistory as List<QRRapidoApp.Models.QRCodeHistory> ?? new List<QRRapidoApp.Models.QRCodeHistory>();
|
||||
Layout = "~/Views/Shared/_Layout.cshtml";
|
||||
}
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="row">
|
||||
<div class="col-lg-8 mx-auto">
|
||||
<!-- Header do Perfil -->
|
||||
<div class="card mb-4 border-0 shadow-sm">
|
||||
<div class="card-header bg-primary text-white d-flex align-items-center">
|
||||
<i class="fas fa-user-circle fa-2x me-3"></i>
|
||||
<div>
|
||||
<h4 class="mb-0">@Model.Name</h4>
|
||||
<small class="opacity-75">@Model.Email</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<!-- Status do Plano -->
|
||||
<div class="col-md-6">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<i class="fas fa-crown me-2 @(isPremium ? "text-warning" : "text-muted")"></i>
|
||||
<strong>Status do Plano:</strong>
|
||||
</div>
|
||||
@if (isPremium)
|
||||
{
|
||||
<span class="badge bg-warning text-dark fs-6">
|
||||
<i class="fas fa-star me-1"></i>Premium
|
||||
</span>
|
||||
@if (Model.PremiumExpiresAt.HasValue)
|
||||
{
|
||||
<p class="text-muted small mt-1 mb-0">
|
||||
Expira em: @Model.PremiumExpiresAt.Value.ToString("dd/MM/yyyy")
|
||||
</p>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="badge bg-secondary fs-6">
|
||||
<i class="fas fa-user me-1"></i>Gratuito
|
||||
</span>
|
||||
<p class="text-muted small mt-1 mb-0">
|
||||
<a href="/Premium/Upgrade" class="text-decoration-none">
|
||||
<i class="fas fa-arrow-up me-1"></i>Fazer upgrade
|
||||
</a>
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
|
||||
<!-- Data de Cadastro -->
|
||||
<div class="col-md-6">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<i class="fas fa-calendar-alt me-2 text-info"></i>
|
||||
<strong>Membro desde:</strong>
|
||||
</div>
|
||||
<p class="text-muted mb-0">@Model.CreatedAt.ToString("dd/MM/yyyy")</p>
|
||||
</div>
|
||||
|
||||
<!-- Provedor de Login -->
|
||||
<div class="col-md-6">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<i class="fab fa-@(Model.Provider.ToLower()) me-2 text-primary"></i>
|
||||
<strong>Conectado via:</strong>
|
||||
</div>
|
||||
<p class="text-muted mb-0">@Model.Provider</p>
|
||||
</div>
|
||||
|
||||
<!-- Último Login -->
|
||||
<div class="col-md-6">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<i class="fas fa-sign-in-alt me-2 text-success"></i>
|
||||
<strong>Último acesso:</strong>
|
||||
</div>
|
||||
<p class="text-muted mb-0">@Model.LastLoginAt.ToString("dd/MM/yyyy HH:mm")</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Estatísticas de Uso -->
|
||||
<div class="card mb-4 border-0 shadow-sm">
|
||||
<div class="card-header bg-info text-white">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-chart-bar me-2"></i>Estatísticas de Uso
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row text-center g-3">
|
||||
<div class="col-md-4">
|
||||
<div class="p-3 border rounded bg-light profile-stat">
|
||||
<h3 class="text-primary mb-1">@Model.TotalQRGenerated</h3>
|
||||
<small class="text-muted">QR Codes Criados</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="p-3 border rounded bg-light profile-stat">
|
||||
<h3 class="text-success mb-1">@monthlyQRCount</h3>
|
||||
<small class="text-muted">Este Mês</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="p-3 border rounded bg-light profile-stat">
|
||||
<h3 class="text-info mb-1">@Model.DailyQRCount</h3>
|
||||
<small class="text-muted">Hoje</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Histórico Recente -->
|
||||
@if (qrHistory.Any())
|
||||
{
|
||||
<div class="card mb-4 border-0 shadow-sm">
|
||||
<div class="card-header bg-success text-white d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-history me-2"></i>Histórico Recente
|
||||
</h5>
|
||||
<a href="/Account/History" class="btn btn-light btn-sm">
|
||||
<i class="fas fa-list me-1"></i>Ver Todos
|
||||
</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="list-group list-group-flush">
|
||||
@foreach (var qr in qrHistory.Take(5))
|
||||
{
|
||||
<div class="list-group-item d-flex justify-content-between align-items-center px-0">
|
||||
<div>
|
||||
<div class="d-flex align-items-center">
|
||||
<i class="fas fa-qrcode text-primary me-2"></i>
|
||||
<div>
|
||||
<h6 class="mb-1">@qr.Type.ToUpper()</h6>
|
||||
<p class="mb-0 text-muted small">
|
||||
@(qr.Content.Length > 50 ? qr.Content.Substring(0, 50) + "..." : qr.Content)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<small class="text-muted">@qr.CreatedAt.ToString("dd/MM HH:mm")</small>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Ações do Perfil -->
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-dark text-white">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-cogs me-2"></i>Ações
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
@if (!isPremium)
|
||||
{
|
||||
<div class="col-md-6">
|
||||
<a href="/Premium/Upgrade" class="btn btn-warning w-100">
|
||||
<i class="fas fa-crown me-2"></i>Upgrade para Premium
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="col-md-6">
|
||||
<a href="/Account/History" class="btn btn-info w-100">
|
||||
<i class="fas fa-history me-2"></i>Ver Histórico Completo
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<a href="/" class="btn btn-primary w-100">
|
||||
<i class="fas fa-qrcode me-2"></i>Criar Novo QR Code
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<a href="/Account/Logout" class="btn btn-outline-danger w-100">
|
||||
<i class="fas fa-sign-out-alt me-2"></i>Sair
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.card {
|
||||
transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 15px rgba(0,0,0,0.1) !important;
|
||||
}
|
||||
|
||||
.badge {
|
||||
font-size: 0.85em;
|
||||
padding: 8px 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.bg-light {
|
||||
background-color: #f8f9fa !important;
|
||||
border: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
border: none;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
padding: 15px 0;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.list-group-item:hover {
|
||||
background-color: rgba(0,123,255,0.05);
|
||||
}
|
||||
|
||||
.list-group-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.profile-stat {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.profile-stat:hover {
|
||||
background-color: #e3f2fd !important;
|
||||
border-color: #2196f3 !important;
|
||||
}
|
||||
|
||||
.btn {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
font-weight: 600;
|
||||
border-bottom: 2px solid rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
@@media (max-width: 768px) {
|
||||
.container {
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.col-md-6 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.card-body .row .col-md-4 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -105,7 +105,7 @@
|
||||
<span data-type-guide-text>@Localizer["TypeGuideText"]</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<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>
|
||||
@ -122,7 +122,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3" id="content-group">
|
||||
<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>
|
||||
@ -138,7 +138,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Dynamic QR Section (Premium) -->
|
||||
<div id="dynamic-qr-section" style="display: none;">
|
||||
<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>
|
||||
@ -146,30 +146,30 @@
|
||||
<i class="fas fa-chart-line text-warning"></i> QR Dinâmico - Premium
|
||||
</h6>
|
||||
<small class="text-muted">
|
||||
Analytics em tempo real: cliques, localização, dispositivos, etc.
|
||||
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">
|
||||
<input class="form-check-input" type="checkbox" id="qr-dynamic-toggle" style="display: none;">
|
||||
<label class="form-check-label" for="qr-dynamic-toggle">
|
||||
Ativar Analytics
|
||||
Adicione o logotivo na Personalização avançada
|
||||
</label>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="premium-upgrade-prompt">
|
||||
<input class="form-check-input" type="checkbox" disabled>
|
||||
<label class="form-check-label text-muted">
|
||||
Ativar Analytics
|
||||
<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> para analytics
|
||||
</a> QR Code com logotipo
|
||||
</small>
|
||||
</div>
|
||||
}
|
||||
@ -179,7 +179,7 @@
|
||||
</div>
|
||||
|
||||
<!-- URL Preview -->
|
||||
<div id="url-preview" class="mt-3" style="display: none;">
|
||||
<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>
|
||||
@ -188,7 +188,7 @@
|
||||
</div>
|
||||
|
||||
<!-- VCard Interface (dynamic) -->
|
||||
<div id="vcard-interface" class="mb-3" style="display: none;">
|
||||
<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.
|
||||
@ -330,7 +330,7 @@
|
||||
</div>
|
||||
|
||||
<!-- WiFi Interface (dynamic) -->
|
||||
<div id="wifi-interface" class="mb-3" style="display: none;">
|
||||
<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"]
|
||||
@ -469,7 +469,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Email Interface (dynamic) -->
|
||||
<div id="email-interface" class="mb-3" style="display: none;">
|
||||
<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.
|
||||
@ -500,7 +500,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Advanced customization (collapsible) -->
|
||||
<div class="accordion mb-3" id="customization-accordion">
|
||||
<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">
|
||||
@ -702,7 +702,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<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">
|
||||
@ -961,6 +961,9 @@
|
||||
<!-- 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
|
||||
@ -974,6 +977,21 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
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;
|
||||
|
||||
@ -333,6 +333,7 @@
|
||||
} else {
|
||||
console.error('❌ Botão não encontrado pelo script inline!');
|
||||
}
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
},
|
||||
"Authentication": {
|
||||
"Google": {
|
||||
"ClientId": "your-google-client-id",
|
||||
"ClientSecret": "your-google-client-secret"
|
||||
"ClientId": "1080447252222-dqjsu999tvrpb69oj5iapckdh9g8rvha.apps.googleusercontent.com",
|
||||
"ClientSecret": "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"
|
||||
},
|
||||
"Microsoft": {
|
||||
"ClientId": "9bec3835-acdb-4c5a-8668-6b90955c6ad2",
|
||||
|
||||
@ -284,3 +284,15 @@ body {
|
||||
.text-success {
|
||||
color: #28a745 !important;
|
||||
}
|
||||
|
||||
/* CLASSE PARA CONTROLAR OPACIDADE */
|
||||
.opacity-controlled {
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* ESTADO OPACO (quando nada selecionado) */
|
||||
.opacity-controlled.disabled-state {
|
||||
opacity: 0.2 !important; /* Bem opaco */
|
||||
pointer-events: none; /* Desabilita interação */
|
||||
}
|
||||
|
||||
@ -108,8 +108,13 @@ class QRRapidoGenerator {
|
||||
// Content validation
|
||||
const qrContent = document.getElementById('qr-content');
|
||||
if (qrContent) {
|
||||
let timer;
|
||||
qrContent.addEventListener('input', (e) => {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(() => {
|
||||
this.handleContentChange(e.target.value);
|
||||
this.updateGenerateButton();
|
||||
}, 300);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
64
wwwroot/js/simple-opcacity.js
Normal file
64
wwwroot/js/simple-opcacity.js
Normal file
@ -0,0 +1,64 @@
|
||||
class SimpleOpacityController {
|
||||
constructor(controlSelector, targetSelector) {
|
||||
this.controlSelector = controlSelector;
|
||||
this.targetSelector = targetSelector;
|
||||
this.disabledClass = 'disabled-state';
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
const controls = document.querySelectorAll(this.controlSelector);
|
||||
const targets = document.querySelectorAll(this.targetSelector);
|
||||
|
||||
// Listener para detectar mudanças
|
||||
controls.forEach(control => {
|
||||
control.addEventListener('change', () => {
|
||||
this.updateOpacity();
|
||||
});
|
||||
});
|
||||
|
||||
// Estado inicial
|
||||
this.updateOpacity();
|
||||
|
||||
console.log('✅ Sistema simples de opacidade inicializado');
|
||||
console.log('Controlando:', controls.length, 'controles e', targets.length, 'alvos');
|
||||
}
|
||||
|
||||
updateOpacity() {
|
||||
const hasSelection = this.hasSelection();
|
||||
const targets = document.querySelectorAll(this.targetSelector);
|
||||
|
||||
targets.forEach(target => {
|
||||
if (hasSelection) {
|
||||
// TEM seleção = div normal
|
||||
target.classList.remove(this.disabledClass);
|
||||
console.log('🟢 Div ativada - seleção detectada');
|
||||
} else {
|
||||
// NÃO tem seleção = div opaca
|
||||
target.classList.add(this.disabledClass);
|
||||
console.log('🔴 Div desativada - nenhuma seleção');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
hasSelection() {
|
||||
// Para SELECT: verificar se valor não está vazio
|
||||
const selects = document.querySelectorAll(this.controlSelector + '[type=""], ' + this.controlSelector + ':not([type])');
|
||||
for (let select of selects) {
|
||||
if (select.value && select.value.trim() !== '') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Para RADIO BUTTONS: verificar se algum está selecionado E não é vazio
|
||||
const radios = document.querySelectorAll(this.controlSelector + '[type="radio"]');
|
||||
for (let radio of radios) {
|
||||
if (radio.checked && radio.value && radio.value.trim() !== '') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user