Changeset 6fa5831
- Timestamp:
- 02/10/26 19:33:59 (5 months ago)
- Branches:
- master
- Children:
- c4c43f3
- Parents:
- 8c01a1f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
frontend/src/pages/Dashboard/pages/Investing/components/InvestingAssetsTable.jsx
r8c01a1f r6fa5831 1 import React from "react";1 import React, { useMemo } from "react"; 2 2 import { MdDelete } from "react-icons/md"; 3 3 … … 20 20 isDeletingId, 21 21 }) { 22 const totals = useMemo(() => { 23 let totalInvested = 0; 24 let totalCurrent = 0; 25 let investedCount = 0; 26 let currentCount = 0; 27 28 for (const a of assets) { 29 const symbol = String(a?.tickerSymbol ?? "").toUpperCase(); 30 const quantity = Number(a?.quantity); 31 if (!symbol || Number.isNaN(quantity) || quantity <= 0) continue; 32 33 const buyPrice = Number(a?.buyPrice); 34 if (!Number.isNaN(buyPrice) && buyPrice >= 0) { 35 totalInvested += buyPrice * quantity; 36 investedCount += 1; 37 } 38 39 const currentPrice = Number(quotesBySymbol?.[symbol]); 40 if (!Number.isNaN(currentPrice) && currentPrice >= 0) { 41 totalCurrent += currentPrice * quantity; 42 currentCount += 1; 43 } 44 } 45 46 const hasInvested = investedCount > 0 && totalInvested > 0; 47 const hasCurrent = currentCount > 0; 48 const roiPct = 49 hasInvested && hasCurrent 50 ? ((totalCurrent - totalInvested) / totalInvested) * 100 51 : null; 52 53 return { totalInvested, totalCurrent, roiPct, hasInvested, hasCurrent }; 54 }, [assets, quotesBySymbol]); 55 22 56 return ( 23 57 <div className="card bg-base-200 border border-base-300"> … … 35 69 </div> 36 70 ) : null} 71 72 <div className="mt-4 grid grid-cols-1 gap-3 sm:grid-cols-3"> 73 <div className="stat bg-base-100 rounded-box border border-base-300"> 74 <div className="stat-title">Total invested</div> 75 <div className="stat-value text-xl"> 76 {totals.hasInvested ? formatMoney(totals.totalInvested) : "—"} 77 </div> 78 <div className="stat-desc opacity-70"> 79 Cost basis (buy price × quantity) 80 </div> 81 </div> 82 83 <div className="stat bg-base-100 rounded-box border border-base-300"> 84 <div className="stat-title">Current value</div> 85 <div className="stat-value text-xl"> 86 {totals.hasCurrent && !isQuotesLoading 87 ? formatMoney(totals.totalCurrent) 88 : isQuotesLoading 89 ? "Loading…" 90 : "—"} 91 </div> 92 <div className="stat-desc opacity-70">Live price × quantity</div> 93 </div> 94 95 <div className="stat bg-base-100 rounded-box border border-base-300"> 96 <div className="stat-title">Total ROI</div> 97 <div className="stat-value text-xl"> 98 {typeof totals.roiPct === "number" && 99 !Number.isNaN(totals.roiPct) ? ( 100 <span 101 className={ 102 totals.roiPct > 0 103 ? "text-green-400 font-semibold" 104 : totals.roiPct < 0 105 ? "text-red-400 font-semibold" 106 : "opacity-80" 107 } 108 > 109 {totals.roiPct > 0 ? "+" : ""} 110 {totals.roiPct.toFixed(2)}% 111 </span> 112 ) : isQuotesLoading ? ( 113 "Loading…" 114 ) : ( 115 "—" 116 )} 117 </div> 118 <div className="stat-desc opacity-70"> 119 (current − invested) ÷ invested 120 </div> 121 </div> 122 </div> 37 123 38 124 <div className="mt-4 overflow-x-auto">
Note:
See TracChangeset
for help on using the changeset viewer.
