Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: insights feedback functionality #10342

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions packages/client/hooks/useManualClientSideTrack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {useCallback} from 'react'
import SendClientSideEvent from '../utils/SendClientSideEvent'
import useAtmosphere from './useAtmosphere'

const useManualClientSideTrack = () => {
const atmosphere = useAtmosphere()

const trackEvent = useCallback(
(event: string, options: Record<string, any>) => {
SendClientSideEvent(atmosphere, event, {
...options
})
},
[atmosphere]
)

return trackEvent
}

export default useManualClientSideTrack
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {RadioButtonChecked, RadioButtonUnchecked, ThumbDown, ThumbUp} from '@mui/icons-material'
import React, {useState} from 'react'
import React, {useCallback, useState} from 'react'
import BasicTextArea from '../../../../components/InputField/BasicTextArea'
import PrimaryButton from '../../../../components/PrimaryButton'
import useManualClientSideTrack from '../../../../hooks/useManualClientSideTrack'
import {Dialog} from '../../../../ui/Dialog/Dialog'
import {DialogActions} from '../../../../ui/Dialog/DialogActions'
import {DialogContent} from '../../../../ui/Dialog/DialogContent'
Expand All @@ -12,46 +13,67 @@ type Props = {
onClose: () => void
}

type FeedbackState = {
isUseful: boolean
feedback: string
canEmail: boolean
}

const defaultFeedbackState: FeedbackState = {
isUseful: true,
feedback: '',
canEmail: true
}

const InsightsFeedbackModal = (props: Props) => {
const {isOpen, onClose} = props
const [isUseful, setIsUseful] = useState<boolean | null>(null)
const [feedback, setFeedback] = useState('')
const [canEmail, setCanEmail] = useState<boolean>(true)
const [feedbackState, setFeedbackState] = useState(defaultFeedbackState)
const trackEvent = useManualClientSideTrack()

const handleSubmit = () => {
console.log({isUseful, feedback, canEmail})
const handleSubmit = useCallback(() => {
trackEvent('Insights Feedback Submitted', feedbackState)
onClose()
}
setFeedbackState(defaultFeedbackState)
}, [trackEvent, feedbackState, onClose])

const handleClose = useCallback(() => {
onClose()
setFeedbackState(defaultFeedbackState)
}, [onClose])

const updateField = useCallback((field: keyof FeedbackState, value: any) => {
setFeedbackState((prev) => ({...prev, [field]: value}))
}, [])

return (
<Dialog isOpen={isOpen} onClose={onClose}>
<Dialog isOpen={isOpen} onClose={handleClose}>
<DialogContent>
<DialogTitle>Insights Feedback</DialogTitle>
<div className='mt-4 flex items-center justify-between'>
<p className='font-semibold'>Were these insights useful?</p>
<div className='flex space-x-4'>
<button
onClick={() => setIsUseful(true)}
onClick={() => updateField('isUseful', true)}
className='group flex items-center space-x-2 bg-transparent hover:cursor-pointer'
>
<ThumbUp
className={`transition-colors duration-200 ${isUseful === true ? 'text-sky-500' : 'text-slate-500 group-hover:text-sky-500'}`}
className={`transition-colors duration-200 ${feedbackState.isUseful ? 'text-sky-500' : 'text-slate-500 group-hover:text-sky-500'}`}
/>
<span
className={`transition-colors duration-200 ${isUseful === true ? 'text-sky-500' : 'text-slate-500 group-hover:text-sky-500'}`}
className={`transition-colors duration-200 ${feedbackState.isUseful ? 'text-sky-500' : 'text-slate-500 group-hover:text-sky-500'}`}
>
Yes
</span>
</button>
<button
onClick={() => setIsUseful(false)}
onClick={() => updateField('isUseful', false)}
className='group flex items-center space-x-2 bg-transparent hover:cursor-pointer'
>
<ThumbDown
className={`transition-colors duration-200 ${isUseful === false ? 'text-sky-500' : 'text-slate-500 group-hover:text-sky-500'}`}
className={`transition-colors duration-200 ${!feedbackState.isUseful ? 'text-sky-500' : 'text-slate-500 group-hover:text-sky-500'}`}
/>
<span
className={`transition-colors duration-200 ${isUseful === false ? 'text-sky-500' : 'text-slate-500 group-hover:text-sky-500'}`}
className={`transition-colors duration-200 ${!feedbackState.isUseful ? 'text-sky-500' : 'text-slate-500 group-hover:text-sky-500'}`}
>
No
</span>
Expand All @@ -62,30 +84,30 @@ const InsightsFeedbackModal = (props: Props) => {
<p className='mb-2 font-semibold'>Additional feedback (optional):</p>
<BasicTextArea
name='feedback'
value={feedback}
onChange={(e) => setFeedback(e.target.value)}
value={feedbackState.feedback}
onChange={(e) => updateField('feedback', e.target.value)}
placeholder='Your feedback here...'
/>
</div>
<div className='mt-4'>
<p className='mb-2 font-bold'>May we email you to talk more regarding your feedback?</p>
<div className='flex space-x-4'>
<button
onClick={() => setCanEmail(true)}
onClick={() => updateField('canEmail', true)}
className='flex items-center space-x-2 bg-transparent hover:cursor-pointer'
>
{canEmail ? (
{feedbackState.canEmail ? (
<RadioButtonChecked className='text-sky-500' />
) : (
<RadioButtonUnchecked className='text-slate-500' />
)}
<span>Yes, you may email me</span>
</button>
<button
onClick={() => setCanEmail(false)}
onClick={() => updateField('canEmail', false)}
className='flex items-center space-x-2 bg-transparent hover:cursor-pointer'
>
{!canEmail ? (
{!feedbackState.canEmail ? (
<RadioButtonChecked className='text-sky-500' />
) : (
<RadioButtonUnchecked className='text-slate-500' />
Expand Down
14 changes: 14 additions & 0 deletions packages/server/utils/analytics/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ export type AnalyticsEvent =
| 'Slack notification sent'
| 'Smart group title changed'
| 'Task due date set'
| 'Insights Feedback Submitted'

/**
* Provides a unified interface for sending all the analytics events
Expand Down Expand Up @@ -709,6 +710,19 @@ class Analytics {
})
}

insightsFeedbackSubmitted = (
user: AnalyticsUser,
isUseful: boolean,
feedback: string,
canEmail: boolean
) => {
this.track(user, 'Insights Feedback Submitted', {
isUseful,
feedback,
canEmail
})
}

identify = (options: IdentifyOptions) => {
this.amplitudeAnalytics.identify(options)
}
Expand Down
Loading