Changeset 6fa5831


Ignore:
Timestamp:
02/10/26 19:33:59 (5 months ago)
Author:
Andrej <asumanovski@…>
Branches:
master
Children:
c4c43f3
Parents:
8c01a1f
Message:

Made total investment stats for all assets

File:
1 edited

Legend:

Unmodified
Added
Removed
  • frontend/src/pages/Dashboard/pages/Investing/components/InvestingAssetsTable.jsx

    r8c01a1f r6fa5831  
    1 import React from "react";
     1import React, { useMemo } from "react";
    22import { MdDelete } from "react-icons/md";
    33
     
    2020  isDeletingId,
    2121}) {
     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
    2256  return (
    2357    <div className="card bg-base-200 border border-base-300">
     
    3569          </div>
    3670        ) : 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>
    37123
    38124        <div className="mt-4 overflow-x-auto">
Note: See TracChangeset for help on using the changeset viewer.