Major changes across backend, frontend, infrastructure: - Provider system with model selection (Google, DeepL, OpenAI, Ollama, Google Cloud) - Admin panel: user management, pricing, settings - Glossary system with CSV import/export - Subscription and tier quota management - Security hardening (rate limiting, API key auth, path traversal fixes) - Docker compose for dev, prod, and IONOS deployment - Alembic migrations for new tables - Frontend: dashboard, pricing page, landing page, i18n (en/fr) - Test suite and verification scripts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
77 lines
2.5 KiB
TypeScript
77 lines
2.5 KiB
TypeScript
"use client"
|
|
|
|
import { Badge } from "@/components/ui/badge"
|
|
import {
|
|
Tooltip,
|
|
TooltipTrigger,
|
|
TooltipContent,
|
|
} from "@/components/ui/tooltip"
|
|
|
|
interface Provider {
|
|
name: string
|
|
status: "online" | "degraded" | "offline"
|
|
latency: string
|
|
}
|
|
|
|
const providers: Provider[] = [
|
|
{ name: "Google Translate", status: "online", latency: "42ms" },
|
|
{ name: "DeepL", status: "online", latency: "68ms" },
|
|
{ name: "Ollama (Local)", status: "online", latency: "12ms" },
|
|
{ name: "OpenAI", status: "degraded", latency: "340ms" },
|
|
]
|
|
|
|
const statusConfig = {
|
|
online: {
|
|
dotClass: "bg-[oklch(0.59_0.16_145)]",
|
|
label: "Online",
|
|
badgeClass: "border-[oklch(0.59_0.16_145/0.2)] bg-[oklch(0.59_0.16_145/0.06)] text-[oklch(0.45_0.12_145)]",
|
|
},
|
|
degraded: {
|
|
dotClass: "bg-[oklch(0.75_0.18_55)]",
|
|
label: "Degraded",
|
|
badgeClass: "border-[oklch(0.75_0.18_55/0.3)] bg-[oklch(0.75_0.18_55/0.08)] text-[oklch(0.55_0.16_55)]",
|
|
},
|
|
offline: {
|
|
dotClass: "bg-destructive",
|
|
label: "Offline",
|
|
badgeClass: "border-destructive/20 bg-destructive/5 text-destructive",
|
|
},
|
|
}
|
|
|
|
export function ProviderStatus() {
|
|
return (
|
|
<div className="flex flex-col gap-2 rounded-lg border border-border bg-card px-4 py-3">
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-[10px] font-medium uppercase tracking-wider text-muted-foreground">
|
|
Translation API Providers
|
|
</span>
|
|
<span className="text-[10px] text-muted-foreground">Last checked: 14s ago</span>
|
|
</div>
|
|
<div className="flex flex-wrap items-center gap-2">
|
|
{providers.map((provider) => {
|
|
const config = statusConfig[provider.status]
|
|
return (
|
|
<Tooltip key={provider.name}>
|
|
<TooltipTrigger asChild>
|
|
<Badge
|
|
variant="outline"
|
|
className={`cursor-default gap-1.5 px-2.5 py-1 text-xs font-medium ${config.badgeClass}`}
|
|
>
|
|
<span className={`size-1.5 rounded-full ${config.dotClass}`} />
|
|
{provider.name}
|
|
</Badge>
|
|
</TooltipTrigger>
|
|
<TooltipContent>
|
|
<div className="flex flex-col gap-0.5 text-xs">
|
|
<span className="font-medium">{config.label}</span>
|
|
<span className="text-muted-foreground">Latency: {provider.latency}</span>
|
|
</div>
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
)
|
|
})}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|