From 02ad26469355bf891fb4e5b624425d8e49118748 Mon Sep 17 00:00:00 2001 From: Dmitriy Shamal Date: Sun, 20 Apr 2025 14:49:06 +0300 Subject: [PATCH 1/2] fix: condition --- .../pages/admin/ConditionPage/ConditionPage.tsx | 4 +++- .../ConditionPage/components/Jettons/Jettons.tsx | 14 +++++++++----- .../admin/ConditionPage/components/NFT/NFT.tsx | 10 ++++++---- .../ConditionPage/components/Premium/Premium.tsx | 2 +- .../ConditionPage/components/Toncoin/Toncoin.tsx | 2 +- .../components/Whitelist/Whitelist.tsx | 5 ++--- .../NewConditionModule/NewConditionModule.tsx | 9 +++------ 7 files changed, 25 insertions(+), 21 deletions(-) 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, From d30bee4a0a152a0cea4b567980d85a15dd4c9652 Mon Sep 17 00:00:00 2001 From: Dmitriy Shamal Date: Sun, 20 Apr 2025 15:08:55 +0300 Subject: [PATCH 2/2] feat: hidden chat --- frontend/src/Routes.tsx | 6 +++ .../src/pages/admin/ChatPage/ChatPage.tsx | 43 ++++++++++++------- .../ClientChatHidden/ClientChatHidden.tsx | 36 ++++++++++++++++ .../pages/client/ClientChatHidden/index.ts | 1 + .../ClientTasksPage/ClientTasksPage.tsx | 8 ++++ frontend/src/pages/client/index.ts | 1 + frontend/src/pages/not-found/NotFound.tsx | 4 +- frontend/src/store/chat/api.ts | 12 ++++++ frontend/src/store/chat/chat.ts | 18 ++++++++ frontend/src/store/chat/types.ts | 1 + 10 files changed, 113 insertions(+), 17 deletions(-) create mode 100644 frontend/src/pages/client/ClientChatHidden/ClientChatHidden.tsx create mode 100644 frontend/src/pages/client/ClientChatHidden/index.ts 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/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 {