Painel administrativo completo para gestão de uma plataforma SaaS multi-tenant. Desenvolvido com Nuxt 3, PrimeVue 4 e Tailwind CSS 4, consome a API REST em Go disponível no repositório abaixo.
| Projeto | Repositório |
|---|---|
| 🚀 API Backend (Go) | saas-single-db-auth-api |
| 🏢 Painel do Tenant | saas-tenant-panel-demo |
- Autenticação — Login JWT com persistência via
localStorage, guard global de rotas e sistema de permissões por slug - Dashboard — Visão geral com métricas (tenants, planos, features, usuários) e listagem de tenants recentes
- Tenants — CRUD completo, histórico de planos, membros, alteração de status e troca de plano
- Planos — CRUD com gerenciamento de features vinculadas, tipo (individual/business), preço e multilinguagem
- Features — CRUD de funcionalidades com slug/code únicos
- Promoções — CRUD de promoções com desconto percentual ou fixo e validade por data
- Sys Users — CRUD de usuários administrativos, atribuição/remoção de roles
- Roles & Permissões — CRUD de roles com listagem de permissões disponíveis
- Perfil — Edição de dados pessoais, links sociais e alteração de senha
- Multilinguagem — Campos de nome/título/descrição com suporte a
pt-BR,pt,eneesnos formulários de Planos, Features, Promoções e Roles - Tema — Dark/light mode com detecção automática da preferência do sistema e persistência em
localStorage
| Camada | Tecnologia |
|---|---|
| Framework | Nuxt 3 (SPA mode, ssr: false) |
| UI Components | PrimeVue 4 com tema Aura |
| CSS | Tailwind CSS 4 + tailwindcss-primeui |
| State Management | Pinia via @pinia/nuxt |
| Ícones | @iconify/vue (conjunto mdi) |
| HTTP | $fetch nativo do Nuxt |
- Node.js 20+
- API backend rodando em
http://localhost:8081(ver saas-single-db-auth-api)
# Instalar dependências
npm install
# Servidor de desenvolvimento (http://localhost:3000)
npm run dev
# Build de produção
npm run build
# Preview do build
npm run previewO endereço base da API é definido em services/adminApi.ts:
const BASE_URL = 'http://localhost:8081/api/v1/admin'Altere esse valor conforme o ambiente desejado.
| Campo | Valor |
|---|---|
admin@saas.com |
|
| Senha | admin123 |
As credenciais acima são as padrões geradas pelo seed da API. Altere-as após o primeiro acesso.
├── assets/ # CSS global (Tailwind)
├── components/
│ ├── shared/ # StatusBadge, EmptyState, LoadingOverlay
│ └── TranslatableField.vue # Campo com seletor de idioma
├── composables/ # useTheme, usePermission, useApiError, usePagination, useConfirmDialog
├── layouts/
│ ├── admin.vue # Layout principal com sidebar e header
│ └── auth.vue # Layout de login
├── middleware/ # auth.global.ts, permission.ts
├── pages/
│ ├── dashboard.vue
│ ├── tenants/
│ ├── plans/
│ ├── features/
│ ├── promotions/
│ ├── sys-users/
│ ├── roles/
│ └── settings/
├── plugins/ # can-directive.ts, primevue-services.ts
├── services/ # adminApi.ts
├── stores/ # useAuthStore, useTenantStore, usePlanStore, ...
└── types/ # admin.ts, tenant.ts, plan.ts, feature.ts, promotion.ts, shared.ts
O acesso às rotas é controlado pelo middleware permission.ts via metadado requiredPermission. A diretiva v-can="'slug'" oculta elementos no template conforme as permissões do usuário logado.
Exemplos de slugs: view_tenants, manage_plans, manage_features, manage_billing, manage_sys_users.
Os campos traduzíveis exibem um seletor de bandeiras (🇧🇷 🇵🇹 🏴 🇪🇸). O payload enviado à API segue o formato:
{
"name": "Plano Pro",
"translations": {
"name": {
"pt-BR": "Plano Pro",
"pt": "Plano Pro",
"en": "Pro Plan",
"es": "Plan Pro"
},
"description": {
"pt-BR": "Descrição em português",
"en": "Description in English",
"es": "Descripción en español",
"pt": "Descrição em português de Portugal"
}
}
}MIT