revision v3 from the designers

Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
Uncle Fatso 2026-02-03 17:01:19 +03:00
parent 20f2e78ae7
commit 1fbaf94c24
Signed by: f4ts0
GPG Key ID: 565F4F2860226EBB
17 changed files with 141 additions and 46 deletions

View File

@ -1,7 +1,7 @@
{
"name": "ghost-dao-interface",
"private": true,
"version": "0.5.1",
"version": "0.5.2",
"type": "module",
"scripts": {
"dev": "vite",

View File

@ -20,7 +20,7 @@ const StyledMuiChip = styled(MuiChip, {
: template === "gray"
? theme.colors.gray[500]
: template === "darkGray"
? theme.colors.gray[600]
? theme.colors.primary[300]
: theme.colors.feedback[template]
: theme.palette.mode === "light"
? theme.colors.gray[90]
@ -34,7 +34,7 @@ const StyledMuiChip = styled(MuiChip, {
: template === "gray"
? theme.colors.gray[10]
: template === "darkGray"
? theme.colors.gray[90]
? theme.colors.gray[800]
: theme.colors.gray[600],
fontWeight: strong ? 700 : 450,
},

View File

@ -57,7 +57,17 @@ const Bonds = ({ chainId, address, connect }) => {
}}
>
<Box display="flex" alignItems="center" justifyContent="center" flexDirection="column">
<Paper headerText="Active bonds" fullWidth enableBackground>
<Paper
fullWidth
enableBackground
headerContent={
<Box display="flex" alignItems="center" flexDirection="row" gap="5px">
<Typography variant="h6">
Active bonds
</Typography>
</Box>
}
>
<MetricCollection>
<Metric
label={`Treasury Balance`}

View File

@ -83,7 +83,17 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => {
warmupLength={warmupInfo.expiry - epoch.number}
setPreClaimConfirmed={() => setPreClaimConfirmed(true)}
/>
<Paper headerText="Your Bonds" fullWidth enableBackground>
<Paper
fullWidth
enableBackground
headerContent={
<Box display="flex" alignItems="center" flexDirection="row" gap="5px">
<Typography variant="h6">
Your Bonds
</Typography>
</Box>
}
>
<Box display="flex" flexDirection="column" alignItems="center">
<Typography variant="h4" align="center" color="textSecondary">
Payout Options

View File

@ -291,7 +291,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
return (
<>
<PageTitle name="GHOST Bridge" subtitle="The only pure Web3 decentralized bridge." />
<PageTitle name="GHOST Bridge" subtitle={`Bridge $${ghstSymbol} via the only pure Web3 protocol`} />
<Container
style={{
paddingLeft: isSmallScreen || isVerySmallScreen ? "0" : "3.3rem",
@ -347,7 +347,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
onClick={() => setBridgeAction(!bridgeAction)}
/>)}
<Typography variant="h4">{
bridgeAction ? `Bridge $${ghstSymbol}` : "Transaction History"
bridgeAction ? `Bridge-In $${ghstSymbol}` : "Transaction History"
}</Typography>
</Box>
}

View File

@ -186,7 +186,7 @@ const Dex = ({ chainId, address, connect }) => {
<PageTitle
name={`${pathname.name.charAt(0).toUpperCase() + pathname.name.slice(1).toLowerCase()} V2 Classic`}
subtitle="Classic interface to V2 smart contracts."
subtitle="Classic interface to V2 smart contracts"
/>
<Container
style={{

View File

@ -159,7 +159,7 @@ const Faucet = ({ chainId, address, config, connect }) => {
<meta name="twitter:image" content="https://ghostchain.io/wp-content/uploads/2025/03/ghostFaucet-Featured_Image.png" />
</Helmet>
<PageTitle name={`${reserveSymbol} Faucet`} subtitle={`Swap Sepolia ${nativeInfo.symbol} for ${reserveSymbol}.`} />
<PageTitle name={`${reserveSymbol} Faucet`} subtitle={`Swap Sepolia ${nativeInfo.symbol} for ${reserveSymbol}`} />
<Container
style={{
paddingLeft: isSmallScreen || isVerySmallScreen ? "0" : "3.3rem",

View File

@ -30,7 +30,7 @@ const Governance = ({ connect, config, address, chainId }) => {
return (
<Box>
<PageTitle name="ghostDAO Governance" subtitle={`Vote for proposals and suggest new with $${ghstSymbol}`} />
<PageTitle name="Protocol Governance" subtitle={`Cast $${ghstSymbol} to facilitate DAO decisions`} />
<Container
style={{
paddingLeft: isSmallScreen || isVerySmallScreen ? "0" : "3.3rem",
@ -58,7 +58,7 @@ const Governance = ({ connect, config, address, chainId }) => {
<ProposalsCount chainId={chainId} />
</Grid>
<Grid item xs={isSmallScreen ? 12 : 4}>
<MinQuorumPercentage chainId={chainId} />
<MinQuorumPercentage chainId={chainId} ghstSymbol={ghstSymbol} />
</Grid>
<Grid item xs={isSmallScreen ? 12 : 4}>
<ProposalThreshold chainId={chainId} ghstSymbol={ghstSymbol} />

View File

@ -115,13 +115,13 @@ const ProposalDetails = ({ chainId, address }) => {
<ProposalDiscussion onClick={() => setSelectedDiscussionUrl("dicks")} />
}
>
<Box height="220px" display="flex" flexDirection="column" justifyContent="space-between" gap="20px">
<Box height="200px" display="flex" flexDirection="column" justifyContent="space-between" gap="20px">
<Box display="flex" flexDirection="column">
<Box display="flex" justifyContent="space-between">
<Typography variant="body2" color={theme.colors.feedback.success}>
<Typography sx={{ textShadow: "0 0 black", fontWeight: 600 }} variant="body2" color={theme.colors.feedback.success}>
For: {formatNumber(forVotes.toString(), 2)} ({formatNumber(forVotes * HUNDRED / proposalQuorum, 1)}%)
</Typography>
<Typography variant="body2" color={theme.colors.feedback.error}>
<Typography sx={{ textShadow: "0 0 black", fontWeight: 600 }} variant="body2" color={theme.colors.feedback.error}>
Against: {formatNumber(againstVotes.toString(), 2)} ({formatNumber(againstVotes * HUNDRED / proposalQuorum, 1)}%)
</Typography>
</Box>
@ -218,7 +218,7 @@ const VotingTimeline = ({ proposalId, chainId }) => {
<Timeline sx={{ margin: 0, padding: 0 }}>
<VotingTimelineItem time={voteStarted} message="Proposed on:" isFirst />
<VotingTimelineItem time={proposalSnapshot} message="Voting started:" />
<VotingTimelineItem time={proposalDeadline} message="Voting ends:" />
<VotingTimelineItem time={proposalDeadline} message="Voting ends:" isLast />
</Timeline>
)
}
@ -226,16 +226,33 @@ const VotingTimeline = ({ proposalId, chainId }) => {
const VotingTimelineItem = ({ isFirst, isLast, time, message }) => {
return (
<TimelineItem>
<TimelineOppositeContent sx={{ display: "none" }} />
<TimelineOppositeContent
sx={{
maxWidth: "120px",
textAlign: "left",
paddingLeft: "0",
display: "flex",
alignItems: "center",
}}
>
<Typography>{message}</Typography>
</TimelineOppositeContent>
<TimelineSeparator>
{!isFirst && <TimelineConnector sx={{ background: "#fff" }} />}
<TimelineDot sx={{ width: "15px", height: "15px", background: "#fff" }}></TimelineDot>
{!isLast && <TimelineConnector sx={{ background: "#fff" }} />}
<TimelineConnector sx={{ background: isFirst ? "transparent" : "#fff" }} />
<TimelineDot sx={{ width: "15px", height: "15px", background: "#fff", margin: "12px 0" }} />
<TimelineConnector sx={{ background: isLast ? "transparent" : "#fff" }} />
</TimelineSeparator>
<TimelineContent>
<Typography>{message}</Typography>
<Typography component="span">{new Date(time * 1000).toLocaleString()}</Typography>
<TimelineContent
sx={{
display: "flex",
alignItems: "center",
}}
>
<Typography>
{new Date(time * 1000).toLocaleString()}
</Typography>
</TimelineContent>
</TimelineItem>
)

View File

@ -9,10 +9,10 @@ const GovernanceInfoText = () => {
fontSize="0.875em"
lineHeight="15px"
>
ghostDAO's adaptive governance system algorithmically sets proposal threshold based on activity.
ghostDAOs adaptive governance system algorithmically sets minimum collateral based on activity.
&nbsp;<Link
color={theme.colors.primary[300]}
href="https://ghostchain.io/ghostdao_litepaper"
href="https://docs.dao.ghostchain.io/"
target="_blank"
rel="noopener noreferrer"
>Learn more here.</Link>

View File

@ -1,6 +1,9 @@
import Metric from "../../../components/Metric/Metric";
import { formatCurrency, formatNumber } from "../../../helpers";
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
import { getTokenDecimals } from "../../../hooks/helpers";
import { useTotalSupply } from "../../../hooks/tokens";
import {
useMinQuorum,
useProposalThreshold,
@ -8,15 +11,22 @@ import {
} from "../../../hooks/governance";
export const MinQuorumPercentage = props => {
const { percentage } = useMinQuorum(props.chainId);
const { numerator, denominator, percentage } = useMinQuorum(props.chainId);
const { totalSupply } = useTotalSupply(props.chainId, "GHST");
const decimals = getTokenDecimals(props.ghstSymbol);
const value = new DecimalBigNumber(
(totalSupply?._value ?? 0n) * numerator / denominator,
decimals
);
const _props = {
...props,
label: `Min Quorum`,
tooltip: `Minimum quorum needed for proposal to be succeeded.`,
tooltip: `Minimum $${props.ghstSymbol} turnout required for the proposal to become valid`,
};
if (percentage) _props.metric = `${formatNumber(percentage, 2)}%`;
if (percentage) _props.metric = `${formatCurrency(value?.toString(), 2, props.ghstSymbol)} (${formatNumber(percentage * 100, 2)}%)`;
else _props.isLoading = true;
return <Metric {..._props} />;
@ -28,7 +38,7 @@ export const ProposalThreshold = props => {
const _props = {
...props,
label: `$${props.ghstSymbol} Threshold`,
tooltip: `Minimum $${props.ghstSymbol} amount to be locked to create proposal.`,
tooltip: `Minimum $${props.ghstSymbol} required to be locked to create a proposal`,
};
if (threshold) _props.metric = `${formatCurrency(threshold.toString(), 0, props.ghstSymbol)}`;
@ -43,7 +53,7 @@ export const ProposalsCount = props => {
const _props = {
...props,
label: `Proposals Count`,
tooltip: `How much proposals already passed.`,
tooltip: `Total proposals created`,
};
if (proposalsCount) _props.metric = proposalsCount.toString();

View File

@ -7,7 +7,7 @@ const ProposalDiscussion = (linkProps) => {
<Link
{...linkProps}
underline="hover"
sx={{ fontFamily: "Ubuntu" }}
sx={{ fontFamily: "Ubuntu", fontSize: "14px", marginLeft: "9px" }}
display="flex"
flexDirection="row"
alignItems="center"

View File

@ -9,7 +9,7 @@ const ProposalInfoText = () => {
fontSize="0.875em"
lineHeight="15px"
>
Important: We display only the 10 most recent proposals. Only one proposal can be active at a time.
Important: Only the 10 most recent proposals are displayed. Only one proposal can be active at a time.
&nbsp;<Link
color={theme.colors.primary[300]}
href="https://ghostchain.io/ghostdao_litepaper"

View File

@ -16,7 +16,6 @@ import {
useTheme,
useMediaQuery
} from "@mui/material";
import { NavLink } from "react-router-dom";
import { getBlockNumber } from "@wagmi/core";
import { networkAvgBlockSpeed } from "../../../constants";
@ -44,6 +43,7 @@ const MAX_PROPOSALS_TO_SHOW = 10;
const ProposalsList = ({ chainId, config }) => {
const isSmallScreen = useScreenSize("md");
const navigate = useNavigate();
const theme = useTheme();
const [blockNumber, setBlockNumber] = useState(0n);
const [selectedDiscussionUrl, setSelectedDiscussionUrl] = useState(undefined);
@ -83,11 +83,17 @@ const ProposalsList = ({ chainId, config }) => {
isOpened={isDiscussionModalOpened}
closeModal={() => setSelectedDiscussionUrl(undefined)}
/>
<Paper headerText="Proposals" fullWidth enableBackground>
<Box my="24px" textAlign="center">
<ProposalInfoText />
<Paper
fullWidth
enableBackground
headerContent={
<Box display="flex" alignItems="center" flexDirection="row" gap="5px">
<Typography variant="h6">
Proposals
</Typography>
</Box>
}
>
<Box display="flex" flexDirection="column" gap="40px">
{filteredProposals?.map(proposal => (
<ProposalCard
@ -100,6 +106,10 @@ const ProposalsList = ({ chainId, config }) => {
/>
))}
</Box>
{proposalsFilter === "active" && <Box my="24px" textAlign="center">
<ProposalInfoText />
</Box>}
</Paper>
</>
);
@ -112,7 +122,35 @@ const ProposalsList = ({ chainId, config }) => {
isOpened={isDiscussionModalOpened}
closeModal={() => setSelectedDiscussionUrl(undefined)}
/>
<Paper headerText="Proposals" fullWidth enableBackground>
<Paper
fullWidth
enableBackground
headerContent={
<Box
width="100%"
display="flex"
alignItems="center"
justifyContent="space-between"
flexDirection="row"
gap="5px"
>
<Typography variant="h6">
Proposals
</Typography>
<Link
color={theme.colors.primary[300]}
href="https://ghostchain.io/ghostdao_litepaper"
target="_blank"
rel="noopener noreferrer"
>
<Typography variant="h7">
Discussion Forum
</Typography>
</Link>
</Box>
}
>
<ProposalFilterTrigger trigger={proposalsFilter} setTrigger={setProposalFilter} />
<ProposalTable>
@ -128,9 +166,9 @@ const ProposalsList = ({ chainId, config }) => {
))}
</ProposalTable>
<Box mt="24px" textAlign="center" width="70%" mx="auto">
{proposalsFilter === "active" && <Box mt="24px" textAlign="center" width="70%" mx="auto">
<ProposalInfoText />
</Box>
</Box>}
</Paper>
</>
);
@ -141,7 +179,7 @@ const ProposalTable = ({ children }) => (
<Table aria-label="Available bonds" style={{ tableLayout: "fixed" }}>
<TableHead>
<TableRow>
<TableCell style={{ width: "100px", padding: "8px 0" }}>Proposal ID</TableCell>
<TableCell align="center" style={{ width: "100px", padding: "8px 0" }}>Proposal ID</TableCell>
<TableCell align="center" style={{ width: "120px", padding: "8px 0" }}>Status</TableCell>
<TableCell align="center" style={{ padding: "8px 0" }}>Discussion</TableCell>
<TableCell align="center" style={{ padding: "8px 0" }}>Vote Ends</TableCell>
@ -160,7 +198,7 @@ const ProposalRow = ({ proposal, setActive, blockNumber, openProposal, chainId }
return (
<TableRow id={proposal.id + `--proposal`} data-testid={proposal.id + `--proposal`}>
<TableCell style={{ padding: "8px 0" }}>
<TableCell align="center" style={{ padding: "8px 0" }}>
<Typography>GDP-{proposal.id}</Typography>
</TableCell>

View File

@ -1,7 +1,7 @@
export const convertStatusToTemplate = (status) => {
switch (status.toUpperCase()) {
case "EXECUTED":
return 'info';
return 'darkGray';
case "CANCELED":
return 'warning';
case "SUCCEEDED":
@ -9,6 +9,6 @@ export const convertStatusToTemplate = (status) => {
case "DEFEATED":
return 'error';
default:
return 'info';
return 'darkGray';
}
}

View File

@ -61,7 +61,17 @@ const FarmPools = ({ chainId }) => {
}
return (
<Paper headerText="Farm Pools" fullWidth enableBackground>
<Paper
fullWidth
enableBackground
headerContent={
<Box display="flex" alignItems="center" flexDirection="row" gap="5px">
<Typography variant="h6">
Farm Pools
</Typography>
</Box>
}
>
<TableContainer>
<Table aria-label="Farm pools" style={{ tableLayout: "fixed" }}>
<TableHead>

View File

@ -137,7 +137,7 @@ const WethWrapper = ({ chainId, address, config, connect }) => {
<meta name="twitter:image" content="https://ghostchain.io/wp-content/uploads/2025/03/ghostFaucet-Featured_Image.png" />
</Helmet>
<PageTitle name={`${reserveSymbol} Wrapper`} subtitle={`Wrap ${nativeInfo.symbol} into ${reserveSymbol}.`} />
<PageTitle name={`${reserveSymbol} Wrapper`} subtitle={`Wrap ${nativeInfo.symbol} into ${reserveSymbol}`} />
<Container
style={{
paddingLeft: isSmallScreen || isVerySmallScreen ? "0" : "3.3rem",