Setup completo do projeto com Next.js 14, TypeScript, Tailwind CSS e configuração do App Router para o frontend do Restaurantix.
Nesta aula vamos configurar o ambiente completo para desenvolver o frontend do Restaurantix usando as tecnologias mais modernas.
# 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
--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 @/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
# 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
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 configimport { 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))
}/** @type {import('next').NextConfig} */
const nextConfig = {
env: {
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3333'
},
images: {
domains: ['localhost']
}
}
module.exports = nextConfigimport 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">
{children}
</div>
</body>
</html>
)
}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-lime-500 mb-4">
Restaurantix Dashboard
</h1>
<p className="text-xl text-gray-400 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 text-gray-600 font-semibold mb-4">
🚀 Projeto Configurado!
</h2>
<p className="text-gray-600">
Next.js 15 com App Router, TypeScript e Tailwind CSS estão
funcionando perfeitamente.
</p>
</div>
</div>
</div>
);
}
# Executar em modo desenvolvimento npm run dev # Ou com yarn yarn dev # Ou com bun bun run dev # Ou com pnpm pnpm dev
http://localhost:3000Agora é sua vez! Complete os seguintes desafios:
Modifique o componente da página inicial para incluir:
Crie um componente Button em src/components/ui/:
Crie um arquivo .env.local com:
NEXT_PUBLIC_API_URL=http://localhost:3333 NEXT_PUBLIC_APP_NAME=Restaurantix
npx create-next-app@latest sempre