| import type { GroupedInstance } from "../types"; | |
| interface Props { | |
| instances: GroupedInstance[]; | |
| currentId: string; | |
| onSelect: (id: string) => void; | |
| } | |
| export function InstanceNav({ instances, currentId, onSelect }: Props) { | |
| const currentIdx = instances.findIndex((g) => g.instance_id === currentId); | |
| return ( | |
| <div className="bg-gray-900 border-t border-gray-800 px-4 py-2 flex items-center justify-between"> | |
| <button | |
| onClick={() => currentIdx > 0 && onSelect(instances[currentIdx - 1].instance_id)} | |
| disabled={currentIdx <= 0} | |
| className="px-3 py-1 rounded text-xs bg-gray-800 text-gray-300 hover:bg-gray-700 disabled:opacity-30 disabled:cursor-not-allowed" | |
| > | |
| ← Prev (k) | |
| </button> | |
| <div className="flex items-center gap-2"> | |
| <span className="text-xs text-gray-500"> | |
| {currentIdx + 1} / {instances.length} | |
| </span> | |
| {/* Dot navigation for nearby instances */} | |
| <div className="flex gap-0.5"> | |
| {instances.slice(Math.max(0, currentIdx - 5), currentIdx + 6).map((g) => ( | |
| <button | |
| key={g.instance_id} | |
| onClick={() => onSelect(g.instance_id)} | |
| className={`w-2 h-2 rounded-full ${ | |
| g.instance_id === currentId | |
| ? "bg-blue-400" | |
| : g.datasets.every((d) => d.summary.resolved) | |
| ? "bg-emerald-600" | |
| : "bg-gray-600" | |
| }`} | |
| title={g.instance_id} | |
| /> | |
| ))} | |
| </div> | |
| </div> | |
| <button | |
| onClick={() => | |
| currentIdx < instances.length - 1 && | |
| onSelect(instances[currentIdx + 1].instance_id) | |
| } | |
| disabled={currentIdx >= instances.length - 1} | |
| className="px-3 py-1 rounded text-xs bg-gray-800 text-gray-300 hover:bg-gray-700 disabled:opacity-30 disabled:cursor-not-allowed" | |
| > | |
| Next (j) → | |
| </button> | |
| </div> | |
| ); | |
| } | |