diff --git a/src/modules/etherlink/components/EvmDaoSettingsModal.tsx b/src/modules/etherlink/components/EvmDaoSettingsModal.tsx
new file mode 100644
index 00000000..0f9e6d70
--- /dev/null
+++ b/src/modules/etherlink/components/EvmDaoSettingsModal.tsx
@@ -0,0 +1,138 @@
+import React, { useContext } from "react"
+import {
+ Grid,
+ styled,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ Typography,
+ useMediaQuery,
+ useTheme
+} from "@material-ui/core"
+import { ResponsiveDialog } from "modules/explorer/components/ResponsiveDialog"
+
+import { EtherlinkContext } from "services/wagmi/context"
+import { CopyButton } from "modules/common/CopyButton"
+import { CopyAddress } from "modules/common/CopyAddress"
+
+const CustomTableContainer = styled(TableContainer)(({ theme }) => ({
+ width: "inherit",
+ [theme.breakpoints.down("sm")]: {}
+}))
+
+const CustomTableCell = styled(TableCell)(({ theme }) => ({
+ [theme.breakpoints.down("sm")]: {
+ paddingBottom: 0,
+ paddingLeft: "16px !important",
+ textAlign: "end"
+ }
+}))
+
+const CustomTableCellValue = styled(TableCell)(({ theme }) => ({
+ [theme.breakpoints.down("sm")]: {
+ paddingTop: 0,
+ paddingRight: "16px !important",
+ textAlign: "end",
+ paddingBottom: 0
+ }
+}))
+
+const RowValue = styled(Typography)(({ theme }) => ({
+ fontWeight: 300,
+ fontSize: 18,
+ [theme.breakpoints.down("sm")]: {
+ fontSize: 16
+ }
+}))
+
+export const EvmDaoSettingModal: React.FC<{
+ open: boolean
+ handleClose: () => void
+}> = ({ open, handleClose }) => {
+ const { daoSelected } = useContext(EtherlinkContext)
+ const theme = useTheme()
+ const isMobileSmall = useMediaQuery(theme.breakpoints.down("sm"))
+
+ const tableData = [
+ {
+ key: "DAO Contract Address",
+ value: daoSelected?.address
+ },
+ {
+ key: "Treasury Address",
+ value: daoSelected?.treasuryAddress
+ },
+ {
+ key: "Registry Address",
+ value: daoSelected?.registryAddress
+ },
+ {
+ key: "Governance Token",
+ value: daoSelected?.token
+ },
+ {
+ key: "Quorum",
+ value: daoSelected?.quorum
+ },
+ {
+ key: "Proposal Threshold",
+ value: daoSelected?.proposalThreshold
+ },
+ {
+ key: "Voting Duration (minutes",
+ value: daoSelected?.votingDuration
+ },
+ {
+ key: "Voting Delay (minutes)",
+ value: daoSelected?.votingDelay
+ },
+ {
+ key: "Execution Delay (minutes)",
+ value: daoSelected?.executionDelay
+ }
+ ]
+
+ return (
+ <>
+
+
+
+
+ {daoSelected?.id &&
+ tableData.map((item: { key: string; value: string }) => (
+
+
+
+ {item.key}
+
+
+
+ {typeof item.value === "string" && item?.value?.startsWith("0x") ? (
+
+ {isMobileSmall ? (
+
+ ) : (
+ <>
+
+ {item.value}
+
+
+ >
+ )}
+
+ ) : (
+ {item.value}
+ )}
+
+
+ ))}
+
+
+
+
+ >
+ )
+}
diff --git a/src/modules/etherlink/components/EvmDaoStatsRow.tsx b/src/modules/etherlink/components/EvmDaoStatsRow.tsx
new file mode 100644
index 00000000..2b37dbef
--- /dev/null
+++ b/src/modules/etherlink/components/EvmDaoStatsRow.tsx
@@ -0,0 +1,72 @@
+import React, { useContext, useMemo } from "react"
+import { Box, Grid, styled, useTheme, Typography, Paper } from "@material-ui/core"
+
+import { EtherlinkContext } from "services/wagmi/context"
+
+const Item = styled(Paper)(({ theme }) => ({
+ backgroundColor: "#24282d",
+ borderRadius: 8,
+ color: theme.palette.text.primary,
+ height: 84,
+ display: "flex",
+ padding: "33px 40px 30px 40px",
+ flexDirection: "column",
+ gap: 8
+}))
+
+const ItemContent = styled(Grid)({
+ gap: 8
+})
+
+const ItemTitle = styled(Typography)(({ theme }) => ({
+ fontSize: 18,
+ fontWeight: 500,
+ [theme.breakpoints.down("md")]: {
+ fontSize: 15
+ }
+}))
+
+const ItemValue = styled(Typography)(({ theme }) => ({
+ fontSize: 32,
+ fontWeight: 300,
+ overflowX: "scroll",
+ cursor: "default",
+ [theme.breakpoints.down("sm")]: {
+ fontSize: 28
+ }
+}))
+
+export const EvmDaoStatsRow = () => {
+ const { daoSelected } = useContext(EtherlinkContext)
+ return (
+
+
+ {[
+ {
+ title: "Members",
+ value: daoSelected?.holders
+ },
+ {
+ title: "Active Proposals",
+ value: daoSelected?.proposals?.length || "0"
+ },
+ {
+ title: "Awaiting Executions",
+ value: daoSelected?.awaiting_executions || "-"
+ }
+ ].map((item, index) => (
+
+ -
+
+ {item.title}
+
+
+ {item.value}
+
+
+
+ ))}
+
+
+ )
+}
diff --git a/src/modules/etherlink/components/EvmProposalDetailCard.tsx b/src/modules/etherlink/components/EvmProposalDetailCard.tsx
new file mode 100644
index 00000000..267ac5d6
--- /dev/null
+++ b/src/modules/etherlink/components/EvmProposalDetailCard.tsx
@@ -0,0 +1,218 @@
+import React from "react"
+import { Grid, styled, Typography, Link, useTheme, useMediaQuery, Popover, withStyles } from "@material-ui/core"
+import { GridContainer } from "modules/common/GridContainer"
+import { ProposalStatus, TableStatusBadge } from "modules/lite/explorer/components/ProposalTableRowStatusBadge"
+import { CreatorBadge } from "modules/lite/explorer/components/CreatorBadge"
+import { FileCopyOutlined } from "@material-ui/icons"
+import Share from "assets/img/share.svg"
+import { CommunityBadge } from "modules/lite/explorer/components/CommunityBadge"
+import LinkIcon from "assets/img/link.svg"
+import { Poll } from "models/Polls"
+import dayjs from "dayjs"
+import { useNotification } from "modules/common/hooks/useNotification"
+import ReactHtmlParser from "react-html-parser"
+
+const LogoItem = styled("img")(({ theme }) => ({
+ cursor: "pointer",
+ [theme.breakpoints.down("sm")]: {
+ height: 10
+ }
+}))
+
+const TextContainer = styled(Typography)(({ theme }) => ({
+ display: "flex",
+ alignItems: "center",
+ gap: 10,
+ marginRight: 8,
+ [theme.breakpoints.down("sm")]: {
+ marginTop: 20
+ }
+}))
+
+const EndTextContainer = styled(Typography)(({ theme }) => ({
+ display: "flex",
+ alignItems: "center",
+ gap: 10,
+ marginRight: 8,
+ [theme.breakpoints.down("sm")]: {
+ marginTop: 20
+ }
+}))
+
+const EndText = styled(Typography)(({ theme }) => ({
+ [theme.breakpoints.down("sm")]: {
+ marginTop: 20
+ }
+}))
+
+const Divider = styled(Typography)(({ theme }) => ({
+ marginLeft: 8,
+ marginRight: 8,
+ [theme.breakpoints.down("sm")]: {
+ marginTop: 20
+ }
+}))
+
+const StyledLink = styled(Link)(({ theme }) => ({
+ fontFamily: "Roboto Flex",
+ fontWeight: 300,
+ fontSize: 16,
+ marginLeft: 8,
+ [theme.breakpoints.down("sm")]: {
+ fontWeight: 100,
+ fontSize: 10
+ }
+}))
+
+const CopyIcon = styled(FileCopyOutlined)({
+ marginRight: 8,
+ cursor: "pointer"
+})
+
+const CustomPopover = withStyles({
+ paper: {
+ "marginTop": 10,
+ "padding": 8,
+ "cursor": "pointer",
+ "background": "#1c1f23 !important",
+ "&:hover": {
+ background: "#81feb76b !important"
+ }
+ }
+})(Popover)
+
+export const EvmProposalDetailCard: React.FC<{ poll: Poll | undefined }> = ({ poll }) => {
+ const theme = useTheme()
+ const isMobileSmall = useMediaQuery(theme.breakpoints.down("sm"))
+ const [anchorEl, setAnchorEl] = React.useState(null)
+ const openNotification = useNotification()
+
+ const handleClick = (event: React.MouseEvent) => {
+ setAnchorEl(anchorEl ? null : event.currentTarget)
+ }
+
+ const handleClose = () => {
+ setAnchorEl(null)
+ }
+
+ const open = Boolean(anchorEl)
+ const id = open ? "simple-popper" : undefined
+
+ const handleCopy = () => {
+ const url = location.href
+ navigator.clipboard.writeText(url)
+ openNotification({
+ message: "Proposal link copied to clipboard!",
+ autoHideDuration: 3000,
+ variant: "success"
+ })
+ handleClose()
+ }
+
+ return (
+ <>
+
+
+
+
+
+ {poll?.name}
+
+
+
+
+
+
+
+
+ Share
+
+
+
+
+
+ Copy link
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* */}
+
+
+
+
+
+
+
+
+
+ Start date:{" "}
+
+
+ {dayjs(Number(poll?.startTime)).format("lll")}
+
+ -
+
+ End date:{" "}
+
+
+ {dayjs(Number(poll?.endTime)).format("lll")}
+
+
+
+
+
+
+ {ReactHtmlParser(poll?.description ? poll?.description : "")}
+
+
+
+ {poll?.externalLink ? (
+
+
+
+ {poll?.externalLink}
+
+
+ ) : null}
+
+
+ >
+ )
+}
diff --git a/src/modules/etherlink/components/EvmProposalItem.tsx b/src/modules/etherlink/components/EvmProposalItem.tsx
index c8948fca..680dd0ed 100644
--- a/src/modules/etherlink/components/EvmProposalItem.tsx
+++ b/src/modules/etherlink/components/EvmProposalItem.tsx
@@ -1,8 +1,8 @@
-import { Box, Grid, Theme, Typography, styled, useMediaQuery, useTheme } from "@material-ui/core"
+import { Grid, Theme, Typography, styled } from "@material-ui/core"
import dayjs from "dayjs"
import React from "react"
import { toShortAddress } from "services/contracts/utils"
-import { Proposal, ProposalStatus } from "services/services/dao/mappers/proposal/types"
+import { Proposal } from "services/services/dao/mappers/proposal/types"
import { StatusBadge } from "modules/explorer/components/StatusBadge"
const ContentBlockItem = styled(Grid)(({ theme }: { theme: Theme }) => ({
@@ -20,30 +20,6 @@ const CreatedText = styled(Typography)({
color: "#bfc5ca"
})
-const getStatusByHistory = (history: { active: number; executable: number; passed: number; pending: number }) => {
- const statuses = Object.keys(history)
- const status = statuses.reduce((maxStatus, currentStatus) => {
- return history[currentStatus as keyof typeof history] > history[maxStatus as keyof typeof history]
- ? currentStatus
- : maxStatus
- })
- // TODO: @ashutoshpw, handle more statuses
- switch (status) {
- case "active":
- return ProposalStatus.ACTIVE
- case "pending":
- return ProposalStatus.PENDING
- case "rejected":
- return ProposalStatus.REJECTED
- case "accepted":
- return ProposalStatus.ACTIVE
- case "executed":
- return ProposalStatus.EXECUTED
- default:
- return ProposalStatus.NO_QUORUM
- }
-}
-
export const EvmProposalItem: React.FC<{
proposal: Proposal | any
}> = ({ proposal, children }) => {
@@ -61,7 +37,7 @@ export const EvmProposalItem: React.FC<{
-
+
diff --git a/src/modules/etherlink/components/EvmProposalVoteDetail.tsx b/src/modules/etherlink/components/EvmProposalVoteDetail.tsx
new file mode 100644
index 00000000..df2ead34
--- /dev/null
+++ b/src/modules/etherlink/components/EvmProposalVoteDetail.tsx
@@ -0,0 +1,235 @@
+/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */
+/* eslint-disable @typescript-eslint/no-non-null-assertion */
+import React, { useContext, useEffect, useMemo, useState } from "react"
+import { Button, Grid, LinearProgress, styled, Typography, useMediaQuery, useTheme } from "@material-ui/core"
+import { GridContainer } from "modules/common/GridContainer"
+import { VotesDialog } from "modules/lite/explorer/components/VotesDialog"
+import { Poll } from "models/Polls"
+import { Choice } from "models/Choice"
+
+import { useTezos } from "services/beacon/hooks/useTezos"
+import { getTurnoutValue } from "services/utils/utils"
+import { useTokenDelegationSupported } from "services/contracts/token/hooks/useTokenDelegationSupported"
+import { DownloadCsvFile } from "modules/lite/explorer/components/DownloadCsvFile"
+import { EtherlinkContext } from "services/wagmi/context"
+
+const Container = styled(Grid)(({ theme }) => ({
+ background: theme.palette.primary.main,
+ borderRadius: 8
+}))
+
+const TitleContainer = styled(Grid)(({ theme }) => ({
+ paddingTop: 18,
+ paddingLeft: 46,
+ paddingRight: 46,
+ paddingBottom: 18,
+ borderBottom: `0.3px solid ${theme.palette.primary.light}`,
+ [theme.breakpoints.down("sm")]: {
+ padding: "18px 25px"
+ }
+}))
+
+const LinearContainer = styled(GridContainer)({
+ paddingBottom: 0,
+ minHeight: 110
+})
+
+const LegendContainer = styled(GridContainer)({
+ minHeight: 30,
+ paddingBottom: 0
+})
+
+const GraphicsContainer = styled(Grid)({
+ paddingBottom: 25
+})
+
+export const EvmProposalVoteDetail: React.FC<{
+ poll: Poll | undefined
+ choices: Choice[]
+ token: any
+ isXTZ: boolean
+}> = ({ poll, choices, token, isXTZ }) => {
+ const theme = useTheme()
+ const isMobileSmall = useMediaQuery(theme.breakpoints.down("xs"))
+ const isMobile = useMediaQuery(theme.breakpoints.down("sm"))
+ const [open, setOpen] = React.useState(false)
+ const { network } = useTezos()
+ const [turnout, setTurnout] = useState()
+ const [votes, setVotes] = useState([])
+ const { daoSelected, daoProposalSelected } = useContext(EtherlinkContext)
+ const tokenData = useMemo(
+ () => ({
+ tokenAddress: daoSelected?.token,
+ tokenID: daoSelected?.id,
+ symbol: daoSelected?.symbol,
+ decimals: daoSelected?.decimals
+ }),
+ [daoSelected]
+ )
+ const { data: isTokenDelegationSupported } = useTokenDelegationSupported(tokenData?.tokenAddress)
+ const totalVoteCount = daoProposalSelected?.votesFor + daoProposalSelected?.votesAgainst
+
+ const handleClickOpen = () => {
+ setVotes(choices.filter(elem => elem.walletAddresses.length > 0))
+ setOpen(true)
+ }
+
+ const handleClose = () => {
+ setOpen(false)
+ }
+
+ const formatConfig = {
+ average: true,
+ mantissa: 1,
+ thousandSeparated: true,
+ trimMantissa: true
+ }
+
+ useMemo(async () => {
+ if (token && tokenData) {
+ const value = await getTurnoutValue(
+ network,
+ tokenData?.tokenAddress,
+ tokenData.tokenID,
+ Number(poll?.referenceBlock),
+ totalVoteCount
+ )
+ if (value) {
+ setTurnout(value)
+ }
+ }
+ }, [poll, network, token, tokenData, totalVoteCount])
+
+ return (
+
+ {/* Disabled as Data is wrong in Firebase */}
+ {/*
+
+ Voter Turnout
+
+
+
+
+
+
+
+
+ */}
+
+
+ Vorting Results
+
+
+
+ {choices &&
+ choices.map((choice: Choice, index) => {
+ const isFor = choice.name === "For"
+ const voteCount = isFor ? daoProposalSelected?.votesFor : daoProposalSelected?.votesAgainst
+
+ const linearProgressValue = totalVoteCount > 0 ? (voteCount / totalVoteCount) * 100 : 0
+ return (
+
+
+
+
+ {choice.name}
+
+
+
+
+ {voteCount} Voters - {tokenData?.symbol}
+
+
+
+
+
+
+
+
+
+ {linearProgressValue}%
+
+
+
+
+ )
+ })}
+
+
+
+ handleClickOpen()}>
+ {totalVoteCount}
+
+ handleClickOpen()}>
+ Votes
+
+ {isTokenDelegationSupported && turnout && !poll?.isXTZ ? (
+
+ ({turnout.toFixed(2)} % Turnout)
+
+ ) : null}
+
+
+
+ {/*
+ {numbro(calculateProposalTotal(choices, isXTZ ? 6 : tokenData?.decimals)).format(formatConfig)}
+
+
+ {isXTZ ? "XTZ" : poll?.tokenSymbol}
+ */}
+
+ {/* {!poll?.isXTZ && (
+
+ (
+ {getTreasuryPercentage(
+ calculateProposalTotal(choices, isXTZ ? 6 : tokenData?.decimals),
+ poll?.totalSupplyAtReferenceBlock,
+ isXTZ ? 6 : tokenData?.decimals
+ )
+ .dp(5, 1)
+ .toString()}
+ % of Total Supply)
+
+ )} */}
+ {totalVoteCount > 0 ? (
+
+ ) : null}
+
+
+
+
+
+ )
+}
diff --git a/src/modules/etherlink/components/VotingPowerWidget.tsx b/src/modules/etherlink/components/VotingPowerWidget.tsx
new file mode 100644
index 00000000..9e9b6a93
--- /dev/null
+++ b/src/modules/etherlink/components/VotingPowerWidget.tsx
@@ -0,0 +1,154 @@
+import React, { useState, useEffect } from "react"
+import { Box, Select, MenuItem, Typography, Slider, Paper, styled, SelectChangeEvent, Grid } from "@mui/material"
+import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"
+
+export interface Org {
+ symbol: string
+}
+
+export interface Member {
+ name: string
+ votingWeight: number
+}
+
+// TODO: @ashutoshpw Replace with actual data
+export const generateMembers = (): Member[] => {
+ return Array.from({ length: 100 }, (_, index) => ({
+ name: `Member ${index + 1}`,
+ votingWeight: Math.random() * 100 + 1
+ }))
+}
+
+const StyledPaper = styled(Paper)(({ theme }) => ({
+ minWidth: 520,
+ height: 30,
+ backgroundColor: theme.palette.grey[200],
+ display: "flex",
+ alignItems: "center",
+ justifyContent: "center"
+}))
+
+const StyledSelect = styled(Select)(({ theme }) => ({
+ "& .MuiSelect-select": {
+ paddingRight: theme.spacing(4),
+ fontWeight: 600,
+ backgroundColor: "transparent"
+ },
+ "&:before, &:after": {
+ display: "none"
+ }
+}))
+
+export const VotingPowerStats: React.FC<{
+ membersCount: number
+ membersPercentage: number
+ votingPower: number
+ votingPowerPercentage: number
+}> = ({ membersCount, membersPercentage, votingPower, votingPowerPercentage }) => {
+ return (
+
+
+
+ Number of Members
+
+
+ {membersCount}
+
+
+ {membersPercentage.toFixed(2)}%
+
+
+
+
+ Voting Power
+
+
+ {votingPower.toFixed(2)}
+
+
+ {votingPowerPercentage.toFixed(2)}%
+
+
+
+ )
+}
+
+export const VotingPowerWidget: React.FC<{ tokenSymbol: string }> = ({ tokenSymbol }) => {
+ const [sliderValue, setSliderValue] = useState(1)
+ const [members, setMembers] = useState([])
+ const [selectedFeature, setSelectedFeature] = useState("vote concentration")
+ const concentrationOptions = ["vote concentration", `${tokenSymbol} ownership`]
+
+ useEffect(() => {
+ const initialMembers = generateMembers()
+ initialMembers.sort((a, b) => b.votingWeight - a.votingWeight)
+ setMembers(initialMembers)
+ }, [])
+
+ const totalMembers = members.length
+ const totalVotingPower = members.reduce((sum, member) => sum + member.votingWeight, 0)
+ const percentageOfMembers = 101 - sliderValue
+ const membersToInclude = Math.max(1, Math.round((percentageOfMembers / 100) * totalMembers))
+ const selectedMembers = members.slice(0, membersToInclude)
+ const cumulativeVotingPower = selectedMembers.reduce((sum, member) => sum + member.votingWeight, 0)
+
+ const membersPercentage = (membersToInclude / totalMembers) * 100
+ const votingPowerPercentage = (cumulativeVotingPower / totalVotingPower) * 100
+
+ return (
+
+
+
+ Drag slider to check
+
+
+ {
+ setSelectedFeature(event.target.value)
+ }}
+ IconComponent={KeyboardArrowDownIcon}
+ variant="standard"
+ >
+ {concentrationOptions.map(option => (
+
+ ))}
+
+
+
+
+
+
+
+
+ setSliderValue(value as number)}
+ min={1}
+ max={100}
+ sx={{ width: 430 }}
+ />
+
+
+
+ )
+}
diff --git a/src/modules/etherlink/explorer/EtherlinkDAO/EvmMembersPage.tsx b/src/modules/etherlink/explorer/EtherlinkDAO/EvmMembersPage.tsx
index deb8e0f9..3699a972 100644
--- a/src/modules/etherlink/explorer/EtherlinkDAO/EvmMembersPage.tsx
+++ b/src/modules/etherlink/explorer/EtherlinkDAO/EvmMembersPage.tsx
@@ -3,6 +3,7 @@ import { TitleText } from "components/ui/TitleText"
import { EvmMembersTable } from "modules/etherlink/components/EvmMembersTable"
import { EtherlinkContext } from "services/wagmi/context"
import { useContext } from "react"
+import { VotingPowerWidget } from "modules/etherlink/components/VotingPowerWidget"
export const EvmMembersPage = () => {
const { daoMembers } = useContext(EtherlinkContext)
@@ -16,10 +17,14 @@ export const EvmMembersPage = () => {
console.log("daoMemberData", daoMemberData, daoMembers)
return (
-
+
Members
+
+
+
+
diff --git a/src/modules/etherlink/explorer/EtherlinkDAO/EvmProposalDetailsPage.tsx b/src/modules/etherlink/explorer/EtherlinkDAO/EvmProposalDetailsPage.tsx
index a6732bd8..465bcb95 100644
--- a/src/modules/etherlink/explorer/EtherlinkDAO/EvmProposalDetailsPage.tsx
+++ b/src/modules/etherlink/explorer/EtherlinkDAO/EvmProposalDetailsPage.tsx
@@ -1,3 +1,107 @@
+import { ArrowBackIosOutlined } from "@mui/icons-material"
+import { GridContainer } from "modules/common/GridContainer"
+import { Button, Grid, Typography, useMediaQuery, useTheme } from "@mui/material"
+import { PageContainer } from "components/ui/DaoCreator"
+import { ProposalDetailCard } from "modules/lite/explorer/components/ProposalDetailCard"
+import { useContext, useEffect } from "react"
+import { useParams } from "react-router-dom"
+import { EtherlinkContext } from "services/wagmi/context"
+import { ProposalStatus } from "services/services/dao/mappers/proposal/types"
+import { EvmProposalDetailCard } from "modules/etherlink/components/EvmProposalDetailCard"
+import { ChoiceItemSelected } from "modules/lite/explorer/components/ChoiceItemSelected"
+import { EvmProposalVoteDetail } from "modules/etherlink/components/EvmProposalVoteDetail"
export const EvmProposalDetailsPage = () => {
- return Proposal Details
+ const params = useParams() as { proposalId: string }
+ const proposalId = params?.proposalId
+
+ const { daoSelected, daoProposalSelected, selectDaoProposal } = useContext(EtherlinkContext)
+ const theme = useTheme()
+ const isMobileSmall = useMediaQuery(theme.breakpoints.down("sm"))
+
+ useEffect(() => {
+ selectDaoProposal(proposalId)
+ }, [proposalId, selectDaoProposal])
+
+ const choices = [
+ {
+ name: "For",
+ pollID: "1",
+ walletAddresses: [],
+ selected: true
+ },
+ {
+ name: "Against",
+ pollID: "1",
+ walletAddresses: [],
+ selected: false
+ }
+ ]
+ console.log("daoProposalSelected", daoProposalSelected)
+
+ return (
+
+
Proposal Details
+
+
+
+
+
+
+ {choices && choices.length > 0 ? (
+
+
+ {/* {[choices].map((choice, index) => {
+ return (
+ {}}
+ />
+ )
+ })} */}
+
+ {/* {poll?.isActive === ProposalStatus.ACTIVE ? (
+
+ ) : null} */}
+
+ ) : null}
+
+
+
+ {/* {poll && poll !== undefined ? (
+
+ ) : null} */}
+
+
+
+
+ )
}
diff --git a/src/modules/etherlink/explorer/EtherlinkDAO/EvmRegistryPage.tsx b/src/modules/etherlink/explorer/EtherlinkDAO/EvmRegistryPage.tsx
index 88f75fa7..e2b88585 100644
--- a/src/modules/etherlink/explorer/EtherlinkDAO/EvmRegistryPage.tsx
+++ b/src/modules/etherlink/explorer/EtherlinkDAO/EvmRegistryPage.tsx
@@ -89,7 +89,7 @@ export const EvmRegistryPage: React.FC = () => {
Registry
{dao && (
{
const daoId = useEtherlinkDAOID()
const { data, cycleInfo, ledger } = useDAO(daoId)
+ const { daoSelected } = useContext(EtherlinkContext)
- console.log("explorer/index.tsx", data)
const theme = useTheme()
const isExtraSmall = useMediaQuery(theme.breakpoints.down("xs"))
- const symbol = (data && data.data.token?.symbol?.toUpperCase()) || "Unknown"
+ const symbol = (daoSelected && daoSelected?.token?.toUpperCase()) || "Unknown"
- const name = data && data.data.name
- const description = data && data.data.description
+ const name = daoSelected && daoSelected?.name
+ const description = daoSelected && daoSelected?.description
const [openDialog, setOpenDialog] = useState(false)
const [openChangeDialog, setChangeOpenDialog] = useState(false)
@@ -45,28 +40,6 @@ export const EtherlinkDAOOverview: React.FC = () => {
setChangeOpenDialog(false)
}
- const usersTableData = useMemo(() => {
- if (data?.data?.meta?.users) {
- return data.data.meta.users
- }
-
- if (!ledger || !cycleInfo || !data) {
- return []
- }
-
- return ledger
- .sort((a, b) => b.available_balance.minus(a.available_balance).toNumber())
- .map(p => ({
- address: p.holder.address,
- totalStaked: new BigNumber(p.total_balance).dp(10, 1).toString(),
- availableStaked: new BigNumber(p.available_balance).dp(10, 1).toString(),
- votes: p.holder.votes_cast.toString(),
- proposalsVoted: p.holder.proposals_voted.toString()
- }))
- }, [cycleInfo, data, ledger])
-
- console.log({ usersTableData })
-
return (
@@ -83,7 +56,7 @@ export const EtherlinkDAOOverview: React.FC = () => {
View Settings
- {/* */}
+
setChangeOpenDialog(true)}>
@@ -94,86 +67,70 @@ export const EtherlinkDAOOverview: React.FC = () => {
- {data?.data.network?.startsWith("etherlink") ? (
- <>
-
-
-
- DAO Contract
-
-
- {data?.data.address || "-"}
- {
- if (data?.data.address) {
- navigator.clipboard.writeText(data.data.address)
- }
- }}
- size="small"
- style={{ marginLeft: "8px", color: theme.palette.primary.light }}
- >
-
-
-
-
-
-
- Governance Token
-
-
- {data?.data.token.symbol || "-"}
- {
- if (data?.data.token.symbol) {
- navigator.clipboard.writeText(data.data.token.symbol)
- }
- }}
- size="small"
- style={{ marginLeft: "8px" }}
- >
-
-
-
-
-
- {description}
-
-
-
- >
- ) : (
- {description}
- )}
+
+
+
+ DAO Contract
+
+
+ {daoSelected?.address || "-"}
+ {
+ if (daoSelected?.address) {
+ navigator.clipboard.writeText(daoSelected.address)
+ }
+ }}
+ size="small"
+ style={{ marginLeft: "8px", color: theme.palette.primary.light }}
+ >
+
+
+
+
+
+
+ Governance Token
+
+
+ {daoSelected?.token || "-"}
+ {
+ if (daoSelected?.token) {
+ navigator.clipboard.writeText(daoSelected.token)
+ }
+ }}
+ size="small"
+ style={{ marginLeft: "8px" }}
+ >
+
+
+
+
+
+ {description}
+
+
+
-
-
-
- {/* */}
-
+
)
}
diff --git a/src/modules/explorer/pages/Proposals/index.tsx b/src/modules/explorer/pages/Proposals/index.tsx
index 1e75e58b..2252196f 100644
--- a/src/modules/explorer/pages/Proposals/index.tsx
+++ b/src/modules/explorer/pages/Proposals/index.tsx
@@ -348,7 +348,7 @@ export const EtherlinkProposals = () => {
const theme = useTheme()
// const isMobileSmall = useMediaQuery(theme.breakpoints.down("xs"))
const [openDialog, setOpenDialog] = useState(false)
-
+ console.log({ daoProposals })
const handleCloseModal = () => {
setOpenDialog(false)
}
diff --git a/src/services/wagmi/context.tsx b/src/services/wagmi/context.tsx
index a891b41f..78d3568d 100644
--- a/src/services/wagmi/context.tsx
+++ b/src/services/wagmi/context.tsx
@@ -6,6 +6,8 @@ import { etherlink, etherlinkTestnet } from "wagmi/chains"
import { useSIWE, useModal, SIWESession } from "connectkit"
import { useEthersProvider, useEthersSigner } from "./ethers"
import useFirestoreStore from "services/contracts/etherlinkDAO/hooks/useFirestoreStore"
+import { useParams } from "react-router-dom"
+import { Proposal, ProposalStatus } from "services/services/dao/mappers/proposal/types"
interface EtherlinkType {
isConnected: boolean
@@ -19,6 +21,31 @@ interface EtherlinkType {
disconnect: () => void
}
+// TODO: @ashutoshpw, handle more statuus and move to utils
+const getStatusByHistory = (history: { active: number; executable: number; passed: number; pending: number }) => {
+ const statuses = Object.keys(history)
+ const status = statuses.reduce((maxStatus, currentStatus) => {
+ return history[currentStatus as keyof typeof history] > history[maxStatus as keyof typeof history]
+ ? currentStatus
+ : maxStatus
+ })
+ // TODO: @ashutoshpw, handle more statuses
+ switch (status) {
+ case "active":
+ return ProposalStatus.ACTIVE
+ case "pending":
+ return ProposalStatus.PENDING
+ case "rejected":
+ return ProposalStatus.REJECTED
+ case "accepted":
+ return ProposalStatus.ACTIVE
+ case "executed":
+ return ProposalStatus.EXECUTED
+ default:
+ return ProposalStatus.NO_QUORUM
+ }
+}
+
export const EtherlinkContext = createContext(undefined)
export const EtherlinkProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
@@ -66,6 +93,7 @@ export const EtherlinkProvider: React.FC<{ children: ReactNode }> = ({ children
const [daoData, setDaoData] = useState([])
const [daoSelected, setDaoSelected] = useState({})
const [daoProposals, setDaoProposals] = useState([])
+ const [daoProposalSelectedId, setDaoProposalSelectedId] = useState(null)
const [daoProposalSelected, setDaoProposalSelected] = useState({})
const [daoMembers, setDaoMembers] = useState([])
const { data: firestoreData, loading, fetchCollection } = useFirestoreStore()
@@ -83,7 +111,16 @@ export const EtherlinkProvider: React.FC<{ children: ReactNode }> = ({ children
}
const daoProposalKey = `daosEtherlink-Testnet/${daoSelected.id}/proposals`
if (firestoreData?.[daoProposalKey]) {
- setDaoProposals(firestoreData[daoProposalKey]?.sort((a: any, b: any) => b.createdAt - a.createdAt))
+ setDaoProposals(
+ firestoreData[daoProposalKey]
+ ?.sort((a: any, b: any) => b.createdAt - a.createdAt)
+ .map(firebaseProposal => {
+ return {
+ ...firebaseProposal,
+ status: getStatusByHistory(firebaseProposal.statusHistory)
+ }
+ })
+ )
}
const daoMembersKey = `daosEtherlink-Testnet/${daoSelected.id}/members`
if (firestoreData?.[daoMembersKey]) {
@@ -120,6 +157,13 @@ export const EtherlinkProvider: React.FC<{ children: ReactNode }> = ({ children
daoProposals: daoProposals,
daoProposalSelected: daoProposalSelected,
daoMembers: daoMembers,
+ selectDaoProposal: (proposalId: string) => {
+ const proposal = daoProposals.find((proposal: any) => proposal.id === proposalId)
+ if (proposal) {
+ setDaoProposalSelected(proposal)
+ // fetchCollection(`daosEtherlink-Testnet/${daoSelected.id}/proposals/${proposalId}`)
+ }
+ },
selectDao: (daoId: string) => {
const dao = daoData.find(dao => dao.id === daoId)
// alert(`dao:${daoId}`)