diff --git a/src/app/api/health/route.ts b/src/app/api/health/route.ts new file mode 100644 index 0000000..135d104 --- /dev/null +++ b/src/app/api/health/route.ts @@ -0,0 +1,69 @@ +import { NextResponse } from "next/server" + +export const runtime = "nodejs" +export const dynamic = "force-dynamic" + +export async function GET() { + const diagnostics: Record = { + timestamp: new Date().toISOString(), + nodeVersion: process.version, + platform: process.platform, + arch: process.arch, + env: { + NODE_ENV: process.env.NODE_ENV, + BETTER_AUTH_URL: process.env.BETTER_AUTH_URL ? "set" : "not set", + NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL ? "set" : "not set", + DATABASE_URL: process.env.DATABASE_URL ? "set" : "not set", + BETTER_AUTH_SECRET: process.env.BETTER_AUTH_SECRET ? "set" : "not set", + }, + } + + // Test SQLite binding + try { + const Database = (await import("better-sqlite3")).default + const testDb = new Database(":memory:") + testDb.exec("SELECT 1") + testDb.close() + diagnostics.sqlite = { status: "ok", message: "better-sqlite3 binding works" } + } catch (error) { + diagnostics.sqlite = { + status: "error", + message: error instanceof Error ? error.message : String(error), + } + } + + // Test Prisma connection + try { + const { prisma } = await import("@/lib/prisma") + await prisma.$queryRaw`SELECT 1` + diagnostics.prisma = { status: "ok", message: "Prisma connection works" } + } catch (error) { + diagnostics.prisma = { + status: "error", + message: error instanceof Error ? error.message : String(error), + } + } + + // Test auth config + try { + const { auth } = await import("@/lib/auth") + diagnostics.auth = { + status: "ok", + baseURL: (auth as { options?: { baseURL?: string } }).options?.baseURL ?? "unknown", + trustedOrigins: "configured", + } + } catch (error) { + diagnostics.auth = { + status: "error", + message: error instanceof Error ? error.message : String(error), + } + } + + const hasErrors = Object.values(diagnostics).some( + (v) => typeof v === "object" && v !== null && "status" in v && v.status === "error" + ) + + return NextResponse.json(diagnostics, { + status: hasErrors ? 500 : 200, + }) +} diff --git a/src/app/emprestimos/emprestimos-page-client.tsx b/src/app/emprestimos/emprestimos-page-client.tsx index d1f4bc3..2441504 100644 --- a/src/app/emprestimos/emprestimos-page-client.tsx +++ b/src/app/emprestimos/emprestimos-page-client.tsx @@ -53,6 +53,8 @@ import { DateRangeButton, type DateRangeValue } from "@/components/date-range-bu import { DatePicker } from "@/components/ui/date-picker" import { Textarea } from "@/components/ui/textarea" import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group" +import { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription } from "@/components/ui/empty" +import { Plus } from "lucide-react" const EQUIPAMENTO_TIPOS = [ "NOTEBOOK", @@ -401,12 +403,12 @@ export function EmprestimosPageClient() { const fieldTrigger = "h-10 w-full rounded-2xl border border-slate-300 bg-slate-50/80 px-3 text-left text-sm font-semibold text-neutral-700 focus:ring-neutral-300 flex items-center gap-2" const segmentedRoot = - "flex h-10 min-w-[200px] items-stretch rounded-full border border-slate-200 bg-slate-50/70 p-1 gap-1" + "flex h-10 min-w-[220px] flex-1 items-stretch rounded-full border border-slate-200 bg-slate-50/70 p-1 gap-1" const segmentedItem = - "inline-flex h-full flex-1 items-center justify-center rounded-full px-4 text-sm font-semibold text-neutral-600 transition-colors hover:bg-slate-100 data-[state=on]:bg-cyan-600 data-[state=on]:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-300" + "inline-flex h-full flex-1 items-center justify-center rounded-full first:rounded-full last:rounded-full px-4 text-sm font-semibold text-neutral-600 transition-colors hover:bg-slate-100 data-[state=on]:bg-neutral-900 data-[state=on]:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-300" return ( -
+
{/* Stats Cards */}
@@ -429,24 +431,17 @@ export function EmprestimosPageClient() {
+ {/* Action Button */} +
+ +
+ {/* Filters Section */}
- {/* Header with title and action */} -
-
-

Empréstimos de Equipamentos

-

Gerencie o empréstimo de equipamentos para clientes.

-
- -
- {/* Search and Date Range */}
@@ -517,14 +512,22 @@ export function EmprestimosPageClient() { {/* Table Section */}
{!emprestimos ? ( -
- +
+ + Carregando empréstimos...
) : filteredEmprestimos.length === 0 ? ( -
- -

Nenhum empréstimo encontrado.

-
+ + + + + + Nenhum empréstimo encontrado + + Ajuste os filtros ou crie um novo empréstimo para começar. + + + ) : (
@@ -571,14 +574,14 @@ export function EmprestimosPageClient() { {emp.status === "ATIVO" && ( - + )} @@ -767,14 +770,10 @@ export function EmprestimosPageClient() { - - -