Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
r4zendev committed Dec 31, 2024
1 parent eb3d3fb commit 4bf285e
Show file tree
Hide file tree
Showing 2 changed files with 225 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
import { adsProviderAdapter } from '@/components';
import { AdsProviders, severityToDisplaySeverity } from '@/components/templates/report/constants';
import { TAdsProvider } from '@/components/templates/report/types';
import { SeverityType } from '@ballerine/common';
import dayjs from 'dayjs';
import { capitalize } from 'string-ts';

const getLabel = ({ label, provider }: { label: string; provider: string }) => {
if (label === 'page') {
return `${provider} Page`;
}

return label;
};

export const toRiskLabels = (riskIndicators: Array<{ name: string; riskLevel: string }>) => {
if (!Array.isArray(riskIndicators) || !riskIndicators.length) {
return [];
}

return riskIndicators.map(({ name, riskLevel, ...rest }) => ({
label: name,
severity:
severityToDisplaySeverity[riskLevel as keyof typeof severityToDisplaySeverity] ?? riskLevel,
}));
};

const normalizeRiskLevel = (riskTypeLevels: Record<string, SeverityType>) => {
return Object.entries(riskTypeLevels).reduce((acc, [riskType, riskLevel]) => {
acc[riskType] =
severityToDisplaySeverity[riskLevel as keyof typeof severityToDisplaySeverity] ?? riskLevel;

return acc;
}, {} as Record<string, SeverityType>);
};

const normalizeHyphenedDataString = (str: string) => {
const parts = str.split(' - ');

return {
label: capitalize(parts.length > 1 ? parts.slice(0, -1).join(' - ') : parts.at(0) ?? 'Unknown'),
value: parts.at(-1),
};
};

