Skip to content

Commit

Permalink
Merge pull request #3085 from jk-labs-inc/staging
Browse files Browse the repository at this point in the history
  • Loading branch information
siobh9 authored Dec 16, 2024
2 parents 3a6e0fa + b167450 commit 44c7b86
Show file tree
Hide file tree
Showing 13 changed files with 354 additions and 220 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ const ChargeInfo: React.FC<ChargeInfoProps> = ({ charge }) => {
}

return (
<div className="flex justify-between text-neutral-9 text-[16px]">
<div
className={`flex justify-between ${charge.voteType === VoteType.PerTransaction ? "text-neutral-11" : "text-neutral-9"} text-[16px]`}
>
<p>{chargeLabel}:</p>
<p>
{entryChargeFormatted} {chainUnitLabel}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,23 @@ const MyVotes: React.FC<MyVotesProps> = ({ charge, amountOfVotes, chainId }) =>
});

const insufficientBalance = charge && balanceData ? balanceData.value < BigInt(charge.type.costToVote) : false;
const isPerVote = charge?.voteType === VoteType.PerVote;

return (
<div
className={`flex justify-between items-center text-[16px] ${insufficientBalance ? "text-negative-11" : "text-neutral-11"} transition-colors duration-300`}
>
<span className="text-neutral-11">my votes:</span>
<span className="text-neutral-9">{isPerVote ? "my wallet" : "my votes:"}</span>
<div className="flex items-center gap-2">
{balanceData && charge?.voteType === VoteType.PerVote && (
<>
<span className="text-neutral-14">
{formatBalance(balanceData.formatted)} {balanceData.symbol}
</span>
<span className="text-neutral-14">=</span>
</>
{balanceData && isPerVote ? (
<span className="text-neutral-9">
{formatBalance(balanceData.formatted)} {balanceData.symbol}
</span>
) : (
<span className="text-neutral-9">
{formatNumberAbbreviated(amountOfVotes)} vote{amountOfVotes !== 1 ? "s" : ""}
</span>
)}
<span className="text-neutral-11">
{formatNumberAbbreviated(amountOfVotes)} vote{amountOfVotes !== 1 ? "s" : ""}
</span>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { chains } from "@config/wagmi";
import { extractPathSegments } from "@helpers/extractPath";
import { Charge } from "@hooks/useDeployContest/types";
import { Charge, VoteType } from "@hooks/useDeployContest/types";
import { usePathname } from "next/navigation";
import React, { useEffect, useState } from "react";
import { formatEther } from "viem";
Expand All @@ -27,7 +27,7 @@ const TotalCharge: React.FC<TotalChargeProps> = ({ charge: contestCharge, amount
return;
}

if (contestCharge.voteType === "PerVote") {
if (contestCharge.voteType === VoteType.PerVote) {
const chargeAmount = parseFloat(formatEther(BigInt(contestCharge.type.costToVote)));
const multipliedCharge = chargeAmount * amountOfVotes;
const charge = +multipliedCharge.toFixed(6);
Expand All @@ -37,6 +37,10 @@ const TotalCharge: React.FC<TotalChargeProps> = ({ charge: contestCharge, amount
}
}, [contestCharge, amountOfVotes]);

if (contestCharge.voteType === VoteType.PerTransaction) {
return null;
}

return (
<div className="flex items-center justify-between text-neutral-11 text-[16px]">
<p>total charge:</p>
Expand Down
2 changes: 1 addition & 1 deletion packages/react-app-revamp/components/UI/Slider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const StepSlider: FC<StepSliderProps> = ({
};

return (
<div onKeyDown={onKeyDown} tabIndex={0} className="p-4 md:p-0">
<div onKeyDown={onKeyDown} tabIndex={0}>
<Slider
className="w-60"
min={min}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import ChargeInfo from "@components/ChargeLayout/components/Vote/components/ChargeInfo";
import MyVotes from "@components/ChargeLayout/components/Vote/components/MyVotes";
import TotalCharge from "@components/ChargeLayout/components/Vote/components/TotalCharge";
import ButtonV3, { ButtonSize, ButtonType } from "@components/UI/ButtonV3";
import StepSlider from "@components/UI/Slider";
import { Charge, VoteType } from "@hooks/useDeployContest/types";
import { FC } from "react";

interface VotingWidgetMobileProps {
downvoteAllowed: boolean;
isUpvote: boolean;
isInvalid: boolean;
inputRef: React.RefObject<HTMLInputElement>;
amount: number;
amountOfVotes: number;
isFocused: boolean;
sliderValue: number;
charge: Charge | null;
chainId: number;
voteDisabled: boolean;
handleVote: () => void;
handleChange: (value: string) => void;
handleKeyDownInput: (e: React.KeyboardEvent<HTMLInputElement>) => void;
handleKeyDownSlider: (e: React.KeyboardEvent<HTMLDivElement>) => void;
handleSliderChange: (value: number) => void;
handleClick: (isUpvote: boolean) => void;
setIsFocused: (value: boolean) => void;
handleInput: (e: React.ChangeEvent<HTMLInputElement>) => void;
}

const VotingWidgetMobile: FC<VotingWidgetMobileProps> = ({
downvoteAllowed,
isUpvote,
isInvalid,
inputRef,
amount,
amountOfVotes,
isFocused,
handleVote,
handleChange,
handleKeyDownInput,
handleKeyDownSlider,
handleSliderChange,
handleClick,
setIsFocused,
handleInput,
sliderValue,
charge,
chainId,
voteDisabled,
}) => {
return (
<div className="flex flex-col gap-8">
<div className="flex flex-col gap-4">
{downvoteAllowed ? (
<div className="flex w-full border border-neutral-10 rounded-[25px] overflow-hidden text-[16px] text-center">
<div
className={`w-full px-4 py-1 cursor-pointer ${
isUpvote ? "bg-neutral-11 text-true-black font-bold" : "bg-true-black text-neutral-10"
}`}
onClick={() => handleClick(true)}
>
upvote
</div>
<div
className={`w-full px-4 py-1 cursor-pointer ${
!isUpvote ? "bg-neutral-11 text-true-black font-bold" : "bg-true-black text-neutral-10"
}`}
onClick={() => handleClick(false)}
>
downvote
</div>
</div>
) : null}
<div className="flex flex-col gap-8">
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
{charge?.voteType === VoteType.PerVote ? (
<>
<MyVotes amountOfVotes={amountOfVotes} charge={charge} chainId={chainId} />
{charge ? <ChargeInfo charge={charge} /> : null}
</>
) : null}
</div>
</div>
<div className="flex flex-col gap-6">
<div
className={`relative flex w-full md:w-80 h-16 items-center px-8 text-[16px] bg-transparent font-bold ${
isInvalid ? "text-negative-11" : "text-neutral-11"
} border-2 ${isFocused && !isInvalid ? "border-neutral-11" : isInvalid ? "border-negative-11" : "border-neutral-10"} rounded-[40px] transition-colors duration-300`}
>
<input
ref={inputRef}
type="number"
value={amount || ""}
onChange={e => handleChange(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
placeholder="0.00"
max={amountOfVotes}
onKeyDown={handleKeyDownInput}
onInput={handleInput}
className="w-full text-[32px] bg-transparent outline-none placeholder-primary-5"
/>
<span className="absolute right-4 text-neutral-9 text-[16px] font-bold">
vote{amount !== 1 ? "s" : ""}
</span>
</div>
<div className="flex flex-col gap-4">
<StepSlider val={sliderValue} onChange={handleSliderChange} onKeyDown={handleKeyDownSlider} />
{charge?.voteType === VoteType.PerTransaction ? (
<>
<MyVotes amountOfVotes={amountOfVotes} charge={charge} chainId={chainId} />
{charge ? <ChargeInfo charge={charge} /> : null}
</>
) : null}
{charge ? <TotalCharge charge={charge} amountOfVotes={amount} /> : null}
</div>
</div>

<ButtonV3
type={ButtonType.TX_ACTION}
isDisabled={voteDisabled}
colorClass="px-[20px] bg-gradient-purple rounded-[40px] w-full"
size={ButtonSize.FULL}
onClick={handleVote}
>
<span className="w-full text-center">add votes to entry</span>
</ButtonV3>
</div>
</div>
</div>
);
};

export default VotingWidgetMobile;
126 changes: 72 additions & 54 deletions packages/react-app-revamp/components/Voting/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import { ContestStateEnum, useContestStateStore } from "@hooks/useContestState/s
import { switchChain } from "@wagmi/core";
import { usePathname } from "next/navigation";
import { FC, useEffect, useRef, useState } from "react";
import { useMediaQuery } from "react-responsive";
import { useAccount } from "wagmi";
import VotingWidgetMobile from "./components/Mobile";

interface VotingWidgetProps {
proposalId: string;
Expand All @@ -22,6 +24,7 @@ interface VotingWidgetProps {

const VotingWidget: FC<VotingWidgetProps> = ({ proposalId, amountOfVotes, downvoteAllowed, onVote }) => {
const { charge } = useContestStore(state => state);
const isMobile = useMediaQuery({ query: "(max-width: 768px)" });
const asPath = usePathname();
const { chainId: accountChainId } = useAccount();
const { chainName } = extractPathSegments(asPath ?? "");
Expand All @@ -33,7 +36,7 @@ const VotingWidget: FC<VotingWidgetProps> = ({ proposalId, amountOfVotes, downvo
const [isFocused, setIsFocused] = useState(true);
const voteDisabled = isLoading || amount === 0 || isInvalid || isNaN(amount);
const chainId = chains.filter(
(chain: { name: string }) => chain.name.toLowerCase().replace(" ", "") === chainName,
(chain: { name: string }) => chain.name.toLowerCase().replace(" ", "") === chainName.toLowerCase(),
)?.[0]?.id;
const isCorrectNetwork = chainId === accountChainId;
const { contestState } = useContestStateStore(state => state);
Expand Down Expand Up @@ -105,20 +108,42 @@ const VotingWidget: FC<VotingWidgetProps> = ({ proposalId, amountOfVotes, downvo
}
};

const handleVote = () => {
if (isCorrectNetwork) {
onVote?.(amount, isUpvote);
} else {
onSwitchNetwork();
const handleVote = async () => {
if (!isCorrectNetwork) {
await switchChain(config, { chainId });
}
};

const onSwitchNetwork = async () => {
await switchChain(config, { chainId });
onVote?.(amount, isUpvote);
};

if (isContestCanceled) return null;

if (isMobile) {
return (
<VotingWidgetMobile
amount={amount}
inputRef={inputRef}
sliderValue={sliderValue}
isUpvote={isUpvote}
handleVote={handleVote}
chainId={chainId}
charge={charge}
amountOfVotes={amountOfVotes}
downvoteAllowed={downvoteAllowed ?? false}
isFocused={isFocused}
setIsFocused={setIsFocused}
isInvalid={isInvalid}
voteDisabled={voteDisabled}
handleClick={handleClick}
handleSliderChange={handleSliderChange}
handleChange={handleChange}
handleKeyDownSlider={handleKeyDownSlider}
handleKeyDownInput={handleKeyDownInput}
handleInput={handleInput}
/>
);
}

return (
<div className="flex flex-col gap-8">
<div className="flex flex-col gap-4">
Expand All @@ -142,57 +167,50 @@ const VotingWidget: FC<VotingWidgetProps> = ({ proposalId, amountOfVotes, downvo
</div>
</div>
) : null}
<div className="flex flex-col gap-6">
<div className="flex flex-col gap-2">
<MyVotes amountOfVotes={amountOfVotes} charge={charge} chainId={chainId} />
{charge ? <ChargeInfo charge={charge} /> : null}
</div>
<div
className={`relative flex w-full md:w-80 h-16 items-center px-8 text-[16px] bg-transparent font-bold ${
isInvalid ? "text-negative-11" : "text-neutral-11"
} border-2 ${isFocused && !isInvalid ? "border-neutral-11" : isInvalid ? "border-negative-11" : "border-neutral-10"} rounded-[40px] transition-colors duration-300`}
>
<input
ref={inputRef}
type="number"
value={amount || ""}
onChange={e => handleChange(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
placeholder="0.00"
max={amountOfVotes}
onKeyDown={handleKeyDownInput}
onInput={handleInput}
className="w-full text-[32px] bg-transparent outline-none placeholder-primary-5"
/>
<span className="absolute right-4 text-neutral-9 text-[16px] font-bold">vote{amount !== 1 ? "s" : ""}</span>
<div className="flex flex-col gap-12">
<div className="flex flex-col gap-6">
<div
className={`relative flex w-full md:w-80 h-16 items-center px-8 text-[16px] bg-transparent font-bold ${
isInvalid ? "text-negative-11" : "text-neutral-11"
} border-2 ${isFocused && !isInvalid ? "border-neutral-11" : isInvalid ? "border-negative-11" : "border-neutral-10"} rounded-[40px] transition-colors duration-300`}
>
<input
ref={inputRef}
type="number"
value={amount || ""}
onChange={e => handleChange(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
placeholder="0.00"
max={amountOfVotes}
onKeyDown={handleKeyDownInput}
onInput={handleInput}
className="w-full text-[32px] bg-transparent outline-none placeholder-primary-5"
/>
<span className="absolute right-4 text-neutral-9 text-[16px] font-bold">
vote{amount !== 1 ? "s" : ""}
</span>
</div>
<StepSlider val={sliderValue} onChange={handleSliderChange} onKeyDown={handleKeyDownSlider} />
</div>
<div className="flex flex-col gap-4">
<StepSlider val={sliderValue} onChange={handleSliderChange} onKeyDown={handleKeyDownSlider} />
<div className="flex flex-col gap-2">
<MyVotes amountOfVotes={amountOfVotes} charge={charge} chainId={chainId} />
{charge ? <ChargeInfo charge={charge} /> : null}
</div>
{charge ? <TotalCharge charge={charge} amountOfVotes={amount} /> : null}
</div>
<ButtonV3
type={ButtonType.TX_ACTION}
isDisabled={voteDisabled}
colorClass="px-[20px] bg-gradient-purple rounded-[40px] w-full"
size={ButtonSize.FULL}
onClick={handleVote}
>
<span className="w-full text-center">add votes to entry</span>
</ButtonV3>
</div>
</div>
{isCorrectNetwork ? (
<ButtonV3
type={ButtonType.TX_ACTION}
isDisabled={voteDisabled}
colorClass="px-[20px] bg-gradient-purple rounded-[40px] w-full"
size={ButtonSize.FULL}
onClick={() => onVote?.(amount, isUpvote)}
>
<span className="w-full text-center">add votes to entry</span>
</ButtonV3>
) : (
<ButtonV3
type={ButtonType.TX_ACTION}
colorClass="flex items-center justify-center bg-gradient-vote rounded-[40px] w-full"
size={ButtonSize.FULL}
onClick={onSwitchNetwork}
>
switch network
</ButtonV3>
)}
</div>
);
};
Expand Down
Loading

0 comments on commit 44c7b86

Please sign in to comment.