Commit 3bff33f8 authored by Max Alekseenko's avatar Max Alekseenko

add mixpanel events

parent b89c3a17
......@@ -98,8 +98,12 @@ Type extends EventTypes.PAGE_WIDGET ? (
{
'Type': 'Tokens dropdown' | 'Tokens show all (icon)' | 'Add to watchlist' | 'Address actions (more button)';
} | {
'Type': 'Favorite app' | 'More button';
'Type': 'Favorite app' | 'More button' | 'Security score' | 'Total contracts' | 'Verified contracts' | 'Analyzed contracts';
'Info': string;
'Source': 'Discovery view' | 'Security view' | 'App modal' | 'App page' | 'Security score popup';
} | {
'Type': 'Security score';
'Source': 'Analyzed contracts popup';
}
) :
Type extends EventTypes.TX_INTERPRETATION_INTERACTION ? {
......
......@@ -3,20 +3,33 @@ import React from 'react';
import config from 'configs/app';
import { apos } from 'lib/html-entities';
import * as mixpanel from 'lib/mixpanel/index';
import IconSvg from 'ui/shared/IconSvg';
import SolidityscanReportButton from 'ui/shared/solidityscanReport/SolidityscanReportButton';
import SolidityscanReportDetails from 'ui/shared/solidityscanReport/SolidityscanReportDetails';
import SolidityscanReportScore from 'ui/shared/solidityscanReport/SolidityscanReportScore';
type Props = {
id: string;
securityReport?: any; // eslint-disable-line @typescript-eslint/no-explicit-any
height?: string | undefined;
showContractList: () => void;
isLoading?: boolean;
onlyIcon?: boolean;
source: 'Security view' | 'App modal' | 'App page';
}
const AppSecurityReport = ({ securityReport, height, showContractList, isLoading, onlyIcon }: Props) => {
const AppSecurityReport = ({ id, securityReport, height, showContractList, isLoading, onlyIcon, source }: Props) => {
const handleButtonClick = React.useCallback(() => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'Security score', Info: id, Source: source });
}, [ id, source ]);
const handleLinkClick = React.useCallback(() => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'Analyzed contracts', Info: id, Source: 'Security score popup' });
showContractList();
}, [ id, showContractList ]);
if (!securityReport && !isLoading) {
return null;
}
......@@ -34,6 +47,7 @@ const AppSecurityReport = ({ securityReport, height, showContractList, isLoading
height={ height }
score={ securityScore }
onlyIcon={ onlyIcon }
onClick={ handleButtonClick }
popoverContent={ (
<>
<Box mb={ 5 }>
......@@ -47,7 +61,7 @@ const AppSecurityReport = ({ securityReport, height, showContractList, isLoading
<SolidityscanReportDetails vulnerabilities={ issueSeverityDistribution } vulnerabilitiesCount={ totalIssues }/>
</Box>
) }
<Link onClick={ showContractList } display="inline-flex" alignItems="center">
<Link onClick={ handleLinkClick } display="inline-flex" alignItems="center">
Analyzed contracts
<IconSvg name="arrows/north-east" boxSize={ 5 } color="gray.400"/>
</Link>
......
......@@ -2,6 +2,7 @@ import { Box, Text } from '@chakra-ui/react';
import React from 'react';
import config from 'configs/app';
import * as mixpanel from 'lib/mixpanel/index';
import LinkExternal from 'ui/shared/LinkExternal';
import SolidityscanReportButton from 'ui/shared/solidityscanReport/SolidityscanReportButton';
import SolidityscanReportDetails from 'ui/shared/solidityscanReport/SolidityscanReportDetails';
......@@ -22,9 +23,14 @@ const ContractSecurityReport = ({ securityReport }: Props) => {
const totalIssues = Object.values(issueSeverityDistribution as Record<string, number>).reduce((acc, val) => acc + val, 0);
const handleClick = React.useCallback(() => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'Security score', Source: 'Analyzed contracts popup' });
}, [ ]);
return (
<SolidityscanReportButton
score={ securityScore }
onClick={ handleClick }
popoverContent={ (
<>
<Box mb={ 5 }>
......
......@@ -13,7 +13,7 @@ import MarketplaceAppIntegrationIcon from './MarketplaceAppIntegrationIcon';
interface Props extends MarketplaceAppPreview {
onInfoClick: (id: string) => void;
isFavorite: boolean;
onFavoriteClick: (id: string, isFavorite: boolean) => void;
onFavoriteClick: (id: string, isFavorite: boolean, source: 'Discovery view') => void;
isLoading: boolean;
onAppClick: (event: MouseEvent, id: string) => void;
}
......@@ -38,12 +38,12 @@ const MarketplaceAppCard = ({
const handleInfoClick = useCallback((event: MouseEvent) => {
event.preventDefault();
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'More button', Info: id });
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'More button', Info: id, Source: 'Discovery view' });
onInfoClick(id);
}, [ onInfoClick, id ]);
const handleFavoriteClick = useCallback(() => {
onFavoriteClick(id, isFavorite);
onFavoriteClick(id, isFavorite, 'Discovery view');
}, [ onFavoriteClick, id, isFavorite ]);
const logoUrl = useColorModeValue(logo, logoDarkMode || logo);
......
......@@ -10,6 +10,7 @@ import { ContractListTypes } from 'types/client/marketplace';
import useFeatureValue from 'lib/growthbook/useFeatureValue';
import useIsMobile from 'lib/hooks/useIsMobile';
import { nbsp } from 'lib/html-entities';
import * as mixpanel from 'lib/mixpanel/index';
import type { IconName } from 'ui/shared/IconSvg';
import IconSvg from 'ui/shared/IconSvg';
......@@ -20,7 +21,7 @@ import MarketplaceAppModalLink from './MarketplaceAppModalLink';
type Props = {
onClose: () => void;
isFavorite: boolean;
onFavoriteClick: (id: string, isFavorite: boolean) => void;
onFavoriteClick: (id: string, isFavorite: boolean, source: 'App modal') => void;
data: MarketplaceAppWithSecurityReport;
showContractList: (id: string, type: ContractListTypes) => void;
}
......@@ -71,7 +72,7 @@ const MarketplaceAppModal = ({
}
const handleFavoriteClick = useCallback(() => {
onFavoriteClick(id, isFavorite);
onFavoriteClick(id, isFavorite, 'App modal');
}, [ onFavoriteClick, id, isFavorite ]);
const showContractList = useCallback((type: ContractListTypes) => {
......@@ -80,12 +81,14 @@ const MarketplaceAppModal = ({
}, [ onClose, showContractListDefault, id ]);
const showAllContracts = React.useCallback(() => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'Total contracts', Info: id, Source: 'App modal' });
showContractList(ContractListTypes.ALL);
}, [ showContractList ]);
}, [ showContractList, id ]);
const showVerifiedContracts = React.useCallback(() => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'Verified contracts', Info: id, Source: 'App modal' });
showContractList(ContractListTypes.VERIFIED);
}, [ showContractList ]);
}, [ showContractList, id ]);
const showAnalyzedContracts = React.useCallback(() => {
showContractList(ContractListTypes.ANALYZED);
......@@ -174,7 +177,12 @@ const MarketplaceAppModal = ({
{ (isExperiment && securityReport) && (
<Flex alignItems="center" gap={ 3 }>
<AppSecurityReport securityReport={ securityReport } showContractList={ showAnalyzedContracts }/>
<AppSecurityReport
id={ id }
securityReport={ securityReport }
showContractList={ showAnalyzedContracts }
source="App modal"
/>
<ContractListButton
onClick={ showAllContracts }
variant={ ContractListButtonVariants.ALL_CONTRACTS }
......
......@@ -61,10 +61,12 @@ const MarketplaceAppTopBar = ({ data, isLoading, isWalletConnected, securityRepo
{ (isExperiment && (securityReport || isLoading)) && (
<Box order={{ base: 3, md: 4 }}>
<AppSecurityReport
id={ data?.id || '' }
securityReport={ securityReport }
showContractList={ setShowContractList.on }
isLoading={ isLoading }
onlyIcon={ isMobile }
source="App page"
/>
</Box>
) }
......
......@@ -11,7 +11,7 @@ type Props = {
apps: Array<MarketplaceAppPreview>;
showAppInfo: (id: string) => void;
favoriteApps: Array<string>;
onFavoriteClick: (id: string, isFavorite: boolean) => void;
onFavoriteClick: (id: string, isFavorite: boolean, source: 'Discovery view') => void;
isLoading: boolean;
selectedCategoryId?: string;
onAppClick: (event: MouseEvent, id: string) => void;
......
......@@ -14,7 +14,7 @@ interface Props {
apps: Array<MarketplaceAppWithSecurityReport>;
showAppInfo: (id: string) => void;
favoriteApps: Array<string>;
onFavoriteClick: (id: string, isFavorite: boolean) => void;
onFavoriteClick: (id: string, isFavorite: boolean, source: 'Security view') => void;
isLoading: boolean;
selectedCategoryId?: string;
onAppClick: (event: MouseEvent, id: string) => void;
......
......@@ -18,7 +18,7 @@ type Props = {
app: MarketplaceAppPreview & { securityReport?: any }; // eslint-disable-line @typescript-eslint/no-explicit-any
onInfoClick: (id: string) => void;
isFavorite: boolean;
onFavoriteClick: (id: string, isFavorite: boolean) => void;
onFavoriteClick: (id: string, isFavorite: boolean, source: 'Security view') => void;
isLoading: boolean;
onAppClick: (event: MouseEvent, id: string) => void;
showContractList: (id: string, type: ContractListTypes) => void;
......@@ -29,19 +29,21 @@ const ListItem = ({ app, onInfoClick, isFavorite, onFavoriteClick, isLoading, on
const handleInfoClick = React.useCallback((event: MouseEvent) => {
event.preventDefault();
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'More button', Info: id });
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'More button', Info: id, Source: 'Security view' });
onInfoClick(id);
}, [ onInfoClick, id ]);
const handleFavoriteClick = React.useCallback(() => {
onFavoriteClick(id, isFavorite);
onFavoriteClick(id, isFavorite, 'Security view');
}, [ onFavoriteClick, id, isFavorite ]);
const showAllContracts = React.useCallback(() => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'Total contracts', Info: id, Source: 'Security view' });
showContractList(id, ContractListTypes.ALL);
}, [ showContractList, id ]);
const showVerifiedContracts = React.useCallback(() => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'Verified contracts', Info: id, Source: 'Security view' });
showContractList(id, ContractListTypes.VERIFIED);
}, [ showContractList, id ]);
......@@ -96,10 +98,12 @@ const ListItem = ({ app, onInfoClick, isFavorite, onFavoriteClick, isLoading, on
{ (securityReport || isLoading) ? (
<>
<AppSecurityReport
id={ id }
isLoading={ isLoading }
securityReport={ securityReport }
showContractList={ showAnalyzedContracts }
height="30px"
source="Security view"
/>
<ContractListButton
onClick={ showAllContracts }
......
......@@ -12,7 +12,7 @@ type Props = {
apps: Array<MarketplaceAppPreview>;
isLoading?: boolean;
favoriteApps: Array<string>;
onFavoriteClick: (id: string, isFavorite: boolean) => void;
onFavoriteClick: (id: string, isFavorite: boolean, source: 'Security view') => void;
onAppClick: (event: MouseEvent, id: string) => void;
onInfoClick: (id: string) => void;
showContractList: (id: string, type: ContractListTypes) => void;
......
......@@ -17,7 +17,7 @@ type Props = {
app: MarketplaceAppPreview & { securityReport?: any }; // eslint-disable-line @typescript-eslint/no-explicit-any
isLoading?: boolean;
isFavorite: boolean;
onFavoriteClick: (id: string, isFavorite: boolean) => void;
onFavoriteClick: (id: string, isFavorite: boolean, source: 'Security view') => void;
onAppClick: (event: MouseEvent, id: string) => void;
onInfoClick: (id: string) => void;
showContractList: (id: string, type: ContractListTypes) => void;
......@@ -37,19 +37,21 @@ const TableItem = ({
const handleInfoClick = React.useCallback((event: MouseEvent) => {
event.preventDefault();
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'More button', Info: id });
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'More button', Info: id, Source: 'Security view' });
onInfoClick(id);
}, [ onInfoClick, id ]);
const handleFavoriteClick = React.useCallback(() => {
onFavoriteClick(id, isFavorite);
onFavoriteClick(id, isFavorite, 'Security view');
}, [ onFavoriteClick, id, isFavorite ]);
const showAllContracts = React.useCallback(() => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'Total contracts', Info: id, Source: 'Security view' });
showContractList(id, ContractListTypes.ALL);
}, [ showContractList, id ]);
const showVerifiedContracts = React.useCallback(() => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'Verified contracts', Info: id, Source: 'Security view' });
showContractList(id, ContractListTypes.VERIFIED);
}, [ showContractList, id ]);
......@@ -83,9 +85,11 @@ const TableItem = ({
<>
<Td verticalAlign="middle">
<AppSecurityReport
id={ id }
securityReport={ securityReport }
showContractList={ showAnalyzedContracts }
isLoading={ isLoading }
source="Security view"
/>
</Td>
<Td verticalAlign="middle">
......
......@@ -42,8 +42,8 @@ export default function useMarketplace() {
const [ isDisclaimerModalOpen, setIsDisclaimerModalOpen ] = React.useState<boolean>(false);
const [ contractListModalType, setContractListModalType ] = React.useState<ContractListTypes | null>(null);
const handleFavoriteClick = React.useCallback((id: string, isFavorite: boolean) => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'Favorite app', Info: id });
const handleFavoriteClick = React.useCallback((id: string, isFavorite: boolean, source: 'Discovery view' | 'Security view' | 'App modal') => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'Favorite app', Info: id, Source: source });
const favoriteApps = getFavoriteApps();
......
......@@ -21,12 +21,18 @@ interface Props {
isLoading?: boolean;
height?: string;
onlyIcon?: boolean;
onClick?: () => void;
}
const SolidityscanReportButton = ({ className, score, popoverContent, isLoading, height = '32px', onlyIcon }: Props) => {
const SolidityscanReportButton = ({ className, score, popoverContent, isLoading, height = '32px', onlyIcon, onClick }: Props) => {
const { isOpen, onToggle, onClose } = useDisclosure();
const { scoreColor } = useScoreLevelAndColor(score);
const handleClick = React.useCallback(() => {
onClick?.();
onToggle();
}, [ onClick, onToggle ]);
return (
<Popover isOpen={ isOpen } onClose={ onClose } placement="bottom-start" isLazy>
<PopoverTrigger>
......@@ -37,7 +43,7 @@ const SolidityscanReportButton = ({ className, score, popoverContent, isLoading,
size="sm"
variant="outline"
colorScheme="gray"
onClick={ onToggle }
onClick={ handleClick }
aria-label="SolidityScan score"
fontWeight={ 500 }
px="6px"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment