Skip to content

Commit

Permalink
Merge pull request #35 from Laina-Protocol/feat/deposit-amount-modal
Browse files Browse the repository at this point in the history
Feat: Deposit modal
  • Loading branch information
kovipu authored Sep 12, 2024
2 parents 73efaaa + 4b91e27 commit 088b94f
Show file tree
Hide file tree
Showing 11 changed files with 277 additions and 34 deletions.
74 changes: 71 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
"devDependencies": {
"@biomejs/biome": "1.8.3",
"@vitejs/plugin-basic-ssl": "^1.1.0",
"daisyui": "^4.12.10",
"dotenv": "^16.4.5",
"postcss": "^8.4.45",
"prettier": "^3.3.3",
"prettier-plugin-astro": "^0.14.1"
},
Expand Down
4 changes: 2 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ const PageWrapper = () => {
const isIndex = pathname === '/';

return (
<body className={`font-sans flex flex-col min-h-screen ${isIndex ? 'bg-white' : 'bg-grey-light'}`}>
<div className="min-h-screen flex flex-col">
<Nav />
<main className={`max-w-screen flex-1 ${isIndex ? 'w-[74rem]' : 'w-256'}`}>
<Outlet />
</main>
<Footer />
</body>
</div>
);
};

Expand Down
9 changes: 5 additions & 4 deletions src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import type { PropsWithChildren } from 'react';
import { Link } from 'react-router-dom';

export interface ButtonProps {
onClick: () => void;
onClick?: () => void;
className?: string;
disabled?: boolean;
}

const buttonStyle = 'bg-black font-semibold text-white rounded-full px-8 py-2 hover:bg-grey-dark transition';
const buttonStyle = 'btn btn-neutral font-semibold text-base rounded-full px-8 py-2';

export const Button = ({ onClick, className = '', children }: PropsWithChildren<ButtonProps>) => (
<button type="button" onClick={onClick} className={`${buttonStyle} ${className}`}>
export const Button = ({ onClick, disabled = false, className = '', children }: PropsWithChildren<ButtonProps>) => (
<button type="button" onClick={onClick} disabled={disabled} className={`${buttonStyle} ${className}`}>
{children}
</button>
);
Expand Down
5 changes: 3 additions & 2 deletions src/currencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import XLMPoolContract from '@contracts/loan_pool';
import USDCPoolContract from '@contracts/usdc_pool';
import StellarIcon from '@images/Stellar_Symbol.png';
import USDCIcon from '@images/usdc.svg';
import type { SupportedCurrency } from './stellar-wallet';

export type Currency = {
name: string;
symbol: string; // could be a type union of currency symbols.
symbol: SupportedCurrency;
icon: string;
loanPoolContract: typeof XLMPoolContract;
};
Expand All @@ -23,4 +24,4 @@ export const CURRENCIES: Currency[] = [
icon: USDCIcon.src,
loanPoolContract: USDCPoolContract,
},
];
] as const;
8 changes: 4 additions & 4 deletions src/layouts/Layout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const { title, description } = Astro.props;
---

<!doctype html>
<html lang="en">
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8" />
<meta name="description" content={description} />
Expand All @@ -21,7 +21,9 @@ const { title, description } = Astro.props;
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
</head>
<slot />
<body class="font-sans bg-white">
<slot />
</body>
<style is:global>
html {
font-family: system-ui, sans-serif;
Expand Down Expand Up @@ -58,6 +60,4 @@ const { title, description } = Astro.props;
width: 1px;
}
</style>


</html>
6 changes: 6 additions & 0 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';

export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
107 changes: 107 additions & 0 deletions src/pages/_lend/DepositModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { Button } from '@components/Button';
import { type ChangeEvent, useState } from 'react';
import type { Currency } from 'src/currencies';
import { useWallet } from 'src/stellar-wallet';

export interface DepositModalProps {
modalId: string;
onClose: () => void;
currency: Currency;
}

export const DepositModal = ({ modalId, onClose, currency }: DepositModalProps) => {
const { loanPoolContract, name, symbol } = currency;

const { wallet, balances, signTransaction } = useWallet();
const [isDepositing, setIsDepositing] = useState(false);
const [amount, setAmount] = useState('0');

const balance = balances[symbol];

if (!balance) return null;

const handleDepositClick = async () => {
if (!wallet) {
alert('Please connect your wallet first!');
return;
}

setIsDepositing(true);

loanPoolContract.options.publicKey = wallet.address;

// Multiply by ten million by adding zeroes.
const stroops = BigInt(amount) * BigInt(10_000_000);

const tx = await loanPoolContract.deposit({
user: wallet.address,
amount: stroops,
});

try {
const { result } = await tx.signAndSend({ signTransaction });
alert(`Deposit successful, result: ${result}`);
onClose();
} catch (err) {
alert(`Error depositing: ${JSON.stringify(err)}`);
}
setIsDepositing(false);
};

const handleAmountChange = (ev: ChangeEvent<HTMLInputElement>) => {
setAmount(ev.target.value);
};

return (
<dialog id={modalId} className="modal">
<div className="modal-box">
<h3 className="font-bold text-lg mb-8">Deposit {name}</h3>

<div className="flex flex-row items-center">
<div className="w-full">
<p className="text-lg mb-2">Amount to deposit</p>
<input
type="range"
min={0}
max={balance.balance}
value={amount}
className="range"
onChange={handleAmountChange}
/>
<div className="flex w-full justify-between px-2 text-xs">
<span>|</span>
<span>|</span>
<span>|</span>
<span>|</span>
<span>|</span>
</div>
</div>
</div>

<p>
{amount} {symbol} out of {balance.balance} {symbol}
</p>

<div className="flex flex-row justify-end mt-8">
<Button onClick={onClose} className="btn-ghost mr-4">
Cancel
</Button>
{!isDepositing ? (
<Button disabled={amount === '0'} onClick={handleDepositClick}>
Deposit
</Button>
) : (
<Button disabled>
<span className="loading loading-spinner" />
Depositing
</Button>
)}
</div>
</div>
{/* Invisible backdrop that closes the modal on click */}
<form method="dialog" className="modal-backdrop">
<button type="button">close</button>
</form>
</dialog>
);
};
Loading

0 comments on commit 088b94f

Please sign in to comment.