createPool.ts
1 import { atom } from 'jotai'; 2 import { UseFormReturn } from 'react-hook-form'; 3 import { FormWizardStep } from 'components/FormWizard'; 4 5 const initialSteps = [ 6 { 7 title: 'Name & Description', 8 key: 'nameDesc', 9 }, 10 { 11 title: 'Assets', 12 key: 'assetsTemp', 13 }, 14 { 15 title: 'Asset Settings', 16 key: 'assetSettings', 17 }, 18 { 19 title: 'Pool Settings', 20 key: 'poolSettings', 21 }, 22 { 23 title: 'Pool Incentives', 24 key: 'poolIncentives', 25 }, 26 // { 27 // title: 'Pool Managers', 28 // key: 'governance', 29 // }, 30 { 31 title: 'Confirm', 32 key: 'confirm', 33 }, 34 ] as const; 35 36 const formValuesMap = initialSteps.reduce( 37 (acc, { key }) => Object.assign(acc, { [key]: null }), 38 {} as { [key: string]: any }, 39 ); 40 41 export type CreatePoolFormKeys = typeof initialSteps[number]['key']; 42 43 export interface CreatePoolState { 44 currentStep: number; 45 steps: FormWizardStep[]; 46 formValues: { 47 [key in CreatePoolFormKeys]: { 48 [key: string]: any; 49 }; 50 }; 51 } 52 53 const initialStepsWithStatus = initialSteps.map((step) => ({ 54 ...step, 55 status: { 56 isDirty: false, 57 isValid: false, 58 }, 59 })); 60 61 export const createPoolAtom = atom({ 62 currentStep: 0, 63 steps: initialStepsWithStatus, 64 formValues: formValuesMap, 65 }); 66 67 export const stepsAtom = atom( 68 (get) => get(createPoolAtom), 69 (get, set, newStep: number) => { 70 const nextState = Object.assign({}, get(createPoolAtom)); 71 nextState.currentStep = newStep; 72 set(createPoolAtom, nextState); 73 }, 74 ); 75 76 interface FormValuesUpdater { 77 formKey: FormWizardStep['key']; 78 values: { [key: string]: any }; 79 } 80 81 export const formValuesAtom = atom( 82 (get) => get(createPoolAtom).formValues, 83 (get, set, { formKey, values }: FormValuesUpdater) => { 84 const nextState = Object.assign({}, get(createPoolAtom)); 85 nextState.formValues[formKey] = values; 86 set(createPoolAtom, nextState); 87 }, 88 ); 89 90 interface FormStateUpdater { 91 isDirty: UseFormReturn['formState']['isDirty']; 92 isValid: UseFormReturn['formState']['isValid']; 93 } 94 95 export const formStateWriterAtom = atom( 96 undefined, 97 (get, set, { isDirty, isValid }: FormStateUpdater) => { 98 const nextState = Object.assign({}, get(createPoolAtom)); 99 nextState.steps[nextState.currentStep].status = { 100 isDirty, 101 isValid, 102 }; 103 set(createPoolAtom, nextState); 104 }, 105 ); 106 107 export const confirmStateReader = atom((get) => { 108 // strip out intermediate form steps 109 const keysToSkip = ['assetsTemp']; 110 return Object.entries(get(createPoolAtom).formValues).reduce( 111 (acc, [key, values]) => { 112 if (keysToSkip.indexOf(key) > -1) return acc; 113 return values ? Object.assign(acc, values) : acc; 114 }, 115 {}, 116 ); 117 });