Compare commits

...
Author SHA1 Message Date
iamsivin 1a679da329 chore: Clean up 2026-07-09 17:45:57 +05:30
Muhsin 5f5634ced3 feat: add support action to suspended account page 2026-07-09 14:53:14 +04:00
3 changed files with 59 additions and 16 deletions
@@ -44,6 +44,12 @@ const showChatSupport = computed(() => {
);
});
const toggleChatSupport = () => {
if (window.$chatwoot) {
window.$chatwoot.toggle();
}
};
const menuItems = computed(() => {
return [
{
@@ -51,9 +57,7 @@ const menuItems = computed(() => {
showOnCustomBrandedInstance: false,
label: t('SIDEBAR_ITEMS.CONTACT_SUPPORT'),
icon: 'i-lucide-life-buoy',
click: () => {
window.$chatwoot.toggle();
},
click: toggleChatSupport,
},
{
show: true,
@@ -263,7 +263,7 @@
"EMAIL_VERIFICATION_SENT": "Verification email has been sent. Please check your inbox.",
"ACCOUNT_SUSPENDED": {
"TITLE": "Account Suspended",
"MESSAGE": "Your account has been suspended after we detected activity that may violate our policies or put other users at risk. If you believe this is a mistake, please contact our support team."
"MESSAGE": "Your account has been suspended due to activity that may violate our policies. If you believe this is a mistake, please contact our support team."
},
"NO_ACCOUNTS": {
"TITLE": "No account found",
@@ -1,22 +1,51 @@
<script setup>
import { ref, computed, onMounted, onBeforeUnmount } from 'vue';
import EmptyState from 'dashboard/components/widgets/EmptyState.vue';
import { onMounted } from 'vue';
import NextButton from 'dashboard/components-next/button/Button.vue';
import { useMapGetter } from 'dashboard/composables/store';
const toggleSupportWidgetVisibility = () => {
if (window.$chatwoot) {
window.$chatwoot.toggleBubbleVisibility('show');
}
const globalConfig = useMapGetter('globalConfig/get');
// Hide the CTA entirely when the installation has no support inbox — the widget
// SDK never loads there, so window.$chatwoot stays undefined and the button
// would be a no-op.
const canContactSupport = computed(() =>
Boolean(globalConfig.value.chatwootInboxToken)
);
// The widget SDK loads asynchronously. Until it signals `chatwoot:ready` it
// can't be opened, and poking it early throws (its bubble DOM isn't mounted yet),
// so keep the button disabled with a loader till then.
const isWidgetReady = ref(Boolean(window.$chatwoot?.hasLoaded));
const showSupportBubble = () => {
window.$chatwoot?.toggleBubbleVisibility('show');
};
const setupListenerForWidgetEvent = () => {
window.addEventListener('chatwoot:on-message', () => {
toggleSupportWidgetVisibility();
});
const toggleSupportWidget = () => {
window.$chatwoot?.toggle();
};
const onWidgetReady = () => {
isWidgetReady.value = true;
showSupportBubble();
};
onMounted(() => {
toggleSupportWidgetVisibility();
setupListenerForWidgetEvent();
// Reveal the support bubble once the widget is ready (immediately if it
// already loaded before this view mounted), and keep it revealed whenever a
// new support message comes in.
if (isWidgetReady.value) {
showSupportBubble();
} else {
window.addEventListener('chatwoot:ready', onWidgetReady);
}
window.addEventListener('chatwoot:on-message', showSupportBubble);
});
onBeforeUnmount(() => {
window.removeEventListener('chatwoot:ready', onWidgetReady);
window.removeEventListener('chatwoot:on-message', showSupportBubble);
});
</script>
@@ -25,6 +54,16 @@ onMounted(() => {
<EmptyState
:title="$t('APP_GLOBAL.ACCOUNT_SUSPENDED.TITLE')"
:message="$t('APP_GLOBAL.ACCOUNT_SUSPENDED.MESSAGE')"
/>
>
<div v-if="canContactSupport" class="flex justify-center">
<NextButton
icon="i-lucide-life-buoy"
:label="$t('SIDEBAR_ITEMS.CONTACT_SUPPORT')"
:is-loading="!isWidgetReady"
:disabled="!isWidgetReady"
@click="toggleSupportWidget"
/>
</div>
</EmptyState>
</div>
</template>