PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.5
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.5
4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 All 203 releases
betterdocs / react-src / admin / analytics / components / Chrome.js

Chrome.js in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.9.5, at react-src/admin/analytics/components/Chrome.js

106 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { __ } from "@wordpress/i18n";
2 import React, { useEffect, useState } from "react";
3 import { createPortal } from "react-dom";
4 import { I } from "./common/icons";
5 import { cn, DateRange } from "./common/ui";
6 import DarkModeToggle from "../../components/DarkModeToggle";
7
8 export const TITLES = {
9 overview: { title: __( "Overview", "betterdocs" ), subtitle: __( "Reader behavior across all your knowledge bases.", "betterdocs" ) },
10 "ai-traffic": { title: __( "AI Traffic", "betterdocs" ), subtitle: __( "Which AI agents are reading your docs — and how often.", "betterdocs" ) },
11 articles: { title: __( "Docs Performance", "betterdocs" ), subtitle: __( "How each doc is performing — views, unique readers, and trends.", "betterdocs" ) },
12 search: { title: __( "Search Analytics", "betterdocs" ), subtitle: __( "What your readers are looking for — and what they can't find.", "betterdocs" ) },
13 engagement: { title: __( "Reader Engagement", "betterdocs" ), subtitle: __( "Geography, sources, devices, and languages.", "betterdocs" ) },
14 feedback: { title: __( "Feedback Inbox", "betterdocs" ), subtitle: __( "Likes, dislikes, and comments — all in one feed.", "betterdocs" ) },
15 links: { title: __( "Link Health", "betterdocs" ), subtitle: __( "Broken links and redirects across your articles.", "betterdocs" ) },
16 authors: { title: __( "Author Performance", "betterdocs" ), subtitle: __( "Per-author contribution and reception across the knowledge base.", "betterdocs" ) },
17 settings: { title: __( "Analytics Settings", "betterdocs" ), subtitle: __( "Configure data retention, privacy, and integrations.", "betterdocs" ) }
18 };
19
20 /* The tab title + sub-header + filters are portalled into the admin header's
21 second-row .betterdocs-dashboard-container so the analytics title sits in the
22 unified header (consistent with FAQ Builder + Pro).
23
24 `titles` / `fallbackRoute` are parameterised so the Content Intelligence teaser
25 (content-intelligence/index.js) can reuse this exact portal — same header slot,
26 same dark-mode switcher — with its own per-module heading map. */
27 export function PageHeader( { route, days, onDays, showFilters = true, titles = TITLES, fallbackRoute = "overview" } ) {
28 const [ host, setHost ] = useState( null );
29
30 useEffect( () => {
31 const target = document.querySelector( ".betterdocs-dashboard-header > .betterdocs-dashboard-container" );
32 if ( ! target ) {
33 return;
34 }
35 const node = document.createElement( "div" );
36 node.className = "bda-analytics-header";
37 target.appendChild( node );
38 setHost( node );
39 return () => { node.remove(); };
40 }, [] );
41
42 if ( ! host ) {
43 return null;
44 }
45
46 const meta = titles[ route ] || titles[ fallbackRoute ];
47
48 return createPortal(
49 <div className="betterdocs-row">
50 <div className="betterdocs-col betterdocs-header-left betterdocs-col-xs-6">
51 <div className="bda-page-heading">
52 <h2 className="betterdocs-dashboard-header-title">{ meta.title }</h2>
53 { meta.subtitle && <p className="bda-page-sub">{ meta.subtitle }</p> }
54 </div>
55 </div>
56 <div className="betterdocs-col betterdocs-header-right betterdocs-col-xs-6 betterdocs-d-flex betterdocs-justify-end">
57 { showFilters && <DateRange value={ days } onChange={ onDays } /> }
58 <ul className="betterdocs-dashboard-header-action-list betterdocs-text-align-right">
59 <li><DarkModeToggle /></li>
60 </ul>
61 </div>
62 </div>,
63 host
64 );
65 }
66
67 /* Pro flag — every tab is gated in Free (Overview now shows a locked teaser
68 too). The `pro` field controls the inline nav badge AND which view renders. */
69 const NAV = [
70 { id: "overview", label: __( "Overview", "betterdocs" ), icon: I.Home, pro: true },
71 { id: "ai-traffic", label: __( "AI Traffic", "betterdocs" ), icon: I.Sparkle, pro: true },
72 { id: "articles", label: __( "Docs Performance", "betterdocs" ), icon: I.Article, pro: true },
73 { id: "search", label: __( "Search Analytics", "betterdocs" ), icon: I.Search, pro: true },
74 { id: "engagement", label: __( "Reader Engagement", "betterdocs" ), icon: I.Users, pro: true },
75 { id: "feedback", label: __( "Feedback Inbox", "betterdocs" ), icon: I.Inbox, pro: true },
76 { id: "links", label: __( "Link Health", "betterdocs" ), icon: I.Link, pro: true },
77 { id: "authors", label: __( "Author Performance", "betterdocs" ), icon: I.Pen, pro: true }
78 ];
79
80 const NAV_CONFIG = [
81 { id: "settings", label: __( "Settings", "betterdocs" ), icon: I.Settings, pro: true }
82 ];
83
84 export function AnalyticsNav( { active, onNav } ) {
85 const renderItem = ( item ) => {
86 const Icon = item.icon;
87 const isActive = item.id === active;
88 return (
89 <button key={ item.id } className={ cn( "bda-nav-item", isActive && "active" ) } onClick={ () => onNav( item.id ) }>
90 <Icon size={ 16 } className="bda-nav-ico" strokeWidth={ isActive ? 2.2 : 1.8 } />
91 <span>{ item.label }</span>
92 </button>
93 );
94 };
95 return (
96 <nav className="bda-nav">
97 <div className="bda-nav-items">
98 { NAV.map( renderItem ) }
99 </div>
100 <div className="bda-nav-items">
101 { NAV_CONFIG.map( renderItem ) }
102 </div>
103 </nav>
104 );
105 }
106