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>
  );
}