2025-08-18 17:35:19 +05:30

179 lines
5.6 KiB
Vue

<template>
<Dialog
v-model="showSettings"
:options="{ size: '5xl' }"
@close="activeSettingsPage = ''"
>
<template #body>
<div class="flex h-[calc(100vh_-_8rem)]">
<div class="flex flex-col p-2 w-52 shrink-0 bg-surface-gray-2">
<h1 class="px-2 pt-2 mb-3 text-lg font-semibold text-ink-gray-8">
{{ __('Settings') }}
</h1>
<div v-for="tab in tabs">
<div
v-if="!tab.hideLabel"
class="mb-2 mt-3 flex cursor-pointer gap-1.5 px-1 text-base font-medium text-ink-gray-5 transition-all duration-300 ease-in-out"
>
<span>{{ __(tab.label) }}</span>
</div>
<nav class="space-y-1">
<SidebarLink
v-for="i in tab.items"
:icon="i.icon"
:label="__(i.label)"
class="w-full"
:class="
activeTab?.label == i.label
? 'bg-surface-selected shadow-sm hover:bg-surface-selected'
: 'hover:bg-surface-gray-3'
"
@click="activeSettingsPage = i.label"
/>
</nav>
</div>
</div>
<div class="flex flex-col flex-1 overflow-y-auto bg-surface-modal">
<component :is="activeTab.component" v-if="activeTab" />
</div>
</div>
</template>
</Dialog>
</template>
<script setup>
import WhatsAppIcon from '@/components/Icons/WhatsAppIcon.vue'
import ERPNextIcon from '@/components/Icons/ERPNextIcon.vue'
import HelpdeskIcon from '@/components/Icons/HelpdeskIcon.vue'
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
import Email2Icon from '@/components/Icons/Email2Icon.vue'
import EmailTemplateIcon from '@/components/Icons/EmailTemplateIcon.vue'
import Users from '@/components/Settings/Users.vue'
import GeneralSettingsPage from '@/components/Settings/General/GeneralSettingsPage.vue'
import InviteUserPage from '@/components/Settings/InviteUserPage.vue'
import ProfileSettings from '@/components/Settings/ProfileSettings.vue'
import WhatsAppSettings from '@/components/Settings/WhatsAppSettings.vue'
import ERPNextSettings from '@/components/Settings/ERPNextSettings.vue'
import HelpdeskSettings from '@/components/Settings/HelpdeskSettings.vue'
import EmailTemplatePage from '@/components/Settings/EmailTemplate/EmailTemplatePage.vue'
import TelephonySettings from '@/components/Settings/TelephonySettings.vue'
import EmailConfig from '@/components/Settings/EmailConfig.vue'
import SidebarLink from '@/components/SidebarLink.vue'
import { usersStore } from '@/stores/users'
import {
isWhatsappInstalled,
showSettings,
activeSettingsPage,
} from '@/composables/settings'
import { Dialog, Avatar } from 'frappe-ui'
import { ref, markRaw, computed, watch, h } from 'vue'
const { isManager, isTelephonyAgent, getUser } = usersStore()
const user = computed(() => getUser() || {})
const tabs = computed(() => {
let _tabs = [
{
label: __('Settings'),
hideLabel: true,
items: [
{
label: __('Profile'),
icon: () =>
h(Avatar, {
size: 'xs',
label: user.value.full_name,
image: user.value.user_image,
}),
component: markRaw(ProfileSettings),
},
{
label: __('General'),
icon: 'settings',
component: markRaw(GeneralSettingsPage),
condition: () => isManager(),
},
{
label: __('Users'),
icon: 'user',
component: markRaw(Users),
condition: () => isManager(),
},
{
label: __('Invite User'),
icon: 'user-plus',
component: markRaw(InviteUserPage),
condition: () => isManager(),
},
{
label: __('Email Accounts'),
icon: Email2Icon,
component: markRaw(EmailConfig),
condition: () => isManager(),
},
{
label: __('Email Templates'),
icon: EmailTemplateIcon,
component: markRaw(EmailTemplatePage),
},
],
},
{
label: __('Integrations', null, 'FCRM'),
items: [
{
label: __('Telephony'),
icon: PhoneIcon,
component: markRaw(TelephonySettings),
condition: () => isManager() || isTelephonyAgent(),
},
{
label: __('WhatsApp'),
icon: WhatsAppIcon,
component: markRaw(WhatsAppSettings),
condition: () => isWhatsappInstalled.value && isManager(),
},
{
label: __('ERPNext'),
icon: ERPNextIcon,
component: markRaw(ERPNextSettings),
condition: () => isManager(),
},
{
label: __('Helpdesk'),
icon: HelpdeskIcon,
component: markRaw(HelpdeskSettings),
condition: () => isManager(),
},
],
condition: () => isManager() || isTelephonyAgent(),
},
]
return _tabs.filter((tab) => {
if (tab.condition && !tab.condition()) return false
if (tab.items) {
tab.items = tab.items.filter((item) => {
if (item.condition && !item.condition()) return false
return true
})
}
return true
})
})
const activeTab = ref(tabs.value[0].items[0])
function setActiveTab(tabName) {
activeTab.value =
(tabName &&
tabs.value
.map((tab) => tab.items)
.flat()
.find((tab) => tab.label === tabName)) ||
tabs.value[0].items[0]
}
watch(activeSettingsPage, (activePage) => setActiveTab(activePage))
</script>