diff --git a/packages/commonwealth/client/scripts/models/types.ts b/packages/commonwealth/client/scripts/models/types.ts index 2cf81698304..7095a34e894 100644 --- a/packages/commonwealth/client/scripts/models/types.ts +++ b/packages/commonwealth/client/scripts/models/types.ts @@ -38,6 +38,11 @@ export enum ThreadFeaturedFilterTypes { LatestActivity = 'latestActivity', } +export enum ThreadViewFilterTypes { + All = 'all', + Overview = 'overview', +} + export enum CommentsFeaturedFilterTypes { Newest = 'newest', Oldest = 'oldest', diff --git a/packages/commonwealth/client/scripts/views/components/component_kit/cw_icons/cw_icon_lookup.ts b/packages/commonwealth/client/scripts/views/components/component_kit/cw_icons/cw_icon_lookup.ts index 52eb337b034..39e5b83f72a 100644 --- a/packages/commonwealth/client/scripts/views/components/component_kit/cw_icons/cw_icon_lookup.ts +++ b/packages/commonwealth/client/scripts/views/components/component_kit/cw_icons/cw_icon_lookup.ts @@ -25,6 +25,7 @@ import { Check, CheckCircle, CircleNotch, + CirclesFour, CirclesThreePlus, Clipboard, ClockCounterClockwise, @@ -292,6 +293,8 @@ export const iconLookup = { download: withPhosphorIcon(Download), downloadSimple: withPhosphorIcon(DownloadSimple), copySimple: withPhosphorIcon(CopySimple), + viewAll: withPhosphorIcon(Rows), + viewOverView: withPhosphorIcon(CirclesFour), }; export const customIconLookup = { diff --git a/packages/commonwealth/client/scripts/views/components/sidebar/discussion_section.tsx b/packages/commonwealth/client/scripts/views/components/sidebar/discussion_section.tsx index d2122a0839c..59f28f8a17f 100644 --- a/packages/commonwealth/client/scripts/views/components/sidebar/discussion_section.tsx +++ b/packages/commonwealth/client/scripts/views/components/sidebar/discussion_section.tsx @@ -1,8 +1,7 @@ import React from 'react'; +import { matchRoutes, useLocation } from 'react-router-dom'; -import 'components/sidebar/index.scss'; import { useCommonNavigate } from 'navigation/helpers'; -import { matchRoutes, useLocation } from 'react-router-dom'; import app from 'state'; import { useFetchTopicsQuery } from 'state/api/topics'; import { sidebarStore } from 'state/ui/sidebar'; @@ -17,6 +16,8 @@ import type { ToggleTree, } from './types'; +import 'components/sidebar/index.scss'; + const resetSidebarState = () => { if (isWindowSmallInclusive(window.innerWidth)) { sidebarStore.getState().setMenu({ name: 'default', isVisible: false }); @@ -24,7 +25,6 @@ const resetSidebarState = () => { sidebarStore.getState().setMenu({ name: 'default', isVisible: true }); } }; - function setDiscussionsToggleTree(path: string, toggle: boolean) { let currentTree = JSON.parse( localStorage[`${app.activeChainId()}-discussions-toggle-tree`], @@ -42,27 +42,20 @@ function setDiscussionsToggleTree(path: string, toggle: boolean) { localStorage[`${app.activeChainId()}-discussions-toggle-tree`] = JSON.stringify(newTree); } - interface DiscussionSectionProps { isContestAvailable: boolean; topicIdsIncludedInContest: number[]; } - export const DiscussionSection = ({ isContestAvailable, topicIdsIncludedInContest, }: DiscussionSectionProps) => { const navigate = useCommonNavigate(); const location = useLocation(); - const matchesDiscussionsRoute = matchRoutes( [{ path: '/discussions' }, { path: ':scope/discussions' }], location, ); - const matchesOverviewRoute = matchRoutes( - [{ path: '/overview' }, { path: ':scope/overview' }], - location, - ); const matchesContestsRoute = matchRoutes( [{ path: '/contests' }, { path: ':scope/contests' }], location, @@ -124,7 +117,6 @@ export const DiscussionSection = ({ const toggleTreeState = JSON.parse( localStorage[`${app.activeChainId()}-discussions-toggle-tree`], ); - const discussionsGroupData: SectionGroupAttrs[] = [ { title: 'All', @@ -171,22 +163,6 @@ export const DiscussionSection = ({ }, ] : []), - { - title: 'Overview', - containsChildren: false, - hasDefaultToggle: false, - isVisible: true, - isUpdated: true, - isActive: !!matchesOverviewRoute, - onClick: (e, toggle: boolean) => { - e.preventDefault(); - resetSidebarState(); - handleRedirectClicks(navigate, e, `/overview`, communityId, () => { - setDiscussionsToggleTree(`children.Overview.toggledState`, toggle); - }); - }, - displayData: null, - }, ]; for (const topic of topics) { diff --git a/packages/commonwealth/client/scripts/views/pages/discussions/DiscussionsPage.tsx b/packages/commonwealth/client/scripts/views/pages/discussions/DiscussionsPage.tsx index 8057a64e275..102ad23a623 100644 --- a/packages/commonwealth/client/scripts/views/pages/discussions/DiscussionsPage.tsx +++ b/packages/commonwealth/client/scripts/views/pages/discussions/DiscussionsPage.tsx @@ -1,7 +1,7 @@ import { PermissionEnum, TopicWeightedVoting } from '@hicommonwealth/schemas'; import { getProposalUrlPath } from 'identifiers'; import { getScopePrefix, useCommonNavigate } from 'navigation/helpers'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; import { Virtuoso } from 'react-virtuoso'; import useFetchThreadsQuery, { @@ -19,6 +19,7 @@ import { ThreadCard } from './ThreadCard'; import { sortByFeaturedFilter, sortPinned } from './helpers'; import { slugify, splitAndDecodeURL } from '@hicommonwealth/shared'; +import useUserStore from 'client/scripts/state/ui/user'; import { getThreadActionTooltipText } from 'helpers/threads'; import useBrowserWindow from 'hooks/useBrowserWindow'; import useManageDocumentTitle from 'hooks/useManageDocumentTitle'; @@ -27,7 +28,6 @@ import 'pages/discussions/index.scss'; import { useGetCommunityByIdQuery } from 'state/api/communities'; import { useFetchCustomDomainQuery } from 'state/api/configuration'; import { useGetERC20BalanceQuery } from 'state/api/tokens'; -import useUserStore from 'state/ui/user'; import Permissions from 'utils/Permissions'; import { saveToClipboard } from 'utils/clipboard'; import { checkIsTopicInContest } from 'views/components/NewThreadFormLegacy/helpers'; @@ -40,14 +40,23 @@ import { AdminOnboardingSlider } from '../../components/AdminOnboardingSlider'; import { UserTrainingSlider } from '../../components/UserTrainingSlider'; import { CWText } from '../../components/component_kit/cw_text'; import CWIconButton from '../../components/component_kit/new_designs/CWIconButton'; +import OverviewPage from '../overview'; import { DiscussionsFeedDiscovery } from './DiscussionsFeedDiscovery'; import { EmptyThreadsPlaceholder } from './EmptyThreadsPlaceholder'; type DiscussionsPageProps = { + tabs?: { value: string; label: string }; + selectedView?: string; topicName?: string; + updateSelectedView?: (tabValue: string) => void; }; - +const VIEWS = [ + { value: 'all', label: 'All' }, + { value: 'overview', label: 'Overview' }, +]; const DiscussionsPage = ({ topicName }: DiscussionsPageProps) => { + const [selectedView, setSelectedView] = useState(VIEWS[0].value); + const communityId = app.activeChainId() || ''; const navigate = useCommonNavigate(); const [includeSpamThreads, setIncludeSpamThreads] = useState(false); @@ -77,8 +86,14 @@ const DiscussionsPage = ({ topicName }: DiscussionsPageProps) => { }); const contestAddress = searchParams.get('contest'); const contestStatus = searchParams.get('status'); + const tabStatus = searchParams.get('tab'); const containerRef = useRef(); + useLayoutEffect(() => { + if (tabStatus === 'overview') { + setSelectedView(VIEWS[1].value); + } + }, [tabStatus]); useBrowserWindow({}); @@ -139,7 +154,7 @@ const DiscussionsPage = ({ topicName }: DiscussionsPageProps) => { contestAddress, // @ts-expect-error contestStatus, - apiEnabled: !!communityId, + apiEnabled: !!communityId && selectedView === 'all', }); const threads = sortPinned(sortByFeaturedFilter(data || [], featuredFilter)); @@ -165,7 +180,9 @@ const DiscussionsPage = ({ topicName }: DiscussionsPageProps) => { if ( !isLoadingTopics && topicNameFromURL && - topicNameFromURL !== 'archived' + topicNameFromURL !== 'archived' && + topicNameFromURL !== 'overview' && + tabStatus !== 'overview' ) { const validTopics = topics?.some( (topic) => topic?.name === topicNameFromURL, @@ -174,6 +191,9 @@ const DiscussionsPage = ({ topicName }: DiscussionsPageProps) => { navigate('/discussions'); } } + if (topicNameFromURL === 'overview') { + setSelectedView(VIEWS[1].value); + } // eslint-disable-next-line react-hooks/exhaustive-deps }, [topics, topicNameFromURL, isLoadingTopics]); @@ -198,197 +218,203 @@ const DiscussionsPage = ({ topicName }: DiscussionsPageProps) => { ).toFixed(0), ) : ''; + const updateSelectedView = (activeTab: string) => { + const params = new URLSearchParams(); + params.set('tab', activeTab); + navigate(`${window.location.pathname}?${params.toString()}`, {}, null); + setSelectedView(activeTab); + }; return ( - // @ts-expect-error - - - { - const discussionLink = getProposalUrlPath( - thread.slug, - `${thread.identifier}-${slugify(thread.title)}`, - ); - - const isTopicGated = !!(memberships || []).find( - (membership) => - thread?.topic?.id && - membership.topics.find((t) => t.id === thread.topic!.id), - ); - - const isActionAllowedInGatedTopic = !!(memberships || []).find( - (membership) => - thread?.topic?.id && - membership.topics.find((t) => t.id === thread.topic!.id) && - membership.isAllowed, - ); - - const isRestrictedMembership = - !isAdmin && isTopicGated && !isActionAllowedInGatedTopic; - - const foundTopicPermissions = topicPermissions.find( - (tp) => tp.id === thread.topic!.id, - ); - - const disabledActionsTooltipText = getThreadActionTooltipText({ - isCommunityMember: !!user.activeAccount, - isThreadArchived: !!thread?.archivedAt, - isThreadLocked: !!thread?.lockedAt, - isThreadTopicGated: isRestrictedMembership, - }); - - const disabledReactPermissionTooltipText = getThreadActionTooltipText( - { - isCommunityMember: !!user.activeAccount, - threadTopicInteractionRestrictions: - !isAdmin && - !foundTopicPermissions?.permissions?.includes( - // this should be updated if we start displaying recent comments on this page - PermissionEnum.CREATE_THREAD_REACTION, - ) - ? foundTopicPermissions?.permissions - : undefined, - }, - ); - - const disabledCommentPermissionTooltipText = - getThreadActionTooltipText({ - isCommunityMember: !!user.activeAccount, - threadTopicInteractionRestrictions: - !isAdmin && - !foundTopicPermissions?.permissions?.includes( - PermissionEnum.CREATE_COMMENT, - ) - ? foundTopicPermissions?.permissions - : undefined, - }); - - const isThreadTopicInContest = checkIsTopicInContest( - contestsData.all, - thread?.topic?.id, - ); - - return ( - navigate(`${discussionLink}?isEdit=true`)} - onStageTagClick={() => { - navigate(`/discussions?stage=${thread.stage}`); - }} - threadHref={`${getScopePrefix()}${discussionLink}`} - onBodyClick={() => { - const scrollEle = document.getElementsByClassName('Body')[0]; - - localStorage[`${communityId}-discussions-scrollY`] = - scrollEle.scrollTop; - }} - onCommentBtnClick={() => - navigate(`${discussionLink}?focusComments=true`) - } - disabledActionsTooltipText={ - disabledCommentPermissionTooltipText || - disabledReactPermissionTooltipText || - disabledActionsTooltipText - } - hideRecentComments - editingDisabled={isThreadTopicInContest} - /> - ); - }} - endReached={() => { - hasNextPage && fetchNextPage(); - }} - overscan={50} - components={{ - // eslint-disable-next-line react/no-multi-comp - EmptyPlaceholder: () => ( - - ), - // eslint-disable-next-line react/no-multi-comp - Header: () => ( - <> - - - - {isTopicWeighted && ( - - - This topic has weighted voting enabled using{' '} - - {topicObj.token_address} - - { - saveToClipboard( - topicObj.token_address!, - true, - ).catch(console.error); - }} - /> - - - ), + <> + + ref={containerRef} + className="DiscussionsPageLayout" + > + + {/* Updated Header Content Outside Virsoto */} + + + + + {isTopicWeighted && ( + + + This topic has weighted voting enabled using{' '} + + {topicObj.token_address} + + { + saveToClipboard(topicObj.token_address!, true).catch( + console.error, + ); + }} + /> + + + ), + }} + /> + )} + + + topic={topicName} + stage={stageName} + featuredFilter={featuredFilter} + dateRange={dateRange} + totalThreadCount={ + isOnArchivePage + ? filteredThreads.length || 0 + : threads + ? community?.lifetime_thread_count || 0 + : 0 + } + isIncludingSpamThreads={includeSpamThreads} + onIncludeSpamThreads={setIncludeSpamThreads} + isIncludingArchivedThreads={includeArchivedThreads} + onIncludeArchivedThreads={setIncludeArchivedThreads} + isOnArchivePage={isOnArchivePage} + activeContests={activeContestsInTopic} + views={VIEWS} + selectedView={selectedView} + setSelectedView={updateSelectedView} + /> + + {selectedView === VIEWS[0].value ? ( + { + const discussionLink = getProposalUrlPath( + thread.slug, + `${thread.identifier}-${slugify(thread.title)}`, + ); + + const isTopicGated = !!(memberships || []).find( + (membership) => + thread?.topic?.id && + membership.topics.find((t) => t.id === thread.topic!.id), + ); + const isActionAllowedInGatedTopic = !!(memberships || []).find( + (membership) => + thread?.topic?.id && + membership.topics.find((t) => t.id === thread.topic!.id) && + membership.isAllowed, + ); + const isRestrictedMembership = + !isAdmin && isTopicGated && !isActionAllowedInGatedTopic; + const foundTopicPermissions = topicPermissions.find( + (tp) => tp.id === thread.topic!.id, + ); + const disabledActionsTooltipText = getThreadActionTooltipText({ + isCommunityMember: !!user.activeAccount, + isThreadArchived: !!thread?.archivedAt, + isThreadLocked: !!thread?.lockedAt, + isThreadTopicGated: isRestrictedMembership, + }); + const disabledReactPermissionTooltipText = + getThreadActionTooltipText({ + isCommunityMember: !!user.activeAccount, + threadTopicInteractionRestrictions: + !isAdmin && + !foundTopicPermissions?.permissions?.includes( + // this should be updated if we start displaying recent comments on this page + PermissionEnum.CREATE_THREAD_REACTION, + ) + ? foundTopicPermissions?.permissions + : undefined, + }); + const disabledCommentPermissionTooltipText = + getThreadActionTooltipText({ + isCommunityMember: !!user.activeAccount, + threadTopicInteractionRestrictions: + !isAdmin && + !foundTopicPermissions?.permissions?.includes( + PermissionEnum.CREATE_COMMENT, + ) + ? foundTopicPermissions?.permissions + : undefined, + }); + const isThreadTopicInContest = checkIsTopicInContest( + contestsData.all, + thread?.topic?.id, + ); + + return ( + navigate(`${discussionLink}?isEdit=true`)} + onStageTagClick={() => { + navigate(`/discussions?stage=${thread.stage}`); }} + threadHref={`${getScopePrefix()}${discussionLink}`} + onBodyClick={() => { + const scrollEle = + document.getElementsByClassName('Body')[0]; + localStorage[`${communityId}-discussions-scrollY`] = + scrollEle.scrollTop; + }} + onCommentBtnClick={() => + navigate(`${discussionLink}?focusComments=true`) + } + disabledActionsTooltipText={ + disabledCommentPermissionTooltipText || + disabledReactPermissionTooltipText || + disabledActionsTooltipText + } + hideRecentComments + editingDisabled={isThreadTopicInContest} + /> + ); + }} + endReached={() => { + hasNextPage && fetchNextPage(); + }} + overscan={50} + components={{ + // eslint-disable-next-line react/no-multi-comp + EmptyPlaceholder: () => ( + - )} - - - topic={topicName} - stage={stageName} - featuredFilter={featuredFilter} - dateRange={dateRange} - totalThreadCount={ - isOnArchivePage - ? filteredThreads.length || 0 - : threads - ? community?.lifetime_thread_count || 0 - : 0 - } - isIncludingSpamThreads={includeSpamThreads} - onIncludeSpamThreads={setIncludeSpamThreads} - isIncludingArchivedThreads={includeArchivedThreads} - onIncludeArchivedThreads={setIncludeArchivedThreads} - isOnArchivePage={isOnArchivePage} - activeContests={activeContestsInTopic} - /> - - ), - }} - /> - + ), + }} + /> + ) : ( + + )} + + ); }; - export default DiscussionsPage; diff --git a/packages/commonwealth/client/scripts/views/pages/discussions/HeaderWithFilters/HeaderWithFilters.tsx b/packages/commonwealth/client/scripts/views/pages/discussions/HeaderWithFilters/HeaderWithFilters.tsx index e902b24a08d..5823ed675b5 100644 --- a/packages/commonwealth/client/scripts/views/pages/discussions/HeaderWithFilters/HeaderWithFilters.tsx +++ b/packages/commonwealth/client/scripts/views/pages/discussions/HeaderWithFilters/HeaderWithFilters.tsx @@ -25,9 +25,21 @@ import { ThreadFeaturedFilterTypes, ThreadStage, ThreadTimelineFilterTypes, + ThreadViewFilterTypes, } from '../../../../models/types'; import './HeaderWithFilters.scss'; +type TabsProps = { + label: string; + value: string; +}; + +type ViewType = { + id: number; + value: string; + label: string; + iconLeft: string; +}; type HeaderWithFiltersProps = { stage: string; topic: string; @@ -40,6 +52,9 @@ type HeaderWithFiltersProps = { onIncludeArchivedThreads: (includeArchived: boolean) => any; isOnArchivePage?: boolean; activeContests: Contest[]; + views?: TabsProps[]; + selectedView?: string; + setSelectedView?: (tabValue: string) => void; }; export const HeaderWithFilters = ({ @@ -54,6 +69,9 @@ export const HeaderWithFilters = ({ onIncludeArchivedThreads, isOnArchivePage, activeContests, + views, + selectedView, + setSelectedView, }: HeaderWithFiltersProps) => { const navigate = useCommonNavigate(); const location = useLocation(); @@ -199,13 +217,38 @@ export const HeaderWithFilters = ({ return (
- - {isUndefined(topic) - ? isOnArchivePage - ? 'Archived' - : 'All Discussions' - : topic} - + {views && views.length ? ( +
+ { - onFilterSelect({ - filterKey: 'featured', - filterVal: item.value as ThreadFeaturedFilterTypes, - }); - }} - options={[ - { - id: 1, - value: ThreadFeaturedFilterTypes.Newest, - label: 'Newest', - iconLeft: 'sparkle', - }, - { - id: 2, - value: ThreadFeaturedFilterTypes.Oldest, - label: 'Oldest', - iconLeft: 'clockCounterClockwise', - }, - { - id: 3, - value: ThreadFeaturedFilterTypes.MostLikes, - label: 'Upvotes', - iconLeft: 'upvote', - }, - { - id: 4, - value: ThreadFeaturedFilterTypes.MostComments, - label: 'Comments', - iconLeft: 'chatDots', - }, - { - id: 5, - value: ThreadFeaturedFilterTypes.LatestActivity, - label: 'Latest Activity', - iconLeft: 'bellRinging', - }, - ]} + {views && views[0].value === selectedView ? ( + <> + {selectedTopic?.description && ( + -
+ )} -
-

Filter

-
- {(topics || []).length > 0 && ( - { + onFilterSelect({ + filterKey: 'featured', + filterVal: item.value as ThreadFeaturedFilterTypes, + }); }} options={[ - ...(isContestAvailable - ? [{ type: 'header', label: 'Topics' }] - : []), { - id: 0, - label: 'All Topics', - value: 'All Topics', + id: 1, + value: ThreadFeaturedFilterTypes.Newest, + label: 'Newest', + iconLeft: 'sparkle', }, - ...[...featuredTopics, ...otherTopics].map((t) => ({ - id: t.id, - value: t.name, - label: t.name, - })), - ...(isContestAvailable - ? [ - { type: 'header-divider', label: 'Contests' }, - ...contestNameOptions, - ] - : []), - ]} - dropdownPosition={rightFiltersDropdownPosition} - canEditOption={Permissions.isCommunityAdmin()} - onOptionEdit={(item: any) => - setTopicSelectedToEdit( - [...featuredTopics, ...otherTopics].find( - (x) => x.id === item.id, - ), - ) - } - /> - )} - {matchesContestFilterRoute ? ( - { + if (typeof item === 'string') { + // All topics + onFilterSelect({ pickedTopic: '' }); + return; + } + + if (item.type === 'contest') { + onFilterSelect({ + filterKey: 'contest', + filterVal: item.value, + pickedTopic: '', + }); + return; + } + + onFilterSelect({ pickedTopic: item.value }); + }} + options={[ + ...(isContestAvailable + ? [{ type: 'header', label: 'Topics' }] + : []), + { + id: 0, + label: 'All Topics', + value: 'All Topics', + }, + ...[...featuredTopics, ...otherTopics].map((t) => ({ + id: t.id, + value: t.name, + label: t.name, + })), + ...(isContestAvailable + ? [ + { type: 'header-divider', label: 'Contests' }, + ...contestNameOptions, + ] + : []), + ]} + dropdownPosition={rightFiltersDropdownPosition} + canEditOption={Permissions.isCommunityAdmin()} + // eslint-disable-next-line @typescript-eslint/no-explicit-any + onOptionEdit={(item: any) => + setTopicSelectedToEdit( + [...featuredTopics, ...otherTopics].find( + (x) => x.id === item.id, + ), + ) + } + /> + )} + {matchesContestFilterRoute ? ( + + onFilterSelect({ + filterKey: 'stage', + filterVal: + typeof item !== 'string' + ? item.value === 'All Stages' + ? '' + : item.value + : '', + }) + } + options={[ + { + id: 0, + label: 'All Stages', + value: 'All Stages', + }, + ...stages.map((s) => ({ + id: s, + value: s, + label: `${threadStageToLabel(s)} ${ + s === ThreadStage.Voting + ? community?.numVotingThreads || 0 + : '' + }`, + })), + ]} + dropdownPosition={rightFiltersDropdownPosition} + /> + ) + )} { - onFilterSelect({ - filterKey: 'dateRange', - filterVal: item.value as ThreadTimelineFilterTypes, - }); +
+
+
+ )} + +
+ { + // @ts-expect-error + onIncludeSpamThreads(e.target.checked); + }} + /> + + {!isOnArchivePage && ( + { + // @ts-expect-error + onIncludeArchivedThreads(e.target.checked); }} - options={[ - { - id: 1, - value: ThreadTimelineFilterTypes.AllTime, - label: 'All Time', - }, - { - id: 2, - value: ThreadTimelineFilterTypes.ThisMonth, - label: 'Month', - }, - { - id: 3, - value: ThreadTimelineFilterTypes.ThisWeek, - label: 'Week', - }, - ]} - dropdownPosition={rightFiltersDropdownPosition} /> -
+ )}
- - )} -
- { - // @ts-expect-error - onIncludeSpamThreads(e.target.checked); - }} - /> - - {!isOnArchivePage && ( - { + {(activeContests || []).map((contest) => { + const { end_time } = // @ts-expect-error - onIncludeArchivedThreads(e.target.checked); - }} - /> - )} -
- - {(activeContests || []).map((contest) => { - const { end_time } = - // @ts-expect-error - contest?.contests[0] || {}; - - return ( - - address={contest.contest_address} - // @ts-expect-error - name={contest.name} - imageUrl={contest.image_url} - // @ts-expect-error - topics={contest.topics} - decimals={contest.decimals} - ticker={contest.ticker} - finishDate={end_time ? moment(end_time).toISOString() : ''} - isCancelled={contest.cancelled} - isRecurring={!contest.funding_token_address} - isHorizontal - showShareButton={false} - payoutStructure={contest.payout_structure} - /> - ); - })} - + contest?.contests[0] || {}; + + return ( + + address={contest.contest_address} + // @ts-expect-error + name={contest.name} + imageUrl={contest.image_url} + // @ts-expect-error + topics={contest.topics} + decimals={contest.decimals} + ticker={contest.ticker} + finishDate={end_time ? moment(end_time).toISOString() : ''} + isCancelled={contest.cancelled} + isRecurring={!contest.funding_token_address} + isHorizontal + showShareButton={false} + payoutStructure={contest.payout_structure} + /> + ); + })} + + ) : null} { const navigate = useCommonNavigate(); - const { isWindowSmallInclusive } = useBrowserWindow({}); - const user = useUserStore(); + const topicNameFromURL = splitAndDecodeURL(location.pathname); + + useRunOnceOnCondition({ + callback: () => { + if (topicNameFromURL === 'overview') { + const params = new URLSearchParams(); + params.set('tab', 'overview'); + const url = `/discussions?${params.toString()}`; + navigate(url); + } + }, + shouldRun: topicNameFromURL === 'overview', + }); const communityId = app.activeChainId() || ''; const { data: recentlyActiveThreads, isLoading } = useFetchThreadsQuery({ @@ -70,61 +79,30 @@ const OverviewPage = () => { return !topicSummaryRows.length ? ( ) : ( - -
-
-
- - Overview - - { - navigate('/discussions'); - }} - /> -
- {!isWindowSmallInclusive && ( - { - navigate('/new/discussion'); - }} - disabled={!user.activeAccount} - /> - )} -
-
+
+
+ + Topic + +
- Topic + Recent threads -
- - Recent threads - -
- - {topicSummaryRows.map((row, i) => ( - - ))}
- + + {topicSummaryRows.map((row, i) => ( + + ))} +
); }; diff --git a/packages/commonwealth/client/styles/pages/overview/index.scss b/packages/commonwealth/client/styles/pages/overview/index.scss index 86af2f38c25..84a3ccc0d91 100644 --- a/packages/commonwealth/client/styles/pages/overview/index.scss +++ b/packages/commonwealth/client/styles/pages/overview/index.scss @@ -5,6 +5,7 @@ flex: 1; flex-direction: column; width: 100%; + margin-top: 16px; .header-row { align-items: center;