-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathhooks.tsx
29 lines (26 loc) · 1.19 KB
/
hooks.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { Account, DID, PlanGetSuccess, PlanSetSuccess, PlanSetFailure, Result } from '@w3ui/react'
import useSWR, { SWRResponse, useSWRConfig } from 'swr'
/**
* calculate the cache key for a plan's account
*/
const planKey = (account: Account) => account ? `/plan/${account.did()}` : undefined
type UsePlanResult = SWRResponse<PlanGetSuccess | undefined> & {
setPlan: (plan: DID) => Promise<Result<PlanSetSuccess, PlanSetFailure>>
}
export const usePlan = (account: Account) => {
const { mutate } = useSWRConfig()
const result = useSWR<PlanGetSuccess | undefined>(planKey(account), {
fetcher: async () => {
if (!account) return
const result = await account.plan.get()
if (result.error) throw new Error('getting plan', { cause: result.error })
return result.ok
},
onError: err => console.error(err.message, err.cause)
})
// @ts-ignore it's important to assign this into the existing object
// to avoid calling the getters in SWRResponse when copying values over -
// I can't think of a cleaner way to do this but open to refactoring
result.setPlan = async (plan: DID) => await mutate(planKey(account), account.plan.set(plan))
return result as UsePlanResult
}