diff --git a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/profiles/[profileId]/profile-metrics/profile-metrics.tsx b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/profiles/[profileId]/profile-metrics/profile-metrics.tsx index 0ec5a4d2..79d0f80b 100644 --- a/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/profiles/[profileId]/profile-metrics/profile-metrics.tsx +++ b/apps/dashboard/src/app/(app)/[organizationSlug]/[projectId]/profiles/[profileId]/profile-metrics/profile-metrics.tsx @@ -1,6 +1,7 @@ 'use client'; import { useNumber } from '@/hooks/useNumerFormatter'; +import { utc } from '@/utils/date'; import { formatDistanceToNow } from 'date-fns'; import type { IProfileMetrics } from '@openpanel/db'; @@ -18,7 +19,7 @@ const ProfileMetrics = ({ data }: Props) => { First seen
- {formatDistanceToNow(data.firstSeen)} + {formatDistanceToNow(utc(data.firstSeen))}
@@ -26,7 +27,7 @@ const ProfileMetrics = ({ data }: Props) => { Last seen
- {formatDistanceToNow(data.lastSeen)} + {formatDistanceToNow(utc(data.lastSeen))}
diff --git a/apps/dashboard/src/components/overview/overview-top-devices.tsx b/apps/dashboard/src/components/overview/overview-top-devices.tsx index 6bc56c3b..e38dc46d 100644 --- a/apps/dashboard/src/components/overview/overview-top-devices.tsx +++ b/apps/dashboard/src/components/overview/overview-top-devices.tsx @@ -196,6 +196,75 @@ export default function OverviewTopDevices({ metric: 'sum', }, }, + brands: { + title: 'Top Brands', + btn: 'Brands', + chart: { + limit: 10, + projectId, + startDate, + endDate, + events: [ + { + segment: 'user', + filters, + id: 'A', + name: isPageFilter ? 'screen_view' : 'session_start', + }, + ], + breakdowns: [ + { + id: 'A', + name: 'brand', + }, + ], + chartType, + lineType: 'monotone', + interval: interval, + name: 'Top Brands', + range: range, + previous: previous, + metric: 'sum', + }, + }, + models: { + title: 'Top Models', + btn: 'Models', + chart: { + renderSerieName(name) { + return name[1] || NOT_SET_VALUE; + }, + limit: 10, + projectId, + startDate, + endDate, + events: [ + { + segment: 'user', + filters, + id: 'A', + name: isPageFilter ? 'screen_view' : 'session_start', + }, + ], + breakdowns: [ + { + id: 'A', + name: 'brand', + }, + { + id: 'B', + name: 'model', + }, + ], + chartType, + lineType: 'monotone', + interval: interval, + name: 'Top Models', + range: range, + previous: previous, + metric: 'sum', + }, + }, }); return ( diff --git a/apps/dashboard/src/components/report/chart/SerieIcon.urls.ts b/apps/dashboard/src/components/report/chart/SerieIcon.urls.ts index 4f0cdb04..072a99e1 100644 --- a/apps/dashboard/src/components/report/chart/SerieIcon.urls.ts +++ b/apps/dashboard/src/components/report/chart/SerieIcon.urls.ts @@ -2,6 +2,18 @@ const data = { 'chromium os': 'https://upload.wikimedia.org/wikipedia/commons/2/28/Chromium_Logo.svg', 'mac os': 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/30/MacOS_logo.svg/1200px-MacOS_logo.svg.png', + 'apple': 'https://sladesportfolio.wordpress.com/wp-content/uploads/2015/08/apple_logo_black-svg.png', + 'huawei': 'https://upload.wikimedia.org/wikipedia/en/0/04/Huawei_Standard_logo.svg', + 'xiaomi': 'https://upload.wikimedia.org/wikipedia/commons/2/29/Xiaomi_logo.svg', + 'sony': 'https://serialtrainer7.com/wp-content/uploads/2021/07/sony-logo-300px-square.png', + 'lg': 'https://upload.wikimedia.org/wikipedia/commons/2/20/LG_symbol.svg', + 'samsung': 'https://seekvectors.com/storage/images/Samsung-Logo-22.svg', + 'oppo': 'https://indoleads.nyc3.cdn.digitaloceanspaces.com/uploads/offers/logos/8695_95411e367b832.png', + 'motorola': 'https://upload.wikimedia.org/wikipedia/commons/8/8f/Motorola_M_symbol_blue.svg', + 'oneplus': 'https://pbs.twimg.com/profile_images/1709165009148809216/ebHb4xhF_400x400.png', + 'asus': 'https://cdn-icons-png.freepik.com/512/5969/5969050.png', + 'fairphone': 'https://cdn.dribbble.com/users/433772/screenshots/2109827/fairphone_dribbble.jpg', + 'nokia': 'https://www.gizchina.com/wp-content/uploads/images/2023/02/Nokia-logo.webp', 'mobile safari': 'https://upload.wikimedia.org/wikipedia/commons/5/52/Safari_browser_logo.svg', 'openpanel.dev': 'https://openpanel.dev', 'samsung internet': 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/Samsung_Internet_logo.svg/1024px-Samsung_Internet_logo.svg.png', diff --git a/apps/dashboard/src/components/report/funnel/Funnel.tsx b/apps/dashboard/src/components/report/funnel/Funnel.tsx index 08811578..e5011646 100644 --- a/apps/dashboard/src/components/report/funnel/Funnel.tsx +++ b/apps/dashboard/src/components/report/funnel/Funnel.tsx @@ -194,7 +194,7 @@ export function FunnelSteps({
{step.count} - + */}
diff --git a/apps/dashboard/src/utils/date.ts b/apps/dashboard/src/utils/date.ts index d784672f..36d44cea 100644 --- a/apps/dashboard/src/utils/date.ts +++ b/apps/dashboard/src/utils/date.ts @@ -45,3 +45,10 @@ const ta = new TimeAgo(getLocale()); export function timeAgo(date: Date, style?: FormatStyleName) { return ta.format(new Date(date), style); } + +export function utc(date: string) { + if (date.match(/^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.\d{3}$/)) { + return new Date(`${date}Z`); + } + return new Date(date).toISOString(); +} diff --git a/packages/db/src/services/profile.service.ts b/packages/db/src/services/profile.service.ts index d6935f78..b457a398 100644 --- a/packages/db/src/services/profile.service.ts +++ b/packages/db/src/services/profile.service.ts @@ -5,7 +5,6 @@ import type { IChartEventFilter } from '@openpanel/validation'; import { ch, chQuery } from '../clickhouse-client'; import { createSqlBuilder } from '../sql-builder'; -import { getEventFiltersWhereClause } from './chart.service'; export type IProfileMetrics = { lastSeen: string;