Skip to content

Commit

Permalink
Overhaul feedback systems
Browse files Browse the repository at this point in the history
  • Loading branch information
scott-klaytn committed Jan 15, 2025
1 parent 7e553bb commit f93248d
Show file tree
Hide file tree
Showing 10 changed files with 299 additions and 153 deletions.
4 changes: 4 additions & 0 deletions i18n/en/code.json
Original file line number Diff line number Diff line change
Expand Up @@ -628,5 +628,9 @@
"theme.blog.author.noPosts": {
"message": "This author has not written any posts yet.",
"description": "The text for authors with 0 blog post"
},
"theme.feedback.helpful": {
"message": "Is this page helpful?",
"description": "The text asking if the page is helpful"
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@docusaurus/preset-classic": "^3.6.3",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@feelback/react": "^0.3.4",
"clsx": "^1.2.1",
"docusaurus-plugin-openapi-docs": "^4.0.1",
"docusaurus-theme-openapi-docs": "^4.0.1",
Expand Down
105 changes: 105 additions & 0 deletions src/theme/Footer/Feedback/Feedback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// /src/theme/Footer/Feedback/Feedback.js
import React, { useEffect, useState } from 'react';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import { FeedbackButton } from 'pushfeedback-react';
import { defineCustomElements } from 'pushfeedback/loader';
import 'pushfeedback/dist/pushfeedback/pushfeedback.css';
import styles from './Feedback.module.css';

const placeholders = {
'en': {
feedbackButtonText: "Make this page better",
modalTitle: "Your feedback helps us improve.",
emailPlaceholder: "Enter your email",
errorMessage: "Please try again later.",
modalTitleError403: "The request URL does not match the one defined in PushFeedback for this project.",
modalTitleError404: "We could not find the provided project id in PushFeedback.",
messagePlaceholder: "Comments",
modalTitleError: "Oops!",
modalTitleSuccess: "Thanks for your feedback!",
screenshotButtonText: "Add a Screenshot",
screenshotTopbarText: "SELECT AN ELEMENT ON THE PAGE",
sendButtonText: "Send",
ratingPlaceholder: "Was this page helpful?",
ratingStarsPlaceholder: "How would you rate this page?"
},
'ko': {
feedbackButtonText: "페이지를 개선해 주세요",
modalTitle: "여러분의 피드백은 문서 개선에 큰 도움이 됩니다.",
emailPlaceholder: "이메일을 입력해 주세요",
errorMessage: "나중에 다시 시도해주세요.",
modalTitleError403: "요청 URL이 PushFeedback에서 정의된 URL과 일치하지 않습니다.",
modalTitleError404: "PushFeedback에서 제공된 프로젝트 ID를 찾을 수 없습니다.",
messagePlaceholder: "의견",
modalTitleError: "이런!",
modalTitleSuccess: "피드백을 보내주셔서 감사합니다!",
screenshotButtonText: "스크린샷 찍기",
screenshotTopbarText: "해당 위치를 선택하세요",
sendButtonText: "보내기",
ratingPlaceholder: "이 페이지가 도움이 되었나요?",
ratingStarsPlaceholder: "이 페이지를 평가해 주세요."
},
'zh-CN': {
feedbackButtonText: "让这个页面变得更好",
modalTitle: "您的反馈有助于我们改进工作。",
emailPlaceholder: "请输入您的电子邮件",
errorMessage: "请稍后再试",
modalTitleError403: "请求的 URL 与 PushFeedback 中为该项目定义的 URL 不匹配。",
modalTitleError404: "我们无法在 PushFeedback 中找到所提供的项目 ID。",
messagePlaceholder: "评论",
modalTitleError: "哎呀!",
modalTitleSuccess: "感谢您的反馈!",
screenshotButtonText: "添加截图",
screenshotTopbarText: "在页面上选择一个元素",
sendButtonText: "发送",
ratingPlaceholder: "本页对您有帮助吗?",
ratingStarsPlaceholder: "您如何评价本页面?"
},
'vi': {
feedbackButtonText: "Cải thiện trang này",
modalTitle: "Phản hồi của bạn giúp chúng tôi cải thiện.",
emailPlaceholder: "Nhập email của bạn",
errorMessage: "Vui lòng thử lại sau.",
modalTitleError403: "URL yêu cầu không khớp với URL được xác định trong PushFeedback cho dự án này.",
modalTitleError404: "Chúng tôi không thể tìm thấy ID dự án được cung cấp trong PushFeedback.",
messagePlaceholder: "Nhận xét",
modalTitleError: "Ôi!",
modalTitleSuccess: "Cảm ơn bạn đã phản hồi!",
screenshotButtonText: "Chụp ảnh màn hình",
screenshotTopbarText: "CHỌN MỘT YẾU TỐ TRÊN TRANG",
sendButtonText: "Gửi",
ratingPlaceholder: "Trang này có hữu ích không?",
ratingStarsPlaceholder: "Bạn đánh giá trang này như thế nào"
}
};

export default function PushFeedback() {
const { i18n } = useDocusaurusContext();
const language = i18n.currentLocale;
const [isLoaded, setIsLoaded] = useState(false);
const projectId = '8ou0itrmqd';

useEffect(() => {
if (typeof window !== 'undefined') {
defineCustomElements(window);
setIsLoaded(true); // Set loaded immediately after defining elements
}
}, []);

const texts = placeholders[language] || placeholders.en;

return (
<div className={`${styles.feedbackWrapper} ${isLoaded ? styles.loaded : ''}`}>
<FeedbackButton
project={projectId}
button-position="bottom-right"
modal-position="bottom-right"
button-style="dark"
rating-mode="stars"
{...texts}
>
{texts.feedbackButtonText}
</FeedbackButton>
</div>
);
}
20 changes: 20 additions & 0 deletions src/theme/Footer/Feedback/Feedback.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* /src/theme/Footer/Feedback/Feedback.module.css */
.feedbackWrapper {
opacity: 0;
transition: opacity 0.3s ease-in;
pointer-events: none;
}

.loaded {
opacity: 1;
pointer-events: auto;
}

.feedbackWrapper:not(.loaded) :global(pushfeedback-button) {
display: none;
}

:global(:root) {
--feedback-primary-color: #789806;
--feedback-button-dark-bg-color: var(--feedback-primary-color);
}
78 changes: 78 additions & 0 deletions src/theme/Footer/Rating/Rating.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React, { useEffect, useRef } from 'react';
import ReactDOM from 'react-dom/client';
import { FeelbackYesNo } from "@feelback/react";
import { useLocation } from '@docusaurus/router';
import Translate from '@docusaurus/Translate';
import styles from './Rating.module.css';
import ThumbsUp from '@site/static/img/misc/button-thumbs-up.svg';
import ThumbsDown from '@site/static/img/misc/button-thumbs-down.svg';

const CUSTOM_LIKE_DISLIKE = [
{
value: "+1",
icon: <ThumbsUp />,
title: "Like",
},
{
value: "-1",
icon: <ThumbsDown />,
title: "Dislike",
}
];

export default function FeelbackRating() {
const rootRef = useRef(null);
const location = useLocation();
const containerRef = useRef(null);

useEffect(() => {
if (typeof window === 'undefined' || location.pathname === '/') {
return;
}

if (!containerRef.current) {
containerRef.current = document.createElement('div');
containerRef.current.className = styles.feedbackContainer;
}

if (!rootRef.current) {
const footerElement = document.querySelector('footer');
if (footerElement) {
footerElement.appendChild(containerRef.current);
rootRef.current = ReactDOM.createRoot(containerRef.current);

rootRef.current.render(
<>
<hr className={styles.feedbackDivider} />
<div className={styles.feedbackContent}>
<span className={styles.questionText}>
<Translate
id="theme.feedback.helpful"
description="The text asking if the page is helpful"
>
Is this page helpful?
</Translate>
</span>
<FeelbackYesNo
contentSetId="bff04c29-b7aa-4481-8507-4cce4d3f5de6"
preset={CUSTOM_LIKE_DISLIKE}
className={styles.feelbackButtonsCustom}
/>
</div>
</>
);
}
}

return () => {
if (rootRef.current) {
rootRef.current.unmount();
containerRef.current?.remove();
rootRef.current = null;
containerRef.current = null;
}
};
}, [location.pathname]);

return null;
}
79 changes: 79 additions & 0 deletions src/theme/Footer/Rating/Rating.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* /src/theme/Footer/Rating/Rating.module.css */
.feedbackContainer {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}

.feedbackDivider {
width: 100%;
border: 0;
height: 1px;
background-color: var(--ifm-color-emphasis-200);
margin: 1rem 0;
}

.feedbackContent {
display: flex;
align-items: center;
gap: 1rem;
}

.questionText {
color: var(--ifm-color-emphasis-700);
}

.feelbackButtonsCustom :global(.feelback-buttons) {
display: flex;
gap: 0.5rem;
}

.feelbackButtonsCustom :global(.feelback-btn) {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.5rem 1rem;
border: 1px solid var(--ifm-color-primary);
border-radius: 0.375rem;
background-color: transparent;
color: var(--ifm-color-primary);
cursor: pointer;
transition: all 0.2s ease;
}

.feelbackButtonsCustom :global(.feelback-btn:hover),
.feelbackButtonsCustom :global(.feelback-btn.active) {
background-color: var(--ifm-color-primary);
color: white;
}

/* Updated SVG styling */
.feelbackButtonsCustom :global(.feelback-btn) svg {
width: 1.25rem;
height: 1.25rem;
transition: transform 0.2s ease;
}

.feelbackButtonsCustom :global(.feelback-btn) svg path {
fill: none;
stroke: currentColor;
stroke-width: 1.5px;
transition: stroke-width 0.2s ease;
}

/* Modified hover selectors */
.feelbackButtonsCustom :global(.feelback-btn:hover) svg {
transform: scale(1.1);
}

.feelbackButtonsCustom :global(.feelback-btn:hover) svg path {
stroke-width: 2px;
}

@media (max-width: 768px) {
.feedbackContent {
flex-direction: column;
text-align: center;
}
}
17 changes: 0 additions & 17 deletions src/theme/Footer/custom.feedback.css

This file was deleted.

Loading

0 comments on commit f93248d

Please sign in to comment.