Files
stats/apps/dashboard/src/components/report-chart/common/serie-icon.tsx
Carl-Gerhard Lindesvärd 32e91959f6 chore(root): migrate to biome
2024-09-18 23:46:11 +02:00

104 lines
2.2 KiB
TypeScript

import type { LucideIcon, LucideProps } from 'lucide-react';
import {
ActivityIcon,
ExternalLinkIcon,
HelpCircleIcon,
MailIcon,
MessageCircleIcon,
MonitorIcon,
MonitorPlayIcon,
PodcastIcon,
ScanIcon,
SearchIcon,
SmartphoneIcon,
TabletIcon,
TvIcon,
} from 'lucide-react';
import { useMemo } from 'react';
import { NOT_SET_VALUE } from '@openpanel/constants';
import flags from './serie-icon.flags';
import iconsWithUrls from './serie-icon.urls';
type SerieIconProps = Omit<LucideProps, 'name'> & {
name?: string | string[];
};
function getProxyImage(url: string) {
return `${String(process.env.NEXT_PUBLIC_API_URL)}/misc/favicon?url=${encodeURIComponent(url)}`;
}
const createImageIcon = (url: string) => {
return ((_props: LucideProps) => (
<img
alt="serie icon"
className="max-h-4 rounded-[2px] object-contain"
src={url}
/>
)) as LucideIcon;
};
const mapper: Record<string, LucideIcon> = {
// Events
screen_view: MonitorPlayIcon,
session_start: ActivityIcon,
session_end: ActivityIcon,
link_out: ExternalLinkIcon,
// Misc
smarttv: TvIcon,
mobile: SmartphoneIcon,
desktop: MonitorIcon,
tablet: TabletIcon,
search: SearchIcon,
social: PodcastIcon,
email: MailIcon,
podcast: PodcastIcon,
comment: MessageCircleIcon,
unknown: HelpCircleIcon,
[NOT_SET_VALUE]: ScanIcon,
...Object.entries(iconsWithUrls).reduce(
(acc, [key, value]) => ({
...acc,
[key]: createImageIcon(getProxyImage(value)),
}),
{},
),
...flags,
};
export function SerieIcon({ name: names, ...props }: SerieIconProps) {
const name = Array.isArray(names) ? names[0] : names;
const Icon = useMemo(() => {
if (!name) {
return null;
}
const mapped = mapper[name.toLowerCase()] ?? null;
if (mapped) {
return mapped;
}
if (name.includes('http')) {
return createImageIcon(getProxyImage(name));
}
// Matching image file name
if (name.match(/(.+)\.\w{2,3}$/)) {
return createImageIcon(getProxyImage(`https://${name}`));
}
return null;
}, [name]);
return Icon ? (
<div className="relative max-h-4 flex-shrink-0 [&_svg]:!rounded-[2px]">
<Icon size={16} {...props} name={name} />
</div>
) : null;
}