From 8ae9b700a07a2b06f56a2ccef43bcf1ab1d9e805 Mon Sep 17 00:00:00 2001 From: Dikran Samarjian Date: Mon, 22 Jun 2026 15:45:17 -0700 Subject: [PATCH 1/2] fix 404 --- src/components/CsatWidget/index.tsx | 124 ++++++++++++++++------------ 1 file changed, 70 insertions(+), 54 deletions(-) diff --git a/src/components/CsatWidget/index.tsx b/src/components/CsatWidget/index.tsx index 293f0afc..950648bb 100644 --- a/src/components/CsatWidget/index.tsx +++ b/src/components/CsatWidget/index.tsx @@ -1,10 +1,10 @@ -import clsx from 'clsx'; -import { useLocation } from '@docusaurus/router'; -import React, { useEffect, useMemo, useState } from 'react'; +import clsx from "clsx"; +import { useLocation } from "@docusaurus/router"; +import React, { useEffect, useMemo, useState } from "react"; -import styles from './styles.module.css'; +import styles from "./styles.module.css"; -const CSAT_STORAGE_PREFIX = 'devvit_docs_csat_submitted:'; +const CSAT_STORAGE_PREFIX = "devvit_docs_csat_submitted:"; declare global { interface Window { @@ -12,6 +12,10 @@ declare global { } } +type CsatReaction = "positive" | "negative"; +type CsatScore = 1 | 5; +type CsatAction = "view" | "select_score" | "submit" | "dismiss"; + function getStorageKey(pathname: string): string { return `${CSAT_STORAGE_PREFIX}${pathname}`; } @@ -36,58 +40,65 @@ function getReferrerInfo(): { url?: string; domain?: string } { type ScoreOption = { label: string; - value: number; + value: CsatScore; emoji: string; - reaction: 'positive' | 'negative'; + reaction: CsatReaction; }; const SCORE_OPTIONS: ScoreOption[] = [ { - label: 'Thumbs down', + label: "Thumbs down", value: 1, - emoji: '👎', - reaction: 'negative', + emoji: "👎", + reaction: "negative", }, { - label: 'Thumbs up', + label: "Thumbs up", value: 5, - emoji: '👍', - reaction: 'positive', + emoji: "👍", + reaction: "positive", }, ]; const NEGATIVE_REASON_OPTIONS = [ - 'The page is unclear', - 'Important details are missing', - 'The instructions did not work', + "The page is unclear", + "Important details are missing", + "The instructions did not work", ]; export default function CsatWidget(): React.ReactElement | null { const { pathname } = useLocation(); const [selectedScore, setSelectedScore] = useState(null); - const [feedback, setFeedback] = useState(''); + const [feedback, setFeedback] = useState(""); const [selectedReasons, setSelectedReasons] = useState([]); const [isVisible, setIsVisible] = useState(false); const [isSubmitted, setIsSubmitted] = useState(false); const storageKey = useMemo(() => getStorageKey(pathname), [pathname]); const shouldShowForPath = useMemo(() => { - const normalizedPath = pathname.replace(/\/+$/, '') || '/'; - return normalizedPath !== '/' && normalizedPath !== '/docs'; + const normalizedPath = pathname.replace(/\/+$/, "") || "/"; + return normalizedPath !== "/" && normalizedPath !== "/docs"; }, [pathname]); - const sendEvent = (action: string, details: Record) => { - if (typeof window === 'undefined' || typeof window.sendV2Event !== 'function') { + const sendCsatEvent = ( + action: CsatAction, + details: Record = {}, + ) => { + if ( + typeof window === "undefined" || + typeof window.sendV2Event !== "function" + ) { return; } window.sendV2Event({ - source: 'docs_csat_widget', + source: "docs_csat_widget", action, - noun: 'csat', + noun: "csat", action_info: { - page_type: 'dev_portal_docs', + page_type: "dev_portal_docs", page_path: pathname, + widget: "docs_csat", ...details, }, request: { @@ -98,48 +109,54 @@ export default function CsatWidget(): React.ReactElement | null { }; useEffect(() => { - if (typeof window === 'undefined') { + if (typeof window === "undefined") { return; } if (!shouldShowForPath) { setSelectedScore(null); - setFeedback(''); + setFeedback(""); setSelectedReasons([]); setIsSubmitted(false); setIsVisible(false); return; } - const hasSubmitted = window.sessionStorage.getItem(storageKey) === '1'; + const hasSubmitted = window.sessionStorage.getItem(storageKey) === "1"; setSelectedScore(null); - setFeedback(''); + setFeedback(""); setSelectedReasons([]); setIsSubmitted(false); setIsVisible(!hasSubmitted); if (!hasSubmitted) { - sendEvent('view', { widget: 'docs_csat' }); + sendCsatEvent("view"); } }, [storageKey, shouldShowForPath]); const dismiss = () => { - sendEvent('dismiss', { widget: 'docs_csat' }); + sendCsatEvent("dismiss"); setIsVisible(false); }; - const submit = (score: number, extraDetails: Record = {}) => { - if (typeof window === 'undefined') { + const submit = ( + score: CsatScore, + reaction: CsatReaction, + feedbackValue: string, + reasons: string[], + ) => { + if (typeof window === "undefined") { return; } - sendEvent('submit', { - widget: 'docs_csat', + sendCsatEvent("submit", { score, - ...extraDetails, + reaction, + feedback: feedbackValue, + reasons, }); - window.sessionStorage.setItem(storageKey, '1'); + window.sessionStorage.setItem(storageKey, "1"); setIsSubmitted(true); window.setTimeout(() => { setIsVisible(false); @@ -149,29 +166,26 @@ export default function CsatWidget(): React.ReactElement | null { const onScoreSelect = (option: ScoreOption) => { const score = option.value; setSelectedScore(score); - if (option.reaction === 'positive') { + if (option.reaction === "positive") { setSelectedReasons([]); - setFeedback(''); + setFeedback(""); } - sendEvent('select_score', { - widget: 'docs_csat', + sendCsatEvent("select_score", { score, reaction: option.reaction, }); - if (option.reaction === 'positive') { - submit(score, { - reaction: option.reaction, - feedback: '', - reasons: [], - }); + if (option.reaction === "positive") { + submit(score, option.reaction, "", []); } }; const toggleReason = (reason: string) => { setSelectedReasons((current) => - current.includes(reason) ? current.filter((item) => item !== reason) : [...current, reason] + current.includes(reason) + ? current.filter((item) => item !== reason) + : [...current, reason], ); }; @@ -181,11 +195,7 @@ export default function CsatWidget(): React.ReactElement | null { } const trimmedFeedback = feedback.trim(); - submit(selectedScore, { - reaction: 'negative', - feedback: trimmedFeedback, - reasons: selectedReasons, - }); + submit(selectedScore, "negative", trimmedFeedback, selectedReasons); }; if (!isVisible) { @@ -243,12 +253,18 @@ export default function CsatWidget(): React.ReactElement | null { ))} - )} - {isSubmitted &&
Thanks for the feedback!
} + {isSubmitted && ( +
Thanks for the feedback!
+ )} ); } From 6a2dea47652938f61e349f1fe90256a0a727fb2f Mon Sep 17 00:00:00 2001 From: Dikran Samarjian Date: Mon, 22 Jun 2026 16:33:36 -0700 Subject: [PATCH 2/2] simplify --- src/components/CsatWidget/index.tsx | 33 ++++++++++------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/components/CsatWidget/index.tsx b/src/components/CsatWidget/index.tsx index 950648bb..d663e6be 100644 --- a/src/components/CsatWidget/index.tsx +++ b/src/components/CsatWidget/index.tsx @@ -14,7 +14,6 @@ declare global { type CsatReaction = "positive" | "negative"; type CsatScore = 1 | 5; -type CsatAction = "view" | "select_score" | "submit" | "dismiss"; function getStorageKey(pathname: string): string { return `${CSAT_STORAGE_PREFIX}${pathname}`; @@ -80,9 +79,11 @@ export default function CsatWidget(): React.ReactElement | null { return normalizedPath !== "/" && normalizedPath !== "/docs"; }, [pathname]); - const sendCsatEvent = ( - action: CsatAction, - details: Record = {}, + const sendCsatSubmitEvent = ( + score: CsatScore, + reaction: CsatReaction, + feedbackValue: string, + reasons: string[], ) => { if ( typeof window === "undefined" || @@ -93,13 +94,16 @@ export default function CsatWidget(): React.ReactElement | null { window.sendV2Event({ source: "docs_csat_widget", - action, + action: "submit", noun: "csat", action_info: { page_type: "dev_portal_docs", page_path: pathname, widget: "docs_csat", - ...details, + score, + reaction, + feedback: feedbackValue, + reasons, }, request: { base_url: window.location.href, @@ -128,14 +132,9 @@ export default function CsatWidget(): React.ReactElement | null { setSelectedReasons([]); setIsSubmitted(false); setIsVisible(!hasSubmitted); - - if (!hasSubmitted) { - sendCsatEvent("view"); - } }, [storageKey, shouldShowForPath]); const dismiss = () => { - sendCsatEvent("dismiss"); setIsVisible(false); }; @@ -149,12 +148,7 @@ export default function CsatWidget(): React.ReactElement | null { return; } - sendCsatEvent("submit", { - score, - reaction, - feedback: feedbackValue, - reasons, - }); + sendCsatSubmitEvent(score, reaction, feedbackValue, reasons); window.sessionStorage.setItem(storageKey, "1"); setIsSubmitted(true); @@ -171,11 +165,6 @@ export default function CsatWidget(): React.ReactElement | null { setFeedback(""); } - sendCsatEvent("select_score", { - score, - reaction: option.reaction, - }); - if (option.reaction === "positive") { submit(score, option.reaction, "", []); }