harshapitla/stackoverflow
0
1{"version":3,"file":"static/js/103.34050452.chunk.js","mappings":"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","sources":["components/charts/ChartCard.jsx","charts/TopProductsCharts.jsx"],"sourcesContent":["import React from \"react\";\r\n\r\nexport default function ChartCard({ title, subtitle, children, actions, footer }) {\r\n return (\r\n <section className=\"card chart-card\">\r\n {(title || subtitle || actions) && (\r\n <div className=\"chart-card-header\">\r\n <div>\r\n {title && <h3 className=\"chart-card-title\">{title}</h3>}\r\n {subtitle && <p className=\"chart-card-subtitle\">{subtitle}</p>}\r\n </div>\r\n {actions && <div className=\"chart-card-actions\">{actions}</div>}\r\n </div>\r\n )}\r\n <div className=\"chart-card-body\">{children}</div>\r\n {footer && <div className=\"chart-card-footer\">{footer}</div>}\r\n </section>\r\n );\r\n}\r\n","import React, { useMemo, useState } from \"react\";\r\nimport {\r\n ResponsiveContainer,\r\n BarChart,\r\n Bar,\r\n XAxis,\r\n YAxis,\r\n Tooltip,\r\n CartesianGrid,\r\n} from \"recharts\";\r\nimport ChartCard from \"../components/charts/ChartCard\";\r\n\r\n/* ================= SAFE NUMBER PARSER ================= */\r\nfunction parseNumber(value) {\r\n if (value === null || value === undefined) return 0;\r\n if (typeof value === \"number\") return value;\r\n if (typeof value === \"string\") {\r\n const cleaned = value.replace(/,/g, \"\").trim();\r\n const num = Number(cleaned);\r\n return isNaN(num) ? 0 : num;\r\n }\r\n return 0;\r\n}\r\n\r\n/* ================= CUSTOM TOOLTIP ================= */\r\nfunction CustomTooltip({ active, payload, label }) {\r\n if (active && payload && payload.length) {\r\n return (\r\n <div\r\n style={{\r\n background: \"#ffffff\",\r\n padding: \"8px 12px\",\r\n borderRadius: 6,\r\n border: \"1px solid #cbd5e1\",\r\n }}\r\n >\r\n <strong>{label}</strong>\r\n <div style={{ marginTop: 4 }}>\r\n {payload[0].dataKey}: {payload[0].value.toLocaleString()}\r\n </div>\r\n </div>\r\n );\r\n }\r\n return null;\r\n}\r\n\r\n/* ================= MAIN CHART ================= */\r\nexport default function TopProductsCharts({ rows = [] }) {\r\n const [metric, setMetric] = useState(\"followers\");\r\n\r\n const chartData = useMemo(() => {\r\n if (!Array.isArray(rows)) return [];\r\n\r\n return rows\r\n .map((r) => {\r\n const followers = parseNumber(r.followers_count);\r\n const reviews = parseNumber(r.reviews_count);\r\n const usage = parseNumber(r.used_by_count);\r\n\r\n return {\r\n title: r.title,\r\n value:\r\n metric === \"followers\"\r\n ? followers\r\n : metric === \"reviews\"\r\n ? reviews\r\n : usage,\r\n };\r\n })\r\n .filter((r) => r.title && r.value > 0)\r\n .sort((a, b) => b.value - a.value)\r\n .slice(0, 10);\r\n }, [rows, metric]);\r\n\r\n if (!chartData.length) {\r\n return (\r\n <ChartCard\r\n title=\"Top Product Hunt Products\"\r\n subtitle=\"Based on followers, reviews, or usage\"\r\n >\r\n <p className=\"small\">No valid data available.</p>\r\n </ChartCard>\r\n );\r\n }\r\n\r\n const getTitle = () => {\r\n switch (metric) {\r\n case \"followers\":\r\n return \"Top Products by Followers\";\r\n case \"reviews\":\r\n return \"Top Products by Reviews\";\r\n case \"usage\":\r\n return \"Products by Usage Count\";\r\n default:\r\n return \"Top Product Hunt Products\";\r\n }\r\n };\r\n\r\n const getSubtitle = () => {\r\n switch (metric) {\r\n case \"followers\":\r\n return \"Identify most followed products\";\r\n case \"reviews\":\r\n return \"Measure active user engagement\";\r\n case \"usage\":\r\n return \"Measure real adoption\";\r\n default:\r\n return \"\";\r\n }\r\n };\r\n\r\n return (\r\n <ChartCard title={getTitle()} subtitle={getSubtitle()}>\r\n {/* ================= TOGGLE ================= */}\r\n <div style={{ marginBottom: 16, display: \"flex\", gap: \"8px\" }}>\r\n <button\r\n onClick={() => setMetric(\"followers\")}\r\n style={{\r\n padding: \"10px 16px\",\r\n borderRadius: \"8px\",\r\n background: metric === \"followers\" ? \"#007acc\" : \"#f0f0f0\",\r\n color: metric === \"followers\" ? \"white\" : \"black\",\r\n border: \"none\",\r\n cursor: \"pointer\",\r\n }}\r\n >\r\n ๐ฅ Followers\r\n </button>\r\n <button\r\n onClick={() => setMetric(\"reviews\")}\r\n style={{\r\n padding: \"10px 16px\",\r\n borderRadius: \"8px\",\r\n background: metric === \"reviews\" ? \"#007acc\" : \"#f0f0f0\",\r\n color: metric === \"reviews\" ? \"white\" : \"black\",\r\n border: \"none\",\r\n cursor: \"pointer\",\r\n }}\r\n >\r\n ๐ Reviews\r\n </button>\r\n <button\r\n onClick={() => setMetric(\"usage\")}\r\n style={{\r\n padding: \"10px 16px\",\r\n borderRadius: \"8px\",\r\n background: metric === \"usage\" ? \"#007acc\" : \"#f0f0f0\",\r\n color: metric === \"usage\" ? \"white\" : \"black\",\r\n border: \"none\",\r\n cursor: \"pointer\",\r\n }}\r\n >\r\n ๐ฅ Usage\r\n </button>\r\n </div>\r\n\r\n <ResponsiveContainer width=\"100%\" height={300}>\r\n <BarChart data={chartData}>\r\n <CartesianGrid strokeDasharray=\"3 3\" />\r\n <XAxis dataKey=\"title\" angle={-45} textAnchor=\"end\" interval={0} />\r\n <YAxis />\r\n <Tooltip content={<CustomTooltip />} />\r\n <Bar dataKey=\"value\" fill=\"#8884d8\" />\r\n </BarChart>\r\n </ResponsiveContainer>\r\n </ChartCard>\r\n );\r\n}\r\n"],"names":["ChartCard","_ref","title","subtitle","children","actions","footer","_jsxs","className","_jsx","parseNumber","value","undefined","cleaned","replace","trim","num","Number","isNaN","CustomTooltip","active","payload","label","length","style","background","padding","borderRadius","border","marginTop","dataKey","toLocaleString","TopProductsCharts","_ref2","rows","metric","setMetric","useState","chartData","useMemo","Array","isArray","map","r","followers","followers_count","reviews","reviews_count","usage","used_by_count","filter","sort","a","b","slice","getTitle","getSubtitle","marginBottom","display","gap","onClick","color","cursor","ResponsiveContainer","width","height","BarChart","data","CartesianGrid","strokeDasharray","XAxis","angle","textAnchor","interval","YAxis","Tooltip","content","Bar","fill"],"sourceRoot":""}