Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 91 additions & 11 deletions src/components/pages/wallet/governance/proposals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import VoteButton from "./proposal/voteButtton";
import { UTxO } from "@meshsdk/core";
import useMultisigWallet from "@/hooks/useMultisigWallet";
import { Badge } from "@/components/ui/badge";
import { CheckCircle2, XCircle, MinusCircle, ChevronDown, ChevronUp, Clock, Calendar, Coins, Hash, FileText, Plus } from "lucide-react";
import { CheckCircle2, XCircle, MinusCircle, ChevronDown, ChevronUp, Clock, Calendar, Coins, Hash, FileText, Plus, Settings2, GitBranch, Users } from "lucide-react";
import { EmptyState } from "@/components/common/empty-state";
import { useProxy } from "@/hooks/useProxy";
import { useProxyData } from "@/lib/zustand/proxy";
Expand Down Expand Up @@ -99,6 +99,88 @@ const getAnchorUrls = (anchorUrl: string): string[] => {
];
};

type GovTypeChip = {
label: string;
className: string;
Icon: React.ComponentType<{ className?: string }>;
};

// Color-coded chip per Conway governance action type. Keys match the
// `governance_type` strings returned by the proposals endpoint.
const GOV_TYPE_CHIPS: Record<string, GovTypeChip> = {
treasury_withdrawals: {
label: "Treasury Withdrawal",
className:
"border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-900/50 dark:bg-amber-950/40 dark:text-amber-300",
Icon: Coins,
},
info_action: {
label: "Info Action",
className:
"border-blue-200 bg-blue-50 text-blue-700 dark:border-blue-900/50 dark:bg-blue-950/40 dark:text-blue-300",
Icon: FileText,
},
parameter_change: {
label: "Parameter Change",
className:
"border-purple-200 bg-purple-50 text-purple-700 dark:border-purple-900/50 dark:bg-purple-950/40 dark:text-purple-300",
Icon: Settings2,
},
hard_fork_initiation: {
label: "Hard Fork",
className:
"border-orange-200 bg-orange-50 text-orange-700 dark:border-orange-900/50 dark:bg-orange-950/40 dark:text-orange-300",
Icon: GitBranch,
},
no_confidence: {
label: "No Confidence",
className:
"border-red-200 bg-red-50 text-red-700 dark:border-red-900/50 dark:bg-red-950/40 dark:text-red-300",
Icon: XCircle,
},
new_constitution: {
label: "New Constitution",
className:
"border-teal-200 bg-teal-50 text-teal-700 dark:border-teal-900/50 dark:bg-teal-950/40 dark:text-teal-300",
Icon: FileText,
},
new_committee: {
label: "Committee Update",
className:
"border-indigo-200 bg-indigo-50 text-indigo-700 dark:border-indigo-900/50 dark:bg-indigo-950/40 dark:text-indigo-300",
Icon: Users,
},
update_committee: {
label: "Committee Update",
className:
"border-indigo-200 bg-indigo-50 text-indigo-700 dark:border-indigo-900/50 dark:bg-indigo-950/40 dark:text-indigo-300",
Icon: Users,
},
};

const toTitleCase = (value: string): string =>
value
.split("_")
.filter(Boolean)
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ");

function GovernanceTypeChip({ governanceType }: { governanceType: string }) {
const cfg = GOV_TYPE_CHIPS[governanceType] ?? {
label: toTitleCase(governanceType) || "Unknown",
className:
"border-slate-200 bg-slate-50 text-slate-700 dark:border-slate-800 dark:bg-slate-900/40 dark:text-slate-300",
Icon: Hash,
};
const Icon = cfg.Icon;
return (
<Badge variant="outline" className={`gap-1 font-medium ${cfg.className}`}>
<Icon className="h-3 w-3" />
{cfg.label}
</Badge>
);
}

async function fetchJsonFromUrl(url: string): Promise<any> {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10000);
Expand Down Expand Up @@ -777,11 +859,11 @@ export default function AllProposals({ appWallet, utxos, selectedBallotId, onSel
</div>
);
})()}
<div>
<span className="font-medium">Type:</span>{" "}
<span className="font-semibold">
{proposal.governance_type.split("_").join(" ").toUpperCase()}
</span>
<div className="flex flex-wrap items-center gap-2">
<span className="font-medium">Type:</span>
<GovernanceTypeChip
governanceType={proposal.governance_type}
/>
</div>
{proposal.json_metadata.authors.length > 0 && (
<div>
Expand Down Expand Up @@ -984,11 +1066,9 @@ function ProposalRow({
</div>
);
})()}
<div>
<span className="font-medium">Type:</span>{" "}
<span className="font-semibold">
{proposal.governance_type.split("_").join(" ").toUpperCase()}
</span>
<div className="flex flex-wrap items-center gap-2">
<span className="font-medium">Type:</span>
<GovernanceTypeChip governanceType={proposal.governance_type} />
</div>
{proposal.json_metadata.authors.length > 0 && (
<div>
Expand Down
Loading