Skip to content

Commit c43f326

Browse files
authored
Merge pull request #1290 from dacadeorg/refactor/wallet-component
refactor: split wallet component into different components
2 parents 23b4dc4 + b9be9b4 commit c43f326

File tree

8 files changed

+243
-155
lines changed

8 files changed

+243
-155
lines changed

check_branch_name.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ local_branch_name="$(git rev-parse --abbrev-ref HEAD)"
66
# - ^(dev|main)$)
77
# 2. checking for branch Name starting with fix,ft,ht,chore or doc follwed by a "/" then the "branch name"
88
# - ^((fix|ft|ht|chore|doc)\/[a-zA-Z0-9\-]+)$
9-
valid_branch_regex='^(dev|main)$|^((fix|ft|ht|chore|doc|test)\/[a-zA-Z0-9\-]+)$'
9+
valid_branch_regex='^(dev|main)$|^((fix|ft|ht|chore|doc|test|refactor)\/[a-zA-Z0-9\-]+)$'
1010

1111
green='\033[0;32m'
1212
red='\033[0;31m'

src/components/cards/Wallet.tsx

Lines changed: 0 additions & 153 deletions
This file was deleted.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { useTranslation } from "next-i18next";
2+
import { ReactElement, useMemo } from "react";
3+
interface AddressDisplayProps {
4+
walletAddress: string;
5+
description: string;
6+
triggerEditAddress: () => void;
7+
}
8+
/**
9+
* Address display component
10+
*
11+
* @returns {ReactElement}
12+
*/
13+
export default function AddressDisplay({ walletAddress, description, triggerEditAddress }: AddressDisplayProps): ReactElement {
14+
const { t } = useTranslation();
15+
const address = useMemo(() => (walletAddress ? walletAddress.match(/.{1,4}/g) : null), [walletAddress]);
16+
return (
17+
<div className="text-sm text-gray-700">
18+
{address ? (
19+
<p className="leading-5 text-sm flex gap-x-2 gap-y-1 flex-wrap font-mono font-normal">
20+
{address.map((part, index) => (
21+
<span key={`address-${index}`} className="mr-2">
22+
{part}
23+
</span>
24+
))}
25+
</p>
26+
) : (
27+
<p>{description}</p>
28+
)}
29+
<div className="text-gray-700 text-sm mt-3">
30+
<span className="cursor-pointer hover:underline" onClick={triggerEditAddress}>
31+
{address ? t("profile.wallets.address-change") : t("profile.wallets.address-set")}
32+
</span>
33+
</div>
34+
</div>
35+
);
36+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import ArrowButton from "@/components/ui/button/Arrow";
2+
import { useTranslation } from "next-i18next";
3+
import { useDispatch } from "@/hooks/useTypedDispatch";
4+
import { setCurrentWallet } from "@/store/feature/user/wallets.slice";
5+
import { toggleBodyScrolling } from "@/store/feature/ui.slice";
6+
import { useSelector } from "@/hooks/useTypedSelector";
7+
import { openVerificationModal } from "@/store/feature/kyc.slice";
8+
import { Wallet } from "@/types/wallet";
9+
import { ReactElement, useCallback, useMemo } from "react";
10+
import AddressDisplay from "./AddressDisplay";
11+
12+
interface CashoutProps {
13+
wallet: Wallet;
14+
setShowEditModal: (show: boolean) => void;
15+
disabled: boolean;
16+
setShowPayoutModal: (show: boolean) => void;
17+
testId?: string;
18+
}
19+
20+
/**
21+
* Cashout address component
22+
*
23+
* @returns {ReactElement}
24+
*/
25+
export default function Cashout({ wallet, setShowEditModal, disabled, setShowPayoutModal, testId = "cashoutAddressId" }: CashoutProps): ReactElement {
26+
const { t } = useTranslation();
27+
const dispatch = useDispatch();
28+
const user = useSelector((state) => state.user.data);
29+
const isKycVerified = useMemo(() => user?.kycStatus === "VERIFIED", [user?.kycStatus]);
30+
const cashable = useMemo(() => String(wallet.token).toUpperCase() !== "DAC", [wallet.token]);
31+
32+
const triggerEditAddress = useCallback(() => {
33+
dispatch(setCurrentWallet(wallet));
34+
setShowEditModal(true);
35+
dispatch(toggleBodyScrolling(true));
36+
}, [dispatch, setShowEditModal, wallet]);
37+
38+
const triggerCashout = useCallback(() => {
39+
setShowPayoutModal(true);
40+
dispatch(toggleBodyScrolling(true));
41+
}, [setShowPayoutModal, dispatch]);
42+
43+
const triggerKYCVerification = useCallback(() => {
44+
dispatch(
45+
openVerificationModal({
46+
description: t("kyc.payout.reason"),
47+
completedActionText: t("kyc.payout.button.completed"),
48+
completedAction: () => {
49+
triggerCashout();
50+
},
51+
})
52+
);
53+
}, [dispatch, t, triggerCashout]);
54+
const cashout = () => {
55+
if (!isKycVerified) return triggerKYCVerification();
56+
triggerCashout();
57+
};
58+
return (
59+
<div className="px-7 pt-6 flex-1 pb-24 lg:pb-24" data-testid={testId}>
60+
{cashable ? (
61+
<AddressDisplay walletAddress={wallet.address} description={wallet.description} triggerEditAddress={triggerEditAddress} />
62+
) : (
63+
<div className="prose">
64+
<p
65+
dangerouslySetInnerHTML={{
66+
__html: t("profile.wallets.uncashable", {
67+
token: `${wallet.title}`,
68+
link: "https://discord.gg/5yDZvVnpQQ",
69+
}),
70+
}}
71+
/>
72+
</div>
73+
)}
74+
{cashable && (
75+
<div className="right-2 absolute bottom-2 mt-5">
76+
<ArrowButton disabled={!wallet.balance || !wallet.address || disabled} variant="outline-primary" minWidthClass="min-w-40" onClick={cashout}>
77+
{t("profile.wallets.cash-out")}
78+
</ArrowButton>
79+
</div>
80+
)}
81+
</div>
82+
);
83+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Wallet } from "@/types/wallet";
2+
import Currency from "@/components/ui/Currency";
3+
import Hint from "@/components/ui/Hint";
4+
import { useTranslation } from "next-i18next";
5+
import { ReactElement } from "react";
6+
7+
interface HintsProps {
8+
wallet: Wallet;
9+
}
10+
11+
/**
12+
* Wallet hint component
13+
*
14+
* @returns {ReactElement}
15+
*/
16+
17+
export default function Hints({ wallet }: HintsProps): ReactElement {
18+
const { t } = useTranslation();
19+
return (
20+
<>
21+
{wallet.payouts.map((payout, i) => (
22+
<Hint key={`wallet-payout-${i}`} className="mt-2">
23+
<span className="font-medium">
24+
<Currency value={payout.amount} token={payout.token} />
25+
</span>{" "}
26+
{t("profile.wallet.payout.text")}
27+
</Hint>
28+
))}
29+
</>
30+
);
31+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import Coin from "@/components/ui/Coin";
2+
import Tag from "@/components/ui/Tag";
3+
import Currency from "@/components/ui/Currency";
4+
import { Wallet } from "@/types/wallet";
5+
import { useTranslation } from "next-i18next";
6+
import { ReactElement } from "react";
7+
8+
interface OverviewProps {
9+
wallet: Wallet;
10+
testId?: string;
11+
}
12+
13+
/**
14+
* Wallet overview component
15+
*
16+
* @returns {ReactElement}
17+
*/
18+
export default function Overview({ wallet, testId = "overviewId" }: OverviewProps): ReactElement {
19+
const { t } = useTranslation();
20+
return (
21+
<div className="bg-secondary lg:w-60 md:w-60 sm:w-60 rounded-3.5xl" data-testid={testId}>
22+
<div className="p-6">
23+
<div className="border-b border-dotted border-gray-900">
24+
<h1 className="text-2xl">{wallet.title}</h1>
25+
<Tag value={wallet.token} />
26+
<div className="text-right mb-4">
27+
<Coin size="medium" token={wallet.token} />
28+
</div>
29+
</div>
30+
<div className="flex">
31+
<div className="w-1/2 pt-5 text-sm">
32+
<h1>{t("profile.wallets.balance")}</h1>
33+
</div>
34+
<div className="w-1/2 pt-3.5 text-right text-2xl font-medium">
35+
<h1>
36+
<Currency value={wallet.balance} />
37+
</h1>
38+
</div>
39+
</div>
40+
</div>
41+
</div>
42+
);
43+
}

0 commit comments

Comments
 (0)