🚀 Oferta especial: 60% OFF no CrazyStack - Últimas vagas!Garantir vaga →
Voltar ao Curso
MÓDULO 1
AULA 1

Next.js 14 + App Router

Setup completo do projeto com Next.js 14, TypeScript, Tailwind CSS e configuração do App Router para o frontend do Restaurantix.

35 min
Prático
Setup
🎯 Objetivos da Aula

Nesta aula vamos configurar o ambiente completo para desenvolver o frontend do Restaurantix usando as tecnologias mais modernas.

O que vamos fazer

  • • Criar projeto Next.js 14 com App Router
  • • Configurar TypeScript para type safety
  • • Setup do Tailwind CSS para estilização
  • • Estruturar pastas do projeto
  • • Configurar ESLint e Prettier

Tecnologias

  • Next.js 14: Framework React
  • TypeScript: Tipagem estática
  • Tailwind CSS: Utility-first CSS
  • App Router: Nova arquitetura
  • ESLint: Linting de código
Passo 1: Criando o Projeto Next.js

Comando para criar o projeto

# Criar projeto Next.js com todas as configurações
npx create-next-app@latest restaurantix-frontend \
  --typescript \
  --tailwind \
  --eslint \
  --app \
  --src-dir \
  --import-alias "@/*"

# Entrar no diretório
cd restaurantix-frontend

# Instalar dependências adicionais
npm install lucide-react class-variance-authority clsx tailwind-merge

Explicação dos parâmetros

--typescriptConfigura TypeScript automaticamente
--tailwindInstala e configura Tailwind CSS
--appUsa o novo App Router (recomendado)
--src-dirOrganiza código na pasta src/
--import-aliasConfigura imports absolutos com @/
Passo 2: Estrutura de Pastas

Estrutura inicial do projeto

restaurantix-frontend/
├── src/
│   ├── app/                    # App Router (Next.js 14)
│   │   ├── globals.css        # Estilos globais
│   │   ├── layout.tsx         # Layout principal
│   │   ├── page.tsx           # Página inicial
│   │   └── loading.tsx        # Loading UI
│   ├── components/            # Componentes reutilizáveis
│   │   ├── ui/               # Componentes base (shadcn/ui)
│   │   └── layout/           # Componentes de layout
│   ├── lib/                  # Utilitários e configurações
│   │   ├── utils.ts          # Funções utilitárias
│   │   └── api.ts            # Cliente da API
│   ├── hooks/                # Custom hooks
│   ├── store/                # Estado global (Zustand)
│   └── types/                # Definições de tipos
├── public/                   # Arquivos estáticos
├── tailwind.config.ts        # Configuração Tailwind
├── tsconfig.json            # Configuração TypeScript
└── next.config.js           # Configuração Next.js

Criando a estrutura de pastas

# Criar estrutura de pastas
mkdir -p src/components/ui
mkdir -p src/components/layout
mkdir -p src/lib
mkdir -p src/hooks
mkdir -p src/store
mkdir -p src/types

# Criar arquivos base
touch src/lib/utils.ts
touch src/lib/api.ts
touch src/types/index.ts
Passo 3: Configurações Essenciais

tailwind.config.ts

import type { Config } from 'tailwindcss'

const config: Config = {
  content: [
    './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
    './src/components/**/*.{js,ts,jsx,tsx,mdx}',
    './src/app/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  theme: {
    extend: {
      colors: {
        border: "hsl(var(--border))",
        input: "hsl(var(--input))",
        ring: "hsl(var(--ring))",
        background: "hsl(var(--background))",
        foreground: "hsl(var(--foreground))",
        primary: {
          DEFAULT: "hsl(var(--primary))",
          foreground: "hsl(var(--primary-foreground))",
        },
        secondary: {
          DEFAULT: "hsl(var(--secondary))",
          foreground: "hsl(var(--secondary-foreground))",
        },
        destructive: {
          DEFAULT: "hsl(var(--destructive))",
          foreground: "hsl(var(--destructive-foreground))",
        },
        muted: {
          DEFAULT: "hsl(var(--muted))",
          foreground: "hsl(var(--muted-foreground))",
        },
        accent: {
          DEFAULT: "hsl(var(--accent))",
          foreground: "hsl(var(--accent-foreground))",
        },
        popover: {
          DEFAULT: "hsl(var(--popover))",
          foreground: "hsl(var(--popover-foreground))",
        },
        card: {
          DEFAULT: "hsl(var(--card))",
          foreground: "hsl(var(--card-foreground))",
        },
      },
      borderRadius: {
        lg: "var(--radius)",
        md: "calc(var(--radius) - 2px)",
        sm: "calc(var(--radius) - 4px)",
      },
    },
  },
  plugins: [],
}
export default config

src/lib/utils.ts

import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

export function formatCurrency(value: number) {
  return new Intl.NumberFormat('pt-BR', {
    style: 'currency',
    currency: 'BRL',
  }).format(value / 100)
}

export function formatDate(date: string | Date) {
  return new Intl.DateTimeFormat('pt-BR', {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  }).format(new Date(date))
}

next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    appDir: true,
  },
  env: {
    NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3333',
  },
  images: {
    domains: ['localhost'],
  },
}

module.exports = nextConfig
Passo 4: Primeiro Componente

src/app/layout.tsx

import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import './globals.css'

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
  title: 'Restaurantix - Dashboard',
  description: 'Sistema de gestão para restaurantes',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="pt-BR">
      <body className={inter.className}>
        <div className="min-h-screen bg-gray-50">
          {children}
        </div>
      </body>
    </html>
  )
}

src/app/page.tsx

export default function HomePage() {
  return (
    <div className="container mx-auto px-4 py-8">
      <div className="text-center">
        <h1 className="text-4xl font-bold text-gray-900 mb-4">
          Restaurantix Dashboard
        </h1>
        <p className="text-xl text-gray-600 mb-8">
          Sistema de gestão para restaurantes
        </p>
        
        <div className="bg-white rounded-lg shadow-lg p-8 max-w-md mx-auto">
          <h2 className="text-2xl font-semibold mb-4">
            🚀 Projeto Configurado!
          </h2>
          <p className="text-gray-600">
            Next.js 14 com App Router, TypeScript e Tailwind CSS 
            estão funcionando perfeitamente.
          </p>
        </div>
      </div>
    </div>
  )
}
🧪 Testando o Projeto

Executar o projeto

# Executar em modo desenvolvimento
npm run dev

# Ou com yarn
yarn dev

# Ou com pnpm
pnpm dev

Verificar se está funcionando

Abrir http://localhost:3000
Verificar se a página carrega sem erros
Confirmar que o Tailwind CSS está aplicado
Testar hot reload fazendo uma alteração
🎯 Exercício Prático

Agora é sua vez! Complete os seguintes desafios:

1. Personalizar a página inicial

Modifique o componente da página inicial para incluir:

  • • Um header com navegação
  • • Cards com informações sobre o projeto
  • • Footer com links úteis

2. Criar componente reutilizável

Crie um componente Button em src/components/ui/:

  • • Com variantes de cor (primary, secondary)
  • • Com diferentes tamanhos (sm, md, lg)
  • • Tipado com TypeScript

3. Configurar variáveis de ambiente

Crie um arquivo .env.local com:

NEXT_PUBLIC_API_URL=http://localhost:3333
NEXT_PUBLIC_APP_NAME=Restaurantix

💡 Dicas importantes:

  • • Use o comando npx create-next-app@latest sempre
  • • Prefira TypeScript para projetos profissionais
  • • O App Router é o futuro do Next.js
  • • Organize bem a estrutura de pastas desde o início