From 9ef3e6b75813f4512aaac386e99ee98f739cd2aa Mon Sep 17 00:00:00 2001
From: 0xExp-po <153439271+0xExp-po@users.noreply.github.com>
Date: Thu, 21 Nov 2024 17:50:40 +0900
Subject: [PATCH] Add first DAO UI components (#89)
---
dapp/package.json | 1 +
dapp/public/ag.svg | 19 +-
dapp/public/icons/arrow-down.svg | 23 +-
dapp/public/icons/arrow-up.svg | 23 +-
dapp/public/icons/arrow.svg | 14 +-
dapp/public/icons/avatar.svg | 27 +
dapp/public/icons/check.svg | 18 +-
dapp/public/icons/failed.svg | 18 +-
dapp/public/icons/logos/discord.svg | 6 +-
dapp/public/icons/logos/git.svg | 11 +-
dapp/public/icons/logos/github.svg | 6 +-
dapp/public/icons/logos/instagram.svg | 6 +-
dapp/public/icons/logos/stellar-expert.svg | 19 +-
dapp/public/icons/logos/stellar-xlm.svg | 15 +
dapp/public/icons/logos/tansu.svg | 39 +-
dapp/public/icons/logos/telegram.svg | 6 +-
dapp/public/icons/logos/twitter.svg | 6 +-
dapp/public/icons/logos/web.svg | 16 +-
dapp/public/icons/release.svg | 12 +-
dapp/public/icons/search.svg | 8 +-
dapp/public/logo.svg | 39 +-
dapp/src/components/layout/Container.astro | 2 +-
.../page/governance/GovernancePage.astro | 9 +
.../page/governance/GovernancePageTitle.astro | 36 +
.../components/page/governance/IdeaList.tsx | 28 +
.../page/governance/ProposalCard.tsx | 69 ++
.../page/governance/ProposalList.tsx | 48 ++
.../page/governance/ProposalStatusShow.tsx | 49 ++
.../page/governance/ProposalTypeButton.tsx | 40 ++
.../page/governance/ProposalsSection.tsx | 36 +
dapp/src/components/page/project/Commit.astro | 4 +-
.../components/page/project/CommitHistory.jsx | 66 +-
.../components/page/project/DonateModal.astro | 14 +-
.../components/page/project/GetCommit.astro | 4 +-
.../components/page/project/ProjectInfo.astro | 68 +-
.../components/page/project/ReadmeViewer.tsx | 1 -
.../page/proposal/ExecuteProposalModal.tsx | 97 +++
.../page/proposal/ProposalDetail.tsx | 217 ++++++
.../components/page/proposal/ProposalPage.tsx | 123 ++++
.../page/proposal/ProposalPageTitle.tsx | 92 +++
.../page/proposal/ProposalStatusSection.tsx | 28 +
.../page/proposal/VoteStatusBar.tsx | 43 ++
.../components/page/proposal/VotersModal.tsx | 92 +++
.../components/page/proposal/VotingModal.tsx | 103 +++
.../page/register/RegisterProject.astro | 4 +-
dapp/src/components/stellar-wallets-kit.ts | 2 +
dapp/src/components/utils/Pagination.tsx | 74 ++
dapp/src/components/utils/PrimaryButton.astro | 6 +-
dapp/src/components/utils/Topic.astro | 2 +-
dapp/src/constants/demoProposalData.ts | 632 ++++++++++++++++++
dapp/src/constants/serviceLinks.js | 2 +
dapp/src/layouts/Layout.astro | 4 +-
dapp/src/pages/governance/index.astro | 30 +
dapp/src/pages/proposal/index.astro | 30 +
dapp/src/service/ProposalService.ts | 31 +
dapp/src/styles/global.css | 12 +-
dapp/src/types/proposal.ts | 68 ++
dapp/src/utils/formatTimeFunctions.ts | 16 +
dapp/src/utils/store.js | 3 +
dapp/src/utils/utils.ts | 33 +
dapp/tailwind.config.mjs | 20 +-
61 files changed, 2395 insertions(+), 175 deletions(-)
create mode 100644 dapp/public/icons/avatar.svg
create mode 100644 dapp/public/icons/logos/stellar-xlm.svg
create mode 100644 dapp/src/components/page/governance/GovernancePage.astro
create mode 100644 dapp/src/components/page/governance/GovernancePageTitle.astro
create mode 100644 dapp/src/components/page/governance/IdeaList.tsx
create mode 100644 dapp/src/components/page/governance/ProposalCard.tsx
create mode 100644 dapp/src/components/page/governance/ProposalList.tsx
create mode 100644 dapp/src/components/page/governance/ProposalStatusShow.tsx
create mode 100644 dapp/src/components/page/governance/ProposalTypeButton.tsx
create mode 100644 dapp/src/components/page/governance/ProposalsSection.tsx
create mode 100644 dapp/src/components/page/proposal/ExecuteProposalModal.tsx
create mode 100644 dapp/src/components/page/proposal/ProposalDetail.tsx
create mode 100644 dapp/src/components/page/proposal/ProposalPage.tsx
create mode 100644 dapp/src/components/page/proposal/ProposalPageTitle.tsx
create mode 100644 dapp/src/components/page/proposal/ProposalStatusSection.tsx
create mode 100644 dapp/src/components/page/proposal/VoteStatusBar.tsx
create mode 100644 dapp/src/components/page/proposal/VotersModal.tsx
create mode 100644 dapp/src/components/page/proposal/VotingModal.tsx
create mode 100644 dapp/src/components/utils/Pagination.tsx
create mode 100644 dapp/src/constants/demoProposalData.ts
create mode 100644 dapp/src/constants/serviceLinks.js
create mode 100644 dapp/src/pages/governance/index.astro
create mode 100644 dapp/src/pages/proposal/index.astro
create mode 100644 dapp/src/service/ProposalService.ts
create mode 100644 dapp/src/types/proposal.ts
diff --git a/dapp/package.json b/dapp/package.json
index f669c00..a324df5 100644
--- a/dapp/package.json
+++ b/dapp/package.json
@@ -14,6 +14,7 @@
"js-sha3": "^0.9.3",
"markdown-to-jsx": "^7.6.2",
"nanostores": "^0.11.3",
+ "react18-json-view": "^0.2.8",
"tailwindcss": "^3.4.15",
"typescript": "^5.6.3"
},
diff --git a/dapp/public/ag.svg b/dapp/public/ag.svg
index 6262e7b..bf50d7b 100644
--- a/dapp/public/ag.svg
+++ b/dapp/public/ag.svg
@@ -1,6 +1,15 @@
-
\ No newline at end of file
+ strokeLinejoin="round">
+
diff --git a/dapp/public/logo.svg b/dapp/public/logo.svg
index cf33d48..362f087 100644
--- a/dapp/public/logo.svg
+++ b/dapp/public/logo.svg
@@ -1,7 +1,21 @@
-
-
+
-
+
-
-
\ No newline at end of file
+z"
+ >
+
diff --git a/dapp/src/components/layout/Container.astro b/dapp/src/components/layout/Container.astro
index b7e8944..0a0dced 100644
--- a/dapp/src/components/layout/Container.astro
+++ b/dapp/src/components/layout/Container.astro
@@ -1,5 +1,5 @@
diff --git a/dapp/src/components/page/governance/GovernancePage.astro b/dapp/src/components/page/governance/GovernancePage.astro
new file mode 100644
index 0000000..15f65ec
--- /dev/null
+++ b/dapp/src/components/page/governance/GovernancePage.astro
@@ -0,0 +1,9 @@
+---
+import GovernancePageTitle from "./GovernancePageTitle.astro";
+import ProposalsSection from "./ProposalsSection.tsx";
+---
+
+
diff --git a/dapp/src/components/page/governance/GovernancePageTitle.astro b/dapp/src/components/page/governance/GovernancePageTitle.astro
new file mode 100644
index 0000000..85833b8
--- /dev/null
+++ b/dapp/src/components/page/governance/GovernancePageTitle.astro
@@ -0,0 +1,36 @@
+---
+import PrimaryButton from "../../utils/PrimaryButton.astro";
+import Topic from "../../utils/Topic.astro";
+---
+
+
+
+
diff --git a/dapp/src/components/page/governance/IdeaList.tsx b/dapp/src/components/page/governance/IdeaList.tsx
new file mode 100644
index 0000000..e395778
--- /dev/null
+++ b/dapp/src/components/page/governance/IdeaList.tsx
@@ -0,0 +1,28 @@
+import React from "react";
+import { useState } from "react";
+import Pagination from "../../utils/Pagination";
+import { projectNameForGovernance } from "utils/store";
+import { useStore } from "@nanostores/react";
+
+const IdeaList: React.FC = () => {
+ const projectName = useStore(projectNameForGovernance);
+ const [currentPage, setCurrentPage] = useState(1);
+
+ return (
+
+
+
+
setCurrentPage(page)}
+ />
+
+
+ );
+};
+
+export default IdeaList;
diff --git a/dapp/src/components/page/governance/ProposalCard.tsx b/dapp/src/components/page/governance/ProposalCard.tsx
new file mode 100644
index 0000000..bac1802
--- /dev/null
+++ b/dapp/src/components/page/governance/ProposalCard.tsx
@@ -0,0 +1,69 @@
+import React from "react";
+import ProposalStatusShow from "./ProposalStatusShow";
+import type { ProposalCardProps } from "types/proposal";
+import { calculateDateDifference } from "utils/formatTimeFunctions";
+import { navigate } from "astro:transitions/client";
+
+const ProposalCard: React.FC = ({
+ proposalNumber,
+ proposalTitle,
+ proposalStatus,
+ endDate,
+}) => {
+ return (
+ navigate(`/proposal?id=${proposalNumber}`)}
+ >
+
+
+
+
+ {proposalTitle}
+
+
+
+
+ {proposalStatus === "active" &&
+ endDate &&
+ calculateDateDifference(endDate) && (
+
+ Ends in {calculateDateDifference(endDate)}
+
+ )}
+ {proposalStatus === "voted" && (
+
+ Pending execution
+
+ )}
+
+
+
+
+
+
+ {proposalStatus === "active" &&
+ endDate &&
+ calculateDateDifference(endDate) && (
+
+ Ends in {calculateDateDifference(endDate)}
+
+ )}
+ {proposalStatus === "voted" && (
+
+ Pending execution
+
+ )}
+
+
+
+ );
+};
+
+export default ProposalCard;
diff --git a/dapp/src/components/page/governance/ProposalList.tsx b/dapp/src/components/page/governance/ProposalList.tsx
new file mode 100644
index 0000000..b922f40
--- /dev/null
+++ b/dapp/src/components/page/governance/ProposalList.tsx
@@ -0,0 +1,48 @@
+import React from "react";
+import { useState, useEffect } from "react";
+import Pagination from "../../utils/Pagination";
+import { demoProposalCardData } from "constants/demoProposalData";
+import ProposalCard from "./ProposalCard";
+import { projectNameForGovernance } from "utils/store";
+import { useStore } from "@nanostores/react";
+import type { ProposalCardProps } from "types/proposal";
+
+const ProposalList: React.FC = () => {
+ const projectName = useStore(projectNameForGovernance);
+ const [currentPage, setCurrentPage] = useState(1);
+ const [proposalCardData, setProposalCardData] = useState(
+ [],
+ );
+
+ const fetchProposalCardData = async (_page: number) => {
+ setProposalCardData(demoProposalCardData);
+ };
+
+ useEffect(() => {
+ fetchProposalCardData(currentPage);
+ }, [currentPage, projectName]);
+
+ return (
+
+
+ {proposalCardData.map((proposal) => (
+
+ ))}
+
+
+
setCurrentPage(page)}
+ />
+
+
+ );
+};
+
+export default ProposalList;
diff --git a/dapp/src/components/page/governance/ProposalStatusShow.tsx b/dapp/src/components/page/governance/ProposalStatusShow.tsx
new file mode 100644
index 0000000..fb27b20
--- /dev/null
+++ b/dapp/src/components/page/governance/ProposalStatusShow.tsx
@@ -0,0 +1,49 @@
+import React from "react";
+import type { ProposalStatus } from "types/proposal";
+
+interface ProposalStatusShowProps {
+ proposalStatus: ProposalStatus;
+}
+
+const ProposalStatusShow: React.FC = ({
+ proposalStatus,
+}) => {
+ let title;
+ let backgroundColorClass;
+
+ switch (proposalStatus) {
+ case "active":
+ title = "Active";
+ backgroundColorClass = "bg-active";
+ break;
+ case "rejected":
+ title = "Rejected";
+ backgroundColorClass = "bg-conflict";
+ break;
+ case "cancelled":
+ title = "Cancelled";
+ backgroundColorClass = "bg-abstain";
+ break;
+ case "voted":
+ title = "Voted";
+ backgroundColorClass = "bg-voted";
+ break;
+ case "approved":
+ title = "Approved";
+ backgroundColorClass = "bg-approved";
+ break;
+ default:
+ title = "Unknown";
+ backgroundColorClass = "bg-gray";
+ }
+
+ return (
+
+
{title}
+
+ );
+};
+
+export default ProposalStatusShow;
diff --git a/dapp/src/components/page/governance/ProposalTypeButton.tsx b/dapp/src/components/page/governance/ProposalTypeButton.tsx
new file mode 100644
index 0000000..169a9ef
--- /dev/null
+++ b/dapp/src/components/page/governance/ProposalTypeButton.tsx
@@ -0,0 +1,40 @@
+import React from "react";
+import { useState, useEffect } from "react";
+
+interface ProposalTypeButtonProps {
+ proposalTypeStatus: string;
+ proposalType: string;
+ title: string;
+ position?: "start" | "end";
+ onClick: (proposalType: string) => void;
+}
+
+const ProposalTypeButton: React.FC = ({
+ proposalTypeStatus,
+ proposalType,
+ title,
+ position = null,
+ onClick,
+}) => {
+ const [isSelected, setIsSelected] = useState(true);
+
+ useEffect(() => {
+ if (proposalTypeStatus === proposalType) {
+ setIsSelected(true);
+ } else {
+ setIsSelected(false);
+ }
+ }, [proposalTypeStatus]);
+
+ const buttonClass = `px-2.5 sm:px-3 py-1.5 sm:py-2 text-md sm:text-xl font-medium border border-zinc-200 focus:outline-none ${
+ isSelected ? "bg-zinc-200" : "bg-white"
+ } ${position === "start" ? "rounded-tl-lg" : position === "end" ? "rounded-tr-lg" : ""}`;
+
+ return (
+
+ );
+};
+
+export default ProposalTypeButton;
diff --git a/dapp/src/components/page/governance/ProposalsSection.tsx b/dapp/src/components/page/governance/ProposalsSection.tsx
new file mode 100644
index 0000000..29ba8be
--- /dev/null
+++ b/dapp/src/components/page/governance/ProposalsSection.tsx
@@ -0,0 +1,36 @@
+import React from "react";
+import { useState } from "react";
+import ProposalTypeButton from "./ProposalTypeButton";
+import ProposalList from "./ProposalList";
+import IdeaList from "./IdeaList";
+
+const ProposalsSection: React.FC = () => {
+ const [proposalType, setProposalType] = useState("proposal");
+
+ return (
+
+
+
setProposalType(proposalType)}
+ />
+ setProposalType(proposalType)}
+ />
+
+
+ {proposalType === "proposal" &&
}
+ {proposalType === "idea" &&
}
+
+
+ );
+};
+
+export default ProposalsSection;
diff --git a/dapp/src/components/page/project/Commit.astro b/dapp/src/components/page/project/Commit.astro
index a4b09c5..d95c183 100644
--- a/dapp/src/components/page/project/Commit.astro
+++ b/dapp/src/components/page/project/Commit.astro
@@ -5,7 +5,9 @@ import PrimaryButton from "../../utils/PrimaryButton.astro";
---
-
+
diff --git a/dapp/src/components/page/project/CommitHistory.jsx b/dapp/src/components/page/project/CommitHistory.jsx
index a853563..b286f33 100644
--- a/dapp/src/components/page/project/CommitHistory.jsx
+++ b/dapp/src/components/page/project/CommitHistory.jsx
@@ -9,6 +9,7 @@ import {
} from "../../../service/StateService.ts";
import { getCommitHistory } from "../../../service/GithubService.ts";
import { useStore } from "@nanostores/react";
+import Pagination from "components/utils/Pagination.tsx";
const CommitHistory = () => {
const isProjectInfoLoaded = useStore(projectInfoLoaded);
@@ -92,67 +93,10 @@ const CommitHistory = () => {
))}
- {/* Pagination */}
-
-
-
- {currentPage > 2 &&
...}
- {currentPage !== 1 && (
-
- )}
-
-
+
fetchCommitHistory(page)}
+ />
>
);
};
diff --git a/dapp/src/components/page/project/DonateModal.astro b/dapp/src/components/page/project/DonateModal.astro
index f1e1e7b..aefc95a 100644
--- a/dapp/src/components/page/project/DonateModal.astro
+++ b/dapp/src/components/page/project/DonateModal.astro
@@ -11,7 +11,7 @@ import Loading from "../../utils/Loading.astro";
>
@@ -57,7 +57,7 @@ import Loading from "../../utils/Loading.astro";