shinmentakezo07
Add OmniRoute codebase without binary assets
9e4583c
Raw
History Blame Contribute Delete
2.16 kB
"use client";
import { useState, useEffect } from "react";
import { Card } from "@/shared/components";
export default function CacheStatsCard() {
const [cache, setCache] = useState(null);
const [flushing, setFlushing] = useState(false);
const fetchStats = () => {
fetch("/api/cache/stats")
.then((r) => r.json())
.then(setCache)
.catch(() => {});
};
useEffect(fetchStats, []);
const handleFlush = async () => {
setFlushing(true);
try {
await fetch("/api/cache/stats", { method: "DELETE" });
fetchStats();
} finally {
setFlushing(false);
}
};
return (
<Card className="p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-semibold text-text-main flex items-center gap-2">
<span className="material-symbols-outlined text-[20px]">cached</span>
Prompt Cache
</h3>
<button
onClick={handleFlush}
disabled={flushing}
className="px-3 py-1.5 text-xs rounded-lg bg-red-500/10 text-red-400 hover:bg-red-500/20 transition-colors disabled:opacity-50"
>
{flushing ? "Flushing…" : "Flush Cache"}
</button>
</div>
{cache ? (
<div className="grid grid-cols-2 gap-4 text-sm">
<div>
<p className="text-text-muted">Size</p>
<p className="font-mono text-lg text-text-main">
{cache.size}/{cache.maxSize}
</p>
</div>
<div>
<p className="text-text-muted">Hit Rate</p>
<p className="font-mono text-lg text-text-main">{cache.hitRate?.toFixed(1) ?? 0}%</p>
</div>
<div>
<p className="text-text-muted">Hits</p>
<p className="font-mono text-text-main">{cache.hits ?? 0}</p>
</div>
<div>
<p className="text-text-muted">Evictions</p>
<p className="font-mono text-text-main">{cache.evictions ?? 0}</p>
</div>
</div>
) : (
<p className="text-sm text-text-muted">Loading cache stats…</p>
)}
</Card>
);
}