Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adicionando Firebase como base de dados. #95

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

filipeleonelbatista
Copy link

@filipeleonelbatista filipeleonelbatista commented Sep 18, 2023

Adicionei o firebase como base de dados. Não modifiquei nada de muito preciso embora acredite em uma refatoração do projeto usando algumas outras tecnologias que possam melhorar e agilizar a entrega de um serviço para a comunidade.

Optei pelo uso do firebase pois ele tem um plano gratuito que tem como limite de leituras diario 50 mil requisições o que pode ser muito neste inicio.

Com esse refactor fiz uma area administrativa com login de email/senha do firebase onde se tem mum semi crud para adicionar e remover os desafios.

Fiz alguns ajustes nos links da página inicial e nos selects da pagina de desafios para trazerem os desafios de acordo com a estrutura do firebase mas sem alterar os componentes no geral.

Como nao tem a integração com o dev nesta versão eu adicionei o link do repositório e o usuário no cadastro do desafio..

Existe uma flag no desafio chamada active que é boolean e que pode nos ajudar a controlar se os desafios enviados foram aprovados ou não.

A estrutura do desafio ficou assim

interface Challenges {
            type: "Back-end" | "Front-end" | "Mobile",
            level: "Iniciante" | "Intermediário" | "Avançado",
            techs: string[],
            githubRepository: string,
            username: string,
            background: string,
            name: string,
            description: string,
            createdAt: number,
            active: boolean,
        };

Junto com isso adicionei uma tabela de newsletter para podermos trabalhar com isso em um futuro proximo automatizando com cron jobs (que ja tenho um serviço similar rodando hoje). Usei uma estrutura bem básica.

interface Newsletter {
            email: string,
            optInDate: number,
            optOutDate: number,
            createdAt: number,
            active: boolean,
        };

Para finalizar a implementação teria que criar uma base no firebase, e colocar as chaves que forem geradas nas variaveis de ambiente do projeto e configurar os buckets storage e firestore database para poder usar.

Alguns pontos a considerar e que adoraria participar:

  • Adicionar Typescript
  • Migrar de CRA para VITE
  • Usar alguma ferramenta que adiante o processo de criação dos componentes, eu curto Material UI ou ShadCn/ui
  • Usar validadores de forms, como implementado, YUP e formik para manipulação dos estados do form.
  • Criar um roadmap de release de features para podermos implementar com a comunidade.

Fica aí o pr para aprovação. Qualquer dúvida estou aqui animado e ansioso para colaborar mais.

@vercel
Copy link

vercel bot commented Sep 18, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
dev ❌ Failed (Inspect) Sep 18, 2023 11:38am

@filipeleonelbatista
Copy link
Author

image
image
image
image
image
image
image

