Skip to content

Commit a1a3355

Browse files
committed
feat: implemented sharable link with prefilled deposit amout
1 parent e28c4f8 commit a1a3355

3 files changed

Lines changed: 86 additions & 8 deletions

File tree

frontend/src/components/VaultDashboard.tsx

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
import React, { useEffect, useState } from "react";
2-
import { Activity, AlertCircle, ShieldCheck, TrendingUp, Wallet as WalletIcon, Loader2, Info } from "./icons";
2+
import { useSearchParams } from "react-router-dom";
3+
import {
4+
Activity,
5+
AlertCircle,
6+
ShieldCheck,
7+
TrendingUp,
8+
Wallet as WalletIcon,
9+
Loader2,
10+
Info,
11+
Share2
12+
} from "./icons";
313
import Skeleton from "./Skeleton";
414
import { useVault } from "../context/VaultContext";
515
import ApiStatusBanner from "./ApiStatusBanner";
616
import VaultPerformanceChart from "./VaultPerformanceChart";
717
import { useToast } from "../context/ToastContext";
818
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./Tabs";
9-
import { FormField } from "../forms";
10-
import WithdrawalConfirmationModal from "./WithdrawalConfirmationModal";
1119
import { FormField, SubmitButton } from "../forms";
20+
import WithdrawalConfirmationModal from "./WithdrawalConfirmationModal";
1221
import { useDepositMutation, useWithdrawMutation } from "../hooks/useVaultMutations";
1322
import TransactionStatus, { type ActionStatus } from "./TransactionStatus";
1423
import CopyButton from "./CopyButton";
15-
import {
16-
useDepositMutation,
17-
useWithdrawMutation,
18-
} from "../hooks/useVaultMutations";
24+
import { copyTextToClipboard } from "../lib/clipboard";
1925

2026
interface VaultDashboardProps {
2127
walletAddress: string | null;
@@ -145,6 +151,19 @@ const VaultDashboard: React.FC<VaultDashboardProps> = ({
145151
const depositMutation = useDepositMutation();
146152
const withdrawMutation = useWithdrawMutation();
147153

154+
const [searchParams] = useSearchParams();
155+
156+
useEffect(() => {
157+
const amountParam = searchParams.get("amount");
158+
if (amountParam) {
159+
const val = Number(amountParam);
160+
if (!Number.isNaN(val) && val > 0) {
161+
setAmount(val.toString());
162+
setActiveTab("deposit");
163+
}
164+
}
165+
}, [searchParams]);
166+
148167
useEffect(() => {
149168
const handleTrigger = () => {
150169
setActiveTab("deposit");
@@ -547,7 +566,41 @@ const VaultDashboard: React.FC<VaultDashboardProps> = ({
547566
/>
548567

549568
<div className="flex justify-between items-center" style={{ margin: "16px 0 24px" }}>
550-
<span style={{ color: "var(--text-secondary)", fontSize: "0.85rem" }}>Asset: USDC</span>
569+
<div className="flex items-center gap-sm">
570+
<span style={{ color: "var(--text-secondary)", fontSize: "0.85rem" }}>Asset: USDC</span>
571+
{tab === "deposit" && (
572+
<>
573+
<div style={{ width: "1px", height: "14px", background: "var(--border-glass)", margin: "0 4px" }} />
574+
<button
575+
type="button"
576+
className="btn-link flex items-center gap-xs"
577+
style={{ fontSize: "0.75rem", color: "var(--accent-cyan)", padding: 0 }}
578+
onClick={async () => {
579+
const baseUrl = window.location.origin + window.location.pathname;
580+
const shareUrl = amount && !isNaN(Number(amount)) && Number(amount) > 0
581+
? `${baseUrl}?amount=${amount}`
582+
: baseUrl;
583+
584+
try {
585+
await copyTextToClipboard(shareUrl);
586+
toast.success({
587+
title: "Link copied",
588+
description: "Shareable vault link is ready to paste."
589+
});
590+
} catch (err) {
591+
toast.error({
592+
title: "Copy failed",
593+
description: "Could not copy link to clipboard."
594+
});
595+
}
596+
}}
597+
>
598+
<Share2 size={12} />
599+
Share Link
600+
</button>
601+
</>
602+
)}
603+
</div>
551604
<button
552605
type="button"
553606
className="btn-max"

frontend/src/components/icons.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ export {
2020
DollarSign,
2121
Percent,
2222
Briefcase,
23+
Share2,
24+
Link,
2325
} from "lucide-react";

frontend/src/index.css

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,29 @@ button {
594594
border-color: rgba(255, 255, 255, 0.2);
595595
}
596596

597+
.btn-link {
598+
background: none;
599+
border: none;
600+
padding: 0;
601+
color: var(--accent-cyan);
602+
cursor: pointer;
603+
display: inline-flex;
604+
align-items: center;
605+
gap: 4px;
606+
transition: opacity 0.2s, color 0.2s;
607+
min-height: auto;
608+
min-width: auto;
609+
}
610+
611+
.btn-link:hover {
612+
opacity: 0.8;
613+
text-decoration: underline;
614+
}
615+
616+
.btn-link:active {
617+
transform: scale(0.98);
618+
}
619+
597620
/* Animations */
598621
@keyframes puiseGlow {
599622
0% { box-shadow: 0 0 20px rgba(0, 240, 255, 0.1); }

0 commit comments

Comments
 (0)