mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-19 05:54:06 +01:00
connect recent funded people to database
This commit is contained in:
parent
0150b4840b
commit
f65fc2a696
@ -7,14 +7,17 @@ export type Deal = {
|
||||
investor_id: string;
|
||||
};
|
||||
|
||||
// Sort the dealList by created_time in descending order
|
||||
export function byCreatedTimeDesc(a: Deal, b: Deal) {
|
||||
return new Date(b.created_time).getTime() - new Date(a.created_time).getTime();
|
||||
}
|
||||
|
||||
export async function getDealList() {
|
||||
const supabase = createSupabaseClient();
|
||||
const { data: dealData, error } = await supabase
|
||||
.from('business')
|
||||
.select(`
|
||||
id,
|
||||
project (
|
||||
id,
|
||||
investment_deal (
|
||||
deal_amount,
|
||||
created_time,
|
||||
@ -25,7 +28,6 @@ export async function getDealList() {
|
||||
.eq('user_id', await getCurrentUserID())
|
||||
.single();
|
||||
|
||||
// Handle errors and no data cases
|
||||
if (error) {
|
||||
alert(JSON.stringify(error));
|
||||
console.error('Error fetching deal list:', error);
|
||||
@ -37,22 +39,51 @@ export async function getDealList() {
|
||||
return; // Exit if there's no data
|
||||
}
|
||||
|
||||
const dealList = dealData.project[0].investment_deal;
|
||||
const flattenedDeals = dealData.project.flatMap((proj) =>
|
||||
proj.investment_deal.map((deal) => ({
|
||||
deal_amount: deal.deal_amount,
|
||||
created_time: deal.created_time,
|
||||
investor_id: deal.investor_id,
|
||||
}))
|
||||
)
|
||||
|
||||
// Check for empty dealList
|
||||
if (!dealList.length) {
|
||||
if (!flattenedDeals.length) {
|
||||
alert("No deal list available");
|
||||
return; // Exit if there's no data
|
||||
}
|
||||
|
||||
// Sort the dealList by created_time in descending order
|
||||
const byCreatedTimeDesc = (a: Deal, b: Deal) =>
|
||||
new Date(b.created_time).getTime() - new Date(a.created_time).getTime();
|
||||
return dealList.sort(byCreatedTimeDesc);
|
||||
return flattenedDeals.sort(byCreatedTimeDesc);
|
||||
};
|
||||
|
||||
export async function getRecentDealData() {
|
||||
const supabase = createSupabaseClient();
|
||||
let dealList = await getDealList();
|
||||
|
||||
if (!dealList) {
|
||||
// #TODO div no deals available?
|
||||
return;
|
||||
}
|
||||
|
||||
dealList = dealList.slice(0, 5)
|
||||
|
||||
const investorIdList: string[] = dealList.map(deal => deal.investor_id);
|
||||
const { data: userData, error } = await supabase
|
||||
.from("profiles")
|
||||
.select("username, avatar_url") // #TODO add email
|
||||
.in("id", investorIdList); // Filter by investor_id
|
||||
|
||||
if (error) {
|
||||
// Handle the error and return a meaningful message
|
||||
console.error("Error fetching usernames and avatars:", error);
|
||||
}
|
||||
|
||||
alert(JSON.stringify(userData));
|
||||
return userData || [];
|
||||
}
|
||||
|
||||
// #TODO move to util
|
||||
export function convertToGraphData(deals: Deal[]): Record<string, number> {
|
||||
// group by year & month
|
||||
let graphData = deals.reduce((acc, deal) => {
|
||||
const monthYear = new Date(deal.created_time).toISOString().slice(0, 7); // E.g., '2024-10'
|
||||
acc[monthYear] = (acc[monthYear] || 0) + deal.deal_amount; // Sum the deal_amount
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Deal, getDealList, convertToGraphData } from "../api/dealApi";
|
||||
import { Deal, getDealList, convertToGraphData, getRecentDealData } from "../api/dealApi";
|
||||
|
||||
|
||||
type RecentDealData = { username: string; avatar_url: string }[]
|
||||
|
||||
// custom hook for deal list
|
||||
export function useDealList() {
|
||||
@ -17,7 +20,7 @@ export function useDealList() {
|
||||
}
|
||||
|
||||
export function useGraphData() {
|
||||
const [graphData, setGraphData] = useState<Record<string, number>>({});
|
||||
const [graphData, setGraphData] = useState({});
|
||||
|
||||
const fetchGraphData = async () => {
|
||||
const dealList = await getDealList();
|
||||
@ -31,4 +34,18 @@ export function useGraphData() {
|
||||
}, []);
|
||||
|
||||
return graphData;
|
||||
}
|
||||
|
||||
export function useRecentDealData() {
|
||||
const [recentDealData, setRecentDealData] = useState<RecentDealData>();
|
||||
|
||||
const fetchRecentDealData = async () => {
|
||||
setRecentDealData(await getRecentDealData());
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchRecentDealData();
|
||||
}, []);
|
||||
|
||||
return recentDealData;
|
||||
}
|
||||
@ -12,12 +12,13 @@ import { Overview } from "@/components/ui/overview";
|
||||
import { RecentFunds } from "@/components/recent-funds";
|
||||
import { useState } from "react";
|
||||
|
||||
import { useDealList, useGraphData } from "./hook";
|
||||
import { useDealList, useGraphData, useRecentDealData } from "./hook";
|
||||
|
||||
export default function Dashboard() {
|
||||
const [graphType, setGraphType] = useState("line");
|
||||
const graphData = useGraphData();
|
||||
const dealList = useDealList();
|
||||
const recentDealData = useRecentDealData();
|
||||
const totalDealAmount = dealList?.reduce((sum, deal) => sum + deal.deal_amount, 0) || 0;
|
||||
|
||||
return (
|
||||
@ -198,7 +199,7 @@ export default function Dashboard() {
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<RecentFunds>
|
||||
<RecentFunds recentDealData={recentDealData!}>
|
||||
</RecentFunds>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@ -1,59 +1,31 @@
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
|
||||
const data = [
|
||||
{
|
||||
name: "Olivia Martin",
|
||||
email: "olivia.martin@email.com",
|
||||
amount: "1900.00",
|
||||
avatar: "/avatars/01.png", // psuedo avatar image
|
||||
initials: "OM",
|
||||
},
|
||||
{
|
||||
name: "Jackson Lee",
|
||||
email: "jackson.lee@email.com",
|
||||
amount: "39.00",
|
||||
avatar: "/avatars/02.png",
|
||||
initials: "JL",
|
||||
},
|
||||
{
|
||||
name: "Isabella Nguyen",
|
||||
email: "isabella.nguyen@email.com",
|
||||
amount: "299.00",
|
||||
avatar: "/avatars/03.png",
|
||||
initials: "IN",
|
||||
},
|
||||
{
|
||||
name: "William Kim",
|
||||
email: "will@email.com",
|
||||
amount: "99.00",
|
||||
avatar: "/avatars/04.png",
|
||||
initials: "WK",
|
||||
},
|
||||
{
|
||||
name: "Sofia Davis",
|
||||
email: "sofia.davis@email.com",
|
||||
amount: "39.00",
|
||||
avatar: "/avatars/05.png",
|
||||
initials: "SD",
|
||||
},
|
||||
];
|
||||
type RecentDealData = {
|
||||
username: string;
|
||||
avatar_url: string;
|
||||
// email: string;
|
||||
};
|
||||
|
||||
export function RecentFunds() {
|
||||
interface RecentFundsProps {
|
||||
recentDealData: RecentDealData[];
|
||||
}
|
||||
|
||||
export function RecentFunds({ recentDealData }: RecentFundsProps) {
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
{data.map((person, index) => (
|
||||
{recentDealData?.map((person, index) => (
|
||||
<div className="flex items-center" key={index}>
|
||||
<Avatar className="h-9 w-9">
|
||||
<AvatarImage src={person.avatar} alt={person.name} />
|
||||
<AvatarFallback>{person.initials}</AvatarFallback>
|
||||
<AvatarImage src={person.avatar_url} alt={person.username} />
|
||||
{<AvatarFallback>{person.username[0]}</AvatarFallback>}
|
||||
</Avatar>
|
||||
<div className="ml-4 space-y-1">
|
||||
<p className="text-sm font-medium leading-none">{person.name}</p>
|
||||
<p className="text-sm text-muted-foreground">{person.email}</p>
|
||||
<p className="text-sm font-medium leading-none">{person.username}</p>
|
||||
{/* <p className="text-sm text-muted-foreground">{person.email}</p> */}
|
||||
</div>
|
||||
<div className="ml-auto font-medium">+${person.amount}</div>
|
||||
{/* <div className="ml-auto font-medium">+${person.amount}</div> */}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
0
src/hooks/useDealList.ts
Normal file
0
src/hooks/useDealList.ts
Normal file
Loading…
Reference in New Issue
Block a user