From 8acd872ac4ef83e898f494f3dd6d5b83f2cd1d77 Mon Sep 17 00:00:00 2001 From: Akash Singh Date: Sun, 10 Mar 2024 16:29:12 +0530 Subject: [PATCH] Add Section Survey Features --- documentation/docusaurus.config.js | 3 + documentation/package-lock.json | 99 +++++ documentation/package.json | 1 + .../plugins/thumbs-up-down-feedback-widget.js | 184 +++++++++ .../plugins/thumbs-up-down-feedback-widget.ts | 177 +++++++++ .../src/hooks/use-refine-cloud-survey-api.tsx | 118 ++++++ .../common-header/mobile-menu-modal.tsx | 2 +- .../src/prepverse-theme/doc-footer.tsx | 4 +- .../src/prepverse-theme/doc-item-layout.tsx | 2 +- .../src/prepverse-theme/doc-survey-widget.tsx | 114 +----- .../doc-thumbs-up-down-feedback-widget.tsx | 358 ++++++++++++++++++ .../icons/popover/instagram.tsx | 4 +- .../src/prepverse-theme/icons/thumbs-down.tsx | 21 + .../src/prepverse-theme/icons/thumbs-up.tsx | 21 + .../src/theme/MDXComponents/index.js | 2 + documentation/tailwind.config.js | 1 + 16 files changed, 1006 insertions(+), 105 deletions(-) create mode 100644 documentation/plugins/thumbs-up-down-feedback-widget.js create mode 100644 documentation/plugins/thumbs-up-down-feedback-widget.ts create mode 100644 documentation/src/hooks/use-refine-cloud-survey-api.tsx create mode 100644 documentation/src/prepverse-theme/doc-thumbs-up-down-feedback-widget.tsx create mode 100644 documentation/src/prepverse-theme/icons/thumbs-down.tsx create mode 100644 documentation/src/prepverse-theme/icons/thumbs-up.tsx diff --git a/documentation/docusaurus.config.js b/documentation/docusaurus.config.js index 8d5f2aa7..4a9b6e21 100644 --- a/documentation/docusaurus.config.js +++ b/documentation/docusaurus.config.js @@ -9,6 +9,7 @@ require("dotenv").config(); const redirectJson = require("./redirects.json"); const tutorialData = require("./tutorial-units"); +const thumbsUpDownFeedbackWidget = require("./plugins/thumbs-up-down-feedback-widget"); const math = require('remark-math'); const katex = require('rehype-katex'); @@ -85,6 +86,8 @@ const siteConfig = { "simple", ], }, + exclude: ["**/**/_*.md"], + // remarkPlugins: [thumbsUpDownFeedbackWidget.plugin], }, blog: false, theme: { diff --git a/documentation/package-lock.json b/documentation/package-lock.json index 5d740e4a..c38bb2fe 100644 --- a/documentation/package-lock.json +++ b/documentation/package-lock.json @@ -14,6 +14,7 @@ "@docusaurus/plugin-client-redirects": "2.4.0", "@docusaurus/preset-classic": "2.4.0", "@docusaurus/utils": "^3.1.1", + "@floating-ui/react": "^0.26.9", "@giscus/react": "^2.4.0", "@headlessui/react": "^1.7.15", "@iconify/react": "^4.1.1", @@ -3506,6 +3507,54 @@ "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", "optional": true }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.9.tgz", + "integrity": "sha512-p86wynZJVEkEq2BBjY/8p2g3biQ6TlgT4o/3KgFKyTWoJLU1GZ8wpctwRqtkEl2tseYA+kw7dBAIDFcednfI5w==", + "dependencies": { + "@floating-ui/react-dom": "^2.0.8", + "@floating-ui/utils": "^0.2.1", + "tabbable": "^6.0.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, "node_modules/@giscus/react": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@giscus/react/-/react-2.4.0.tgz", @@ -14964,6 +15013,11 @@ "webpack": ">=2" } }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + }, "node_modules/tailwindcss": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz", @@ -19207,6 +19261,46 @@ "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", "optional": true }, + "@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "requires": { + "@floating-ui/utils": "^0.2.1" + } + }, + "@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "requires": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "@floating-ui/react": { + "version": "0.26.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.9.tgz", + "integrity": "sha512-p86wynZJVEkEq2BBjY/8p2g3biQ6TlgT4o/3KgFKyTWoJLU1GZ8wpctwRqtkEl2tseYA+kw7dBAIDFcednfI5w==", + "requires": { + "@floating-ui/react-dom": "^2.0.8", + "@floating-ui/utils": "^0.2.1", + "tabbable": "^6.0.1" + } + }, + "@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "requires": { + "@floating-ui/dom": "^1.6.1" + } + }, + "@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, "@giscus/react": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@giscus/react/-/react-2.4.0.tgz", @@ -27547,6 +27641,11 @@ "integrity": "sha512-D1p6XXURfSPleZZA/Lipb3A8pZ17fP4NObZvFCDjK/OKljroqDpPmsBdTraWhVBqUNpcWBQY1imWdoPScRlQ7A==", "requires": {} }, + "tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + }, "tailwindcss": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz", diff --git a/documentation/package.json b/documentation/package.json index 86edc55e..cf7936ed 100644 --- a/documentation/package.json +++ b/documentation/package.json @@ -22,6 +22,7 @@ "@docusaurus/plugin-client-redirects": "2.4.0", "@docusaurus/preset-classic": "2.4.0", "@docusaurus/utils": "^3.1.1", + "@floating-ui/react": "^0.26.9", "@giscus/react": "^2.4.0", "@headlessui/react": "^1.7.15", "@iconify/react": "^4.1.1", diff --git a/documentation/plugins/thumbs-up-down-feedback-widget.js b/documentation/plugins/thumbs-up-down-feedback-widget.js new file mode 100644 index 00000000..7c3e40d5 --- /dev/null +++ b/documentation/plugins/thumbs-up-down-feedback-widget.js @@ -0,0 +1,184 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; +} +function _optionalChain(ops) { + let lastAccessLHS = undefined; + let value = ops[0]; + let i = 1; + while (i < ops.length) { + const op = ops[i]; + const fn = ops[i + 1]; + i += 2; + if ((op === "optionalAccess" || op === "optionalCall") && value == null) { + return undefined; + } + if (op === "access" || op === "optionalAccess") { + lastAccessLHS = value; + value = fn(value); + } else if (op === "call" || op === "optionalCall") { + value = fn((...args) => value.call(lastAccessLHS, ...args)); + lastAccessLHS = undefined; + } + } + return value; +} +var _unistutilvisit = require("unist-util-visit"); +var _unistutilvisit2 = _interopRequireDefault(_unistutilvisit); + +/* + This plugin wraps children of each heading with thumbs up-down feedback widget. + Example of result after transformation: + + before: +

