fix: ajustes na edição
This commit is contained in:
parent
dca698e4c4
commit
cff7962cc5
@ -558,10 +558,13 @@ public class AdminController : Controller
|
||||
var socialLinks = new List<LinkItem>();
|
||||
if (!string.IsNullOrEmpty(model.WhatsAppNumber))
|
||||
{
|
||||
var whatsappDigits = model.WhatsAppNumber
|
||||
.Replace("https://wa.me/", "").Replace("whatsapp://", "")
|
||||
.Replace("+", "").Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "");
|
||||
socialLinks.Add(new LinkItem
|
||||
{
|
||||
Title = "WhatsApp",
|
||||
Url = $"https://wa.me/{model.WhatsAppNumber.Replace("+", "").Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "")}",
|
||||
Url = $"https://wa.me/{whatsappDigits}",
|
||||
Icon = "fab fa-whatsapp",
|
||||
IsActive = true,
|
||||
Order = userPage.Links.Count + socialLinks.Count
|
||||
@ -837,6 +840,16 @@ public class AdminController : Controller
|
||||
FileSize = d.FileSize,
|
||||
UploadedAt = d.UploadedAt
|
||||
}).ToList() ?? new List<ManageDocumentViewModel>(),
|
||||
// Social media fields — extracted from Links so the edit form pre-fills correctly
|
||||
WhatsAppNumber = page.Links?.FirstOrDefault(l => l.Icon?.Contains("whatsapp") == true)?.Url
|
||||
?.Replace("https://wa.me/", "").Replace("whatsapp://", "") ?? string.Empty,
|
||||
FacebookUrl = page.Links?.FirstOrDefault(l => l.Icon?.Contains("facebook") == true)?.Url ?? string.Empty,
|
||||
InstagramUrl = page.Links?.FirstOrDefault(l => l.Icon?.Contains("instagram") == true)?.Url ?? string.Empty,
|
||||
TwitterUrl = page.Links?.FirstOrDefault(l => l.Icon?.Contains("twitter") == true)?.Url ?? string.Empty,
|
||||
TiktokUrl = page.Links?.FirstOrDefault(l => l.Icon?.Contains("tiktok") == true)?.Url ?? string.Empty,
|
||||
PinterestUrl = page.Links?.FirstOrDefault(l => l.Icon?.Contains("pinterest") == true)?.Url ?? string.Empty,
|
||||
DiscordUrl = page.Links?.FirstOrDefault(l => l.Icon?.Contains("discord") == true)?.Url ?? string.Empty,
|
||||
KawaiUrl = page.Links?.FirstOrDefault(l => l.Icon?.Contains("kawai") == true)?.Url ?? string.Empty,
|
||||
AvailableCategories = categories,
|
||||
AvailableThemes = themes.Where(t => !t.IsPremium || userPlanType.AllowsCustomThemes()).ToList(),
|
||||
MaxLinksAllowed = userPlanType.GetMaxLinksPerPage(),
|
||||
@ -892,10 +905,13 @@ public class AdminController : Controller
|
||||
|
||||
if (!string.IsNullOrEmpty(model.WhatsAppNumber))
|
||||
{
|
||||
var whatsappDigits = model.WhatsAppNumber
|
||||
.Replace("https://wa.me/", "").Replace("whatsapp://", "")
|
||||
.Replace("+", "").Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "");
|
||||
socialLinks.Add(new LinkItem
|
||||
{
|
||||
Title = "WhatsApp",
|
||||
Url = $"https://wa.me/{model.WhatsAppNumber.Replace("+", "").Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "")}",
|
||||
Url = $"https://wa.me/{whatsappDigits}",
|
||||
Icon = "fab fa-whatsapp",
|
||||
IsActive = true,
|
||||
Order = currentOrder++
|
||||
@ -1241,10 +1257,13 @@ public class AdminController : Controller
|
||||
|
||||
if (!string.IsNullOrEmpty(model.WhatsAppNumber))
|
||||
{
|
||||
var whatsappDigits = model.WhatsAppNumber
|
||||
.Replace("https://wa.me/", "").Replace("whatsapp://", "")
|
||||
.Replace("+", "").Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "");
|
||||
socialLinks.Add(new LinkItem
|
||||
{
|
||||
Title = "WhatsApp",
|
||||
Url = $"https://wa.me/{model.WhatsAppNumber.Replace("+", "").Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "")}",
|
||||
Url = $"https://wa.me/{whatsappDigits}",
|
||||
Icon = "fab fa-whatsapp",
|
||||
IsActive = true,
|
||||
Order = currentOrder++
|
||||
|
||||
@ -82,9 +82,15 @@
|
||||
|
||||
<div class="mb-3">
|
||||
<label asp-for="Bio" class="form-label">Bio/Descrição</label>
|
||||
<textarea asp-for="Bio" class="form-control" rows="8" maxlength="3000" placeholder="Uma breve descrição sobre você ou sua empresa..."></textarea>
|
||||
<div class="md-toolbar border rounded-top border-bottom-0 bg-light px-2 py-1 d-flex gap-1">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary md-btn" data-target="Bio" data-wrap="**" title="Negrito"><b>B</b></button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary md-btn" data-target="Bio" data-wrap="*" title="Itálico"><i>I</i></button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary md-list-btn" data-target="Bio" title="Lista">• Lista</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary md-link-btn" data-target="Bio" title="Link">🔗 Link</button>
|
||||
</div>
|
||||
<textarea asp-for="Bio" id="Bio" class="form-control rounded-0 rounded-bottom" rows="5" maxlength="3000" placeholder="Uma breve descrição sobre você ou sua empresa..." style="font-family: monospace; font-size: 0.9rem;"></textarea>
|
||||
<span asp-validation-for="Bio" class="text-danger"></span>
|
||||
<div class="form-text">Máximo 3000 caracteres</div>
|
||||
<div class="form-text">Máximo 3000 caracteres. Use **negrito**, *itálico*, - item para listas.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -616,4 +622,51 @@ function generatePreview() {
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
document.querySelectorAll('.md-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var targetId = this.dataset.target;
|
||||
var wrap = this.dataset.wrap;
|
||||
var ta = document.getElementById(targetId);
|
||||
var start = ta.selectionStart, end = ta.selectionEnd;
|
||||
var sel = ta.value.substring(start, end) || 'texto';
|
||||
var before = ta.value.substring(0, start);
|
||||
var after = ta.value.substring(end);
|
||||
ta.value = before + wrap + sel + wrap + after;
|
||||
ta.selectionStart = start + wrap.length;
|
||||
ta.selectionEnd = start + wrap.length + sel.length;
|
||||
ta.focus();
|
||||
});
|
||||
});
|
||||
document.querySelectorAll('.md-list-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var targetId = this.dataset.target;
|
||||
var ta = document.getElementById(targetId);
|
||||
var start = ta.selectionStart;
|
||||
var lineStart = ta.value.lastIndexOf('\n', start - 1) + 1;
|
||||
var before = ta.value.substring(0, lineStart);
|
||||
var after = ta.value.substring(lineStart);
|
||||
ta.value = before + '- ' + after;
|
||||
ta.selectionStart = ta.selectionEnd = start + 2;
|
||||
ta.focus();
|
||||
});
|
||||
});
|
||||
document.querySelectorAll('.md-link-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var targetId = this.dataset.target;
|
||||
var ta = document.getElementById(targetId);
|
||||
var start = ta.selectionStart, end = ta.selectionEnd;
|
||||
var sel = ta.value.substring(start, end) || 'texto do link';
|
||||
var url = prompt('URL do link:') || 'https://';
|
||||
var before = ta.value.substring(0, start);
|
||||
var after = ta.value.substring(end);
|
||||
var md = '[' + sel + '](' + url + ')';
|
||||
ta.value = before + md + after;
|
||||
ta.selectionStart = ta.selectionEnd = start + md.length;
|
||||
ta.focus();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
}
|
||||
@ -115,9 +115,15 @@
|
||||
|
||||
<div class="mb-3">
|
||||
<label asp-for="Bio" class="form-label">Bio/Descrição</label>
|
||||
<textarea asp-for="Bio" class="form-control" rows="8" maxlength="3000" placeholder="Uma breve descrição sobre você ou sua empresa..."></textarea>
|
||||
<div class="md-toolbar border rounded-top border-bottom-0 bg-light px-2 py-1 d-flex gap-1">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary md-btn" data-target="Bio" data-wrap="**" title="Negrito"><b>B</b></button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary md-btn" data-target="Bio" data-wrap="*" title="Itálico"><i>I</i></button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary md-btn md-list-btn" data-target="Bio" title="Lista">• Lista</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary md-link-btn" data-target="Bio" title="Link">🔗 Link</button>
|
||||
</div>
|
||||
<textarea asp-for="Bio" id="Bio" class="form-control rounded-0 rounded-bottom" rows="5" maxlength="3000" placeholder="Uma breve descrição sobre você ou sua empresa..." style="font-family: monospace; font-size: 0.9rem;"></textarea>
|
||||
<span asp-validation-for="Bio" class="text-danger"></span>
|
||||
<div class="form-text">Máximo 3000 caracteres</div>
|
||||
<div class="form-text">Máximo 3000 caracteres. Use **negrito**, *itálico*, - item para listas.</div>
|
||||
</div>
|
||||
|
||||
<!-- Profile Image Upload -->
|
||||
@ -1210,7 +1216,6 @@
|
||||
|
||||
@section Scripts {
|
||||
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
|
||||
|
||||
<script>
|
||||
const LINK_TYPES_CONFIG = @Html.Raw(linkTypesJson);
|
||||
let linkCount = @Model.Links.Count;
|
||||
@ -1219,6 +1224,9 @@
|
||||
const totalSteps = 5;
|
||||
|
||||
$(document).ready(function() {
|
||||
// Initialize Markdown toolbar
|
||||
initMarkdownToolbar();
|
||||
|
||||
// Initialize social media fields
|
||||
initializeSocialMedia();
|
||||
|
||||
@ -1337,11 +1345,11 @@
|
||||
updateLinkNumbers();
|
||||
});
|
||||
|
||||
// Form validation
|
||||
// Loading state — só desabilita se a validação JS não bloqueou o submit
|
||||
$('#managePageForm').on('submit', function(e) {
|
||||
console.log('Form submitted');
|
||||
// Allow submission but add loading state
|
||||
$(this).find('button[type="submit"]').prop('disabled', true).html('<i class="fas fa-spinner fa-spin me-2"></i>Criando...');
|
||||
if (!e.isDefaultPrevented()) {
|
||||
$(this).find('button[type="submit"]').prop('disabled', true).html('<i class="fas fa-spinner fa-spin me-2"></i>Salvando...');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -1943,6 +1951,53 @@
|
||||
}, 7000);
|
||||
}
|
||||
|
||||
// Markdown Toolbar
|
||||
function initMarkdownToolbar() {
|
||||
document.querySelectorAll('.md-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var targetId = this.dataset.target;
|
||||
var wrap = this.dataset.wrap;
|
||||
var ta = document.getElementById(targetId);
|
||||
var start = ta.selectionStart, end = ta.selectionEnd;
|
||||
var sel = ta.value.substring(start, end) || 'texto';
|
||||
var before = ta.value.substring(0, start);
|
||||
var after = ta.value.substring(end);
|
||||
ta.value = before + wrap + sel + wrap + after;
|
||||
ta.selectionStart = start + wrap.length;
|
||||
ta.selectionEnd = start + wrap.length + sel.length;
|
||||
ta.focus();
|
||||
});
|
||||
});
|
||||
document.querySelectorAll('.md-list-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var targetId = this.dataset.target;
|
||||
var ta = document.getElementById(targetId);
|
||||
var start = ta.selectionStart;
|
||||
var lineStart = ta.value.lastIndexOf('\n', start - 1) + 1;
|
||||
var before = ta.value.substring(0, lineStart);
|
||||
var after = ta.value.substring(lineStart);
|
||||
ta.value = before + '- ' + after;
|
||||
ta.selectionStart = ta.selectionEnd = start + 2;
|
||||
ta.focus();
|
||||
});
|
||||
});
|
||||
document.querySelectorAll('.md-link-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var targetId = this.dataset.target;
|
||||
var ta = document.getElementById(targetId);
|
||||
var start = ta.selectionStart, end = ta.selectionEnd;
|
||||
var sel = ta.value.substring(start, end) || 'texto do link';
|
||||
var url = prompt('URL do link:') || 'https://';
|
||||
var before = ta.value.substring(0, start);
|
||||
var after = ta.value.substring(end);
|
||||
var md = '[' + sel + '](' + url + ')';
|
||||
ta.value = before + md + after;
|
||||
ta.selectionStart = ta.selectionEnd = start + md.length;
|
||||
ta.focus();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Validation Error Handling
|
||||
function checkValidationErrors() {
|
||||
// Só verificar erros se estamos em um POST-back (ou seja, se ModelState foi validado)
|
||||
@ -2262,8 +2317,10 @@
|
||||
}
|
||||
|
||||
// Atualizar campo hidden - SEMPRE string, nunca null
|
||||
// WhatsApp: armazena só o número (servidor adiciona https://wa.me/ ao salvar)
|
||||
// Outros: armazena URL completa (servidor usa diretamente)
|
||||
if (value) {
|
||||
hiddenField.val(prefix + value);
|
||||
hiddenField.val(isWhatsApp ? value : prefix + value);
|
||||
} else {
|
||||
hiddenField.val(' '); // Espaço em branco para evitar null
|
||||
}
|
||||
|
||||
@ -103,9 +103,11 @@
|
||||
<div class="card-body">
|
||||
@if (!string.IsNullOrEmpty(Model.Page.Bio))
|
||||
{
|
||||
var bioPipeline = new Markdig.MarkdownPipelineBuilder().UseAutoLinks().DisableHtml().Build();
|
||||
var bioHtml = Markdig.Markdown.ToHtml(Model.Page.Bio, bioPipeline);
|
||||
<div class="mb-3">
|
||||
<strong>Biografia:</strong>
|
||||
<p>@Model.Page.Bio</p>
|
||||
<div>@Html.Raw(bioHtml)</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@ -367,7 +367,9 @@
|
||||
|
||||
@if (!string.IsNullOrEmpty(Model.Bio))
|
||||
{
|
||||
<p class="profile-bio">@Model.Bio</p>
|
||||
var bioPipeline = new Markdig.MarkdownPipelineBuilder().UseAutoLinks().DisableHtml().Build();
|
||||
var bioHtml = Markdig.Markdown.ToHtml(Model.Bio, bioPipeline);
|
||||
<div class="profile-bio">@Html.Raw(bioHtml)</div>
|
||||
}
|
||||
|
||||
<!-- Links Container -->
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
@using BCards.Web
|
||||
@using BCards.Web.Models
|
||||
@using Markdig
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
Loading…
Reference in New Issue
Block a user