Exibe loading em máquinas e moderniza time picker

This commit is contained in:
codex-bot 2025-10-23 15:06:41 -03:00
parent 9bfdb451bc
commit aef5e66718
2 changed files with 57 additions and 67 deletions

View file

@ -36,6 +36,7 @@ import { api } from "@/convex/_generated/api"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Spinner } from "@/components/ui/spinner"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { Checkbox } from "@/components/ui/checkbox"
@ -737,12 +738,16 @@ export function normalizeMachineItem(raw: Record<string, unknown>): MachinesQuer
}
}
function useMachinesQuery(tenantId: string): MachinesQueryItem[] {
function useMachinesQuery(tenantId: string): { machines: MachinesQueryItem[]; isLoading: boolean } {
const result = useQuery(api.machines.listByTenant, {
tenantId,
includeMetadata: true,
}) as Array<Record<string, unknown>> | undefined
return useMemo(() => (result ?? []).map((item) => normalizeMachineItem(item)), [result])
const machines = useMemo(() => (result ?? []).map((item) => normalizeMachineItem(item)), [result])
return {
machines,
isLoading: result === undefined,
}
}
const DEFAULT_OFFLINE_THRESHOLD_MS = 10 * 60 * 1000
@ -1047,7 +1052,7 @@ function OsIcon({ osName }: { osName?: string | null }) {
}
export function AdminMachinesOverview({ tenantId, initialCompanyFilterSlug = "all" }: { tenantId: string; initialCompanyFilterSlug?: string }) {
const machines = useMachinesQuery(tenantId)
const { machines, isLoading } = useMachinesQuery(tenantId)
const [q, setQ] = useState("")
const [statusFilter, setStatusFilter] = useState<string>("all")
const [companyFilterSlug, setCompanyFilterSlug] = useState<string>(initialCompanyFilterSlug)
@ -1184,7 +1189,9 @@ const filteredMachines = useMemo(() => {
</label>
<Button variant="outline" onClick={() => { setQ(""); setStatusFilter("all"); setCompanyFilterSlug("all"); setCompanySearch(""); setOnlyAlerts(false) }}>Limpar</Button>
</div>
{machines.length === 0 ? (
{isLoading ? (
<LoadingState />
) : machines.length === 0 ? (
<EmptyState />
) : (
<MachinesGrid machines={filteredMachines} companyNameBySlug={companyNameBySlug} />
@ -1251,6 +1258,22 @@ function EmptyState() {
)
}
function LoadingState() {
return (
<div className="flex flex-col items-center gap-3 rounded-lg border border-dashed border-slate-300 bg-slate-50/50 py-12 text-center">
<div className="inline-flex size-12 items-center justify-center rounded-full border border-slate-200 bg-white shadow-sm">
<Spinner className="size-6 text-slate-500" />
</div>
<div className="space-y-1">
<p className="text-sm font-semibold text-slate-600">Carregando máquinas...</p>
<p className="text-sm text-muted-foreground">
Sincronizando o inventário em tempo real. Isso leva apenas alguns instantes.
</p>
</div>
</div>
)
}
type MachineDetailsProps = {
machine: MachinesQueryItem | null
}