Refactor dependencies and add PieChart component

This commit is contained in:
Pattadon 2024-10-30 10:04:38 +07:00
parent 44a389c488
commit 8b9663f0f2
5 changed files with 137 additions and 33 deletions

27
package-lock.json generated
View File

@ -33,6 +33,7 @@
"@tanstack/react-query": "^5.59.0", "@tanstack/react-query": "^5.59.0",
"@tanstack/react-query-devtools": "^5.59.0", "@tanstack/react-query-devtools": "^5.59.0",
"b2d-ventures": "file:", "b2d-ventures": "file:",
"chart.js": "^4.4.6",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk": "1.0.0", "cmdk": "1.0.0",
@ -43,6 +44,7 @@
"next": "^14.2.15", "next": "^14.2.15",
"next-themes": "^0.3.0", "next-themes": "^0.3.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-chartjs-2": "^5.2.0",
"react-countup": "^6.5.3", "react-countup": "^6.5.3",
"react-dom": "^18", "react-dom": "^18",
"react-hook-form": "^7.53.0", "react-hook-form": "^7.53.0",
@ -717,6 +719,11 @@
"@jridgewell/sourcemap-codec": "^1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"node_modules/@kurkle/color": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
"integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
},
"node_modules/@next/env": { "node_modules/@next/env": {
"version": "14.2.15", "version": "14.2.15",
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.15.tgz", "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.15.tgz",
@ -3194,6 +3201,17 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/chart.js": {
"version": "4.4.6",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.6.tgz",
"integrity": "sha512-8Y406zevUPbbIBA/HRk33khEmQPk5+cxeflWE/2rx1NJsjVWMPw/9mSP9rxHP5eqi6LNoPBVMfZHxbwLSgldYA==",
"dependencies": {
"@kurkle/color": "^0.3.0"
},
"engines": {
"pnpm": ">=8"
}
},
"node_modules/chokidar": { "node_modules/chokidar": {
"version": "3.6.0", "version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
@ -7650,6 +7668,15 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/react-chartjs-2": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz",
"integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==",
"peerDependencies": {
"chart.js": "^4.1.1",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-countup": { "node_modules/react-countup": {
"version": "6.5.3", "version": "6.5.3",
"resolved": "https://registry.npmjs.org/react-countup/-/react-countup-6.5.3.tgz", "resolved": "https://registry.npmjs.org/react-countup/-/react-countup-6.5.3.tgz",

View File

@ -34,6 +34,7 @@
"@tanstack/react-query": "^5.59.0", "@tanstack/react-query": "^5.59.0",
"@tanstack/react-query-devtools": "^5.59.0", "@tanstack/react-query-devtools": "^5.59.0",
"b2d-ventures": "file:", "b2d-ventures": "file:",
"chart.js": "^4.4.6",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk": "1.0.0", "cmdk": "1.0.0",
@ -44,6 +45,7 @@
"next": "^14.2.15", "next": "^14.2.15",
"next-themes": "^0.3.0", "next-themes": "^0.3.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-chartjs-2": "^5.2.0",
"react-countup": "^6.5.3", "react-countup": "^6.5.3",
"react-dom": "^18", "react-dom": "^18",
"react-hook-form": "^7.53.0", "react-hook-form": "^7.53.0",

View File

@ -1,6 +1,7 @@
import { Overview } from "@/components/ui/overview"; import { Overview } from "@/components/ui/overview";
import { createSupabaseClient } from "@/lib/supabase/serverComponentClient"; import { createSupabaseClient } from "@/lib/supabase/serverComponentClient";
import { getInvestorDeal } from "@/lib/data/query"; import { getInvestorDeal } from "@/lib/data/query";
import PieChart from "@/components/pieChart";
export default async function Portfolio({ export default async function Portfolio({
params, params,
@ -8,6 +9,8 @@ export default async function Portfolio({
params: { uid: string }; params: { uid: string };
}) { }) {
const supabase = createSupabaseClient(); const supabase = createSupabaseClient();
const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
const dayOfWeekData = daysOfWeek.map((day) => ({ name: day, value: 0 }));
const { data: deals, error } = await getInvestorDeal(supabase, params.uid); const { data: deals, error } = await getInvestorDeal(supabase, params.uid);
if (error) { if (error) {
console.error(error); console.error(error);
@ -23,6 +26,7 @@ export default async function Portfolio({
return date.toLocaleString("default", { month: "long", year: "numeric" }); return date.toLocaleString("default", { month: "long", year: "numeric" });
}; };
// only use deal that were made at most year ago
const overAllGraphData = deals const overAllGraphData = deals
? deals ? deals
.filter((item) => new Date(item.created_time) >= yearAgo(1)) .filter((item) => new Date(item.created_time) >= yearAgo(1))
@ -52,13 +56,13 @@ const threeYearGraphData = deals
(acc, item) => { (acc, item) => {
const year = new Date(item.created_time).getFullYear(); const year = new Date(item.created_time).getFullYear();
const existingYear = acc.find( const existingYear = acc.find(
(entry: { name: string; }) => entry.name === year.toString() (entry: { name: string }) => entry.name === year.toString()
); );
if (existingYear) { if (existingYear) {
existingYear.value += item.deal_amount; existingYear.value += item.deal_amount;
} else { } else {
acc.push({ name: year.toString(), value: item.deal_amount }) acc.push({ name: year.toString(), value: item.deal_amount });
} }
return acc; return acc;
@ -66,28 +70,36 @@ const threeYearGraphData = deals
[] as { name: string; value: number }[] [] as { name: string; value: number }[]
) )
: []; : [];
const getDayAbbreviation = (dateString: string | number | Date) => {
const date = new Date(dateString);
return date.toLocaleString("default", { weekday: "short" });
};
if (deals) {
deals
// const graphData = [ .filter((item) => new Date(item.created_time) >= yearAgo(1))
// { name: "October", value: 500 }, .forEach((item) => {
// { name: "October", value: 500 }, const day = getDayAbbreviation(item.created_time);
// { name: "November", value: 500 }, const dayEntry = dayOfWeekData.find((entry) => entry.name === day);
// { name: "December", value: 500 }, if (dayEntry) {
// { name: "January", value: 500 }, dayEntry.value += item.deal_amount;
// { name: "Febuary", value: 500 }, }
// { name: "March", value: 500 }, });
// ]; }
return ( return (
<div> <div>
{/* {JSON.stringify(params.uid)} */}
{/* {JSON.stringify(deals)} */} {/* {JSON.stringify(deals)} */}
{/* {JSON.stringify(deals)} */} {/* {JSON.stringify(dayOfWeekData)} */}
{/* {JSON.stringify(overAllGraphData)} */}
{/* {JSON.stringify(threeYearGraphData)} */} {/* {JSON.stringify(threeYearGraphData)} */}
<div className="flex w-full gap-10"> <div className="flex w-full gap-10">
<Overview graphType="line" data={overAllGraphData}></Overview> <Overview graphType="line" data={overAllGraphData}></Overview>
<Overview graphType="bar" data={threeYearGraphData}></Overview> <Overview graphType="bar" data={threeYearGraphData}></Overview>
<Overview graphType="bar" data={dayOfWeekData}></Overview>
</div> </div>
{/* <PieChart /> */}
</div> </div>
); );
} }

View File

@ -0,0 +1,33 @@
import { Pie } from "react-chartjs-2";
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js";
ChartJS.register(ArcElement, Tooltip, Legend);
interface PieChartProps {
labels: string[];
data: string[];
header:string
}
const PieChart = (props: PieChartProps) => {
const chartData = {
labels: props.labels,
datasets: [
{
label: props.header,
data: props.data,
backgroundColor: ["#FF6384", "#36A2EB", "#FFCE56"],
hoverBackgroundColor: ["#FF6384", "#36A2EB", "#FFCE56"],
borderWidth: 1,
},
],
};
return (
<div style={{ width: "50%", margin: "auto" }}>
<Pie data={chartData} />
</div>
);
};
export default PieChart;

View File

@ -1,6 +1,15 @@
"use client"; "use client";
import { Bar, BarChart, ResponsiveContainer, XAxis, YAxis, LineChart, Line } from "recharts"; import {
Bar,
BarChart,
ResponsiveContainer,
XAxis,
YAxis,
LineChart,
Line,
Tooltip,
} from "recharts";
// const data = [ // const data = [
// { // {
@ -77,6 +86,14 @@ export function Overview(props: OverViewProps) {
axisLine={false} axisLine={false}
tickFormatter={(value) => `$${value}`} tickFormatter={(value) => `$${value}`}
/> />
<Tooltip
formatter={(value) => `$${value}`}
contentStyle={{
backgroundColor: "#f5f5f5",
borderRadius: "5px",
color: "#000",
}}
/>
<Line <Line
dataKey="value" dataKey="value"
fill="currentColor" fill="currentColor"
@ -99,7 +116,20 @@ export function Overview(props: OverViewProps) {
axisLine={false} axisLine={false}
tickFormatter={(value) => `$${value}`} tickFormatter={(value) => `$${value}`}
/> />
<Bar dataKey="value" fill="currentColor" className="fill-primary" /> <Tooltip
formatter={(value) => `$${value}`}
contentStyle={{
backgroundColor: "#f5f5f5",
borderRadius: "5px",
color: "#000",
}}
/>
<Bar
dataKey="value"
fill="currentColor"
className="fill-primary"
radius={[15, 15, 0, 0]}
/>
</BarChart> </BarChart>
)} )}
</ResponsiveContainer> </ResponsiveContainer>