feat: add lib

This commit is contained in:
dextmorgn
2025-04-05 12:06:04 +02:00
parent e96b5ec131
commit c48523d905
2 changed files with 185 additions and 185 deletions

View File

@@ -19,197 +19,197 @@ export default function ProfilePanel({ data, type }: { data: any, type: "individ
setCurrentNode(null)
}
if (type === "email") {
return (
<div className="overflow-auto h-full flex flex-col w-full !p-0 !m-0">
<Button className="absolute top-2 right-2" size={"icon"} variant={"ghost"} onClick={closePanel}><XIcon className="h-5 w-5" /></Button>
<div className="p-6 md:p-8">
<div className="grid grid-cols-1 gap-6">
{/* Left column with email info */}
<div className="space-y-6">
<div className="flex flex-col items-center gap-4">
<div className="bg-primary/10 p-3 rounded-full">
<Mail className="h-8 w-8 text-primary" />
</div>
<div className="w-full text-center">
<h2 className="text-xl w-full font-bold break-all">{data.email}</h2>
<p className="text-sm text-muted-foreground">Email Address</p>
</div>
<SearchEmail investigation_id={investigation_id as string} email={data.email} />
</div>
<Separator />
<div className="space-y-4 text-center">
<div className="space-y-1 text-center">
<div className="flex items-center justify-center gap-2 text-primary">
<Shield className="h-4 w-4" />
<span className="text-sm">Security Status</span>
</div>
<div className="flex gap-2 mt-1 items-center justify-center">
<Badge variant={data.breach_found ? "destructive" : "outline"} className="px-3 py-1">
{data.breach_found ? "Breach Found" : "No Breach Detected"}
</Badge>
</div>
</div>
<div className="space-y-1">
<div className="flex items-center justify-center gap-2 text-primary">
<Info className="h-4 w-4" />
<span className="text-sm">Email ID</span>
</div>
<p className="text-xs font-mono text-center text-muted-foreground">{data.id}</p>
</div>
</div>
</div>
{/* Right column with related info */}
<div className="space-y-6">
<div className="space-y-1">
<div className="flex items-center justify-center gap-2 text-primary">
<Link2 className="h-4 w-4" />
<span className="text-sm">Associated Individual</span>
</div>
<p className="text-xs font-mono text-center text-muted-foreground">{data.individual_id}</p>
</div>
<div className="space-y-1">
<div className="flex items-center justify-center gap-2 text-primary">
<Info className="h-4 w-4" />
<span className="text-sm">Investigation ID</span>
</div>
<p className="text-xs font-mono text-center text-muted-foreground">{data.investigation_id}</p>
</div>
</div>
</div>
</div>
</div>)
}
if (type === "individual")
return (
<div className="overflow-auto h-full flex flex-col w-full !p-0 !m-0">
<Button className="absolute top-2 right-2" size={"icon"} variant={"ghost"} onClick={closePanel}><XIcon className="h-5 w-5" /></Button>
<div className="p-6 md:p-8">
<div className="grid grid-cols-1 gap-2">
{/* Left column with avatar */}
<div className="flex flex-col items-center gap-6">
<div className="relative flex flex-col items-center gap-4">
<Avatar className="w-28 h-28 border-4">
<AvatarImage src={data.image_url} alt={data.full_name} />
<AvatarFallback className="text-2xl">
{data.full_name
.split(" ")
.map((n: any[]) => n[0])
.join("")}
</AvatarFallback>
</Avatar>
<Link href={`/dashboard/projects/${project_id}/individuals/${data.id}`}>
<Button variant={"outline"}>View</Button>
</Link>
</div>
<div className="space-y-1 text-center">
<div className="flex items-center justify-center gap-2 text-primary">
<User className="h-4 w-4" />
<span className="text-sm">Full Name</span>
</div>
<h1 className="text-2xl font-bold tracking-tight">{data.full_name}</h1>
</div>
// if (type === "email") {
// return (
// <div className="overflow-auto h-full flex flex-col w-full !p-0 !m-0">
// <Button className="absolute top-2 right-2" size={"icon"} variant={"ghost"} onClick={closePanel}><XIcon className="h-5 w-5" /></Button>
// <div className="p-6 md:p-8">
// <div className="grid grid-cols-1 gap-6">
// {/* Left column with email info */}
// <div className="space-y-6">
// <div className="flex flex-col items-center gap-4">
// <div className="bg-primary/10 p-3 rounded-full">
// <Mail className="h-8 w-8 text-primary" />
// </div>
// <div className="w-full text-center">
// <h2 className="text-xl w-full font-bold break-all">{data.email}</h2>
// <p className="text-sm text-muted-foreground">Email Address</p>
// </div>
// <SearchEmail investigation_id={investigation_id as string} email={data.email} />
// </div>
// <Separator />
// <div className="space-y-4 text-center">
// <div className="space-y-1 text-center">
// <div className="flex items-center justify-center gap-2 text-primary">
// <Shield className="h-4 w-4" />
// <span className="text-sm">Security Status</span>
// </div>
// <div className="flex gap-2 mt-1 items-center justify-center">
// <Badge variant={data.breach_found ? "destructive" : "outline"} className="px-3 py-1">
// {data.breach_found ? "Breach Found" : "No Breach Detected"}
// </Badge>
// </div>
// </div>
// <div className="space-y-1">
// <div className="flex items-center justify-center gap-2 text-primary">
// <Info className="h-4 w-4" />
// <span className="text-sm">Email ID</span>
// </div>
// <p className="text-xs font-mono text-center text-muted-foreground">{data.id}</p>
// </div>
// </div>
// </div>
// {/* Right column with related info */}
// <div className="space-y-6">
// <div className="space-y-1">
// <div className="flex items-center justify-center gap-2 text-primary">
// <Link2 className="h-4 w-4" />
// <span className="text-sm">Associated Individual</span>
// </div>
// <p className="text-xs font-mono text-center text-muted-foreground">{data.individual_id}</p>
// </div>
// <div className="space-y-1">
// <div className="flex items-center justify-center gap-2 text-primary">
// <Info className="h-4 w-4" />
// <span className="text-sm">Investigation ID</span>
// </div>
// <p className="text-xs font-mono text-center text-muted-foreground">{data.investigation_id}</p>
// </div>
// </div>
// </div>
// </div>
// </div>)
// }
// if (type === "individual")
// return (
// <div className="overflow-auto h-full flex flex-col w-full !p-0 !m-0">
// <Button className="absolute top-2 right-2" size={"icon"} variant={"ghost"} onClick={closePanel}><XIcon className="h-5 w-5" /></Button>
// <div className="p-6 md:p-8">
// <div className="grid grid-cols-1 gap-2">
// {/* Left column with avatar */}
// <div className="flex flex-col items-center gap-6">
// <div className="relative flex flex-col items-center gap-4">
// <Avatar className="w-28 h-28 border-4">
// <AvatarImage src={data.image_url} alt={data.full_name} />
// <AvatarFallback className="text-2xl">
// {data.full_name
// .split(" ")
// .map((n: any[]) => n[0])
// .join("")}
// </AvatarFallback>
// </Avatar>
// <Link href={`/dashboard/projects/${project_id}/individuals/${data.id}`}>
// <Button variant={"outline"}>View</Button>
// </Link>
// </div>
// <div className="space-y-1 text-center">
// <div className="flex items-center justify-center gap-2 text-primary">
// <User className="h-4 w-4" />
// <span className="text-sm">Full Name</span>
// </div>
// <h1 className="text-2xl font-bold tracking-tight">{data.full_name}</h1>
// </div>
<div className="space-y-1 text-center">
<div className="flex items-center justify-center gap-2 text-primary">
<Info className="h-4 w-4" />
<span className="text-sm">Investigation ID</span>
</div>
<p className="text-sm font-mono">{data.investigation_id}</p>
</div>
</div>
// <div className="space-y-1 text-center">
// <div className="flex items-center justify-center gap-2 text-primary">
// <Info className="h-4 w-4" />
// <span className="text-sm">Investigation ID</span>
// </div>
// <p className="text-sm font-mono">{data.investigation_id}</p>
// </div>
// </div>
{/* Middle column */}
<div className="space-y-6">
<div className="space-y-1">
<div className="flex items-center justify-center gap-2 text-primary">
<AtSign className="h-4 w-4" />
<span className="text-sm text-center">Email</span>
</div>
{data?.emails?.length > 0 ? (
<p className="font-medium text-center">{data?.emails?.[0].email}</p>
) : (
<p className="text-gray-500 text-center">No email available</p>
)}
</div>
// {/* Middle column */}
// <div className="space-y-6">
// <div className="space-y-1">
// <div className="flex items-center justify-center gap-2 text-primary">
// <AtSign className="h-4 w-4" />
// <span className="text-sm text-center">Email</span>
// </div>
// {data?.emails?.length > 0 ? (
// <p className="font-medium text-center">{data?.emails?.[0].email}</p>
// ) : (
// <p className="text-gray-500 text-center">No email available</p>
// )}
// </div>
<div className="space-y-1">
<div className="flex items-center justify-center gap-2 text-primary">
<Globe className="h-4 w-4" />
<span className="text-sm text-center">Nationality</span>
</div>
<p className="font-medium text-center">{data.nationality || "Unknown"}</p>
</div>
// <div className="space-y-1">
// <div className="flex items-center justify-center gap-2 text-primary">
// <Globe className="h-4 w-4" />
// <span className="text-sm text-center">Nationality</span>
// </div>
// <p className="font-medium text-center">{data.nationality || "Unknown"}</p>
// </div>
<div className="space-y-1">
<div className="flex items-center justify-center gap-2 text-primary">
<User className="h-4 w-4" />
<span className="text-sm text-center">Gender</span>
</div>
<p className="font-medium text-center">{data.gender || "Unknown"}</p>
</div>
// <div className="space-y-1">
// <div className="flex items-center justify-center gap-2 text-primary">
// <User className="h-4 w-4" />
// <span className="text-sm text-center">Gender</span>
// </div>
// <p className="font-medium text-center">{data.gender || "Unknown"}</p>
// </div>
{data?.phone_numbers?.length > 0 && (
<div className="space-y-1">
<div className="flex items-center justify-center gap-2 text-primary">
<Phone className="h-4 w-4" />
<span className="text-sm text-center">Phone Number</span>
</div>
<p className="font-medium text-center">{data?.phone_numbers?.[0]}</p>
</div>
)}
</div>
// {data?.phone_numbers?.length > 0 && (
// <div className="space-y-1">
// <div className="flex items-center justify-center gap-2 text-primary">
// <Phone className="h-4 w-4" />
// <span className="text-sm text-center">Phone Number</span>
// </div>
// <p className="font-medium text-center">{data?.phone_numbers?.[0]}</p>
// </div>
// )}
// </div>
{/* Right column */}
<div className="space-y-6">
{data.birth_date && (
<div className="space-y-1">
<div className="flex items-center justify-center gap-2 text-primary">
<Calendar className="h-4 w-4" />
<span className="text-sm text-center">Birth Date</span>
</div>
<p className="font-medium text-center">{data.birth_date}</p>
</div>
)}
// {/* Right column */}
// <div className="space-y-6">
// {data.birth_date && (
// <div className="space-y-1">
// <div className="flex items-center justify-center gap-2 text-primary">
// <Calendar className="h-4 w-4" />
// <span className="text-sm text-center">Birth Date</span>
// </div>
// <p className="font-medium text-center">{data.birth_date}</p>
// </div>
// )}
<div className="space-y-1">
<div className="flex items-center justify-center gap-2 text-primary">
<Info className="h-4 w-4" />
<span className="text-sm text-center">Email Security</span>
</div>
<div className="flex gap-2 mt-1 justify-center">
{data?.emails?.length > 0 && (
<Badge
variant={data.emails?.[0].breach_found ? "destructive" : "outline"}
>
{data.emails?.[0].breach_found ? "Breach Found" : "No Breach"}
</Badge>
)}
</div>
</div>
// <div className="space-y-1">
// <div className="flex items-center justify-center gap-2 text-primary">
// <Info className="h-4 w-4" />
// <span className="text-sm text-center">Email Security</span>
// </div>
// <div className="flex gap-2 mt-1 justify-center">
// {data?.emails?.length > 0 && (
// <Badge
// variant={data.emails?.[0].breach_found ? "destructive" : "outline"}
// >
// {data.emails?.[0].breach_found ? "Breach Found" : "No Breach"}
// </Badge>
// )}
// </div>
// </div>
{data.physical_addresses?.length > 0 && (
<div className="space-y-1">
<div className="flex items-center justify-center gap-2 text-primary">
<MapPin className="h-4 w-4" />
<span className="text-sm text-center">Location</span>
</div>
<p className="font-medium text-center">{data.physical_addresses?.[0]}</p>
</div>
)}
// {data.physical_addresses?.length > 0 && (
// <div className="space-y-1">
// <div className="flex items-center justify-center gap-2 text-primary">
// <MapPin className="h-4 w-4" />
// <span className="text-sm text-center">Location</span>
// </div>
// <p className="font-medium text-center">{data.physical_addresses?.[0]}</p>
// </div>
// )}
<div className="space-y-1">
<div className="flex items-center justify-center gap-2 text-primary">
<Info className="h-4 w-4" />
<span className="text-sm">Individual ID</span>
</div>
<p className="text-xs font-mono text-gray-400 text-center">{data.id}</p>
</div>
</div>
</div>
</div>
</div>
)
// <div className="space-y-1">
// <div className="flex items-center justify-center gap-2 text-primary">
// <Info className="h-4 w-4" />
// <span className="text-sm">Individual ID</span>
// </div>
// <p className="text-xs font-mono text-gray-400 text-center">{data.id}</p>
// </div>
// </div>
// </div>
// </div>
// </div>
// )
return (
<KeyValueDisplay data={data} />
@@ -224,7 +224,7 @@ interface KeyValueDisplayProps {
function KeyValueDisplay({ data, className }: KeyValueDisplayProps) {
return (
<div className={cn("w-full overflow-y-auto h-full border-collapse ", className)}>
{Object.entries(data).map(([key, value], index) => (
{data && Object.entries(data).map(([key, value], index) => (
<div key={index} className="flex w-full border-b border-border divide-x divide-border">
<div className="w-1/2 bg-background px-4 p-2 text-sm font-medium text-muted-foreground">{key}</div>
<div className="w-1/2 bg-background px-4 p-2 text-sm font-medium">{value?.toString() || ""}</div>

View File

@@ -10,8 +10,8 @@ export const BaseNode = forwardRef<
className={cn(
"relative rounded-md border bg-background p-2 flex items-center justify-between text-card-foreground",
className,
selected ? "border-muted-foreground shadow-lg" : "",
"hover:ring-1",
selected ? "border-primary shadow-lg" : "",
"hover:border-primary",
)}
tabIndex={0}
{...props}