import { useState, useEffect } from 'react'; import { getStatus } from './api'; // --------------------------------------------------------------------------- // Translation dictionaries // --------------------------------------------------------------------------- export type Locale = 'en' | 'zh' | 'tr'; const translations: Record> = { zh: { // Navigation 'nav.dashboard': '仪表盘', 'nav.agent': '智能体', 'nav.tools': '工具', 'nav.cron': '定时任务', 'nav.integrations': '集成', 'nav.memory': '记忆', 'nav.config': '配置', 'nav.cost': '成本追踪', 'nav.logs': '日志', 'nav.doctor': '诊断', 'nav.canvas': '画布', // Dashboard 'dashboard.title': '仪表盘', 'dashboard.provider': '提供商', 'dashboard.model': '模型', 'dashboard.uptime': '运行时间', 'dashboard.temperature': '温度', 'dashboard.gateway_port': '网关端口', 'dashboard.memory_backend': '记忆后端', 'dashboard.paired': '已配对', 'dashboard.channels': '频道', 'dashboard.health': '健康状态', 'dashboard.status': '状态', 'dashboard.overview': '概览', 'dashboard.system_info': '系统信息', 'dashboard.quick_actions': '快速操作', // Agent / Chat 'agent.title': '智能体对话', 'agent.send': '发送', 'agent.placeholder': '输入消息...', 'agent.start_conversation': '发送消息开始对话', 'agent.type_message': '输入消息...', 'agent.connecting': '连接中...', 'agent.connected': '已连接', 'agent.disconnected': '已断开', 'agent.reconnecting': '重新连接中...', 'agent.thinking': '思考中...', 'agent.tool_call': '工具调用', 'agent.tool_result': '工具结果', 'agent.connection_error': '连接错误,正在尝试重连...', 'agent.tool_call_prefix': '[工具调用]', 'agent.tool_result_prefix': '[工具结果]', 'agent.error_prefix': '[错误]', 'agent.unknown_error': '未知错误', 'agent.send_error': '发送消息失败,请重试。', 'agent.copy_message': '复制消息', 'agent.connected_status': '已连接', 'agent.disconnected_status': '已断开', // Tools 'tools.title': '可用工具', 'tools.name': '名称', 'tools.description': '描述', 'tools.parameters': '参数', 'tools.search': '搜索工具...', 'tools.empty': '暂无可用工具。', 'tools.count': '工具总数', 'tools.agent_tools': '智能体工具箱', 'tools.cli_tools': 'CLI 工具箱', 'tools.parameter_schema': '参数结构', 'tools.path': '路径', 'tools.version': '版本', 'tools.category': '类别', 'tools.load_error': '加载工具失败', // Cron 'cron.title': '定时任务', 'cron.scheduled_tasks': '定时任务', 'cron.add': '添加任务', 'cron.add_job': '添加任务', 'cron.add_modal_title': '添加 Cron 任务', 'cron.delete': '删除', 'cron.enable': '启用', 'cron.disable': '禁用', 'cron.name': '名称', 'cron.name_optional': '名称(可选)', 'cron.command': '命令', 'cron.command_required': '命令', 'cron.schedule': '计划', 'cron.schedule_required': '计划', 'cron.next_run': '下次执行', 'cron.last_run': '上次执行', 'cron.last_status': '上次状态', 'cron.enabled': '已启用', 'cron.enabled_status': '启用', 'cron.disabled_status': '禁用', 'cron.empty': '暂无定时任务。', 'cron.confirm_delete': '确定要删除此任务吗?', 'cron.load_error': '加载定时任务失败', 'cron.validation_error': '计划和命令是必需的。', 'cron.add_error': '添加任务失败', 'cron.delete_error': '删除任务失败', 'cron.cancel': '取消', 'cron.adding': '添加中...', 'cron.id': 'ID', 'cron.actions': '操作', 'cron.loading_run_history': '加载运行历史...', 'cron.load_run_history_error': '加载运行历史失败', 'cron.no_runs': '暂无运行记录。', 'cron.recent_runs': '最近运行', 'cron.yes': '是', 'cron.no': '否', 'cron.edit': '编辑', 'cron.edit_modal_title': '编辑 Cron 任务', 'cron.edit_error': '更新任务失败', 'cron.saving': '保存中...', 'cron.save': '保存', // Integrations 'integrations.title': '集成', 'integrations.available': '可用', 'integrations.active': '活跃', 'integrations.coming_soon': '即将推出', 'integrations.category': '类别', 'integrations.status': '状态', 'integrations.search': '搜索集成...', 'integrations.empty': '未找到集成。', 'integrations.activate': '激活', 'integrations.deactivate': '停用', 'integrations.load_error': '加载集成失败', 'integrations.status_active': '活跃', 'integrations.status_available': '可用', 'integrations.status_coming_soon': '即将推出', // Memory 'memory.title': '记忆存储', 'memory.memory_title': '记忆', 'memory.search': '搜索记忆...', 'memory.search_placeholder': '搜索记忆条目...', 'memory.add': '存储记忆', 'memory.add_memory': '添加记忆', 'memory.add_modal_title': '添加记忆', 'memory.delete': '删除', 'memory.key': '键', 'memory.key_required': '键', 'memory.content': '内容', 'memory.content_required': '内容', 'memory.category': '类别', 'memory.category_optional': '类别(可选)', 'memory.timestamp': '时间戳', 'memory.session': '会话', 'memory.score': '分数', 'memory.empty': '未找到记忆条目。', 'memory.confirm_delete': '确定要删除此记忆条目吗?', 'memory.all_categories': '所有类别', 'memory.search_button': '搜索', 'memory.load_error': '加载记忆失败', 'memory.saving': '保存中...', 'memory.validation_error': '键和内容是必需的。', 'memory.store_error': '保存记忆失败', 'memory.delete_error': '删除记忆失败', 'memory.delete_confirm': '删除?', 'memory.yes': '是', 'memory.no': '否', 'memory.cancel': '取消', // Config 'config.title': '配置', 'config.save': '保存', 'config.saving': '保存中...', 'config.reset': '重置', 'config.saved': '配置保存成功。', 'config.error': '配置保存失败。', 'config.loading': '加载配置中...', 'config.editor_placeholder': 'TOML 配置...', 'config.configuration_title': '配置', 'config.sensitive_title': '敏感字段已隐藏', 'config.sensitive_hint': 'API 密钥、令牌和密码已隐藏以保护安全。要更新已隐藏的字段,请将整个隐藏值替换为您的新值。', 'config.save_success': '配置保存成功。', 'config.save_error': '保存配置失败', 'config.toml_label': 'TOML 配置', 'config.lines': '行', // Cost 'cost.title': '成本追踪', 'cost.session': '会话成本', 'cost.daily': '每日成本', 'cost.monthly': '每月成本', 'cost.total_tokens': '总 Tokens', 'cost.request_count': '请求数', 'cost.by_model': '按模型统计', 'cost.model': '模型', 'cost.tokens': 'Token', 'cost.requests': '请求', 'cost.usd': '成本(美元)', 'cost.load_error': '加载成本数据失败', 'cost.session_cost': '会话成本', 'cost.daily_cost': '每日成本', 'cost.monthly_cost': '每月成本', 'cost.total_requests': '总请求数', 'cost.token_statistics': 'Token 统计', 'cost.avg_tokens_per_request': '平均 Token / 请求', 'cost.cost_per_1k_tokens': '每 1K Token 成本', 'cost.model_breakdown': '模型细分', 'cost.no_model_data': '没有模型数据可用。', 'cost.cost': '成本', 'cost.share': '占比', // Logs 'logs.title': '实时日志', 'logs.live_logs': '实时日志', 'logs.clear': '清除', 'logs.pause': '暂停', 'logs.resume': '继续', 'logs.filter': '筛选日志...', 'logs.filter_label': '筛选', 'logs.empty': '暂无日志条目。', 'logs.connected': '已连接', 'logs.disconnected': '已断开', 'logs.events': '事件', 'logs.jump_to_bottom': '跳转到底部', 'logs.paused_hint': '日志流已暂停。', 'logs.waiting_hint': '等待事件...', // Doctor 'doctor.title': '系统诊断', 'doctor.diagnostics_title': '系统诊断', 'doctor.run': '运行诊断', 'doctor.run_diagnostics': '运行诊断', 'doctor.running': '正在运行诊断...', 'doctor.running_btn': '运行中...', 'doctor.running_desc': '正在运行诊断...', 'doctor.running_hint': '这可能需要几秒钟。', 'doctor.ok': '正常', 'doctor.warn': '警告', 'doctor.error': '错误', 'doctor.severity': '严重程度', 'doctor.category': '类别', 'doctor.message': '消息', 'doctor.empty': '尚未运行诊断。', 'doctor.summary': '诊断摘要', 'doctor.issues_found': '发现问题', 'doctor.warnings_summary': '警告', 'doctor.all_clear': '一切正常', 'doctor.system_diagnostics': '系统诊断', 'doctor.empty_hint': '点击"运行诊断"检查您的 ZeroClaw 安装。', // Auth / Pairing 'auth.pair': '配对设备', 'auth.pairing_code': '配对码', 'auth.pair_button': '配对', 'auth.logout': '退出', 'auth.pairing_success': '配对成功!', 'auth.pairing_failed': '配对失败,请重试。', 'auth.enter_code': '请输入配对码以连接到智能体。', // Common 'common.loading': '加载中...', 'common.error': '发生错误。', 'common.retry': '重试', 'common.cancel': '取消', 'common.confirm': '确认', 'common.save': '保存', 'common.delete': '删除', 'common.edit': '编辑', 'common.close': '关闭', 'common.yes': '是', 'common.no': '否', 'common.search': '搜索...', 'common.no_data': '暂无数据。', 'common.refresh': '刷新', 'common.back': '返回', 'common.actions': '操作', 'common.name': '名称', 'common.description': '描述', 'common.status': '状态', 'common.created': '创建时间', 'common.updated': '更新时间', // Health 'health.title': '系统健康', 'health.component': '组件', 'health.status': '状态', 'health.last_ok': '上次正常', 'health.last_error': '上次错误', 'health.restart_count': '重启次数', 'health.pid': '进程 ID', 'health.uptime': '运行时间', 'health.updated_at': '最后更新', // Dashboard specific labels 'dashboard.provider_model': '提供商 / 模型', 'dashboard.since_last_restart': '自上次重启', 'dashboard.paired_yes': '是', 'dashboard.paired_no': '否', 'dashboard.cost_overview': '成本概览', 'dashboard.active_channels': '活跃频道', 'dashboard.filter_active': '活跃', 'dashboard.filter_all': '全部', 'dashboard.no_active_channels': '没有活跃频道', 'dashboard.component_health': '组件健康', 'dashboard.load_error': '加载仪表盘失败', 'dashboard.session_label': '会话', 'dashboard.daily_label': '每日', 'dashboard.monthly_label': '每月', 'dashboard.total_tokens_label': '总 Tokens', 'dashboard.requests_label': '请求', 'dashboard.no_channels': '未配置频道', 'dashboard.active': '活跃', 'dashboard.inactive': '非活跃', 'dashboard.no_components': '没有组件报告', 'dashboard.restarts': '重启次数', 'dashboard.tab_overview': '概览', 'dashboard.tab_sessions': '会话', 'dashboard.tab_channels': '频道', 'dashboard.sessions_title': '活跃会话', 'dashboard.no_sessions': '没有活跃会话', 'dashboard.session_id': '会话 ID', 'dashboard.session_channel': '频道', 'dashboard.session_started': '开始时间', 'dashboard.session_last_activity': '最近活动', 'dashboard.session_status': '状态', 'dashboard.session_messages': '消息数', 'dashboard.session_details': '会话详情', 'dashboard.session_history': '查看历史', 'dashboard.channels_title': '频道状态', 'dashboard.no_channels_detail': '没有频道详情', 'dashboard.channel_type': '类型', 'dashboard.channel_messages': '消息数', 'dashboard.channel_last_message': '最近消息', 'dashboard.channel_config': '配置摘要', 'dashboard.channel_enabled': '已启用', 'dashboard.channel_disabled': '已禁用', 'dashboard.loading_sessions': '加载会话中...', 'dashboard.loading_channels': '加载频道中...', 'dashboard.load_sessions_error': '加载会话失败', 'dashboard.load_channels_error': '加载频道失败', 'dashboard.never': '从未', // Settings 'settings.title': '设置', 'settings.tab.appearance': '外观', 'settings.tab.typography': '排版', 'settings.appearance': '外观设置', 'settings.typography': '字体设置', 'settings.fontUi': '界面字体', 'settings.fontMono': '代码字体', 'settings.fontSize': '界面字号', 'settings.fontMonoSize': '代码字号', 'settings.preview': '预览', 'settings.previewText': '界面字体预览文本', 'settings.fontNote': '字体设置需要刷新页面后生效', 'settings.language': '界面语言', // Theme 'theme.mode': '主题模式', 'theme.accent': '强调色', 'theme.system': '跟随系统', 'theme.dark': '深色', 'theme.light': '浅色', 'theme.oled': '纯黑', }, en: { // Navigation 'nav.dashboard': 'Dashboard', 'nav.agent': 'Agent', 'nav.tools': 'Tools', 'nav.cron': 'Scheduled Jobs', 'nav.integrations': 'Integrations', 'nav.memory': 'Memory', 'nav.config': 'Configuration', 'nav.cost': 'Cost Tracker', 'nav.logs': 'Logs', 'nav.doctor': 'Doctor', 'nav.canvas': 'Canvas', // Dashboard 'dashboard.title': 'Dashboard', 'dashboard.provider': 'Provider', 'dashboard.model': 'Model', 'dashboard.uptime': 'Uptime', 'dashboard.temperature': 'Temperature', 'dashboard.gateway_port': 'Gateway Port', 'dashboard.memory_backend': 'Memory Backend', 'dashboard.paired': 'Paired', 'dashboard.channels': 'Channels', 'dashboard.health': 'Health', 'dashboard.status': 'Status', 'dashboard.overview': 'Overview', 'dashboard.system_info': 'System Information', 'dashboard.quick_actions': 'Quick Actions', // Agent / Chat 'agent.title': 'Agent Chat', 'agent.send': 'Send', 'agent.placeholder': 'Type a message...', 'agent.start_conversation': 'Send a message to start the conversation', 'agent.type_message': 'Type a message...', 'agent.connecting': 'Connecting...', 'agent.connected': 'Connected', 'agent.disconnected': 'Disconnected', 'agent.reconnecting': 'Reconnecting...', 'agent.thinking': 'Thinking...', 'agent.tool_call': 'Tool Call', 'agent.tool_result': 'Tool Result', 'agent.connection_error': 'Connection error. Attempting to reconnect...', 'agent.tool_call_prefix': '[Tool Call]', 'agent.tool_result_prefix': '[Tool Result]', 'agent.error_prefix': '[Error]', 'agent.unknown_error': 'Unknown error', 'agent.send_error': 'Failed to send message. Please try again.', 'agent.copy_message': 'Copy message', 'agent.connected_status': 'Connected', 'agent.disconnected_status': 'Disconnected', // Tools 'tools.title': 'Available Tools', 'tools.name': 'Name', 'tools.description': 'Description', 'tools.parameters': 'Parameters', 'tools.search': 'Search tools...', 'tools.empty': 'No tools available.', 'tools.count': 'Total tools', 'tools.agent_tools': 'Agent Tools', 'tools.cli_tools': 'CLI Tools', 'tools.parameter_schema': 'Parameter Schema', 'tools.path': 'Path', 'tools.version': 'Version', 'tools.category': 'Category', 'tools.load_error': 'Failed to load tools', // Cron 'cron.title': 'Scheduled Jobs', 'cron.scheduled_tasks': 'Scheduled Tasks', 'cron.add': 'Add Job', 'cron.add_job': 'Add Job', 'cron.add_modal_title': 'Add Cron Job', 'cron.delete': 'Delete', 'cron.enable': 'Enable', 'cron.disable': 'Disable', 'cron.name': 'Name', 'cron.name_optional': 'Name (optional)', 'cron.command': 'Command', 'cron.command_required': 'Command', 'cron.schedule': 'Schedule', 'cron.schedule_required': 'Schedule', 'cron.next_run': 'Next Run', 'cron.last_run': 'Last Run', 'cron.last_status': 'Last Status', 'cron.enabled': 'Enabled', 'cron.enabled_status': 'Enabled', 'cron.disabled_status': 'Disabled', 'cron.empty': 'No scheduled jobs.', 'cron.confirm_delete': 'Are you sure you want to delete this job?', 'cron.load_error': 'Failed to load cron jobs', 'cron.validation_error': 'Schedule and command are required.', 'cron.add_error': 'Failed to add job', 'cron.delete_error': 'Failed to delete job', 'cron.cancel': 'Cancel', 'cron.adding': 'Adding...', 'cron.id': 'ID', 'cron.actions': 'Actions', 'cron.loading_run_history': 'Loading run history...', 'cron.load_run_history_error': 'Failed to load run history', 'cron.no_runs': 'No runs recorded yet.', 'cron.recent_runs': 'Recent Runs', 'cron.yes': 'Yes', 'cron.no': 'No', 'cron.edit': 'Edit', 'cron.edit_modal_title': 'Edit Cron Job', 'cron.edit_error': 'Failed to update job', 'cron.saving': 'Saving...', 'cron.save': 'Save', // Integrations 'integrations.title': 'Integrations', 'integrations.available': 'Available', 'integrations.active': 'Active', 'integrations.coming_soon': 'Coming Soon', 'integrations.category': 'Category', 'integrations.status': 'Status', 'integrations.search': 'Search integrations...', 'integrations.empty': 'No integrations found.', 'integrations.activate': 'Activate', 'integrations.deactivate': 'Deactivate', 'integrations.load_error': 'Failed to load integrations', 'integrations.status_active': 'Active', 'integrations.status_available': 'Available', 'integrations.status_coming_soon': 'Coming Soon', // Memory 'memory.title': 'Memory Store', 'memory.memory_title': 'Memory', 'memory.search': 'Search memory...', 'memory.search_placeholder': 'Search memory entries...', 'memory.add': 'Store Memory', 'memory.add_memory': 'Add Memory', 'memory.add_modal_title': 'Add Memory', 'memory.delete': 'Delete', 'memory.key': 'Key', 'memory.key_required': 'Key', 'memory.content': 'Content', 'memory.content_required': 'Content', 'memory.category': 'Category', 'memory.category_optional': 'Category (optional)', 'memory.timestamp': 'Timestamp', 'memory.session': 'Session', 'memory.score': 'Score', 'memory.empty': 'No memory entries found.', 'memory.confirm_delete': 'Are you sure you want to delete this memory entry?', 'memory.all_categories': 'All Categories', 'memory.search_button': 'Search', 'memory.load_error': 'Failed to load memory', 'memory.saving': 'Saving...', 'memory.validation_error': 'Key and content are required.', 'memory.store_error': 'Failed to store memory', 'memory.delete_error': 'Failed to delete memory', 'memory.delete_confirm': 'Delete?', 'memory.yes': 'Yes', 'memory.no': 'No', 'memory.cancel': 'Cancel', // Config 'config.title': 'Configuration', 'config.save': 'Save', 'config.saving': 'Saving...', 'config.reset': 'Reset', 'config.saved': 'Configuration saved successfully.', 'config.error': 'Failed to save configuration.', 'config.loading': 'Loading configuration...', 'config.editor_placeholder': 'TOML configuration...', 'config.configuration_title': 'Configuration', 'config.sensitive_title': 'Sensitive fields are masked', 'config.sensitive_hint': 'API keys, tokens, and passwords are hidden for security. To update a masked field, replace the entire masked value with your new value.', 'config.save_success': 'Configuration saved successfully.', 'config.save_error': 'Failed to save configuration', 'config.toml_label': 'TOML Configuration', 'config.lines': 'lines', // Cost 'cost.title': 'Cost Tracker', 'cost.session': 'Session Cost', 'cost.daily': 'Daily Cost', 'cost.monthly': 'Monthly Cost', 'cost.total_tokens': 'Total Tokens', 'cost.request_count': 'Requests', 'cost.by_model': 'Cost by Model', 'cost.model': 'Model', 'cost.tokens': 'Tokens', 'cost.requests': 'Requests', 'cost.usd': 'Cost (USD)', 'cost.load_error': 'Failed to load cost data', 'cost.session_cost': 'Session Cost', 'cost.daily_cost': 'Daily Cost', 'cost.monthly_cost': 'Monthly Cost', 'cost.total_requests': 'Total Requests', 'cost.token_statistics': 'Token Statistics', 'cost.avg_tokens_per_request': 'Avg Tokens / Request', 'cost.cost_per_1k_tokens': 'Cost per 1K Tokens', 'cost.model_breakdown': 'Model Breakdown', 'cost.no_model_data': 'No model data available.', 'cost.cost': 'Cost', 'cost.share': 'Share', // Logs 'logs.title': 'Live Logs', 'logs.live_logs': 'Live Logs', 'logs.clear': 'Clear', 'logs.pause': 'Pause', 'logs.resume': 'Resume', 'logs.filter': 'Filter logs...', 'logs.filter_label': 'Filter', 'logs.empty': 'No log entries.', 'logs.connected': 'Connected', 'logs.disconnected': 'Disconnected', 'logs.events': 'events', 'logs.jump_to_bottom': 'Jump to bottom', 'logs.paused_hint': 'Log streaming is paused.', 'logs.waiting_hint': 'Waiting for events...', // Doctor 'doctor.title': 'System Diagnostics', 'doctor.diagnostics_title': 'Diagnostics', 'doctor.run': 'Run Diagnostics', 'doctor.run_diagnostics': 'Run Diagnostics', 'doctor.running': 'Running diagnostics...', 'doctor.running_btn': 'Running...', 'doctor.running_desc': 'Running diagnostics...', 'doctor.running_hint': 'This may take a few seconds.', 'doctor.ok': 'OK', 'doctor.warn': 'Warning', 'doctor.error': 'Error', 'doctor.severity': 'Severity', 'doctor.category': 'Category', 'doctor.message': 'Message', 'doctor.empty': 'No diagnostics have been run yet.', 'doctor.summary': 'Diagnostic Summary', 'doctor.issues_found': 'Issues Found', 'doctor.warnings_summary': 'Warnings', 'doctor.all_clear': 'All Clear', 'doctor.system_diagnostics': 'System Diagnostics', 'doctor.empty_hint': 'Click "Run Diagnostics" to check your ZeroClaw installation.', // Auth / Pairing 'auth.pair': 'Pair Device', 'auth.pairing_code': 'Pairing Code', 'auth.pair_button': 'Pair', 'auth.logout': 'Logout', 'auth.pairing_success': 'Pairing successful!', 'auth.pairing_failed': 'Pairing failed. Please try again.', 'auth.enter_code': 'Enter your pairing code to connect to the agent.', // Common 'common.loading': 'Loading...', 'common.error': 'An error occurred.', 'common.retry': 'Retry', 'common.cancel': 'Cancel', 'common.confirm': 'Confirm', 'common.save': 'Save', 'common.delete': 'Delete', 'common.edit': 'Edit', 'common.close': 'Close', 'common.yes': 'Yes', 'common.no': 'No', 'common.search': 'Search...', 'common.no_data': 'No data available.', 'common.refresh': 'Refresh', 'common.back': 'Back', 'common.actions': 'Actions', 'common.name': 'Name', 'common.description': 'Description', 'common.status': 'Status', 'common.created': 'Created', 'common.updated': 'Updated', // Health 'health.title': 'System Health', 'health.component': 'Component', 'health.status': 'Status', 'health.last_ok': 'Last OK', 'health.last_error': 'Last Error', 'health.restart_count': 'Restarts', 'health.pid': 'Process ID', 'health.uptime': 'Uptime', 'health.updated_at': 'Last Updated', // Dashboard specific labels 'dashboard.provider_model': 'Provider / Model', 'dashboard.since_last_restart': 'Since last restart', 'dashboard.paired_yes': 'Yes', 'dashboard.paired_no': 'No', 'dashboard.cost_overview': 'Cost Overview', 'dashboard.active_channels': 'Active Channels', 'dashboard.filter_active': 'Active', 'dashboard.filter_all': 'All', 'dashboard.no_active_channels': 'No active channels', 'dashboard.component_health': 'Component Health', 'dashboard.load_error': 'Failed to load dashboard', 'dashboard.session_label': 'Session', 'dashboard.daily_label': 'Daily', 'dashboard.monthly_label': 'Monthly', 'dashboard.total_tokens_label': 'Total Tokens', 'dashboard.requests_label': 'Requests', 'dashboard.no_channels': 'No channels configured', 'dashboard.active': 'Active', 'dashboard.inactive': 'Inactive', 'dashboard.no_components': 'No components reporting', 'dashboard.restarts': 'Restarts', 'dashboard.tab_overview': 'Overview', 'dashboard.tab_sessions': 'Sessions', 'dashboard.tab_channels': 'Channels', 'dashboard.sessions_title': 'Active Sessions', 'dashboard.no_sessions': 'No active sessions', 'dashboard.session_id': 'Session ID', 'dashboard.session_channel': 'Channel', 'dashboard.session_started': 'Started', 'dashboard.session_last_activity': 'Last Activity', 'dashboard.session_status': 'Status', 'dashboard.session_messages': 'Messages', 'dashboard.session_details': 'Session Details', 'dashboard.session_history': 'View History', 'dashboard.channels_title': 'Channel Status', 'dashboard.no_channels_detail': 'No channel details available', 'dashboard.channel_type': 'Type', 'dashboard.channel_messages': 'Messages', 'dashboard.channel_last_message': 'Last Message', 'dashboard.channel_config': 'Configuration', 'dashboard.channel_enabled': 'Enabled', 'dashboard.channel_disabled': 'Disabled', 'dashboard.loading_sessions': 'Loading sessions...', 'dashboard.loading_channels': 'Loading channels...', 'dashboard.load_sessions_error': 'Failed to load sessions', 'dashboard.load_channels_error': 'Failed to load channels', 'dashboard.never': 'Never', // Settings 'settings.title': 'Settings', 'settings.tab.appearance': 'Appearance', 'settings.tab.typography': 'Typography', 'settings.appearance': 'Appearance', 'settings.typography': 'Typography', 'settings.fontUi': 'UI Font', 'settings.fontMono': 'Code Font', 'settings.fontSize': 'UI Font Size', 'settings.fontMonoSize': 'Code Font Size', 'settings.preview': 'Preview', 'settings.previewText': 'The quick brown fox jumps over the lazy dog.', 'settings.fontNote': 'Font changes apply on page reload.', 'settings.language': 'Language', // Theme 'theme.mode': 'Theme Mode', 'theme.accent': 'Accent Color', 'theme.system': 'System', 'theme.dark': 'Dark', 'theme.light': 'Light', 'theme.oled': 'OLED Black', }, tr: { // Navigation 'nav.dashboard': 'Kontrol Paneli', 'nav.agent': 'Ajan', 'nav.tools': 'Araçlar', 'nav.cron': 'Zamanlanmış Görevler', 'nav.integrations': 'Entegrasyonlar', 'nav.memory': 'Hafıza', 'nav.config': 'Yapılandırma', 'nav.cost': 'Maliyet Takibi', 'nav.logs': 'Kayıtlar', 'nav.doctor': 'Doktor', 'nav.canvas': 'Tuval', // Dashboard 'dashboard.title': 'Kontrol Paneli', 'dashboard.provider': 'Sağlayıcı', 'dashboard.model': 'Model', 'dashboard.uptime': 'Çalışma Süresi', 'dashboard.temperature': 'Sıcaklık', 'dashboard.gateway_port': 'Ağ Geçidi Portu', 'dashboard.locale': 'Dil', 'dashboard.memory_backend': 'Hafıza Motoru', 'dashboard.paired': 'Eşleştirilmiş', 'dashboard.channels': 'Kanallar', 'dashboard.health': 'Sağlık', 'dashboard.status': 'Durum', 'dashboard.overview': 'Genel Bakış', 'dashboard.system_info': 'Sistem Bilgisi', 'dashboard.quick_actions': 'Hızlı İşlemler', 'dashboard.provider_model': 'Sağlayıcı / Model', 'dashboard.since_last_restart': 'Son Yeniden Başlatmadan Beri', 'dashboard.paired_yes': 'Evet', 'dashboard.paired_no': 'Hayır', 'dashboard.cost_overview': 'Maliyet Genel Bakışı', 'dashboard.active_channels': 'Aktif Kanallar', 'dashboard.filter_active': 'Aktif', 'dashboard.filter_all': 'Tümü', 'dashboard.no_active_channels': 'Aktif kanal yok', 'dashboard.component_health': 'Bileşen Sağlığı', 'dashboard.load_error': 'Kontrol paneli yüklenemedi', 'dashboard.session_label': 'Oturum', 'dashboard.daily_label': 'Günlük', 'dashboard.monthly_label': 'Aylık', 'dashboard.total_tokens_label': 'Toplam Token', 'dashboard.requests_label': 'İstekler', 'dashboard.no_channels': 'Kanal yapılandırılmamış', 'dashboard.active': 'Aktif', 'dashboard.inactive': 'Aktif Değil', 'dashboard.no_components': 'Bileşen raporlamıyor', 'dashboard.restarts': 'Yeniden Başlatmalar', 'dashboard.tab_overview': 'Genel Bakış', 'dashboard.tab_sessions': 'Oturumlar', 'dashboard.tab_channels': 'Kanallar', 'dashboard.sessions_title': 'Aktif Oturumlar', 'dashboard.no_sessions': 'Aktif oturum yok', 'dashboard.session_id': 'Oturum Kimliği', 'dashboard.session_channel': 'Kanal', 'dashboard.session_started': 'Başlangıç', 'dashboard.session_last_activity': 'Son Etkinlik', 'dashboard.session_status': 'Durum', 'dashboard.session_messages': 'Mesajlar', 'dashboard.session_details': 'Oturum Ayrıntıları', 'dashboard.session_history': 'Geçmişi Görüntüle', 'dashboard.channels_title': 'Kanal Durumu', 'dashboard.no_channels_detail': 'Kanal ayrıntısı yok', 'dashboard.channel_type': 'Tür', 'dashboard.channel_messages': 'Mesajlar', 'dashboard.channel_last_message': 'Son Mesaj', 'dashboard.channel_config': 'Yapılandırma', 'dashboard.channel_enabled': 'Etkin', 'dashboard.channel_disabled': 'Devre Dışı', 'dashboard.loading_sessions': 'Oturumlar yükleniyor...', 'dashboard.loading_channels': 'Kanallar yükleniyor...', 'dashboard.load_sessions_error': 'Oturumlar yüklenemedi', 'dashboard.load_channels_error': 'Kanallar yüklenemedi', 'dashboard.never': 'Hiç', // Agent / Chat 'agent.title': 'Ajan Sohbeti', 'agent.send': 'Gönder', 'agent.placeholder': 'Bir mesaj yazın...', 'agent.start_conversation': 'Sohbeti başlatmak için mesaj gönderin', 'agent.type_message': 'Bir mesaj yazın...', 'agent.connecting': 'Bağlanıyor...', 'agent.connected': 'Bağlandı', 'agent.disconnected': 'Bağlantı kesildi', 'agent.reconnecting': 'Yeniden bağlanıyor...', 'agent.thinking': 'Düşünüyor...', 'agent.tool_call': 'Araç Çağrısı', 'agent.tool_result': 'Araç Sonucu', 'agent.connection_error': 'Bağlantı hatası. Yeniden bağlanmaya çalışılıyor...', 'agent.tool_call_prefix': '[Araç Çağrısı]', 'agent.tool_result_prefix': '[Araç Sonucu]', 'agent.error_prefix': '[Hata]', 'agent.unknown_error': 'Bilinmeyen hata', 'agent.send_error': 'Mesaj gönderilemedi. Lütfen tekrar deneyin.', 'agent.copy_message': 'Mesajı kopyala', 'agent.connected_status': 'Bağlandı', 'agent.disconnected_status': 'Bağlantı kesildi', // Tools 'tools.title': 'Mevcut Araçlar', 'tools.name': 'Ad', 'tools.description': 'Açıklama', 'tools.parameters': 'Parametreler', 'tools.search': 'Araç ara...', 'tools.empty': 'Araç bulunamadı.', 'tools.count': 'Toplam araç', 'tools.agent_tools': 'Ajan Araçları', 'tools.cli_tools': 'CLI Araçları', 'tools.parameter_schema': 'Parametre Şeması', 'tools.path': 'Yol', 'tools.version': 'Sürüm', 'tools.category': 'Kategori', 'tools.load_error': 'Araçlar yüklenemedi', // Cron 'cron.title': 'Zamanlanmış Görevler', 'cron.scheduled_tasks': 'Zamanlanmış Görevler', 'cron.add': 'Görev Ekle', 'cron.add_job': 'Görev Ekle', 'cron.add_modal_title': 'Cron Görevi Ekle', 'cron.delete': 'Sil', 'cron.enable': 'Etkinleştir', 'cron.disable': 'Devre Dışı Bırak', 'cron.name': 'Ad', 'cron.name_optional': 'Ad (isteğe bağlı)', 'cron.command': 'Komut', 'cron.command_required': 'Komut', 'cron.schedule': 'Zamanlama', 'cron.schedule_required': 'Zamanlama', 'cron.next_run': 'Sonraki Çalıştırma', 'cron.last_run': 'Son Çalıştırma', 'cron.last_status': 'Son Durum', 'cron.enabled': 'Etkin', 'cron.enabled_status': 'Etkin', 'cron.disabled_status': 'Devre Dışı', 'cron.empty': 'Zamanlanmış görev bulunamadı.', 'cron.confirm_delete': 'Bu görevi silmek istediğinizden emin misiniz?', 'cron.load_error': 'Cron görevleri yüklenemedi', 'cron.validation_error': 'Zamanlama ve komut gereklidir.', 'cron.add_error': 'Görev eklenemedi', 'cron.delete_error': 'Görev silinemedi', 'cron.cancel': 'İptal', 'cron.adding': 'Ekleniyor...', 'cron.id': 'ID', 'cron.actions': 'İşlemler', 'cron.loading_run_history': 'Çalıştırma geçmişi yükleniyor...', 'cron.load_run_history_error': 'Çalıştırma geçmişi yüklenemedi', 'cron.no_runs': 'Henüz çalıştırma kaydı yok.', 'cron.recent_runs': 'Son Çalıştırmalar', 'cron.yes': 'Evet', 'cron.no': 'Hayır', 'cron.edit': 'Düzenle', 'cron.edit_modal_title': 'Cron Görevini Düzenle', 'cron.edit_error': 'Görev güncellenemedi', 'cron.saving': 'Kaydediliyor...', 'cron.save': 'Kaydet', // Integrations 'integrations.title': 'Entegrasyonlar', 'integrations.available': 'Mevcut', 'integrations.active': 'Aktif', 'integrations.coming_soon': 'Yakında', 'integrations.category': 'Kategori', 'integrations.status': 'Durum', 'integrations.search': 'Entegrasyon ara...', 'integrations.empty': 'Entegrasyon bulunamadı.', 'integrations.activate': 'Etkinleştir', 'integrations.deactivate': 'Devre Dışı Bırak', 'integrations.load_error': 'Entegrasyonlar yüklenemedi', 'integrations.all': 'Tümü', 'integrations.status_active': 'Aktif', 'integrations.status_available': 'Mevcut', 'integrations.status_coming_soon': 'Yakında', // Memory 'memory.title': 'Hafıza Deposu', 'memory.memory_title': 'Hafıza', 'memory.search': 'Hafıza ara...', 'memory.search_placeholder': 'Hafıza girişleri ara...', 'memory.add': 'Hafıza Ekle', 'memory.add_memory': 'Hafıza Ekle', 'memory.add_modal_title': 'Hafıza Ekle', 'memory.delete': 'Sil', 'memory.key': 'Anahtar', 'memory.key_required': 'Anahtar', 'memory.content': 'İçerik', 'memory.content_required': 'İçerik', 'memory.category': 'Kategori', 'memory.category_optional': 'Kategori (isteğe bağlı)', 'memory.timestamp': 'Zaman Damgası', 'memory.session': 'Oturum', 'memory.score': 'Puan', 'memory.empty': 'Hafıza girişi bulunamadı.', 'memory.confirm_delete': 'Bu hafıza girişini silmek istediğinizden emin misiniz?', 'memory.all_categories': 'Tüm Kategoriler', 'memory.search_button': 'Ara', 'memory.load_error': 'Hafıza yüklenemedi', 'memory.saving': 'Kaydediliyor...', 'memory.validation_error': 'Anahtar ve içerik gereklidir.', 'memory.store_error': 'Hafıza kaydedilemedi', 'memory.delete_error': 'Hafıza silinemedi', 'memory.delete_confirm': 'Sil?', 'memory.yes': 'Evet', 'memory.no': 'Hayır', 'memory.cancel': 'İptal', // Config 'config.title': 'Yapılandırma', 'config.save': 'Kaydet', 'config.saving': 'Kaydediliyor...', 'config.reset': 'Sıfırla', 'config.saved': 'Yapılandırma başarıyla kaydedildi.', 'config.error': 'Yapılandırma kaydedilemedi.', 'config.loading': 'Yapılandırma yükleniyor...', 'config.editor_placeholder': 'TOML yapılandırması...', 'config.configuration_title': 'Yapılandırma', 'config.sensitive_title': 'Hassas alanlar gizlendi', 'config.sensitive_hint': 'API anahtarları, belirteçler ve parolalar güvenlik için gizlendi. Maskeli bir alanı güncellemek için, tüm maskeli değeri yeni değerinizle değiştirin.', 'config.save_success': 'Yapılandırma başarıyla kaydedildi.', 'config.save_error': 'Yapılandırma kaydedilemedi', 'config.toml_label': 'TOML Yapılandırması', 'config.lines': 'satır', // Cost 'cost.title': 'Maliyet Takibi', 'cost.session': 'Oturum Maliyeti', 'cost.daily': 'Günlük Maliyet', 'cost.monthly': 'Aylık Maliyet', 'cost.total_tokens': 'Toplam Token', 'cost.request_count': 'İstek Sayısı', 'cost.by_model': 'Modele Göre Maliyet', 'cost.model': 'Model', 'cost.tokens': 'Token', 'cost.requests': 'İstekler', 'cost.usd': 'Maliyet (USD)', 'cost.load_error': 'Maliyet verileri yüklenemedi', 'cost.session_cost': 'Oturum Maliyeti', 'cost.daily_cost': 'Günlük Maliyet', 'cost.monthly_cost': 'Aylık Maliyet', 'cost.total_requests': 'Toplam İstek', 'cost.token_statistics': 'Token İstatistikleri', 'cost.avg_tokens_per_request': 'Ortalama Token / İstek', 'cost.cost_per_1k_tokens': '1K Token Başına Maliyet', 'cost.model_breakdown': 'Model Detayı', 'cost.no_model_data': 'Model verisi mevcut değil.', 'cost.cost': 'Maliyet', 'cost.share': 'Pay', // Logs 'logs.title': 'Canlı Kayıtlar', 'logs.live_logs': 'Canlı Kayıtlar', 'logs.clear': 'Temizle', 'logs.pause': 'Duraklat', 'logs.resume': 'Devam Et', 'logs.filter': 'Kayıtları filtrele...', 'logs.filter_label': 'Filtre', 'logs.empty': 'Kayıt girişi bulunamadı.', 'logs.connected': 'Bağlandı', 'logs.disconnected': 'Bağlantı kesildi', 'logs.events': 'olay', 'logs.jump_to_bottom': 'En alta atla', 'logs.paused_hint': 'Kayıt akışı duraklatıldı.', 'logs.waiting_hint': 'Olay bekleniyor...', // Doctor 'doctor.title': 'Sistem Tanıları', 'doctor.diagnostics_title': 'Tanılar', 'doctor.run': 'Tanı Çalıştır', 'doctor.run_diagnostics': 'Tanı Çalıştır', 'doctor.running': 'Tanı çalıştırılıyor...', 'doctor.running_btn': 'Çalıştırılıyor...', 'doctor.running_desc': 'Tanı çalıştırılıyor...', 'doctor.running_hint': 'Bu birkaç saniye sürebilir.', 'doctor.ok': 'Tamam', 'doctor.warn': 'Uyarı', 'doctor.error': 'Hata', 'doctor.severity': 'Şiddet', 'doctor.category': 'Kategori', 'doctor.message': 'Mesaj', 'doctor.empty': 'Henüz tanı çalıştırılmadı.', 'doctor.summary': 'Tanı Özeti', 'doctor.issues_found': 'Sorunlar Bulundu', 'doctor.warnings_summary': 'Uyarılar', 'doctor.all_clear': 'Her Şey Yolunda', 'doctor.system_diagnostics': 'Sistem Tanıları', 'doctor.empty_hint': 'ZeroClaw kurulumunuzu kontrol etmek için "Tanı Çalıştır" düğmesine tıklayın.', // Auth / Pairing 'auth.pair': 'Cihaz Eşleştir', 'auth.pairing_code': 'Eşleştirme Kodu', 'auth.pair_button': 'Eşleştir', 'auth.logout': 'Çıkış Yap', 'auth.pairing_success': 'Eşleştirme başarılı!', 'auth.pairing_failed': 'Eşleştirme başarısız. Lütfen tekrar deneyin.', 'auth.enter_code': 'Akıllı birine bağlanmak için eşleştirme kodunuzu girin.', // Common 'common.loading': 'Yükleniyor...', 'common.error': 'Bir hata oluştu.', 'common.retry': 'Tekrar Dene', 'common.cancel': 'İptal', 'common.confirm': 'Onayla', 'common.save': 'Kaydet', 'common.delete': 'Sil', 'common.edit': 'Düzenle', 'common.close': 'Kapat', 'common.yes': 'Evet', 'common.no': 'Hayır', 'common.search': 'Ara...', 'common.no_data': 'Veri mevcut değil.', 'common.refresh': 'Yenile', 'common.back': 'Geri', 'common.actions': 'İşlemler', 'common.name': 'Ad', 'common.description': 'Açıklama', 'common.status': 'Durum', 'common.created': 'Oluşturulma', 'common.updated': 'Güncellenme', // Health 'health.title': 'Sistem Sağlığı', 'health.component': 'Bileşen', 'health.status': 'Durum', 'health.last_ok': 'Son Başarılı', 'health.last_error': 'Son Hata', 'health.restart_count': 'Yeniden Başlatmalar', 'health.pid': 'İşlem Kimliği', 'health.uptime': 'Çalışma Süresi', 'health.updated_at': 'Son Güncelleme', // Settings 'settings.title': 'Ayarlar', 'settings.tab.appearance': 'Görünüm', 'settings.tab.typography': 'Tipografi', 'settings.appearance': 'Görünüm', 'settings.typography': 'Tipografi', 'settings.fontUi': 'Arayüz Yazı Tipi', 'settings.fontMono': 'Kod Yazı Tipi', 'settings.fontSize': 'Arayüz Boyutu', 'settings.fontMonoSize': 'Kod Boyutu', 'settings.preview': 'Önizleme', 'settings.previewText': 'Tembel köpek üzerinde hızlı kahverengi tilki zıplar.', 'settings.fontNote': 'Yazı tipi değişiklikleri sayfa yeniden yüklendikten sonra geçerli olur.', 'settings.language': 'Dil', // Theme 'theme.mode': 'Tema Modu', 'theme.accent': 'Vurgu Rengi', 'theme.system': 'Sistem', 'theme.dark': 'Koyu', 'theme.light': 'Açık', 'theme.oled': 'OLED Siyah', }, }; // --------------------------------------------------------------------------- // Current locale state // --------------------------------------------------------------------------- let currentLocale: Locale = 'en'; export function getLocale(): Locale { return currentLocale; } export function setLocale(locale: Locale): void { currentLocale = locale; } // --------------------------------------------------------------------------- // Translation function // --------------------------------------------------------------------------- /** * Translate a key using the current locale. Returns the key itself if no * translation is found. */ export function t(key: string): string { return translations[currentLocale]?.[key] ?? translations.en[key] ?? key; } /** * Get the translation for a specific locale. Falls back to English, then to the * raw key. */ export function tLocale(key: string, locale: Locale): string { return translations[locale]?.[key] ?? translations.en[key] ?? key; } // --------------------------------------------------------------------------- // React hook // --------------------------------------------------------------------------- /** * React hook that fetches the locale from /api/status on mount and keeps the * i18n module in sync. Returns the current locale and a `t` helper bound to it. */ export function useLocale(): { locale: Locale; t: (key: string) => string } { const [locale, setLocaleState] = useState(currentLocale); useEffect(() => { let cancelled = false; getStatus() .then((status) => { if (cancelled) return; const localeStr = status.locale?.toLowerCase() ?? ''; let detected: Locale; if (localeStr.startsWith('zh')) { detected = 'zh'; } else if (localeStr.startsWith('tr')) { detected = 'tr'; } else { detected = 'en'; } setLocale(detected); setLocaleState(detected); }) .catch(() => { // Keep default locale on error }); return () => { cancelled = true; }; }, []); return { locale, t: (key: string) => tLocale(key, locale), }; }