| 1 |
import { useState, useEffect } from '@wordpress/element' |
| 2 |
import { create } from 'zustand' |
| 3 |
import { persist, createJSONStorage } from 'zustand/middleware' |
| 4 |
import { User } from '@library/api/User' |
| 5 |
|
| 6 |
const storage = { |
| 7 |
getItem: async () => await User.getData(), |
| 8 |
setItem: async (_name, value) => await User.setData(value), |
| 9 |
removeItem: async () => await User.deleteData(), |
| 10 |
} |
| 11 |
|
| 12 |
const MAX_IMPORTS = 10 |
| 13 |
export const useUserStore = create( |
| 14 |
persist( |
| 15 |
(set, get) => ({ |
| 16 |
firstLoadedOn: new Date().toISOString(), |
| 17 |
email: '', |
| 18 |
apiKey: '', |
| 19 |
uuid: '', |
| 20 |
sdkPartner: '', |
| 21 |
noticesDismissedAt: {}, |
| 22 |
modalNoticesDismissedAt: {}, |
| 23 |
imports: 0, // total imports over time |
| 24 |
runningImports: 0, // timed imports, resets to 0 every month |
| 25 |
entryPoint: 'not-set', |
| 26 |
// enabled: true, // removed |
| 27 |
canInstallPlugins: false, |
| 28 |
canActivatePlugins: false, |
| 29 |
openOnNewPage: undefined, // This is only being used on the server |
| 30 |
setOpenOnNewPage: (value) => set({ openOnNewPage: value }), |
| 31 |
incrementImports: () => { |
| 32 |
set((state) => ({ |
| 33 |
imports: Number(state.imports) + 1, |
| 34 |
runningImports: Number(state.runningImports) + 1, |
| 35 |
})) |
| 36 |
}, |
| 37 |
hasAvailableImports: () => { |
| 38 |
return get().apiKey |
| 39 |
? true |
| 40 |
: Number(get().runningImports) < MAX_IMPORTS |
| 41 |
}, |
| 42 |
remainingImports: () => { |
| 43 |
const remaining = MAX_IMPORTS - Number(get().runningImports) |
| 44 |
return remaining > 0 ? remaining : 0 |
| 45 |
}, |
| 46 |
// Will mark a modal or footer notice |
| 47 |
markNoticeSeen: (key, type) => { |
| 48 |
set({ |
| 49 |
[`${type}DismissedAt`]: { |
| 50 |
...get()[`${type}DismissedAt`], |
| 51 |
[key]: new Date().toISOString(), |
| 52 |
}, |
| 53 |
}) |
| 54 |
}, |
| 55 |
}), |
| 56 |
{ |
| 57 |
name: 'extendify-user', |
| 58 |
storage: createJSONStorage(() => storage), |
| 59 |
}, |
| 60 |
), |
| 61 |
) |
| 62 |
|
| 63 |
/* Hook useful for when you need to wait on the async state to hydrate */ |
| 64 |
export const useUserStoreReady = () => { |
| 65 |
const [hydrated, setHydrated] = useState(useUserStore.persist.hasHydrated) |
| 66 |
useEffect(() => { |
| 67 |
const unsubFinishHydration = useUserStore.persist.onFinishHydration( |
| 68 |
() => setHydrated(true), |
| 69 |
) |
| 70 |
return () => { |
| 71 |
unsubFinishHydration() |
| 72 |
} |
| 73 |
}, []) |
| 74 |
return hydrated |
| 75 |
} |
| 76 |
|