TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
Gerencie hábitos e metas com um dashboard gamificado que rastreia progresso e recompensa consistência
Translation pending
AI summary · website and README
ProductivityHTML · JavaScriptGitHub @joaossrOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
NIVORA — Seu progresso, todo dia. App de hábitos com dashboard gamificado (níveis, XP, streaks, missões, loja e conquistas), autenticação real via Supabase e dados por usuário. O projeto usa Vite apenas como servidor de desenvolvimento (hot reload). Não há build de verdade além de empacotar os dois HTMLs. Copie .env.example para .env e preencha com as credenciais do seu projeto Supabase (URL e chave publishable, ambas públicas por natureza): Também dá para abrir os arquivos direto no navegador, sem servidor:Read the full README ↗
App de hábitos com dashboard gamificado (níveis, XP, streaks, missões, loja e conquistas), autenticação real via Supabase e dados por usuário.
Produção: https://nivora-app-coral.vercel.app
.
├── index.html # Dashboard completo (Hoje, Hábitos, Metas, Calendário,
│ # Estatísticas, Relatórios, Conquistas, Missões, Loja,
│ # Configurações)
├── login.html # Tela de login
└── README.md
O projeto usa Vite apenas como servidor de desenvolvimento (hot reload). Não há build de verdade além de empacotar os dois HTMLs.
npm install
npm run dev
# depois acesse http://localhost:5173/login.html
Copie .env.example para .env e preencha com as credenciais do seu projeto
Supabase (URL e chave publishable, ambas públicas por natureza):
cp .env.example .env
Outros comandos:
npm run build # gera a pasta dist/ com os arquivos otimizados
npm run preview # serve a pasta dist/ localmente, para conferir o build
Também dá para abrir os arquivos direto no navegador, sem servidor:
open index.html # macOS
xdg-open index.html # Linux
O projeto está hospedado na Vercel e conectado ao repositório do GitHub
(joaossr/Nivora) — todo push para main gera um deploy automático em
produção. As variáveis NEXT_PUBLIC_SUPABASE_URL e
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY já estão configuradas direto no
projeto da Vercel (Production, Preview e Development).
Para fazer um deploy manual (sem precisar de push):
npx vercel --prod
Produção: https://nivora-app-coral.vercel.app
login.html faz login, cadastro
(e-mail/senha), recuperação de senha (link por e-mail) e login com Google
(supabase.auth.signInWithOAuth). index.html exige sessão — sem login,
redireciona para login.html — e o botão Sair encerra a sessão de
verdade (supabase.auth.signOut()).user_id (RLS restrita ao
dono da linha). Cada pessoa só vê e edita os próprios dados.habit_logs): cada conclusão vira uma
linha com a data. Streak atual, melhor streak e taxa de conclusão de cada
hábito são calculados a partir desse histórico, não de contadores fixos.incremento
— por padrão 1, mas pode ser qualquer número, útil pra metas em dinheiro
onde cada conclusão vale, por exemplo, R$50). Uma meta pode ter vários
hábitos vinculados; um hábito pode alimentar várias metas ao mesmo tempo.
O progresso da meta (atual, %, checkpoints, conclusão) é recalculado
automaticamente — do zero, a partir do histórico de conclusões — toda
vez que um hábito vinculado é marcado, desmarcado ou editado no
calendário, incluindo dias retroativos. Metas sem nenhum hábito vinculado
mantêm o último valor conhecido (o atual não é forçado a zero).dtkgomdoraxoyofsiywh).public.profiles: id (= auth.users.id), nome, avatar_url (do
Google), avatar_escolhido, avatares_desbloqueados (coluna legada, não
usada mais — os avatares deixaram de ser vendidos na Loja), total_xp,
coins, moedas_gastas. Criado automaticamente por um trigger
(handle_new_user) quando alguém se cadastra.public.habits: hábitos cadastrados (nome, categoria, emoji, xp).public.habit_logs: uma linha por (habit_id, data) — o histórico real
de conclusões, base de streaks, taxas, calendário, estatísticas e
relatórios.public.goals: metas do usuário (atual/alvo são numeric, aceitam
decimais para metas em dinheiro). concluida_em marca quando o alvo foi
atingido pela primeira vez.public.habit_goals: vínculo N:N entre habits e goals, com
incremento (quanto cada conclusão do hábito soma na meta).public.goal_checkpoints: marcos opcionais de uma meta (valor,
rotulo opcional em texto, atingido, atingido_em) — recalculados
junto com o progresso.public.mission_claims: uma linha por (mission_key, period_key)
resgatado — evita resgatar a mesma missão duas vezes no período.public.reward_redemptions: uma linha por resgate de item da Loja
(reward_key, period_key) — usada pra contar quantas vezes cada
recompensa foi usada dentro do período atual e aplicar o usageLimit.*_select_own, *_insert_own, etc.), com user_id default auth.uid().@supabase/ssr está instalado nas dependências (era um requisito do
pedido original), mas ainda não é usado — o app é 100% client-side e fala
com o Supabase direto pelo @supabase/supabase-js.Isso não dá para ser feito por código — precisa ser feito uma vez no painel do Supabase:
Login com Google: em Authentication → Sign In / Providers → Google,
habilite o provedor e informe um Client ID e Client Secret OAuth
criados no Google Cloud Console
(tipo "Web application", com a URI de callback que o próprio painel do
Supabase mostra nessa tela, algo como
https://dtkgomdoraxoyofsiywh.supabase.co/auth/v1/callback). Sem isso,
o botão "Entrar com Google" mostra um erro do Supabase dizendo que o
provedor não está habilitado.
URLs de redirecionamento (⚠️ pendente agora que o app está no ar): em Authentication → URL Configuration, adicione:
https://nivora-app-coral.vercel.apphttps://nivora-app-coral.vercel.app/* e
http://localhost:5173/* (para continuar testando localmente)Sem isso, o login com Google e o link de recuperação de senha redirecionam para o lugar errado (ou são bloqueados pelo Supabase) em produção.
(Opcional) Confirmação de e-mail: por padrão o Supabase exige que o usuário confirme o e-mail antes de logar. Para testar mais rápido em desenvolvimento, isso pode ser desativado em Authentication → Sign In / Providers → Email.
A Loja é uma economia de recompensa pessoal: as 23 recompensas estão
organizadas em 5 categorias (Sistema, Lazer, Guitarra e hobbies, Comida,
Compras pessoais), com preços de 60 a 1.000 moedas — de propósito, a maioria
fica acima de 200 moedas, pra recompensas maiores exigirem várias semanas de
acumulação. Cada item tem raridade (comum/raro/épico/lendário, com as
mesmas cores dos avatares) e um limite de uso modular:
usageLimit (quantas vezes) + usagePeriod ('week', 'month', 'once'
ou 'N_months', ex. '2_months'). Toda recompensa resgatada grava uma
linha em reward_redemptions (reward_key + period_key, esse último
calculado a partir do usagePeriod — ex. a segunda-feira da semana atual,
ou "2026-1m8" pra um item mensal em setembro/2026); ao atingir o limite no
período atual, o botão vira "🔒 Limite atingido" (ou "🔒 Já resgatado" nas
recompensas de compra única) mostrando a data em que libera de novo. Cada
item tem uma imagem própria (public/rewards/*.svg) que ocupa o card
inteiro. Adicionar uma recompensa nova é só empurrar um objeto no array
loja (nome, descrição, preço, categoria, raridade, usageLimit,
usagePeriod, imagem) — o motor de limites não muda. As recompensas "da
vida real" são simbólicas: resgatá-las só desconta moedas e conta para a
conquista "Primeira compra" — não há efeito automático no app (é o próprio
usuário que se recompensa depois). Moedas continuam vindo exclusivamente
do resgate de missões — hábitos nunca dão moeda diretamente, só XP.
usuário + data sempre gera o mesmo sorteio, sem
precisar guardar nada extra no banco) e evitando repetir o conjunto do
dia/semana anterior. Algumas missões são geradas a partir dos hábitos
reais do usuário (ex.: hábito "Estudar Python" vira "💻 Complete seu
hábito de Python hoje"), e outras só aparecem se o usuário tiver hábitos
numa certa categoria (Saúde/Estudos/Pessoal). Moedas só existem via
missão resgatada — completar um hábito nunca dá moeda diretamente, só
XP. Cada resgate grava uma linha em mission_claims (usada tanto para
não deixar resgatar duas vezes quanto para o cooldown de cada missão);
toda a lógica de seleção/rotação vive em index.html perto do banco de
missões, isolada do resto do app — adicionar uma missão nova é só
acrescentar um objeto num dos bancos (BANCO_DIARIAS, BANCO_SEMANAIS,
BANCO_DESAFIO, BANCO_SURPRESA ou MISSOES_DIA_ESPECIAL).login.html), em public/favicon.png e public/apple-touch-icon.png.