Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import {
- getCognitoUser,
- getEVUser,
- setEVUserAttributes,
- } from '@/lib/schema/user/client-fetch';
- import { CognitoUser, EVUser } from '@/lib/schema/user/types';
- import { showToast } from '@/lib/toast';
- import { useQuery } from '@tanstack/react-query';
- import {
- deleteUser as deleteCognitoUser,
- updateUserAttributes,
- } from 'aws-amplify/auth';
- import { Hub, HubCapsule } from 'aws-amplify/utils';
- import {
- createContext,
- FC,
- PropsWithChildren,
- useCallback,
- useEffect,
- useMemo,
- useState,
- } from 'react';
- export interface AuthContextType {
- user: CognitoUser | null;
- evUser: EVUser | null;
- updateEVUser: (newEVUser: EVUser) => Promise<{ ok: boolean }>;
- deleteUser: () => Promise<{ ok: boolean }>;
- error: boolean;
- loading: boolean;
- }
- export const AuthContext = createContext<AuthContextType | null>(null);
- interface AuthProviderProps {
- ssrUser?: CognitoUser | null;
- }
- /**
- * Context that holds and controls the signed in state.
- *
- * @param {AuthProviderProps} props - The properties for the AuthProvider component.
- * @param {ReactNode} props.children - The children components that require access to authentication context.
- * @param {User} [props.preloadedUser] - A user object that is preloaded, if available.
- * @param {User} [props.user] - The current authenticated Cognito user.
- * @param {EVUser} props.evUser - The user data stored in the database - used to render user info on client side.
- * @param {() => void} props.updateEVUser - Function to update the evUser - updates the database and will update the client render.
- * @param {boolean} props.isLoading - Loading state of the authentication context.
- * @param {boolean} props.isError - Error state of the authentication context.
- * @returns {JSX.Element} The AuthContext.Provider component with authentication context values.
- */
- export const AuthProvider: FC<PropsWithChildren<AuthProviderProps>> = ({
- children,
- ssrUser,
- }) => {
- const [preloadedUser, setPreloadedUser] = useState(ssrUser);
- const [evUser, setEVUser] = useState<EVUser | null>(null);
- Hub.listen('auth', async (data: HubCapsule<'auth', any>) => {
- switch (data.payload.event) {
- case 'signedIn':
- console.log('signedIn from auth provider');
- refetchUser();
- setPreloadedUser(null);
- break;
- case 'signedOut':
- console.log('signed out from auth provider');
- setPreloadedUser(null);
- refetchUser();
- break;
- default:
- break;
- }
- });
- const updateUser = async () => {
- const newUser = await getCognitoUser();
- if (newUser) {
- const newEVUser = await getEVUser();
- setEVUser(newEVUser);
- if (newEVUser) {
- const updatedFields: { given_name?: string; family_name?: string } = {};
- if (newEVUser.firstName) {
- updatedFields.given_name = newEVUser.firstName;
- }
- if (newEVUser.lastName) {
- updatedFields.family_name = newEVUser.lastName;
- }
- await updateUserAttributes({ userAttributes: updatedFields });
- }
- }
- return newUser;
- };
- const updateEVUser = useCallback(async (newEVUser: EVUser) => {
- try {
- await setEVUserAttributes(newEVUser);
- await updateUserAttributes({
- userAttributes: {
- given_name: newEVUser.firstName,
- family_name: newEVUser.lastName,
- },
- });
- setEVUser(newEVUser);
- showToast('Successfully saved your profile!', { type: 'success' });
- return { ok: true };
- } catch (err) {
- showToast('Something went wrong saving your profile. Please try again.', {
- type: 'error',
- });
- return { ok: false };
- }
- }, []);
- const deleteUser = useCallback(async () => {
- try {
- if (evUser) {
- await setEVUserAttributes({
- ...evUser,
- flaggedForDeletion: true,
- });
- await deleteCognitoUser();
- setEVUser(null);
- }
- return { ok: true };
- } catch (err) {
- showToast(
- 'Something went wrong deleting your account. Please try again.',
- {
- type: 'error',
- }
- );
- return { ok: false };
- }
- }, [evUser]);
- const {
- data: user,
- refetch: refetchUser,
- isLoading,
- isError,
- } = useQuery({
- queryKey: ['cognito-user'],
- queryFn: updateUser,
- });
- const value = useMemo(
- () => ({
- user: preloadedUser || user || null,
- evUser,
- updateEVUser,
- deleteUser,
- loading: isLoading,
- error: isError,
- }),
- [preloadedUser, user, isLoading, isError, evUser, updateEVUser, deleteUser]
- );
- return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement