Skip to content

Commit

Permalink
Move expand with AI button around
Browse files Browse the repository at this point in the history
  • Loading branch information
tubarao312 committed Mar 6, 2024
1 parent 1b104e3 commit 95a1bff
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 113 deletions.
2 changes: 1 addition & 1 deletion src/components/graph/analysis_window/AnalysisWindow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ const DraggableWindow: FC<DraggableWindowProps> = ({
width:
analysisMode.name === AnalysisModeNames.Advanced
? "68rem"
: "55rem",
: "61rem",
transition: "width 0.5s ease-in-out, opacity 0.2s ease-in-out",
}}
onMouseEnter={() => {
Expand Down
113 changes: 104 additions & 9 deletions src/components/graph/analysis_window/content/overview/Overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ import clsx from "clsx";
import {
ArrowDownLeftIcon,
ArrowUpRightIcon,
ArrowsPointingInIcon,
ArrowsRightLeftIcon,
BuildingLibraryIcon,
IdentificationIcon,
InformationCircleIcon,
} from "@heroicons/react/16/solid";
import { CheckIcon, PlusIcon } from "@heroicons/react/20/solid";
import { CheckIcon, PlusIcon, SparklesIcon } from "@heroicons/react/20/solid";
import { Transition } from "@headlessui/react";

import { Category } from "../../../../../api/model";
Expand All @@ -30,6 +33,13 @@ import { AnalysisContext } from "../../AnalysisWindow";

import "../../../../common/Scrollbar.css";
import { logAnalyticsEvent } from "../../../../../services/firestore/analytics/analytics";
import WithPremium, { WithPremiumProps } from "../../../../premium/WithPremium";
import { AddressAnalysis } from "../../../../../api/model";
import { PathExpansionArgs } from "../../../Graph";
import useAuthState from "../../../../../hooks/useAuthState";
import { useFreeTierExpandWithAIUsage } from "../../../../../services/firestore/user/free_usage";
import getExpandWithAIPaths from "../../../expand_with_ai";
import { addFreeTierExpandWithAIInteraction } from "../../../../../services/firestore/user/free_usage";

/** There can be 3 incoming states for an entity row:
* - **Outgoing**: The address is sending funds to the entity
Expand Down Expand Up @@ -213,7 +223,7 @@ const EntityRow: FC<EntityRowProps> = ({
</span>
</span>
{showExpandButton ? (
<BigButton text={expandButtonText} Icon={PlusIcon} onClick={() => { }} />
<BigButton text={expandButtonText} Icon={PlusIcon} onClick={() => {}} />
) : (
<h3 className="flex flex-row items-center gap-x-1 text-sm font-semibold tracking-wide text-gray-400">
<CheckIcon className="h-5 w-5 rounded-full text-gray-400" />
Expand All @@ -224,6 +234,78 @@ const EntityRow: FC<EntityRowProps> = ({
);
};

interface ExpandWithAIProps extends WithPremiumProps {
analysisData: AddressAnalysis;
addMultipleDifferentPaths: (args: PathExpansionArgs[]) => void;
}

const ExpandWithAI: FC<ExpandWithAIProps> = ({
analysisData,
addMultipleDifferentPaths,
handleActionRequiringAuth,
handleActionRequiringPremium,
}) => {
const { user } = useAuthState();
const userID = useMemo(() => (user ? user.uid : ""), [user]);
const { hasReachedUsageLimit } = useFreeTierExpandWithAIUsage(userID);

const expandWithAI = useCallback((analysisData: AddressAnalysis) => {
// Get the paths for the AI to expand
const paths = getExpandWithAIPaths(analysisData);

// Add the paths to the graph
addMultipleDifferentPaths(paths);
}, []);

return (
<button
onClick={async () => {
handleActionRequiringAuth({
pathname: "graph",
});
if (hasReachedUsageLimit) {
handleActionRequiringPremium({
successPath: "graph",
cancelPath: "graph",
});
}

await addFreeTierExpandWithAIInteraction(userID);

expandWithAI(analysisData!);
logAnalyticsEvent("expand_addresses_with_AI");
}}
className="group mr-6 flex h-11 flex-row items-center justify-center gap-x-1.5 rounded-md bg-indigo-50 px-3 py-2 text-sm font-semibold text-indigo-900 shadow-md shadow-indigo-500/25 ring-1 ring-inset ring-indigo-300 transition-all ease-in-out hover:bg-indigo-100 hover:shadow-lg hover:shadow-indigo-500/25 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2"
>
<SparklesIcon className="h-5 w-5 text-indigo-400" />
Expand w/AI
<div className="pointer-events-none absolute z-10 mb-0.5 mr-48 mt-48 w-max origin-top scale-50 divide-y divide-gray-700 rounded-lg bg-gray-800 px-3 py-3 text-white opacity-0 shadow-sm transition-all duration-300 ease-in-out group-hover:scale-100 group-hover:opacity-100">
<div className="flex flex-row items-center gap-x-1.5 pb-1">
<InformationCircleIcon className="h-5 w-5 text-indigo-200" />
<h1 className="text-base font-semibold leading-7">Expand w/AI</h1>
</div>
<div className="flex max-w-xs flex-col gap-y-1.5 pt-1 text-xs font-normal text-gray-400">
The AI algorithm will expand based on the following criteria:
<ul className="flex flex-col gap-y-2 pl-3 text-white">
<li className="flex flex-row items-center gap-x-1">
<IdentificationIcon className="h-5 w-5 text-indigo-200" />
<span className="font-bold">Highest risk</span>categories of
addresses
</li>
<li className="flex flex-row items-center gap-x-1">
<ArrowsPointingInIcon className="h-5 w-5 text-indigo-200" />
<span className="font-bold">Most relevant</span> multi-hop paths
</li>
</ul>
</div>
</div>
</button>
);
};

// Expand with AI with authentication
const ExpandWithAIWithPremium = WithPremium(ExpandWithAI);

const Overview: FC = () => {
const focusedAddressData = useContext(GraphContext).focusedAddressData!;

Expand Down Expand Up @@ -271,10 +353,18 @@ const Overview: FC = () => {
// TODO - Add a max height and a scrollbar, maybe a slight fade effect to the bottom and top
return (
<div className="flex h-full flex-col gap-y-2">
<h3 className="flex h-fit flex-row items-center gap-x-1 text-sm font-semibold tracking-wide text-gray-600">
<BuildingLibraryIcon className="h-5 w-5 text-gray-400" />
TOP ENTITIES
</h3>
<span className="flex h-fit w-full flex-row items-end justify-between">
<h3 className="flex h-fit flex-row items-center gap-x-1 text-sm font-semibold tracking-wide text-gray-600">
<BuildingLibraryIcon className="h-5 w-5 text-gray-400" />
TOP ENTITIES
</h3>
<ExpandWithAIWithPremium
analysisData={focusedAddressData}
addMultipleDifferentPaths={
useContext(GraphContext).addMultipleDifferentPaths
}
/>
</span>
<ul className="scrollbar flex flex-grow scroll-m-28 flex-col gap-y-1.5 overflow-scroll overflow-x-hidden">
{topEntityRows.map((row, index) => (
<Transition
Expand All @@ -292,9 +382,14 @@ const Overview: FC = () => {
}}
key={row.entity + focusedAddressData.address}
>
<div onClick={() => {
logAnalyticsEvent("expand_address", { page: "overview", address: focusedAddressData.address })
}}>
<div
onClick={() => {
logAnalyticsEvent("expand_address", {
page: "overview",
address: focusedAddressData.address,
});
}}
>
<EntityRow
entity={row.entity}
totalIncoming={row.totalIncoming}
Expand Down
111 changes: 8 additions & 103 deletions src/components/graph/analysis_window/header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
import {
ArrowsPointingInIcon,
IdentificationIcon,
InformationCircleIcon,
} from "@heroicons/react/20/solid";

import { SparklesIcon, XMarkIcon } from "@heroicons/react/24/solid";
import { XMarkIcon } from "@heroicons/react/24/solid";

import { TrashIcon } from "@heroicons/react/24/outline";

import { XMarkIcon as XMarkSmallIcon } from "@heroicons/react/16/solid";

import clsx from "clsx";
import { FC, useCallback, useContext, useMemo } from "react";

import { AddressAnalysis } from "../../../../api/model";
import { FC, useCallback, useContext } from "react";

import {
addCustomAddressTag,
Expand All @@ -38,19 +30,9 @@ import {
AnalysisModes,
} from "../AnalysisWindow";

import { PathExpansionArgs } from "../../Graph";

import WithAuth, { WithAuthProps } from "../../../auth/WithAuth";
import useAuthState from "../../../../hooks/useAuthState";
import { logAnalyticsEvent } from "../../../../services/firestore/analytics/analytics";
import WithPremium, { WithPremiumProps } from "../../../premium/WithPremium";
import TagInput from "./TagInput";
import {
addFreeTierExpandWithAIInteraction,
useFreeTierExpandWithAIUsage,
} from "../../../../services/firestore/user/free_usage";

import getExpandWithAIPaths from "../../expand_with_ai";

interface ModeButtonProps {
isActive: boolean;
Expand Down Expand Up @@ -84,11 +66,11 @@ const ModeButton: FC<ModeButtonProps> = ({
/>
<p
className="w-fit overflow-hidden"
style={{
maxWidth: isActive ? "5rem" : "0px",
opacity: isActive ? 1 : 0,
transition: "all 0.3s ease-in-out",
}}
// style={{
// maxWidth: isActive ? "5rem" : "0px",
// opacity: isActive ? 1 : 0,
// transition: "all 0.3s ease-in-out",
// }}
>
{analysisMode.name}
</p>
Expand Down Expand Up @@ -201,79 +183,6 @@ const LabelsAndTags: FC<LabelsAndTagsProps> = ({
// The tag input will only be shown if the user is authenticated
const LabelsAndTagsWithAuth = WithAuth(LabelsAndTags);

// Expand with AI -------------------------------------------------------------
interface ExpandWithAIProps extends WithPremiumProps {
analysisData: AddressAnalysis;
addMultipleDifferentPaths: (args: PathExpansionArgs[]) => void;
}

const ExpandWithAI: FC<ExpandWithAIProps> = ({
analysisData,
addMultipleDifferentPaths,
handleActionRequiringAuth,
handleActionRequiringPremium,
}) => {
const { user } = useAuthState();
const userID = useMemo(() => (user ? user.uid : ""), [user]);
const { hasReachedUsageLimit } = useFreeTierExpandWithAIUsage(userID);

const expandWithAI = useCallback((analysisData: AddressAnalysis) => {
// Get the paths for the AI to expand
const paths = getExpandWithAIPaths(analysisData);

// Add the paths to the graph
addMultipleDifferentPaths(paths);
}, []);

return (
<div className="group flex flex-row items-center justify-center">
<SparklesIcon
onClick={async () => {
handleActionRequiringAuth({
pathname: "graph",
});

if (hasReachedUsageLimit) {
handleActionRequiringPremium({
successPath: "graph",
cancelPath: "graph",
});
}

await addFreeTierExpandWithAIInteraction(userID);

expandWithAI(analysisData!);
logAnalyticsEvent("expand_addresses_with_AI");
}}
className="h-11 w-11 cursor-pointer rounded-md p-1.5 text-indigo-400 transition-all duration-150 ease-in-out hover:bg-indigo-50 "
/>
<div className="pointer-events-none absolute mb-48 mt-0.5 w-max origin-bottom scale-50 divide-y divide-gray-700 rounded-lg bg-gray-800 px-3 py-3 text-white opacity-0 shadow-sm transition-all duration-300 ease-in-out group-hover:scale-100 group-hover:opacity-100">
<div className="flex flex-row items-center gap-x-1.5 pb-1">
<InformationCircleIcon className="h-5 w-5 text-indigo-200" />
<h1 className="text-base font-semibold leading-7">Expand w/AI</h1>
</div>
<div className="flex max-w-xs flex-col gap-y-1.5 pt-1 text-xs font-normal text-gray-400">
The AI algorithm will expand based on the following criteria:
<ul className="flex flex-col gap-y-2 pl-3 text-white">
<li className="flex flex-row items-center gap-x-1">
<IdentificationIcon className="h-5 w-5 text-indigo-200" />
<span className="font-bold">Highest risk</span>categories of
addresses
</li>
<li className="flex flex-row items-center gap-x-1">
<ArrowsPointingInIcon className="h-5 w-5 text-indigo-200" />
<span className="font-bold">Most relevant</span> multi-hop paths
</li>
</ul>
</div>
</div>
</div>
);
};

// Expand with AI with authentication
const ExpandWithAIWithPremium = WithPremium(ExpandWithAI);

interface HeaderProps {
onExit: () => void;
setAnalysisMode: (mode: AnalysisMode) => void;
Expand All @@ -286,7 +195,7 @@ const Header: FC<HeaderProps> = ({
analysisMode,
}: HeaderProps) => {
// Extract analysisData from context
const { addMultipleDifferentPaths, deleteNodes } = useContext(GraphContext);
const { deleteNodes } = useContext(GraphContext);
const { analysisData, address } = useContext(AnalysisContext);

// When minimized, the address hash should be sliced off
Expand Down Expand Up @@ -336,10 +245,6 @@ const Header: FC<HeaderProps> = ({
/>

<span className="flex flex-row">
<ExpandWithAIWithPremium
analysisData={analysisData!}
addMultipleDifferentPaths={addMultipleDifferentPaths}
/>
<div className="group flex flex-row items-center justify-center">
<TrashIcon
onClick={() => {
Expand Down

0 comments on commit 95a1bff

Please sign in to comment.