Aplicação web para registro e controle de horas trabalhadas. Permite cadastrar jornadas diárias com múltiplas sessões de trabalho, calcular o total de horas e visualizar pausas entre sessões.
Não possui backend — todos os dados são armazenados localmente no navegador via localStorage.
- Adicionar, editar e excluir registros diários de trabalho
- Suporte a múltiplas sessões por dia (ex: turno manhã + tarde)
- Detecção automática de sessões que cruzam a meia-noite (indicadas com 🌙)
- Cálculo de tempo de pausa entre sessões consecutivas
- Aviso de horas extras: destaca em vermelho entradas com mais de 10h/dia
- Validação de sessões: máximo de 16h por sessão, campos obrigatórios
- Total acumulado exibido em um card de resumo
- Alternância entre tema claro e escuro (persistida no
localStorage)
| Pacote | Função |
|---|---|
| React 19 + TypeScript | Interface e tipagem |
| Vite 8 | Build e servidor de desenvolvimento |
| Tailwind CSS v4 | Estilização utilitária |
| Radix UI | Primitivos acessíveis (Dialog, Tooltip, DropdownMenu) |
| shadcn/ui | Componentes sobre o Radix |
| lucide-react | Ícones |
| next-themes | Gerenciamento de tema claro/escuro |
src/
├── App.tsx # Componente raiz
├── components/
│ ├── entry-form/
│ │ ├── entry-form.tsx # Formulário para criar um novo registro
│ │ └── sessions-fields.tsx # Campos dinâmicos de sessões (entrada/saída)
│ ├── edit-entry-dialog.tsx # Modal de edição de registro existente
│ ├── entry-table.tsx # Tabela com todos os registros
│ ├── summary-card.tsx # Card com total de registros e horas acumuladas
│ ├── mode-toggle.tsx # Botão de alternância de tema
│ └── theme-provider.tsx # Provider de tema (next-themes)
├── hooks/
│ └── use-work-entries.ts # Hook central de estado (add, edit, delete)
├── lib/
│ ├── calculation.ts # Funções de cálculo de tempo
│ ├── storage.ts # Persistência via localStorage
│ └── utils.ts # Utilitários de className
└── types/
└── work-entry.ts # Tipos WorkEntry e WorkSession
type WorkSession = {
startTime: string; // "HH:MM"
endTime: string; // "HH:MM"
};
type WorkEntry = {
id: string;
date: string; // "YYYY-MM-DD"
sessions: WorkSession[];
notes?: string;
};Toda a aritmética de tempo é feita em minutos inteiros para evitar imprecisões de ponto flutuante.
| Função | Descrição |
|---|---|
timeToMinutes(time) |
Converte "HH:MM" em total de minutos |
minutesToHours(minutes) |
Converte minutos em string "HH:MM" |
calculateWorkedSessionMinutes(session) |
Calcula duração de uma sessão; trata virada de meia-noite |
calculateBreakMinutes(sessions) |
Soma os intervalos entre sessões consecutivas |
calculateWorkedMinutes(entry) |
Total trabalhado em um registro (soma das sessões) |
calculateTotalMinutes(entries) |
Total acumulado de todos os registros |
Os dados são armazenados na chave "work-entries" do localStorage. As funções loadEntries() e saveEntries(entries) em src/lib/storage.ts gerenciam a leitura e escrita. Qualquer mutação (adição, edição ou exclusão) persiste o array completo imediatamente.
# Instalar dependências
npm install
# Iniciar servidor de desenvolvimento
npm run dev
# Gerar build de produção
npm run build
# Visualizar build de produção localmente
npm run preview
# Executar lint
npm run lint