Skip to content

Repository files navigation

Documentacao do Projeto Questlog

1. Visao geral do projeto

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.

2. Tecnologias utilizadas

React Native

React Native e a base do aplicativo mobile. Ele permite criar interfaces nativas usando componentes React, como View, Text, Pressable, TextInput e ScrollView.

Expo

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

Expo Router e usado para navegacao baseada em arquivos. As rotas do app sao definidas dentro de src/app, por exemplo:

  • src/app/login.tsx gera a rota /login.
  • src/app/quests.tsx gera a rota /quests.
  • src/app/quest-details/[id].tsx gera uma rota dinamica.

O arquivo principal de layout e src/app/_layout.tsx, que configura o Stack de navegacao.

TypeScript

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 Auth

Firebase Authentication e usado para cadastro, login, controle de sessao e logout. O app utiliza e-mail e senha, com funcoes como:

  • createUserWithEmailAndPassword
  • signInWithEmailAndPassword
  • updateProfile
  • onAuthStateChanged
  • signOut

Firebase Realtime Database

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

Outras bibliotecas importantes

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-reanimated e react-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, eslint e eslint-config-expo: tipagem e validacao do codigo.

3. Estrutura de pastas

src/app

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.

src/components

Contem componentes reutilizaveis de interface. Essa pasta concentra os elementos visuais usados em varias telas, como cards, botoes, pills, inputs, textos tematicos e tabs.

src/constants

Guarda constantes e regras compartilhadas, como:

  • status de tarefas;
  • dificuldades;
  • XP por dificuldade;
  • metadados visuais;
  • cores;
  • espacamentos;
  • regras de nivel e titulo do perfil.

src/hooks

Contem hooks relacionados ao tema e esquema de cores:

  • use-color-scheme.ts
  • use-color-scheme.web.ts
  • use-theme.ts

Esses hooks ajudam a obter o tema atual do app.

src/services

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.

assets

Contem imagens e icones usados pelo Expo, como icone do app, splash screen e imagens de icone Android.

scripts

Contem scripts auxiliares do projeto, como reset-project.js.

Arquivos de configuracao

  • 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 usando expo/metro-config.
  • eas.json: perfis de build EAS.

4. Paginas/telas do app

src/app/_layout.tsx

  • 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] e login;
    • configura estilo da barra de navegacao e status bar.

src/app/index.tsx

  • 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" />.

src/app/login.tsx

  • 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 /quests apos sucesso;
    • exibir mensagens de erro.

src/app/dashboard.tsx

  • 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.

src/app/quests.tsx

  • 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}.

src/app/create-quest.tsx

  • 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.

src/app/quest-details/[id].tsx

  • 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.

src/app/profile.tsx

  • 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.

5. Componentes reutilizaveis

QuestlogScreen

  • 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>

QuestlogCard

  • Arquivo: src/components/questlog-card.tsx
  • Funcao: cria blocos visuais para agrupar informacoes.
  • Props principais: recebe props de View, incluindo style e children.
  • 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>

QuestlogAction

  • Arquivo: src/components/questlog-card.tsx
  • Funcao: botao padronizado do app.
  • Props principais:
    • children: texto do botao;
    • variant: primary, secondary, danger ou ghost;
    • props de Pressable, como onPress e disabled.
  • 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>

QuestlogPill

  • 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, info ou muted.
  • 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>

QuestlogFeedback

  • Arquivo: src/components/questlog-card.tsx
  • Funcao: exibe mensagens de erro, sucesso ou informacao.
  • Props principais:
    • children;
    • tone: info, success, warning ou danger.
  • 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}

QuestlogField

  • 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>

QuestlogTextInput

  • 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}
/>

