Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Google Analytics & feedback component #120

Merged
merged 11 commits into from
Jan 30, 2024
7 changes: 7 additions & 0 deletions docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ const config = {
theme: {
customCss: require.resolve("./src/css/custom.css"),
},
gtag: {
trackingID: "G-1NP64B0XVM",
anonymizeIP: true,
},
}),
],
],
Expand Down Expand Up @@ -258,6 +262,9 @@ const config = {
{
html: '<a href="https://shift.infinite.red/" target="_blank" rel="noopener noreferrer" class="footer__link-item">RedShift Blog <div class="footer__links__custom"><svg width="18" height="18" viewBox="0 0 27 26" fill="none" xmlns="http://www.w3.org/2000/svg" class="" role="img"><g clip-path="url(#a)" stroke="#F4F2F1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.312 18.781 19.245 6.85M19.245 17.986V6.849H8.108"></path></g><defs><clipPath id="a"><path fill="#fff" transform="rotate(45 6.534 16.072)" d="M0 0h18v18H0z"></path></clipPath></defs></svg></div></a>',
},
{
html: '<a href="https:/infinite.red/privacy-policy" target="_blank" rel="noopener noreferrer" class="footer__link-item">Privacy Policy<div class="footer__links__custom"><svg width="18" height="18" viewBox="0 0 27 26" fill="none" xmlns="http://www.w3.org/2000/svg" class="" role="img"><g clip-path="url(#a)" stroke="#F4F2F1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.312 18.781 19.245 6.85M19.245 17.986V6.849H8.108"></path></g><defs><clipPath id="a"><path fill="#fff" transform="rotate(45 6.534 16.072)" d="M0 0h18v18H0z"></path></clipPath></defs></svg></div></a>',
},
],
},
],
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"devDependencies": {
"@docusaurus/module-type-aliases": "^2.0.1",
"@tsconfig/docusaurus": "^1.0.6",
"@types/gtag.js": "^0.0.18",
"gitlog": "^4.0.4",
"typescript": "^4.7.4"
},
Expand Down
69 changes: 69 additions & 0 deletions src/components/Feedback/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { useEffect, useState } from "react";
import ExecutionEnvironment from "@docusaurus/ExecutionEnvironment";
import styles from "./styles.module.css";

import * as ThumbsUp from "@site/static/img/thumbs-up.svg";
import * as ThumbsDown from "@site/static/img/thumbs-down.svg";

const VotedYes = () => {
return (
<span>Thanks for your feedback! We hope this recipe has been helpful.</span>
);
};

const VotedNo = () => {
return (
<span>
Thanks for your feedback. We will update this recipe as soon as we can.
</span>
);
};

