This commit is contained in:
@@ -4,7 +4,11 @@ import { authOptions } from '@/lib/auth'
|
||||
import { redirect } from 'next/navigation'
|
||||
import { formatCurrency, formatNumber, formatPnl, pnlColor } from '@/lib/utils'
|
||||
import Link from 'next/link'
|
||||
import { Coins } from 'lucide-react'
|
||||
import { Coins, AlertTriangle } from 'lucide-react'
|
||||
import { formatDistanceToNow } from 'date-fns'
|
||||
|
||||
const ZOMBIE_ZERO_COUNT = parseInt(process.env.ZOMBIE_ZERO_COUNT ?? '1000', 10)
|
||||
const PRICE_UPDATE_INTERVAL_MINUTES = parseInt(process.env.PRICE_UPDATE_INTERVAL_MINUTES ?? '60', 10)
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
@@ -50,6 +54,7 @@ export default async function PositionsPage() {
|
||||
tag: true,
|
||||
displayTag: true,
|
||||
currentPrice: true,
|
||||
zeroCount: true,
|
||||
priceHistory: {
|
||||
orderBy: { recordedAt: 'asc' },
|
||||
take: 20,
|
||||
@@ -98,6 +103,18 @@ export default async function PositionsPage() {
|
||||
const currentValue = pos.hashtag.currentPrice * pos.shares
|
||||
const pnlPct = costBasis > 0 ? (pnl / costBasis) * 100 : 0
|
||||
const sparkPrices = pos.hashtag.priceHistory.map((h) => h.price)
|
||||
const isZombieWarning = pos.hashtag.zeroCount >= ZOMBIE_ZERO_COUNT * 0.9
|
||||
const zombieSince = isZombieWarning
|
||||
? formatDistanceToNow(
|
||||
new Date(Date.now() - pos.hashtag.zeroCount * PRICE_UPDATE_INTERVAL_MINUTES * 60 * 1000),
|
||||
)
|
||||
: null
|
||||
const zombieEta = isZombieWarning
|
||||
? formatDistanceToNow(
|
||||
new Date(Date.now() + (ZOMBIE_ZERO_COUNT - pos.hashtag.zeroCount) * PRICE_UPDATE_INTERVAL_MINUTES * 60 * 1000),
|
||||
{ addSuffix: true },
|
||||
)
|
||||
: null
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -114,6 +131,15 @@ export default async function PositionsPage() {
|
||||
>
|
||||
#{pos.hashtag.displayTag}
|
||||
</Link>
|
||||
{isZombieWarning && zombieSince && zombieEta && (
|
||||
<span
|
||||
title={`No activity detected for ${zombieSince}. Estimated auto-liquidation ${zombieEta}.`}
|
||||
className="inline-flex items-center gap-1 text-xs font-medium px-1.5 py-0.5 rounded bg-amber-500/15 text-amber-400 border border-amber-500/20 mt-0.5"
|
||||
>
|
||||
<AlertTriangle className="h-3 w-3" />
|
||||
No activity for {zombieSince} · Liquidates {zombieEta}
|
||||
</span>
|
||||
)}
|
||||
<span
|
||||
className={`text-xs font-medium px-1.5 py-0.5 rounded ${
|
||||
pos.positionType === 'LONG'
|
||||
|
||||
Reference in New Issue
Block a user