diff --git a/dapp/src/components/page/proposal/ProposalDetail.tsx b/dapp/src/components/page/proposal/ProposalDetail.tsx index 1e45443..5005b2b 100644 --- a/dapp/src/components/page/proposal/ProposalDetail.tsx +++ b/dapp/src/components/page/proposal/ProposalDetail.tsx @@ -1,10 +1,11 @@ import React from "react"; import Markdown from "markdown-to-jsx"; import "github-markdown-css"; +import type { ProposalOutcome } from "types/proposal"; interface ProposalDetailProps { description: string; - outcome: string; + outcome: ProposalOutcome | null; } const ProposalDetail: React.FC = ({ @@ -15,7 +16,7 @@ const ProposalDetail: React.FC = ({
-
+
Proposal Description
@@ -25,11 +26,16 @@ const ProposalDetail: React.FC = ({
-
+
Proposed Outcome
-
-
{outcome}
+
+
+ {outcome && + Object.entries(outcome).map(([key, value]) => ( + + ))} +
@@ -38,3 +44,50 @@ const ProposalDetail: React.FC = ({ }; export default ProposalDetail; + +const OutcomeDetail: React.FC<{ + type: string; + detail: { description: string; xdr: string }; +}> = ({ type, detail }) => { + const [isExpanded, setIsExpanded] = React.useState(false); + + const toggleExpand = () => { + setIsExpanded((prev) => !prev); + }; + + return ( +
+
+
+ {type} +
+
+ {detail.description} +
+
+
+
+ +
+
+ {detail.xdr} +
+
+ {isExpanded ? "^" : "#"} +
+
+
+ ); +}; diff --git a/dapp/src/components/page/proposal/ProposalPage.tsx b/dapp/src/components/page/proposal/ProposalPage.tsx index fdd8eed..c9ecc8a 100644 --- a/dapp/src/components/page/proposal/ProposalPage.tsx +++ b/dapp/src/components/page/proposal/ProposalPage.tsx @@ -10,11 +10,13 @@ import type { VoteType, VoteStatus } from "types/proposal"; import { demoProposalData } from "constants/demoProposalData"; import ProposalDetail from "./ProposalDetail"; import { fetchProposalFromIPFS } from "@service/ProposalService"; +import type { ProposalOutcome } from "types/proposal"; const ProposalPage: React.FC = () => { const id = useStore(proposalId); const [isModalOpen, setIsModalOpen] = useState(false); const [description, setDescription] = useState(""); + const [outcome, setOutcome] = useState(null); const [voteType, setVoteType] = useState(); const [voteStatus, setVoteStatus] = useState(); @@ -26,6 +28,7 @@ const ProposalPage: React.FC = () => { const getProposalDetails = async () => { const proposal = demoProposalData[0]; if (proposal) { + setOutcome(proposal.outcome); setVoteStatus(proposal.voteStatus); const description = await fetchProposalFromIPFS(proposal.ipfsLink); console.log("description:", description); @@ -54,7 +57,7 @@ const ProposalPage: React.FC = () => { abstain={20} onClick={(voteType) => openVotersModal(voteType)} /> - +
{isModalOpen && voteStatus && ( = ({ id, title, submitVote }) => { {projectId} -

+

{title}

diff --git a/dapp/src/constants/demoProposalData.ts b/dapp/src/constants/demoProposalData.ts index 8237b15..b230662 100644 --- a/dapp/src/constants/demoProposalData.ts +++ b/dapp/src/constants/demoProposalData.ts @@ -71,7 +71,20 @@ export const demoProposalData: Proposal[] = [ "https://bafybeidsfg2rfmpgtisfnmk6lur5dmy6j4kwjblh2rhme6nrsvjcaci4jq.ipfs.w3s.link/", description: "https://bafybeidsfg2rfmpgtisfnmk6lur5dmy6j4kwjblh2rhme6nrsvjcaci4jq.ipfs.w3s.link/proposal.md", - outcome: "", + outcome: { + approved: { + description: "What happens if this proposal is approved", + xdr: "AAAAAgAAAABiuAAAAAgAAAABiuAAAAAgAAAABiuAAAAAgAAAABiuSDFSDFLKFDERIFKLJIOERDVKLJDFERERGJBKJRKJREIKERIFDJFDKVJNERKGLERJNGEKRJNVDFKJVNDKFVJERIGUEHVEJBNERLKJGELIRKGJBELKVDJFNSOIERGBSLKFDJVBSEKGUHERSILJVNBDSFKVJEGKDJFNDFSKFDDKFGNDLKGJHERIDJNVERIUGFHERIJDFGKSDGJHDFSLKFJVNDKJERPOIGJERLKGJDFNKLDFJNGKEJGHDFIUGHEIRGJHDSKFNEROFIWJOWIUEYOIVSDNVLKXVNZXKLFKJWLOEIFHWOGRHWALFIVAWUHFOWHIASDKLJVNAOIGFWUHEOGFIWEBGKDSJNVALWIEUHFWOEIFBASKJDHFGQKWUFGOSDUIGFWUAYGGQPHDVNZKSJVNZXCVNZVLISAUHFLSkdjBNFSZKDVNSLKJFOSDIVBEJWSBVSDKJVBWKRVHBSIKWOIVBDSZVLSPSABDVCSDHVCSDJVSPDVIBWJSHDCKSVCBEWHJVBCSDJCHBXZVKSDGVWSPWVCSDMVCSDKLDVSVDJMXHVCBXMNVCXBVJVJDNCXBJDSHFGIWUFWGHEIFOGSDJKFFHLASFGSFUEWYOWHIASDKLJVNAOIGFWUHEOGFIWEBGKDSJNVALWIEUHFWOEIFBASKJDHFGQKWUFGOSDUIGFWUAYGGQPHDVNZKSJVNZXCVNZVLISAUHFLSkdjBNFSZKDVNSLKJFOSDIVBEJWSBVSDKJVBWKRVHBSIKWOIVBDSZVLSPSABDVCSDHVCSDJVSPDVIBWJSHDCKSVCBEWHJVBCSDJCHBXZVKSDGVWSPWVCSDMVCSDKLDVSVDJMXHVCBXMNVCXBVJVJDNCXBJDSHFGIWUFWGHEIFOGSDJKFFHLASFGSFUEWYKSDGVWSPWVCSDMVCSDKLDVSVDJ", + }, + rejected: { + description: "What happens if this proposal is rejected", + xdr: "AAAAAgAAAABiuAAAAAgAAAABiuAAAAAgAAAABiuAAAAAgAAAABiuSDFSDFLKFDERIFKLJIOERDVKLJDFERERGJBKJRKJREIKERIFDJFDKVJNERKGLERJNGEKRJNVDFKJVNDKFVJERIGUEHVEJBNERLKJGELIRKGJBELKVDJFNSOIERGBSLKFDJVBSEKGUHERSILJVNBDSFKVJEGKDJFNDFSKFDDKFGNDLKGJHERIDJNVERIUGFHERIJDFGKSDGJHDFSLKFJVNDKJERPOIGJERLKGJDFNKLDFJNGKEJGHDFIUGHEIRGJHDSKFNEROFIWJOWIUEYOIVSDNVLKXVNZXKLFKJWLOEIFHWOGRHWALFIVAWUHFOWHIASDKLJVNAOIGFWUHEOGFIWEBGKDSJNVALWIEUHFWOEIFBASKJDHFGQKWUFGOSDUIGFWUAYGGQPHDVNZKSJVNZXCVNZVLISAUHFLSkdjBNFSZKDVNSLKJFOSDIVBEJWSBVSDKJVBWKRVHBSIKWOIVBDSZVLSPSABDVCSDHVCSDJVSPDVIBWJSHDCKSVCBEWHJVBCSDJCHBXZVKSDGVWSPWVCSDMVCSDKLDVSVDJMXHVCBXMNVCXBVJVJDNCXBJDSHFGIWUFWGHEIFOGSDJKFFHLASFGSFUEWYOWHIASDKLJVNAOIGFWUHEOGFIWEBGKDSJNVALWIEUHFWOEIFBASKJDHFGQKWUFGOSDUIGFWUAYGGQPHDVNZKSJVNZXCVNZVLISAUHFLSkdjBNFSZKDVNSLKJFOSDIVBEJWSBVSDKJVBWKRVHBSIKWOIVBDSZVLSPSABDVCSDHVCSDJVSPDVIBWJSHDCKSVCBEWHJVBCSDJCHBXZVKSDGVWSPWVCSDMVCSDKLDVSVDJMXHVCBXMNVCXBVJVJDNCXBJDSHFGIWUFWGHEIFOGSDJKFFHLASFGSFUEWYKSDGVWSPWVCSDMVCSDKLDVSVDJ", + }, + cancelled: { + description: "What happens if this proposal is cancelled", + xdr: "AAAAAgAAAABiuAAAAAgAAAABiuAAAAAgAAAABiuAAAAAgAAAABiuSDFSDFLKFDERIFKLJIOERDVKLJDFERERGJBKJRKJREIKERIFDJFDKVJNERKGLERJNGEKRJNVDFKJVNDKFVJERIGUEHVEJBNERLKJGELIRKGJBELKVDJFNSOIERGBSLKFDJVBSEKGUHERSILJVNBDSFKVJEGKDJFNDFSKFDDKFGNDLKGJHERIDJNVERIUGFHERIJDFGKSDGJHDFSLKFJVNDKJERPOIGJERLKGJDFNKLDFJNGKEJGHDFIUGHEIRGJHDSKFNEROFIWJOWIUEYOIVSDNVLKXVNZXKLFKJWLOEIFHWOGRHWALFIVAWUHFOWHIASDKLJVNAOIGFWUHEOGFIWEBGKDSJNVALWIEUHFWOEIFBASKJDHFGQKWUFGOSDUIGFWUAYGGQPHDVNZKSJVNZXCVNZVLISAUHFLSkdjBNFSZKDVNSLKJFOSDIVBEJWSBVSDKJVBWKRVHBSIKWOIVBDSZVLSPSABDVCSDHVCSDJVSPDVIBWJSHDCKSVCBEWHJVBCSDJCHBXZVKSDGVWSPWVCSDMVCSDKLDVSVDJMXHVCBXMNVCXBVJVJDNCXBJDSHFGIWUFWGHEIFOGSDJKFFHLASFGSFUEWYOWHIASDKLJVNAOIGFWUHEOGFIWEBGKDSJNVALWIEUHFWOEIFBASKJDHFGQKWUFGOSDUIGFWUAYGGQPHDVNZKSJVNZXCVNZVLISAUHFLSkdjBNFSZKDVNSLKJFOSDIVBEJWSBVSDKJVBWKRVHBSIKWOIVBDSZVLSPSABDVCSDHVCSDJVSPDVIBWJSHDCKSVCBEWHJVBCSDJCHBXZVKSDGVWSPWVCSDMVCSDKLDVSVDJMXHVCBXMNVCXBVJVJDNCXBJDSHFGIWUFWGHEIFOGSDJKFFHLASFGSFUEWYKSDGVWSPWVCSDMVCSDKLDVSVDJ", + }, + }, status: "active", voteStatus: { totalScore: 6, diff --git a/dapp/src/types/proposal.ts b/dapp/src/types/proposal.ts index 4d0e3a9..8fd68e2 100644 --- a/dapp/src/types/proposal.ts +++ b/dapp/src/types/proposal.ts @@ -5,7 +5,7 @@ export interface Proposal { title: string; ipfsLink: string; description: string; - outcome: string; + outcome: ProposalOutcome; status: ProposalStatus; voteStatus: VoteStatus; endDate: string; @@ -43,3 +43,18 @@ export interface Voter { address: string; image: string | null; } + +export interface ProposalOutcome { + approved: { + description: string; + xdr: string; + }; + rejected: { + description: string; + xdr: string; + }; + cancelled: { + description: string; + xdr: string; + }; +}