diff --git a/govtool/frontend/.env.example b/govtool/frontend/.env.example index 2489d65a0..9fad9f100 100644 --- a/govtool/frontend/.env.example +++ b/govtool/frontend/.env.example @@ -7,6 +7,7 @@ VITE_GTM_ID="" VITE_IS_DEV=true VITE_USERSNAP_SPACE_API_KEY="" VITE_IS_PROPOSAL_DISCUSSION_FORUM_ENABLED='true' +VITE_IS_GOVERNANCE_OUTCOMES_PILLAR_ENABLED=true VITE_PDF_API_URL="" VITE_IPFS_GATEWAY="" VITE_IPFS_PROJECT_ID="" \ No newline at end of file diff --git a/govtool/frontend/package.json b/govtool/frontend/package.json index 909459ad4..1cff721e0 100644 --- a/govtool/frontend/package.json +++ b/govtool/frontend/package.json @@ -27,6 +27,7 @@ "@emotion/styled": "^11.11.0", "@emurgo/cardano-serialization-lib-asmjs": "^12.1.1", "@hookform/resolvers": "^3.3.1", + "@intersect.mbo/govtool-outcomes-pillar-ui": "^1.0.0-beta.1", "@intersect.mbo/intersectmbo.org-icons-set": "^1.0.8", "@intersect.mbo/pdf-ui": "^0.5.5", "@mui/icons-material": "^5.14.3", diff --git a/govtool/frontend/src/App.tsx b/govtool/frontend/src/App.tsx index 553d5295f..38fa605a5 100644 --- a/govtool/frontend/src/App.tsx +++ b/govtool/frontend/src/App.tsx @@ -2,7 +2,7 @@ import { useCallback, useEffect } from "react"; import { Route, Routes, useNavigate } from "react-router-dom"; import { Modal, ScrollToTop } from "@atoms"; -import { PATHS, PDF_PATHS } from "@consts"; +import { PATHS, PDF_PATHS, OUTCOMES_PATHS, USER_PATHS } from "@consts"; import { useCardano, useFeatureFlag, useModal } from "@context"; import { useWalletConnectionListener } from "@hooks"; import { @@ -39,9 +39,13 @@ import { import { PublicRoute } from "./pages/PublicRoute"; import { TopBanners } from "./components/organisms/TopBanners"; import { DashboardHome } from "./pages/DashboardHome"; +import { GovernanceActionOutComesPillar } from "./pages/GovernanceActionOutComes"; export default () => { - const { isProposalDiscussionForumEnabled } = useFeatureFlag(); + const { + isProposalDiscussionForumEnabled, + isGovernanceOutcomesPillarEnabled, + } = useFeatureFlag(); const { enable, isEnabled } = useCardano(); const navigate = useNavigate(); const { modal, openModal, modals } = useModal(); @@ -111,6 +115,18 @@ export default () => { element={} /> )} + {isGovernanceOutcomesPillarEnabled && ( + <> + } + /> + } + /> + + )} } diff --git a/govtool/frontend/src/components/organisms/DashboardDrawerMobile.tsx b/govtool/frontend/src/components/organisms/DashboardDrawerMobile.tsx index 00bb80cec..ac88387cc 100644 --- a/govtool/frontend/src/components/organisms/DashboardDrawerMobile.tsx +++ b/govtool/frontend/src/components/organisms/DashboardDrawerMobile.tsx @@ -18,7 +18,7 @@ export const DashboardDrawerMobile = ({ isDrawerOpen, setIsDrawerOpen, }: DashboardDrawerMobileProps) => { - const { isProposalDiscussionForumEnabled } = useFeatureFlag(); + const { isProposalDiscussionForumEnabled, isGovernanceOutcomesPillarEnabled } = useFeatureFlag(); const { screenWidth } = useScreenDimension(); const { voter } = useGetVoterInfo(); @@ -75,26 +75,60 @@ export const DashboardDrawerMobile = ({ {CONNECTED_NAV_ITEMS.map((navItem) => { - if ( - !isProposalDiscussionForumEnabled && - navItem.dataTestId === "proposal-discussion-link" - ) { - return null; - } - return ( { - // TODO: Refine if it is needed to remove this eslint-disable - // eslint-disable-next-line no-unused-expressions - navItem.newTabLink && openInNewTab(navItem.newTabLink); + if (navItem.newTabLink) { + openInNewTab(navItem.newTabLink); + } setIsDrawerOpen(false); }} isConnectWallet /> + {navItem.childNavItems && ( + + {navItem.childNavItems.map((childItem) => { + if ( + !isProposalDiscussionForumEnabled && + childItem.dataTestId === "proposal-discussion-link" + ) { + return null; + } + + if ( + !isGovernanceOutcomesPillarEnabled && + (childItem.dataTestId === "governance-actions-voted-by-me-link" || + childItem.dataTestId === "governance-actions-outcomes-link") + ) { + return null; + } + + return ( + { + if (childItem.newTabLink) { + openInNewTab(childItem.newTabLink); + } + setIsDrawerOpen(false); + }} + isConnectWallet + /> + ); + })} + + )} ); })} diff --git a/govtool/frontend/src/components/organisms/Drawer.tsx b/govtool/frontend/src/components/organisms/Drawer.tsx index 02b74ae1e..87a8d50ab 100644 --- a/govtool/frontend/src/components/organisms/Drawer.tsx +++ b/govtool/frontend/src/components/organisms/Drawer.tsx @@ -9,7 +9,7 @@ import { WalletInfoCard, DRepInfoCard } from "@molecules"; import { openInNewTab } from "@utils"; export const Drawer = () => { - const { isProposalDiscussionForumEnabled } = useFeatureFlag(); + const { isProposalDiscussionForumEnabled, isGovernanceOutcomesPillarEnabled } = useFeatureFlag(); const { voter } = useGetVoterInfo(); return ( @@ -47,13 +47,6 @@ export const Drawer = () => { rowGap={2} > {CONNECTED_NAV_ITEMS.map((navItem) => { - if ( - !isProposalDiscussionForumEnabled && - navItem.dataTestId === "proposal-discussion-link" - ) { - return null; - } - return ( { : undefined } /> + {navItem.childNavItems && ( + + {navItem.childNavItems.map((childItem) => { + if ( + !isProposalDiscussionForumEnabled && + childItem.dataTestId === "proposal-discussion-link" + ) { + return null; + } + + if ( + !isGovernanceOutcomesPillarEnabled && + (childItem.dataTestId === "governance-actions-voted-by-me-link" || + childItem.dataTestId === "governance-actions-outcomes-link") + ) { + return null; + } + + return ( + openInNewTab(childItem.newTabLink!) + : undefined + } + /> + ); + })} + + )} ); })} diff --git a/govtool/frontend/src/consts/navItems.tsx b/govtool/frontend/src/consts/navItems.tsx index 74795d562..922f2b360 100644 --- a/govtool/frontend/src/consts/navItems.tsx +++ b/govtool/frontend/src/consts/navItems.tsx @@ -4,7 +4,7 @@ import { theme } from "@/theme"; import { ICONS } from "./icons"; import { LINKS } from "./links"; -import { PATHS, PDF_PATHS } from "./paths"; +import { PATHS, PDF_PATHS, OUTCOMES_PATHS, USER_PATHS } from "./paths"; export const NAV_ITEMS = [ { @@ -59,6 +59,7 @@ export const CONNECTED_NAV_ITEMS = [ navTo: PATHS.dashboardDRepDirectory, activeIcon: ICONS.dRepDirectoryActiveIcon, icon: ICONS.dRepDirectoryIcon, + newTabLink: null, }, { dataTestId: "governance-actions-link", @@ -67,28 +68,54 @@ export const CONNECTED_NAV_ITEMS = [ activeIcon: ICONS.governanceActionsActiveIcon, icon: ICONS.governanceActionsIcon, newTabLink: null, - }, - { - dataTestId: "proposal-discussion-link", - label: i18n.t("proposalDiscussion.title"), - navTo: PDF_PATHS.proposalDiscussion, - activeIcon: ( - - ), - icon: ( - - ), - newTabLink: null, + childNavItems: [ + { + dataTestId: "proposal-discussion-link", + label: i18n.t("proposalDiscussion.title"), + navTo: PDF_PATHS.proposalDiscussion, + activeIcon: ( + + ), + icon: ( + + ), + newTabLink: null, + }, + { + dataTestId: "governance-actions-live-voting-link", + label: i18n.t("govActions.liveVoting.title"), + navTo: OUTCOMES_PATHS.governanceActionsLiveVoting, + activeIcon: ICONS.governanceActionsActiveIcon, + icon: ICONS.governanceActionsIcon, + newTabLink: null, + }, + { + dataTestId: "governance-actions-outcomes-link", + label: i18n.t("govActions.outcomes.title"), + navTo: OUTCOMES_PATHS.governanceActionsOutcomes, + activeIcon: ICONS.governanceActionsActiveIcon, + icon: ICONS.governanceActionsIcon, + newTabLink: null, + }, + { + dataTestId: "governance-actions-voted-by-me-link", + label: i18n.t("govActions.votedByMe.title"), + navTo: USER_PATHS.governanceActionsVotedByMe, + activeIcon: ICONS.governanceActionsActiveIcon, + icon: ICONS.governanceActionsIcon, + newTabLink: null, + }, + ], }, { dataTestId: "guides-link", diff --git a/govtool/frontend/src/consts/paths.ts b/govtool/frontend/src/consts/paths.ts index 296b61d7e..a392aeb12 100644 --- a/govtool/frontend/src/consts/paths.ts +++ b/govtool/frontend/src/consts/paths.ts @@ -31,3 +31,13 @@ export const PDF_PATHS = { proposalDiscussionProposal: "/proposal_discussion/:id", proposalDiscussionPropose: "/proposal_discussion/propose", }; + +export const USER_PATHS = { + governanceActionsVotedByMe: "/my/votes_and_favorites", +}; + +export const OUTCOMES_PATHS = { + governanceActionsOutcomes: "/outcomes", + governanceActionOutcomes: "/outcomes/governance_actions/:id", + governanceActionsLiveVoting: "/connected/governance_actions", +}; \ No newline at end of file diff --git a/govtool/frontend/src/context/featureFlag.tsx b/govtool/frontend/src/context/featureFlag.tsx index 23b1a9ecd..b45eacaa5 100644 --- a/govtool/frontend/src/context/featureFlag.tsx +++ b/govtool/frontend/src/context/featureFlag.tsx @@ -15,6 +15,7 @@ import { useAppContext } from "./appContext"; */ type FeatureFlagContextType = { isProposalDiscussionForumEnabled: boolean; + isGovernanceOutcomesPillarEnabled: boolean; isVotingOnGovernanceActionEnabled: ( governanceActionType: GovernanceActionType, ) => boolean; @@ -33,6 +34,7 @@ type FeatureFlagContextType = { const FeatureFlagContext = createContext({ isProposalDiscussionForumEnabled: false, + isGovernanceOutcomesPillarEnabled: false, isVotingOnGovernanceActionEnabled: () => false, areDRepVoteTotalsDisplayed: () => false, areSPOVoteTotalsDisplayed: () => false, @@ -129,6 +131,10 @@ const FeatureFlagProvider = ({ children }: PropsWithChildren) => { import.meta.env.VITE_IS_PROPOSAL_DISCUSSION_FORUM_ENABLED === "true" || import.meta.env.VITE_IS_PROPOSAL_DISCUSSION_FORUM_ENABLED === true || false, + isGovernanceOutcomesPillarEnabled: + import.meta.env.VITE_IS_GOVERNANCE_OUTCOMES_PILLAR_ENABLED === "true" || + import.meta.env.VITE_IS_GOVERNANCE_OUTCOMES_PILLAR_ENABLED === true || + false, isVotingOnGovernanceActionEnabled, areDRepVoteTotalsDisplayed, areSPOVoteTotalsDisplayed, diff --git a/govtool/frontend/src/i18n/locales/en.json b/govtool/frontend/src/i18n/locales/en.json index d3faf4074..75b45a80d 100644 --- a/govtool/frontend/src/i18n/locales/en.json +++ b/govtool/frontend/src/i18n/locales/en.json @@ -455,6 +455,18 @@ "title": "Info Action", "label": "Info Action" } + }, + "liveVoting": { + "title": "Live Voting", + "label": "Live Voting" + }, + "outcomes": { + "title": "Outcomes", + "label": "Outcomes" + }, + "votedByMe": { + "title": "Voted by me", + "label": "Voted by me" } }, "hero": { diff --git a/govtool/frontend/src/pages/Dashboard.tsx b/govtool/frontend/src/pages/Dashboard.tsx index 18f7a504b..77d9181d7 100644 --- a/govtool/frontend/src/pages/Dashboard.tsx +++ b/govtool/frontend/src/pages/Dashboard.tsx @@ -19,12 +19,18 @@ export const Dashboard = () => { const getPageTitle = (path: string) => { if (path === PATHS.dashboard) return t("dashboard.title"); - return ( - Object.values(CONNECTED_NAV_ITEMS).find(({ navTo }) => - pathname.startsWith(navTo), - )?.label ?? "" - ); + return findNavItem(CONNECTED_NAV_ITEMS, path) ?? ""; }; + + const findNavItem = (items: NavItem[], targetPath: string): string | null => ( + items.reduce((result, item) => ( + result ?? ( + targetPath === item.navTo + ? item.label + : (item.childNavItems ? findNavItem(item.childNavItems, targetPath) : null) + ) + ), null) + ); useEffect(() => { if (divRef.current && pathname !== PATHS.dashboardGovernanceActions) { diff --git a/govtool/frontend/src/pages/GovernanceActionOutComes.tsx b/govtool/frontend/src/pages/GovernanceActionOutComes.tsx new file mode 100644 index 000000000..62b389343 --- /dev/null +++ b/govtool/frontend/src/pages/GovernanceActionOutComes.tsx @@ -0,0 +1,49 @@ +import { Footer, TopNav } from "@/components/organisms"; +import { useCardano } from "@/context"; +import { useScreenDimension } from "@/hooks"; +import Outcomes from "@intersect.mbo/govtool-outcomes-pillar-ui"; +import { Box, CircularProgress } from "@mui/material"; +import { Suspense } from "react"; + +export const GovernanceActionOutComesPillar = () => { + const { pagePadding } = useScreenDimension(); + const { ...context } = useCardano(); + return ( + + {!context.isEnabled && } + + + + + } + > + + + + {!context.isEnabled &&