...
intl-whitelabel-graphql
TASK 1 - Create type
We will create a
type
namedRequiredAcceptanceAgreementInfo
path:
intl-whitelabel-graphql/src/functions/graphql/schemas/users.gql
Code Block language graphql type RequiredAcceptanceAgreementInfo { """ Acceptance Agreement ID """ id: String """ Updated Date """ updatedAt: String }
Also, we will add
requiredAcceptanceAgreementInfo
on typeUserDetails
Code Block language graphql type UserDetails { ... """ Acceptance Agreement info """ requiredAcceptanceAgreementInfo: [RequiredAcceptanceAgreementInfo] }
We will run the command:
Code Block yarn run graphql:types
After that, will be created an automatic code on file:
intl-whitelabel-graphql/src/functions/graphql/generated/graphql.ts
, probably, will be many changes, but we can to discard all, except of change related aboutrequiredAcceptanceAgreementInfo
intl-whitelabel-app
TASK 2 - Create fragment
We will add the attribute
requiredAcceptanceAgreementInfo
onfragment
:path:
intl-whitelabel-app/workspaces/frontend/src/remote/queries/user.ts
Code Block language graphql const DetailsFragment = gql` fragment DetailsFragment on UserDetails { ... requiredAcceptanceAgreementInfo { id updatedAt } } `;
We will run the command:
Code Block language powershell yarn run apollo:generate
After that, will be created an automatic code on file:
intl-whitelabel-app/workspaces/frontend/src/generated/rbi-graphql.tsx
, probably, will be many changes, but we can to discard all, except of change related about:Code Block language typescript export interface IRequiredAcceptanceAgreementInfo { readonly __typename?: 'RequiredAcceptanceAgreementInfo', readonly id: Maybe<Scalars['String']>, readonly updatedAt: Maybe<Scalars['String']>, }
Code Block language typescript export interface IUserDetails { ... readonly requiredAcceptanceAgreementInfo: Maybe<ReadonlyArray<Maybe<IRequiredAcceptanceAgreementInfo>>>, }
Code Block language typescript export type IUserDetailsFragment = { ... readonly requiredAcceptanceAgreementInfo: Maybe<ReadonlyArray<Maybe<{ readonly __typename?: 'RequiredAcceptanceAgreementInfo', readonly id: Maybe<string>, readonly updatedAt: Maybe<string> }>>>}
Code Block language graphql export const UserDetailsFragmentFragmentDoc = gql` fragment UserDetailsFragment on UserDetails { ... requiredAcceptanceAgreementInfo { id updatedAt } }
TASK 3 - Refactore method getRequiredAcceptanceAgreementInfo
We will change the existent method
getRequiredAcceptanceAgreementInfo
(name and container)path:
intl-whitelabel-app/workspaces/frontend/src/state/auth/hooks/use-account-authentication.ts
before
Code Block language typescript const getRequiredAcceptanceAgreementInfo = useCallback(() => { if (!loadRoutesHasBeenCalled) { loadRoutes(); } return staticPageRoute .map(pages => { if (pages?.requiredUserAcceptance) { return { id: pages._id, updatedAt: pages._updatedAt, } as IRequiredAcceptanceAgreementInfoInput; } return []; }) .flat(); }, [loadRoutes, loadRoutesHasBeenCalled, staticPageRoute]);
after
Code Block language typescript const getAcceptanceAgreementFromSanity = useCallback(() => { if (!loadRoutesHasBeenCalled) { loadRoutes(); } return staticPageRoute.filter(pages => pages?.requiredUserAcceptance); }, [loadRoutes, loadRoutesHasBeenCalled, staticPageRoute]);
After that, we will update the call from method
signUp
before
Code Block language typescript const requiredAcceptance = enableRequiredAcceptanceAgreementInfo ? getRequiredAcceptanceAgreementInfo() : undefined; try { if (enableSignUpInBE) { const { data } = await signUpMutation({ variables: { input: { ... requiredAcceptanceAgreementInfo: requiredAcceptance, }, }, }); ... } else { ... } } catch (error) { ... };
after
Code Block language typescript const requiredAcceptance = enableRequiredAcceptanceAgreementInfo ? getAcceptanceAgreementFromSanity() : []; const requiredAcceptanceFilter = requiredAcceptance.map(pages => { return { id: pages._id, updatedAt: pages._updatedAt, } as IRequiredAcceptanceAgreementInfoInput; }); try { if (enableSignUpInBE) { const { data } = await signUpMutation({ variables: { input: { ... requiredAcceptanceAgreementInfo: requiredAcceptanceFilter, }, }, }); ... } else { ... } } catch (error) { ... };
We will create the method
validateAcceptanceAgreement
Code Block language typescript const validateAcceptanceAgreement = useCallback((user: IUser): IStaticPageRoute[] => { const requiredAcceptanceAgreementInfo = user?.details?.requiredAcceptanceAgreementInfo; if (requiredAcceptanceAgreementInfo?.length) { const sanityAcceptanceAgreement = getAcceptanceAgreementFromSanity(); const sanityAcceptanceAgreement =if getAcceptanceAgreementFromSanity(requiredAcceptanceAgreementInfo?.length); { return sanityAcceptanceAgreement.filter((sanityAcceptance: IStaticPageRoute) => requiredAcceptanceAgreementInfo.find( (acceptanceAgreement: IRequiredAcceptanceAgreementInfo) => sanityAcceptance._id === acceptanceAgreement.id && sanityAcceptance._updatedAt !== acceptanceAgreement.updatedAt ) ); } return []sanityAcceptanceAgreement; }, [getAcceptanceAgreementFromSanity, user]);
Finishing, we will export these methods
getAcceptanceAgreementFromSanity
andvalidateAcceptanceAgreement
on hookuseAccountAuthentication
returnCode Block language typescript return { ... getAcceptanceAgreementFromSanity, validateAcceptanceAgreement };
TASK 4 - Add validation on index auth
On file:
path:
intl-whitelabel-app/workspaces/frontend/src/state/auth/index.tsx
We will export
validateAcceptanceAgreement
Code Block language typescript const { ... validateAcceptanceAgreement, } = useAccountAuthentication({ refreshCurrentUser, openErrorDialog, setCurrentUser, });
After that, we will create a
useEffect
:Code Block language typescript useEffect(() => { const validate = enableRequiredAcceptanceAgreementInfo ? validateAcceptanceAgreement(user) : []; if (validate?.length) { // TODO MODAL COMPONENT } }, [user, validateAcceptanceAgreement, getCtx]);
We will add on
useEffect
the methodgetCtx
because all time thegetCtx
will change, we will validate the Acceptance Agreements
...