Skip to content

Instantly share code, notes, and snippets.

@ArthurDias01
Created December 16, 2021 12:52
Show Gist options
  • Save ArthurDias01/f98d7a62e7434cc2831177e2d15a4f6a to your computer and use it in GitHub Desktop.
Save ArthurDias01/f98d7a62e7434cc2831177e2d15a4f6a to your computer and use it in GitHub Desktop.
import { useState, useEffect, useContext, createContext, ReactNode } from 'react';
import nookies, { setCookie } from 'nookies';
import { firebaseUUID } from '../utils/FirebaseUUID';
import router from 'next/router';
import { useToast } from '@chakra-ui/react';
import { auth, db, authSecond, firebase, storage } from '../config/firebase';
import {
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
sendPasswordResetEmail,
sendEmailVerification,
updateProfile,
User,
signOut,
} from 'firebase/auth';
import { doc, setDoc, getDoc, getDocs, query, collection, where, orderBy } from 'firebase/firestore';
type AuthProviderProps = {
children: ReactNode;
}
type AuthContextProps = {
user: User | null;
signUp: ({ name, email, password }: UserData) => Promise<void>;
signIn: (email: string, password: string) => Promise<void>;
signUpNewUser: ({ name, email, password }: UserSignInData) => Promise<void>;
sendPasswordResetEmailfb: (email: string) => void;
signOutfb: () => void;
signMonitorUp: ({ name, email, password, Venda }: UserMonitorData) => Promise<void>;
loadingUser: boolean;
selectMonitorUp: ({ Monitor, Venda }: UserMonitorSelectedData) => Promise<void>;
userFromFirebase: UserFromFirestore | null | any;
}
type UserData = {
name: string;
email: string;
password: string;
ProfPic?: string;
uid: string;
}
type UserMonitorData = {
name: string;
email: string;
password: string;
ProfPic?: string;
Venda: any;
}
type MonitorType = {
email: string;
name: string;
permissions: string;
photoURL: string;
uid: string;
}
type UserMonitorSelectedData = {
Monitor: MonitorType;
Venda: any;
}
type UserFromFirestore = {
LastCreatedNotifications: firebase.firestore.Timestamp;
permissions: string;
photoURL: string;
Notifications: {
DataConclusao: firebase.firestore.Timestamp;
Resumo: string;
Titulo: string;
TaskID: string;
isRead: boolean;
}[];
} & UserData;
type UserSignInData = {
name: string;
email: string;
password: string;
ProfPic?: string;
}
const AuthContext = createContext({} as AuthContextProps);
export const AuthProvider = ({ children }: AuthProviderProps) => {
const [user, setUser] = useState<AuthContextProps['user']>(null);
const [loadingUser, setLoadinUser] = useState<boolean>(true);
const [userFromFirebase, setUserFromFirebase] = useState<UserFromFirestore | null>(null);
const [permissionsState, setPermissionState] = useState(null)
const toast = useToast();
const signUp = async ({ name, email, password }: UserSignInData) => {
return await
createUserWithEmailAndPassword(auth, email, password)
.then(() => {
sendEmailVerification(auth.currentUser as User);
updateProfile(auth.currentUser as User, {
displayName: name,
photoURL: 'https://i.ibb.co/9qcn0DY/1519871684414.jpg',
}).then(async () => {
await
setDoc(doc(db, "users", `${auth.currentUser?.uid}`), {
name: auth.currentUser?.displayName,
email: auth.currentUser?.email,
photoURL: auth.currentUser?.photoURL,
permissions: 'admin',
uid: auth.currentUser?.uid,
LastCreatedNotifications: new Date(),
Notifications: [],
});
toast({
variant: 'solid',
position: 'top',
title: 'Sucesso!',
description: `${auth.currentUser?.displayName} sua conta foi criada com sucesso`,
status: 'success',
duration: 4000,
isClosable: true
});
})
router.push('/dashboard')
return;
})
.catch((error) => {
const message = error.message;
toast({
variant: 'solid',
position: 'top',
title: 'Erro!',
description: message,
status: 'error',
duration: 4000,
isClosable: true
})
})
};
const signUpNewUser = async ({ name, email, password }: UserSignInData) => {
return await
createUserWithEmailAndPassword(authSecond, email, password)
.then(() => {
sendEmailVerification(authSecond.currentUser as User);
updateProfile(authSecond.currentUser as User, {
displayName: name,
photoURL: 'https://i.ibb.co/9qcn0DY/1519871684414.jpg',
}).then(async () => {
await
setDoc(doc(db, "users", `${authSecond.currentUser?.uid}`), {
name: authSecond.currentUser?.displayName,
email: authSecond.currentUser?.email,
photoURL: authSecond.currentUser?.photoURL,
permissions: 'admin',
uid: authSecond.currentUser?.uid,
LastCreatedNotifications: new Date(),
Notifications: [],
});
toast({
variant: 'solid',
position: 'top',
title: 'Sucesso!',
description: `${auth.currentUser?.displayName} sua conta foi criada com sucesso`,
status: 'success',
duration: 4000,
isClosable: true
});
})
return signOut(authSecond);
})
.catch((error) => {
const message = error.message;
toast({
variant: 'solid',
position: 'top',
title: 'Erro!',
description: message,
status: 'error',
duration: 4000,
isClosable: true
})
})
};
const signMonitorUp = async ({ name, email, password, Venda }: UserMonitorData) => {
const MonitoramentoID = firebaseUUID()();
return await
createUserWithEmailAndPassword(authSecond, email, password)
.then(async () => {
await sendEmailVerification(authSecond.currentUser as User);
await updateProfile(authSecond.currentUser as User, {
displayName: name,
photoURL: 'https://i.ibb.co/9qcn0DY/1519871684414.jpg',
}).then(async () => {
await
setDoc(doc(db, "users", `${authSecond.currentUser?.uid}`), {
name: authSecond.currentUser?.displayName,
email: authSecond.currentUser?.email,
photoURL: authSecond.currentUser?.photoURL,
permissions: ['monitor'],
uid: authSecond.currentUser?.uid,
LastCreatedNotifications: new Date(),
Notifications: [],
}).then(async () => {
await setDoc(doc(db, `Vendas/${Venda.VendaID}/Monitoramentos/${MonitoramentoID}`), {
MonitorID: authSecond.currentUser?.uid,
Monitor: {
name: authSecond.currentUser?.displayName,
email: authSecond.currentUser?.email,
},
VendaID: Venda.VendaID,
DadosMontoramento: [],
TipoDeServico: Venda.Area.TipoDeServico,
Periodo: {
DataInicial: Venda.PERIODO_ACORDADO.DataInicial,
DataFinal: Venda.PERIODO_ACORDADO.DataFinal,
},
Local: Venda.Area.Localizacao,
Maquina: Venda.Maquina,
Area: Venda.Area,
TamanhoTotal: Venda.Area.Tamanho,
Talhoes: [],
STATUS_RELATORIO: 'PENDENTE',
NumeroSemanasTotal: Math.ceil(Venda.PERIODO_ACORDADO.DataFinal.getTime() - Venda.PERIODO_ACORDADO.DataInicial.getTime()) / (1000 * 60 * 60 * 24 * 7),
MonitoramentoID: MonitoramentoID,
ClienteMaquina: Venda.ClienteMaquina,
});
await setDoc(doc(db, `Vendas/${Venda.VendaID}`), {
MonitorID: authSecond.currentUser?.uid,
MonitorNome: authSecond.currentUser?.displayName,
MonitoramentoID: MonitoramentoID,
}, { merge: true });
}).catch(error => {
toast({
variant: 'solid',
position: 'top',
title: 'ERRO!',
description: `ERRO AO CRIAR O DOCUMENTO DE MONITORAMENTO: ${error}`,
status: 'error',
duration: 4000,
isClosable: true
});
})
toast({
variant: 'solid',
position: 'top',
title: 'Sucesso!',
description: `A conta do Monitor ${authSecond.currentUser?.displayName} foi criada com sucesso`,
status: 'success',
duration: 4000,
isClosable: true
});
})
signOut(authSecond);
return;
})
.catch((error) => {
const message = error.message;
toast({
variant: 'solid',
position: 'top',
title: 'Erro!',
description: message,
status: 'error',
duration: 4000,
isClosable: true
})
})
};
const selectMonitorUp = async ({ Monitor, Venda }: UserMonitorSelectedData) => {
const MonitoramentoID = firebaseUUID()();
return await setDoc(doc(db, `Vendas/${Venda.VendaID}/Monitoramentos/${MonitoramentoID}`), {
MonitorID: Monitor.uid,
Monitor: Monitor,
Talhoes: [],
VendaID: Venda.VendaID,
DadosMontoramento: [],
TipoDeServico: Venda.Area.TipoDeServico,
Periodo: {
DataInicial: Venda.PERIODO_ACORDADO.DataInicial,
DataFinal: Venda.PERIODO_ACORDADO.DataFinal,
},
Local: Venda.Area.Localizacao,
Maquina: Venda.Maquina,
Area: Venda.Area,
TamanhoTotal: Venda.Area.Tamanho,
STATUS_RELATORIO: 'PENDENTE',
NumeroSemanasTotal: Math.ceil(Venda.PERIODO_ACORDADO.DataFinal.getTime() - Venda.PERIODO_ACORDADO.DataInicial.getTime()) / (1000 * 60 * 60 * 24 * 7),
MonitoramentoID: MonitoramentoID,
ClienteMaquina: Venda.ClienteMaquina,
}).then(async () => {
await setDoc(doc(db, `Vendas/${Venda.VendaID}`), {
MonitorID: Monitor.uid,
MonitorNome: Monitor.name,
MonitoramentoID: MonitoramentoID,
}, { merge: true });
toast({
variant: 'solid',
position: 'bottom',
title: 'Sucesso!',
description: `A conta do Monitor ${Monitor.name} foi criada com sucesso`,
status: 'success',
duration: 4000,
isClosable: true
});
})
};
const signIn = async (email: string, password: string) => {
await
signInWithEmailAndPassword(auth, email, password)
.then(async () => {
const docRef = doc(db, `users/${auth.currentUser?.uid}`);
const docSnapshot = await getDoc(docRef).then(doc => {
setUserFromFirebase(doc.data() as UserFromFirestore)
nookies.set(undefined, "permissions", doc.data()?.permissions, { path: '/' });
}).catch(error => {
console.log('error', error);
})
router.push('/dashboard');
return auth.currentUser;
}).catch((error) => {
const message = error.message;
toast({
variant: 'solid',
position: 'top',
title: 'Erro!',
description: message,
status: 'error',
duration: 4000,
isClosable: true
})
});
}
const signOutfb = async () => {
await signOut(auth);
nookies.set(undefined, "token", "", { path: '/' });
nookies.set(undefined, "permissions", "", { path: '/' });
setUser(null);
router.push('/');
};
const sendPasswordResetEmailfb = async (email: string) => {
await sendPasswordResetEmail(auth, email)
.then(() => {
toast({
variant: 'solid',
position: 'top',
title: 'Sucesso!',
description: `Um email de reset de senha foi enviado para: ${email}`,
status: 'info',
duration: 4000,
isClosable: true
});
router.push('/')
}).catch((error) => {
const message = error.message;
toast({
variant: 'solid',
position: 'top',
title: 'Erro!',
description: message,
status: 'error',
duration: 4000,
isClosable: true
})
})
}
useEffect(() => {
return auth.onIdTokenChanged(async (user) => {
if (!user) {
setUser(null);
nookies.set(undefined, "token", "", { path: '/' });
nookies.set(undefined, "permissions", "", { path: '/' });
setLoadinUser(false);
return;
}
const token = await user.getIdToken();
setUser(user);
nookies.set(undefined, "token", token, { path: '/' });
const refreshDate = new Date();
if (userFromFirebase?.permissions === 'admin' && userFromFirebase.LastCreatedNotifications.toDate().getDate() < refreshDate.getDate()) {
const ref = query(collection(db, "Tarefas"), where("CriadorID", '==', `${userFromFirebase.uid}`), orderBy('Data_criacao', 'asc'),);
const TasksData: Array<any> = [];
const snapshot = await getDocs(ref);
snapshot.forEach((doc: any) => {
TasksData.push({ ...doc.data(), docRef: doc.id })
});
const TodayDate = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate());
const TomorrowDate = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate() + 1);
const TarefasDoDia = TasksData.length > 0 ? TasksData.filter((Tarefa) => {
return Tarefa.DataConclusao?.toDate() >= TodayDate && Tarefa.DataConclusao?.toDate() < TomorrowDate;
}) : [];
const TarefasAtrasadas = TasksData.length > 0 ? TasksData.filter((Tarefa) => {
return Tarefa.DataConclusao.toDate() < TodayDate;
}) : [];
const AllNotifications = [
...TarefasDoDia,
...TarefasAtrasadas,
];
const Collection = collection(db, "users");
const refNotifications = doc(Collection, `${userFromFirebase.uid}`);
//Getting User Data before overwrite it
const DocUserData = {
email: userFromFirebase.email,
name: userFromFirebase.name,
photoURL: userFromFirebase.photoURL,
permissions: userFromFirebase.permissions,
uid: userFromFirebase.uid,
};
return await setDoc(refNotifications, {
LastCreatedNotifications: new Date(),
Notifications: AllNotifications,
...DocUserData,
}, { merge: false }).then(() => {
console.log('Notifications created');
});
}
setLoadinUser(false);
});
}, [])
return (
<AuthContext.Provider value={{ user, signUp, signIn, signUpNewUser, sendPasswordResetEmailfb, signOutfb, signMonitorUp, loadingUser, selectMonitorUp, userFromFirebase }}>
{children}
</AuthContext.Provider>
)
}
export const useAuth = () => useContext(AuthContext);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment