feat: add CoinIcon component for displaying cryptocurrency icons

feat: implement TradeModal for buying and selling coins with validation and transaction handling

feat: create server-side trade API for executing buy/sell transactions and updating user balances

feat: add transactions API to fetch user transaction history

feat: implement portfolio page to display user's holdings and recent transactions
This commit is contained in:
Face 2025-05-23 19:48:23 +03:00
parent 0784e0f3d3
commit a278d0c6a5
13 changed files with 1342 additions and 210 deletions

View file

@ -5,9 +5,7 @@ import { user, userPortfolio, coin } from '$lib/server/db/schema';
import { eq } from 'drizzle-orm';
export async function GET({ request }) {
const session = await auth.api.getSession({
headers: request.headers
});
const session = await auth.api.getSession({ headers: request.headers });
if (!session?.user) {
throw error(401, 'Not authenticated');
@ -15,27 +13,30 @@ export async function GET({ request }) {
const userId = Number(session.user.id);
const [userData] = await db
.select({ baseCurrencyBalance: user.baseCurrencyBalance })
.from(user)
.where(eq(user.id, userId))
.limit(1);
const [userData, holdings] = await Promise.all([
db.select({ baseCurrencyBalance: user.baseCurrencyBalance })
.from(user)
.where(eq(user.id, userId))
.limit(1),
if (!userData) {
db.select({
quantity: userPortfolio.quantity,
currentPrice: coin.currentPrice,
symbol: coin.symbol,
icon: coin.icon,
change24h: coin.change24h
})
.from(userPortfolio)
.innerJoin(coin, eq(userPortfolio.coinId, coin.id))
.where(eq(userPortfolio.userId, userId))
]);
if (!userData[0]) {
throw error(404, 'User not found');
}
const holdings = await db
.select({
quantity: userPortfolio.quantity,
currentPrice: coin.currentPrice,
symbol: coin.symbol
})
.from(userPortfolio)
.innerJoin(coin, eq(userPortfolio.coinId, coin.id))
.where(eq(userPortfolio.userId, userId));
let totalCoinValue = 0;
const coinHoldings = holdings.map(holding => {
const quantity = Number(holding.quantity);
const price = Number(holding.currentPrice);
@ -44,13 +45,15 @@ export async function GET({ request }) {
return {
symbol: holding.symbol,
icon: holding.icon,
quantity,
currentPrice: price,
value
value,
change24h: Number(holding.change24h)
};
});
const baseCurrencyBalance = Number(userData.baseCurrencyBalance);
const baseCurrencyBalance = Number(userData[0].baseCurrencyBalance);
return json({
baseCurrencyBalance,