Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f54a332345 | |||
| 039e2662f7 |
@@ -180,9 +180,9 @@ export default function AdminFundActions({ funds: initialFunds }: { funds: Fund[
|
||||
)}
|
||||
|
||||
{funds.map((fund) => (
|
||||
<div key={fund.id} className="bg-surface-card border border-surface-border rounded-xl overflow-hidden">
|
||||
<div key={fund.id} className="bg-surface-card border border-surface-border rounded-xl">
|
||||
<div
|
||||
className="flex items-center justify-between px-4 py-3 cursor-pointer hover:bg-surface/50 transition-colors"
|
||||
className="flex items-center justify-between px-4 py-3 cursor-pointer hover:bg-surface/50 transition-colors rounded-t-xl"
|
||||
onClick={() => setExpandedId(expandedId === fund.id ? null : fund.id)}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
|
||||
@@ -5,7 +5,7 @@ import { notFound } from 'next/navigation'
|
||||
import { formatCurrency, formatNumber, pnlColor, formatPnl } from '@/lib/utils'
|
||||
import { getBalanceTier } from '@/lib/pricing'
|
||||
import Link from 'next/link'
|
||||
import { TrendingUp, TrendingDown, Coins } from 'lucide-react'
|
||||
import { TrendingUp, TrendingDown, Coins, Building2 } from 'lucide-react'
|
||||
import ChangePasswordForm from './ChangePasswordForm'
|
||||
import AccountSettingsForm from './AccountSettingsForm'
|
||||
|
||||
@@ -38,6 +38,12 @@ export default async function ProfilePage({ params }: Props) {
|
||||
take: 30,
|
||||
include: { hashtag: { select: { tag: true, displayTag: true } } },
|
||||
},
|
||||
managedFunds: {
|
||||
orderBy: { addedAt: 'asc' },
|
||||
select: {
|
||||
fund: { select: { id: true, name: true, slug: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -174,6 +180,37 @@ export default async function ProfilePage({ params }: Props) {
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Funds managed — only shown to the profile owner */}
|
||||
{isOwn && user.managedFunds.length > 0 && (
|
||||
<section>
|
||||
<h2 className="text-lg font-semibold mb-4 flex items-center gap-2">
|
||||
<Building2 className="h-5 w-5 text-indigo-400" />
|
||||
Funds you manage
|
||||
</h2>
|
||||
<div className="bg-surface-card border border-surface-border rounded-xl overflow-hidden">
|
||||
<div className="divide-y divide-surface-border">
|
||||
{user.managedFunds.map(({ fund }) => (
|
||||
<div key={fund.id} className="flex items-center justify-between px-4 py-3">
|
||||
<Link
|
||||
href={`/fund/${fund.slug}`}
|
||||
className="font-medium hover:text-indigo-300 transition-colors flex items-center gap-2"
|
||||
>
|
||||
<Building2 className="h-3.5 w-3.5 text-indigo-400 shrink-0" />
|
||||
{fund.name}
|
||||
</Link>
|
||||
<Link
|
||||
href={`/stocks?fund=${fund.slug}`}
|
||||
className="text-xs text-indigo-400 hover:text-indigo-300 transition-colors"
|
||||
>
|
||||
Trade as this fund →
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Trade history */}
|
||||
{user.trades.length > 0 && (
|
||||
<section>
|
||||
|
||||
+25
-9
@@ -13,7 +13,7 @@ type SortField = 'price' | 'tag' | 'change' | 'updated'
|
||||
type SortDir = 'asc' | 'desc'
|
||||
|
||||
interface PageProps {
|
||||
searchParams: { page?: string; sort?: string; dir?: string; tab?: string }
|
||||
searchParams: { page?: string; sort?: string; dir?: string; tab?: string; fund?: string }
|
||||
}
|
||||
|
||||
function SortLink({
|
||||
@@ -22,19 +22,22 @@ function SortLink({
|
||||
currentSort,
|
||||
currentDir,
|
||||
page,
|
||||
fund,
|
||||
}: {
|
||||
field: SortField
|
||||
label: string
|
||||
currentSort: SortField
|
||||
currentDir: SortDir
|
||||
page: number
|
||||
fund?: string
|
||||
}) {
|
||||
const isActive = currentSort === field
|
||||
const nextDir: SortDir = isActive && currentDir === 'desc' ? 'asc' : 'desc'
|
||||
const Icon = isActive ? (currentDir === 'desc' ? ArrowDown : ArrowUp) : ArrowUpDown
|
||||
const fundParam = fund ? `&fund=${encodeURIComponent(fund)}` : ''
|
||||
return (
|
||||
<Link
|
||||
href={`/stocks?page=1&sort=${field}&dir=${nextDir}&tab=stocks`}
|
||||
href={`/stocks?page=1&sort=${field}&dir=${nextDir}&tab=stocks${fundParam}`}
|
||||
className={`flex items-center gap-1 hover:text-slate-200 transition-colors select-none ${isActive ? 'text-indigo-400' : 'text-slate-400'}`}
|
||||
>
|
||||
{label}
|
||||
@@ -45,6 +48,8 @@ function SortLink({
|
||||
|
||||
export default async function StocksPage({ searchParams }: PageProps) {
|
||||
const tab = searchParams.tab === 'funds' ? 'funds' : 'stocks'
|
||||
const fund = searchParams.fund ? decodeURIComponent(searchParams.fund) : undefined
|
||||
const fundParam = fund ? `&fund=${encodeURIComponent(fund)}` : ''
|
||||
const page = Math.max(1, parseInt(searchParams.page ?? '1', 10))
|
||||
const sort = (['price', 'tag', 'change', 'updated'].includes(searchParams.sort ?? '')
|
||||
? searchParams.sort
|
||||
@@ -224,20 +229,31 @@ export default async function StocksPage({ searchParams }: PageProps) {
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Fund mode banner */}
|
||||
{fund && (
|
||||
<div className="flex items-center justify-between gap-3 bg-indigo-500/10 border border-indigo-500/20 rounded-xl px-4 py-3 text-sm">
|
||||
<div className="flex items-center gap-2">
|
||||
<Building2 className="h-4 w-4 text-indigo-400 shrink-0" />
|
||||
<span className="text-indigo-200">Trading as <span className="font-semibold">{fund}</span> — click any hashtag to trade on behalf of this fund</span>
|
||||
</div>
|
||||
<Link href="/stocks" className="text-xs text-slate-400 hover:text-slate-200 shrink-0">Exit fund mode ×</Link>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{tab === 'stocks' && (<>
|
||||
<div className="bg-surface-card border border-surface-border rounded-xl overflow-hidden">
|
||||
{/* Column headers */}
|
||||
<div className="grid grid-cols-[2fr_1fr_1fr_1fr_1fr] gap-4 px-4 py-2.5 border-b border-surface-border text-xs font-medium">
|
||||
<SortLink field="tag" label="Hashtag" currentSort={sort} currentDir={dir} page={page} />
|
||||
<SortLink field="tag" label="Hashtag" currentSort={sort} currentDir={dir} page={page} fund={fund} />
|
||||
<div className="text-right">
|
||||
<SortLink field="price" label="Price" currentSort={sort} currentDir={dir} page={page} />
|
||||
<SortLink field="price" label="Price" currentSort={sort} currentDir={dir} page={page} fund={fund} />
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<SortLink field="change" label="Change" currentSort={sort} currentDir={dir} page={page} />
|
||||
<SortLink field="change" label="Change" currentSort={sort} currentDir={dir} page={page} fund={fund} />
|
||||
</div>
|
||||
<div className="text-right hidden sm:block text-slate-400">Posts/hr</div>
|
||||
<div className="text-right">
|
||||
<SortLink field="updated" label="Updated" currentSort={sort} currentDir={dir} page={page} />
|
||||
<SortLink field="updated" label="Updated" currentSort={sort} currentDir={dir} page={page} fund={fund} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -262,7 +278,7 @@ export default async function StocksPage({ searchParams }: PageProps) {
|
||||
{(page - 1) * PAGE_SIZE + i + 1}
|
||||
</span>
|
||||
<Link
|
||||
href={`/hashtag/${stock.tag}`}
|
||||
href={`/hashtag/${stock.tag}${fund ? `?fund=${encodeURIComponent(fund)}` : ''}`}
|
||||
className="font-medium hover:text-indigo-300 transition-colors truncate"
|
||||
>
|
||||
#{stock.displayTag}
|
||||
@@ -311,7 +327,7 @@ export default async function StocksPage({ searchParams }: PageProps) {
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
{page > 1 && (
|
||||
<Link
|
||||
href={`/stocks?page=${page - 1}&sort=${sort}&dir=${dir}&tab=stocks`}
|
||||
href={`/stocks?page=${page - 1}&sort=${sort}&dir=${dir}&tab=stocks${fundParam}`}
|
||||
className="px-3 py-1.5 text-sm bg-surface-card border border-surface-border rounded-lg hover:border-indigo-500/50 transition-colors"
|
||||
>
|
||||
← Prev
|
||||
@@ -322,7 +338,7 @@ export default async function StocksPage({ searchParams }: PageProps) {
|
||||
</span>
|
||||
{page < totalPages && (
|
||||
<Link
|
||||
href={`/stocks?page=${page + 1}&sort=${sort}&dir=${dir}&tab=stocks`}
|
||||
href={`/stocks?page=${page + 1}&sort=${sort}&dir=${dir}&tab=stocks${fundParam}`}
|
||||
className="px-3 py-1.5 text-sm bg-surface-card border border-surface-border rounded-lg hover:border-indigo-500/50 transition-colors"
|
||||
>
|
||||
Next →
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user