## DEV NOTES: useCanInteract useCanInteract is a way to provide a boolean value (can interact) and a list of errors to the developer so that they can quickly handle any situation where they want to gate a feature based on any application data It mainly replaces the daoConnectedAndSameChain() helper function that we see everywhere, but it has a lot of other benefits. But to start if we want to use this hook to replace daoConnectedAndSameChain, we do this: ``` const SomeComponent =() => { const { canInteract } = useCanInteract(); return (<AnyChakraComponent disabled={!canInteract}/>) } ``` Before we had to load all the dependencies as argument for daoConnectedAndSameChain (address, daoMemeber, injectedChain) from 2 different contexts. This hook pulls all of its data from the global context (TXContext), so we can check all data within the DAO context and return whether or not it can interact More on that later. Another thing it does is returns errors (in a similar format to react-hook-form). This allows us to display why the user can't interact. That data can be loaded into a tool tip or an ErrorList Example. ``` const SomeComponent =() => { const { canInteract, interactErrors } = useCanInteract(); return ( <> <AnyChakraComponent disabled={!canInteract}/> {interactErrors?.map(error => <SomErrorComponent error={error} />} </> ) } ``` However, by default useCanInteract only returns the first error. If we want a list of errors, we pass params into the hook like this. ``` const { canInteract, interactErrors } = useCanInteract({ errorDeliveryType: 'arrayOfStrings', }); ``` There's also: ``` const { canInteract, interactErrors } = useCanInteract({ errorDeliveryType: 'softErrors', }); ``` 'SoftErrors' are objects that have a type and message property on them. They interface with a lot of the other soft error handling we do across the app. But what does this hook check for? By default the hook checks for: `const defaults = ['isConnected', 'isSameChain', 'isMember'];` This is the default array embedded in the hook itself. But say we want to ignore the isMember check Then we'd initialize the hook like this: ``` const { canInteract, interactErrors } = useCanInteract({ checklist: ['isConnected', 'isSameChain'], }); ``` If this is a form, you can do this inside of your form lego ex. ``` BUY_SHARES: { id: 'BUY_SHARES', ... checklist: ['isConnected', 'isSameChain'], }, ``` FormBuilder will do the rest of the work for you You can also add new checks. We can check for any data in the app, at the DAO context level. All you need to do is add a function to the appCheckFns object in appCheckFns.js Then you add the name of that function to the checklist property ``` const appCheckFns = Object.freeze({ isConnected({ address }) { ... }, isSameChain({ injectedChain, daochain }) { ... }, isMember({ isMember }) { ... }, customThing({appData}){ ... // do something cool and custon } }); ``` ``` const { canInteract, interactErrors } = useCanInteract({ checklist: ['isConnected', 'isSameChain', 'isMember', 'customThing'], }); ``` The hook handles the rest remotely This needs to be copied to a doc, I think