diff --git a/src/app/page.tsx b/src/app/page.tsx
index 1733b41..b1fa23f 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -183,6 +183,12 @@ export default async function HomePage() {
Your top positions
+
+ View all →
+
{holdings.biggestGain && (
diff --git a/src/app/profile/[username]/page.tsx b/src/app/profile/[username]/page.tsx
index 71bd680..eeca647 100644
--- a/src/app/profile/[username]/page.tsx
+++ b/src/app/profile/[username]/page.tsx
@@ -187,6 +187,37 @@ export default async function ProfilePage({ params }: Props) {
)}
+ {/* Funds managed — only shown to the profile owner */}
+ {isOwn && user.managedFunds.length > 0 && (
+
+
+
+ Funds you manage
+
+
+
+ {user.managedFunds.map(({ fund }) => (
+
+
+
+ {fund.name}
+
+
+ Trade as this fund →
+
+
+ ))}
+
+
+
+ )}
+
{/* Positions */}
{user.positions.length > 0 && (
@@ -240,37 +271,6 @@ export default async function ProfilePage({ params }: Props) {
)}
- {/* Funds managed — only shown to the profile owner */}
- {isOwn && user.managedFunds.length > 0 && (
-
-
-
- Funds you manage
-
-
-
- {user.managedFunds.map(({ fund }) => (
-
-
-
- {fund.name}
-
-
- Trade as this fund →
-
-
- ))}
-
-
-
- )}
-
{/* Trade history */}
{user.trades.length > 0 && (
diff --git a/src/app/trades/page.tsx b/src/app/trades/page.tsx
index d10249e..150fed2 100644
--- a/src/app/trades/page.tsx
+++ b/src/app/trades/page.tsx
@@ -15,15 +15,23 @@ interface PageProps {
export default async function GlobalTradesPage({ searchParams }: PageProps) {
const page = Math.max(1, parseInt(searchParams.page ?? '1', 10))
+ const tradeWhere = {
+ OR: [
+ { hashtagId: { not: null }, type: { not: 'LOTTERY_WIN' } },
+ { type: { in: ['FUND_INVEST', 'FUND_REDEEM'] } },
+ ],
+ } as const
+
const [total, trades] = await Promise.all([
- prisma.trade.count({ where: { hashtagId: { not: null }, type: { not: 'LOTTERY_WIN' } } }),
+ prisma.trade.count({ where: tradeWhere }),
prisma.trade.findMany({
- where: { hashtagId: { not: null }, type: { not: 'LOTTERY_WIN' } },
+ where: tradeWhere,
orderBy: { createdAt: 'desc' },
take: PAGE_SIZE,
skip: (page - 1) * PAGE_SIZE,
include: {
hashtag: { select: { tag: true, displayTag: true } },
+ fund: { select: { name: true, slug: true } },
user: { select: { username: true, displayUsername: true, isFund: true } },
},
}),
@@ -49,19 +57,34 @@ export default async function GlobalTradesPage({ searchParams }: PageProps) {
className={`text-xs font-medium px-2 py-0.5 rounded shrink-0 ${
(t.type === 'LIQUIDATE_LONG' || t.type === 'LIQUIDATE_SHORT')
? 'bg-orange-500/15 text-orange-400'
- : t.type.startsWith('BUY')
- ? 'bg-emerald-500/15 text-emerald-400'
- : 'bg-red-500/15 text-red-400'
+ : (t.type === 'FUND_INVEST' || t.type === 'FUND_REDEEM')
+ ? 'bg-indigo-500/15 text-indigo-400'
+ : t.type.startsWith('BUY')
+ ? 'bg-emerald-500/15 text-emerald-400'
+ : 'bg-red-500/15 text-red-400'
}`}
>
- {(t.type === 'LIQUIDATE_LONG' || t.type === 'LIQUIDATE_SHORT') ? 'LIQUIDATED' : t.type.replace('_', ' ')}
+ {(t.type === 'LIQUIDATE_LONG' || t.type === 'LIQUIDATE_SHORT') ? 'LIQUIDATED' : t.type.replace(/_/g, ' ')}
-
- #{t.hashtag!.displayTag}
-
+ {(t.type === 'FUND_INVEST' || t.type === 'FUND_REDEEM') ? (
+ t.fund ? (
+
+ {t.fund.name}
+
+ ) : (
+ Deleted Fund
+ )
+ ) : (
+
+ #{t.hashtag!.displayTag}
+
+ )}
{formatCurrency(t.total)}
{/* Secondary row: user · time (left) shares @ price (right) */}
@@ -79,8 +102,8 @@ export default async function GlobalTradesPage({ searchParams }: PageProps) {
{formatNumber(t.shares)} sh @ {formatCurrency(t.price)}
- {/* PnL: sell and liquidation trades */}
- {(t.type === 'SELL_LONG' || t.type === 'SELL_SHORT' || t.type === 'LIQUIDATE_LONG' || t.type === 'LIQUIDATE_SHORT') && (
+ {/* PnL: sell, liquidation, and fund redeem trades */}
+ {(t.type === 'SELL_LONG' || t.type === 'SELL_SHORT' || t.type === 'LIQUIDATE_LONG' || t.type === 'LIQUIDATE_SHORT' || t.type === 'FUND_REDEEM') && (
{formatPnl(t.profit)}
)}