@@ -10,30 +10,38 @@ import { TradeDialog } from '@/components/trade-dialog';
1010import { Button } from '@/components/ui/button' ;
1111import { Loader2 } from 'lucide-react' ;
1212import type { AssetFromDb } from '@/lib/actions/assets' ;
13+ import { SellSharesDialog } from './sell-shares-dialog' ;
14+ import { InvestDialog } from './invest-dialog' ;
15+ import type { CompanyWithDetails } from '@/lib/actions/companies' ;
1316
1417export default function PortfolioClientPage ( ) {
1518 const { holdings, cash, initialCash, loading } = usePortfolio ( ) ;
1619 const { getAssetByTicker, assets : marketAssets , loading : marketLoading } = useMarketData ( ) ;
1720
1821 const holdingsWithMarketData = useMemo ( ( ) => {
19- if ( ! marketAssets . length ) return [ ] ; // Don't compute until market data is ready
22+ if ( marketLoading && ! marketAssets . length ) return [ ] ;
2023 return holdings . map ( holding => {
21- const asset = getAssetByTicker ( holding . ticker ) ;
22- const currentPrice = asset ?. price || holding . avgCost ;
24+ const isCompany = holding . type === 'Company Share' ;
25+ const asset = ! isCompany ? getAssetByTicker ( holding . ticker ) : undefined ;
26+
27+ // For company shares, the price is stored directly in the holding from the portfolio context
28+ const currentPrice = isCompany ? holding . avgCost : ( asset ?. price || holding . avgCost ) ;
29+
2330 const currentValue = holding . quantity * currentPrice ;
24- const totalCost = holding . quantity * holding . avgCost ;
31+ const totalCost = holding . quantity * holding . avgCost ; // This might be less accurate for company shares over time, but good for a start
2532 const pnl = currentValue - totalCost ;
2633 const pnlPercent = totalCost > 0 ? ( pnl / totalCost ) * 100 : 0 ;
2734 return {
2835 ...holding ,
29- asset : asset ! , // Asset should exist if we have a holding
36+ asset : asset ,
37+ isCompanyShare : isCompany ,
3038 currentPrice,
3139 currentValue,
3240 pnl,
3341 pnlPercent
3442 } ;
3543 } ) . sort ( ( a , b ) => b . currentValue - a . currentValue ) ;
36- } , [ holdings , getAssetByTicker , marketAssets ] ) ;
44+ } , [ holdings , getAssetByTicker , marketAssets , marketLoading ] ) ;
3745
3846 const assetsValue = useMemo ( ( ) => holdingsWithMarketData . reduce ( ( sum , holding ) => sum + holding . currentValue , 0 ) , [ holdingsWithMarketData ] ) ;
3947 const portfolioValue = assetsValue + cash ;
@@ -84,10 +92,8 @@ export default function PortfolioClientPage() {
8492 < TableRow >
8593 < TableHead > Actif</ TableHead >
8694 < TableHead > Quantité</ TableHead >
87- < TableHead > Coût Moyen</ TableHead >
8895 < TableHead > Prix Actuel</ TableHead >
8996 < TableHead > Valeur Actuelle</ TableHead >
90- < TableHead > Gains/Pertes</ TableHead >
9197 < TableHead className = "text-right" > Actions</ TableHead >
9298 </ TableRow >
9399 </ TableHeader >
@@ -100,23 +106,37 @@ export default function PortfolioClientPage() {
100106 < div className = "text-sm text-muted-foreground" > { holding . ticker } </ div >
101107 </ TableCell >
102108 < TableCell > { holding . quantity . toLocaleString ( undefined , { maximumFractionDigits : 8 } ) } </ TableCell >
103- < TableCell > ${ holding . avgCost . toFixed ( 2 ) } </ TableCell >
104- < TableCell > ${ holding . currentPrice . toFixed ( 2 ) } </ TableCell >
109+ < TableCell > ${ holding . currentPrice . toFixed ( holding . currentPrice > 10 ? 2 : 4 ) } </ TableCell >
105110 < TableCell > ${ holding . currentValue . toFixed ( 2 ) } </ TableCell >
106- < TableCell className = { `font-medium ${ holding . pnl >= 0 ? 'text-green-500' : 'text-red-500' } ` } >
107- < div > { holding . pnl >= 0 ? '+' : '-' } ${ Math . abs ( holding . pnl ) . toFixed ( 2 ) } </ div >
108- < div className = "text-xs" > ({ holding . pnlPercent . toFixed ( 2 ) } %)</ div >
109- </ TableCell >
110111 < TableCell className = "text-right space-x-2" >
111- < Button asChild variant = "outline" size = "sm" >
112- < Link href = { `/trading/${ holding . asset . ticker } ` } > Détails</ Link >
113- </ Button >
114- { holding . asset ? (
115- < TradeDialog asset = { holding . asset as AssetFromDb } tradeType = "Sell" >
116- < Button variant = "secondary" size = "sm" > Vendre</ Button >
117- </ TradeDialog >
112+ { holding . isCompanyShare ? (
113+ < >
114+ < Button asChild variant = "outline" size = "sm" >
115+ < Link href = { `/companies/${ holding . id } ` } > Détails</ Link >
116+ </ Button >
117+ < SellSharesDialog
118+ companyId = { holding . id }
119+ companyName = { holding . name }
120+ sharePrice = { holding . currentPrice }
121+ sharesHeld = { holding . quantity }
122+ isListed = { true }
123+ >
124+ < Button variant = "secondary" size = "sm" > Vendre</ Button >
125+ </ SellSharesDialog >
126+ </ >
118127 ) : (
119- < Button variant = "secondary" size = "sm" disabled > Vendre</ Button >
128+ < >
129+ < Button asChild variant = "outline" size = "sm" >
130+ < Link href = { `/trading/${ holding . asset ! . ticker } ` } > Détails</ Link >
131+ </ Button >
132+ { holding . asset ? (
133+ < TradeDialog asset = { holding . asset as AssetFromDb } tradeType = "Sell" >
134+ < Button variant = "secondary" size = "sm" > Vendre</ Button >
135+ </ TradeDialog >
136+ ) : (
137+ < Button variant = "secondary" size = "sm" disabled > Vendre</ Button >
138+ ) }
139+ </ >
120140 ) }
121141 </ TableCell >
122142 </ TableRow >
0 commit comments