diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index b49a2be..33a6464 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -30,7 +30,11 @@
"Bash(ssh:*)",
"Bash(cat:*)",
"Bash(dig:*)",
- "Bash(git commit:*)"
+ "Bash(git commit:*)",
+ "Bash(netstat:*)",
+ "Bash(ss:*)",
+ "Bash(lsof:*)",
+ "Bash(dotnet run:*)"
]
},
"enableAllProjectMcpServers": false
diff --git a/src/BCards.Web/Views/Admin/ManagePage.cshtml b/src/BCards.Web/Views/Admin/ManagePage.cshtml
index bf0d22f..1d47fec 100644
--- a/src/BCards.Web/Views/Admin/ManagePage.cshtml
+++ b/src/BCards.Web/Views/Admin/ManagePage.cshtml
@@ -535,7 +535,7 @@
var twitterUrl = twitter !=null ? twitter.Url.Replace("https://x.com/","").Replace("https://twitter.com/","").Replace("https://www.twitter.com/","") : "";
var whatsappUrl = whatsapp !=null ? whatsapp.Url.Replace("https://wa.me/","").Replace("whatsapp://","") : "";
var instagramUrl = instagram !=null ? instagram.Url.Replace("https://instagram.com/","").Replace("https://www.instagram.com/","") : "";
- var tiktokUrl = tiktok !=null ? tiktok.Url.Replace("https://tiktok.com/@@","").Replace("https://www.tiktok.com/@@","").Replace("https://vm.tiktok.com/","") : "";
+ var tiktokUrl = tiktok !=null ? tiktok.Url.Replace("https://tiktok.com/@","").Replace("https://www.tiktok.com/@","").Replace("https://vm.tiktok.com/","") : "";
var pinterestUrl = pinterest !=null ? pinterest.Url.Replace("https://pinterest.com/","").Replace("https://www.pinterest.com/","").Replace("https://pin.it/","") : "";
var discordUrl = discord !=null ? discord.Url.Replace("https://discord.gg/","").Replace("https://discord.com/invite/","") : "";
var kawaiUrl = kawai !=null ? kawai.Url.Replace("https://kawai.com/","").Replace("https://www.kawai.com/","") : "";
@@ -573,9 +573,12 @@
https://wa.me/
-
+
- Exemplo: 5511999999999 (código do país + DDD + número)
+
+ Brasil: Digite apenas DDD + número (ex: 11987654321). O código 55 será adicionado automaticamente.
+ Outros países: Digite o código do país + número completo.
+
@@ -1204,14 +1207,22 @@
checkServerImageErrors();
// Garantir que campos não marcados sejam string vazia ao submeter
- $('form').on('submit', function() {
+ $('form').on('submit', function(e) {
ensureUncheckedFieldsAreEmpty();
-
+
+ // Validar URLs de redes sociais antes de submeter
+ const validationResult = validateSocialMediaUrls();
+ if (!validationResult.valid) {
+ e.preventDefault();
+ alert('Erro de validação:\n\n' + validationResult.errors.join('\n'));
+ return false;
+ }
+
// Debug: Verificar quais campos de links estão sendo enviados
console.log('=== DEBUG FORM SUBMISSION ===');
const formData = new FormData(this);
for (let [key, value] of formData.entries()) {
- if (key.includes('Links[')) {
+ if (key.includes('Links[') || key.includes('Url') || key.includes('Number')) {
console.log(`${key}: ${value}`);
}
}
@@ -2014,7 +2025,7 @@
{ checkbox: '#enableDiscord', hidden: 'input[name="DiscordUrl"]' },
{ checkbox: '#enableKawai', hidden: 'input[name="KawaiUrl"]' }
];
-
+
socialFields.forEach(field => {
if (!$(field.checkbox).is(':checked')) {
$(field.hidden).val(' '); // Forçar espaço para campos não marcados
@@ -2022,6 +2033,82 @@
});
}
+ // Validar URLs de redes sociais antes de submeter o formulário
+ function validateSocialMediaUrls() {
+ const errors = [];
+ const userLang = navigator.language || navigator.userLanguage;
+ const isBrazil = userLang.startsWith('pt-BR') || userLang.startsWith('pt');
+
+ // Validar WhatsApp
+ if ($('#enableWhatsApp').is(':checked')) {
+ const whatsappValue = $('input[name="WhatsAppNumber"]').val().trim();
+ if (whatsappValue && whatsappValue !== ' ') {
+ const cleanNumber = whatsappValue.replace('https://wa.me/', '').replace(/\D/g, '');
+
+ if (isBrazil) {
+ // Brasil: deve ter 13 dígitos (55 + DDD + número)
+ if (cleanNumber.length !== 13 || !cleanNumber.startsWith('55')) {
+ errors.push('⚠️ WhatsApp: Número brasileiro deve ter 13 dígitos (55 + DDD + número).\nExemplo: 5511987654321');
+ }
+ } else {
+ // Outros países: validar entre 10 e 15 dígitos
+ if (cleanNumber.length < 10 || cleanNumber.length > 15) {
+ errors.push('⚠️ WhatsApp: Número deve ter entre 10 e 15 dígitos (incluindo código do país).');
+ }
+ }
+ }
+ }
+
+ // Validar Facebook
+ if ($('#enableFacebook').is(':checked')) {
+ const facebookValue = $('input[name="FacebookUrl"]').val().trim();
+ if (facebookValue && facebookValue !== ' ') {
+ const cleanUrl = facebookValue.replace('https://facebook.com/', '').replace('https://www.facebook.com/', '');
+ if (cleanUrl.length < 3) {
+ errors.push('⚠️ Facebook: Nome de usuário deve ter pelo menos 3 caracteres.');
+ }
+ }
+ }
+
+ // Validar Instagram
+ if ($('#enableInstagram').is(':checked')) {
+ const instagramValue = $('input[name="InstagramUrl"]').val().trim();
+ if (instagramValue && instagramValue !== ' ') {
+ const cleanUrl = instagramValue.replace('https://instagram.com/', '').replace('https://www.instagram.com/', '');
+ if (cleanUrl.length < 3) {
+ errors.push('⚠️ Instagram: Nome de usuário deve ter pelo menos 3 caracteres.');
+ }
+ }
+ }
+
+ // Validar Twitter
+ if ($('#enableTwitter').is(':checked')) {
+ const twitterValue = $('input[name="TwitterUrl"]').val().trim();
+ if (twitterValue && twitterValue !== ' ') {
+ const cleanUrl = twitterValue.replace('https://x.com/', '').replace('https://twitter.com/', '');
+ if (cleanUrl.length < 3) {
+ errors.push('⚠️ Twitter/X: Nome de usuário deve ter pelo menos 3 caracteres.');
+ }
+ }
+ }
+
+ // Validar TikTok
+ if ($('#enableTiktok').is(':checked')) {
+ const tiktokValue = $('input[name="TiktokUrl"]').val().trim();
+ if (tiktokValue && tiktokValue !== ' ') {
+ const cleanUrl = tiktokValue.replace('https://tiktok.com/@@', '').replace('https://www.tiktok.com/@@', '');
+ if (cleanUrl.length < 3) {
+ errors.push('⚠️ TikTok: Nome de usuário deve ter pelo menos 3 caracteres.');
+ }
+ }
+ }
+
+ return {
+ valid: errors.length === 0,
+ errors: errors
+ };
+ }
+
// Social Media Functions
function cleanSocialPrefix(value, socialType) {
const prefixes = {
@@ -2039,10 +2126,16 @@
for (let prefix of typePrefixes) {
if (value.startsWith(prefix)) {
- return value.replace(prefix, '');
+ value = value.replace(prefix, '');
+ break;
}
}
+ // TikTok: remover @@ do início (o prefixo já tem @@)
+ if (socialType === 'Tiktok' && value.startsWith('@@')) {
+ value = value.substring(1);
+ }
+
return value;
}
@@ -2124,9 +2217,19 @@
if (isWhatsApp) {
// WhatsApp: apenas números
value = value.replace(/\D/g, '');
+
+ // Auto-adicionar código +55 para números brasileiros (11 dígitos sem código país)
+ // Detecta cultura pt-BR para aplicar validação BR
+ const userLang = navigator.language || navigator.userLanguage;
+ const isBrazil = userLang.startsWith('pt-BR') || userLang.startsWith('pt');
+
+ if (isBrazil && value.length === 11 && !value.startsWith('55')) {
+ value = '55' + value;
+ }
+
$(this).val(value);
}
-
+
// Atualizar campo hidden - SEMPRE string, nunca null
if (value) {
hiddenField.val(prefix + value);
@@ -2142,15 +2245,29 @@
function updateSocialFieldFeedback(input, value, isWhatsApp) {
// Remover classes anteriores
input.removeClass('is-valid is-invalid');
-
+
if (!value) return;
-
+
if (isWhatsApp) {
- // Validar WhatsApp (mínimo 10 dígitos)
- if (value.length >= 10) {
- input.addClass('is-valid');
+ // Validar WhatsApp com detecção de idioma
+ const userLang = navigator.language || navigator.userLanguage;
+ const isBrazil = userLang.startsWith('pt-BR') || userLang.startsWith('pt');
+
+ if (isBrazil) {
+ // Brasil: validar 13 dígitos (55 + DDD + número)
+ if (value.length === 13 && value.startsWith('55')) {
+ input.addClass('is-valid');
+ } else if (value.length >= 10) {
+ // Ainda está digitando ou formato incorreto
+ input.addClass('is-invalid');
+ }
} else {
- input.addClass('is-invalid');
+ // Outros países: validar mínimo 10 dígitos (genérico)
+ if (value.length >= 10 && value.length <= 15) {
+ input.addClass('is-valid');
+ } else if (value.length > 0) {
+ input.addClass('is-invalid');
+ }
}
} else {
// Validar username (mínimo 3 caracteres, sem espaços)
diff --git a/src/BCards.Web/Views/UserPage/Display.cshtml b/src/BCards.Web/Views/UserPage/Display.cshtml
index 0991be7..0501289 100644
--- a/src/BCards.Web/Views/UserPage/Display.cshtml
+++ b/src/BCards.Web/Views/UserPage/Display.cshtml
@@ -10,6 +10,84 @@
Layout = isPreview ? "_PreviewLayout" : "_UserPageLayout";
}
+@functions {
+ ///