Heading 1

+ +

Paragraph 1

+

Paragraph 2

+ +

Heading 2

+ +

Paragraph 3

+

Paragraph 4

+ + after: +

Heading 1

+ +

Paragraph 1

+

Paragraph 2

+
+ +

Heading 2

+ +

Paragraph 3

+

Paragraph 4

+
+*/ + +const plugin = () => { + const transformer = async (ast) => { + exports.transform.call(void 0, ast); + }; + + return transformer; +}; +exports.plugin = plugin; + +const transform = (ast) => { + const headingIndexes = []; + + let nodeBefore = null; + + _unistutilvisit2.default.call(void 0, ast, "heading", (nodeCurrent) => { + const { depth } = nodeCurrent; + + if (depth === 1) { + return; + } + + if (!nodeBefore) { + nodeBefore = nodeCurrent; + return; + } + + const nodeBeforeIndex = ast.children.indexOf(nodeBefore); + const nodeCurrentIndex = ast.children.indexOf(nodeCurrent) - 1; + + const itemCountBetweenHeadings = nodeCurrentIndex - nodeBeforeIndex; + + if (itemCountBetweenHeadings < 1) { + nodeBefore = nodeCurrent; + return; + } + + headingIndexes.push({ + startIndex: nodeBeforeIndex, + endIndex: nodeCurrentIndex, + itemCountBetweenHeadings, + data: { + id: nodeBefore.data.id, + }, + }); + + nodeBefore = nodeCurrent; + }); + + // add thumbs up down feedback widget to the below of each heading + let totalCountOfAddedNodes = 0; + let totalCountOfRemovedNodes = 0; + for (let i = 0; i < headingIndexes.length; i++) { + const { startIndex, itemCountBetweenHeadings, data } = headingIndexes[i]; + let belowHeadingIndex = startIndex + 1; + + // get nodes between headings + const nodesBetweenHeadings = ast.children.slice( + belowHeadingIndex, + belowHeadingIndex + itemCountBetweenHeadings, + ); + + // remove nodes between headings + ast.children.splice(belowHeadingIndex, itemCountBetweenHeadings); + totalCountOfRemovedNodes += itemCountBetweenHeadings; + + // create widget opening tag + ast.children.splice(belowHeadingIndex, 0, { + type: "jsx", + value: ``, + }); + totalCountOfAddedNodes++; + + // add nodesBetweenHeadings as children of widget + ast.children.splice(belowHeadingIndex + 1, 0, ...nodesBetweenHeadings); + totalCountOfAddedNodes += nodesBetweenHeadings.length; + + // create widget closing tag + ast.children.splice( + belowHeadingIndex + 1 + nodesBetweenHeadings.length, + 0, + { + type: "jsx", + value: ``, + }, + ); + totalCountOfAddedNodes++; + + const currentHeading = headingIndexes.at(i); + if (currentHeading) { + currentHeading.endIndex += 1; + currentHeading.endIndex -= itemCountBetweenHeadings; + } + + const nextHeading = headingIndexes.at(i + 1); + if (nextHeading) { + nextHeading.startIndex += totalCountOfAddedNodes; + nextHeading.startIndex -= totalCountOfRemovedNodes; + nextHeading.endIndex += totalCountOfAddedNodes; + nextHeading.endIndex -= totalCountOfRemovedNodes; + } + } + + // add last thumbs up/down widget to the end of the ast because we didn't add it in the loop above because there is no next heading + if ( + nodeBefore && + _optionalChain([ + nodeBefore, + "optionalAccess", + (_) => _.data, + "optionalAccess", + (_2) => _2.id, + ]) + ) { + const nodeBeforeIndex = ast.children.indexOf(nodeBefore); + ast.children.splice(nodeBeforeIndex + 1, 0, { + type: "jsx", + value: ``, + }); + + ast.children.push({ + type: "jsx", + value: ``, + }); + } +}; +exports.transform = transform; \ No newline at end of file diff --git a/documentation/plugins/thumbs-up-down-feedback-widget.ts b/documentation/plugins/thumbs-up-down-feedback-widget.ts new file mode 100644 index 00000000..3e77f03d --- /dev/null +++ b/documentation/plugins/thumbs-up-down-feedback-widget.ts @@ -0,0 +1,177 @@ +import visit from "unist-util-visit"; +import fs from "fs"; + +/* + This plugin wraps children of each heading with thumbs up-down feedback widget. + Example of result after transformation: + + before: +

Heading 1

+ +

Paragraph 1

+

Paragraph 2

+ +

Heading 2

+ +

Paragraph 3

+

Paragraph 4

+ + after: +

Heading 1

+ +

Paragraph 1

+

Paragraph 2

+
+ +

Heading 2

+ +

Paragraph 3

+

Paragraph 4

+
+*/ + +export const plugin = () => { + const transformer = async (ast) => { + transform(ast); + }; + + return transformer; +}; + +export const transform = (ast) => { + const headingIndexes: { + startIndex: number; + endIndex: number; + itemCountBetweenHeadings: number; + data: { + id: string; + }; + }[] = []; + + let nodeBefore: NodeHeading | null = null; + + visit(ast, "heading", (nodeCurrent: NodeHeading) => { + const { depth } = nodeCurrent; + + if (depth === 1) { + return; + } + + if (!nodeBefore) { + nodeBefore = nodeCurrent; + return; + } + + const nodeBeforeIndex = ast.children.indexOf(nodeBefore); + const nodeCurrentIndex = ast.children.indexOf(nodeCurrent) - 1; + + const itemCountBetweenHeadings = nodeCurrentIndex - nodeBeforeIndex; + + if (itemCountBetweenHeadings < 1) { + nodeBefore = nodeCurrent; + return; + } + + headingIndexes.push({ + startIndex: nodeBeforeIndex, + endIndex: nodeCurrentIndex, + itemCountBetweenHeadings, + data: { + id: nodeBefore.data.id, + }, + }); + + nodeBefore = nodeCurrent; + }); + + // add thumbs up down feedback widget to the below of each heading + let totalCountOfAddedNodes = 0; + let totalCountOfRemovedNodes = 0; + for (let i = 0; i < headingIndexes.length; i++) { + const { startIndex, itemCountBetweenHeadings, data } = headingIndexes[i]; + let belowHeadingIndex = startIndex + 1; + + // get nodes between headings + const nodesBetweenHeadings = ast.children.slice( + belowHeadingIndex, + belowHeadingIndex + itemCountBetweenHeadings, + ); + + // remove nodes between headings + ast.children.splice(belowHeadingIndex, itemCountBetweenHeadings); + totalCountOfRemovedNodes += itemCountBetweenHeadings; + + // create widget opening tag + ast.children.splice(belowHeadingIndex, 0, { + type: "jsx", + value: ``, + }); + totalCountOfAddedNodes++; + + // add nodesBetweenHeadings as children of widget + ast.children.splice(belowHeadingIndex + 1, 0, ...nodesBetweenHeadings); + totalCountOfAddedNodes += nodesBetweenHeadings.length; + + // create widget closing tag + ast.children.splice( + belowHeadingIndex + 1 + nodesBetweenHeadings.length, + 0, + { + type: "jsx", + value: ``, + }, + ); + totalCountOfAddedNodes++; + + const currentHeading = headingIndexes.at(i); + if (currentHeading) { + currentHeading.endIndex += 1; + currentHeading.endIndex -= itemCountBetweenHeadings; + } + + const nextHeading = headingIndexes.at(i + 1); + if (nextHeading) { + nextHeading.startIndex += totalCountOfAddedNodes; + nextHeading.startIndex -= totalCountOfRemovedNodes; + nextHeading.endIndex += totalCountOfAddedNodes; + nextHeading.endIndex -= totalCountOfRemovedNodes; + } + } + + // add last thumbs up/down widget to the end of the ast because we didn't add it in the loop above because there is no next heading + if (nodeBefore && nodeBefore?.data?.id) { + const nodeBeforeIndex = ast.children.indexOf(nodeBefore); + ast.children.splice(nodeBeforeIndex + 1, 0, { + type: "jsx", + value: ``, + }); + + ast.children.push({ + type: "jsx", + value: ``, + }); + } +}; + +type NodeHeading = { + type: "heading"; + depth: 1 | 2 | 3 | 4 | 5 | 6; + children: any[]; + position: { + start: { + line: number; + column: number; + offset: number; + }; + end: { + line: number; + column: number; + offset: number; + }; + indent: number[]; + }; + data: { + id: string; + hProperties: Record; + }; +}; \ No newline at end of file diff --git a/documentation/src/hooks/use-refine-cloud-survey-api.tsx b/documentation/src/hooks/use-refine-cloud-survey-api.tsx new file mode 100644 index 00000000..8e3198af --- /dev/null +++ b/documentation/src/hooks/use-refine-cloud-survey-api.tsx @@ -0,0 +1,118 @@ +import { useState } from "react"; + +export type SurveyOption = 1 | 2 | 3 | 4 | 5; + +export enum SurveyTypeEnum { + EMOJI = "EMOJI", + THUMBS = "THUMBS", +} + +export type Survey = { + id: string; + name: string; + slug: string; + options: SurveyOption[]; + source: string; + entityType: string; + surveyType: SurveyTypeEnum; + createdAt: string; + updatedAt: string; +}; + +export type SurveyMetaData = Record; + +export type DocSurveyCreateDto = { + response: number; + entityId: string; + responseText?: string; + metaData?: SurveyMetaData; +}; + +export type DocSurveyUpdateDto = { + response: number; + responseText?: string; + metaData?: SurveyMetaData; +}; + +export type DocSurveyResponse = { + response: number; + entityId: string; + survey: Survey; + responseText?: string | null; + metaData: SurveyMetaData; + id: string; + createdAt: string; + updatedAt: string; +}; + +type Props = { + type: SurveyTypeEnum; +}; + +export const useRefineCloudSurveyAPI = (props: Props) => { + const [survey, setSurvey] = useState(null); + + const API_URL = URL_MAP[props.type]; + + const createSurvey = async ({ body }: { body: DocSurveyCreateDto }) => { + const response = await fetch(`${API_URL}/responses`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + }); + + if (!response.ok) { + return null; + } + + const data: DocSurveyResponse = await response.json(); + if (!data) return; + setSurvey(data); + return data; + }; + + const updateSurvey = async ({ + surveyId, + body, + }: { + surveyId?: string; + body: DocSurveyUpdateDto; + }) => { + const response = await fetch(`${API_URL}/responses/${surveyId}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + }); + + if (!response.ok) { + return null; + } + + const data: DocSurveyResponse = await response.json(); + if (!data) return; + setSurvey(data); + return data; + }; + + return { + survey, + setSurvey, + createSurvey, + updateSurvey, + }; +}; + +const BASE_URL = "https://prepverse.github.io/surveys"; + +const PAGES_SURVEY_URL = `${BASE_URL}/documentation-pages-survey`; + +const SECTIONS_SURVEY_URL = `${BASE_URL}/documentation-sections-survey`; + +const URL_MAP = { + [SurveyTypeEnum.EMOJI]: PAGES_SURVEY_URL, + [SurveyTypeEnum.THUMBS]: SECTIONS_SURVEY_URL, +}; \ No newline at end of file diff --git a/documentation/src/prepverse-theme/common-header/mobile-menu-modal.tsx b/documentation/src/prepverse-theme/common-header/mobile-menu-modal.tsx index dcbd2c9e..d2e25182 100644 --- a/documentation/src/prepverse-theme/common-header/mobile-menu-modal.tsx +++ b/documentation/src/prepverse-theme/common-header/mobile-menu-modal.tsx @@ -295,7 +295,7 @@ const Social = (props: { id?: string }) => { - + diff --git a/documentation/src/prepverse-theme/doc-footer.tsx b/documentation/src/prepverse-theme/doc-footer.tsx index 6f2d495c..e27aec75 100644 --- a/documentation/src/prepverse-theme/doc-footer.tsx +++ b/documentation/src/prepverse-theme/doc-footer.tsx @@ -36,7 +36,7 @@ function EditMetaRow({ "gap-4", )} > - {tutorial?.isTutorial ? ( diff --git a/documentation/src/prepverse-theme/doc-survey-widget.tsx b/documentation/src/prepverse-theme/doc-survey-widget.tsx index 1dd9744e..7a4598c3 100644 --- a/documentation/src/prepverse-theme/doc-survey-widget.tsx +++ b/documentation/src/prepverse-theme/doc-survey-widget.tsx @@ -2,6 +2,11 @@ import clsx from "clsx"; import React, { useState } from "react"; import { useLocation } from "@docusaurus/router"; import { AnimatePresence, motion } from "framer-motion"; +import { + SurveyOption, + SurveyTypeEnum, + useRefineCloudSurveyAPI, +} from "../hooks/use-refine-cloud-survey-api"; type Props = { className?: string; @@ -13,8 +18,6 @@ type Props = { export const DocSurveyWidget = ({ className }: Props) => { const refWidget = React.useRef(null); const location = useLocation(); - // users can change their rating feedback, so we need to keep track of the survey response - const [survey, setSurvey] = useState(null); // if the user submits rating feedback, we show the text feedback input const [isSurveyTextVisible, setIsSurveyTextVisible] = useState(false); // if the user submits text feedback, we show a thank you message @@ -24,6 +27,11 @@ export const DocSurveyWidget = ({ className }: Props) => { null, ); + const { survey, setSurvey, createSurvey, updateSurvey } = + useRefineCloudSurveyAPI({ + type: SurveyTypeEnum.EMOJI, + }); + const handleSurveyOptionClick = async (option: SurveyOption) => { setSelectedOption(option); setIsSurveyTextVisible(true); @@ -36,21 +44,17 @@ export const DocSurveyWidget = ({ className }: Props) => { }, 150); if (survey) { - const data = await updateSurvey({ + await updateSurvey({ surveyId: survey.id, body: { response: option }, }); - if (!data) return; - setSurvey(data); } else { - const data = await createSurvey({ + await createSurvey({ body: { response: option, entityId: location.pathname, }, }); - if (!data) return; - setSurvey(data); } }; @@ -59,13 +63,10 @@ export const DocSurveyWidget = ({ className }: Props) => { return; } - const data = await updateSurvey({ + await updateSurvey({ surveyId: survey.id, body: { response: selectedOption, responseText: text }, }); - if (!data) return; - - setSurvey(data); // when the user submits text feedback, we show a thank you message setIsFinished(true); @@ -161,6 +162,7 @@ const SurveyOptions = (props: { return ( + + + { + if (resultViewVisible) return; + + if (!isOpen) { + setIsFeedbackTextIsVisible(false); + setResultViewVisible(false); + } + }} + arrowStyle={{ + right: selectedThumb === 1 ? "150px" : "115px", + }} + > + {!resultViewVisible && ( +
{ + e.preventDefault(); + onFeedbackTextSubmit(); + }} + > +