mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-19 05:54:06 +01:00
refactor some json query + restructure recent funds json + make amount show in recent funds tab
This commit is contained in:
parent
f65fc2a696
commit
070077f7f3
@ -7,20 +7,14 @@ export type Deal = {
|
|||||||
investor_id: string;
|
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() {
|
export async function getDealList() {
|
||||||
const supabase = createSupabaseClient();
|
const supabase = createSupabaseClient();
|
||||||
const { data: dealData, error } = await supabase
|
// get id of investor who invests in the business
|
||||||
|
const { data: dealData, error: dealError } = await supabase
|
||||||
.from('business')
|
.from('business')
|
||||||
.select(`
|
.select(`
|
||||||
project (
|
project (
|
||||||
investment_deal (
|
investment_deal (
|
||||||
deal_amount,
|
|
||||||
created_time,
|
|
||||||
investor_id
|
investor_id
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -28,9 +22,9 @@ export async function getDealList() {
|
|||||||
.eq('user_id', await getCurrentUserID())
|
.eq('user_id', await getCurrentUserID())
|
||||||
.single();
|
.single();
|
||||||
|
|
||||||
if (error) {
|
if (dealError) {
|
||||||
alert(JSON.stringify(error));
|
alert(JSON.stringify(dealError));
|
||||||
console.error('Error fetching deal list:', error);
|
console.error('Error fetching deal list:', dealError);
|
||||||
return; // Exit on error
|
return; // Exit on error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,48 +33,71 @@ export async function getDealList() {
|
|||||||
return; // Exit if there's no data
|
return; // Exit if there's no data
|
||||||
}
|
}
|
||||||
|
|
||||||
const flattenedDeals = dealData.project.flatMap((proj) =>
|
const investorIdList = dealData.project[0].investment_deal.map(deal => deal.investor_id);
|
||||||
proj.investment_deal.map((deal) => ({
|
|
||||||
deal_amount: deal.deal_amount,
|
|
||||||
created_time: deal.created_time,
|
|
||||||
investor_id: deal.investor_id,
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
|
|
||||||
// Check for empty dealList
|
// get investment_deal data then sort by created_time
|
||||||
if (!flattenedDeals.length) {
|
const { data: sortedDealData, error: sortedDealDataError } = await supabase
|
||||||
alert("No deal list available");
|
.from("investment_deal")
|
||||||
return; // Exit if there's no data
|
.select(`
|
||||||
|
deal_amount,
|
||||||
|
created_time,
|
||||||
|
investor_id
|
||||||
|
`)
|
||||||
|
.in('investor_id', investorIdList)
|
||||||
|
.order('created_time', { ascending: false })
|
||||||
|
|
||||||
|
if (sortedDealDataError) {
|
||||||
|
alert(JSON.stringify(sortedDealDataError));
|
||||||
|
console.error('Error sorting deal list:', sortedDealDataError);
|
||||||
|
return; // Exit on error
|
||||||
}
|
}
|
||||||
return flattenedDeals.sort(byCreatedTimeDesc);
|
|
||||||
|
return sortedDealData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #TODO fix query to be non unique
|
||||||
export async function getRecentDealData() {
|
export async function getRecentDealData() {
|
||||||
const supabase = createSupabaseClient();
|
const supabase = createSupabaseClient();
|
||||||
let dealList = await getDealList();
|
const dealList = await getDealList();
|
||||||
|
|
||||||
if (!dealList) {
|
if (!dealList) {
|
||||||
// #TODO div no deals available?
|
// #TODO div error
|
||||||
|
console.error("No deal available");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dealList = dealList.slice(0, 5)
|
|
||||||
|
|
||||||
const investorIdList: string[] = dealList.map(deal => deal.investor_id);
|
// get 5 most recent investor
|
||||||
const { data: userData, error } = await supabase
|
const recentDealList = dealList.slice(0, 5);
|
||||||
|
const recentInvestorIdList = recentDealList.map(deal => deal.investor_id);
|
||||||
|
|
||||||
|
const { data: recentUserData, error: recentUserError } = await supabase
|
||||||
.from("profiles")
|
.from("profiles")
|
||||||
.select("username, avatar_url") // #TODO add email
|
.select(`
|
||||||
.in("id", investorIdList); // Filter by investor_id
|
username,
|
||||||
|
avatar_url
|
||||||
|
`)
|
||||||
|
.in('id', recentInvestorIdList);
|
||||||
|
|
||||||
if (error) {
|
if (!recentUserData) {
|
||||||
// Handle the error and return a meaningful message
|
alert("No recent users available");
|
||||||
console.error("Error fetching usernames and avatars:", error);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
alert(JSON.stringify(userData));
|
if (recentUserError) {
|
||||||
return userData || [];
|
// Handle the error and return a meaningful message
|
||||||
|
console.error("Error fetching profiles:", recentUserError);
|
||||||
|
return;
|
||||||
|
// #TODO div error
|
||||||
|
}
|
||||||
|
|
||||||
|
// combine two arrays
|
||||||
|
const recentDealData = recentDealList.map((item, index) => {
|
||||||
|
return { ...item, ...recentUserData[index] };
|
||||||
|
});
|
||||||
|
return recentDealData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #TODO refactor using supabase query instead of manual
|
||||||
// #TODO move to util
|
// #TODO move to util
|
||||||
export function convertToGraphData(deals: Deal[]): Record<string, number> {
|
export function convertToGraphData(deals: Deal[]): Record<string, number> {
|
||||||
// group by year & month
|
// group by year & month
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Deal, getDealList, convertToGraphData, getRecentDealData } from "../api/dealApi";
|
import { Deal, getDealList, convertToGraphData, getRecentDealData } from "../api/dealApi";
|
||||||
|
import { RecentDealData } from "@/components/recent-funds";
|
||||||
|
|
||||||
type RecentDealData = { username: string; avatar_url: string }[]
|
|
||||||
|
|
||||||
// custom hook for deal list
|
// custom hook for deal list
|
||||||
export function useDealList() {
|
export function useDealList() {
|
||||||
@ -37,7 +35,7 @@ export function useGraphData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useRecentDealData() {
|
export function useRecentDealData() {
|
||||||
const [recentDealData, setRecentDealData] = useState<RecentDealData>();
|
const [recentDealData, setRecentDealData] = useState<RecentDealData[]>();
|
||||||
|
|
||||||
const fetchRecentDealData = async () => {
|
const fetchRecentDealData = async () => {
|
||||||
setRecentDealData(await getRecentDealData());
|
setRecentDealData(await getRecentDealData());
|
||||||
|
|||||||
@ -18,18 +18,19 @@ export default function Dashboard() {
|
|||||||
const [graphType, setGraphType] = useState("line");
|
const [graphType, setGraphType] = useState("line");
|
||||||
const graphData = useGraphData();
|
const graphData = useGraphData();
|
||||||
const dealList = useDealList();
|
const dealList = useDealList();
|
||||||
const recentDealData = useRecentDealData();
|
// #TODO dependency injection refactor + define default value inside function (and not here)
|
||||||
|
const recentDealData = useRecentDealData() || [];
|
||||||
const totalDealAmount = dealList?.reduce((sum, deal) => sum + deal.deal_amount, 0) || 0;
|
const totalDealAmount = dealList?.reduce((sum, deal) => sum + deal.deal_amount, 0) || 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{dealList?.map((deal, index) => (
|
{/* {dealList?.map((deal, index) => (
|
||||||
<div key={index} className="deal-item">
|
<div key={index} className="deal-item">
|
||||||
<p>Deal Amount: {deal.deal_amount}</p>
|
<p>Deal Amount: {deal.deal_amount}</p>
|
||||||
<p>Created Time: {new Date(deal.created_time).toUTCString()}</p>
|
<p>Created Time: {new Date(deal.created_time).toUTCString()}</p>
|
||||||
<p>Investor ID: {deal.investor_id}</p>
|
<p>Investor ID: {deal.investor_id}</p>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))} */}
|
||||||
<div className="md:hidden">
|
<div className="md:hidden">
|
||||||
<Image
|
<Image
|
||||||
src="/examples/dashboard-light.png"
|
src="/examples/dashboard-light.png"
|
||||||
@ -199,7 +200,7 @@ export default function Dashboard() {
|
|||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<RecentFunds recentDealData={recentDealData!}>
|
<RecentFunds recentDealData={recentDealData}>
|
||||||
</RecentFunds>
|
</RecentFunds>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
|
|
||||||
type RecentDealData = {
|
export type RecentDealData = {
|
||||||
|
created_time: Date;
|
||||||
|
deal_amount: number;
|
||||||
|
investor_id: string;
|
||||||
username: string;
|
username: string;
|
||||||
avatar_url: string;
|
avatar_url?: string;
|
||||||
// email: string;
|
// email: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -13,19 +16,24 @@ interface RecentFundsProps {
|
|||||||
export function RecentFunds({ recentDealData }: RecentFundsProps) {
|
export function RecentFunds({ recentDealData }: RecentFundsProps) {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-8">
|
<div className="space-y-8">
|
||||||
{recentDealData?.map((person, index) => (
|
{recentDealData?.length > 0 ? (
|
||||||
<div className="flex items-center" key={index}>
|
recentDealData.map((data) => (
|
||||||
<Avatar className="h-9 w-9">
|
<div className="flex items-center" key={data.investor_id}>
|
||||||
<AvatarImage src={person.avatar_url} alt={person.username} />
|
<Avatar className="h-9 w-9">
|
||||||
{<AvatarFallback>{person.username[0]}</AvatarFallback>}
|
<AvatarImage src={data.avatar_url} alt={data.username} />
|
||||||
</Avatar>
|
{/* #TODO make this not quick fix */}
|
||||||
<div className="ml-4 space-y-1">
|
<AvatarFallback>{data.username ? data.username[0]: ""}</AvatarFallback>
|
||||||
<p className="text-sm font-medium leading-none">{person.username}</p>
|
</Avatar>
|
||||||
{/* <p className="text-sm text-muted-foreground">{person.email}</p> */}
|
<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>
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="ml-auto font-medium">+${person.amount}</div> */}
|
))
|
||||||
</div>
|
) : (
|
||||||
))}
|
<p>No recent deals available.</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user