export default function Feedback({ resource }) {
const [reaction, setReaction] = useState(null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we care about any type of persistence for this (local storage or beyond?)? probably not, but just adding an note.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good callout - I went with the easiest route, but that does allow users to full-refresh and vote again. didn't think it was worth the effort for now, but we can keep an eye on stats and add it later if needed.
FWIW I noticed that other docs sites (reactnative.dev, docs.expo.dev) do the same thing.


const isReacted = reaction === "yes" || reaction === "no";

const handleReaction = (reaction: string) => {
setReaction(reaction);

// track using Google Analytics custom event
// include the resource name and yes/no in the event name for tracking purposes
gtag("event", `feedback_${resource}_${reaction}`, {
event_category: "feedback",
event_label: resource,
});
};

return (
<div className={styles.root}>
<h3 className={styles.title}>
Is this page still up to date? Did it work for you?
</h3>
{!isReacted ? (
<div className={styles.grid}>
<button
className={styles.reactionButton}
onClick={() => handleReaction("yes")}
aria-label="Yes"
>
<ThumbsUp.default className={styles.reactionIcon} />
<div className={styles.reactionText}>Yes</div>
</button>
<button
className={styles.reactionButton}
onClick={() => handleReaction("no")}
aria-label="No"
>
<ThumbsDown.default className={styles.reactionIcon} />
<div className={styles.reactionText}>No</div>
</button>
</div>
) : reaction === "no" ? (
<VotedNo />
) : (
<VotedYes />
)}
</div>
);
}
44 changes: 44 additions & 0 deletions src/components/Feedback/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.root {
margin-top: 45px;
}

.grid {
display: flex;
flex-direction: row;
justify-content: flex-start;
gap: 8px;
}

.reactionButton {
all: unset;
cursor: pointer;
padding: 8px;
padding-top: 4px;
padding-bottom: 4px;
border: #d6d6d6 1px solid;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
}

.reactionButton:hover {
background-color: #e3e3e3;
}

.reactionIcon {
width: 20px;
height: 20px;
}

.reactionText {
margin-left: 6px;
font-size: 14px;
font-weight: 500;
color: #4a4a4a;
}

.footer {
margin-top: 10px;
margin-left: 0;
}
72 changes: 72 additions & 0 deletions src/theme/DocItem/Footer/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from 'react';
import clsx from 'clsx';
import {ThemeClassNames} from '@docusaurus/theme-common';
import {useDoc} from '@docusaurus/theme-common/internal';
import LastUpdated from '@theme/LastUpdated';
import EditThisPage from '@theme/EditThisPage';
import TagsListInline from '@theme/TagsListInline';
import Feedback from '@site/src/components/Feedback';
import styles from './styles.module.css';
function TagsRow(props) {
return (
<div
className={clsx(
ThemeClassNames.docs.docFooterTagsRow,
'row margin-bottom--sm',
)}>
<div className="col">
<TagsListInline {...props} />
</div>
</div>
);
}
function EditMetaRow({
editUrl,
lastUpdatedAt,
lastUpdatedBy,
formattedLastUpdatedAt,
}) {
return (
<div className={clsx(ThemeClassNames.docs.docFooterEditMetaRow, 'row')}>
<div className="col">{editUrl && <EditThisPage editUrl={editUrl} />}</div>

<div className={clsx('col', styles.lastUpdated)}>
{(lastUpdatedAt || lastUpdatedBy) && (
<LastUpdated
lastUpdatedAt={lastUpdatedAt}
formattedLastUpdatedAt={formattedLastUpdatedAt}
lastUpdatedBy={lastUpdatedBy}
/>
)}
</div>
</div>
);
}
export default function DocItemFooter() {
const {metadata} = useDoc();
const {editUrl, lastUpdatedAt, formattedLastUpdatedAt, lastUpdatedBy, tags, unversionedId} =
metadata;
const canDisplayTagsRow = tags.length > 0;
const canDisplayEditMetaRow = !!(editUrl || lastUpdatedAt || lastUpdatedBy);
const canDisplayFooter = canDisplayTagsRow || canDisplayEditMetaRow;
if (!canDisplayFooter) {
return null;
}
return (
<>
<Feedback resource={unversionedId} />
<footer
className={clsx(ThemeClassNames.docs.docFooter, 'docusaurus-mt-lg')}>
{canDisplayTagsRow && <TagsRow tags={tags} />}
{canDisplayEditMetaRow && (
<EditMetaRow
editUrl={editUrl}
lastUpdatedAt={lastUpdatedAt}
lastUpdatedBy={lastUpdatedBy}
formattedLastUpdatedAt={formattedLastUpdatedAt}
/>
)}
</footer>
</>
);
}
11 changes: 11 additions & 0 deletions src/theme/DocItem/Footer/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.lastUpdated {
margin-top: 0.2rem;
font-style: italic;
font-size: smaller;
}

@media (min-width: 997px) {
.lastUpdated {
text-align: right;
}
}
1 change: 1 addition & 0 deletions static/img/thumbs-down.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions static/img/thumbs-up.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// This file is not used in compilation. It is here just for a nice editor experience.
"extends": "@tsconfig/docusaurus/tsconfig.json",
"compilerOptions": {
"baseUrl": "."
"baseUrl": ".",
"types": ["@types/gtag.js"]
}
}
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2124,6 +2124,11 @@
"@types/qs" "*"
"@types/serve-static" "*"

"@types/gtag.js@^0.0.18":
version "0.0.18"
resolved "https://registry.yarnpkg.com/@types/gtag.js/-/gtag.js-0.0.18.tgz#d6bc7cb1acc64ff4f4e4be918d401c53fe9ccf20"
integrity sha512-GJxnIvuXuVhKaHfsOdzGipoOoXq72y3mdcncc9h6i6E7nlz89zBEj2wrLM7bqO5Xk9Lm2B94MwdQsSwRlaPSWw==

"@types/hast@^2.0.0":
version "2.3.4"
resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc"
Expand Down
Loading