mirror of
https://github.com/reconurge/flowsint.git
synced 2026-03-12 01:44:42 -05:00
feat: icons
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
"use client"
|
||||
import React from 'react'
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { useIndividuals } from '@/lib/hooks/individuals/use-individuals';
|
||||
import { useInvestigationContext } from '@/components/contexts/investigation-provider';
|
||||
import { useIndividuals } from '@/lib/hooks/investigation/use-individuals';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { AtSignIcon, RotateCwIcon, UserIcon } from 'lucide-react';
|
||||
import { useEmails } from '@/lib/hooks/emails/use-emails';
|
||||
import { AtSignIcon, PhoneIcon, UserIcon } from 'lucide-react';
|
||||
import { useEmails } from '@/lib/hooks/investigation/use-emails';
|
||||
import { usePhones } from '@/lib/hooks/investigation/use-phones';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
@@ -18,6 +18,8 @@ import { useFlowStore } from '@/components/contexts/use-flow-store';
|
||||
const Left = ({ investigation_id }: { investigation_id: string }) => {
|
||||
const { individuals, isLoading: isLoadingIndividuals, refetch: refetchIndividuals } = useIndividuals(investigation_id)
|
||||
const { emails, isLoading: isLoadingEmails, refetch: refetchEmails } = useEmails(investigation_id)
|
||||
const { phones, isLoading: isLoadingPhones, refetch: refetchPhones } = usePhones(investigation_id)
|
||||
|
||||
const { currentNode, setCurrentNode } = useFlowStore()
|
||||
|
||||
return (
|
||||
@@ -72,6 +74,31 @@ const Left = ({ investigation_id }: { investigation_id: string }) => {
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
<Accordion type="single" collapsible defaultValue='phones'>
|
||||
<AccordionItem value="phones">
|
||||
<AccordionTrigger className='p-2 px-4 hover:bg-sidebar-accent text-sidebar-accent-foreground/60 hover:text-sidebar-accent-foreground text-sm rounded-none'>
|
||||
Phones {!isLoadingPhones && <>({phones?.length})</>}</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
{isLoadingPhones && <div className='flex flex-col gap-1'>
|
||||
<Skeleton className='w-full h-[20px] bg-foreground/10 rounded-none' />
|
||||
<Skeleton className='w-full h-[20px] bg-foreground/10 rounded-none' />
|
||||
<Skeleton className='w-full h-[20px] bg-foreground/10 rounded-none' />
|
||||
</div>
|
||||
}
|
||||
<ul>
|
||||
{phones?.map((phone: any) => (
|
||||
<li className={cn('hover:bg-sidebar-accent text-sidebar-accent-foreground/60 hover:text-sidebar-accent-foreground text-sm', currentNode === phone.id && "bg-sidebar-accent text-sidebar-accent-foreground")} key={phone.id}>
|
||||
<button onClick={() => setCurrentNode(phone.id)} className='flex items-center p-1 px-4 w-full gap-2'>
|
||||
<PhoneIcon className='h-3 w-3' />
|
||||
{phone.phone_number}
|
||||
</button>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</div >
|
||||
)
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ const LayoutFlow = ({ theme }: { theme: ColorMode }) => {
|
||||
proOptions={{ hideAttribution: true }}
|
||||
nodeTypes={nodeTypes}
|
||||
edgeTypes={edgeTypes}
|
||||
className='!bg-background'
|
||||
>
|
||||
<Panel position="top-left" className='flex items-center gap-1'>
|
||||
<Tooltip>
|
||||
@@ -131,7 +132,6 @@ const LayoutFlow = ({ theme }: { theme: ColorMode }) => {
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</Panel>
|
||||
|
||||
<Panel position="top-right" className='flex items-center gap-1'>
|
||||
<div className='flex flex-col items-end gap-2'>
|
||||
<div className='flex gap-1 items-center'>
|
||||
@@ -149,7 +149,6 @@ const LayoutFlow = ({ theme }: { theme: ColorMode }) => {
|
||||
)}
|
||||
</div>
|
||||
</Panel>
|
||||
|
||||
<Panel position="bottom-left" className='flex flex-col items-center gap-1'>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
|
||||
@@ -79,8 +79,8 @@ function Custom(props: any) {
|
||||
<Card
|
||||
onDoubleClick={() => handleOpenIndividualModal(data.id)}
|
||||
className={cn(
|
||||
"p-1 border border-border hover:border-primary/40 rounded-full shadow-none backdrop-blur bg-background/40",
|
||||
currentNode === data.id && "border-primary/40",
|
||||
"p-1 border border-border hover:border-primary/40 duration-100 rounded-full shadow-none backdrop-blur bg-background/40",
|
||||
currentNode === data.id && "border-primary",
|
||||
)}
|
||||
>
|
||||
<div className="flex gap-2 items-center rounded-full">
|
||||
|
||||
@@ -44,9 +44,10 @@ function SocialNode({ data }: any) {
|
||||
>
|
||||
<div className="flex items-center gap-2 p-1">
|
||||
{/* @ts-ignore */}
|
||||
<Badge variant="secondary" className={cn("h-6 h-6 w-6 p-0 rounded-full", `bg-${platformsIcons?.[data?.platform]?.color}-100`)}
|
||||
<Badge variant="secondary" className={cn("h-6 h-6 w-6 p-0 rounded-full")}
|
||||
>
|
||||
<MapPinIcon className="h-4 w-4" />
|
||||
{/* @ts-ignore */}
|
||||
{platformsIcons?.[data?.platform]?.icon}
|
||||
</Badge>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm">{data.username || data.profile_url}</span>
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import * as React from "react"
|
||||
|
||||
const MOBILE_BREAKPOINT = 768
|
||||
|
||||
export function useIsMobile() {
|
||||
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
|
||||
|
||||
React.useEffect(() => {
|
||||
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
|
||||
const onChange = () => {
|
||||
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
||||
}
|
||||
mql.addEventListener("change", onChange)
|
||||
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
||||
return () => mql.removeEventListener("change", onChange)
|
||||
}, [])
|
||||
|
||||
return !!isMobile
|
||||
}
|
||||
25
src/lib/hooks/investigation/use-phones.tsx
Normal file
25
src/lib/hooks/investigation/use-phones.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import { supabase } from "@/lib/supabase/client";
|
||||
import { useQuery } from "@supabase-cache-helpers/postgrest-swr";
|
||||
|
||||
export function usePhones(investigationId: string | null | undefined) {
|
||||
const { data: phones, mutate, isLoading, error } = useQuery(Boolean(investigationId) ?
|
||||
supabase
|
||||
.from('phone_numbers')
|
||||
.select(`
|
||||
*
|
||||
`)
|
||||
.eq("investigation_id", investigationId)
|
||||
: null,
|
||||
{
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false,
|
||||
}
|
||||
);
|
||||
return {
|
||||
phones: phones || null,
|
||||
isLoading,
|
||||
refetch: mutate,
|
||||
error: error
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useMemo } from "react"
|
||||
import { CameraIcon, FacebookIcon, InstagramIcon, MessageCircleDashedIcon, SendIcon } from 'lucide-react';
|
||||
import { CameraIcon, FacebookIcon, GithubIcon, InstagramIcon, MessageCircleDashedIcon, SendIcon } from 'lucide-react';
|
||||
|
||||
export const usePlatformIcons = (size = "small") => {
|
||||
const className = size === "small" ? 'h-3 w-3' : 'h-5 w-5'
|
||||
@@ -19,6 +19,9 @@ export const usePlatformIcons = (size = "small") => {
|
||||
"snapchat": {
|
||||
icon: <CameraIcon className={className} />, color: "yellow"
|
||||
},
|
||||
"github": {
|
||||
icon: <GithubIcon className={className} />, color: "gray"
|
||||
},
|
||||
}), [])
|
||||
return platformsIcons
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
--card-foreground: hsl(0 0% 3.9%);
|
||||
--popover: hsl(0 0% 100%);
|
||||
--popover-foreground: hsl(0 0% 3.9%);
|
||||
--primary: hsl(0 0% 9%);
|
||||
--primary: hsl(262.1 83.3% 57.8%);
|
||||
--primary-foreground: hsl(0 0% 98%);
|
||||
--secondary: hsl(0 0% 96.1%);
|
||||
--secondary-foreground: hsl(0 0% 9%);
|
||||
@@ -51,7 +51,7 @@
|
||||
--foreground: hsl(0 0% 98%);
|
||||
--card: hsl(0 0% 3.9%);
|
||||
--card-foreground: hsl(0 0% 98%);
|
||||
--popover: hsl(0 0% 3.9%);
|
||||
--popover: hsl(240 0% 9.9%);
|
||||
--popover-foreground: hsl(0 0% 98%);
|
||||
--primary: hsl(262.1 83.3% 57.8%);
|
||||
--primary-foreground: hsl(0, 0%, 100%);
|
||||
|
||||
Reference in New Issue
Block a user