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";