Skip to content

Commit 9e6bc29

Browse files
committed
feat(dashboard): add primary logo to overview chart and key tables
Introduce SectionBrandOverlay (inline + corner layouts) and show the primary logo in Traffic Trends and Traffic Sources/Pages headers via DataTable showBrandInHeader. Table toolbar uses a ghost icon button for fullscreen; fullscreen modal matches optional header branding.
1 parent 24749ca commit 9e6bc29

5 files changed

Lines changed: 78 additions & 14 deletions

File tree

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
} from "@/components/analytics";
1919
import { MetricsChartWithAnnotations } from "@/components/charts/metrics-chart-with-annotations";
2020
import { BrowserIcon, OSIcon } from "@/components/icon";
21+
import { SectionBrandOverlay } from "@/components/logo/section-brand-overlay";
2122
import { DataTable } from "@/components/table/data-table";
2223
import {
2324
createMetricColumns,
@@ -941,12 +942,12 @@ export function WebsiteOverviewTab({
941942

942943
{/* Chart */}
943944
<div className="rounded border bg-sidebar">
944-
<div className="flex flex-col items-start justify-between gap-3 border-b px-3 py-2.5 sm:flex-row sm:px-4 sm:py-3">
945+
<div className="flex flex-row items-start justify-between gap-3 border-b px-3 py-2.5 sm:items-center sm:px-4 sm:py-3">
945946
<div className="min-w-0 flex-1">
946-
<h2 className="font-semibold text-base text-sidebar-foreground sm:text-lg">
947+
<h2 className="text-balance font-semibold text-base text-sidebar-foreground sm:text-lg">
947948
Traffic Trends
948949
</h2>
949-
<p className="text-sidebar-foreground/70 text-xs sm:text-sm">
950+
<p className="text-pretty text-sidebar-foreground/70 text-xs sm:text-sm">
950951
{dateRange.granularity === "hourly" ? "Hourly" : "Daily"} traffic
951952
data
952953
</p>
@@ -963,6 +964,7 @@ export function WebsiteOverviewTab({
963964
</div>
964965
)}
965966
</div>
967+
<SectionBrandOverlay layout="inline" />
966968
</div>
967969
<div className="overflow-x-auto">
968970
<MetricsChartWithAnnotations
@@ -992,6 +994,7 @@ export function WebsiteOverviewTab({
992994
isLoading={isLoading}
993995
minHeight={350}
994996
onAddFilter={onAddFilter}
997+
showBrandInHeader
995998
tabs={referrerTabs}
996999
title="Traffic Sources"
9971000
/>
@@ -1001,6 +1004,7 @@ export function WebsiteOverviewTab({
10011004
isLoading={isLoading}
10021005
minHeight={350}
10031006
onAddFilter={onAddFilter}
1007+
showBrandInHeader
10041008
tabs={pagesTabs as any}
10051009
title="Pages"
10061010
/>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Branding } from "@/components/logo/branding";
2+
import { cn } from "@/lib/utils";
3+
4+
export type SectionBrandOverlayProps = {
5+
className?: string;
6+
/** Corner overlay vs inline (e.g. chart card header). */
7+
layout?: "overlay" | "inline";
8+
/** When `layout` is `overlay`: horizontal corner. */
9+
position?: "start" | "end";
10+
};
11+
12+
export function SectionBrandOverlay({
13+
className,
14+
layout = "overlay",
15+
position = "end",
16+
}: SectionBrandOverlayProps) {
17+
if (layout === "inline") {
18+
return (
19+
<div
20+
aria-hidden
21+
className={cn(
22+
"inline-flex shrink-0 items-center opacity-60",
23+
className
24+
)}
25+
>
26+
<Branding heightPx={24} variant="primary-logo" />
27+
</div>
28+
);
29+
}
30+
31+
return (
32+
<div
33+
aria-hidden
34+
className={cn(
35+
"pointer-events-none absolute bottom-2 z-10 inline-flex items-center opacity-60",
36+
position === "end" ? "inset-e-2" : "inset-s-2",
37+
className
38+
)}
39+
>
40+
<Branding heightPx={24} variant="primary-logo" />
41+
</div>
42+
);
43+
}

apps/dashboard/components/table/data-table.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ interface DataTableProps<TData extends { name: string | number }, TValue> {
4949
expandable?: boolean;
5050
/** Native title on Share column; omit for default visitor-share explanation; pass "" to hide. */
5151
shareColumnTooltip?: string;
52+
/** Primary logo in the card header (e.g. overview screenshots). */
53+
showBrandInHeader?: boolean;
5254
}
5355

5456
const SKELETON_ROW_WIDTHS = ["60%", "45%", "55%", "35%", "50%"] as const;
@@ -91,6 +93,7 @@ export function DataTable<TData extends { name: string | number }, TValue>({
9193
onAddFilter,
9294
onRowAction,
9395
shareColumnTooltip,
96+
showBrandInHeader = false,
9497
}: DataTableProps<TData, TValue>) {
9598
const [activeTab, setActiveTab] = useState(tabs?.[0]?.id || "");
9699

@@ -125,6 +128,7 @@ export function DataTable<TData extends { name: string | number }, TValue>({
125128
<TableToolbar
126129
borderBottom={!tabs}
127130
description={description}
131+
showBrand={showBrandInHeader}
128132
showFullScreen={false}
129133
title={title}
130134
/>
@@ -160,6 +164,7 @@ export function DataTable<TData extends { name: string | number }, TValue>({
160164
borderBottom={!tabs}
161165
description={description}
162166
onFullScreenToggle={() => setFullScreen(true)}
167+
showBrand={showBrandInHeader}
163168
title={title}
164169
/>
165170

@@ -222,6 +227,7 @@ export function DataTable<TData extends { name: string | number }, TValue>({
222227
onTabChange={handleTabChange}
223228
renderSubRow={renderSubRow}
224229
shareColumnTooltip={shareColumnTooltip}
230+
showBrand={showBrandInHeader}
225231
tabs={tabs}
226232
title={title}
227233
/>

apps/dashboard/components/table/fullscreen-modal.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
getCoreRowModel,
55
useReactTable,
66
} from "@tanstack/react-table";
7+
import { SectionBrandOverlay } from "@/components/logo/section-brand-overlay";
78
import { TableContent } from "./table-content";
89
import { TableTabs } from "./table-tabs";
910

@@ -35,6 +36,7 @@ interface FullScreenModalProps<TData extends { name: string | number }> {
3536
onRowAction?: (row: TData) => void;
3637
onRowClick?: (field: string, value: string | number) => void;
3738
shareColumnTooltip?: string;
39+
showBrand?: boolean;
3840
}
3941

4042
export function FullScreenModal<TData extends { name: string | number }>({
@@ -53,6 +55,7 @@ export function FullScreenModal<TData extends { name: string | number }>({
5355
onRowAction,
5456
onRowClick,
5557
shareColumnTooltip,
58+
showBrand = false,
5659
}: FullScreenModalProps<TData>) {
5760
const currentTabData = tabs?.find((tab) => tab.id === activeTab);
5861
const tableData = currentTabData?.data || data || [];
@@ -73,23 +76,24 @@ export function FullScreenModal<TData extends { name: string | number }>({
7376
};
7477
return (
7578
<div className="relative flex h-full w-full flex-col bg-sidebar">
76-
<div className="flex items-start justify-between border-sidebar-border border-b bg-sidebar px-3 pt-3 pb-2">
79+
<div className="flex items-start justify-between gap-3 border-sidebar-border border-b bg-sidebar px-3 pt-3 pb-2 sm:items-center">
7780
<div className="min-w-0 flex-1">
7881
{title && (
7982
<h3 className="truncate font-semibold text-sidebar-foreground text-sm">
8083
{title}
8184
</h3>
8285
)}
8386
{description && (
84-
<p className="mt-0.5 line-clamp-2 text-sidebar-foreground/70 text-xs">
87+
<p className="mt-0.5 line-clamp-2 text-pretty text-sidebar-foreground/70 text-xs">
8588
{description}
8689
</p>
8790
)}
8891
</div>
89-
<div className="flex items-center gap-2">
92+
<div className="flex shrink-0 items-center gap-2">
93+
{showBrand ? <SectionBrandOverlay layout="inline" /> : null}
9094
<button
9195
aria-label="Close full screen"
92-
className="ml-2 flex items-center justify-center rounded bg-sidebar-accent/60 p-2 text-sidebar-foreground hover:bg-sidebar-accent"
96+
className="flex items-center justify-center rounded bg-sidebar-accent/60 p-2 text-sidebar-foreground hover:bg-sidebar-accent"
9397
onClick={onClose}
9498
style={{ minWidth: 40, minHeight: 40 }}
9599
tabIndex={0}

apps/dashboard/components/table/table-toolbar.tsx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { ArrowsOutSimpleIcon } from "@phosphor-icons/react";
2+
import { SectionBrandOverlay } from "@/components/logo/section-brand-overlay";
3+
import { Button } from "@/components/ui/button";
24
import { cn } from "@/lib/utils";
35

46
interface TableToolbarProps {
@@ -7,6 +9,7 @@ interface TableToolbarProps {
79
showFullScreen?: boolean;
810
onFullScreenToggle?: () => void;
911
borderBottom?: boolean;
12+
showBrand?: boolean;
1013
}
1114

1215
export function TableToolbar({
@@ -15,31 +18,35 @@ export function TableToolbar({
1518
showFullScreen = true,
1619
onFullScreenToggle,
1720
borderBottom = false,
21+
showBrand = false,
1822
}: TableToolbarProps) {
1923
return (
2024
<div className={cn("px-3 pt-3 pb-2", borderBottom && "border-b")}>
21-
<div className="flex flex-col items-center justify-between gap-3 sm:flex-row">
25+
<div className="flex flex-row items-start justify-between gap-3 sm:items-center">
2226
<div className="min-w-0 flex-1">
2327
<h3 className="truncate font-semibold text-sidebar-foreground text-sm">
2428
{title}
2529
</h3>
2630
{description && (
27-
<p className="mt-0.5 line-clamp-2 text-sidebar-foreground/70 text-xs">
31+
<p className="mt-0.5 line-clamp-2 text-pretty text-sidebar-foreground/70 text-xs">
2832
{description}
2933
</p>
3034
)}
3135
</div>
32-
<div className="flex items-center gap-2">
36+
<div className="flex shrink-0 items-center gap-2">
37+
{showBrand ? <SectionBrandOverlay layout="inline" /> : null}
3338
{showFullScreen && onFullScreenToggle && (
34-
<button
39+
<Button
3540
aria-label="Full screen"
36-
className="flex size-8 items-center justify-center rounded border-sidebar-border bg-sidebar-accent/30 text-sidebar-foreground hover:bg-accent-brighter"
41+
className="size-8 shrink-0 text-muted-foreground hover:text-foreground"
3742
onClick={onFullScreenToggle}
43+
size="icon"
3844
title="Full screen"
3945
type="button"
46+
variant="ghost"
4047
>
41-
<ArrowsOutSimpleIcon size={16} />
42-
</button>
48+
<ArrowsOutSimpleIcon className="size-4" weight="fill" />
49+
</Button>
4350
)}
4451
</div>
4552
</div>

0 commit comments

Comments
 (0)