export const reportAdapter = {
DEFAULT: (report: Record<string, any>) => {
return {
websitesCompanyAnalysis: toRiskLabels(
report?.summary?.riskIndicatorsByDomain?.companyNameViolations,
),
adsAndSocialMediaAnalysis: toRiskLabels(
report?.summary?.riskIndicatorsByDomain?.adsAndSocialViolations,
),
adsAndSocialMediaPresence: [
...Object.entries({ facebook: report?.socialMedia?.facebookData ?? {} }),
...Object.entries({ instagram: report?.socialMedia?.instagramData ?? {} }),
]
.map(([provider, data]) => {
if (!AdsProviders.includes(provider.toUpperCase() as TAdsProvider)) {
return;
}

const adapter = adsProviderAdapter[provider as keyof typeof adsProviderAdapter];
const adaptedData = adapter(data);

return {
label: provider,
items: Object.entries(adaptedData).map(([label, value]) => ({
label: getLabel({
label,
provider,
}),
value,
})),
};
})
?.filter((value): value is NonNullable<typeof value> => Boolean(value)),
websiteLineOfBusinessAnalysis:
report?.summary?.riskIndicatorsByDomain?.lineOfBusinessViolations?.map(
({
name,
riskLevel,
sourceUrl,
screenshot,
explanation,
}: {
name: string;
riskLevel: string;
sourceUrl: string;
screenshot: {
screenshotUrl: string;
};
explanation: string;
}) => ({
label: name,
severity:
severityToDisplaySeverity[riskLevel as keyof typeof severityToDisplaySeverity] ??
riskLevel,
screenshotUrl: screenshot?.screenshotUrl,
sourceUrl,
explanation,
}),
),
ecosystemAnalysis: toRiskLabels(report?.summary?.riskIndicatorsByDomain?.ecosystemViolations),
ecosystemMatches: report?.ecosystem?.domains?.map(
({
domain,
relatedNode,
relatedNodeType,
indicator,
}: {
domain: string;
relatedNode: string;
relatedNodeType: string;
indicator: Record<
string,
{
name: string;
riskLevel: string;
}
>;
}) => ({
matchedName: domain,
relatedNode,
relatedNodeType: relatedNodeType,
indicators: {
label: indicator?.name,
severity:
severityToDisplaySeverity[
indicator?.riskLevel as unknown as keyof typeof severityToDisplaySeverity
] ?? indicator?.riskLevel,
},
}),
),
websiteCredibilityAnalysis: toRiskLabels(
report?.summary?.riskIndicatorsByDomain?.tldViolations,
),
adsImages: [
...Object.entries({ facebook: report?.socialMedia?.facebookData ?? {} }),
...Object.entries({ instagram: report?.socialMedia?.instagramData ?? {} }),
]
.map(([provider, data]) => ({
provider,
src: data?.screenshotUrl,
link: data?.pageUrl,
}))
.filter(({ src }: { src: string }) => !!src),
relatedAdsImages: report?.socialMedia?.pickedAds
?.map((data: { screenshotUrl: string; link: string }) => ({
src: data?.screenshotUrl,
link: data?.link,
}))
.filter(({ src }: { src: string }) => !!src),
onlineReputationAnalysis: report?.transactionLaundering?.scamOrFraud?.indicators
?.filter(({ violation }: { violation: string }) => !!violation)
?.map(({ violation, sourceUrl }: { violation: string; sourceUrl: string }) => ({
label: violation,
url: sourceUrl,
})),
summary: report?.summary?.summary,
ongoingMonitoringSummary: report?.summary?.ongoingMonitoringSummary,
riskScore: report?.summary?.riskScore,
riskLevels: normalizeRiskLevel(report?.summary?.riskLevels ?? {}),
companyReputationAnalysis: report?.websiteCompanyAnalysis?.scamOrFraud?.indicators
?.filter(({ violation }: { violation: string }) => !!violation)
?.map(({ violation, sourceUrl }: { violation: string; sourceUrl: string }) => ({
label: violation,
url: sourceUrl,
})),
lineOfBusinessDescription: report?.lineOfBusiness?.lobDescription,
relatedAdsSummary: report?.socialMedia?.relatedAds?.summary,
pricingAnalysis: report?.transactionLaundering?.pricingAnalysis?.indicators,
websiteStructureAndContentEvaluation:
report?.transactionLaundering?.websiteStructureEvaluation?.indicators,
// Example data:
// {
// "trafficSources": [
// "search / organic - 46.31%",
// "direct - 42.68%"
// ],
// "engagements": [
// "Time on site - 117.09 seconds",
// "Page per visit - 2.71",
// "Bounce rate - 44.76%"
// ],
// "montlyVisitsIndicators": [
// "May 2024 - 1987263",
// "June 2024 - 3500503",
// "July 2024 - 1671071",
// "August 2024 - 1793033",
// "September 2024 - 2520118",
// "October 2024 - 3384101"
// ]
// }
trafficAnalysis: {
montlyVisitsIndicators: (
report?.transactionLaundering?.trafficAnalysis?.montlyVisitsIndicators ?? []
).map((item: string) => {
const normalized = normalizeHyphenedDataString(item);

return {
label: dayjs(normalized.label, 'MMMM YYYY').format('MMM YYYY'),
value: normalized.value,
};
}),
trafficSources: (report?.transactionLaundering?.trafficAnalysis?.trafficSources ?? []).map(
normalizeHyphenedDataString,
),
engagements: (report?.transactionLaundering?.trafficAnalysis?.engagements ?? []).map(
normalizeHyphenedDataString,
),
},
homepageScreenshotUrl: report?.homepageScreenshot,
formattedMcc: report?.lineOfBusiness?.formattedMcc,
};
},
} as const;
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import { ctw } from '@/common';
import { Card, CardContent, CardHeader } from '@/components';
import { BallerineLink } from '@/components/atoms/BallerineLink/BallerineLink';
import { RiskIndicators } from '@/components/molecules/RiskIndicators/RiskIndicators';
import { FunctionComponent } from 'react';
import {
Bar,
BarChart,
CartesianGrid,
Cell,
Legend,
Pie,
PieChart,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis,
} from 'recharts';
import React, { FunctionComponent } from 'react';
import { Card, CardContent, CardHeader } from '@/components';
import { ctw } from '@/common';
import { BallerineLink } from '@/components/atoms/BallerineLink/BallerineLink';

export const WebsiteCredibility: FunctionComponent<{
violations: Array<{
Expand Down Expand Up @@ -119,7 +117,7 @@ export const WebsiteCredibility: FunctionComponent<{
barSize={46}
>
<CartesianGrid vertical={false} strokeDasharray="0" />
<XAxis dataKey="label" />
<XAxis dataKey="label" fill="rgb(144, 144, 144)" />
<YAxis />
<Tooltip />
{/* <Legend verticalAlign="top" align={'right'} content={<CustomLegend />} /> */}
Expand All @@ -131,7 +129,7 @@ export const WebsiteCredibility: FunctionComponent<{
<div className="flex flex-col gap-8 h-full w-2/5">
<ResponsiveContainer width="100%" height="50%">
<PieChart>
<text
{/* <text
x={35}
y={37}
textAnchor="middle"
Expand All @@ -141,7 +139,7 @@ export const WebsiteCredibility: FunctionComponent<{
// })}
>
Hello world
</text>
</text> */}
<Pie
data={trafficAnalysis.trafficSources}
cx={30}
Expand Down

0 comments on commit 4bf285e

Please sign in to comment.