Skip to content

Commit

Permalink
update ui
Browse files Browse the repository at this point in the history
  • Loading branch information
yimingWOW committed Jan 13, 2025
1 parent 62654d6 commit e07169f
Show file tree
Hide file tree
Showing 26 changed files with 1,979 additions and 1,159 deletions.
2 changes: 1 addition & 1 deletion Anchor.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ resolution = true
skip-lint = false

[programs.localnet]
fall = "BmzRwgDaqP6cSLoA2u2A7NysVF8nbbw8xRomRUc3DTt2"
fall = "C8sj5h7nejVHeyWvq6aCwrFWY5Q5QGuZDPqVwVHPxNLm"

[registry]
url = "https://api.apr.dev"
Expand Down
33 changes: 22 additions & 11 deletions app/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
// src/App.tsx
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui';
import { useWallet } from '@solana/wallet-adapter-react';
import { FC } from 'react';
import Dashboard from './components/Dashboard';
import './index.css';
import '@solana/wallet-adapter-react-ui/styles.css';
import { NetworkSelect } from './WalletContextProvider';
import { useNetwork } from './contexts/NetworkContext';
import '@solana/wallet-adapter-react-ui/styles.css';
import './style/App.css';

const App: FC = () => {
const { connected } = useWallet();
const { network, setNetwork } = useNetwork();

return (
<div className="container">
<nav className="navbar">
<div className="navbar-content">
<NetworkSelect onChange={setNetwork} value={network} />
<WalletMultiButton />
<div className="app-container">
<nav className="app-nav">
<div className="nav-content">
<div className="nav-left">
<h1 className="app-title">Fall</h1>
</div>
<div className="nav-right">
<NetworkSelect
onChange={setNetwork}
value={network}
/>
<WalletMultiButton className="wallet-button" />
</div>
</div>
</nav>

<main className="main-content">
<main className="app-main">
{!connected ? (
<div className="connect-prompt">
<h2>Please connect your wallet to continue</h2>
<div className="connect-wallet">
<div className="connect-card">
<span className="connect-icon">🌟</span>
<h2>Welcome to Fall</h2>
<p>Please connect your wallet to continue</p>
</div>
</div>
) : (
<Dashboard />
Expand Down
4 changes: 2 additions & 2 deletions app/src/WalletContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { WalletModalProvider } from '@solana/wallet-adapter-react-ui';
import { PhantomWalletAdapter } from '@solana/wallet-adapter-wallets';
import { clusterApiUrl } from '@solana/web3.js';
import { NetworkContext } from './contexts/NetworkContext';
import './index.css';
import './style/index.css';

export type Cluster = 'mainnet-beta' | 'testnet' | 'devnet' | 'localnet';

Expand All @@ -23,8 +23,8 @@ export const NetworkSelect: FC<{ onChange: (cluster: Cluster) => void, value: Cl
value={value}
className="solana-network-select"
>
<option value="localnet">Localnet</option>
<option value="devnet">Devnet</option>
<option value="localnet">Localnet</option>
<option value="testnet">Testnet</option>
<option value="mainnet-beta">Mainnet</option>
</select>
Expand Down
112 changes: 67 additions & 45 deletions app/src/components/BorrowerPoolList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,77 +3,99 @@ import { useAnchorWallet, useConnection } from '@solana/wallet-adapter-react';
import { getPoolList } from '../utils/getPoolList';
import { PoolInfo } from '../utils/getPoolList';
import { BorrowerPoolItem } from './BorrowerPoolItem';
import '../style/PoolList.css';

export const BorrowerPoolList: FC = () => {
const wallet = useAnchorWallet();
const { connection } = useConnection();
const [pools, setPools] = useState<PoolInfo[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string>("");
const [lastTxSignature, setLastTxSignature] = useState<string>("");
const [isLoading, setIsLoading] = useState(true);
const [selectedPool, setSelectedPool] = useState<PoolInfo | null>(null);
const [lastTxSignature, setLastTxSignature] = useState<string>('');

const fetchPools = async () => {
if (!wallet) return;

setIsLoading(true);
try {
const pools = await getPoolList(wallet, connection);
setPools(pools);
} catch (err) {
console.error("Error fetching pools:", err);
setError(err instanceof Error ? err.message : "Failed to fetch pools");
setIsLoading(true);
if (!wallet) return;
const poolList = await getPoolList(wallet, connection);
setPools(poolList);
} catch (error) {
console.error('Error fetching pools:', error);
} finally {
setIsLoading(false);
}
};

useEffect(() => {
fetchPools();
}, [wallet, connection]);
}, [connection, wallet, lastTxSignature]);

const handleTxSuccess = (signature: string) => {
setLastTxSignature(signature);
fetchPools();
};
if (isLoading) {
return (
<div className="pool-list-loading">
<div className="loading-spinner"></div>
<p>Loading pools...</p>
</div>
);
}

if (selectedPool) {
return (
<div className="pool-detail-view">
<button
className="back-button"
onClick={() => setSelectedPool(null)}
>
← Back to Pool List
</button>
<BorrowerPoolItem
pool={selectedPool}
onTxSuccess={(signature) => {
setLastTxSignature(signature);
fetchPools();
}}
/>
</div>
);
}

return (
<div className="pool-list-container">
<h2>Liquidity Pools</h2>
{error && (
<div className="error-message">
{error}
</div>
)}
{lastTxSignature && (
<div className="success-message">
Transaction successful!
<a
href={`https://explorer.solana.com/tx/${lastTxSignature}`}
target="_blank"
rel="noopener noreferrer"
>
View on Explorer
</a>
</div>
)}
{isLoading ? (
<div className="loading">Loading pools...</div>
) : pools.length === 0 ? (
<div className="empty-state">
<p>No pools found</p>
<h2 className="pool-list-title">Available Borrowing Pools</h2>
{pools.length === 0 ? (
<div className="no-pools-message">
No pools available
</div>
) : (
<div className="pool-list">
{pools.map((pool) => (
<BorrowerPoolItem
// key={pool.pubkey}
pool={pool}
onTxSuccess={handleTxSuccess}
/>
<div
key={pool.pubkey.toString()}
className="pool-list-item"
onClick={() => setSelectedPool(pool)}
>
<div className="pool-tokens">
<div className="token-info">
<span className="token-label">Token A:</span>
<span className="token-address" title={pool.mintA.toString()}>
{pool.mintA.toString().slice(0, 4)}...{pool.mintA.toString().slice(-4)}
</span>
</div>
<div className="token-separator"></div>
<div className="token-info">
<span className="token-label">Token B:</span>
<span className="token-address" title={pool.mintB.toString()}>
{pool.mintB.toString().slice(0, 4)}...{pool.mintB.toString().slice(-4)}
</span>
</div>
</div>
<div className="pool-view-details">
View Details →
</div>
</div>
))}
</div>
)}

</div>
);
};
65 changes: 65 additions & 0 deletions app/src/components/CheckCreditPoolForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { FC, useState, useEffect } from 'react';
import { useConnection } from '@solana/wallet-adapter-react';
import { checkCreditPool } from '../utils/checkCreditPool';
import { useAnchorWallet } from '@solana/wallet-adapter-react';
import { PublicKey } from '@solana/web3.js';
import { PoolInfo } from '../utils/getPoolList';
import { InitPoolForm } from './InitPoolForm';

interface CheckCreditPoolFormProps {
pool: PoolInfo;
}

export const CheckCreditPoolForm: FC<CheckCreditPoolFormProps> = ({ pool }) => {
const wallet = useAnchorWallet();
const { connection } = useConnection();
const [isCreditPool, setIsCreditPool] = useState(false);
const [showInitForm, setShowInitForm] = useState(false);

useEffect(() => {
const checkPool = async () => {
try {
if (!wallet) return;

const poolPubkey = new PublicKey(pool.pubkey);
const isCredit = await checkCreditPool(
wallet,
connection,
poolPubkey,
pool.mintA
);

setIsCreditPool(isCredit.isCreditPoolInitialized);
} catch (error) {
console.error('Error checking credit pool:', error);
}
};

checkPool();
}, [connection, pool, wallet]);

if (!isCreditPool) {
return (
<div className="init-pool-section">
<button
className="action-button"
onClick={() => setShowInitForm(!showInitForm)}
>
{showInitForm ? 'Hide Init Pool' : 'Init Pool'}
</button>

{showInitForm && (
<InitPoolForm
pool={pool}
onSuccess={() => {
setShowInitForm(false);
setIsCreditPool(true);
}}
/>
)}
</div>
);
}

return null;
};
43 changes: 34 additions & 9 deletions app/src/components/CreatePoolForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@ import { FC, useState } from 'react';
import { useAnchorWallet, useConnection } from '@solana/wallet-adapter-react';
import { PublicKey } from '@solana/web3.js';
import { createPool } from '../utils/createPool';
import { useAmm } from '../contexts/AmmContext'; // 导入 useAmm
import { useAmm } from '../contexts/AmmContext';
import '../style/CreatePoolForm.css';

export const PoolCreateForm: FC = () => {
export const CreatePoolForm: FC = () => {
const wallet = useAnchorWallet();
const { connection } = useConnection();
const { amm } = useAmm(); // 从上下文中获取 amm
const { amm } = useAmm();
const [error, setError] = useState<string>("");
const [isLoading, setIsLoading] = useState(false);
const [lastTxSignature, setLastTxSignature] = useState<string>("");
const [showForm, setShowForm] = useState(false);
const [formData, setFormData] = useState({
mintA: '',
mintB: '',
fee: '500',
});

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError("");
Expand All @@ -35,7 +38,6 @@ export const PoolCreateForm: FC = () => {
}

try {
// 验证输入的公钥格式
const ammPubkey = new PublicKey(amm.pubkey);
const mintAPubkey = new PublicKey(formData.mintA);
const mintBPubkey = new PublicKey(formData.mintB);
Expand All @@ -49,9 +51,9 @@ export const PoolCreateForm: FC = () => {
Number(formData.fee)
);

console.log(`Transaction URL: https://explorer.solana.com/tx/${signature}`);
setLastTxSignature(signature.toString());
setFormData({ mintA: '', mintB: '', fee: '500' }); // 重置表单
setFormData({ mintA: '', mintB: '', fee: '500' });
setShowForm(false);
} catch (err) {
console.error("Error creating pool:", err);
setError(err instanceof Error ? err.message : "Failed to create pool");
Expand All @@ -60,10 +62,33 @@ export const PoolCreateForm: FC = () => {
}
};

if (!showForm) {
return (
<div className="create-pool-button-wrapper">
<button
className="create-pool-button"
onClick={() => setShowForm(true)}
>
<div className="button-content">
<span className="plus-icon">+</span>
<span className="button-text">Create Pool</span>
</div>
</button>
</div>
);
}

return (
<div>
<div className="create-amm-container">
<h2>Create Pool</h2>
<div className="create-pool-form-container">
<button
className="back-button"
onClick={() => setShowForm(false)}
>
← Back to Pool List
</button>

<div className="create-pool-form">
<h2 className="form-title">Create New Pool</h2>
{error && (
<div className="error-message">
{error}
Expand Down
Loading

0 comments on commit e07169f

Please sign in to comment.