Frontend
TAILADMIN VUE.JS - INTEGRAÇÃO E DESIGN SYSTEM
TAILADMIN VUE.JS - INTEGRAÇÃO E DESIGN SYSTEM
VISÃO GERAL
O projeto AgrSis utiliza TailAdmin Vue.js como template base para os frontends (produtor e fornecedor), garantindo uma interface moderna, responsiva e consistente.
Site Oficial: https://tailadmin.com/Versão: Vue.js (Nuxt 3 compatible) Licença: (verificar licença adquirida)
1. CARACTERÍSTICAS DO TAILADMIN
Componentes Principais:
- ✅ Dashboard completo - Gráficos, estatísticas e cards
- ✅ Tabelas de dados - Com filtros, paginação e ordenação
- ✅ Formulários - Inputs, selects, datepickers, validação
- ✅ Autenticação - Telas de login, registro, recuperação de senha
- ✅ Navegação - Sidebar, topbar, breadcrumbs
- ✅ Modais e Alerts - Componentes de feedback
- ✅ Cards e Widgets - Elementos reutilizáveis
- ✅ Gráficos - Chart.js integrado
- ✅ Dark Mode - Tema claro/escuro
Tecnologias Utilizadas:
- Vue 3 com Composition API
- Nuxt 3 para SSR/SSG
- Tailwind CSS para estilização
- TypeScript para type safety
- Pinia para gerenciamento de estado
- VueUse para composables utilitários
2. DESIGN SYSTEM AGRSIS
Cores Primárias
// tailwind.config.js - Cores AgrSis
module.exports = {
theme: {
extend: {
colors: {
// Cores principais AgrSis
agrsis: {
primary: {
50: '#e6f7e6',
100: '#b3e6b3',
200: '#80d480',
300: '#4dc24d',
400: '#1ab01a',
500: '#00a000', // Verde principal
600: '#008000',
700: '#006600',
800: '#004d00',
900: '#003300',
},
secondary: {
50: '#fff4e6',
100: '#ffe0b3',
200: '#ffcc80',
300: '#ffb84d',
400: '#ffa41a',
500: '#ff9000', // Laranja secundário
600: '#cc7300',
700: '#995600',
800: '#663a00',
900: '#331d00',
},
neutral: {
50: '#f8f9fa',
100: '#e9ecef',
200: '#dee2e6',
300: '#ced4da',
400: '#adb5bd',
500: '#6c757d', // Cinza neutro
600: '#495057',
700: '#343a40',
800: '#212529',
900: '#0d1117',
},
success: '#28a745',
warning: '#ffc107',
error: '#dc3545',
info: '#17a2b8',
}
}
}
}
}
Tipografia
// Fontes do sistema
fontFamily: {
sans: ['Inter', 'Roboto', 'Helvetica', 'Arial', 'sans-serif'],
mono: ['Fira Code', 'Courier New', 'monospace'],
}
Espaçamentos e Breakpoints
// Seguir padrões Tailwind com algumas customizações
spacing: {
// ... padrão Tailwind
'18': '4.5rem',
'88': '22rem',
}
screens: {
'xs': '480px',
'sm': '640px',
'md': '768px',
'lg': '1024px',
'xl': '1280px',
'2xl': '1536px',
}
3. ESTRUTURA DE PASTAS
Frontend Produtor
frontend-produtor/
├── assets/
│ ├── css/
│ │ └── tailadmin.css # Estilos customizados TailAdmin
│ └── images/
│ └── agrsis-logo.svg # Logo AgrSis
├── components/
│ ├── tailadmin/ # Componentes TailAdmin base
│ │ ├── Dashboard/
│ │ ├── Forms/
│ │ ├── Tables/
│ │ ├── Navigation/
│ │ └── UI/
│ ├── agrsis/ # Componentes customizados AgrSis
│ │ ├── PedidoCotacao/
│ │ ├── ListagemProdutos/
│ │ └── HistoricoPedidos/
│ └── shared/ # Componentes compartilhados
├── composables/
│ └── useTailAdmin.ts # Composable para TailAdmin
├── layouts/
│ ├── dashboard.vue # Layout principal com sidebar TailAdmin
│ └── auth.vue # Layout de autenticação
├── pages/
│ ├── index.vue
│ ├── pedidos/
│ └── perfil/
├── plugins/
│ └── tailadmin.client.ts # Plugin TailAdmin
├── stores/
│ ├── theme.ts # Store para tema (dark/light)
│ └── sidebar.ts # Store para estado do sidebar
└── tailwind.config.js # Configuração com cores AgrSis
Frontend Fornecedor
frontend-fornecedor/
├── (estrutura similar ao frontend-produtor)
└── components/
└── agrsis/
├── ListagemLicitacoes/
├── EnvioPropostas/
└── HistoricoVendas/
4. CONFIGURAÇÃO INICIAL
4.1. Instalação do TailAdmin
# Acessar pasta do frontend
cd frontend-produtor # ou frontend-fornecedor
# Instalar dependências
npm install
# Instalar dependências específicas TailAdmin (se necessário)
npm install @headlessui/vue @heroicons/vue apexcharts vue-apexcharts
4.2. Configuração do Tailwind
// tailwind.config.js
import tailadminPreset from './tailadmin.preset'
export default {
presets: [tailadminPreset],
content: [
'./components/**/*.{js,vue,ts}',
'./layouts/**/*.vue',
'./pages/**/*.vue',
'./plugins/**/*.{js,ts}',
'./app.vue',
],
theme: {
extend: {
colors: {
// Cores AgrSis (conforme seção 2)
}
}
},
plugins: [
require('@tailwindcss/forms'),
require('@tailwindcss/typography'),
],
}
4.3. Configuração Nuxt
// nuxt.config.ts
export default defineNuxtConfig({
modules: [
'@nuxtjs/tailwindcss',
'@pinia/nuxt',
'@vueuse/nuxt',
],
tailwindcss: {
cssPath: '~/assets/css/tailadmin.css',
configPath: 'tailwind.config.js',
},
app: {
head: {
title: 'AgrSis - Plataforma de Licitação Eletrônica',
meta: [
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap' },
],
},
},
})
5. COMPONENTES CUSTOMIZADOS AGRSIS
5.1. Button Component
<!-- components/agrsis/UI/Button.vue -->
<template>
<button
:class="buttonClasses"
:disabled="disabled || loading"
@click="$emit('click', $event)"
>
<span v-if="loading" class="mr-2">
<IconSpinner class="animate-spin" />
</span>
<slot />
</button>
</template>
<script setup lang="ts">
interface Props {
variant?: 'primary' | 'secondary' | 'outline' | 'ghost'
size?: 'sm' | 'md' | 'lg'
disabled?: boolean
loading?: boolean
}
const props = withDefaults(defineProps<Props>(), {
variant: 'primary',
size: 'md',
disabled: false,
loading: false,
})
const buttonClasses = computed(() => {
const base = 'inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2'
const variants = {
primary: 'bg-agrsis-primary-500 text-white hover:bg-agrsis-primary-600 focus:ring-agrsis-primary-500',
secondary: 'bg-agrsis-secondary-500 text-white hover:bg-agrsis-secondary-600 focus:ring-agrsis-secondary-500',
outline: 'border-2 border-agrsis-primary-500 text-agrsis-primary-500 hover:bg-agrsis-primary-50',
ghost: 'text-agrsis-neutral-700 hover:bg-agrsis-neutral-100',
}
const sizes = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg',
}
const disabled = (props.disabled || props.loading) ? 'opacity-50 cursor-not-allowed' : ''
return `${base} ${variants[props.variant]} ${sizes[props.size]} ${disabled}`
})
</script>
5.2. Card Component
<!-- components/agrsis/UI/Card.vue -->
<template>
<div :class="cardClasses">
<div v-if="$slots.header" class="px-6 py-4 border-b border-agrsis-neutral-200">
<slot name="header" />
</div>
<div class="px-6 py-4">
<slot />
</div>
<div v-if="$slots.footer" class="px-6 py-4 border-t border-agrsis-neutral-200 bg-agrsis-neutral-50">
<slot name="footer" />
</div>
</div>
</template>
<script setup lang="ts">
interface Props {
variant?: 'default' | 'bordered' | 'shadow'
}
const props = withDefaults(defineProps<Props>(), {
variant: 'default',
})
const cardClasses = computed(() => {
const base = 'bg-white rounded-lg'
const variants = {
default: '',
bordered: 'border border-agrsis-neutral-200',
shadow: 'shadow-lg',
}
return `${base} ${variants[props.variant]}`
})
</script>
6. LAYOUTS
6.1. Dashboard Layout
<!-- layouts/dashboard.vue -->
<template>
<div class="flex h-screen overflow-hidden">
<!-- Sidebar -->
<TailAdminSidebar
:open="sidebarOpen"
@close="sidebarOpen = false"
/>
<!-- Main Content -->
<div class="relative flex flex-1 flex-col overflow-y-auto overflow-x-hidden">
<!-- Header -->
<TailAdminHeader @toggle-sidebar="sidebarOpen = !sidebarOpen" />
<!-- Main -->
<main class="mx-auto max-w-screen-2xl p-4 md:p-6 2xl:p-10">
<slot />
</main>
</div>
</div>
</template>
<script setup lang="ts">
const sidebarOpen = ref(false)
// Auto-fechar sidebar em mobile quando route mudar
const route = useRoute()
watch(() => route.path, () => {
if (window.innerWidth < 1024) {
sidebarOpen.value = false
}
})
</script>
7. TEMAS E DARK MODE
7.1. Theme Store
// stores/theme.ts
import { defineStore } from 'pinia'
export const useThemeStore = defineStore('theme', {
state: () => ({
isDark: false,
}),
actions: {
toggleTheme() {
this.isDark = !this.isDark
this.applyTheme()
},
applyTheme() {
if (this.isDark) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
// Salvar preferência
localStorage.setItem('theme', this.isDark ? 'dark' : 'light')
},
initTheme() {
// Carregar preferência salva ou usar preferência do sistema
const savedTheme = localStorage.getItem('theme')
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
this.isDark = savedTheme === 'dark' || (!savedTheme && prefersDark)
this.applyTheme()
},
},
})
7.2. Dark Mode Classes
/* assets/css/tailadmin.css */
/* Cores para Dark Mode */
:root {
--agrsis-bg-primary: #ffffff;
--agrsis-text-primary: #0d1117;
}
.dark {
--agrsis-bg-primary: #0d1117;
--agrsis-text-primary: #ffffff;
}
/* Aplicar em componentes */
.bg-primary {
background-color: var(--agrsis-bg-primary);
}
.text-primary {
color: var(--agrsis-text-primary);
}
8. INTEGRAÇÃO COM API LARAVEL
8.1. Configuração do Cliente HTTP
// plugins/api.ts
export default defineNuxtPlugin(() => {
const config = useRuntimeConfig()
const api = $fetch.create({
baseURL: config.public.apiBase,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
onRequest({ options }) {
// Adicionar token de autenticação
const token = useCookie('auth_token')
if (token.value) {
options.headers = {
...options.headers,
Authorization: `Bearer ${token.value}`,
}
}
},
onResponseError({ response }) {
// Tratar erros globalmente
if (response.status === 401) {
// Redirect para login
navigateTo('/login')
}
},
})
return {
provide: {
api,
},
}
})
8.2. Composable para API
// composables/useApi.ts
export const useApi = () => {
const { $api } = useNuxtApp()
return {
// Pedidos
pedidos: {
list: () => $api('/pedidos'),
get: (id: number) => $api(`/pedidos/${id}`),
create: (data: any) => $api('/pedidos', { method: 'POST', body: data }),
update: (id: number, data: any) => $api(`/pedidos/${id}`, { method: 'PUT', body: data }),
delete: (id: number) => $api(`/pedidos/${id}`, { method: 'DELETE' }),
},
// Produtos
produtos: {
list: () => $api('/produtos'),
get: (id: number) => $api(`/produtos/${id}`),
},
// Autenticação
auth: {
login: (credentials: any) => $api('/login', { method: 'POST', body: credentials }),
logout: () => $api('/logout', { method: 'POST' }),
me: () => $api('/me'),
},
}
}
9. BOAS PRÁTICAS
9.1. Componentização
- ✅ Criar componentes pequenos e reutilizáveis
- ✅ Seguir convenção de nomenclatura:
AgrSis[Nome]Component.vue - ✅ Usar Composition API com
<script setup> - ✅ Definir Props e Emits com TypeScript
9.2. Estilização
- ✅ Preferir classes utilitárias Tailwind
- ✅ Criar classes customizadas apenas quando necessário
- ✅ Manter consistência com Design System AgrSis
- ✅ Usar variáveis CSS para temas dinâmicos
9.3. Performance
- ✅ Lazy loading de componentes pesados
- ✅ Otimizar imagens (WebP, lazy loading)
- ✅ Code splitting por rota
- ✅ Usar
v-memopara listas grandes
9.4. Acessibilidade
- ✅ Usar atributos ARIA apropriados
- ✅ Garantir contraste adequado de cores
- ✅ Suporte total a navegação por teclado
- ✅ Textos alternativos em imagens
10. CHECKLIST DE INTEGRAÇÃO
Fase 1: Setup Inicial
- Instalar TailAdmin Vue.js nos projetos frontend
- Configurar Tailwind com cores AgrSis
- Criar preset customizado do TailAdmin
- Configurar layouts base (dashboard, auth)
Fase 2: Componentes Base
- Adaptar componentes TailAdmin para Design System AgrSis
- Criar componentes customizados AgrSis
- Implementar sistema de temas (dark/light)
- Configurar navegação (sidebar, header)
Fase 3: Integração API
- Configurar cliente HTTP
- Criar composables para API
- Implementar autenticação com Sanctum
- Criar stores Pinia para estado global
Fase 4: Páginas e Fluxos
- Implementar telas de autenticação
- Criar dashboards (produtor e fornecedor)
- Desenvolver fluxos principais
- Adicionar validações e feedback
Fase 5: Testes e Otimização
- Testes de responsividade
- Testes de acessibilidade
- Otimização de performance
- Documentação de componentes
11. RECURSOS E REFERÊNCIAS
Documentação Oficial:
- TailAdmin Vue: https://tailadmin.com/docs/vue
- Nuxt 3: https://nuxt.com/docs
- Tailwind CSS: https://tailwindcss.com/docs
- Vue 3: https://vuejs.org/guide
- Pinia: https://pinia.vuejs.org
Ferramentas Úteis:
- Tailwind Play: https://play.tailwindcss.com (testar estilos)
- Heroicons: https://heroicons.com (ícones)
- Headless UI: https://headlessui.com (componentes acessíveis)
Design:
- Figma: (link para designs AgrSis, quando disponível)
- Paleta de Cores: https://coolors.co (gerar variações)
Última atualização: 2025-12-05 Versão do documento: 1.0 Responsável: Claude Code AI