O Questlog e um aplicativo mobile de gerenciamento pessoal de tarefas desenvolvido com React Native e Expo. A proposta do app e transformar tarefas comuns em quests, usando uma linguagem visual inspirada em jogos, guildas, missoes e progresso por experiencia.
O objetivo principal e permitir que uma pessoa organize suas tarefas do dia a dia de forma mais motivadora. Cada tarefa possui status, dificuldade e recompensa de XP. Quando uma tarefa e concluida, o usuario acumula experiencia no perfil.
O publico-alvo sao usuarios que desejam gerenciar tarefas pessoais em um formato mais ludico, especialmente pessoas interessadas em jogos, RPG, produtividade gamificada ou interfaces com tema geek.
Principais funcionalidades implementadas:
- Cadastro e login com Firebase Auth.
- Protecao de telas para usuarios autenticados.
- Criacao de quests/tasks.
- Listagem de quests pertencentes ao usuario logado.
- Agrupamento visual das quests por status.
- Visualizacao de detalhes de uma quest.
- Edicao de titulo, descricao, dificuldade e status.
- Marcacao de quest como concluida.
- Recompensa de XP ao concluir uma quest.
- Controle para evitar XP duplicado na mesma quest.
- Perfil com XP total, nivel, titulo atual, tarefas concluidas e progresso ate o proximo nivel.
O tema visual e dark mode, com estetica de fantasia/sci-fi. A interface usa cards, pills, botoes destacados e textos relacionados a guilda, missoes, contratos e aventureiro.
React Native e a base do aplicativo mobile. Ele permite criar interfaces nativas usando componentes React, como View, Text, Pressable, TextInput e ScrollView.
Expo e usado para facilitar o desenvolvimento, configuracao e build do app React Native. O projeto usa o pacote expo e scripts como:
npm start: inicia o servidor Expo.npm run android: inicia o app no Android.npm run ios: inicia o app no iOS.npm run web: inicia a versao web.npm run lint: executa o lint do Expo.
O projeto esta configurado com Expo SDK 55, conforme package.json.
Expo Router e usado para navegacao baseada em arquivos. As rotas do app sao definidas dentro de src/app, por exemplo:
src/app/login.tsxgera a rota/login.src/app/quests.tsxgera a rota/quests.src/app/quest-details/[id].tsxgera uma rota dinamica.
O arquivo principal de layout e src/app/_layout.tsx, que configura o Stack de navegacao.
TypeScript e usado para tipagem estatica. O projeto possui tipos para tarefas, status, dificuldades, perfil do usuario e entradas de servico. Isso ajuda a reduzir erros e documentar melhor as estruturas de dados.
Firebase Authentication e usado para cadastro, login, controle de sessao e logout. O app utiliza e-mail e senha, com funcoes como:
createUserWithEmailAndPasswordsignInWithEmailAndPasswordupdateProfileonAuthStateChangedsignOut
Firebase Realtime Database e usado para armazenar as quests e o progresso do usuario. As tarefas sao gravadas no caminho:
users/{uid}/tasks/{taskId}
O progresso do perfil e salvo em:
users/{uid}/profile
Conforme package.json, o projeto tambem usa:
firebase: SDK do Firebase usado para Auth e Realtime Database.@react-navigation/*: bibliotecas de navegacao usadas internamente pelo Expo Router.react-native-screens: otimizacao de telas nativas.react-native-safe-area-context: suporte a areas seguras em dispositivos moveis.react-native-gesture-handler: suporte a gestos.react-native-reanimatedereact-native-worklets: suporte a animacoes e worklets.expo-status-bar: controle da barra de status.expo-splash-screen: configuracao de splash screen.expo-router: roteamento por arquivos.expo-dev-client: suporte a development builds.typescript,eslinteeslint-config-expo: tipagem e validacao do codigo.
Contem as telas e rotas do aplicativo. Como o projeto usa Expo Router, cada arquivo dentro dessa pasta representa uma rota. Tambem contem _layout.tsx, que define a estrutura de navegacao principal.
Contem componentes reutilizaveis de interface. Essa pasta concentra os elementos visuais usados em varias telas, como cards, botoes, pills, inputs, textos tematicos e tabs.
Guarda constantes e regras compartilhadas, como:
- status de tarefas;
- dificuldades;
- XP por dificuldade;
- metadados visuais;
- cores;
- espacamentos;
- regras de nivel e titulo do perfil.
Contem hooks relacionados ao tema e esquema de cores:
use-color-scheme.tsuse-color-scheme.web.tsuse-theme.ts
Esses hooks ajudam a obter o tema atual do app.
Contem a integracao com Firebase e as funcoes que acessam o banco:
firebase.ts: inicializacao do Firebase.tasks.ts: criacao, listagem, busca, edicao e mudanca de status das tasks.profile.ts: leitura do progresso do perfil.
Contem imagens e icones usados pelo Expo, como icone do app, splash screen e imagens de icone Android.
Contem scripts auxiliares do projeto, como reset-project.js.
package.json: scripts e dependencias.app.json: configuracoes do Expo, identificadores do app, icones, splash e plugins.tsconfig.json: configuracao TypeScript.metro.config.js: configuracao do Metro bundler usandoexpo/metro-config.eas.json: perfis de build EAS.
- Rota: layout raiz, nao representa uma tela acessada diretamente.
- Funcao: configura a navegacao principal com
Stack. - Le do banco: nao.
- Escreve no banco: nao.
- Exige login: nao diretamente.
- Principais acoes:
- define rotas como
index,dashboard,quests,profile,create-quest,quest-details/[id]elogin; - configura estilo da barra de navegacao e status bar.
- define rotas como
- Rota:
/ - Funcao: redireciona o usuario para
/dashboard. - Le do banco: nao.
- Escreve no banco: nao.
- Exige login: nao diretamente, mas o dashboard verifica autenticacao.
- Principais acoes:
- executar
<Redirect href="/dashboard" />.
- executar
- Rota:
/login - Funcao: permite login e cadastro de usuario.
- Le do banco: nao usa Realtime Database.
- Escreve no banco: nao usa Realtime Database.
- Usa Firebase Auth: sim.
- Exige login: nao.
- Principais acoes:
- alternar entre modo login e cadastro;
- informar nome no cadastro;
- informar e-mail e senha;
- criar conta com
createUserWithEmailAndPassword; - atualizar nome do usuario com
updateProfile; - entrar com
signInWithEmailAndPassword; - redirecionar para
/questsapos sucesso; - exibir mensagens de erro.
- Rota:
/dashboard - Funcao: apresenta um resumo geral do progresso e das missoes.
- Le do banco: sim.
- Escreve no banco: nao.
- Exige login: sim.
- Principais acoes:
- verificar sessao com
onAuthStateChanged; - assinar tasks do usuario com
subscribeUserTasks; - assinar perfil com
subscribeUserProfile; - mostrar XP total, nivel, missoes ativas e concluidas;
- mostrar proxima missao sugerida;
- navegar para criar missao;
- navegar para o mural de missoes.
- verificar sessao com
- Rota:
/quests - Funcao: lista as quests do usuario agrupadas por status.
- Le do banco: sim.
- Escreve no banco: nao.
- Exige login: sim.
- Principais acoes:
- verificar usuario logado;
- carregar tasks em tempo real por
subscribeUserTasks; - agrupar tasks por status;
- mostrar estados de loading, erro e lista vazia;
- navegar para
/create-quest; - navegar para detalhes em
/quest-details/{id}.
- Rota:
/create-quest - Funcao: permite criar uma nova quest/task.
- Le do banco: nao.
- Escreve no banco: sim.
- Exige login: sim.
- Principais acoes:
- preencher titulo;
- preencher descricao opcional;
- escolher dificuldade;
- escolher status inicial;
- validar titulo e sessao;
- salvar a quest com
createUserTask; - redirecionar para
/quests.
- Rota:
/quest-details/:id - Funcao: exibe e edita os detalhes de uma quest especifica.
- Le do banco: sim.
- Escreve no banco: sim.
- Exige login: sim.
- Principais acoes:
- buscar task pelo id com
getUserTask; - editar titulo;
- editar descricao;
- editar dificuldade;
- editar status;
- salvar alteracoes com
updateUserTask; - marcar rapidamente como concluida com
changeUserTaskStatus; - mostrar recompensa, dificuldade salva, status de XP e data de conclusao.
- buscar task pelo id com
- Rota:
/profile - Funcao: mostra a ficha de progresso do usuario.
- Le do banco: sim.
- Escreve no banco: nao diretamente.
- Exige login: sim.
- Principais acoes:
- verificar sessao;
- assinar perfil com
subscribeUserProfile; - mostrar nome/e-mail do usuario;
- mostrar XP total, nivel, titulo atual, tarefas concluidas e progresso;
- executar logout com
signOut.
- Arquivo:
src/components/questlog-card.tsx - Funcao: estrutura base das telas.
- Props principais:
eyebrow: texto pequeno acima do titulo;title: titulo da tela;subtitle: subtitulo opcional;children: conteudo da tela.
- Onde e usado: login, dashboard, quests, create-quest, quest-details e profile.
- Importancia: padroniza margem, largura maxima, scroll, cabecalho e fundo dark mode.
- Exemplo real de uso em
src/app/create-quest.tsx:
<QuestlogScreen
eyebrow="Forja de contratos"
title="Nova Missão"
subtitle="Registre uma tarefa, escolha sua dificuldade e defina como ela entra no seu mural.">
{/* conteudo da tela */}
</QuestlogScreen>- Arquivo:
src/components/questlog-card.tsx - Funcao: cria blocos visuais para agrupar informacoes.
- Props principais: recebe props de
View, incluindostyleechildren. - Onde e usado: em todas as telas principais.
- Importancia: cria consistencia visual para formularios, resumo de perfil, cards de quest e estados vazios.
- Exemplo real de uso em
src/app/quests.tsx:
<QuestlogCard>
<QuestlogPill tone={taskStatusMetadata[task.status].tone}>
{taskStatusMetadata[task.status].label}
</QuestlogPill>
<ThemedText type="subtitle">{task.title}</ThemedText>
</QuestlogCard>- Arquivo:
src/components/questlog-card.tsx - Funcao: botao padronizado do app.
- Props principais:
children: texto do botao;variant:primary,secondary,dangeroughost;- props de
Pressable, comoonPressedisabled.
- Onde e usado: login, dashboard, listagem, criacao, detalhes e perfil.
- Importancia: garante botoes com area de toque adequada, contraste e estados visuais consistentes.
- Exemplos reais:
Em src/app/login.tsx, o botao principal executa login ou cadastro:
<QuestlogAction disabled={isLoading} onPress={handleAuth}>
{isLoading ? 'Carregando...' : isRegister ? 'Criar conta' : 'Entrar'}
</QuestlogAction>Em src/app/profile.tsx, a variante secundaria e usada para logout:
<QuestlogAction
disabled={isSigningOut}
onPress={handleLogout}
variant="secondary">
{isSigningOut ? 'Saindo...' : 'Sair da conta'}
</QuestlogAction>- Arquivo:
src/components/questlog-card.tsx - Funcao: etiqueta visual compacta usada para status, XP e informacoes curtas.
- Props principais:
children;tone:neutral,accent,success,warning,danger,infooumuted.
- Onde e usado: cards, perfil, status de tasks, loading e resumo.
- Importancia: facilita a leitura visual de status e informacoes importantes.
- Exemplos reais:
Em src/app/quest-details/[id].tsx, a pill mostra o status selecionado:
<QuestlogPill tone={taskStatusMetadata[status].tone}>
{statusLabel}
</QuestlogPill>Em src/app/profile.tsx, a pill mostra XP:
<QuestlogPill tone="success">
{isLoadingProfile ? 'Carregando runas' : `${profile.xpTotal} XP`}
</QuestlogPill>- Arquivo:
src/components/questlog-card.tsx - Funcao: exibe mensagens de erro, sucesso ou informacao.
- Props principais:
children;tone:info,success,warningoudanger.
- Onde e usado: login, criacao, detalhes, perfil, dashboard e listagem.
- Importancia: melhora a experiencia ao indicar estados de erro, carregamento ou sucesso.
- Exemplo real em
src/app/quests.tsx:
{errorMessage ? (
<QuestlogFeedback tone="danger">{errorMessage}</QuestlogFeedback>
) : null}- Arquivo:
src/components/questlog-card.tsx - Funcao: padroniza campos de formulario com label e hint.
- Props principais:
label;hint;children.
- Onde e usado: login, create-quest e quest-details.
- Importancia: reduz duplicacao de layout nos formularios.
- Exemplo real em
src/app/login.tsx:
<QuestlogField label="E-mail">
<QuestlogTextInput
autoCapitalize="none"
keyboardType="email-address"
onChangeText={setEmail}
placeholder="voce@email.com"
value={email}
/>
</QuestlogField>- Arquivo:
src/components/questlog-card.tsx - Funcao: input de texto padronizado.
- Props principais: recebe props de
TextInput. - Onde e usado: login, create-quest e quest-details.
- Importancia: padroniza fundo, borda, cor, espacamento e placeholder.
- Exemplo real em
src/app/quest-details/[id].tsx:
<QuestlogTextInput
editable={!isSaving}
multiline
onChangeText={setDescription}
placeholder="Notas do contrato"
textAlignVertical="top"
value={description}
/>- Arquivo:
src/components/questlog-card.tsx - Funcao: mostra um dado estatistico com label, valor e hint opcional.
- Onde e usado: dashboard e profile.
- Importancia: organiza informacoes numericas como XP, nivel e tarefas concluidas.
- Exemplo real em
src/app/dashboard.tsx:
<QuestlogStat
label="XP total"
value={`${profile.xpTotal}`}
hint={`Nível ${profile.level}`}
/>- Arquivo:
src/components/questlog-card.tsx - Funcao: barra de progresso percentual.
- Onde e usado: dashboard e profile.
- Importancia: representa visualmente o progresso ate o proximo nivel.
- Exemplo real em
src/app/profile.tsx:
<QuestlogProgress percentage={levelInfo.progressPercentage} />- Arquivo:
src/components/questlog-option.tsx - Funcao: botoes selecionaveis para formularios.
- Onde e usado: create-quest e quest-details.
- Importancia: padroniza selecao de dificuldade e status.
- Exemplo real em
src/app/create-quest.tsx, para selecionar dificuldade:
<QuestlogOptionGrid>
{taskDifficulties.map((difficultyOption) => (
<QuestlogOption
disabled={isLoading}
isSelected={difficulty === difficultyOption}
key={difficultyOption}
label={`${taskDifficultyMetadata[difficultyOption].label} · ${taskDifficultyMetadata[difficultyOption].xpReward} XP`}
onPress={() => setDifficulty(difficultyOption)}
/>
))}
</QuestlogOptionGrid>- Arquivo:
src/components/themed-text.tsx - Funcao: componente de texto com estilos tipograficos.
- Props principais:
type:default,title,small,smallBold,subtitle,link,linkPrimaryoucode;themeColor: cor do tema.
- Onde e usado: praticamente todas as telas e componentes visuais.
- Importancia: padroniza tipografia e cores.
- Exemplo real em
src/app/profile.tsx:
<ThemedText type="smallBold" themeColor="accentSoft">
{currentUser?.email || 'E-mail não encontrado'}
</ThemedText>- Arquivos:
src/components/app-tabs.tsxesrc/components/app-tabs.web.tsx - Funcao: navegacao principal entre Painel, Missoes e Perfil.
- Onde e usado: dashboard, quests e profile.
- Importancia: facilita a navegacao entre as principais secoes do app.
- Exemplo real de definicao de abas em
src/components/app-tabs.tsx:
const tabs = [
{ href: '/dashboard', label: tabLabels.dashboard },
{ href: '/quests', label: tabLabels.quests },
{ href: '/profile', label: tabLabels.profile },
] as const;| Componente | Exemplos de uso no projeto | Papel na interface |
|---|---|---|
QuestlogScreen |
login.tsx, dashboard.tsx, quests.tsx, profile.tsx |
Estrutura padrao de tela |
QuestlogCard |
cards de quest, ficha de perfil, dashboard, formularios | Agrupar conteudo visual |
QuestlogAction |
login, criar missao, inspecionar contrato, logout | Acao clicavel padronizada |
QuestlogPill |
status de task, XP, nivel, loading | Etiqueta visual compacta |
QuestlogFeedback |
erro de login, erro de listagem, sucesso ao salvar | Mensagens para usuario |
QuestlogField |
campos de login, criacao e edicao | Padronizar formularios |
QuestlogOption |
selecao de status e dificuldade | Escolhas em formulario |
QuestlogStat |
dashboard e perfil | Exibir numeros importantes |
QuestlogProgress |
dashboard e perfil | Mostrar progresso de nivel |
ThemedView: view tematica.ExternalLink: link externo.HintRow: linha com titulo e dica.Collapsible: secao colapsavel.AnimatedIcon: componente visual animado.WebBadge: badge para ambiente web.
Nem todos esses componentes aparecem nas telas principais atuais, mas estao disponiveis no projeto.
Definidos em src/constants/task.ts:
todo: A fazer.inProgress: Em andamento.onHold: Em pausa.awaitConclusion: Aguardando conclusao.done: Concluida.
Na criacao de tasks, os status iniciais permitidos sao:
todoinProgressonHoldawaitConclusion
O status done e usado para conclusao da task.
Definidas em src/constants/task.ts:
easy: Facil.medium: Media.hard: Dificil.epic: Epica.
Tambem definido em src/constants/task.ts:
| Dificuldade | XP |
|---|---|
| easy | 10 |
| medium | 25 |
| hard | 50 |
| epic | 100 |
A funcao getTaskXpReward retorna a recompensa de XP de acordo com a dificuldade.
Os objetos taskStatusMetadata e taskDifficultyMetadata definem labels e tons visuais para status e dificuldades. Isso permite que o app mostre pills coloridas de forma padronizada.
Definidas em src/constants/profile.ts:
| Nivel | XP minimo | Titulo |
|---|---|---|
| 1 | 0 | Novato da Guilda |
| 2 | 100 | Aprendiz de Aventureiro |
| 3 | 250 | Cacador de Bugs |
| 4 | 500 | Mestre das Quests |
| 5 | 1000 | Lendario Dev Supremo |
A funcao calculateUserLevel calcula:
- nivel atual;
- titulo atual;
- XP inicial do nivel atual;
- XP necessario para o proximo nivel;
- porcentagem de progresso.
A funcao createProgressProfile cria uma estrutura normalizada de perfil com:
xpTotal;tasksCompleted;level;title.
Definidos em src/constants/theme.ts:
Colors: paleta light e dark.Spacing: escala de espacamento.Radius: raios de borda.Fonts: configuracao de fontes por plataforma.MaxContentWidth: largura maxima do conteudo.BottomTabInset: ajuste de espacamento por plataforma.
- Funcao: valida se uma variavel de ambiente obrigatoria existe.
- Parametros:
name: nome da variavel;value: valor lido.
- Retorno: string validada.
- Firebase: nao le nem escreve no banco; apenas valida configuracao.
O arquivo inicializa o Firebase com initializeApp(firebaseConfig) e exporta:
auth: instancia de Firebase Auth.db: instancia de Firestore.realtimeDb: instancia de Realtime Database.
Observacao: o projeto exporta db de Firestore, mas as funcionalidades implementadas de tasks e perfil usam Realtime Database.
- Funcao: cria uma nova task para o usuario logado.
- Parametros:
ownerId;title;description;difficulty;status.
- Retorno:
PersistedTask. - Firebase: escreve em
users/{ownerId}/tasks/{taskId}. - Regras:
- valida
ownerId; - valida usuario autenticado;
- valida titulo;
- calcula
xpReward; - define
createdAteupdatedAt.
- valida
- Exemplo real de chamada em
src/app/create-quest.tsx:
await createUserTask({
ownerId,
title: trimmedTitle,
description,
difficulty,
status,
});- Funcao: busca uma task especifica pelo id.
- Parametros:
ownerId;taskId.
- Retorno:
PersistedTask | null. - Firebase: le
users/{ownerId}/tasks/{taskId}. - Regras:
- valida dono autenticado;
- verifica se
ownerIdda task corresponde ao usuario.
- Exemplo real de chamada em
src/app/quest-details/[id].tsx:
const nextTask = await getUserTask(ownerId, taskId);Essa chamada carrega os dados da task para preencher o formulario de edicao.
- Funcao: atualiza dados de uma task.
- Parametros:
ownerId;taskId;inputcom titulo, descricao, dificuldade e/ou status.
- Retorno:
PersistedTask. - Firebase: escreve por transacao no no
users/{ownerId}. - Regras:
- valida dono;
- recalcula
xpRewardse a dificuldade mudar; - atualiza
updatedAt; - pode acionar XP se o status mudar para
done.
- Exemplo real de chamada em
src/app/quest-details/[id].tsx:
const updatedTask = await updateUserTask(ownerId, taskId, {
title: trimmedTitle,
description,
difficulty,
status,
});Essa funcao e usada quando o usuario toca em Salvar alteracoes.
- Funcao: altera apenas o status de uma task.
- Parametros:
ownerId;taskId;status.
- Retorno:
PersistedTask. - Firebase: escreve por transacao em
users/{ownerId}. - Regras:
- se o status for
done, pode preenchercompletedAte aplicar XP.
- se o status for
- Exemplo real de chamada em
src/app/quest-details/[id].tsx:
const updatedTask = await changeUserTaskStatus(ownerId, taskId, 'done');Essa chamada e usada pela acao rapida Marcar como concluida.
- Funcao: assina a lista de tasks do usuario em tempo real.
- Parametros:
ownerId;- callback
onTasks; - callback
onError.
- Retorno: funcao de unsubscribe.
- Firebase: le
users/{ownerId}/tasks. - Regras:
- transforma snapshot em array;
- filtra objetos validos;
- ordena por
createdAtem ordem decrescente.
- Exemplos reais de uso:
Em src/app/quests.tsx, a funcao alimenta a lista de missoes:
return subscribeUserTasks(
currentUser.uid,
(nextTasks) => {
setTasks(nextTasks);
setIsLoading(false);
},
() => {
setErrorMessage('Não foi possível carregar suas missões.');
setIsLoading(false);
},
);Em src/app/dashboard.tsx, a mesma funcao e reutilizada para calcular resumo de missoes ativas e concluidas.
- Funcao interna usada por
updateUserTaskechangeUserTaskStatus. - Firebase: executa
runTransactionemusers/{ownerId}. - Importancia:
- atualiza task e perfil dentro da mesma transacao;
- evita duplicidade de XP;
- marca
xpClaimed: trueao aplicar XP.
- Trecho principal da regra de XP em
src/services/tasks.ts:
const shouldClaimXp = nextStatus === 'done' && currentTask.xpClaimed !== true;
if (shouldClaimXp) {
const nextProfile = createProgressProfile(
currentProfile.xpTotal + nextTask.xpReward,
currentProfile.tasksCompleted + 1,
);
nextTask.xpClaimed = true;
userData.profile = {
...userData.profile,
...nextProfile,
};
}Esse trecho demonstra a principal regra de negocio do app: somar XP apenas na primeira conclusao da task.
- Funcao: assina o perfil do usuario em tempo real.
- Parametros:
ownerId;- callback
onProfile; - callback
onError.
- Retorno: funcao de unsubscribe.
- Firebase: le
users/{ownerId}/profile. - Regras:
- se o perfil nao existir, retorna perfil padrao com 0 XP.
- Exemplos reais de uso:
Em src/app/profile.tsx, a funcao alimenta a tela de perfil:
return subscribeUserProfile(
currentUser.uid,
(nextProfile) => {
setProfile(nextProfile);
setIsLoadingProfile(false);
},
() => {
setErrorMessage('Não foi possível carregar sua ficha de progresso.');
setIsLoadingProfile(false);
},
);Em src/app/dashboard.tsx, a mesma funcao e reutilizada para exibir XP, nivel e barra de progresso no painel.
| Funcao | Arquivo | Exemplo de tela que usa | Le Firebase | Escreve Firebase |
|---|---|---|---|---|
createUserTask |
src/services/tasks.ts |
src/app/create-quest.tsx |
Nao | Sim |
subscribeUserTasks |
src/services/tasks.ts |
src/app/quests.tsx, src/app/dashboard.tsx |
Sim | Nao |
getUserTask |
src/services/tasks.ts |
src/app/quest-details/[id].tsx |
Sim | Nao |
updateUserTask |
src/services/tasks.ts |
src/app/quest-details/[id].tsx |
Sim, via transacao | Sim |
changeUserTaskStatus |
src/services/tasks.ts |
src/app/quest-details/[id].tsx |
Sim, via transacao | Sim |
subscribeUserProfile |
src/services/profile.ts |
src/app/profile.tsx, src/app/dashboard.tsx |
Sim | Nao |
calculateUserLevel |
src/constants/profile.ts |
src/app/profile.tsx, src/app/dashboard.tsx |
Nao | Nao |
createProgressProfile |
src/constants/profile.ts |
src/services/tasks.ts, src/services/profile.ts |
Nao | Nao |
O Firebase e inicializado em:
src/services/firebase.ts
O arquivo importa:
initializeAppdefirebase/app;getAuthdefirebase/auth;getDatabasedefirebase/database;getFirestoredefirebase/firestore.
O app usa as seguintes variaveis:
EXPO_PUBLIC_FIREBASE_API_KEYEXPO_PUBLIC_FIREBASE_AUTH_DOMAINEXPO_PUBLIC_FIREBASE_PROJECT_IDEXPO_PUBLIC_FIREBASE_STORAGE_BUCKETEXPO_PUBLIC_FIREBASE_MESSAGING_SENDER_IDEXPO_PUBLIC_FIREBASE_APP_IDEXPO_PUBLIC_FIREBASE_DATABASE_URLEXPO_PUBLIC_FIREBASE_MEASUREMENT_ID
Valores reais nao devem ser expostos na documentacao.
Firebase Auth e usado principalmente em src/app/login.tsx e nas telas protegidas.
No login:
- cadastro com
createUserWithEmailAndPassword; - login com
signInWithEmailAndPassword; - atualizacao de nome com
updateProfile.
Nas telas protegidas:
onAuthStateChangedverifica se existe usuario logado;- se nao houver usuario, o app redireciona para
/login.
No perfil:
- logout com
signOut.
O Realtime Database e usado nos servicos tasks.ts e profile.ts.
Nos de banco usados:
users/{uid}/tasks
users/{uid}/tasks/{taskId}
users/{uid}/profile
Cada task possui o campo:
ownerId
Esse campo recebe o uid do usuario autenticado. As funcoes de servico verificam se o usuario atual (auth.currentUser?.uid) corresponde ao ownerId usado na operacao.
Isso evita que um usuario atualize tasks de outro usuario.
Uma task salva pode conter:
id
ownerId
title
description
difficulty
status
xpReward
createdAt
updatedAt
completedAt
xpClaimed
O perfil do usuario e salvo em:
users/{uid}/profile
Campos usados:
xpTotal
tasksCompleted
level
title
Quando uma task muda para done, a funcao de transacao:
- verifica se
xpClaimedainda nao etrue; - soma
xpRewardaoxpTotal; - incrementa
tasksCompleted; - recalcula
leveletitle; - marca a task com
xpClaimed: true.
Se a task sair de done e voltar para done, o XP nao e somado novamente.
- O usuario acessa
/login. - Pode alternar entre login e cadastro.
- No cadastro, informa nome, e-mail e senha.
- O app cria conta com Firebase Auth.
- O nome e salvo no perfil do Auth com
updateProfile. - No login, o app autentica com e-mail e senha.
- Apos sucesso, o usuario e redirecionado para
/quests. - As demais telas usam
onAuthStateChangedpara validar sessao.
- O usuario acessa
/create-quest. - Informa titulo.
- Pode informar descricao.
- Escolhe dificuldade.
- Escolhe status inicial.
- O app valida titulo e usuario logado.
createUserTaskcria uma nova task emusers/{uid}/tasks.- O app redireciona para
/quests.
- O usuario acessa
/quests. - A tela verifica usuario logado.
subscribeUserTasksassinausers/{uid}/tasks.- As tasks sao agrupadas por status.
- O usuario pode abrir o detalhe de cada task.
- O usuario acessa
/quest-details/{id}. - A tela busca a task com
getUserTask. - O usuario edita titulo, descricao, dificuldade ou status.
- Ao salvar,
updateUserTaskexecuta uma transacao. - O app atualiza a task no Realtime Database.
- Tambem existe uma acao rapida para marcar como concluida.
- O status da task muda para
done. - O servico verifica se
xpClaimednao etrue. - O XP da dificuldade e somado ao perfil.
tasksCompletede incrementado.- Nivel e titulo sao recalculados.
- A task recebe
xpClaimed: true. - Se a task for concluida novamente, o XP nao e duplicado.
Sim. O app possui mais de 5 rotas/telas:
/login/dashboard/quests/create-quest/quest-details/:id/profile/
Sim. O app usa Firebase Realtime Database.
Firebase Realtime Database.
Sim:
/dashboard: le tasks e perfil./quests: le tasks./quest-details/:id: le uma task./profile: le perfil.
Sim:
/create-quest: cria task./quest-details/:id: atualiza task, status e pode atualizar XP/perfil.
Sim. O app usa Firebase Auth com e-mail e senha.
Sim. O app usa React Native/Expo, roda em dispositivos moveis e usa componentes nativos como inputs, botoes pressionaveis, scroll e navegacao. Tambem possui configuracao Expo para Android/iOS, icones, splash screen e orientation portrait.
Sim. O app usa Expo Router e navega entre telas como login, dashboard, quests, criacao, detalhes e perfil.
O dark mode foi escolhido para combinar com a ideia de fantasia, sci-fi e guilda de missoes. Ele cria uma aparencia mais imersiva e confortavel para uso prolongado, principalmente em ambientes com pouca luz.
O tema aparece na linguagem e nos elementos visuais:
- "missoes";
- "guilda";
- "contratos";
- "a aventureiro";
- XP;
- niveis;
- titulos;
- recompensas.
Cards ajudam a separar blocos de informacao:
- formularios;
- dados de perfil;
- quests;
- estados vazios;
- resumo do dashboard.
Isso melhora a leitura e torna a interface mais organizada.
Status e dificuldade sao exibidos com labels e pills. Isso facilita entender rapidamente em que etapa uma quest esta e qual recompensa ela oferece.
O app possui feedbacks visuais para:
- carregamento de missoes;
- erro de autenticacao;
- erro ao carregar dados;
- sucesso ao salvar;
- estado vazio.
Esses feedbacks ajudam o usuario a entender o que esta acontecendo.
Componentes reutilizaveis como QuestlogScreen, QuestlogCard, QuestlogAction, QuestlogPill, QuestlogFeedback e ThemedText evitam estilos duplicados e deixam a interface mais consistente.
As seguintes melhorias nao estao implementadas atualmente, mas poderiam ser adicionadas:
- Loja de XP.
- Recompensas cosmeticas.
- Filtros manuais por status.
- Busca de tasks.
- Notificacoes locais.
- Ranking.
- Estatisticas mais avancadas.
- Modo offline.
- Testes automatizados.
- Exclusao de tasks.
- Edicao do perfil do usuario.
- Avatar ou icone de personagem.
- Historico de XP.
- Conquistas/badges.
O Questlog e um projeto mobile que une gerenciamento de tarefas com gamificacao. Ele demonstra conceitos importantes da disciplina de Dispositivos Moveis, como:
- construcao de interfaces com React Native;
- uso do Expo para desenvolvimento mobile;
- roteamento com Expo Router;
- autenticacao com Firebase Auth;
- leitura e escrita em banco de dados com Firebase Realtime Database;
- organizacao do codigo em componentes, constantes e servicos;
- uso de TypeScript para tipagem;
- controle de estado com React Hooks;
- feedback visual para loading, erro e sucesso;
- regras de negocio envolvendo status, XP, nivel e perfil.
O projeto tambem mostra como associar dados ao usuario autenticado usando uid e ownerId, garantindo que cada usuario veja e edite apenas suas proprias quests. A atualizacao de XP usa transacao no Realtime Database para evitar duplicidade, o que e uma decisao importante para manter a consistencia dos dados.
Em resumo, o app atende ao objetivo de ser uma aplicacao mobile funcional, com navegacao, autenticacao, banco de dados, CRUD parcial de tarefas, progresso do usuario e uma identidade visual propria.