diff --git a/src/components/FeedbackWidget.tsx b/src/components/FeedbackWidget.tsx deleted file mode 100644 index 0e13b47fb4f..00000000000 --- a/src/components/FeedbackWidget.tsx +++ /dev/null @@ -1,276 +0,0 @@ -import { useEffect, useMemo, useRef, useState } from "react" -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" -import { - AlertDialog, - AlertDialogBody, - AlertDialogCloseButton, - AlertDialogContent, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogOverlay, - Box, - Button, - ButtonProps, - ScaleFade, - useDisclosure, -} from "@chakra-ui/react" - -import { FeedbackGlyphIcon } from "@/components/icons" -import Text from "@/components/OldText" - -import { trackCustomEvent } from "@/lib/utils/matomo" - -import { DEFAULT_LOCALE } from "@/lib/constants" - -import { useSurvey } from "@/hooks/useSurvey" - -type FixedDotProps = ButtonProps & { - bottomOffset: number - isExpanded: boolean -} -const FixedDot = ({ - children, - bottomOffset, - isExpanded, - ...props -}: FixedDotProps) => { - const { t } = useTranslation("common") - const size = "3rem" - return ( - - ) -} - -const FeedbackWidget = () => { - const { t } = useTranslation("common") - const { asPath, locale } = useRouter() - const { isOpen, onOpen, onClose } = useDisclosure() - const cancelRef = useRef(null) - const [isExpanded, setIsExpanded] = useState(false) - const [feedbackSubmitted, setFeedbackSubmitted] = useState(false) - - useEffect(() => { - // Reset component state when path (asPath) changes - onClose() - setFeedbackSubmitted(false) - setIsExpanded(false) - - let expandTimeout = setTimeout(() => setIsExpanded(true), 30_000) - - return () => clearTimeout(expandTimeout) - }, [asPath, onClose]) - - const surveyUrl = useSurvey(feedbackSubmitted) - - const bottomOffset = useMemo(() => { - const pathsWithBottomNav = ["/staking/", "/dao/", "/defi/", "/nft/"] - const CONDITIONAL_OFFSET = 6.75 - let offset = 0 - pathsWithBottomNav.forEach((path) => { - if (asPath.includes(path)) { - offset = CONDITIONAL_OFFSET - } - }) - return offset - }, [asPath]) - - const handleClose = (): void => { - onClose() - trackCustomEvent({ - eventCategory: `FeedbackWidget toggled`, - eventAction: `Clicked`, - eventName: `Closed feedback widget`, - }) - } - - const handleOpen = (): void => { - onOpen() - setIsExpanded(false) - trackCustomEvent({ - eventCategory: `FeedbackWidget toggled`, - eventAction: `Clicked`, - eventName: `Opened feedback widget`, - }) - } - - const handleSubmit = (choice: boolean): void => { - trackCustomEvent({ - eventCategory: `Page is helpful feedback`, - eventAction: `Clicked`, - eventName: String(choice), - }) - setFeedbackSubmitted(true) - } - const handleSurveyOpen = (): void => { - trackCustomEvent({ - eventCategory: `Feedback survey opened`, - eventAction: `Clicked`, - eventName: "Feedback survey opened", - }) - window && surveyUrl && window.open(surveyUrl, "_blank") - onClose() // Close widget without triggering redundant tracker event - setIsExpanded(false) - } - - // Display on English pages only - if (locale !== DEFAULT_LOCALE) return null - - return ( - <> - - - - {isExpanded && ( - - - {t("feedback-widget-prompt")} - - - )} - - - - - - - - - - - {feedbackSubmitted - ? t("feedback-widget-thank-you-title") - : t("feedback-widget-prompt")} - - - {/* Body: */} - {feedbackSubmitted && ( - <> - - {t("feedback-widget-thank-you-subtitle")} - - - {t("feedback-widget-thank-you-timing")} - - - )} - - - {feedbackSubmitted ? ( - - ) : ( - <> - - - - )} - - - - - - - ) -} - -export default FeedbackWidget diff --git a/src/components/FeedbackWidget/FeedbackWidget.stories.tsx b/src/components/FeedbackWidget/FeedbackWidget.stories.tsx new file mode 100644 index 00000000000..273fcd627bf --- /dev/null +++ b/src/components/FeedbackWidget/FeedbackWidget.stories.tsx @@ -0,0 +1,28 @@ +import * as React from "react" +import { Box, Stack } from "@chakra-ui/react" +import { Meta, StoryObj } from "@storybook/react" + +import FeedbackWidgetComponent from "./" + +type FeedbackWidgetType = typeof FeedbackWidgetComponent + +const meta = { + title: "FeedbackWidget", + parameters: { + layout: "fullscreen", + }, + decorators: [ + (Story) => ( + + + + + ), + ], +} satisfies Meta + +export default meta + +export const FeedbackWidget: StoryObj = { + render: () => , +} diff --git a/src/components/FeedbackWidget/FixedDot.tsx b/src/components/FeedbackWidget/FixedDot.tsx new file mode 100644 index 00000000000..a9a9a8d0a63 --- /dev/null +++ b/src/components/FeedbackWidget/FixedDot.tsx @@ -0,0 +1,60 @@ +import { useTranslation } from "next-i18next" +import { Button, ButtonProps, ScaleFade, Text } from "@chakra-ui/react" + +import { FeedbackGlyphIcon } from "../icons" + +type FixedDotProps = ButtonProps & { + bottomOffset: number + isExpanded: boolean +} +const FixedDot = ({ bottomOffset, isExpanded, ...props }: FixedDotProps) => { + const { t } = useTranslation("common") + const size = "12" + return ( + + ) +} + +export default FixedDot diff --git a/src/components/FeedbackWidget/index.tsx b/src/components/FeedbackWidget/index.tsx new file mode 100644 index 00000000000..060581a57a3 --- /dev/null +++ b/src/components/FeedbackWidget/index.tsx @@ -0,0 +1,136 @@ +import { useTranslation } from "next-i18next" +import { + AlertDialog, + AlertDialogBody, + AlertDialogCloseButton, + AlertDialogContent, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogOverlay, + Box, + Button, +} from "@chakra-ui/react" + +import FixedDot from "./FixedDot" +import { useFeedbackWidget } from "./useFeedbackWidget" + +const FeedbackWidget = () => { + const { t } = useTranslation("common") + const { + bottomOffset, + cancelRef, + feedbackSubmitted, + getButtonProps, + handleClose, + handleOpen, + handleSubmit, + handleSurveyOpen, + isExpanded, + isOpen, + } = useFeedbackWidget() + return ( + <> + + + + + + + + + + {feedbackSubmitted + ? t("feedback-widget-thank-you-title") + : t("feedback-widget-prompt")} + + + {/* Body: */} + {feedbackSubmitted && ( + <> + + {t("feedback-widget-thank-you-subtitle")} + + + {t("feedback-widget-thank-you-timing")} + + + )} + + + {feedbackSubmitted ? ( + + ) : ( + <> + + + + )} + + + + + + + ) +} + +export default FeedbackWidget diff --git a/src/components/FeedbackWidget/useFeedbackWidget.ts b/src/components/FeedbackWidget/useFeedbackWidget.ts new file mode 100644 index 00000000000..a32efcafb67 --- /dev/null +++ b/src/components/FeedbackWidget/useFeedbackWidget.ts @@ -0,0 +1,94 @@ +import { useEffect, useMemo, useRef, useState } from "react" +import { useRouter } from "next/router" +import { useDisclosure } from "@chakra-ui/react" + +import { trackCustomEvent } from "@/lib/utils/matomo" + +import { useSurvey } from "@/hooks/useSurvey" + +export const useFeedbackWidget = () => { + const { asPath } = useRouter() + + const [isExpanded, setIsExpanded] = useState(false) + const [feedbackSubmitted, setFeedbackSubmitted] = useState(false) + + const { getButtonProps, isOpen, onClose, onOpen } = useDisclosure() + + const cancelRef = useRef(null) + + useEffect(() => { + // Reset component state when path (asPath) changes + onClose() + setFeedbackSubmitted(false) + setIsExpanded(false) + + let expandTimeout = setTimeout(() => setIsExpanded(true), 30_000) + + return () => clearTimeout(expandTimeout) + }, [asPath, onClose]) + + const surveyUrl = useSurvey(feedbackSubmitted) + + const bottomOffset = useMemo(() => { + const pathsWithBottomNav = ["/staking", "/dao", "/defi", "/nft"] + const CONDITIONAL_OFFSET = 6.75 + let offset = 0 + pathsWithBottomNav.forEach((path) => { + if (asPath.includes(path)) { + offset = CONDITIONAL_OFFSET + } + }) + return offset + }, [asPath]) + + const handleClose = (): void => { + onClose() + trackCustomEvent({ + eventCategory: `FeedbackWidget toggled`, + eventAction: `Clicked`, + eventName: `Closed feedback widget`, + }) + } + + const handleOpen = (): void => { + onOpen() + setIsExpanded(false) + trackCustomEvent({ + eventCategory: `FeedbackWidget toggled`, + eventAction: `Clicked`, + eventName: `Opened feedback widget`, + }) + } + + const handleSubmit = (choice: boolean): void => { + trackCustomEvent({ + eventCategory: `Page is helpful feedback`, + eventAction: `Clicked`, + eventName: String(choice), + }) + setFeedbackSubmitted(true) + } + const handleSurveyOpen = (): void => { + trackCustomEvent({ + eventCategory: `Feedback survey opened`, + eventAction: `Clicked`, + eventName: "Feedback survey opened", + }) + window && surveyUrl && window.open(surveyUrl, "_blank") + onClose() // Close widget without triggering redundant tracker event + setIsExpanded(false) + } + + return { + bottomOffset, + cancelRef, + feedbackSubmitted, + getButtonProps, + handleClose, + handleOpen, + handleSubmit, + handleSurveyOpen, + isExpanded, + isOpen, + } +} diff --git a/src/data/crowdin/translation-buckets-dirs.json b/src/data/crowdin/translation-buckets-dirs.json index 047969f7919..f3595190c39 100644 --- a/src/data/crowdin/translation-buckets-dirs.json +++ b/src/data/crowdin/translation-buckets-dirs.json @@ -115,4 +115,4 @@ "id": 8218, "name": "Menu redesign & language picker" } -] \ No newline at end of file +]