mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-18 21:44:06 +01:00
Refactor Portfolio component and add data aggregation hooks
This commit is contained in:
parent
62e20c282a
commit
16a171db3c
106
src/app/portfolio/[uid]/hook.ts
Normal file
106
src/app/portfolio/[uid]/hook.ts
Normal file
@ -0,0 +1,106 @@
|
||||
// only use deal that were made at most year ago
|
||||
interface Deal {
|
||||
created_time: string | number | Date;
|
||||
deal_amount: any;
|
||||
}
|
||||
|
||||
interface GraphData {
|
||||
name: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
function overAllGraphData(deals: Deal[]): GraphData[] {
|
||||
return deals
|
||||
? deals
|
||||
.filter((item: Deal) => new Date(item.created_time) >= yearAgo(1))
|
||||
.reduce((acc: GraphData[], item: Deal) => {
|
||||
// get the first three initial letter of the month
|
||||
const monthName = getMonthName(item.created_time.toString()).slice(
|
||||
0,
|
||||
3
|
||||
);
|
||||
const existingMonth = acc.find(
|
||||
(entry: GraphData) => entry.name === monthName
|
||||
);
|
||||
|
||||
if (existingMonth) {
|
||||
existingMonth.value += item.deal_amount;
|
||||
}
|
||||
// if month doesnt exist yet, create new record
|
||||
else {
|
||||
acc.push({ name: monthName, value: item.deal_amount });
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, [] as GraphData[])
|
||||
: [];
|
||||
}
|
||||
|
||||
interface Deal {
|
||||
created_time: string | number | Date;
|
||||
deal_amount: any;
|
||||
}
|
||||
|
||||
interface GraphData {
|
||||
name: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
function fourYearGraphData(deals: Deal[]): GraphData[] {
|
||||
return deals
|
||||
.filter((item: Deal) => new Date(item.created_time) >= yearAgo(3))
|
||||
.reduce((acc: GraphData[], item: Deal) => {
|
||||
const year = new Date(item.created_time).getFullYear();
|
||||
const existingYear = acc.find(
|
||||
(entry: GraphData) => entry.name === year.toString()
|
||||
);
|
||||
|
||||
if (existingYear) {
|
||||
existingYear.value += item.deal_amount;
|
||||
} else {
|
||||
acc.push({ name: year.toString(), value: item.deal_amount });
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, [] as GraphData[]);
|
||||
}
|
||||
|
||||
interface DayOfWeekData {
|
||||
name: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
function dayOftheWeekData(deals: Deal[]): DayOfWeekData[] {
|
||||
const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||
const dayOfWeekData: DayOfWeekData[] = daysOfWeek.map((day) => ({
|
||||
name: day,
|
||||
value: 0,
|
||||
}));
|
||||
deals
|
||||
.filter((item: Deal) => new Date(item.created_time) >= yearAgo(1))
|
||||
.forEach((item: Deal) => {
|
||||
const day = getDayAbbreviation(item.created_time);
|
||||
const dayEntry = dayOfWeekData.find((entry) => entry.name === day);
|
||||
if (dayEntry) {
|
||||
dayEntry.value += item.deal_amount;
|
||||
}
|
||||
});
|
||||
return dayOfWeekData;
|
||||
}
|
||||
const getDayAbbreviation = (dateString: string | number | Date) => {
|
||||
const date = new Date(dateString);
|
||||
return date.toLocaleString("default", { weekday: "short" });
|
||||
};
|
||||
|
||||
const yearAgo = (num: number) => {
|
||||
const newDate = new Date();
|
||||
newDate.setFullYear(newDate.getFullYear() - num);
|
||||
return newDate;
|
||||
};
|
||||
|
||||
const getMonthName = (dateString: string) => {
|
||||
const date = new Date(dateString);
|
||||
return date.toLocaleString("default", { month: "long", year: "numeric" });
|
||||
};
|
||||
|
||||
export { overAllGraphData, fourYearGraphData, dayOftheWeekData };
|
||||
@ -2,6 +2,7 @@ import { Overview } from "@/components/ui/overview";
|
||||
import { createSupabaseClient } from "@/lib/supabase/serverComponentClient";
|
||||
import { getInvestorDeal, getProjectTag, getTagName } from "@/lib/data/query";
|
||||
import PieChart from "@/components/pieChart";
|
||||
import { overAllGraphData, fourYearGraphData, dayOftheWeekData } from "./hook";
|
||||
|
||||
export default async function Portfolio({
|
||||
params,
|
||||
@ -9,12 +10,13 @@ export default async function Portfolio({
|
||||
params: { uid: string };
|
||||
}) {
|
||||
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: investorDealError } = await getInvestorDeal(
|
||||
supabase,
|
||||
params.uid
|
||||
);
|
||||
const overAllData = deals ? overAllGraphData(deals) : [];
|
||||
const fourYearData = deals ? fourYearGraphData(deals) : [];
|
||||
const dayOfWeekData = deals ? dayOftheWeekData(deals) : [];
|
||||
|
||||
const projectTag = async () => {
|
||||
// get unique project id from deals
|
||||
@ -81,80 +83,6 @@ export default async function Portfolio({
|
||||
console.error(investorDealError);
|
||||
}
|
||||
|
||||
const yearAgo = (num: number) => {
|
||||
const newDate = new Date();
|
||||
newDate.setFullYear(newDate.getFullYear() - num);
|
||||
return newDate;
|
||||
};
|
||||
|
||||
const getMonthName = (dateString: string) => {
|
||||
const date = new Date(dateString);
|
||||
return date.toLocaleString("default", { month: "long", year: "numeric" });
|
||||
};
|
||||
|
||||
// only use deal that were made at most year ago
|
||||
const overAllGraphData = deals
|
||||
? deals
|
||||
.filter((item) => new Date(item.created_time) >= yearAgo(1))
|
||||
.reduce(
|
||||
(acc, item) => {
|
||||
const monthName = getMonthName(item.created_time).slice(0, 3);
|
||||
const existingMonth = acc.find(
|
||||
(entry: { name: string }) => entry.name === monthName
|
||||
);
|
||||
|
||||
if (existingMonth) {
|
||||
existingMonth.value += item.deal_amount;
|
||||
} else {
|
||||
acc.push({ name: monthName, value: item.deal_amount });
|
||||
}
|
||||
|
||||
return acc;
|
||||
},
|
||||
[] as { name: string; value: number }[]
|
||||
)
|
||||
: [];
|
||||
|
||||
const threeYearGraphData = deals
|
||||
? deals
|
||||
.filter((item) => new Date(item.created_time) >= yearAgo(3))
|
||||
.reduce(
|
||||
(acc, item) => {
|
||||
const year = new Date(item.created_time).getFullYear();
|
||||
const existingYear = acc.find(
|
||||
(entry: { name: string }) => entry.name === year.toString()
|
||||
);
|
||||
|
||||
if (existingYear) {
|
||||
existingYear.value += item.deal_amount;
|
||||
} else {
|
||||
acc.push({ name: year.toString(), value: item.deal_amount });
|
||||
}
|
||||
|
||||
return acc;
|
||||
},
|
||||
[] as { name: string; value: number }[]
|
||||
)
|
||||
: [];
|
||||
const getDayAbbreviation = (dateString: string | number | Date) => {
|
||||
const date = new Date(dateString);
|
||||
return date.toLocaleString("default", { weekday: "short" });
|
||||
};
|
||||
|
||||
let totalInvest = 0;
|
||||
if (deals) {
|
||||
deals
|
||||
.filter((item) => new Date(item.created_time) >= yearAgo(1))
|
||||
.forEach((item) => {
|
||||
const day = getDayAbbreviation(item.created_time);
|
||||
const dayEntry = dayOfWeekData.find((entry) => entry.name === day);
|
||||
if (dayEntry) {
|
||||
dayEntry.value += item.deal_amount;
|
||||
}
|
||||
});
|
||||
totalInvest = deals.reduce((acc, item) => acc + item.deal_amount, 0);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* {JSON.stringify(params.uid)} */}
|
||||
@ -169,19 +97,21 @@ export default async function Portfolio({
|
||||
<div>{totalInvest}</div>
|
||||
</div> */}
|
||||
<div className="flex w-full gap-10">
|
||||
<Overview graphType="line" data={overAllGraphData}></Overview>
|
||||
<Overview graphType="bar" data={threeYearGraphData}></Overview>
|
||||
<Overview graphType="line" data={overAllData}></Overview>
|
||||
<Overview graphType="bar" data={fourYearData}></Overview>
|
||||
<Overview graphType="bar" data={dayOfWeekData}></Overview>
|
||||
</div>
|
||||
<PieChart
|
||||
data={tagCount.map(
|
||||
(item: { name: string; count: number }) => item.count
|
||||
)}
|
||||
labels={tagCount.map(
|
||||
(item: { name: string; count: number }) => item.name
|
||||
)}
|
||||
header="Total"
|
||||
/>
|
||||
<div className="w-96">
|
||||
<PieChart
|
||||
data={tagCount.map(
|
||||
(item: { name: string; count: number }) => item.count
|
||||
)}
|
||||
labels={tagCount.map(
|
||||
(item: { name: string; count: number }) => item.name
|
||||
)}
|
||||
header="Total"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -24,11 +24,18 @@ const PieChart = (props: PieChartProps) => {
|
||||
},
|
||||
],
|
||||
};
|
||||
const options = {
|
||||
plugins: {
|
||||
legend: {
|
||||
position: "bottom" as const,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ width: "50%", margin: "auto" }}>
|
||||
<Pie data={chartData} />
|
||||
</div>
|
||||
<>
|
||||
<Pie data={chartData} options={options} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user