Skip to content

Commit

Permalink
POC: Convert Provider to Zustand store
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanbonial committed Oct 18, 2024
1 parent 01d0313 commit c1123df
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 100 deletions.
3 changes: 2 additions & 1 deletion packages/sanity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@
"use-hot-module-reload": "^2.0.0",
"use-sync-external-store": "^1.2.0",
"vite": "^4.5.1",
"yargs": "^17.3.0"
"yargs": "^17.3.0",
"zustand": "^5.0.0"
},
"devDependencies": {
"@jest/expect": "^29.7.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ import {
} from './__telemetry__/trialDialogEvents.telemetry'
import {DialogContent} from './DialogContent'
import {FreeTrialButtonSidebar, FreeTrialButtonTopbar} from './FreeTrialButton'
import {useFreeTrialContext} from './FreeTrialContext'
import {useFreeTrial} from './FreeTrialStore'
import {PopoverContent} from './PopoverContent'

interface FreeTrialProps {
type: 'sidebar' | 'topbar'
}

export function FreeTrial({type}: FreeTrialProps) {
const {data, showDialog, showOnLoad, toggleShowContent} = useFreeTrialContext()
// const {data, showDialog, showOnLoad, toggleShowContent} = useFreeTrialContext()
const {data, showDialog, showOnLoad, toggleShowContent} = useFreeTrial()
const scheme = useColorSchemeValue()
const telemetry = useTelemetry()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import {useTelemetry} from '@sanity/telemetry/react'
import {useEffect} from 'react'
import {useRouter} from 'sanity/router'
import {create} from 'zustand'

import {useClient} from '../../../../hooks'
import {SANITY_VERSION} from '../../../../version'
import {getTrialStage, TrialDialogViewed} from './__telemetry__/trialDialogEvents.telemetry'
import {type FreeTrialResponse} from './types'

interface FreeTrialState {
// State
data: FreeTrialResponse | null
showDialog: boolean
showOnLoad: boolean

// Actions
setData: (data: FreeTrialResponse | null) => void
setShowDialog: (show: boolean) => void
setShowOnLoad: (show: boolean) => void
}

// Zustand state management store
const useFreeTrialStore = create<FreeTrialState>((set) => ({
data: null,
showDialog: false,
showOnLoad: false,

setData: (data) => set({data}),
setShowDialog: (show) => set({showDialog: show}),
setShowOnLoad: (show) => set({showOnLoad: show}),
}))

// Custom hook that combines Zustand store with other hooks
export const useFreeTrial = () => {
const router = useRouter()
const client = useClient({apiVersion: '2023-12-11'})
const telemetry = useTelemetry()

const {data, showDialog, showOnLoad, setData, setShowDialog, setShowOnLoad} = useFreeTrialStore()

// Toggle show content function that needs client
const toggleShowContent = async (closeAndReOpen = false) => {
if (showOnLoad) {
setShowOnLoad(false)
setShowDialog(closeAndReOpen)
if (data?.showOnLoad?.id) {
await client.request({
url: `/journey/trial/${data.showOnLoad.id}`,
method: 'POST',
})
}
} else {
setShowDialog(!showDialog)
}
}

// Effect for telemetry tracking
useEffect(() => {
const dialog = data?.showOnLoad
if (showDialog && showOnLoad && dialog) {
telemetry.log(TrialDialogViewed, {
dialogId: dialog.id,
dialogRevision: dialog._rev,
dialogTrialStage: getTrialStage({showOnLoad, dialogId: dialog.id}),
dialogTrigger: showOnLoad ? 'auto' : 'fromClick',
dialogType: dialog.dialogType,
source: 'studio',
trialDaysLeft: data.daysLeft,
})
}
}, [showDialog, data, showOnLoad, telemetry])

// Effect for initialization
useEffect(() => {
const searchParams = new URLSearchParams(router.state._searchParams)
const queryParams = new URLSearchParams()
queryParams.append('studioVersion', SANITY_VERSION)

const trialState = searchParams.get('trialState')
if (trialState) queryParams.append('trialState', trialState)

const seenBefore = searchParams.get('seenBefore')
if (seenBefore) queryParams.append('seenBefore', seenBefore)

const queryURL = queryParams.get('trialState') ? `/journey/trial/override` : `/journey/trial`

const request = client.observable
.request<FreeTrialResponse | null>({
url: `${queryURL}?${queryParams.toString()}`,
})
.subscribe(
(response) => {
setData(response)
if (response?.showOnLoad) {
setShowOnLoad(true)
setShowDialog(true)
}
},
() => {
/* silently ignore any error */
},
)

return () => {
request.unsubscribe()
}
}, [client, router.state._searchParams, setData, setShowDialog, setShowOnLoad])

return {
data,
showDialog,
showOnLoad,
toggleShowContent,
}
}
Loading

0 comments on commit c1123df

Please sign in to comment.