fix: can't access portfolio page

This commit is contained in:
Sosokker 2024-11-04 11:56:18 +07:00
parent 00c6b847e7
commit a440110098
4 changed files with 107 additions and 87 deletions

View File

@ -1,7 +1,7 @@
import { SupabaseClient } from "@supabase/supabase-js";
import { getProjectTag, getTagName } from "@/lib/data/query";
import { getProjectTag, getTagName } from "@/lib/data/tagQuery";
function getTotalInvestment(deals: { deal_amount : number}[]) {
function getTotalInvestment(deals: { deal_amount: number }[]) {
let total = 0;
for (let index = 0; index < deals.length; index++) {
total += deals[index].deal_amount;
@ -16,10 +16,7 @@ async function getLatestInvestment(
const count = 8;
for (let i = deals.length - 1; i >= 0 && llist.length < count; --i) {
let { data: project, error } = await supabase
.from("project")
.select("project_name")
.eq("id", deals[i].project_id);
let { data: project, error } = await supabase.from("project").select("project_name").eq("id", deals[i].project_id);
if (error) {
console.error(error);
}
@ -62,15 +59,9 @@ function countValues(arr: { value: string }[][]): Record<string, number> {
return counts;
}
async function getBusinessTypeName(
supabase: SupabaseClient,
projectId: number
) {
async function getBusinessTypeName(supabase: SupabaseClient, projectId: number) {
// step 1: get business id from project id
let { data: project, error: projectError } = await supabase
.from("project")
.select("business_id")
.eq("id", projectId);
let { data: project, error: projectError } = await supabase.from("project").select("business_id").eq("id", projectId);
if (projectError) {
console.error(projectError);
}
@ -107,20 +98,7 @@ interface GraphData {
function overAllGraphData(deals: Deal[]): GraphData[] {
// Initialize all months with value 0
const months = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
const acc: GraphData[] = months.map((month) => ({ name: month, value: 0 }));
deals
@ -137,7 +115,6 @@ function overAllGraphData(deals: Deal[]): GraphData[] {
return acc;
}
interface Deal {
created_time: string | number | Date;
deal_amount: any;
@ -153,7 +130,7 @@ function fourYearGraphData(deals: Deal[]): GraphData[] {
const acc: GraphData[] = Array.from({ length: 4 }, (_, i) => ({
name: (currentYear - i).toString(),
value: 0,
})).reverse();
})).reverse();
deals
.filter((item: Deal) => new Date(item.created_time) >= yearAgo(3))
.forEach((item: Deal) => {
@ -168,7 +145,6 @@ function fourYearGraphData(deals: Deal[]): GraphData[] {
return acc;
}
interface DayOfWeekData {
name: string;
value: number;
@ -191,24 +167,16 @@ function dayOftheWeekData(deals: Deal[]): DayOfWeekData[] {
});
return dayOfWeekData;
}
async function getInvestorProjectTag(
supabase: SupabaseClient,
deals: number | { project_id: number }[]
) {
async function getInvestorProjectTag(supabase: SupabaseClient, deals: number | { project_id: number }[]) {
// get unique project id from deals
const uniqueProjectIds: number[] = Array.isArray(deals)
? Array.from(
new Set(deals.map((deal: { project_id: number }) => deal.project_id))
)
? Array.from(new Set(deals.map((deal: { project_id: number }) => deal.project_id)))
: [];
const tagIds = (
await Promise.all(
uniqueProjectIds.map(async (projectId: number) => {
const { data: tagIdsArray, error: tagError } = await getProjectTag(
supabase,
projectId
);
const { data: tagIdsArray, error: tagError } = await getProjectTag(supabase, projectId);
if (tagError) {
console.error(tagError);
return [];
@ -223,10 +191,7 @@ async function getInvestorProjectTag(
tagIds
.filter((tagId) => tagId !== null)
.map(async (id: number) => {
const { data: tagName, error: nameError } = await getTagName(
supabase,
id
);
const { data: tagName, error: nameError } = await getTagName(supabase, id);
if (nameError) {
console.error(nameError);
return null;

View File

@ -1,39 +1,24 @@
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
export type RecentDealData = {
created_time: Date;
deal_amount: number;
investor_id: string;
username: string;
avatar_url?: string;
// email: string;
};
interface RecentFundsProps {
recentDealData: RecentDealData[];
data?: { name?: string; amount?: number; avatar?: string; date?: Date }[];
}
export function RecentFunds({ recentDealData }: RecentFundsProps) {
export function RecentFunds(props: RecentFundsProps) {
return (
<div className="space-y-8">
{recentDealData?.length > 0 ? (
recentDealData.map((data) => (
<div className="flex items-center" key={data.investor_id}>
<Avatar className="h-9 w-9">
<AvatarImage src={data.avatar_url} alt={data.username} />
{/* #TODO make this not quick fix */}
<AvatarFallback>{data.username ? data.username[0] : ""}</AvatarFallback>
</Avatar>
<div className="ml-4 space-y-1">
<p className="text-sm font-medium leading-none">{data.username}</p>
{/* <p className="text-sm text-muted-foreground">{data.email}</p> */}
</div>
<div className="ml-auto font-medium">+${data.deal_amount}</div>
{(props?.data || []).map((deal, index) => (
<div className="flex items-center" key={index}>
<Avatar className="h-9 w-9">
<AvatarImage src={deal.avatar} alt={deal.name} />
<AvatarFallback>{(deal.name ?? "").slice(0, 2)}</AvatarFallback>
</Avatar>
<div className="ml-4 space-y-1">
<p className="text-sm font-medium leading-none">{deal.name}</p>
<p className="text-xs text-muted-foreground">{deal?.date?.toLocaleDateString()}</p>
</div>
))
) : (
<p>No recent deals available.</p>
)}
<div className="ml-auto font-medium">+${deal.amount}</div>
</div>
))}
</div>
);
}

View File

@ -2,22 +2,68 @@
import { Bar, BarChart, ResponsiveContainer, XAxis, YAxis, LineChart, Line, Tooltip } from "recharts";
// const data = [
// {
// name: "Jan",
// total: Math.floor(Math.random() * 5000) + 1000,
// },
// {
// name: "Feb",
// total: Math.floor(Math.random() * 5000) + 1000,
// },
// {
// name: "Mar",
// total: Math.floor(Math.random() * 5000) + 1000,
// },
// {
// name: "Apr",
// total: Math.floor(Math.random() * 5000) + 1000,
// },
// {
// name: "May",
// total: Math.floor(Math.random() * 5000) + 1000,
// },
// {
// name: "Jun",
// total: Math.floor(Math.random() * 5000) + 1000,
// },
// {
// name: "Jul",
// total: Math.floor(Math.random() * 5000) + 1000,
// },
// {
// name: "Aug",
// total: Math.floor(Math.random() * 5000) + 1000,
// },
// {
// name: "Sep",
// total: Math.floor(Math.random() * 5000) + 1000,
// },
// {
// name: "Oct",
// total: Math.floor(Math.random() * 5000) + 1000,
// },
// {
// name: "Nov",
// total: Math.floor(Math.random() * 5000) + 1000,
// },
// {
// name: "Dec",
// total: Math.floor(Math.random() * 5000) + 1000,
// },
// ];
interface OverViewProps {
graphType: string;
graphData: Record<string, number>; // Object with month-year as keys and sum as value
data: { name: string; value: number }[];
graphHeight?: number | string;
}
export function Overview(props: OverViewProps) {
// Transform the grouped data into the format for the chart
const chartData = Object.entries(props.graphData).map(([monthYear, totalArray]) => ({
name: monthYear,
total: totalArray, // Get the total amount for the month
}));
return (
<ResponsiveContainer width="100%" height={350}>
<ResponsiveContainer width="100%" height={props.graphHeight || 350}>
{props.graphType === "line" ? (
<LineChart data={chartData}>
<LineChart data={props.data}>
<XAxis dataKey="name" stroke="#888888" fontSize={12} tickLine={false} axisLine={false} />
<YAxis
stroke="#888888"
@ -26,10 +72,18 @@ export function Overview(props: OverViewProps) {
axisLine={false}
tickFormatter={(value) => `$${value}`}
/>
<Line dataKey="total" fill="currentColor" className="fill-primary" />
<Tooltip
formatter={(value) => `$${value}`}
contentStyle={{
backgroundColor: "#f5f5f5",
borderRadius: "5px",
color: "#000",
}}
/>
<Line dataKey="value" fill="currentColor" className="fill-primary" />
</LineChart>
) : (
<BarChart data={chartData}>
<BarChart data={props.data}>
<XAxis dataKey="name" stroke="#888888" fontSize={12} tickLine={false} axisLine={false} />
<YAxis
stroke="#888888"
@ -38,7 +92,15 @@ export function Overview(props: OverViewProps) {
axisLine={false}
tickFormatter={(value) => `$${value}`}
/>
<Bar dataKey="total" 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>
)}
</ResponsiveContainer>

View File

@ -3,3 +3,11 @@ import { SupabaseClient } from "@supabase/supabase-js";
export const getTagsByProjectIds = (client: SupabaseClient, projectIds: string[]) => {
return client.from("project_tag").select(`item_id, ...tag (tag_value:value)`).in("item_id", projectIds);
};
export function getProjectTag(client: SupabaseClient, projectId: number) {
return client.from("project_tag").select("tag_id").in("item_id", [projectId]);
}
export function getTagName(client: SupabaseClient, tagId: number) {
return client.from("tag").select("value").in("id", [tagId]);
}