diff --git a/src/BCards.Web/ViewModels/CreatePageViewModel.cs b/src/BCards.Web/ViewModels/CreatePageViewModel.cs
index 183a273..48b6b9a 100644
--- a/src/BCards.Web/ViewModels/CreatePageViewModel.cs
+++ b/src/BCards.Web/ViewModels/CreatePageViewModel.cs
@@ -14,7 +14,7 @@ public class CreatePageViewModel
[Required(ErrorMessage = "Tipo de negócio é obrigatório")]
public string BusinessType { get; set; } = "individual";
- [StringLength(200, ErrorMessage = "Bio deve ter no máximo 200 caracteres")]
+ [StringLength(3000, ErrorMessage = "Bio deve ter no máximo 3000 caracteres")]
public string Bio { get; set; } = string.Empty;
[Required(ErrorMessage = "Tema é obrigatório")]
diff --git a/src/BCards.Web/ViewModels/ManagePageViewModel.cs b/src/BCards.Web/ViewModels/ManagePageViewModel.cs
index b15487d..564f79f 100644
--- a/src/BCards.Web/ViewModels/ManagePageViewModel.cs
+++ b/src/BCards.Web/ViewModels/ManagePageViewModel.cs
@@ -18,7 +18,7 @@ public class ManagePageViewModel
[Required(ErrorMessage = "Tipo de negócio é obrigatório")]
public string BusinessType { get; set; } = "individual";
- [StringLength(200, ErrorMessage = "Bio deve ter no máximo 200 caracteres")]
+ [StringLength(3000, ErrorMessage = "Bio deve ter no máximo 3000 caracteres")]
public string Bio { get; set; } = string.Empty;
public string Slug { get; set; } = string.Empty;
diff --git a/src/BCards.Web/Views/Admin/CreatePage.cshtml b/src/BCards.Web/Views/Admin/CreatePage.cshtml
index f2eb3c5..93fa622 100644
--- a/src/BCards.Web/Views/Admin/CreatePage.cshtml
+++ b/src/BCards.Web/Views/Admin/CreatePage.cshtml
@@ -82,8 +82,9 @@
-
+
+
Máximo 3000 caracteres
diff --git a/src/BCards.Web/Views/Admin/ManagePage.cshtml b/src/BCards.Web/Views/Admin/ManagePage.cshtml
index 07c8dfc..74f7314 100644
--- a/src/BCards.Web/Views/Admin/ManagePage.cshtml
+++ b/src/BCards.Web/Views/Admin/ManagePage.cshtml
@@ -115,9 +115,9 @@
-
+
-
Máximo 200 caracteres
+
Máximo 3000 caracteres
diff --git a/src/BCards.Web/Views/Shared/_ThemeStyles.cshtml b/src/BCards.Web/Views/Shared/_ThemeStyles.cshtml
index eee1dd8..d1ef72f 100644
--- a/src/BCards.Web/Views/Shared/_ThemeStyles.cshtml
+++ b/src/BCards.Web/Views/Shared/_ThemeStyles.cshtml
@@ -176,7 +176,16 @@
text-overflow: ellipsis;
}
-/* Seta de expansão */
+/* Seta de expansão e Botão de copiar */
+.link-actions-container {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ margin-left: 0.5rem;
+ flex-shrink: 0;
+}
+
+.copy-link-btn,
.expand-arrow {
background: rgba(255, 255, 255, 0.2);
border: none;
@@ -189,15 +198,15 @@
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
- flex-shrink: 0;
- margin-left: 0.5rem;
}
+.copy-link-btn:hover,
.expand-arrow:hover {
background: rgba(255, 255, 255, 0.3);
transform: scale(1.05);
}
+.copy-link-btn i,
.expand-arrow i {
font-size: 0.9rem;
transition: transform 0.3s ease;
@@ -282,6 +291,20 @@
gap: 0.25rem;
}
+.expanded-link {
+ color: var(--primary-color) !important;
+ text-decoration: underline !important;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ transition: opacity 0.2s ease;
+}
+
+.expanded-link:hover {
+ opacity: 0.8;
+ text-decoration: none !important;
+}
+
/* ========== FOOTER ========== */
.profile-footer {
margin-top: 2rem;
diff --git a/src/BCards.Web/Views/UserPage/Display.cshtml b/src/BCards.Web/Views/UserPage/Display.cshtml
index e354720..9756a54 100644
--- a/src/BCards.Web/Views/UserPage/Display.cshtml
+++ b/src/BCards.Web/Views/UserPage/Display.cshtml
@@ -376,7 +376,7 @@
var hasExpandableContent = (!string.IsNullOrEmpty(link.Description) ||
(link.Type == BCards.Web.Models.LinkType.Product && !string.IsNullOrEmpty(link.ProductDescription)));
-
+
-
- @if (hasExpandableContent)
- {
-
}
@@ -517,8 +527,10 @@
}
@@ -653,8 +665,53 @@
// Generate QR Code on page load
generateQRCode();
+
+ // Auto-open link from hash
+ if (window.location.hash) {
+ const targetId = window.location.hash.substring(1);
+ const targetElement = document.getElementById(targetId);
+ if (targetElement) {
+ // Small delay to ensure everything is rendered
+ setTimeout(() => {
+ targetElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
+
+ // If it has a link-id, try to open the details
+ const linkId = targetElement.getAttribute('data-link-id');
+ const docId = targetElement.getAttribute('data-document-id');
+
+ if (linkId !== null) {
+ toggleLinkDetails(linkId);
+ } else if (docId !== null) {
+ toggleLinkDetails(docId);
+ }
+ }, 500);
+ }
+ }
});
+ function copyAnchorLink(id, btn) {
+ // Preserva a URL completa incluindo query strings (importante para o preview token)
+ // e apenas substitui/adiciona o hash
+ const url = new URL(window.location.href);
+ url.hash = id;
+ const fullUrl = url.toString();
+
+ navigator.clipboard.writeText(fullUrl).then(() => {
+ const icon = btn.querySelector('i');
+ const originalClass = icon.className;
+
+ icon.className = 'fas fa-check text-success';
+ btn.classList.add('copied');
+
+ setTimeout(() => {
+ icon.className = originalClass;
+ btn.classList.remove('copied');
+ }, 2000);
+ }).catch(err => {
+ console.error('Erro ao copiar link:', err);
+ });
+ }
+
// QR Code Functions
let qrCodeGenerated = false;