modal-context.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. 'use client'
  2. import type { Dispatch, SetStateAction } from 'react'
  3. import { useState } from 'react'
  4. import { createContext, useContext } from 'use-context-selector'
  5. import { useRouter, useSearchParams } from 'next/navigation'
  6. import AccountSetting from '@/app/components/header/account-setting'
  7. import ApiBasedExtensionModal from '@/app/components/header/account-setting/api-based-extension-page/modal'
  8. import ModerationSettingModal from '@/app/components/app/configuration/toolbox/moderation/moderation-setting-modal'
  9. import ExternalDataToolModal from '@/app/components/app/configuration/tools/external-data-tool-modal'
  10. import Pricing from '@/app/components/billing/pricing'
  11. import type { ModerationConfig } from '@/models/debug'
  12. import type {
  13. ApiBasedExtension,
  14. ExternalDataTool,
  15. } from '@/models/common'
  16. export type ModalState<T> = {
  17. payload: T
  18. onCancelCallback?: () => void
  19. onSaveCallback?: (newPayload: T) => void
  20. onValidateBeforeSaveCallback?: (newPayload: T) => boolean
  21. }
  22. const ModalContext = createContext<{
  23. setShowAccountSettingModal: Dispatch<SetStateAction<ModalState<string> | null>>
  24. setShowApiBasedExtensionModal: Dispatch<SetStateAction<ModalState<ApiBasedExtension> | null>>
  25. setShowModerationSettingModal: Dispatch<SetStateAction<ModalState<ModerationConfig> | null>>
  26. setShowExternalDataToolModal: Dispatch<SetStateAction<ModalState<ExternalDataTool> | null>>
  27. setShowPricingModal: Dispatch<SetStateAction<any>>
  28. }>({
  29. setShowAccountSettingModal: () => {},
  30. setShowApiBasedExtensionModal: () => {},
  31. setShowModerationSettingModal: () => {},
  32. setShowExternalDataToolModal: () => {},
  33. setShowPricingModal: () => {},
  34. })
  35. export const useModalContext = () => useContext(ModalContext)
  36. type ModalContextProviderProps = {
  37. children: React.ReactNode
  38. }
  39. export const ModalContextProvider = ({
  40. children,
  41. }: ModalContextProviderProps) => {
  42. const [showAccountSettingModal, setShowAccountSettingModal] = useState<ModalState<string> | null>(null)
  43. const [showApiBasedExtensionModal, setShowApiBasedExtensionModal] = useState<ModalState<ApiBasedExtension> | null>(null)
  44. const [showModerationSettingModal, setShowModerationSettingModal] = useState<ModalState<ModerationConfig> | null>(null)
  45. const [showExternalDataToolModal, setShowExternalDataToolModal] = useState<ModalState<ExternalDataTool> | null>(null)
  46. const searchParams = useSearchParams()
  47. const router = useRouter()
  48. const [showPricingModal, setShowPricingModal] = useState(searchParams.get('show-pricing') === '1')
  49. const handleCancelAccountSettingModal = () => {
  50. setShowAccountSettingModal(null)
  51. if (showAccountSettingModal?.onCancelCallback)
  52. showAccountSettingModal?.onCancelCallback()
  53. }
  54. const handleCancelModerationSettingModal = () => {
  55. setShowModerationSettingModal(null)
  56. if (showModerationSettingModal?.onCancelCallback)
  57. showModerationSettingModal.onCancelCallback()
  58. }
  59. const handleSaveApiBasedExtension = (newApiBasedExtension: ApiBasedExtension) => {
  60. if (showApiBasedExtensionModal?.onSaveCallback)
  61. showApiBasedExtensionModal.onSaveCallback(newApiBasedExtension)
  62. setShowApiBasedExtensionModal(null)
  63. }
  64. const handleSaveModeration = (newModerationConfig: ModerationConfig) => {
  65. if (showModerationSettingModal?.onSaveCallback)
  66. showModerationSettingModal.onSaveCallback(newModerationConfig)
  67. setShowModerationSettingModal(null)
  68. }
  69. const handleSaveExternalDataTool = (newExternalDataTool: ExternalDataTool) => {
  70. if (showExternalDataToolModal?.onSaveCallback)
  71. showExternalDataToolModal.onSaveCallback(newExternalDataTool)
  72. setShowExternalDataToolModal(null)
  73. }
  74. const handleValidateBeforeSaveExternalDataTool = (newExternalDataTool: ExternalDataTool) => {
  75. if (showExternalDataToolModal?.onValidateBeforeSaveCallback)
  76. return showExternalDataToolModal?.onValidateBeforeSaveCallback(newExternalDataTool)
  77. return true
  78. }
  79. return (
  80. <ModalContext.Provider value={{
  81. setShowAccountSettingModal,
  82. setShowApiBasedExtensionModal,
  83. setShowModerationSettingModal,
  84. setShowExternalDataToolModal,
  85. setShowPricingModal: () => setShowPricingModal(true),
  86. }}>
  87. <>
  88. {children}
  89. {
  90. !!showAccountSettingModal && (
  91. <AccountSetting
  92. activeTab={showAccountSettingModal.payload}
  93. onCancel={handleCancelAccountSettingModal}
  94. />
  95. )
  96. }
  97. {
  98. !!showApiBasedExtensionModal && (
  99. <ApiBasedExtensionModal
  100. data={showApiBasedExtensionModal.payload}
  101. onCancel={() => setShowApiBasedExtensionModal(null)}
  102. onSave={handleSaveApiBasedExtension}
  103. />
  104. )
  105. }
  106. {
  107. !!showModerationSettingModal && (
  108. <ModerationSettingModal
  109. data={showModerationSettingModal.payload}
  110. onCancel={handleCancelModerationSettingModal}
  111. onSave={handleSaveModeration}
  112. />
  113. )
  114. }
  115. {
  116. !!showExternalDataToolModal && (
  117. <ExternalDataToolModal
  118. data={showExternalDataToolModal.payload}
  119. onCancel={() => setShowExternalDataToolModal(null)}
  120. onSave={handleSaveExternalDataTool}
  121. onValidateBeforeSave={handleValidateBeforeSaveExternalDataTool}
  122. />
  123. )
  124. }
  125. {
  126. !!showPricingModal && (
  127. <Pricing onCancel={() => {
  128. if (searchParams.get('show-pricing') === '1')
  129. router.push(location.pathname, { forceOptimisticNavigation: true })
  130. setShowPricingModal(false)
  131. }} />
  132. )
  133. }
  134. </>
  135. </ModalContext.Provider>
  136. )
  137. }
  138. export default ModalContext