Skip to content

Commit

Permalink
[feat] added voting logic
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianvrj committed Nov 2, 2024
1 parent 3d63c86 commit 4a1d344
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 56 deletions.
60 changes: 54 additions & 6 deletions frontend/gostarkme-web/app/app/fund/[fundId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,66 @@
'use client';

import hex2ascii from "@/app/utils";
import Fund from "@/components/modules/Fund/Fund";
import Bounded from "@/components/ui/Bounded";
import Divider from "@/components/ui/Divider";
import { FUND_MANAGER_ADDR } from "@/constants";
import { fundAbi } from "@/contracts/abis/fund";
import { fundManager } from "@/contracts/abis/fundManager";
import { walletStarknetkitLatestAtom } from "@/state/connectedWallet";
import { useAtomValue } from "jotai";
import { useEffect, useState } from "react";
import { Contract } from "starknet";

const FundDetailsPage = ({ params }: { params: { fundId: string } }) => {

const wallet = useAtomValue(walletStarknetkitLatestAtom);

const [fundManagerContract, _setFundManagerContract] = useState<Contract>(new Contract(fundManager, FUND_MANAGER_ADDR, wallet?.account));

const [fund, setFund] = useState<any>({});

async function getDetails() {
let addr = await fundManagerContract.getFund(params.fundId);
addr = "0x" + addr.toString(16);
const fundContract = new Contract(fundAbi, addr, wallet?.account);

// GET FUND NAME
let name = await fundContract.getName();
name = hex2ascii(name.toString(16));
// GET FUND DESCRIPTION
let desc = await fundContract.getReason();
if (desc == " ") {
desc = "No description provided";
}
let state = await fundContract.getState();

let currentBalance = await fundContract.getCurrentGoalState();

let goal = await fundContract.getGoal();

let upVotes = await fundContract.getUpVotes();

setFund({ name: name, desc: desc, state: state, currentBalance: currentBalance, goal: goal, upVotes: upVotes, addr: addr });
}

export function generateStaticParams() {
return [{ fundId: '1' }]
}
useEffect(() => {
getDetails();
}, []);

const FundDetailsPage = async ({ params }: { params: { fundId: string } }) => {
return (
<>
<Bounded className="px-60 text-lg">
<h2 className="font-bold">User&apos;s fund - {params.fundId}</h2>
<h2 className="font-bold">{fund.name}</h2>
<Divider />
<Fund message="I need some Starks to finish my project."></Fund>
<Fund message={fund.desc}
state={fund.state}
currentBalance={fund.currentBalance}
goal={fund.goal}
upVotes={fund.upVotes}
addr={fund.addr}
>
</Fund>
</Bounded>
</>
);
Expand Down
34 changes: 20 additions & 14 deletions frontend/gostarkme-web/app/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import FundCards from "@/components/dashboard/fundCard";
import Footer from "@/components/ui/Footer";
import Navbar from "@/components/ui/Navbar";
import { FUND_MANAGER_ADDR } from "@/constants";
import { fund } from "@/contracts/abis/fund";
import { fundAbi } from "@/contracts/abis/fund";
import { fundManager } from "@/contracts/abis/fundManager";
import { walletStarknetkitLatestAtom } from "@/state/connectedWallet";
import { useAtomValue } from "jotai";
import React, { useEffect, useState } from "react";
import { byteArray, Contract, InvokeFunctionResponse } from "starknet";
import { navItems } from "@/constants";
import hex2ascii from "../utils";

const Dashboard = () => {

Expand All @@ -19,13 +20,7 @@ const Dashboard = () => {

const [funds, setFunds] = useState<any>([]);

function hex2ascii(hexx: string) {
var hex = hexx.toString();//force conversion
var str = '';
for (var i = 0; i < hex.length; i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}
const [loading, setLoading] = useState(true);

async function getFunds() {
const id = await fundManagerContract.getCurrentId();
Expand All @@ -34,20 +29,23 @@ const Dashboard = () => {
// GET FUND ADDRESS
let fundaddr = await fundManagerContract.getFund(i);
fundaddr = "0x" + fundaddr.toString(16);
const fundContract = new Contract(fund, fundaddr, wallet?.account);
const fundContract = new Contract(fundAbi, fundaddr, wallet?.account);
// GET FUND NAME
let name = await fundContract.getName();
name = hex2ascii(name.toString(16));
// GET FUND DESCRIPTION
let desc = await fundContract.getReason();
// GET FUND ID
let fund_id = await fundContract.getId();
fundings.push({
type: "Project",
title: name,
description: desc,
fund_id: fund_id.toString(),
});
}
console.log(fundings);
setFunds(fundings);
setLoading(false);
}

useEffect(() => {
Expand All @@ -70,19 +68,27 @@ const Dashboard = () => {
Latest Funds
<span className="ml-2 text-yellow-400">&#x2728;</span>
</h1>
{funds.length !== 0 ? (

{loading && <div className="text-center text-gray-500">
Loading funds ...
</div>}

{funds.length !== 0 && !loading &&
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-4 gap-y-6 md:gap-x-[138px] md:gap-y-[84px]">
{funds.map((fund: { type: string; title: string; description: string; }, index: number) => (
{funds.map((fund: { type: string; title: string; description: string; fund_id: string }, index: number) => (
<FundCards key={index} fund={fund} index={index} />
))}
</div>
) : (
}

{funds.length === 0 && !loading &&
<div className="flex justify-center items-center h-64">
<div className="text-center text-gray-500">
There is no fundings to display.
</div>
</div>
)}
}

<Footer></Footer>
</div>
);
Expand Down
11 changes: 11 additions & 0 deletions frontend/gostarkme-web/app/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function hex2ascii(hexx: string) {
var hex = hexx.toString();//force conversion
var str = '';
for (var i = 0; i < hex.length; i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}

export function calculatePorcentage(qty: number, goal: number): number {
return (Number(qty) / Number(goal)) * 100;
}
46 changes: 25 additions & 21 deletions frontend/gostarkme-web/components/dashboard/fundCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import { StardustAnimation } from "@/animations/StardustAnimation";
import useComponentSize from "@/hooks/useComponentSize.hook";
import Link from "next/link";
import React from "react";

interface FundCardProps {
fund: {
type: string;
title: string;
description: string;
fund_id: string
};
index: number;
}
Expand All @@ -17,28 +19,30 @@ const FundCards = ({ fund, index }: FundCardProps) => {
const [ref, width, height] = useComponentSize();
return (
<div className="relative" ref={ref}>
<div
key={index}
className="min-w-[30rem] bg-gray-950 shadow-[0px_4px_4px_0px_#00000040] text-white rounded-[10px] py-[32px] md:py-[48px] md:px-[48px] lg:py-[64px] lg:px-[72px] gap-8 md:gap-10 lg:gap-14 flex flex-col items-start justify-between"
>
<div className="flex flex-col items-start justify-between gap-4 md:gap-6">
<p className=" text-sm md:text-base lg:text-lg text-white font-light leading-[22px] md:leading-[25px] lg:leading-[27.6px]">
{fund.type} {fund.type === "Project" ? <span>&#x1f680;</span> : <span>&#x1FAC0;</span>}
</p>
<h1 className="text-lg md:text-lg lg:text-[30px] font-bold">
{fund.title}
</h1>
<Link href={"/app/fund/" + fund.fund_id}>
<div
key={index}
className="min-w-[30rem] bg-gray-950 shadow-[0px_4px_4px_0px_#00000040] text-white rounded-[10px] py-[32px] md:py-[48px] md:px-[48px] lg:py-[64px] lg:px-[72px] gap-8 md:gap-10 lg:gap-14 flex flex-col items-start justify-between"
>
<div className="flex flex-col items-start justify-between gap-4 md:gap-6">
<p className=" text-sm md:text-base lg:text-lg text-white font-light leading-[22px] md:leading-[25px] lg:leading-[27.6px]">
{fund.type} {fund.type === "Project" ? <span>&#x1f680;</span> : <span>&#x1FAC0;</span>}
</p>
<h1 className="text-lg md:text-lg lg:text-[30px] font-bold">
{fund.title}
</h1>
</div>
<div>
{fund.description !== " " ? (
<p className="text-lg md:text-lg lg:text-[25px] text-white">{fund.description}</p>
) :
(
<p className="text-lg md:text-lg lg:text-[25px] text-white">No description provided</p>
)}
</div>
<StardustAnimation height={height} width={width} />
</div>
<div>
{fund.description !== " " ? (
<p className="text-lg md:text-lg lg:text-[25px] text-white">{fund.description}</p>
) :
(
<p className="text-lg md:text-lg lg:text-[25px] text-white">No description provided</p>
)}
</div>
<StardustAnimation height={height} width={width} />
</div>
</Link>
</div>
);
};
Expand Down
20 changes: 13 additions & 7 deletions frontend/gostarkme-web/components/modules/Fund/Fund.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,26 @@ import FundDonate from "./FundDonate";
import starknetlogo from "@/public/icons/starklogo.png";
import { FundVote } from "./FundVote";
import { useState } from "react";
import { upVotesNeeded } from "@/constants";

interface FundProps {
message: string;
message: string,
state: number,
currentBalance: number,
goal: number,
upVotes: number
addr: string
}

const Fund = ({ message }: FundProps) => {
const [type, setType] = useState<string>("donate");

const Fund = ({ message, state, currentBalance, goal, upVotes, addr }: FundProps) => {
return (
<section>
<p className="mb-40">{message}</p>

{type === "donate" ? <FundDonate icon={starknetlogo} /> : <FundVote />}
{/* For Vote, there is no logo, but when you already have it, just pass it through the prop */}
{ Number(state) === 0 && <p>Fund is currently innactive.</p>}
{ Number(state) === 1 && <FundVote upVotes={upVotes} upVotesNeeded={upVotesNeeded} addr={addr}/>}
{ Number(state) === 2 && <FundDonate icon={starknetlogo} />}
{ Number(state) === 3 && <p>Fund is currently closed.</p>}
{ Number(state) === 4 && <p>Fund was already withdrawed.</p>}
</section>
);
};
Expand Down
36 changes: 29 additions & 7 deletions frontend/gostarkme-web/components/modules/Fund/FundVote.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,43 @@
import { calculatePorcentage } from "@/app/utils";
import { Button } from "@/components/ui/Button";
import { LinkButton } from "@/components/ui/LinkButton";
import ProgressBar from "@/components/ui/ProgressBar";
import Image, { StaticImageData } from "next/image";
import { fundAbi } from "@/contracts/abis/fund";
import { walletStarknetkitLatestAtom } from "@/state/connectedWallet";
import { useAtomValue } from "jotai";
import { useState } from "react";
import { Contract, wallet, InvokeFunctionResponse } from "starknet";

interface FundVoteProps {
icon?: StaticImageData;
upVotes: number,
upVotesNeeded: number,
addr: string,
}

export const FundVote = ({ icon }: FundVoteProps) => {
export const FundVote = ({ upVotes, upVotesNeeded, addr }: FundVoteProps) => {

const wallet = useAtomValue(walletStarknetkitLatestAtom);

const progress = calculatePorcentage(upVotes, upVotesNeeded);

function vote() {
const fundContract = new Contract(fundAbi, addr, wallet?.account);
const myCall = fundContract.populate("receiveVote", []);
wallet?.account?.execute(myCall)
.then(async (resp: InvokeFunctionResponse) => {
console.log("increaseBalance txH =", resp.transaction_hash);
})
.catch((e: any) => { console.log("error increase balance =", e) });
}

return (
<div className="flex flex-col">
<ProgressBar progress={34} />
<ProgressBar progress={progress} />
<div className="flex justify-center my-2">
<p className="text-center mx-2">200 / 300 </p>
{/* <Image src={icon || ""} alt="icon" width={24} height={24} /> */}
<p className="text-center mx-2">{upVotes.toString()} / {upVotesNeeded.toString()} </p>
<p>&#127775;</p>
</div>
<LinkButton label="Vote" href="/" />
<Button label="Vote" onClick={vote}></Button>
</div>
);
};
2 changes: 2 additions & 0 deletions frontend/gostarkme-web/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ export const navItems = [
{ label: 'My Profile', href: '/app/myprofile' },
{ label: 'My funds', href: '/app/myfunds' }
];

export const upVotesNeeded = 100;
2 changes: 1 addition & 1 deletion frontend/gostarkme-web/contracts/abis/fund.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const fund = [
export const fundAbi = [
{
"type": "impl",
"name": "FundImpl",
Expand Down

0 comments on commit 4a1d344

Please sign in to comment.