diff --git a/app/controllers/api/v1/accounts/portals_controller.rb b/app/controllers/api/v1/accounts/portals_controller.rb
index 27c4126a6..770018e3c 100644
--- a/app/controllers/api/v1/accounts/portals_controller.rb
+++ b/app/controllers/api/v1/accounts/portals_controller.rb
@@ -78,7 +78,9 @@ class Api::V1::Accounts::PortalsController < Api::V1::Accounts::BaseController
def portal_params
params.require(:portal).permit(
:id, :color, :custom_domain, :header_text, :homepage_link,
- :name, :page_title, :slug, :archived, { config: [:default_locale, { allowed_locales: [] }, { draft_locales: [] }] }
+ :name, :page_title, :slug, :archived,
+ { config: [:default_locale, :layout, { allowed_locales: [] }, { draft_locales: [] },
+ { social_profiles: %i[facebook x instagram linkedin youtube tiktok github whatsapp] }] }
)
end
diff --git a/app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/PortalLayoutContentSettings.vue b/app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/PortalLayoutContentSettings.vue
new file mode 100644
index 000000000..20016dfc1
--- /dev/null
+++ b/app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/PortalLayoutContentSettings.vue
@@ -0,0 +1,290 @@
+
+
+
+
+
+
+ {{ t('HELP_CENTER.PORTAL_SETTINGS.LAYOUT_CONTENT.HEADER') }}
+
+
+ {{ t('HELP_CENTER.PORTAL_SETTINGS.LAYOUT_CONTENT.DESCRIPTION') }}
+
+
+
+
+
+
(state.layout = value)"
+ >
+
+
+
+
+
+
(state.layout = value)"
+ >
+
+
+
+
+
+
+
+
+
+
+ {{
+ t('HELP_CENTER.PORTAL_SETTINGS.LAYOUT_CONTENT.SOCIAL_LINKS.HEADER')
+ }}
+
+
+ {{
+ t(
+ 'HELP_CENTER.PORTAL_SETTINGS.LAYOUT_CONTENT.SOCIAL_LINKS.DESCRIPTION'
+ )
+ }}
+
+
+
+
+
+ {{
+ platform.prefix
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/PortalSettings.vue b/app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/PortalSettings.vue
index 83800e002..eccf988cc 100644
--- a/app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/PortalSettings.vue
+++ b/app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/PortalSettings.vue
@@ -7,6 +7,7 @@ import { useMapGetter } from 'dashboard/composables/store.js';
import HelpCenterLayout from 'dashboard/components-next/HelpCenter/HelpCenterLayout.vue';
import PortalBaseSettings from 'dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/PortalBaseSettings.vue';
import PortalConfigurationSettings from './PortalConfigurationSettings.vue';
+import PortalLayoutContentSettings from './PortalLayoutContentSettings.vue';
import ConfirmDeletePortalDialog from 'dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/ConfirmDeletePortalDialog.vue';
import Spinner from 'dashboard/components-next/spinner/Spinner.vue';
import Button from 'dashboard/components-next/button/Button.vue';
@@ -102,6 +103,12 @@ const handleDeletePortal = () => {
@send-cname-instructions="handleSendCnameInstructions"
/>
+
+
diff --git a/app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/classic-layout-preview.svg b/app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/classic-layout-preview.svg
new file mode 100644
index 000000000..d9fe9078a
--- /dev/null
+++ b/app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/classic-layout-preview.svg
@@ -0,0 +1,10 @@
+
diff --git a/app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/documentation-layout-preview.svg b/app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/documentation-layout-preview.svg
new file mode 100644
index 000000000..efda93a6a
--- /dev/null
+++ b/app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/documentation-layout-preview.svg
@@ -0,0 +1,18 @@
+
diff --git a/app/javascript/dashboard/components-next/radioCard/RadioCard.vue b/app/javascript/dashboard/components-next/radioCard/RadioCard.vue
index 182325ed8..1f5398b15 100644
--- a/app/javascript/dashboard/components-next/radioCard/RadioCard.vue
+++ b/app/javascript/dashboard/components-next/radioCard/RadioCard.vue
@@ -1,4 +1,5 @@
-
@@ -75,5 +83,5 @@ const handleChange = () => {
-
+
diff --git a/app/javascript/dashboard/i18n/locale/en/helpCenter.json b/app/javascript/dashboard/i18n/locale/en/helpCenter.json
index 9ae849d25..758bb1dca 100644
--- a/app/javascript/dashboard/i18n/locale/en/helpCenter.json
+++ b/app/javascript/dashboard/i18n/locale/en/helpCenter.json
@@ -866,6 +866,28 @@
},
"EDIT_CONFIGURATION": "Edit configuration"
},
+ "LAYOUT_CONTENT": {
+ "HEADER": "Appearance",
+ "DESCRIPTION": "Pick the layout that fits how your visitors read.",
+ "LAYOUT": {
+ "CLASSIC": {
+ "TITLE": "Classic",
+ "DESCRIPTION": "A welcoming home page with search and featured topics."
+ },
+ "SIDEBAR": {
+ "TITLE": "Documentation",
+ "DESCRIPTION": "Side-by-side navigation that keeps every guide a click away."
+ }
+ },
+ "SOCIAL_LINKS": {
+ "HEADER": "Social links",
+ "DESCRIPTION": "Add the handle for each network and your help center builds the full link. Shown in the documentation layout footer.",
+ "PLACEHOLDER": "handle",
+ "ADD": "Add social link",
+ "REMOVE": "Remove"
+ },
+ "SAVE": "Save changes"
+ },
"API": {
"CREATE_PORTAL": {
"SUCCESS_MESSAGE": "Portal created successfully",
diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/components/LockToSingleConversationPreview.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/components/LockToSingleConversationPreview.vue
index 77cbc2216..d2109ba9c 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/inbox/components/LockToSingleConversationPreview.vue
+++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/components/LockToSingleConversationPreview.vue
@@ -13,7 +13,7 @@ defineEmits(['update']);
-defineProps({
- active: {
- type: Boolean,
- default: false,
- },
- title: {
- type: String,
- default: '',
- },
- description: {
- type: String,
- default: '',
- },
- lightImage: {
- type: String,
- default: '',
- },
- darkImage: {
- type: String,
- default: '',
- },
-});
-
-
-
-
-
diff --git a/app/javascript/dashboard/routes/dashboard/settings/profile/Index.vue b/app/javascript/dashboard/routes/dashboard/settings/profile/Index.vue
index ed674e3bc..75eb8a2f8 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/profile/Index.vue
+++ b/app/javascript/dashboard/routes/dashboard/settings/profile/Index.vue
@@ -13,7 +13,6 @@ import UserBasicDetails from './UserBasicDetails.vue';
import MessageSignature from './MessageSignature.vue';
import FontSize from './FontSize.vue';
import UserLanguageSelect from './UserLanguageSelect.vue';
-import HotKeyCard from './HotKeyCard.vue';
import ChangePassword from './ChangePassword.vue';
import NotificationPreferences from './NotificationPreferences.vue';
import AudioNotifications from './AudioNotifications.vue';
@@ -22,6 +21,7 @@ import BaseSettingsHeader from '../components/BaseSettingsHeader.vue';
import AccessToken from './AccessToken.vue';
import MfaSettingsCard from './MfaSettingsCard.vue';
import Policy from 'dashboard/components/policy.vue';
+import RadioCard from 'dashboard/components-next/radioCard/RadioCard.vue';
import {
ROLES,
CONVERSATION_PERMISSIONS,
@@ -36,7 +36,7 @@ export default {
UserProfilePicture,
Policy,
UserBasicDetails,
- HotKeyCard,
+ RadioCard,
ChangePassword,
NotificationPreferences,
AudioNotifications,
@@ -268,26 +268,27 @@ export default {
-
+
![]()
+
<%
- socials = (portal.config.is_a?(Hash) && portal.config['social_profiles']) || {}
+ socials = portal.social_profiles
social_definitions = [
- { key: 'facebook', icon: 'i-ri-facebook-circle-fill', label: 'Facebook' },
- { key: 'x', icon: 'i-ri-twitter-x-fill', label: 'X' },
- { key: 'instagram', icon: 'i-ri-instagram-fill', label: 'Instagram' },
- { key: 'tiktok', icon: 'i-ri-tiktok-fill', label: 'TikTok' },
- { key: 'github', icon: 'i-ri-github-fill', label: 'GitHub' },
- { key: 'whatsapp', icon: 'i-ri-whatsapp-fill', label: 'WhatsApp' }
+ { key: 'facebook', icon: 'i-ri-facebook-circle-fill', label: 'Facebook', base_url: 'https://facebook.com/' },
+ { key: 'x', icon: 'i-ri-twitter-x-fill', label: 'X', base_url: 'https://x.com/' },
+ { key: 'instagram', icon: 'i-ri-instagram-fill', label: 'Instagram', base_url: 'https://instagram.com/' },
+ { key: 'linkedin', icon: 'i-ri-linkedin-box-fill', label: 'LinkedIn', base_url: 'https://linkedin.com/' },
+ { key: 'youtube', icon: 'i-ri-youtube-fill', label: 'YouTube', base_url: 'https://youtube.com/' },
+ { key: 'tiktok', icon: 'i-ri-tiktok-fill', label: 'TikTok', base_url: 'https://tiktok.com/' },
+ { key: 'github', icon: 'i-ri-github-fill', label: 'GitHub', base_url: 'https://github.com/' },
+ { key: 'whatsapp', icon: 'i-ri-whatsapp-fill', label: 'WhatsApp', base_url: 'https://wa.me/' }
]
- active_socials = social_definitions.select { |s| socials[s[:key]].to_s.strip.present? }
+ active_socials = social_definitions.filter_map do |social|
+ handle = socials[social[:key]].to_s.strip
+ social.merge(url: "#{social[:base_url]}#{handle}") if handle.present?
+ end
show_branding = !portal.account.feature_enabled?('disable_branding')
%>
<% if show_branding || active_socials.any? %>
-