mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-20 14:34:05 +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 { createSupabaseClient } from "@/lib/supabase/serverComponentClient";
|
||||||
import { getInvestorDeal, getProjectTag, getTagName } from "@/lib/data/query";
|
import { getInvestorDeal, getProjectTag, getTagName } from "@/lib/data/query";
|
||||||
import PieChart from "@/components/pieChart";
|
import PieChart from "@/components/pieChart";
|
||||||
|
import { overAllGraphData, fourYearGraphData, dayOftheWeekData } from "./hook";
|
||||||
|
|
||||||
export default async function Portfolio({
|
export default async function Portfolio({
|
||||||
params,
|
params,
|
||||||
@ -9,12 +10,13 @@ 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: investorDealError } = await getInvestorDeal(
|
const { data: deals, error: investorDealError } = await getInvestorDeal(
|
||||||
supabase,
|
supabase,
|
||||||
params.uid
|
params.uid
|
||||||
);
|
);
|
||||||
|
const overAllData = deals ? overAllGraphData(deals) : [];
|
||||||
|
const fourYearData = deals ? fourYearGraphData(deals) : [];
|
||||||
|
const dayOfWeekData = deals ? dayOftheWeekData(deals) : [];
|
||||||
|
|
||||||
const projectTag = async () => {
|
const projectTag = async () => {
|
||||||
// get unique project id from deals
|
// get unique project id from deals
|
||||||
@ -81,80 +83,6 @@ export default async function Portfolio({
|
|||||||
console.error(investorDealError);
|
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 (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{/* {JSON.stringify(params.uid)} */}
|
{/* {JSON.stringify(params.uid)} */}
|
||||||
@ -169,10 +97,11 @@ export default async function Portfolio({
|
|||||||
<div>{totalInvest}</div>
|
<div>{totalInvest}</div>
|
||||||
</div> */}
|
</div> */}
|
||||||
<div className="flex w-full gap-10">
|
<div className="flex w-full gap-10">
|
||||||
<Overview graphType="line" data={overAllGraphData}></Overview>
|
<Overview graphType="line" data={overAllData}></Overview>
|
||||||
<Overview graphType="bar" data={threeYearGraphData}></Overview>
|
<Overview graphType="bar" data={fourYearData}></Overview>
|
||||||
<Overview graphType="bar" data={dayOfWeekData}></Overview>
|
<Overview graphType="bar" data={dayOfWeekData}></Overview>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="w-96">
|
||||||
<PieChart
|
<PieChart
|
||||||
data={tagCount.map(
|
data={tagCount.map(
|
||||||
(item: { name: string; count: number }) => item.count
|
(item: { name: string; count: number }) => item.count
|
||||||
@ -183,5 +112,6 @@ export default async function Portfolio({
|
|||||||
header="Total"
|
header="Total"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,11 +24,18 @@ const PieChart = (props: PieChartProps) => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
const options = {
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
position: "bottom" as const,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: "50%", margin: "auto" }}>
|
<>
|
||||||
<Pie data={chartData} />
|
<Pie data={chartData} options={options} />
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user