Skip to content

Commit

Permalink
feat: add proposal outcome
Browse files Browse the repository at this point in the history
  • Loading branch information
0xExp-po committed Nov 15, 2024
1 parent 51b220b commit a1fe7d1
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 9 deletions.
63 changes: 58 additions & 5 deletions dapp/src/components/page/proposal/ProposalDetail.tsx
Original file line number Diff line number Diff line change
@@ -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<ProposalDetailProps> = ({
Expand All @@ -15,7 +16,7 @@ const ProposalDetail: React.FC<ProposalDetailProps> = ({
<div className="w-full bg-zinc-100 rounded-xl px-4 sm:px-8 md:px-12 py-4 sm:py-7 md:py-10">
<div className="w-full flex flex-col gap-4 sm:gap-6 md:gap-8">
<div className="">
<div className="text-xl sm:text-2xl md:text-[32px] font-semibold">
<div className="text-xl sm:text-2xl md:text-3xl font-semibold">
Proposal Description
</div>
<div className="w-full mt-4 sm:mt-5 md:mt-7 min-h-24 sm:min-h-32">
Expand All @@ -25,11 +26,16 @@ const ProposalDetail: React.FC<ProposalDetailProps> = ({
</div>
</div>
<div className="">
<div className="text-xl sm:text-2xl md:text-[32px] font-semibold">
<div className="text-xl sm:text-2xl md:text-3xl font-semibold">
Proposed Outcome
</div>
<div className="w-full mt-4 sm:mt-5 md:mt-7 min-h-24 sm:min-h-32">
<div>{outcome}</div>
<div className="w-full mt-4 sm:mt-5 md:mt-7 min-h-24 sm:min-h-32 bg-white">
<div className="px-1 sm:px-2 md:px-3 py-2 sm:py-3 md:py-4 flex flex-col gap-2 sm:gap-3 md:gap-5">
{outcome &&
Object.entries(outcome).map(([key, value]) => (
<OutcomeDetail key={key} type={key} detail={value} />
))}
</div>
</div>
</div>
</div>
Expand All @@ -38,3 +44,50 @@ const ProposalDetail: React.FC<ProposalDetailProps> = ({
};

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 (
<div className="flex flex-col gap-3 sm:gap-4 md:gap-6">
<div className="flex flex-col sm:flex-row items-start gap-1 sm:gap-2 md:gap-3">
<div
className={`text-base sm:text-xl md:text-2xl text-white md:py-0.5 px-1 md:px-2 rounded md:rounded-md
${type === "approved" ? "bg-green" : type === "rejected" ? "bg-conflict" : type === "cancelled" ? "bg-abstain" : "bg-gray-300"}`}
>
{type}
</div>
<div className="text-sm sm:text-lg md:text-[22px] md:mt-1.5">
{detail.description}
</div>
</div>
<div className="flex items-start gap-1">
<div className="w-9 sm:w-11 md:w-16">
<label className="text-base sm:text-xl md:text-[26px]">XDR:</label>
</div>
<div
className={`w-[calc(100%-68px)] px-1 sm:px-2 rounded border bg-zinc-100 border-zinc-300 text-sm sm:text-base md:text-lg break-words transition-all duration-150 ${
isExpanded
? "h-36 py-0.5 sm:py-1 overflow-y-auto"
: "h-5 sm:h-[26px] md:h-[30px] sm:py-0.5 overflow-hidden truncate"
}`}
>
{detail.xdr}
</div>
<div
onClick={toggleExpand}
className="w-5 sm:w-[26px] md:w-[30px] h-5 sm:h-[26px] md:h-[30px] rounded border border-zinc-300"
>
{isExpanded ? "^" : "#"}
</div>
</div>
</div>
);
};
5 changes: 4 additions & 1 deletion dapp/src/components/page/proposal/ProposalPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<ProposalOutcome | null>(null);
const [voteType, setVoteType] = useState<VoteType>();
const [voteStatus, setVoteStatus] = useState<VoteStatus>();

Expand All @@ -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);
Expand Down Expand Up @@ -54,7 +57,7 @@ const ProposalPage: React.FC = () => {
abstain={20}
onClick={(voteType) => openVotersModal(voteType)}
/>
<ProposalDetail description={description} outcome="" />
<ProposalDetail description={description} outcome={outcome} />
</div>
{isModalOpen && voteStatus && (
<VotersModal
Expand Down
2 changes: 1 addition & 1 deletion dapp/src/components/page/proposal/ProposalPageTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const ProposalPageTitle: React.FC<Props> = ({ id, title, submitVote }) => {
<span className="w-14 sm:w-16 md:w-20 flex justify-center text-2xl sm:text-3xl md:text-4xl px-1 font-medium bg-lime rounded-md sm:rounded-lg">
{projectId}
</span>
<p className="text-2xl font-normal text-center md:text-start">
<p className="text-2xl sm:text-3xl lg:text-[34px] font-normal text-center md:text-start">
{title}
</p>
</div>
Expand Down
15 changes: 14 additions & 1 deletion dapp/src/constants/demoProposalData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
17 changes: 16 additions & 1 deletion dapp/src/types/proposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export interface Proposal {
title: string;
ipfsLink: string;
description: string;
outcome: string;
outcome: ProposalOutcome;
status: ProposalStatus;
voteStatus: VoteStatus;
endDate: string;
Expand Down Expand Up @@ -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;
};
}

0 comments on commit a1fe7d1

Please sign in to comment.