Comment on lines +5 to +21
const colorMatch = (option) => {
switch (option) {
case 'Iniciante':
return 'nephritis';
case 'Intermediário':
return 'pumpkin';
case 'Avançado':
return 'pomegranate';
case 'Mobile':
return 'blue';
case 'Front-end':
return 'red';
case 'Back-end':
return 'light-purple';
default:
return 'green';
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acho que seria uma boa manter o objeto para fazer o matching, apenas para fins de simplicidade, já que podemos acessar com colorMatch[option]

<p>{challenge.description}</p>{' '}
<p>
{challenge.description.length > 120
? challenge.description.substr(0, 120) + '...'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

String.substr está depreciado pela linguagem (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr), contudo, você pode usar substring ou slice para mesma finalidade

Comment on lines +123 to +145
return signInWithEmailAndPassword(authentication, email, password)
.then(async (re) => {
setIsLogged(true);
setKeyLocalStorage('UID', re.user.uid);
const currentUser = await getUserByID(re.user.uid);
setUser(currentUser);
const status = {
user: currentUser,
status: true,
};
return status;
})
.catch((err) => {
const status = {
status: false,
message: AuthErrorHandler[err.code],
err,
};

console.log('signInUser error', status);
return status;
});
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ao invés de retornar diretamente a chamada da função, seria mais adequado um bloco de try/catch com o retorno apropriado para cada situação (erro ou sucesso). Além disso, você pode usar async/await para uma vez que signInWithEmailAndPassword é uma função assíncrona e retorna uma promise resolvida ou rejeitada, e assim você naõ precisa usar o then e o catch (esse último é uma sugestão bem pessoal, acredito que aumenta a legibilidade do código)

Comment on lines +148 to +172
return createUserWithEmailAndPassword(authentication, email, password)
.then(async (re) => {
const newUser = {
uid: re.user.uid,
...user,
};
try {
await setDoc(doc(db, 'users', re.user.uid), newUser);

setKeyLocalStorage('UID', re.user.uid);

setUser(newUser);
return true;
} catch (err) {
ToastNotification.notify(
'error',
'Houve um erro ao cadastrar o usuario. Tente novamente mais tarde'
);
return false;
}
})
.catch((err) => {
ToastNotification.notify('error', AuthErrorHandler[err.code]);
return false;
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

o mesmo aqui e todas a funções com estrutura análogas a que eu comentei acima

Comment on lines +203 to +213
value={{
user,
RegisterUser,
signInUser,
logout,
handleForgotUser,
isLogged,
getUserByID,
isMenuHide,
setIsMenuHide,
}}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

É sempre importante salvar esses valores em um useMemo, pois em cada renderização o React vai calcular eses valores novamente, já que a referência dele será perdida entre as renderizações, logo serão tratados como um novo objeto e consequentemente recalculados.

Comment on lines +120 to +129
value={{
challengesList,
selectedChallenge,
setSelectedChallenge,
updateChallengesList,
handleDeleteChallenge,
addChallenge,
updateChallenge,
getChallengeByID,
}}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

o mesmo aqui, sobre usar o useMemo

import { AuthContext } from '../contexts/AuthContext';

export function useAuth() {
const value = useContext(AuthContext);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

é uma boa prática conferir se o Provider desse context está sendo usado da árvore de elementos, dessa forma:

export function useAuth() {
  const context = useContext(AuthContext);

  if (!context) {
    throw new Error('useAuth must be inside an AuthProvider with a value');
  }

  return context;
}

Comment on lines +4 to +7
export function useChallenges() {
const value = useContext(ChallengesContext);
return value;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Comment on lines +47 to +58
if (isLogged.status) {
if (isLogged.user.active) {
history.push('/admin/challenges');
} else {
alert(
'Solicite permissão ao administrador para acessar o sistema'
);
}
} else {
alert(isLogged.message);
setShowRegister(true);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isso tá um pouquinho confuso, porém dá pra refatorar assim:

if (!isLogged.status) {
  alert(isLogged.message);
  setShowRegister(true);
  return;
}

if (!isLogged.user.active) {
  alert("Solicite permissão ao administrador para acessar o sistema");
  return;
}

history.push("/admin/challenges");

que fica mais fácil de entender o que tá acontecendo e evita aninhamento de if/else (que no geral, usar else não é legal)

Comment on lines +75 to +82
if (isRegistered) {
alert(
'Solicite a liberação do acesso ao administrador do sistema'
);
} else {
alert('Houve um problema ao cadastrar');
setShowRegister(true);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mesma coisa, usar else não é muito legal, então você pode inverter a orderm e fazer um "early return" no if pra remover o else

Comment on lines +52 to +68
const colorMatch = (option) => {
switch (option) {
case 'Iniciante':
return 'nephritis';
case 'Intermediário':
return 'pumpkin';
case 'Avançado':
return 'pomegranate';
case 'Mobile':
return 'blue';
case 'Front-end':
return 'red';
case 'Back-end':
return 'light-purple';
default:
return 'green';
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

como disse anteriormente, melhor manter o objeto, só por simplicidade

const [challenge, setChallenge] = useState({});
const [techs, setTechs] = useState([]);
const [dev, setDev] = useState({});
// const [dev, setDev] = useState({});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comentários 😿

Comment on lines +85 to 88
// setDev(response.data.dev_id);
setImages([response[0]?.background]);
setTechs(response[0]?.techs);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comentários 😿


await addDoc(newsletterRef, data);

return true;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

não entendi por quê está retornando true/false

Comment on lines +1 to +8
REACT_APP_FIREBASE_APIKEY=AIzaSyDlSDvVRBTuEBULLJ7F1Zny9uEKvm34U8I
REACT_APP_FIREBASE_AUTHDOMAIN=devchallenge-16edf.firebaseapp.com
REACT_APP_FIREBASE_PROJECTID=devchallenge-16edf
REACT_APP_FIREBASE_STORAGEBUCKET=devchallenge-16edf.appspot.com
REACT_APP_FIREBASE_MESSAGINGSENDERID=457450543508
REACT_APP_FIREBASE_APPID=1:457450543508:web:6afbe9416f72e9830b5781
REACT_APP_FIREBASE_MEASUREMENTID=G-KKVZ30J836

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

acho que isso está aqui por engano!

Copy link

@Isaac-alencar Isaac-alencar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Muito obrigado pela contrib, @filipeleonelbatista , mandou bem!

Só umas coisinhas aqui pra revisar, quando você puder dá uma olhadinha dps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants