mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-05-17 16:37:36 +08:00
fix ui
This commit is contained in:
@@ -32,7 +32,7 @@ export const GlobalDialog: React.FC<{
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{open && (
|
||||
<motion.div className="fixed inset-0 z-[130] bg-black/60 backdrop-blur-sm flex items-center justify-center p-4"
|
||||
<motion.div className="ui-overlay-strong fixed inset-0 z-[130] backdrop-blur-sm flex items-center justify-center p-4"
|
||||
initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }}>
|
||||
<motion.div className="brand-card w-full max-w-md border border-zinc-700 shadow-2xl"
|
||||
initial={{ scale: 0.95, y: 8 }} animate={{ scale: 1, y: 0 }} exit={{ scale: 0.95, y: 8 }}>
|
||||
|
||||
@@ -63,14 +63,14 @@ const Header: React.FC = () => {
|
||||
</button>
|
||||
<div className="hidden md:flex items-center gap-3 rounded-xl px-2 py-1.5 min-w-0">
|
||||
<div className="brand-badge w-9 h-9 rounded-xl flex items-center justify-center shadow-lg shrink-0">
|
||||
<Terminal className="w-5 h-5 text-white" />
|
||||
<Terminal className="w-5 h-5 text-zinc-950" />
|
||||
</div>
|
||||
{!sidebarCollapsed && (
|
||||
<span className="font-semibold text-lg md:text-xl tracking-tight truncate">{t('appName')}</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="brand-badge md:hidden w-8 h-8 rounded-xl flex items-center justify-center shadow-lg shrink-0">
|
||||
<Terminal className="w-4 h-4 text-white" />
|
||||
<Terminal className="w-4 h-4 text-zinc-950" />
|
||||
</div>
|
||||
<span className="md:hidden font-semibold text-lg tracking-tight truncate">{t('appName')}</span>
|
||||
</div>
|
||||
@@ -79,13 +79,13 @@ const Header: React.FC = () => {
|
||||
<div className="flex items-center gap-1.5 md:gap-2.5 bg-zinc-900 border border-zinc-800 px-2 md:px-3 py-1 rounded-lg max-w-[140px] md:max-w-none overflow-hidden">
|
||||
<span className="hidden md:inline text-sm font-medium text-zinc-400">{t('gatewayStatus')}:</span>
|
||||
{isGatewayOnline ? (
|
||||
<div className="flex items-center gap-1.5 bg-emerald-500/10 text-emerald-400 px-2.5 py-0.5 rounded-md text-xs font-semibold border border-emerald-500/20">
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.8)]" />
|
||||
<div className="status-pill-online flex items-center gap-1.5 px-2.5 py-0.5 rounded-md text-xs font-semibold border">
|
||||
<div className="status-dot-online w-1.5 h-1.5 rounded-full" />
|
||||
{t('online')}
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center gap-1.5 bg-red-500/10 text-red-400 px-2.5 py-0.5 rounded-md text-xs font-semibold border border-red-500/20">
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-red-500 shadow-[0_0_8px_rgba(239,68,68,0.8)]" />
|
||||
<div className="status-pill-offline flex items-center gap-1.5 px-2.5 py-0.5 rounded-md text-xs font-semibold border">
|
||||
<div className="status-dot-offline w-1.5 h-1.5 rounded-full" />
|
||||
{t('offline')}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -15,7 +15,7 @@ const Layout: React.FC = () => {
|
||||
<div className="flex flex-1 min-h-0">
|
||||
<Sidebar />
|
||||
{sidebarOpen && (
|
||||
<button className="fixed inset-0 top-16 bg-black/40 z-30 md:hidden" onClick={() => setSidebarOpen(false)} aria-label="close sidebar" />
|
||||
<button className="ui-overlay-soft fixed inset-0 top-16 z-30 md:hidden" onClick={() => setSidebarOpen(false)} aria-label="close sidebar" />
|
||||
)}
|
||||
<main className="flex-1 flex flex-col min-w-0 relative app-main-surface">
|
||||
<AnimatePresence mode="wait">
|
||||
|
||||
@@ -59,7 +59,7 @@ const PrimitiveArrayEditor: React.FC<{
|
||||
{value.map((item, idx) => (
|
||||
<span key={`${item}-${idx}`} className="inline-flex items-center gap-1 px-2 py-1 rounded-xl ui-soft-panel text-xs font-mono text-zinc-700 dark:text-zinc-200">
|
||||
{String(item)}
|
||||
<button onClick={() => removeAt(idx)} className="text-zinc-400 hover:text-red-400">×</button>
|
||||
<button onClick={() => removeAt(idx)} className="ui-text-danger-hover text-zinc-400">×</button>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -11,12 +11,12 @@ const Sidebar: React.FC = () => {
|
||||
const location = useLocation();
|
||||
const [expandedSections, setExpandedSections] = React.useState<Record<string, boolean>>({
|
||||
main: true,
|
||||
agents: true,
|
||||
ops: true,
|
||||
config: true,
|
||||
knowledge: true,
|
||||
insights: true,
|
||||
channels: true,
|
||||
agents: false,
|
||||
ops: false,
|
||||
config: false,
|
||||
knowledge: false,
|
||||
insights: false,
|
||||
channels: false,
|
||||
});
|
||||
|
||||
const sections = [
|
||||
@@ -158,7 +158,7 @@ const Sidebar: React.FC = () => {
|
||||
</div>
|
||||
) : (
|
||||
<div className="hidden md:flex justify-center p-3 border-t border-zinc-800 bg-zinc-900/20">
|
||||
<div className="w-2.5 h-2.5 rounded-full bg-indigo-500 shadow-[0_0_14px_rgba(240,90,40,0.38)]" title={t('gatewayToken')} />
|
||||
<div className="gateway-token-indicator w-2.5 h-2.5 rounded-full" title={t('gatewayToken')} />
|
||||
</div>
|
||||
)}
|
||||
<div className={`hidden md:flex border-t border-zinc-800 bg-zinc-900/20 ${sidebarCollapsed ? 'justify-center p-3' : 'justify-end p-3'}`}>
|
||||
|
||||
@@ -32,9 +32,22 @@ export const SpaceParticles: React.FC = () => {
|
||||
resize();
|
||||
|
||||
let observer: MutationObserver | null = null;
|
||||
let themeStyles = typeof document !== 'undefined' ? getComputedStyle(document.documentElement) : null;
|
||||
|
||||
const readThemeColor = (name: string, fallback: string) => {
|
||||
const value = themeStyles?.getPropertyValue(name).trim();
|
||||
return value || fallback;
|
||||
};
|
||||
|
||||
const readThemeNumber = (name: string, fallback: number) => {
|
||||
const value = Number.parseFloat(themeStyles?.getPropertyValue(name).trim() || '');
|
||||
return Number.isFinite(value) ? value : fallback;
|
||||
};
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
observer = new MutationObserver(() => {
|
||||
isDark = document.documentElement.classList.contains('theme-dark');
|
||||
themeStyles = getComputedStyle(document.documentElement);
|
||||
});
|
||||
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
|
||||
}
|
||||
@@ -60,18 +73,18 @@ export const SpaceParticles: React.FC = () => {
|
||||
canvas.width / 2, canvas.height / 2, 0,
|
||||
canvas.width / 2, canvas.height / 2, Math.max(canvas.width, canvas.height)
|
||||
);
|
||||
if (isDark) {
|
||||
gradient.addColorStop(0, 'rgba(255, 133, 82, 0.16)');
|
||||
gradient.addColorStop(0.55, 'rgba(112, 41, 22, 0.20)');
|
||||
gradient.addColorStop(1, 'rgba(28, 12, 8, 0.88)');
|
||||
} else {
|
||||
gradient.addColorStop(0, 'rgba(255, 243, 233, 0.30)');
|
||||
gradient.addColorStop(0.55, 'rgba(255, 179, 107, 0.16)');
|
||||
gradient.addColorStop(1, 'rgba(255, 226, 209, 0.55)');
|
||||
}
|
||||
gradient.addColorStop(0, readThemeColor('--particle-glow-start', 'rgba(255, 243, 233, 0.30)'));
|
||||
gradient.addColorStop(0.55, readThemeColor('--particle-glow-mid', 'rgba(255, 179, 107, 0.16)'));
|
||||
gradient.addColorStop(1, readThemeColor('--particle-glow-end', 'rgba(255, 226, 209, 0.55)'));
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const particleRGB = readThemeColor('--particle-dot-rgb', isDark ? '255, 179, 107' : '217, 72, 28');
|
||||
const particleOpacityFloor = readThemeNumber('--particle-dot-opacity-floor', isDark ? 0.1 : 0.08);
|
||||
const particleOpacityScale = readThemeNumber('--particle-dot-opacity-scale', isDark ? 1 : 0.65);
|
||||
const lineRGB = readThemeColor('--particle-line-rgb', isDark ? '240, 90, 40' : '164, 58, 24');
|
||||
const lineOpacityScale = readThemeNumber('--particle-line-opacity-scale', isDark ? 1 : 0.85);
|
||||
|
||||
particles.forEach((p) => {
|
||||
p.x += p.speedX;
|
||||
p.y += p.speedY;
|
||||
@@ -83,9 +96,7 @@ export const SpaceParticles: React.FC = () => {
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
|
||||
ctx.fillStyle = isDark
|
||||
? `rgba(255, 179, 107, ${p.opacity})`
|
||||
: `rgba(217, 72, 28, ${Math.max(0.08, p.opacity * 0.65)})`;
|
||||
ctx.fillStyle = `rgba(${particleRGB}, ${Math.max(particleOpacityFloor, p.opacity * particleOpacityScale)})`;
|
||||
ctx.fill();
|
||||
});
|
||||
|
||||
@@ -100,9 +111,7 @@ export const SpaceParticles: React.FC = () => {
|
||||
if (dist < 120) {
|
||||
ctx.beginPath();
|
||||
const lineOpacity = 0.16 * (1 - dist / 120);
|
||||
ctx.strokeStyle = isDark
|
||||
? `rgba(240, 90, 40, ${lineOpacity})`
|
||||
: `rgba(164, 58, 24, ${lineOpacity * 0.85})`;
|
||||
ctx.strokeStyle = `rgba(${lineRGB}, ${lineOpacity * lineOpacityScale})`;
|
||||
ctx.moveTo(particles[i].x, particles[i].y);
|
||||
ctx.lineTo(particles[j].x, particles[j].y);
|
||||
ctx.stroke();
|
||||
|
||||
@@ -8,7 +8,7 @@ interface StatCardProps {
|
||||
|
||||
const StatCard: React.FC<StatCardProps> = ({ title, value, icon }) => (
|
||||
<div className="brand-card h-full min-h-[124px] border border-zinc-800 p-6 flex items-center gap-4">
|
||||
<div className="w-12 h-12 rounded-2xl bg-zinc-800/50 flex items-center justify-center border border-zinc-700/50 shadow-[inset_0_1px_0_rgba(255,255,255,0.18)] relative z-[1]">
|
||||
<div className="card-icon-shell w-12 h-12 rounded-2xl bg-zinc-800/50 flex items-center justify-center border border-zinc-700/50 relative z-[1]">
|
||||
{icon}
|
||||
</div>
|
||||
<div className="relative z-[1]">
|
||||
|
||||
Reference in New Issue
Block a user