Skip to content

Commit

Permalink
feat: Google Analytics & feedback component (#120 by @Jpoliachik)
Browse files Browse the repository at this point in the history
* Initial approach for feedback component

* Added url to config. Got the Reaction Widget working

* install gtag plugin

* use gtag in feedback widget, use custom ui

* add yes / no text to buttons

* remove happyreact script

* comment

* add privacy policy link to footer

* use live GA id

---------

Co-authored-by: Dan Edwards <[email protected]>
  • Loading branch information
Jpoliachik and cdanwards authored Jan 30, 2024
1 parent 5576dcc commit 310381f
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 1 deletion.
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);

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

0 comments on commit 310381f

Please sign in to comment.