mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-01 04:42:10 +03:00
OmniRoute is an intelligent API gateway that unifies 20+ AI providers behind a single OpenAI-compatible endpoint. Features include intelligent routing with 6 strategies, multi-format translation (OpenAI/Claude/Gemini/Responses API), circuit breakers, semantic caching, combo fallback chains, real-time health monitoring, and a full dashboard with provider management, analytics, and CLI tool integration. Key highlights: - 20+ providers (Claude Code, Codex, Gemini CLI, GitHub Copilot, iFlow, Qwen, Kiro, etc.) - 6 routing strategies (Fill First, Round Robin, P2C, Random, Least Used, Cost Optimized) - Export/Import database backup with full archive support - Translator Playground with 4 modes (Playground, Chat Tester, Test Bench, Live Monitor) - 100% TypeScript across src/ and open-sse/ - Docker support with multi-stage builds - Comprehensive documentation and 9 dashboard screenshots
73 lines
1.8 KiB
TypeScript
73 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { cn } from "@/shared/utils/cn";
|
|
|
|
// Spinner loading
|
|
export function Spinner({ size = "md", className }: { size?: string; className?: string }) {
|
|
const sizes: Record<string, string> = {
|
|
sm: "size-4",
|
|
md: "size-6",
|
|
lg: "size-8",
|
|
xl: "size-12",
|
|
};
|
|
|
|
return (
|
|
<span
|
|
role="status"
|
|
aria-label="Loading"
|
|
className={cn("material-symbols-outlined animate-spin text-primary", sizes[size], className)}
|
|
>
|
|
progress_activity
|
|
</span>
|
|
);
|
|
}
|
|
|
|
// Full page loading
|
|
export function PageLoading({ message = "Loading..." }: { message?: string }) {
|
|
return (
|
|
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center bg-bg">
|
|
<Spinner size="xl" />
|
|
<p className="mt-4 text-text-muted">{message}</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Skeleton loading
|
|
export function Skeleton({ className, ...props }: { className?: string; [key: string]: any }) {
|
|
return (
|
|
<div
|
|
aria-hidden="true"
|
|
className={cn("animate-pulse rounded-lg bg-border", className)}
|
|
{...props}
|
|
/>
|
|
);
|
|
}
|
|
|
|
// Card skeleton
|
|
export function CardSkeleton() {
|
|
return (
|
|
<div className="p-6 rounded-xl border border-border bg-surface">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<Skeleton className="h-4 w-24" />
|
|
<Skeleton className="size-10 rounded-lg" />
|
|
</div>
|
|
<Skeleton className="h-8 w-16 mb-2" />
|
|
<Skeleton className="h-3 w-20" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Default export
|
|
export default function Loading({ type = "spinner", ...props }: { type?: string; [key: string]: any }) {
|
|
switch (type) {
|
|
case "page":
|
|
return <PageLoading {...props} />;
|
|
case "skeleton":
|
|
return <Skeleton {...props} />;
|
|
case "card":
|
|
return <CardSkeleton {...props} />;
|
|
default:
|
|
return <Spinner {...props} />;
|
|
}
|
|
}
|