diff --git a/frontend/src/Routes.tsx b/frontend/src/Routes.tsx
index c8f45651..3fe545df 100644
--- a/frontend/src/Routes.tsx
+++ b/frontend/src/Routes.tsx
@@ -10,6 +10,7 @@ import {
ClientWalletsListPage,
ClientJoinPage,
NotFound,
+ ClientChatHidden,
} from '@pages'
import { Route, Routes } from 'react-router-dom'
@@ -26,6 +27,7 @@ export const ROUTES_NAME = {
CLIENT_WALLETS_LIST: '/client/:clientChatSlug/wallets-list',
CLIENT_JOIN: '/client/:clientChatSlug/join',
NOT_FOUND: '/not-found',
+ CLIENT_CHAT_HIDDEN: '/chat-hidden',
}
export default (
@@ -57,5 +59,9 @@ export default (
/>
} />
} />
+ }
+ />
)
diff --git a/frontend/src/pages/admin/ChatPage/ChatPage.tsx b/frontend/src/pages/admin/ChatPage/ChatPage.tsx
index a4890584..4237b9d0 100644
--- a/frontend/src/pages/admin/ChatPage/ChatPage.tsx
+++ b/frontend/src/pages/admin/ChatPage/ChatPage.tsx
@@ -11,7 +11,7 @@ import {
import { useAppNavigation, useError } from '@hooks'
import { ROUTES_NAME } from '@routes'
import { goTo } from '@utils'
-import { useEffect } from 'react'
+import { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'
import { useApp, useAppActions, useChat, useChatActions } from '@store'
@@ -24,14 +24,15 @@ export const ChatPage = () => {
const { isLoading } = useApp()
const { toggleIsLoadingAction } = useAppActions()
- const { showToast } = useToast()
+ const [updateChatVisibilityLoading, setUpdateChatVisibilityLoading] =
+ useState(false)
const { adminChatNotFound } = useError()
const { rules, chat } = useChat()
- const { fetchChatAction } = useChatActions()
+ const { fetchChatAction, updateChatVisibilityAction } = useChatActions()
- const isChatVisible = true
+ const { showToast } = useToast()
const fetchChat = async () => {
if (!chatSlug) return
@@ -43,6 +44,24 @@ export const ChatPage = () => {
}
}
+ const updateChatVisibility = async () => {
+ if (!chatSlug) return
+ try {
+ setUpdateChatVisibilityLoading(true)
+ await updateChatVisibilityAction(chatSlug, {
+ isEnabled: !chat?.isEnabled,
+ })
+ } catch (error) {
+ console.error(error)
+ } finally {
+ setUpdateChatVisibilityLoading(false)
+ showToast({
+ message: 'Chat visibility updated',
+ type: 'success',
+ })
+ }
+ }
+
useEffect(() => {
toggleIsLoadingAction(true)
fetchChat()
@@ -58,13 +77,6 @@ export const ChatPage = () => {
goTo(chat?.joinUrl)
}
- const handleChatVisibility = () => {
- showToast({
- message: 'Chat visibility is not available yet',
- type: 'error',
- })
- }
-
return (
{
- {isChatVisible ? 'Hide Bot From Chat' : 'Show Bot in Chat'}
+
+ {chat?.isEnabled ? 'Hide Bot From Chat' : 'Show Bot in Chat'}
}
- onClick={handleChatVisibility}
+ onClick={updateChatVisibility}
before={
-
+
}
/>
diff --git a/frontend/src/pages/admin/ConditionPage/ConditionPage.tsx b/frontend/src/pages/admin/ConditionPage/ConditionPage.tsx
index 3829c71d..c912d76e 100644
--- a/frontend/src/pages/admin/ConditionPage/ConditionPage.tsx
+++ b/frontend/src/pages/admin/ConditionPage/ConditionPage.tsx
@@ -24,7 +24,9 @@ export const ConditionPage = () => {
})
}
- if (!conditionIdParam)
+ const isNewCondition = !conditionIdParam
+
+ if (isNewCondition)
return (
diff --git a/frontend/src/pages/admin/ConditionPage/components/Jettons/Jettons.tsx b/frontend/src/pages/admin/ConditionPage/components/Jettons/Jettons.tsx
index ec5a1d23..8847d072 100644
--- a/frontend/src/pages/admin/ConditionPage/components/Jettons/Jettons.tsx
+++ b/frontend/src/pages/admin/ConditionPage/components/Jettons/Jettons.tsx
@@ -55,7 +55,7 @@ export const Jettons = ({
prefetchJetton(address)
}, 150),
- []
+ [conditionState?.address, conditionState?.blockchainAddress]
)
const fetchConditionCategories = async () => {
@@ -73,10 +73,14 @@ export const Jettons = ({
}
useEffect(() => {
- if (!isNewCondition && conditionState?.blockchainAddress) {
+ if (
+ !isNewCondition &&
+ conditionState?.blockchainAddress &&
+ !prefetchedConditionData
+ ) {
prefetchJetton(conditionState?.blockchainAddress)
}
- }, [conditionState])
+ }, [conditionState, isNewCondition])
useEffect(() => {
fetchConditionCategories()
@@ -86,7 +90,7 @@ export const Jettons = ({
}, [])
useEffect(() => {
- if (categories?.length && (isNewCondition || condition)) {
+ if (categories?.length) {
let updatedConditionState: Partial = {
type: 'jetton',
asset: condition?.asset || categories[0].asset,
@@ -104,7 +108,7 @@ export const Jettons = ({
setInitialState(updatedConditionState as Partial)
}
- }, [categories?.length, condition])
+ }, [categories?.length, condition, isNewCondition])
if (!categories?.length || !conditionState?.type) return null
diff --git a/frontend/src/pages/admin/ConditionPage/components/NFT/NFT.tsx b/frontend/src/pages/admin/ConditionPage/components/NFT/NFT.tsx
index 638fdb9e..bdfdb87d 100644
--- a/frontend/src/pages/admin/ConditionPage/components/NFT/NFT.tsx
+++ b/frontend/src/pages/admin/ConditionPage/components/NFT/NFT.tsx
@@ -66,7 +66,10 @@ export const NFT = ({
useEffect(() => {
if (
!isNewCondition &&
- (conditionState?.blockchainAddress || conditionState?.address)
+ (conditionState?.blockchainAddress || conditionState?.address) &&
+ !prefetchedConditionData &&
+ !conditionState.asset &&
+ !conditionState.category
) {
prefetchNFTCollection(
conditionState?.blockchainAddress || conditionState?.address || ''
@@ -82,9 +85,8 @@ export const NFT = ({
}, [])
useEffect(() => {
- if (categories?.length && (isNewCondition || condition)) {
+ if (categories?.length) {
let updatedConditionState: Partial = {
- // ...conditionState,
type: 'nft_collection',
asset: condition?.asset || undefined,
category: condition?.category || undefined,
@@ -101,7 +103,7 @@ export const NFT = ({
setInitialState(updatedConditionState as Partial)
}
- }, [categories?.length, condition])
+ }, [categories?.length, condition, isNewCondition])
if (!categories?.length || !conditionState?.type) return null
diff --git a/frontend/src/pages/admin/ConditionPage/components/Premium/Premium.tsx b/frontend/src/pages/admin/ConditionPage/components/Premium/Premium.tsx
index 86aeea0d..2b47d4d2 100644
--- a/frontend/src/pages/admin/ConditionPage/components/Premium/Premium.tsx
+++ b/frontend/src/pages/admin/ConditionPage/components/Premium/Premium.tsx
@@ -18,7 +18,7 @@ export const Premium = ({
isEnabled: isNewCondition ? true : !!condition?.isEnabled,
}
setInitialState(updatedConditionState as Partial)
- }, [condition])
+ }, [condition, isNewCondition])
if (!conditionState?.type) return null
diff --git a/frontend/src/pages/admin/ConditionPage/components/Toncoin/Toncoin.tsx b/frontend/src/pages/admin/ConditionPage/components/Toncoin/Toncoin.tsx
index ed5bf888..5c39a900 100644
--- a/frontend/src/pages/admin/ConditionPage/components/Toncoin/Toncoin.tsx
+++ b/frontend/src/pages/admin/ConditionPage/components/Toncoin/Toncoin.tsx
@@ -57,7 +57,7 @@ export const Toncoin = ({
setInitialState(updatedConditionState as Partial)
}
- }, [categories?.length, condition])
+ }, [categories?.length, condition, isNewCondition])
if (!categories?.length || !conditionState?.type) return null
diff --git a/frontend/src/pages/admin/ConditionPage/components/Whitelist/Whitelist.tsx b/frontend/src/pages/admin/ConditionPage/components/Whitelist/Whitelist.tsx
index 35c384b1..3c2aa63f 100644
--- a/frontend/src/pages/admin/ConditionPage/components/Whitelist/Whitelist.tsx
+++ b/frontend/src/pages/admin/ConditionPage/components/Whitelist/Whitelist.tsx
@@ -17,9 +17,8 @@ export const Whitelist = ({
const { showToast } = useToast()
useEffect(() => {
- if (isNewCondition || condition) {
+ if (isNewCondition) {
let updatedConditionState: Partial = {
- // ...conditionState,
type: 'whitelist',
description: condition?.description || '',
name: condition?.name || '',
@@ -35,7 +34,7 @@ export const Whitelist = ({
setInitialState(updatedConditionState as Partial)
}
- }, [condition])
+ }, [condition, isNewCondition])
if (!conditionState?.type) return null
diff --git a/frontend/src/pages/admin/ConditionPage/modules/NewConditionModule/NewConditionModule.tsx b/frontend/src/pages/admin/ConditionPage/modules/NewConditionModule/NewConditionModule.tsx
index 613ca8c1..7d4df8d6 100644
--- a/frontend/src/pages/admin/ConditionPage/modules/NewConditionModule/NewConditionModule.tsx
+++ b/frontend/src/pages/admin/ConditionPage/modules/NewConditionModule/NewConditionModule.tsx
@@ -106,12 +106,9 @@ export const NewConditionModule = () => {
})
}
- const setInitialState = useCallback(
- (value: Partial) => {
- setConditionState(value)
- },
- [conditionState?.type]
- )
+ const setInitialState = (value: Partial) => {
+ setConditionState(value)
+ }
const payload: ConditionComponentProps = {
isNewCondition: true,
diff --git a/frontend/src/pages/client/ClientChatHidden/ClientChatHidden.tsx b/frontend/src/pages/client/ClientChatHidden/ClientChatHidden.tsx
new file mode 100644
index 00000000..22be6fcc
--- /dev/null
+++ b/frontend/src/pages/client/ClientChatHidden/ClientChatHidden.tsx
@@ -0,0 +1,36 @@
+import sneezeLottie from '@assets/sneeze.json'
+import {
+ Block,
+ StickerPlayer,
+ TelegramBackButton,
+ TelegramMainButton,
+ Text,
+} from '@components'
+import { PageLayout } from '@components'
+
+const webApp = window.Telegram.WebApp
+
+export const ClientChatHidden = () => {
+ const handleCloseApp = () => {
+ webApp.close()
+ }
+
+ return (
+
+
+
+
+
+
+ Chat or Channel Access Is Temporarily Disabled
+
+
+
+
+ The admin has temporarily hidden this chat or channel. Please try
+ again later or contact them directly.
+
+
+
+ )
+}
diff --git a/frontend/src/pages/client/ClientChatHidden/index.ts b/frontend/src/pages/client/ClientChatHidden/index.ts
new file mode 100644
index 00000000..5f4893ba
--- /dev/null
+++ b/frontend/src/pages/client/ClientChatHidden/index.ts
@@ -0,0 +1 @@
+export * from './ClientChatHidden'
diff --git a/frontend/src/pages/client/ClientTasksPage/ClientTasksPage.tsx b/frontend/src/pages/client/ClientTasksPage/ClientTasksPage.tsx
index 38901313..7a3c594a 100644
--- a/frontend/src/pages/client/ClientTasksPage/ClientTasksPage.tsx
+++ b/frontend/src/pages/client/ClientTasksPage/ClientTasksPage.tsx
@@ -45,6 +45,14 @@ export const ClientTasksPage = () => {
}, [clientChatSlug])
useEffect(() => {
+ if (!chat?.isEnabled) {
+ appNavigate({
+ path: ROUTES_NAME.CLIENT_CHAT_HIDDEN,
+ params: { clientChatSlug },
+ })
+ return
+ }
+
if (chat?.isEligible) {
appNavigate({
path: ROUTES_NAME.CLIENT_JOIN,
diff --git a/frontend/src/pages/client/index.ts b/frontend/src/pages/client/index.ts
index 99bb6d5f..31923076 100644
--- a/frontend/src/pages/client/index.ts
+++ b/frontend/src/pages/client/index.ts
@@ -1,3 +1,4 @@
+export * from './ClientChatHidden'
export * from './ClientTasksPage'
export * from './ClientConnectedWalletPage'
export * from './ClientWalletsListPage'
diff --git a/frontend/src/pages/not-found/NotFound.tsx b/frontend/src/pages/not-found/NotFound.tsx
index 047892af..bdad9610 100644
--- a/frontend/src/pages/not-found/NotFound.tsx
+++ b/frontend/src/pages/not-found/NotFound.tsx
@@ -27,8 +27,8 @@ export const NotFound = () => {
- The page you’re looking for doesn’t exist or the link is broken. But
- don’t worry — you’re still in the right universe.
+ The page you`re looking for doesn`t exist or the link is broken. But
+ don`t worry — you`re still in the right universe.
diff --git a/frontend/src/store/chat/api.ts b/frontend/src/store/chat/api.ts
index d17d4629..abd9583f 100644
--- a/frontend/src/store/chat/api.ts
+++ b/frontend/src/store/chat/api.ts
@@ -43,3 +43,15 @@ export const fetchUserChatAPI = async (
return response
}
+
+export const updateChatVisibilityAPI = async (
+ slug: string,
+ data: Partial
+): Promise> => {
+ const response = await ApiService.put({
+ endpoint: `/admin/chats/${slug}/visibility`,
+ data,
+ })
+
+ return response
+}
diff --git a/frontend/src/store/chat/chat.ts b/frontend/src/store/chat/chat.ts
index 6b1b370f..1874fa32 100644
--- a/frontend/src/store/chat/chat.ts
+++ b/frontend/src/store/chat/chat.ts
@@ -7,6 +7,7 @@ import {
fetchChatAPI,
fetchUserChatAPI,
updateChatAPI,
+ updateChatVisibilityAPI,
} from './api'
import { AdminChat, ChatInstance } from './types'
@@ -26,6 +27,10 @@ interface ChatActions {
updateChatAction: (slug: string, data: Partial) => void
fetchAdminUserChatsAction: () => Promise
fetchUserChatAction: (slug: string) => void
+ updateChatVisibilityAction: (
+ slug: string,
+ data: Partial
+ ) => void
}
}
@@ -81,6 +86,19 @@ const useChatStore = create((set) => ({
set({ chat: data?.chat, rules: data?.rules, chatWallet: data?.wallet })
},
+ updateChatVisibilityAction: async (slug, values) => {
+ const { data, ok, error } = await updateChatVisibilityAPI(slug, values)
+
+ if (!ok) {
+ throw new Error(error)
+ }
+
+ if (!data) {
+ throw new Error('Chat data not found')
+ }
+
+ set({ chat: data })
+ },
},
}))
diff --git a/frontend/src/store/chat/types.ts b/frontend/src/store/chat/types.ts
index e664b33d..ba9a37e1 100644
--- a/frontend/src/store/chat/types.ts
+++ b/frontend/src/store/chat/types.ts
@@ -19,6 +19,7 @@ export interface ChatInstance {
title: string
username: string | null
membersCount: number
+ isEnabled: boolean
}
export interface ChatRuleAttribute {