Interface responsiva, focada no uso em celulares. Pronto para Android/iOS via Capacitor.
- Login com JWT Bearer.
- Interceptor anexa o token e, em 401, redireciona para o login.
- (Opcional) tela de cadastro usando
POST /usuarios(público).
- Criar individualmente ou em lote (lista de viagens).
- Editar e excluir viagens salvas.
- Filtros por origem e destino.
- Listagem paginada (Spring Page).
- Simulação individual (
/calculos/frete) e em lote (/calculos/frete/lote). - Exibição de métricas:
- Distância considerada (ida/volta)
- Custo de combustível
- Gastos adicionais
- Valor do frete
- Valor líquido
- Ganho por km
- Recalcular viagem salva sem alterar o banco:
POST /trips/{id}/calcular.
- Por intervalo (início/fim).
- Mensal (por ano).
- Anual (faixa de anos).
- Cartões/tabelas responsivos para leitura rápida em mobile.
- Inputs numéricos com
inputmode="decimal"(teclado numérico). - Formatação BRL com 2 casas; ganho/km com 2 casas.
- (Opcional) tema escuro/visual minimalista.
| Tecnologia | Versão | Observações |
|---|---|---|
| Vue.js | 2.x | SPA |
| Vue Router | 3.x | Guards para rotas autenticadas |
| Vuex | 3.x (opcional) | Armazenar auth/token |
| Axios | latest | Interceptors (token/erros) |
| Capacitor | 3.x | Android/iOS (APK/App) |
| CSS3 | — | Flexbox/Grid, mobile-first |
- Node.js 16+
- npm ou yarn
- Backend rodando (veja base URL abaixo)
git clone https://github.com/seu-usuario/liqrota-frontend.git
cd liqrota-frontendnpm installCrie um .env na raiz:
VUE_APP_API_BASE_URL=http://localhost:8080# Dev
npm run serve
# Build (web)
npm run build
# Lint
npm run lint# adicionar plataformas (uma vez)
npx cap add android
npx cap add ios
# build + sync
npm run build
npx cap sync
# abrir IDEs
npx cap open android # Android Studio
npx cap open ios # XcodeSe preferir Cordova, adapte com
config.xmle scripts equivalentes.
Base: ${VUE_APP_API_BASE_URL}
Padrão de erro (sempre tratar):
{ "timestamp": "...", "status": 400, "path": "/endpoint", "erros": ["mensagem"] }| Método | Endpoint | Body | Observações |
|---|---|---|---|
POST |
/auth/login |
{ "username": "...", "senha": "..." } |
Guarda access_token, role, expires_in |
POST |
/usuarios |
{ "username": "...", "senha": "..." } |
Público; 201 sem corpo |
Nas rotas autenticadas enviar
Authorization: Bearer <token>eContent-Type: application/json.
| Método | Endpoint | Descrição |
|---|---|---|
GET |
/api/v1/trips?origem=&destino=&page=0&size=10 |
Lista paginada (page inicia em 0) |
GET |
/api/v1/trips/{id} |
Detalhe |
POST |
/api/v1/trips |
Criar viagem (individual) |
POST |
/api/v1/trips/lote |
Criar em lote |
PUT |
/api/v1/trips/{id} |
Atualizar |
DELETE |
/api/v1/trips/{id} |
Remover |
POST |
/api/v1/trips/{id}/calcular |
Recalcular (prévia) sem persistir |
POST |
/api/v1/calculos/frete |
Simulação individual |
POST |
/api/v1/calculos/frete/lote |
Simulação em lote (retorna itens + totais) |
| Método | Endpoint | Exemplo |
|---|---|---|
GET |
/api/v1/relatorios/intervalo?inicio=YYYY-MM-DD&fim=YYYY-MM-DD |
/intervalo?inicio=2025-08-01&fim=2025-08-31 |
GET |
/api/v1/relatorios/mensal?ano=YYYY |
/mensal?ano=2025 |
GET |
/api/v1/relatorios/anual?de=YYYY&ate=YYYY |
/anual?de=2024&ate=2025 |
// src/api/http.js
import axios from 'axios';
const api = axios.create({ baseURL: process.env.VUE_APP_API_BASE_URL });
api.interceptors.request.use(cfg => {
const token = localStorage.getItem('token');
if (token) cfg.headers.Authorization = `Bearer ${token}`;
return cfg;
});
api.interceptors.response.use(
res => res,
err => {
const status = err?.response?.status;
const msgs = err?.response?.data?.erros || ['Erro inesperado'];
if (status === 401) {
localStorage.removeItem('token');
window.location.href = '/login';
}
// exiba msgs em um toast/alert global, se existir
return Promise.reject(err);
}
);
export default api;src/
├─ api/ # axios instance/clients
├─ router/ # rotas e guards
├─ store/ # (opcional) Vuex p/ auth
├─ views/ # Login.vue, TripsList.vue, TripForm.vue, Reports.vue
├─ components/ # LotItemForm.vue, TotalsBlock.vue, TripItemCard.vue
└─ utils/ # formatadores (moeda, número, data)
- Tela única de frete: alternar Individual/Lote.
- Dois botões grandes: Simular (não persiste) e Persistir (salva).
- Na simulação em lote, exibir o bloco de Totais.
- Campos numéricos enviam ponto como separador decimal (ex.:
5.99).
- Faça um fork
- Crie uma branch:
git checkout -b feature/minha-feature - Commit:
git commit -m "feat: minha-feature" - Push:
git push origin feature/minha-feature - Abra um PR
Este projeto está sob a licença MIT. Veja LICENSE para detalhes.
LiqRota — tecnologia simples para resolver problemas reais. 🚛