QuestlogStat

  • 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}`}
/>

QuestlogProgress

  • 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} />

QuestlogOption e QuestlogOptionGrid

  • 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>

ThemedText

  • Arquivo: src/components/themed-text.tsx
  • Funcao: componente de texto com estilos tipograficos.
  • Props principais:
    • type: default, title, small, smallBold, subtitle, link, linkPrimary ou code;
    • 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>

AppTabs

  • Arquivos: src/components/app-tabs.tsx e src/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;

Exemplos resumidos de componentes realmente reutilizados

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

Outros componentes

  • 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.

6. Constantes e regras de negocio

Status possiveis das tasks

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:

  • todo
  • inProgress
  • onHold
  • awaitConclusion

O status done e usado para conclusao da task.

Dificuldades possiveis

Definidas em src/constants/task.ts:

  • easy: Facil.
  • medium: Media.
  • hard: Dificil.
  • epic: Epica.

XP por dificuldade

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.

Metadados visuais

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.

Regras de nivel e titulo

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.

Tema, cores e espacamento

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.

7. Servicos e funcoes importantes

src/services/firebase.ts

requireEnv

  • 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.

Inicializacao do Firebase

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.

src/services/tasks.ts

createUserTask

  • 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 createdAt e updatedAt.
  • Exemplo real de chamada em src/app/create-quest.tsx:
await createUserTask({
  ownerId,
  title: trimmedTitle,
  description,
  difficulty,
  status,
});

getUserTask

  • 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 ownerId da 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.

updateUserTask

  • Funcao: atualiza dados de uma task.
  • Parametros:
    • ownerId;
    • taskId;
    • input com titulo, descricao, dificuldade e/ou status.
  • Retorno: PersistedTask.
  • Firebase: escreve por transacao no no users/{ownerId}.
  • Regras:
    • valida dono;
    • recalcula xpReward se 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.

changeUserTaskStatus

  • 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 preencher completedAt e aplicar XP.
  • 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.

subscribeUserTasks

  • 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 createdAt em 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.

mutateUserTask

  • Funcao interna usada por updateUserTask e changeUserTaskStatus.
  • Firebase: executa runTransaction em users/{ownerId}.
  • Importancia:
    • atualiza task e perfil dentro da mesma transacao;
    • evita duplicidade de XP;
    • marca xpClaimed: true ao 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.

src/services/profile.ts

subscribeUserProfile

  • 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.

Exemplos resumidos de funcoes principais

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

8. Conexao com o Firebase

Inicializacao

O Firebase e inicializado em:

src/services/firebase.ts

O arquivo importa:

  • initializeApp de firebase/app;
  • getAuth de firebase/auth;
  • getDatabase de firebase/database;
  • getFirestore de firebase/firestore.

Variaveis de ambiente usadas

O app usa as seguintes variaveis:

  • EXPO_PUBLIC_FIREBASE_API_KEY
  • EXPO_PUBLIC_FIREBASE_AUTH_DOMAIN
  • EXPO_PUBLIC_FIREBASE_PROJECT_ID
  • EXPO_PUBLIC_FIREBASE_STORAGE_BUCKET
  • EXPO_PUBLIC_FIREBASE_MESSAGING_SENDER_ID
  • EXPO_PUBLIC_FIREBASE_APP_ID
  • EXPO_PUBLIC_FIREBASE_DATABASE_URL
  • EXPO_PUBLIC_FIREBASE_MEASUREMENT_ID

Valores reais nao devem ser expostos na documentacao.

Uso do Firebase Auth

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:

  • onAuthStateChanged verifica se existe usuario logado;
  • se nao houver usuario, o app redireciona para /login.

No perfil:

  • logout com signOut.

Uso do Realtime Database

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

Associacao de tasks ao usuario

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.

Estrutura de task persistida

Uma task salva pode conter:

id
ownerId
title
description
difficulty
status
xpReward
createdAt
updatedAt
completedAt
xpClaimed

Estrutura de perfil

O perfil do usuario e salvo em:

users/{uid}/profile

Campos usados:

xpTotal
tasksCompleted
level
title

Atualizacao de XP

Quando uma task muda para done, a funcao de transacao:

  1. verifica se xpClaimed ainda nao e true;
  2. soma xpReward ao xpTotal;
  3. incrementa tasksCompleted;
  4. recalcula level e title;
  5. marca a task com xpClaimed: true.

Se a task sair de done e voltar para done, o XP nao e somado novamente.

9. Fluxo principal do app

Cadastro/login

  1. O usuario acessa /login.
  2. Pode alternar entre login e cadastro.
  3. No cadastro, informa nome, e-mail e senha.
  4. O app cria conta com Firebase Auth.
  5. O nome e salvo no perfil do Auth com updateProfile.
  6. No login, o app autentica com e-mail e senha.
  7. Apos sucesso, o usuario e redirecionado para /quests.
  8. As demais telas usam onAuthStateChanged para validar sessao.

Criacao de quest

  1. O usuario acessa /create-quest.
  2. Informa titulo.
  3. Pode informar descricao.
  4. Escolhe dificuldade.
  5. Escolhe status inicial.
  6. O app valida titulo e usuario logado.
  7. createUserTask cria uma nova task em users/{uid}/tasks.
  8. O app redireciona para /quests.

Listagem de quests

  1. O usuario acessa /quests.
  2. A tela verifica usuario logado.
  3. subscribeUserTasks assina users/{uid}/tasks.
  4. As tasks sao agrupadas por status.
  5. O usuario pode abrir o detalhe de cada task.

Edicao e mudanca de status

  1. O usuario acessa /quest-details/{id}.
  2. A tela busca a task com getUserTask.
  3. O usuario edita titulo, descricao, dificuldade ou status.
  4. Ao salvar, updateUserTask executa uma transacao.
  5. O app atualiza a task no Realtime Database.
  6. Tambem existe uma acao rapida para marcar como concluida.

Conclusao e XP

  1. O status da task muda para done.
  2. O servico verifica se xpClaimed nao e true.
  3. O XP da dificuldade e somado ao perfil.
  4. tasksCompleted e incrementado.
  5. Nivel e titulo sao recalculados.
  6. A task recebe xpClaimed: true.
  7. Se a task for concluida novamente, o XP nao e duplicado.

10. Requisitos da disciplina

Possui no minimo 5 paginas?

Sim. O app possui mais de 5 rotas/telas:

  • /login
  • /dashboard
  • /quests
  • /create-quest
  • /quest-details/:id
  • /profile
  • /

Possui conexao com banco de dados?

Sim. O app usa Firebase Realtime Database.

Qual banco?

Firebase Realtime Database.

Existe tela que le dados do banco?

Sim:

  • /dashboard: le tasks e perfil.
  • /quests: le tasks.
  • /quest-details/:id: le uma task.
  • /profile: le perfil.

Existe tela que escreve dados no banco?

Sim:

  • /create-quest: cria task.
  • /quest-details/:id: atualiza task, status e pode atualizar XP/perfil.

Possui autenticacao?

Sim. O app usa Firebase Auth com e-mail e senha.

Usa recursos de app mobile?

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.

Usa navegacao entre telas?

Sim. O app usa Expo Router e navega entre telas como login, dashboard, quests, criacao, detalhes e perfil.

11. Decisoes de UX/UI

Tema dark mode

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.

Tema geek/RPG

O tema aparece na linguagem e nos elementos visuais:

  • "missoes";
  • "guilda";
  • "contratos";
  • "a aventureiro";
  • XP;
  • niveis;
  • titulos;
  • recompensas.

Uso de cards

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, dificuldade e XP

Status e dificuldade sao exibidos com labels e pills. Isso facilita entender rapidamente em que etapa uma quest esta e qual recompensa ela oferece.

Feedbacks de erro/loading/sucesso

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.

Consistencia visual

Componentes reutilizaveis como QuestlogScreen, QuestlogCard, QuestlogAction, QuestlogPill, QuestlogFeedback e ThemedText evitam estilos duplicados e deixam a interface mais consistente.

12. Possiveis melhorias futuras

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.

13. Resumo tecnico final

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.

Releases

Packages

Contributors

Languages