Skip to content

Commit 82eca0f

Browse files
authored
Merge pull request #1057 from onflow/brian-doyle/add-page-ranking-tags
Add Rate this Page to all Docs Pages
2 parents 18a3c99 + 8769cf8 commit 82eca0f

File tree

7 files changed

+4487
-4785
lines changed

7 files changed

+4487
-4785
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"webpack-merge": "5.8.0"
6060
},
6161
"devDependencies": {
62-
"@docusaurus/module-type-aliases": "^3.5.2",
62+
"@docusaurus/module-type-aliases": "^3.6.3",
6363
"@jest/globals": "^29.7.0",
6464
"@tsconfig/docusaurus": "^2.0.3",
6565
"@types/jest": "^29.5.14",

src/components/feedbackFaces.tsx

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React, { useState } from "react";
2+
import { event } from "@site/src/utils/gtags.client";
3+
4+
export default function FeedbackFaces() {
5+
const [clickedFace, setClickedFace] = useState<string | null>(null);
6+
7+
const faces = [
8+
{ label: "sad", emoji: "😞" },
9+
{ label: "neutral", emoji: "😐" },
10+
{ label: "happy", emoji: "😊" },
11+
];
12+
13+
const handleFeedbackClick = (feedbackType: string) => {
14+
setClickedFace(feedbackType);
15+
16+
const label = `${feedbackType}`;
17+
18+
event({
19+
action: "feedback_click",
20+
category: "feedback",
21+
label: label,
22+
location: true,
23+
});
24+
25+
setTimeout(() => setClickedFace(null), 300);
26+
};
27+
28+
return (
29+
<div className="flex justify-left items-center gap-1">
30+
{faces.map((face) => (
31+
<button
32+
key={face.label}
33+
onClick={() => handleFeedbackClick(face.label)}
34+
className={`text-4xl cursor-pointer p-2 bg-transparent border-none transition-transform duration-200 focus:outline-none ${clickedFace === face.label ? "scale-110 opacity-70" : "scale-100 opacity-100"
35+
}`}
36+
aria-label={face.label}
37+
>
38+
{face.emoji}
39+
</button>
40+
))}
41+
</div>
42+
);
43+
}

src/theme/TOC/index.tsx

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
import clsx from 'clsx';
3+
import TOCItems from '@theme/TOCItems';
4+
import type { Props } from '@theme/TOC';
5+
6+
import styles from './styles.module.css';
7+
import FeedbackFaces from '@site/src/components/feedbackFaces';
8+
9+
// Using a custom className
10+
// This prevents TOCInline/TOCCollapsible getting highlighted by mistake
11+
const LINK_CLASS_NAME = 'table-of-contents__link toc-highlight';
12+
const LINK_ACTIVE_CLASS_NAME = 'table-of-contents__link--active';
13+
14+
export default function TOC({ className, ...props }: Props): JSX.Element {
15+
return (
16+
<div className={clsx(styles.tableOfContents, 'thin-scrollbar', className)}>
17+
<div className="p-1">
18+
<h6 className="mb-0 p-1">Rate this page</h6>
19+
<FeedbackFaces />
20+
</div>
21+
<TOCItems
22+
{...props}
23+
linkClassName={LINK_CLASS_NAME}
24+
linkActiveClassName={LINK_ACTIVE_CLASS_NAME}
25+
/>
26+
</div>
27+
);
28+
}

src/theme/TOC/styles.module.css

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.tableOfContents {
2+
max-height: calc(100vh - (var(--ifm-navbar-height) + 2rem));
3+
overflow-y: auto;
4+
position: sticky;
5+
top: calc(var(--ifm-navbar-height) + 1rem);
6+
}
7+
8+
@media (max-width: 996px) {
9+
.tableOfContents {
10+
display: none;
11+
}
12+
13+
.docItemContainer {
14+
padding: 0 0.3rem;
15+
}
16+
}

src/utils/gtags.client.ts

+13-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const pageview = (url: string, trackingId: string) => {
1919

2020
if (!window.gtag) {
2121
console.warn(
22-
"window.gtag is not defined. This could mean your google anylatics script has not loaded on the page yet."
22+
"window.gtag is not defined. This could mean your google analytics script has not loaded on the page yet."
2323
)
2424
return
2525
}
@@ -37,25 +37,34 @@ export const event = ({
3737
category,
3838
label,
3939
value,
40+
location
4041
}: {
4142
action?: string;
4243
category?: string;
4344
label?: string;
4445
value?: number | string;
46+
location?: boolean;
4547
}) => {
4648
if (process.env.NODE_ENV !== "production") return
4749

4850
if (!window.gtag) {
4951
console.warn(
50-
"window.gtag is not defined. This could mean your google anylatics script has not loaded on the page yet."
52+
"window.gtag is not defined. This could mean your google analytics script has not loaded on the page yet."
5153
)
5254
return
5355
}
54-
window.gtag("event", action, {
56+
57+
const eventPayload: Record<string, any> = {
5558
event_category: category,
5659
event_label: label,
5760
value: value,
58-
})
61+
};
62+
63+
if (location) {
64+
eventPayload.page_location = window.location.href;
65+
}
66+
67+
window.gtag("event", action, eventPayload);
5968
}
6069

6170
export const reportWebVitalsToGA = (vitals: Metric) => {

tsconfig.json

+9-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@
55
"jsx": "react",
66
"baseUrl": ".",
77
"strictNullChecks": true,
8-
"typeRoots": ["./", "./node_modules/@types"]
8+
"typeRoots": [
9+
"./",
10+
"./node_modules/@types"
11+
]
912
},
10-
"include": ["src", "docusaurus.config.d.ts"]
11-
}
13+
"include": [
14+
"src",
15+
"docusaurus.config.d.ts"
16+
]
17+
}

0 commit comments

Comments
 (0)