{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "stocks-dashboard-shadcnui", "type": "registry:block", "title": "Stocks Dashboard", "description": "Interactive stock portfolio dashboard with status cards, data table, and detailed stock information modal", "registryDependencies": [ "button" ], "dependencies": [ "framer-motion", "react" ], "files": [ { "path": "@uitripled/react-shadcn/src/components/components/stocks-dashboard/stocks-dashboard.tsx", "content": "\"use client\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"@/components/ui/dialog\";\nimport { motion } from \"framer-motion\";\nimport {\n Activity,\n BarChart3,\n Building2,\n ChevronRight,\n DollarSign,\n TrendingDown,\n TrendingUp,\n} from \"lucide-react\";\nimport { useState } from \"react\";\n\ninterface Stock {\n id: string;\n symbol: string;\n name: string;\n price: number;\n change: number;\n changePercent: number;\n volume: number;\n marketCap: string;\n sector: string;\n peRatio: number;\n}\n\nconst mockStocks: Stock[] = [\n {\n id: \"1\",\n symbol: \"AAPL\",\n name: \"Apple Inc.\",\n price: 178.23,\n change: 2.45,\n changePercent: 1.39,\n volume: 45234567,\n marketCap: \"2.8T\",\n sector: \"Technology\",\n peRatio: 31.2,\n },\n {\n id: \"2\",\n symbol: \"GOOGL\",\n name: \"Alphabet Inc.\",\n price: 142.56,\n change: -1.23,\n changePercent: -0.85,\n volume: 28345123,\n marketCap: \"1.8T\",\n sector: \"Technology\",\n peRatio: 24.8,\n },\n {\n id: \"3\",\n symbol: \"MSFT\",\n name: \"Microsoft Corporation\",\n price: 378.91,\n change: 5.67,\n changePercent: 1.52,\n volume: 19234567,\n marketCap: \"2.9T\",\n sector: \"Technology\",\n peRatio: 35.4,\n },\n {\n id: \"4\",\n symbol: \"TSLA\",\n name: \"Tesla, Inc.\",\n price: 248.42,\n change: -3.21,\n changePercent: -1.28,\n volume: 78234567,\n marketCap: \"790B\",\n sector: \"Automotive\",\n peRatio: 62.5,\n },\n {\n id: \"5\",\n symbol: \"AMZN\",\n name: \"Amazon.com Inc.\",\n price: 148.76,\n change: 1.89,\n changePercent: 1.29,\n volume: 45234567,\n marketCap: \"1.5T\",\n sector: \"E-commerce\",\n peRatio: 48.3,\n },\n];\n\nfunction formatNumber(num: number): string {\n if (num >= 1000000) {\n return (num / 1000000).toFixed(1) + \"M\";\n }\n if (num >= 1000) {\n return (num / 1000).toFixed(1) + \"K\";\n }\n return num.toString();\n}\n\nfunction StatusSection() {\n const totalValue = mockStocks.reduce(\n (sum, stock) => sum + stock.price * 100,\n 0\n );\n const totalChange = mockStocks.reduce(\n (sum, stock) => sum + stock.change * 100,\n 0\n );\n const totalChangePercent = (totalChange / (totalValue - totalChange)) * 100;\n\n return (\n
\n \n \n \n \n Total Portfolio Value\n \n \n \n \n
\n $\n {totalValue.toLocaleString(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })}\n
\n

\n Based on current prices\n

\n
\n
\n \n\n \n \n \n \n Today's Change\n \n {totalChange >= 0 ? (\n \n ) : (\n \n )}\n \n \n = 0 ? \"text-green-500\" : \"text-red-500\"}`}\n >\n {totalChange >= 0 ? \"+\" : \"\"}$\n {totalChange.toLocaleString(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })}\n
\n = 0 ? \"text-green-500\" : \"text-red-500\"}`}\n >\n {totalChangePercent >= 0 ? \"+\" : \"\"}\n {totalChangePercent.toFixed(2)}%\n

\n \n \n \n\n \n \n \n \n Active Positions\n \n \n \n \n
\n {mockStocks.length}\n
\n

\n Stocks in portfolio\n

\n
\n
\n \n \n );\n}\n\nfunction StockDetails({\n stock,\n isOpen,\n onClose,\n}: {\n stock: Stock | null;\n isOpen: boolean;\n onClose: () => void;\n}) {\n if (!stock) return null;\n\n return (\n \n \n \n
\n
\n \n
\n
\n \n {stock.symbol}\n \n \n {stock.name}\n \n
\n
\n
\n\n
\n
\n \n \n \n Current Price\n \n \n \n
\n ${stock.price.toFixed(2)}\n
\n
\n
\n\n \n \n \n Change\n \n \n \n = 0 ? \"text-green-500\" : \"text-red-500\"}`}\n >\n {stock.change >= 0 ? \"+\" : \"\"}${stock.change.toFixed(2)}\n
\n = 0 ? \"text-green-500\" : \"text-red-500\"}`}\n >\n {stock.change >= 0 ? \"+\" : \"\"}\n {stock.changePercent.toFixed(2)}%\n
\n \n \n \n\n
\n \n \n \n Market Cap\n \n \n \n
\n ${stock.marketCap}\n
\n
\n
\n\n \n \n \n Volume\n \n \n \n
\n {formatNumber(stock.volume)}\n
\n
\n
\n
\n\n
\n \n \n \n Sector\n \n \n \n {stock.sector}\n \n \n\n \n \n \n P/E Ratio\n \n \n \n
\n {stock.peRatio}\n
\n
\n
\n
\n \n
\n
\n );\n}\n\nfunction DataTable({ onRowClick }: { onRowClick: (stock: Stock) => void }) {\n return (\n \n \n \n \n Stock Holdings\n \n \n \n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {mockStocks.map((stock, index) => (\n onRowClick(stock)}\n >\n \n \n \n \n \n \n \n \n \n ))}\n \n
\n Symbol\n \n Name\n \n Price\n \n Change\n \n Actions\n
\n
\n {stock.symbol}\n
\n
\n
\n {stock.name}\n
\n
\n
\n ${stock.price.toFixed(2)}\n
\n
\n = 0 ? \"text-green-500\" : \"text-red-500\"}`}\n >\n {stock.change >= 0 ? (\n \n ) : (\n \n )}\n \n {stock.change >= 0 ? \"+\" : \"\"}$\n {stock.change.toFixed(2)}\n \n \n = 0 ? \"text-green-500\" : \"text-red-500\"}`}\n >\n {stock.changePercent >= 0 ? \"+\" : \"\"}\n {stock.changePercent.toFixed(2)}%\n \n \n \n
\n
\n
\n
\n
\n );\n}\n\nexport function StocksDashboard() {\n const [selectedStock, setSelectedStock] = useState(null);\n const [isDetailsOpen, setIsDetailsOpen] = useState(false);\n\n const handleRowClick = (stock: Stock) => {\n setSelectedStock(stock);\n setIsDetailsOpen(true);\n };\n\n const handleCloseDetails = () => {\n setIsDetailsOpen(false);\n };\n\n return (\n
\n
\n \n

\n Stock Portfolio Dashboard\n

\n

\n Track your investments and monitor market performance\n

\n \n\n \n \n \n
\n
\n );\n}\n", "type": "registry:block", "target": "components/uitripled/stocks-dashboard-shadcnui.tsx" } ] }