Tailwind CSS
Configuracao do Tailwind CSS e paginas SaaS pre-geradas (landing, login, dashboard, settings).
Todos os frontends gerados pelo PlazerCLI incluem Tailwind CSS v3 configurado com design tokens consistentes, dark mode e paginas SaaS prontas para uso.
Configuracao base
// apps/web/tailwind.config.ts
import type { Config } from 'tailwindcss';
const config: Config = {
content: ['./src/**/*.{js,ts,jsx,tsx,vue}'],
darkMode: 'class',
theme: {
extend: {
colors: {
primary: {
50: '#eef2ff',
100: '#e0e7ff',
200: '#c7d2fe',
300: '#a5b4fc',
400: '#818cf8',
500: '#6366f1',
600: '#4f46e5',
700: '#4338ca',
800: '#3730a3',
900: '#312e81',
950: '#1e1b4e',
},
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
},
},
plugins: [],
};
export default config;
Paginas SaaS geradas
O PlazerCLI gera paginas completas prontas para uso:
- Landing Page (
/): Hero section, features grid, pricing cards, CTA e footer - Login (
/login): Formulario de email/senha, botoes OAuth, link para Magic Link - Register (
/register): Formulario de cadastro com validacao client-side - Dashboard (
/dashboard): Layout com sidebar, header, area de conteudo - Settings (
/settings): Pagina de configuracoes do usuario e da organizacao
Layout do Dashboard
// apps/web/src/components/layouts/DashboardLayout.tsx
export function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex h-screen bg-gray-50 dark:bg-gray-900">
{/* Sidebar */}
<aside className="hidden w-64 bg-white shadow-sm dark:bg-gray-800 lg:block">
<div className="flex h-16 items-center px-6">
<Logo />
</div>
<nav className="mt-6 px-3">
<SidebarNav items={navItems} />
</nav>
</aside>
{/* Main content */}
<div className="flex flex-1 flex-col overflow-hidden">
<header className="flex h-16 items-center justify-between border-b bg-white px-6 dark:bg-gray-800">
<MobileMenuButton />
<div className="flex items-center gap-4">
<NotificationBell />
<UserMenu />
</div>
</header>
<main className="flex-1 overflow-y-auto p-6">
{children}
</main>
</div>
</div>
);
}
Componentes utilitarios
Componentes compartilhados gerados para uso nas paginas:
// apps/web/src/components/ui/Button.tsx
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger';
size?: 'sm' | 'md' | 'lg';
loading?: boolean;
}
export function Button({
variant = 'primary',
size = 'md',
loading,
children,
className,
...props
}: ButtonProps) {
const variants = {
primary: 'bg-primary-600 text-white hover:bg-primary-700',
secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200',
outline: 'border border-gray-300 text-gray-700 hover:bg-gray-50',
ghost: 'text-gray-700 hover:bg-gray-100',
danger: 'bg-red-600 text-white hover:bg-red-700',
};
const sizes = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-sm',
lg: 'px-6 py-3 text-base',
};
return (
<button
className={`inline-flex items-center justify-center rounded-lg font-medium
transition-colors disabled:opacity-50 ${variants[variant]} ${sizes[size]}
${className || ''}`}
disabled={loading || props.disabled}
{...props}
>
{loading && <Spinner className="mr-2 h-4 w-4" />}
{children}
</button>
);
}