import { useState } from "react"; import { format } from "date-fns"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Button } from "@/components/ui/button"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Calendar as CalendarUI } from "@/components/ui/calendar"; import { Plus, Calendar as CalendarIcon } from "lucide-react"; import { cn } from "@/lib/utils"; import type { Holding, HistoricalValue } from "@/types/finance"; import { ASSET_CATEGORIES } from "@/lib/holdings"; export function AddInvestmentDialog({ onAdd, defaultCurrency }: { onAdd: (h: Holding) => void; defaultCurrency: string }) { const [open, setOpen] = useState(false); const [name, setName] = useState(""); const [category, setCategory] = useState("Private Equity"); const [currency, setCurrency] = useState(defaultCurrency); const [details, setDetails] = useState(""); const [amount, setAmount] = useState(""); const [currentValue, setCurrentValue] = useState(""); const [ticker, setTicker] = useState(""); const [quantity, setQuantity] = useState("1"); const [dateObj, setDateObj] = useState(new Date()); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!name || !amount || !dateObj) return; const dateStr = format(dateObj, "yyyy-MM-dd"); const costBasis = parseFloat(amount) || 0; const price = currentValue ? parseFloat(currentValue) : costBasis; const shares = parseFloat(quantity) > 0 ? parseFloat(quantity) : 1; const history: HistoricalValue[] = [{ date: dateStr, value: costBasis }]; const today = format(new Date(), "yyyy-MM-dd"); if (price !== costBasis && dateStr !== today) { history.push({ date: today, value: price }); } const derived = name.length > 4 ? name.substring(0, 4).toUpperCase() : name.toUpperCase(); onAdd({ id: `manual_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, name, // A linked public ticker enables live tracking; else a name-derived placeholder. symbol: ticker.trim() ? ticker.trim().toUpperCase() : derived, shares, price, costBasis, change: price - costBasis, changePercent: costBasis > 0 ? ((price - costBasis) / costBasis) * 100 : 0, currency, isManual: true, category, details, dateInvested: dateStr, history, }); setOpen(false); setName(""); setDetails(""); setAmount(""); setCurrentValue(""); setTicker(""); setQuantity("1"); setDateObj(new Date()); }; return ( Add Manual Investment
setName(e.target.value)} required />
d && setDateObj(d)} initialFocus />
setAmount(e.target.value)} required />
setQuantity(e.target.value)} />
setCurrentValue(e.target.value)} />
setTicker(e.target.value)} />

For a public ticker, enter avg cost in its trading currency (e.g. USD for SPCX). The live price will display in that native currency.

setDetails(e.target.value)} />
); }