fix(ui): restore provider assets and model availability endpoint (#367)
* fix(usage): track lifetime request total beyond history cap * fix(ui): restore provider assets and model availability endpoint
This commit is contained in:
1 parent
5fedcad624
commit
9fe4726f34
11 files changed
+707
-258
No files matched your search
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
import { useEffect, useState } from "react";
|
||||
import Image from "next/image";
|
||||
import ProviderIcon from "@/shared/components/ProviderIcon";
|
||||
|
||||
const CLI_TOOLS = [
|
||||
{ id: "claude", name: "Claude Code", image: "/providers/claude.png" },
|
||||
@@ -10,10 +10,30 @@ const CLI_TOOLS = [
|
||||
];
|
||||
|
||||
const PROVIDERS = [
|
||||
{ id: "openai", name: "OpenAI", color: "bg-emerald-500", textColor: "text-white" },
|
||||
{ id: "anthropic", name: "Anthropic", color: "bg-orange-400", textColor: "text-white" },
|
||||
{ id: "gemini", name: "Gemini", color: "bg-blue-500", textColor: "text-white" },
|
||||
{ id: "github", name: "GitHub Copilot", color: "bg-gray-700", textColor: "text-white" },
|
||||
{
|
||||
id: "openai",
|
||||
name: "OpenAI",
|
||||
color: "bg-emerald-500",
|
||||
textColor: "text-white",
|
||||
},
|
||||
{
|
||||
id: "anthropic",
|
||||
name: "Anthropic",
|
||||
color: "bg-orange-400",
|
||||
textColor: "text-white",
|
||||
},
|
||||
{
|
||||
id: "gemini",
|
||||
name: "Gemini",
|
||||
color: "bg-blue-500",
|
||||
textColor: "text-white",
|
||||
},
|
||||
{
|
||||
id: "github",
|
||||
name: "GitHub Copilot",
|
||||
color: "bg-gray-700",
|
||||
textColor: "text-white",
|
||||
},
|
||||
];
|
||||
|
||||
export default function FlowAnimation() {
|
||||
@@ -30,26 +50,29 @@ export default function FlowAnimation() {
|
||||
<div className="mt-16 w-full max-w-4xl relative h-[360px] hidden md:flex items-center justify-center animate-[float_6s_ease-in-out_infinite]">
|
||||
{/* 9Router Hub - Center */}
|
||||
<div className="relative z-20 w-32 h-32 rounded-full bg-[#23180f] border-2 border-[#f97815] shadow-[0_0_40px_rgba(249,120,21,0.3)] flex flex-col items-center justify-center gap-1 group cursor-pointer hover:scale-105 transition-transform duration-500">
|
||||
<span className="material-symbols-outlined text-4xl text-[#f97815]">hub</span>
|
||||
<span className="text-xs font-bold text-white tracking-widest uppercase">9Router</span>
|
||||
<span className="material-symbols-outlined text-4xl text-[#f97815]">
|
||||
hub
|
||||
</span>
|
||||
<span className="text-xs font-bold text-white tracking-widest uppercase">
|
||||
9Router
|
||||
</span>
|
||||
<div className="absolute inset-0 rounded-full border border-[#f97815]/30 animate-ping opacity-20"></div>
|
||||
</div>
|
||||
|
||||
{/* CLI Tools - Left side */}
|
||||
<div className="absolute left-0 top-1/2 -translate-y-1/2 flex flex-col gap-7">
|
||||
{CLI_TOOLS.map((tool) => (
|
||||
<div
|
||||
key={tool.id}
|
||||
<div
|
||||
key={tool.id}
|
||||
className="flex items-center gap-3 opacity-70 hover:opacity-100 transition-opacity group"
|
||||
>
|
||||
<div className="w-16 h-16 rounded-2xl bg-[#23180f] border border-[#3a2f27] flex items-center justify-center overflow-hidden p-2 hover:border-[#f97815]/50 transition-all hover:scale-105">
|
||||
<Image
|
||||
src={tool.image}
|
||||
<ProviderIcon
|
||||
src={tool.image}
|
||||
alt={tool.name}
|
||||
width={48}
|
||||
height={48}
|
||||
size={48}
|
||||
className="object-contain rounded-xl max-w-[48px] max-h-[48px]"
|
||||
sizes="48px"
|
||||
fallbackText={tool.name.slice(0, 2).toUpperCase()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -57,40 +80,70 @@ export default function FlowAnimation() {
|
||||
</div>
|
||||
|
||||
{/* SVG Lines from CLI to 9Router */}
|
||||
<svg className="absolute inset-0 w-full h-full z-10 pointer-events-none stroke-yellow-700" xmlns="http://www.w3.org/2000/svg">
|
||||
<path className="animate-[dash_2s_linear_infinite]" d="M 60 50 C 250 70, 250 180, 360 180" fill="none" strokeDasharray="5,5" strokeWidth="2"></path>
|
||||
<path className="animate-[dash_2s_linear_infinite]" d="M 60 140 C 250 140, 250 180, 360 180" fill="none" strokeDasharray="5,5" strokeWidth="2"></path>
|
||||
<path className="animate-[dash_2s_linear_infinite]" d="M 60 210 C 250 210, 250 180, 360 180" fill="none" strokeDasharray="5,5" strokeWidth="2"></path>
|
||||
<path className="animate-[dash_2s_linear_infinite]" d="M 60 300 C 250 280, 250 180, 360 180" fill="none" strokeDasharray="5,5" strokeWidth="2"></path>
|
||||
<svg
|
||||
className="absolute inset-0 w-full h-full z-10 pointer-events-none stroke-yellow-700"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
className="animate-[dash_2s_linear_infinite]"
|
||||
d="M 60 50 C 250 70, 250 180, 360 180"
|
||||
fill="none"
|
||||
strokeDasharray="5,5"
|
||||
strokeWidth="2"
|
||||
></path>
|
||||
<path
|
||||
className="animate-[dash_2s_linear_infinite]"
|
||||
d="M 60 140 C 250 140, 250 180, 360 180"
|
||||
fill="none"
|
||||
strokeDasharray="5,5"
|
||||
strokeWidth="2"
|
||||
></path>
|
||||
<path
|
||||
className="animate-[dash_2s_linear_infinite]"
|
||||
d="M 60 210 C 250 210, 250 180, 360 180"
|
||||
fill="none"
|
||||
strokeDasharray="5,5"
|
||||
strokeWidth="2"
|
||||
></path>
|
||||
<path
|
||||
className="animate-[dash_2s_linear_infinite]"
|
||||
d="M 60 300 C 250 280, 250 180, 360 180"
|
||||
fill="none"
|
||||
strokeDasharray="5,5"
|
||||
strokeWidth="2"
|
||||
></path>
|
||||
</svg>
|
||||
|
||||
{/* SVG Lines from 9Router to Providers */}
|
||||
<svg className="absolute inset-0 w-full h-full z-10 pointer-events-none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M 440 180 C 550 180, 550 50, 740 50"
|
||||
fill="none"
|
||||
stroke={activeFlow === 0 ? "#f97815" : "rgb(75, 85, 99)"}
|
||||
<svg
|
||||
className="absolute inset-0 w-full h-full z-10 pointer-events-none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M 440 180 C 550 180, 550 50, 740 50"
|
||||
fill="none"
|
||||
stroke={activeFlow === 0 ? "#f97815" : "rgb(75, 85, 99)"}
|
||||
strokeWidth={activeFlow === 0 ? "3" : "2"}
|
||||
className={activeFlow === 0 ? "animate-pulse" : ""}
|
||||
></path>
|
||||
<path
|
||||
d="M 440 180 C 550 180, 550 130, 740 130"
|
||||
fill="none"
|
||||
stroke={activeFlow === 1 ? "#f97815" : "rgb(75, 85, 99)"}
|
||||
<path
|
||||
d="M 440 180 C 550 180, 550 130, 740 130"
|
||||
fill="none"
|
||||
stroke={activeFlow === 1 ? "#f97815" : "rgb(75, 85, 99)"}
|
||||
strokeWidth={activeFlow === 1 ? "3" : "2"}
|
||||
className={activeFlow === 1 ? "animate-pulse" : ""}
|
||||
></path>
|
||||
<path
|
||||
d="M 440 180 C 550 180, 550 230, 740 230"
|
||||
fill="none"
|
||||
stroke={activeFlow === 2 ? "#f97815" : "rgb(75, 85, 99)"}
|
||||
<path
|
||||
d="M 440 180 C 550 180, 550 230, 740 230"
|
||||
fill="none"
|
||||
stroke={activeFlow === 2 ? "#f97815" : "rgb(75, 85, 99)"}
|
||||
strokeWidth={activeFlow === 2 ? "3" : "2"}
|
||||
className={activeFlow === 2 ? "animate-pulse" : ""}
|
||||
></path>
|
||||
<path
|
||||
d="M 440 180 C 550 180, 550 310, 740 310"
|
||||
fill="none"
|
||||
stroke={activeFlow === 3 ? "#f97815" : "rgb(75, 85, 99)"}
|
||||
<path
|
||||
d="M 440 180 C 550 180, 550 310, 740 310"
|
||||
fill="none"
|
||||
stroke={activeFlow === 3 ? "#f97815" : "rgb(75, 85, 99)"}
|
||||
strokeWidth={activeFlow === 3 ? "3" : "2"}
|
||||
className={activeFlow === 3 ? "animate-pulse" : ""}
|
||||
></path>
|
||||
@@ -99,7 +152,7 @@ export default function FlowAnimation() {
|
||||
{/* AI Providers - Right side */}
|
||||
<div className="absolute right-0 top-0 bottom-0 flex flex-col justify-between py-6">
|
||||
{PROVIDERS.map((provider, idx) => (
|
||||
<div
|
||||
<div
|
||||
key={provider.id}
|
||||
className={`px-4 py-2 rounded-lg ${provider.color} ${provider.textColor} flex items-center justify-center font-bold text-xs shadow-lg hover:scale-110 transition-all cursor-help min-w-[140px] ${
|
||||
activeFlow === idx ? "ring-4 ring-[#f97815]/50 scale-110" : ""
|
||||
@@ -113,9 +166,10 @@ export default function FlowAnimation() {
|
||||
|
||||
{/* Mobile fallback */}
|
||||
<div className="md:hidden mt-8 w-full p-4 rounded-lg bg-[#23180f] border border-[#3a2f27]">
|
||||
<p className="text-sm text-center text-gray-400">Interactive diagram visible on desktop</p>
|
||||
<p className="text-sm text-center text-gray-400">
|
||||
Interactive diagram visible on desktop
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user