fix(next): unwrap params with React.use in machine detail route; ui(machines): larger OS/arch badges with OS icon; dotted border for Copy Email; add Export JSON CTA (black);

This commit is contained in:
Esdras Renan 2025-10-10 11:15:38 -03:00
parent 6eb4852e9d
commit ce4b935e0c
2 changed files with 18 additions and 6 deletions

View file

@ -1,7 +1,7 @@
"use client" "use client"
import Link from "next/link" import Link from "next/link"
import { useMemo } from "react" import { use, useMemo } from "react"
import { useQuery } from "convex/react" import { useQuery } from "convex/react"
import type { Id } from "@/convex/_generated/dataModel" import type { Id } from "@/convex/_generated/dataModel"
import { AppShell } from "@/components/app-shell" import { AppShell } from "@/components/app-shell"
@ -14,8 +14,8 @@ import { useAuth } from "@/lib/auth-client"
export const runtime = "nodejs" export const runtime = "nodejs"
export const dynamic = "force-dynamic" export const dynamic = "force-dynamic"
export default function AdminMachineDetailsPage({ params }: { params: { id: string } }) { export default function AdminMachineDetailsPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = params const { id } = use(params)
const { convexUserId } = useAuth() const { convexUserId } = useAuth()
const machines = useQuery( const machines = useQuery(
convexUserId ? api.machines.listByTenant : "skip", convexUserId ? api.machines.listByTenant : "skip",

View file

@ -213,6 +213,14 @@ function getStatusVariant(status?: string | null) {
} }
} }
function osIcon(osName?: string | null) {
const name = (osName ?? "").toLowerCase()
if (name.includes("windows")) return "🪟"
if (name.includes("mac") || name.includes("darwin") || name.includes("macos")) return ""
if (name.includes("linux")) return "🐧"
return "🖥️"
}
export function AdminMachinesOverview({ tenantId }: { tenantId: string }) { export function AdminMachinesOverview({ tenantId }: { tenantId: string }) {
const machines = useMachinesQuery(tenantId) const machines = useMachinesQuery(tenantId)
const [q, setQ] = useState("") const [q, setQ] = useState("")
@ -558,20 +566,24 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
</div> </div>
{/* ping integrado na badge de status */} {/* ping integrado na badge de status */}
<div className="flex flex-wrap items-center gap-2"> <div className="flex flex-wrap items-center gap-2">
<Badge variant="outline" className="border-slate-300 bg-slate-100 text-xs font-medium text-slate-700"> <Badge variant="outline" className="h-7 border-slate-300 bg-slate-100 px-3 text-sm font-medium text-slate-700">
<span className="mr-2">{osIcon(machine.osName)}</span>
{machine.osName ?? "SO desconhecido"} {machine.osVersion ?? ""} {machine.osName ?? "SO desconhecido"} {machine.osVersion ?? ""}
</Badge> </Badge>
<Badge variant="outline" className="border-slate-300 bg-slate-100 text-xs font-medium text-slate-700"> <Badge variant="outline" className="h-7 border-slate-300 bg-slate-100 px-3 text-sm font-medium text-slate-700">
{machine.architecture?.toUpperCase() ?? "Arquitetura indefinida"} {machine.architecture?.toUpperCase() ?? "Arquitetura indefinida"}
</Badge> </Badge>
</div> </div>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
{machine.authEmail ? ( {machine.authEmail ? (
<Button size="sm" variant="outline" onClick={copyEmail} className="gap-2"> <Button size="sm" variant="outline" onClick={copyEmail} className="gap-2 border-dashed">
<ClipboardCopy className="size-4" /> <ClipboardCopy className="size-4" />
Copiar e-mail Copiar e-mail
</Button> </Button>
) : null} ) : null}
<Button size="sm" onClick={exportInventoryJson} className="gap-2 border border-black bg-black text-white hover:bg-black/90">
Exportar inventário (JSON)
</Button>
{machine.registeredBy ? ( {machine.registeredBy ? (
<Badge variant="outline">Registrada via {machine.registeredBy}</Badge> <Badge variant="outline">Registrada via {machine.registeredBy}</Badge>
) : null} ) : null}