Skip to content

Commit b84d7b4

Browse files
committed
Merge branch 'staging'
2 parents 76c857a + 0af0f60 commit b84d7b4

File tree

17 files changed

+389
-280
lines changed

17 files changed

+389
-280
lines changed

apps/dashboard/app/(main)/websites/[id]/_components/tabs/audience-tab.tsx

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import type { FullTabProps } from "../utils/types";
2525
import dayjs from "dayjs";
2626
import utc from "dayjs/plugin/utc";
2727
import timezone from "dayjs/plugin/timezone";
28+
import { ErrorBoundary } from "@/components/error-boundary";
2829
dayjs.extend(utc);
2930
dayjs.extend(timezone);
3031

@@ -582,6 +583,18 @@ export function WebsiteAudienceTab({
582583
[]
583584
);
584585

586+
// Feature detection for Intl.DisplayNames
587+
const canUseDisplayNames = useMemo(() => {
588+
if (typeof window === "undefined") return false;
589+
try {
590+
// Try to construct and use .of
591+
const dn = new Intl.DisplayNames([navigator.language || "en"], { type: "language" });
592+
return typeof dn.of === "function" && !!dn.of("en");
593+
} catch {
594+
return false;
595+
}
596+
}, []);
597+
585598
const displayNames = useMemo(
586599
() =>
587600
typeof window !== "undefined"
@@ -600,7 +613,12 @@ export function WebsiteAudienceTab({
600613
const entry = info.row.original;
601614
const language = entry.name;
602615
const code = (entry as any).code;
603-
const readableName = displayNames?.of(language) || language;
616+
let readableName = language;
617+
try {
618+
readableName = displayNames?.of(language) || language;
619+
} catch {
620+
readableName = language;
621+
}
604622
return (
605623
<div className="flex items-center gap-2">
606624
<Languages className="h-4 w-4 text-primary" />
@@ -688,7 +706,6 @@ export function WebsiteAudienceTab({
688706
[]
689707
);
690708

691-
// Prepare tabs for enhanced geographic data with unique keys
692709
const geographicTabs = useMemo(
693710
() => [
694711
{
@@ -718,15 +735,21 @@ export function WebsiteAudienceTab({
718735
})),
719736
columns: cityColumns,
720737
},
721-
{
722-
id: "languages",
723-
label: "Languages",
724-
data: processedData.geographic.languages.map((item, index) => ({
725-
...item,
726-
_uniqueKey: `language-${item.name}-${index}`,
727-
})),
728-
columns: languageColumns,
729-
},
738+
...(
739+
canUseDisplayNames
740+
? [
741+
{
742+
id: "languages",
743+
label: "Languages",
744+
data: processedData.geographic.languages.map((item, index) => ({
745+
...item,
746+
_uniqueKey: `language-${item.name}-${index}`,
747+
})),
748+
columns: languageColumns,
749+
},
750+
]
751+
: []
752+
),
730753
{
731754
id: "timezones",
732755
label: "Timezones",
@@ -748,6 +771,7 @@ export function WebsiteAudienceTab({
748771
cityColumns,
749772
languageColumns,
750773
timezoneColumns,
774+
canUseDisplayNames,
751775
]
752776
);
753777

@@ -831,14 +855,16 @@ export function WebsiteAudienceTab({
831855

832856
{/* Enhanced Geographic Data */}
833857
<div className="grid grid-cols-1 gap-4">
834-
<DataTable
835-
description="Visitors by location, timezone, and language (limit: 100 per category)"
836-
initialPageSize={8}
837-
isLoading={isLoading}
838-
minHeight={400}
839-
tabs={geographicTabs}
840-
title="Geographic Distribution"
841-
/>
858+
<ErrorBoundary>
859+
<DataTable
860+
description="Visitors by location, timezone, and language (limit: 100 per category)"
861+
initialPageSize={8}
862+
isLoading={isLoading}
863+
minHeight={400}
864+
tabs={geographicTabs}
865+
title="Geographic Distribution"
866+
/>
867+
</ErrorBoundary>
842868
</div>
843869

844870
{/* Screen Resolutions */}

0 commit comments

Comments
 (0)