UpgradeModal.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { useParams } from 'common'
  2. import { includes, without } from 'lodash'
  3. import { useReducer, useState } from 'react'
  4. import { toast } from 'sonner'
  5. import { Modal, TextArea } from 'ui'
  6. import { generateUpgradeReasons } from '../helpers'
  7. import { useSendUpgradeFeedbackMutation } from '@/data/feedback/upgrade-survey-send'
  8. import type { OrgSubscription } from '@/data/subscriptions/types'
  9. export interface UpgradeSurveyModalProps {
  10. visible: boolean
  11. originalPlan?: string
  12. subscription?: OrgSubscription
  13. onClose: (success?: boolean) => void
  14. }
  15. // Upgrade survey is from Free Plan to Pro/Team Plan and from Pro to Team Plan
  16. const UpgradeSurveyModal = ({
  17. visible,
  18. originalPlan,
  19. subscription,
  20. onClose,
  21. }: UpgradeSurveyModalProps) => {
  22. const { slug } = useParams()
  23. const [message, setMessage] = useState('')
  24. const [selectedReasons, dispatchSelectedReasons] = useReducer(reducer, [])
  25. const upgradeReasons = generateUpgradeReasons(originalPlan, subscription?.plan.id)
  26. const { mutate: sendUpgradeSurvey, isPending: isSubmitting } = useSendUpgradeFeedbackMutation({
  27. onError: (error) => {
  28. toast.error(`Failed to submit survey: ${error.message}`)
  29. },
  30. onSuccess: () => {
  31. onClose(true)
  32. window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
  33. },
  34. })
  35. function reducer(state: any, action: any) {
  36. if (includes(state, action.target.value)) {
  37. return without(state, action.target.value)
  38. } else {
  39. return [...state, action.target.value]
  40. }
  41. }
  42. const onSubmit = async () => {
  43. if (selectedReasons.length === 0) {
  44. return toast.error('Please select at least one reason for upgrading your subscription')
  45. }
  46. sendUpgradeSurvey({
  47. orgSlug: slug,
  48. prevPlan: originalPlan,
  49. currentPlan: subscription?.plan?.id,
  50. reasons: selectedReasons,
  51. message: message.trim() || undefined,
  52. })
  53. }
  54. return (
  55. <>
  56. <Modal
  57. alignFooter="right"
  58. size="xlarge"
  59. loading={isSubmitting}
  60. visible={visible}
  61. onCancel={onClose}
  62. onConfirm={onSubmit}
  63. cancelText="Skip"
  64. header="We're excited for your upgrade"
  65. >
  66. <Modal.Content className="space-y-4">
  67. <p className="text-sm text-foreground-light">
  68. What reasons motivated your decision to upgrade? Your feedback helps us improve Briven
  69. as much as we can.
  70. </p>
  71. <div className="space-y-8 mt-6">
  72. <div className="flex flex-wrap gap-2" data-toggle="buttons">
  73. {upgradeReasons.map((option) => {
  74. const active = selectedReasons.find((x) => x === option)
  75. return (
  76. <label
  77. key={option}
  78. className={`
  79. flex cursor-pointer items-center space-x-2 rounded-md py-1
  80. pl-2 pr-3 text-center text-sm
  81. shadow-xs transition-all duration-100
  82. ${
  83. active
  84. ? ` bg-foreground text-background opacity-100 hover:bg-foreground/75`
  85. : ` bg-border-strong text-foreground opacity-25 hover:opacity-50`
  86. }
  87. `}
  88. >
  89. <input
  90. type="checkbox"
  91. name="options"
  92. value={option}
  93. className="hidden"
  94. onClick={dispatchSelectedReasons}
  95. />
  96. <div>{option}</div>
  97. </label>
  98. )
  99. })}
  100. </div>
  101. <div className="text-area-text-sm flex flex-col gap-y-2">
  102. <label htmlFor="message" className="text-sm whitespace-pre-line wrap-break-word">
  103. Anything else that we can improve on?
  104. </label>
  105. <TextArea
  106. id="message"
  107. name="message"
  108. value={message}
  109. onChange={(event: any) => setMessage(event.target.value)}
  110. rows={3}
  111. />
  112. </div>
  113. </div>
  114. </Modal.Content>
  115. </Modal>
  116. </>
  117. )
  118. }
  119. export default UpgradeSurveyModal