mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-05-04 12:47:28 +08:00
refine whatsapp bridge defaults and webui polish
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Terminal, Globe, Github, Menu, Moon, RefreshCw, SunMedium } from 'lucide-react';
|
||||
import { Github, Moon, RefreshCw, SunMedium, Terminal } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAppContext } from '../context/AppContext';
|
||||
import { useUI } from '../context/UIContext';
|
||||
@@ -12,7 +12,7 @@ function normalizeVersion(value: string) {
|
||||
|
||||
const Header: React.FC = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const { isGatewayOnline, setSidebarOpen, sidebarCollapsed, gatewayVersion, webuiVersion } = useAppContext();
|
||||
const { isGatewayOnline, sidebarCollapsed, gatewayVersion, webuiVersion } = useAppContext();
|
||||
const { theme, toggleTheme, notify } = useUI();
|
||||
const [checkingVersion, setCheckingVersion] = React.useState(false);
|
||||
|
||||
@@ -56,28 +56,23 @@ const Header: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<header className="app-header h-14 md:h-16 border-b border-zinc-800 flex items-center justify-between px-3 md:px-6 shrink-0 z-10">
|
||||
<header className="app-header ui-border-subtle h-14 md:h-16 border-b flex items-center justify-between px-3 md:px-6 shrink-0 z-10">
|
||||
<div className="flex items-center gap-2 md:gap-3 min-w-0">
|
||||
<button className="md:hidden p-2 rounded-lg hover:bg-zinc-800 text-zinc-300" onClick={() => setSidebarOpen(true)}>
|
||||
<Menu className="w-5 h-5" />
|
||||
</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-zinc-950" />
|
||||
</div>
|
||||
{!sidebarCollapsed && (
|
||||
<span className="font-semibold text-lg md:text-xl tracking-tight truncate">{t('appName')}</span>
|
||||
)}
|
||||
<div className="brand-badge hidden md:flex h-9 w-9 items-center justify-center rounded-xl shadow-lg shrink-0">
|
||||
<Terminal className="h-5 w-5 text-white" />
|
||||
</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-zinc-950" />
|
||||
<div className="brand-badge flex h-8 w-8 items-center justify-center rounded-xl shadow-lg shrink-0 md:hidden">
|
||||
<Terminal className="h-4 w-4 text-white" />
|
||||
</div>
|
||||
{!sidebarCollapsed && (
|
||||
<span className="hidden md:inline font-semibold text-lg md:text-xl tracking-tight truncate">{t('appName')}</span>
|
||||
)}
|
||||
<span className="md:hidden font-semibold text-lg tracking-tight truncate">{t('appName')}</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 md:gap-6">
|
||||
<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>
|
||||
<div className="ui-toolbar-chip flex items-center gap-1.5 md:gap-2.5 px-2 md:px-3 py-1 rounded-lg max-w-[140px] md:max-w-none overflow-hidden">
|
||||
<span className="ui-text-muted hidden md:inline text-sm font-medium">{t('gatewayStatus')}:</span>
|
||||
{isGatewayOnline ? (
|
||||
<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" />
|
||||
@@ -91,13 +86,13 @@ const Header: React.FC = () => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="hidden md:block h-5 w-px bg-zinc-800" />
|
||||
<div className="ui-border-subtle hidden md:block h-5 w-px bg-transparent border-l" />
|
||||
|
||||
<a
|
||||
href={REPO_URL}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="inline-flex h-9 w-9 items-center justify-center text-sm font-medium text-zinc-400 hover:text-zinc-200 transition-colors bg-zinc-900 hover:bg-zinc-800 border border-zinc-800 rounded-lg"
|
||||
className="ui-button ui-button-neutral ui-button-icon text-sm font-medium"
|
||||
title={t('githubRepo')}
|
||||
>
|
||||
<Github className="w-4 h-4" />
|
||||
@@ -106,7 +101,7 @@ const Header: React.FC = () => {
|
||||
<button
|
||||
onClick={checkVersion}
|
||||
disabled={checkingVersion}
|
||||
className="inline-flex h-9 w-9 items-center justify-center text-sm font-medium text-zinc-400 hover:text-zinc-200 transition-colors bg-zinc-900 hover:bg-zinc-800 border border-zinc-800 rounded-lg disabled:opacity-60"
|
||||
className="ui-button ui-button-neutral ui-button-icon text-sm font-medium disabled:opacity-60"
|
||||
title={t('checkVersion')}
|
||||
>
|
||||
<RefreshCw className={`w-4 h-4 ${checkingVersion ? 'animate-spin' : ''}`} />
|
||||
@@ -114,18 +109,19 @@ const Header: React.FC = () => {
|
||||
|
||||
<button
|
||||
onClick={toggleTheme}
|
||||
className="inline-flex h-9 w-9 items-center justify-center text-sm font-medium text-zinc-400 hover:text-zinc-200 transition-colors bg-zinc-900 hover:bg-zinc-800 border border-zinc-800 rounded-lg"
|
||||
className="ui-button ui-button-neutral ui-button-icon text-sm font-medium"
|
||||
title={theme === 'dark' ? t('themeLight') : t('themeDark')}
|
||||
>
|
||||
{theme === 'dark' ? <SunMedium className="w-4 h-4" /> : <Moon className="w-4 h-4" />}
|
||||
</button>
|
||||
|
||||
<button
|
||||
<button
|
||||
onClick={toggleLang}
|
||||
className="flex items-center gap-2 text-sm font-medium text-zinc-400 hover:text-zinc-200 transition-colors bg-zinc-900 hover:bg-zinc-800 border border-zinc-800 px-3 py-1.5 rounded-lg"
|
||||
className="ui-button ui-button-neutral ui-button-square text-sm font-semibold"
|
||||
title={i18n.language === 'en' ? t('languageZh') : t('languageEn')}
|
||||
aria-label={i18n.language === 'en' ? t('languageZh') : t('languageEn')}
|
||||
>
|
||||
<Globe className="w-4 h-4" />
|
||||
{i18n.language === 'en' ? t('languageZh') : t('languageEn')}
|
||||
{i18n.language === 'en' ? '中' : 'EN'}
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { Plus } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface RecursiveConfigProps {
|
||||
@@ -55,11 +56,11 @@ const PrimitiveArrayEditor: React.FC<{
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{value.length === 0 && <span className="text-xs text-zinc-500 italic">{t('empty')}</span>}
|
||||
{value.length === 0 && <span className="ui-text-muted text-xs italic">{t('empty')}</span>}
|
||||
{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">
|
||||
<span key={`${item}-${idx}`} className="ui-text-secondary inline-flex items-center gap-1 px-2 py-1 rounded-xl ui-soft-panel text-xs font-mono">
|
||||
{String(item)}
|
||||
<button onClick={() => removeAt(idx)} className="ui-text-danger-hover text-zinc-400">×</button>
|
||||
<button onClick={() => removeAt(idx)} className="ui-text-danger-hover ui-text-subtle">×</button>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
@@ -83,9 +84,11 @@ const PrimitiveArrayEditor: React.FC<{
|
||||
addValue(draft);
|
||||
setDraft('');
|
||||
}}
|
||||
className="ui-button ui-button-neutral px-3 py-2 text-xs rounded-xl"
|
||||
className="ui-button ui-button-neutral ui-button-icon rounded-xl"
|
||||
title={t('add')}
|
||||
aria-label={t('add')}
|
||||
>
|
||||
{t('add')}
|
||||
<Plus className="w-4 h-4" />
|
||||
</button>
|
||||
|
||||
<select
|
||||
@@ -126,8 +129,8 @@ const RecursiveConfig: React.FC<RecursiveConfigProps> = ({ data, labels, path =
|
||||
return (
|
||||
<div key={currentPath} className="space-y-2 col-span-full">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm font-medium text-zinc-300 block capitalize">{label}</span>
|
||||
<span className="text-[10px] text-zinc-600 font-mono">{currentPath}</span>
|
||||
<span className="ui-text-secondary text-sm font-medium block capitalize">{label}</span>
|
||||
<span className="ui-text-subtle text-[10px] font-mono">{currentPath}</span>
|
||||
</div>
|
||||
<div className="ui-soft-panel p-3">
|
||||
{allPrimitive ? (
|
||||
@@ -158,11 +161,11 @@ const RecursiveConfig: React.FC<RecursiveConfigProps> = ({ data, labels, path =
|
||||
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
||||
return (
|
||||
<div key={currentPath} className="space-y-6 col-span-full">
|
||||
<h3 className="text-sm font-semibold text-zinc-400 uppercase tracking-wider flex items-center gap-2">
|
||||
<span className="w-1.5 h-4 bg-indigo-500 rounded-full" />
|
||||
<h3 className="ui-text-subtle text-sm font-semibold uppercase tracking-wider flex items-center gap-2">
|
||||
<span className="ui-icon-info w-1.5 h-4 rounded-full" />
|
||||
{label}
|
||||
</h3>
|
||||
<div className="pl-6 border-l border-zinc-800/50 dark:border-zinc-700/50">
|
||||
<div className="ui-border-subtle pl-6 border-l">
|
||||
<RecursiveConfig data={value} labels={labels} path={currentPath} onChange={onChange} hotPaths={hotPaths} onlyHot={onlyHot} />
|
||||
</div>
|
||||
</div>
|
||||
@@ -172,8 +175,8 @@ const RecursiveConfig: React.FC<RecursiveConfigProps> = ({ data, labels, path =
|
||||
return (
|
||||
<div key={currentPath} className="space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm font-medium text-zinc-300 block capitalize">{label}</span>
|
||||
<span className="text-[10px] text-zinc-600 font-mono">{currentPath}</span>
|
||||
<span className="ui-text-secondary text-sm font-medium block capitalize">{label}</span>
|
||||
<span className="ui-text-subtle text-[10px] font-mono">{currentPath}</span>
|
||||
</div>
|
||||
{typeof value === 'boolean' ? (
|
||||
<label className="ui-toggle-card flex items-center gap-3 p-3 cursor-pointer transition-colors group">
|
||||
@@ -181,9 +184,9 @@ const RecursiveConfig: React.FC<RecursiveConfigProps> = ({ data, labels, path =
|
||||
type="checkbox"
|
||||
checked={value}
|
||||
onChange={(e) => onChange(currentPath, e.target.checked)}
|
||||
className="w-4 h-4 rounded border-zinc-700 text-indigo-500 focus:ring-indigo-500 focus:ring-offset-zinc-950 bg-zinc-900"
|
||||
className="w-4 h-4 rounded border-zinc-700 text-indigo-500 focus:ring-indigo-500"
|
||||
/>
|
||||
<span className="text-sm text-zinc-400 group-hover:text-zinc-300 transition-colors">
|
||||
<span className="ui-text-subtle group-hover:ui-text-secondary text-sm transition-colors">
|
||||
{value ? (labels['enabled_true'] || t('enabled_true')) : (labels['enabled_false'] || t('enabled_false'))}
|
||||
</span>
|
||||
</label>
|
||||
|
||||
Reference in New Issue
Block a user