diff --git a/locales/en-US/discover.json b/locales/en-US/discover.json index 802247f6c7..c7ac629d4f 100644 --- a/locales/en-US/discover.json +++ b/locales/en-US/discover.json @@ -477,11 +477,129 @@ "search.placeholder": "Search by name, description, or keywords...", "search.result": "{{count}} results about {{keyword}}", "search.searching": "Searching...", + "skillEmpty.description": "Try adjusting filters or searching with different keywords.", + "skillEmpty.search": "No matching Skills found", + "skillEmpty.title": "No Skills found", + "skills.categories.agent-to-agent-protocols.description": "Inter-agent communication, orchestration, and protocol skills", + "skills.categories.agent-to-agent-protocols.name": "Agent-to-Agent Protocols", + "skills.categories.ai-llms.description": "AI model integrations, LLM tooling, and prompt engineering skills", + "skills.categories.ai-llms.name": "AI & LLMs", + "skills.categories.all.description": "All Skills", + "skills.categories.all.name": "All", + "skills.categories.apple-apps-services.description": "Apple ecosystem apps, services, and platform integrations", + "skills.categories.apple-apps-services.name": "Apple Apps & Services", + "skills.categories.browser-automation.description": "Browser control, web scraping, and UI automation skills", + "skills.categories.browser-automation.name": "Browser & Automation", + "skills.categories.calendar-scheduling.description": "Calendar management, meeting scheduling, and time coordination skills", + "skills.categories.calendar-scheduling.name": "Calendar & Scheduling", + "skills.categories.clawdbot-tools.description": "Skills and utilities built for the Clawdbot ecosystem", + "skills.categories.clawdbot-tools.name": "Clawdbot Tools", + "skills.categories.cli-utilities.description": "Command-line tools, shell scripting, and terminal utilities", + "skills.categories.cli-utilities.name": "CLI Utilities", + "skills.categories.coding-agents-ides.description": "Skills for coding agents, IDEs, and AI-assisted development", + "skills.categories.coding-agents-ides.name": "Coding Agents & IDEs", + "skills.categories.communication.description": "Messaging, email, chat platforms, and communication workflow skills", + "skills.categories.communication.name": "Communication", + "skills.categories.data-analytics.description": "Data analysis, visualization, and business intelligence skills", + "skills.categories.data-analytics.name": "Data & Analytics", + "skills.categories.devops-cloud.description": "DevOps pipelines, cloud infrastructure, and deployment skills", + "skills.categories.devops-cloud.name": "DevOps & Cloud", + "skills.categories.finance.description": "Finance, banking, payments, and financial data skills", + "skills.categories.finance.name": "Finance", + "skills.categories.gaming.description": "Game data, achievements, leaderboards, and gaming platform skills", + "skills.categories.gaming.name": "Gaming", + "skills.categories.git-github.description": "Git version control and GitHub platform integrations", + "skills.categories.git-github.name": "Git & GitHub", + "skills.categories.health-fitness.description": "Health tracking, fitness planning, and wellness skills", + "skills.categories.health-fitness.name": "Health & Fitness", + "skills.categories.image-video-generation.description": "AI image generation, video creation, and visual media skills", + "skills.categories.image-video-generation.name": "Image & Video Generation", + "skills.categories.ios-macos-development.description": "iOS and macOS app development, Xcode, and Swift tooling skills", + "skills.categories.ios-macos-development.name": "iOS & macOS Development", + "skills.categories.marketing-sales.description": "Marketing campaigns, sales workflows, and growth automation skills", + "skills.categories.marketing-sales.name": "Marketing & Sales", + "skills.categories.media-streaming.description": "Media playback, streaming platforms, and content delivery skills", + "skills.categories.media-streaming.name": "Media & Streaming", + "skills.categories.moltbook.description": "Moltbook platform integrations and notebook automation skills", + "skills.categories.moltbook.name": "Moltbook", + "skills.categories.notes-pkm.description": "Note-taking, personal knowledge management, and second-brain skills", + "skills.categories.notes-pkm.name": "Notes & PKM", + "skills.categories.pdf-documents.description": "PDF processing, document parsing, and file management skills", + "skills.categories.pdf-documents.name": "PDF & Documents", + "skills.categories.personal-development.description": "Personal growth, habit building, and self-improvement skills", + "skills.categories.personal-development.name": "Personal Development", + "skills.categories.productivity-tasks.description": "Task management, workflow automation, and productivity skills", + "skills.categories.productivity-tasks.name": "Productivity & Tasks", + "skills.categories.search-research.description": "Web search, data retrieval, and research automation skills", + "skills.categories.search-research.name": "Search & Research", + "skills.categories.security-passwords.description": "Security auditing, password management, and privacy protection skills", + "skills.categories.security-passwords.name": "Security & Passwords", + "skills.categories.self-hosted-automation.description": "Self-hosted services, home lab automation, and infrastructure skills", + "skills.categories.self-hosted-automation.name": "Self-Hosted & Automation", + "skills.categories.shopping-ecommerce.description": "E-commerce integrations, shopping automation, and retail skills", + "skills.categories.shopping-ecommerce.name": "Shopping & E-commerce", + "skills.categories.smart-home-iot.description": "Smart home automation, IoT device control, and home management skills", + "skills.categories.smart-home-iot.name": "Smart Home & IoT", + "skills.categories.speech-transcription.description": "Speech recognition, audio transcription, and voice interface skills", + "skills.categories.speech-transcription.name": "Speech & Transcription", + "skills.categories.transportation.description": "Transportation, logistics, routing, and mobility skills", + "skills.categories.transportation.name": "Transportation", + "skills.categories.web-frontend-development.description": "Web development, frontend frameworks, and UI tooling skills", + "skills.categories.web-frontend-development.name": "Web & Frontend Development", + "skills.details.nav.needHelp": "Need Help?", + "skills.details.nav.reportIssue": "Report Issue", + "skills.details.nav.viewSourceCode": "View Source Code", + "skills.details.overview.title": "Overview", + "skills.details.rating.title": "Ratings", + "skills.details.related.empty": "No related Skills yet", + "skills.details.related.listTitle": "Related Skills", + "skills.details.related.more": "View More", + "skills.details.related.title": "Related Skills", + "skills.details.resources.empty": "No resources available", + "skills.details.resources.table.name": "Name", + "skills.details.resources.table.size": "Size", + "skills.details.resources.title": "Resources", + "skills.details.review.title": "How to Submit a Review", + "skills.details.sidebar.agent.copied": "Prompt Copied", + "skills.details.sidebar.agent.copyPrompt": "Copy Prompt", + "skills.details.sidebar.agent.title": "Send this prompt to your Agent to install this Skill", + "skills.details.sidebar.agent.useOnLobeAI": "Use on LobeAI", + "skills.details.sidebar.description": "Description", + "skills.details.sidebar.details": "Details", + "skills.details.sidebar.directoryLayout": "Directory Layout", + "skills.details.sidebar.downloadSkill": "Download Skill", + "skills.details.sidebar.files": "File Tree", + "skills.details.sidebar.installCommand": "Install Command", + "skills.details.sidebar.installationConfig": "Installation", + "skills.details.sidebar.platform.layout.lobehub": "Skills are managed by LobeHub automatically", + "skills.details.sidebar.platform.layout.resourcesHint": "other resources", + "skills.details.sidebar.platform.steps.claude": "Run the install command in your terminal to download and configure this skill for Claude Code.", + "skills.details.sidebar.platform.steps.cline": "Run the install command in your terminal to download and configure this skill for Cline.", + "skills.details.sidebar.platform.steps.codex": "Run the install command in your terminal to download and configure this skill for Codex.", + "skills.details.sidebar.platform.steps.cursor": "Run the install command in your terminal to download and configure this skill for Cursor.", + "skills.details.sidebar.platform.steps.lobehub": "Install directly from the LobeHub marketplace with one click.", + "skills.details.sidebar.platform.steps.vscode": "Run the install command in your terminal to download and configure this skill for VS Code.", + "skills.details.sidebar.platform.title": "Install on {{platform}}", + "skills.details.sidebar.tags": "Tags", + "skills.details.summary.title": "Summary", + "skills.details.versions.empty": "No historical versions yet", + "skills.details.versions.table.isLatest": "Latest", + "skills.details.versions.table.publishAt": "Published", + "skills.details.versions.table.version": "Version", + "skills.details.versions.title": "Version History", + "skills.hero.guide.agent": "I am Agent", + "skills.hero.guide.human": "I am Human", + "skills.sorts.createdAt": "Recently Published", + "skills.sorts.installCount": "Downloads", + "skills.sorts.name": "Name", + "skills.sorts.stars": "GitHub Stars", + "skills.sorts.updatedAt": "Recently Updated", "tab.assistant": "Agent", "tab.home": "Home", "tab.model": "Model", "tab.plugin": "Skill", "tab.provider": "Provider", + "tab.skill": "Skills", "tab.user": "User", "time.formatOtherYear": "MMM D, YYYY", "time.formatThisYear": "MMM D", diff --git a/locales/zh-CN/discover.json b/locales/zh-CN/discover.json index eea326df5a..90b5e32cd3 100644 --- a/locales/zh-CN/discover.json +++ b/locales/zh-CN/discover.json @@ -477,11 +477,129 @@ "search.placeholder": "搜索名称介绍或关键词…", "search.result": "{{count}} 个关于 {{keyword}} 的搜索结果", "search.searching": "搜索中…", + "skillEmpty.description": "尝试调整筛选条件或搜索关键词", + "skillEmpty.search": "未找到匹配的技能", + "skillEmpty.title": "暂无技能", + "skills.categories.agent-to-agent-protocols.description": "代理间通信、协调和协议技能", + "skills.categories.agent-to-agent-protocols.name": "代理协议", + "skills.categories.ai-llms.description": "AI模型集成、大语言模型工具和提示词工程技能", + "skills.categories.ai-llms.name": "AI & LLMs", + "skills.categories.all.description": "全部技能", + "skills.categories.all.name": "全部", + "skills.categories.apple-apps-services.description": "苹果生态系统应用、服务和平台集成", + "skills.categories.apple-apps-services.name": "苹果应用与服务", + "skills.categories.browser-automation.description": "浏览器控制、网页抓取和UI自动化技能", + "skills.categories.browser-automation.name": "浏览器自动化", + "skills.categories.calendar-scheduling.description": "日历管理、会议安排和时间协调技能", + "skills.categories.calendar-scheduling.name": "日历与日程", + "skills.categories.clawdbot-tools.description": "为 Clawdbot 生态系统构建的技能和工具", + "skills.categories.clawdbot-tools.name": "Clawdbot 工具", + "skills.categories.cli-utilities.description": "命令行工具、Shell脚本和终端工具", + "skills.categories.cli-utilities.name": "CLI 工具", + "skills.categories.coding-agents-ides.description": "用于编程代理、IDE和AI辅助开发的技能", + "skills.categories.coding-agents-ides.name": "编程代理与IDE", + "skills.categories.communication.description": "消息传递、电子邮件、聊天平台和通信工作流技能", + "skills.categories.communication.name": "通信", + "skills.categories.data-analytics.description": "数据分析、可视化和商业智能技能", + "skills.categories.data-analytics.name": "数据分析", + "skills.categories.devops-cloud.description": "DevOps流水线、云基础设施和部署技能", + "skills.categories.devops-cloud.name": "DevOps与云", + "skills.categories.finance.description": "金融、银行、支付和财务数据技能", + "skills.categories.finance.name": "金融", + "skills.categories.gaming.description": "游戏数据、成就、排行榜和游戏平台技能", + "skills.categories.gaming.name": "游戏", + "skills.categories.git-github.description": "Git版本控制和GitHub平台集成", + "skills.categories.git-github.name": "Git与GitHub", + "skills.categories.health-fitness.description": "健康追踪、健身计划和健康技能", + "skills.categories.health-fitness.name": "健康健身", + "skills.categories.image-video-generation.description": "AI图像生成、视频创作和视觉媒体技能", + "skills.categories.image-video-generation.name": "图像与视频生成", + "skills.categories.ios-macos-development.description": "iOS和macOS应用开发、Xcode和Swift工具技能", + "skills.categories.ios-macos-development.name": "iOS与macOS开发", + "skills.categories.marketing-sales.description": "营销活动、销售工作流和增长自动化技能", + "skills.categories.marketing-sales.name": "营销与销售", + "skills.categories.media-streaming.description": "媒体播放、流媒体平台和内容分发技能", + "skills.categories.media-streaming.name": "媒体与流媒体", + "skills.categories.moltbook.description": "Moltbook平台集成和笔记本自动化技能", + "skills.categories.moltbook.name": "Moltbook", + "skills.categories.notes-pkm.description": "笔记、个人知识管理和第二大脑技能", + "skills.categories.notes-pkm.name": "笔记与知识管理", + "skills.categories.pdf-documents.description": "PDF处理、文档解析和文件管理技能", + "skills.categories.pdf-documents.name": "PDF与文档", + "skills.categories.personal-development.description": "个人成长、习惯养成和自我提升技能", + "skills.categories.personal-development.name": "个人发展", + "skills.categories.productivity-tasks.description": "任务管理、工作流自动化和生产力技能", + "skills.categories.productivity-tasks.name": "生产力与任务", + "skills.categories.search-research.description": "网页搜索、数据检索和研究自动化技能", + "skills.categories.search-research.name": "搜索与研究", + "skills.categories.security-passwords.description": "安全审计、密码管理和隐私保护技能", + "skills.categories.security-passwords.name": "安全与密码", + "skills.categories.self-hosted-automation.description": "自托管服务、家庭实验室自动化和基础设施技能", + "skills.categories.self-hosted-automation.name": "自托管与自动化", + "skills.categories.shopping-ecommerce.description": "电子商务集成、购物自动化和零售技能", + "skills.categories.shopping-ecommerce.name": "购物与电商", + "skills.categories.smart-home-iot.description": "智能家居自动化、物联网设备控制和家居管理技能", + "skills.categories.smart-home-iot.name": "智能家居与物联网", + "skills.categories.speech-transcription.description": "语音识别、音频转录和语音接口技能", + "skills.categories.speech-transcription.name": "语音与转录", + "skills.categories.transportation.description": "交通、物流、路线规划和移动技能", + "skills.categories.transportation.name": "交通运输", + "skills.categories.web-frontend-development.description": "Web开发、前端框架和UI工具技能", + "skills.categories.web-frontend-development.name": "Web与前端开发", + "skills.details.nav.needHelp": "需要帮助?", + "skills.details.nav.reportIssue": "报告问题", + "skills.details.nav.viewSourceCode": "查看源码", + "skills.details.overview.title": "概览", + "skills.details.rating.title": "评分", + "skills.details.related.empty": "暂无相关技能", + "skills.details.related.listTitle": "相关技能", + "skills.details.related.more": "查看更多", + "skills.details.related.title": "相关技能", + "skills.details.resources.empty": "暂无资源", + "skills.details.resources.table.name": "名称", + "skills.details.resources.table.size": "大小", + "skills.details.resources.title": "资源", + "skills.details.review.title": "如何提交评价", + "skills.details.sidebar.agent.copied": "已复制提示词", + "skills.details.sidebar.agent.copyPrompt": "复制提示词", + "skills.details.sidebar.agent.title": "发送此提示词给你的 Agent 以安装此技能", + "skills.details.sidebar.agent.useOnLobeAI": "在 LobeAI 上使用", + "skills.details.sidebar.description": "描述", + "skills.details.sidebar.details": "详情", + "skills.details.sidebar.directoryLayout": "目录布局", + "skills.details.sidebar.downloadSkill": "下载技能", + "skills.details.sidebar.files": "文件树", + "skills.details.sidebar.installCommand": "安装命令", + "skills.details.sidebar.installationConfig": "安装方式", + "skills.details.sidebar.platform.layout.lobehub": "技能由 LobeHub 自动管理", + "skills.details.sidebar.platform.layout.resourcesHint": "其他资源", + "skills.details.sidebar.platform.steps.claude": "在终端运行安装命令,为 Claude Code 下载并配置此技能。", + "skills.details.sidebar.platform.steps.cline": "在终端运行安装命令,为 Cline 下载并配置此技能。", + "skills.details.sidebar.platform.steps.codex": "在终端运行安装命令,为 Codex 下载并配置此技能。", + "skills.details.sidebar.platform.steps.cursor": "在终端运行安装命令,为 Cursor 下载并配置此技能。", + "skills.details.sidebar.platform.steps.lobehub": "直接从 LobeHub 市场一键安装。", + "skills.details.sidebar.platform.steps.vscode": "在终端运行安装命令,为 VS Code 下载并配置此技能。", + "skills.details.sidebar.platform.title": "在 {{platform}} 中安装", + "skills.details.sidebar.tags": "标签", + "skills.details.summary.title": "摘要", + "skills.details.versions.empty": "暂无历史版本", + "skills.details.versions.table.isLatest": "最新版本", + "skills.details.versions.table.publishAt": "发布于", + "skills.details.versions.table.version": "版本", + "skills.details.versions.title": "版本历史", + "skills.hero.guide.agent": "我是 Agent", + "skills.hero.guide.human": "我是人类", + "skills.sorts.createdAt": "最近发布", + "skills.sorts.installCount": "最多下载", + "skills.sorts.name": "名称", + "skills.sorts.stars": "GitHub 星标", + "skills.sorts.updatedAt": "最近更新", "tab.assistant": "助理", "tab.home": "首页", "tab.model": "模型", "tab.plugin": "技能", "tab.provider": "模型服务商", + "tab.skill": "Skills", "tab.user": "用户", "time.formatOtherYear": "YYYY年M月D日", "time.formatThisYear": "M月D日", diff --git a/packages/types/src/discover/index.ts b/packages/types/src/discover/index.ts index 23a5aeb7cc..6d67077b78 100644 --- a/packages/types/src/discover/index.ts +++ b/packages/types/src/discover/index.ts @@ -8,6 +8,7 @@ export * from './mcp'; export * from './models'; export * from './plugins'; export * from './providers'; +export * from './skills'; export enum DiscoverTab { Assistants = 'agent', @@ -17,6 +18,7 @@ export enum DiscoverTab { Models = 'model', Plugins = 'plugin', Providers = 'provider', + Skills = 'skill', User = 'user', } @@ -32,6 +34,7 @@ export enum CacheTag { Models = 'models', Plugins = 'plugins', Providers = 'providers', + Skills = 'skills', } export enum CacheRevalidate { diff --git a/packages/types/src/discover/skills.ts b/packages/types/src/discover/skills.ts new file mode 100644 index 0000000000..6ff5d4e33a --- /dev/null +++ b/packages/types/src/discover/skills.ts @@ -0,0 +1,96 @@ +import type { + MarketSkillCategory, + MarketSkillDetail, + MarketSkillListItem, + MarketSkillListResponse, + SkillCommentListResponse, + SkillRatingDistribution, +} from '@lobehub/market-sdk'; + +export enum SkillCategory { + AgentToAgentProtocols = 'agent-to-agent-protocols', + AILLMs = 'ai-llms', + All = 'all', + AppleAppsServices = 'apple-apps-services', + BrowserAutomation = 'browser-automation', + CalendarScheduling = 'calendar-scheduling', + ClawdbotTools = 'clawdbot-tools', + CLIUtilities = 'cli-utilities', + CodingAgentsIDEs = 'coding-agents-ides', + Communication = 'communication', + DataAnalytics = 'data-analytics', + DevOpsCloud = 'devops-cloud', + Finance = 'finance', + Gaming = 'gaming', + GitGitHub = 'git-github', + HealthFitness = 'health-fitness', + ImageVideoGeneration = 'image-video-generation', + IOSMacOSDevelopment = 'ios-macos-development', + MarketingSales = 'marketing-sales', + MediaStreaming = 'media-streaming', + Moltbook = 'moltbook', + NotesPKM = 'notes-pkm', + PDFDocuments = 'pdf-documents', + PersonalDevelopment = 'personal-development', + ProductivityTasks = 'productivity-tasks', + SearchResearch = 'search-research', + SecurityPasswords = 'security-passwords', + SelfHostedAutomation = 'self-hosted-automation', + ShoppingEcommerce = 'shopping-ecommerce', + SmartHomeIoT = 'smart-home-iot', + SpeechTranscription = 'speech-transcription', + Transportation = 'transportation', + WebFrontendDevelopment = 'web-frontend-development', +} + +export enum SkillSorts { + CreatedAt = 'createdAt', + InstallCount = 'installCount', + Name = 'name', + Relevance = 'relevance', + Stars = 'stars', + UpdatedAt = 'updatedAt', +} + +export enum SkillNavKey { + Installation = 'installation', + Overview = 'overview', + Related = 'related', + Resources = 'resources', + Skill = 'skill', + Version = 'version', +} + +export interface DiscoverSkillItem extends Omit { + commentCount?: number; + homepage?: string; + ratingAvg?: number; +} + +export interface SkillQueryParams { + category?: string; + locale?: string; + order?: 'asc' | 'desc'; + page?: number; + pageSize?: number; + q?: string; + sort?: SkillSorts; +} + +export interface SkillListResponse extends MarketSkillListResponse { + categories?: SkillCategoryItem[]; +} + +export interface DiscoverSkillDetail extends MarketSkillDetail { + comments?: SkillCommentListResponse; + downloadUrl?: string; + github?: { + stars?: number; + url?: string; + }; + homepage?: string; + ratingDistribution?: SkillRatingDistribution; + related?: DiscoverSkillItem[]; +} + +export type SkillCategoryItem = MarketSkillCategory; diff --git a/src/hooks/useSkillCategory.tsx b/src/hooks/useSkillCategory.tsx new file mode 100644 index 0000000000..6adfa4d09e --- /dev/null +++ b/src/hooks/useSkillCategory.tsx @@ -0,0 +1,253 @@ +import { + AppleIcon, + BarChart2Icon, + BookIcon, + BookOpenIcon, + BotIcon, + BrainIcon, + CalendarIcon, + CheckSquareIcon, + CloudIcon, + DollarSignIcon, + FileTextIcon, + GamepadIcon, + GitBranchIcon, + GlobeIcon, + HeartIcon, + HomeIcon, + ImageIcon, + LayoutPanelTopIcon, + MegaphoneIcon, + MessageCircleIcon, + MicIcon, + MonitorIcon, + NetworkIcon, + PlayIcon, + SearchIcon, + ServerIcon, + ShieldIcon, + ShoppingCartIcon, + SmartphoneIcon, + TerminalIcon, + TruckIcon, + UserIcon, + WrenchIcon, +} from 'lucide-react'; +import { useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { SkillCategory } from '@/types/discover'; + +export const useSkillCategory = () => { + const { t } = useTranslation('discover'); + return useMemo( + () => [ + { + icon: LayoutPanelTopIcon, + key: SkillCategory.All, + label: t('skills.categories.all.name'), + title: t('skills.categories.all.description'), + }, + // Sorted by category count (descending) + { + icon: BotIcon, + key: SkillCategory.CodingAgentsIDEs, + label: t('skills.categories.coding-agents-ides.name'), + title: t('skills.categories.coding-agents-ides.description'), + }, + { + icon: MonitorIcon, + key: SkillCategory.WebFrontendDevelopment, + label: t('skills.categories.web-frontend-development.name'), + title: t('skills.categories.web-frontend-development.description'), + }, + { + icon: CloudIcon, + key: SkillCategory.DevOpsCloud, + label: t('skills.categories.devops-cloud.name'), + title: t('skills.categories.devops-cloud.description'), + }, + { + icon: SearchIcon, + key: SkillCategory.SearchResearch, + label: t('skills.categories.search-research.name'), + title: t('skills.categories.search-research.description'), + }, + { + icon: GlobeIcon, + key: SkillCategory.BrowserAutomation, + label: t('skills.categories.browser-automation.name'), + title: t('skills.categories.browser-automation.description'), + }, + { + icon: CheckSquareIcon, + key: SkillCategory.ProductivityTasks, + label: t('skills.categories.productivity-tasks.name'), + title: t('skills.categories.productivity-tasks.description'), + }, + { + icon: BrainIcon, + key: SkillCategory.AILLMs, + label: t('skills.categories.ai-llms.name'), + title: t('skills.categories.ai-llms.description'), + }, + { + icon: TerminalIcon, + key: SkillCategory.CLIUtilities, + label: t('skills.categories.cli-utilities.name'), + title: t('skills.categories.cli-utilities.description'), + }, + { + icon: GitBranchIcon, + key: SkillCategory.GitGitHub, + label: t('skills.categories.git-github.name'), + title: t('skills.categories.git-github.description'), + }, + { + icon: ImageIcon, + key: SkillCategory.ImageVideoGeneration, + label: t('skills.categories.image-video-generation.name'), + title: t('skills.categories.image-video-generation.description'), + }, + { + icon: MessageCircleIcon, + key: SkillCategory.Communication, + label: t('skills.categories.communication.name'), + title: t('skills.categories.communication.description'), + }, + { + icon: TruckIcon, + key: SkillCategory.Transportation, + label: t('skills.categories.transportation.name'), + title: t('skills.categories.transportation.description'), + }, + { + icon: FileTextIcon, + key: SkillCategory.PDFDocuments, + label: t('skills.categories.pdf-documents.name'), + title: t('skills.categories.pdf-documents.description'), + }, + { + icon: MegaphoneIcon, + key: SkillCategory.MarketingSales, + label: t('skills.categories.marketing-sales.name'), + title: t('skills.categories.marketing-sales.description'), + }, + { + icon: HeartIcon, + key: SkillCategory.HealthFitness, + label: t('skills.categories.health-fitness.name'), + title: t('skills.categories.health-fitness.description'), + }, + { + icon: PlayIcon, + key: SkillCategory.MediaStreaming, + label: t('skills.categories.media-streaming.name'), + title: t('skills.categories.media-streaming.description'), + }, + { + icon: BookOpenIcon, + key: SkillCategory.NotesPKM, + label: t('skills.categories.notes-pkm.name'), + title: t('skills.categories.notes-pkm.description'), + }, + { + icon: CalendarIcon, + key: SkillCategory.CalendarScheduling, + label: t('skills.categories.calendar-scheduling.name'), + title: t('skills.categories.calendar-scheduling.description'), + }, + { + icon: ShoppingCartIcon, + key: SkillCategory.ShoppingEcommerce, + label: t('skills.categories.shopping-ecommerce.name'), + title: t('skills.categories.shopping-ecommerce.description'), + }, + { + icon: ShieldIcon, + key: SkillCategory.SecurityPasswords, + label: t('skills.categories.security-passwords.name'), + title: t('skills.categories.security-passwords.description'), + }, + { + icon: UserIcon, + key: SkillCategory.PersonalDevelopment, + label: t('skills.categories.personal-development.name'), + title: t('skills.categories.personal-development.description'), + }, + { + icon: MicIcon, + key: SkillCategory.SpeechTranscription, + label: t('skills.categories.speech-transcription.name'), + title: t('skills.categories.speech-transcription.description'), + }, + { + icon: AppleIcon, + key: SkillCategory.AppleAppsServices, + label: t('skills.categories.apple-apps-services.name'), + title: t('skills.categories.apple-apps-services.description'), + }, + { + icon: HomeIcon, + key: SkillCategory.SmartHomeIoT, + label: t('skills.categories.smart-home-iot.name'), + title: t('skills.categories.smart-home-iot.description'), + }, + { + icon: GamepadIcon, + key: SkillCategory.Gaming, + label: t('skills.categories.gaming.name'), + title: t('skills.categories.gaming.description'), + }, + { + icon: WrenchIcon, + key: SkillCategory.ClawdbotTools, + label: t('skills.categories.clawdbot-tools.name'), + title: t('skills.categories.clawdbot-tools.description'), + }, + { + icon: ServerIcon, + key: SkillCategory.SelfHostedAutomation, + label: t('skills.categories.self-hosted-automation.name'), + title: t('skills.categories.self-hosted-automation.description'), + }, + { + icon: SmartphoneIcon, + key: SkillCategory.IOSMacOSDevelopment, + label: t('skills.categories.ios-macos-development.name'), + title: t('skills.categories.ios-macos-development.description'), + }, + { + icon: BookIcon, + key: SkillCategory.Moltbook, + label: t('skills.categories.moltbook.name'), + title: t('skills.categories.moltbook.description'), + }, + { + icon: BarChart2Icon, + key: SkillCategory.DataAnalytics, + label: t('skills.categories.data-analytics.name'), + title: t('skills.categories.data-analytics.description'), + }, + { + icon: DollarSignIcon, + key: SkillCategory.Finance, + label: t('skills.categories.finance.name'), + title: t('skills.categories.finance.description'), + }, + { + icon: NetworkIcon, + key: SkillCategory.AgentToAgentProtocols, + label: t('skills.categories.agent-to-agent-protocols.name'), + title: t('skills.categories.agent-to-agent-protocols.description'), + }, + ], + [t], + ); +}; + +export const useSkillCategoryItem = (key?: string) => { + const items = useSkillCategory(); + if (!key) return; + return items.find((item) => item.key === key); +}; diff --git a/src/locales/default/discover.ts b/src/locales/default/discover.ts index d9c1e15e1d..5901ec224a 100644 --- a/src/locales/default/discover.ts +++ b/src/locales/default/discover.ts @@ -865,6 +865,244 @@ export default { 'search.searching': 'Searching...', + 'skillEmpty.description': 'Try adjusting filters or searching with different keywords.', + + 'skillEmpty.search': 'No matching Skills found', + + 'skillEmpty.title': 'No Skills found', + + 'skills.categories.agent-to-agent-protocols.description': + 'Inter-agent communication, orchestration, and protocol skills', + 'skills.categories.agent-to-agent-protocols.name': 'Agent-to-Agent Protocols', + + 'skills.categories.ai-llms.description': + 'AI model integrations, LLM tooling, and prompt engineering skills', + 'skills.categories.ai-llms.name': 'AI & LLMs', + + 'skills.categories.all.description': 'All Skills', + 'skills.categories.all.name': 'All', + + 'skills.categories.apple-apps-services.description': + 'Apple ecosystem apps, services, and platform integrations', + 'skills.categories.apple-apps-services.name': 'Apple Apps & Services', + + 'skills.categories.browser-automation.description': + 'Browser control, web scraping, and UI automation skills', + 'skills.categories.browser-automation.name': 'Browser & Automation', + + 'skills.categories.calendar-scheduling.description': + 'Calendar management, meeting scheduling, and time coordination skills', + 'skills.categories.calendar-scheduling.name': 'Calendar & Scheduling', + + 'skills.categories.clawdbot-tools.description': + 'Skills and utilities built for the Clawdbot ecosystem', + 'skills.categories.clawdbot-tools.name': 'Clawdbot Tools', + + 'skills.categories.cli-utilities.description': + 'Command-line tools, shell scripting, and terminal utilities', + 'skills.categories.cli-utilities.name': 'CLI Utilities', + + 'skills.categories.coding-agents-ides.description': + 'Skills for coding agents, IDEs, and AI-assisted development', + 'skills.categories.coding-agents-ides.name': 'Coding Agents & IDEs', + + 'skills.categories.communication.description': + 'Messaging, email, chat platforms, and communication workflow skills', + 'skills.categories.communication.name': 'Communication', + + 'skills.categories.data-analytics.description': + 'Data analysis, visualization, and business intelligence skills', + 'skills.categories.data-analytics.name': 'Data & Analytics', + + 'skills.categories.devops-cloud.description': + 'DevOps pipelines, cloud infrastructure, and deployment skills', + 'skills.categories.devops-cloud.name': 'DevOps & Cloud', + + 'skills.categories.finance.description': 'Finance, banking, payments, and financial data skills', + 'skills.categories.finance.name': 'Finance', + + 'skills.categories.gaming.description': + 'Game data, achievements, leaderboards, and gaming platform skills', + 'skills.categories.gaming.name': 'Gaming', + + 'skills.categories.git-github.description': + 'Git version control and GitHub platform integrations', + 'skills.categories.git-github.name': 'Git & GitHub', + + 'skills.categories.health-fitness.description': + 'Health tracking, fitness planning, and wellness skills', + 'skills.categories.health-fitness.name': 'Health & Fitness', + + 'skills.categories.image-video-generation.description': + 'AI image generation, video creation, and visual media skills', + 'skills.categories.image-video-generation.name': 'Image & Video Generation', + + 'skills.categories.ios-macos-development.description': + 'iOS and macOS app development, Xcode, and Swift tooling skills', + 'skills.categories.ios-macos-development.name': 'iOS & macOS Development', + + 'skills.categories.marketing-sales.description': + 'Marketing campaigns, sales workflows, and growth automation skills', + 'skills.categories.marketing-sales.name': 'Marketing & Sales', + + 'skills.categories.media-streaming.description': + 'Media playback, streaming platforms, and content delivery skills', + 'skills.categories.media-streaming.name': 'Media & Streaming', + + 'skills.categories.moltbook.description': + 'Moltbook platform integrations and notebook automation skills', + 'skills.categories.moltbook.name': 'Moltbook', + + 'skills.categories.notes-pkm.description': + 'Note-taking, personal knowledge management, and second-brain skills', + 'skills.categories.notes-pkm.name': 'Notes & PKM', + + 'skills.categories.pdf-documents.description': + 'PDF processing, document parsing, and file management skills', + 'skills.categories.pdf-documents.name': 'PDF & Documents', + + 'skills.categories.personal-development.description': + 'Personal growth, habit building, and self-improvement skills', + 'skills.categories.personal-development.name': 'Personal Development', + + 'skills.categories.productivity-tasks.description': + 'Task management, workflow automation, and productivity skills', + 'skills.categories.productivity-tasks.name': 'Productivity & Tasks', + + 'skills.categories.search-research.description': + 'Web search, data retrieval, and research automation skills', + 'skills.categories.search-research.name': 'Search & Research', + + 'skills.categories.security-passwords.description': + 'Security auditing, password management, and privacy protection skills', + 'skills.categories.security-passwords.name': 'Security & Passwords', + + 'skills.categories.self-hosted-automation.description': + 'Self-hosted services, home lab automation, and infrastructure skills', + 'skills.categories.self-hosted-automation.name': 'Self-Hosted & Automation', + + 'skills.categories.shopping-ecommerce.description': + 'E-commerce integrations, shopping automation, and retail skills', + 'skills.categories.shopping-ecommerce.name': 'Shopping & E-commerce', + + 'skills.categories.smart-home-iot.description': + 'Smart home automation, IoT device control, and home management skills', + 'skills.categories.smart-home-iot.name': 'Smart Home & IoT', + + 'skills.categories.speech-transcription.description': + 'Speech recognition, audio transcription, and voice interface skills', + 'skills.categories.speech-transcription.name': 'Speech & Transcription', + + 'skills.categories.transportation.description': + 'Transportation, logistics, routing, and mobility skills', + 'skills.categories.transportation.name': 'Transportation', + + 'skills.categories.web-frontend-development.description': + 'Web development, frontend frameworks, and UI tooling skills', + 'skills.categories.web-frontend-development.name': 'Web & Frontend Development', + + 'skills.details.nav.needHelp': 'Need Help?', + + 'skills.details.nav.reportIssue': 'Report Issue', + + 'skills.details.nav.viewSourceCode': 'View Source Code', + + 'skills.details.overview.title': 'Overview', + + 'skills.details.rating.title': 'Ratings', + + 'skills.details.related.empty': 'No related Skills yet', + + 'skills.details.related.listTitle': 'Related Skills', + + 'skills.details.related.more': 'View More', + + 'skills.details.related.title': 'Related Skills', + + 'skills.details.resources.empty': 'No resources available', + + 'skills.details.resources.table.name': 'Name', + + 'skills.details.resources.table.size': 'Size', + + 'skills.details.resources.title': 'Resources', + + 'skills.details.review.title': 'How to Submit a Review', + + 'skills.details.sidebar.agent.copied': 'Prompt Copied', + + 'skills.details.sidebar.agent.copyPrompt': 'Copy Prompt', + + 'skills.details.sidebar.agent.title': 'Send this prompt to your Agent to install this Skill', + + 'skills.details.sidebar.agent.useOnLobeAI': 'Use on LobeAI', + + 'skills.details.sidebar.description': 'Description', + + 'skills.details.sidebar.details': 'Details', + + 'skills.details.sidebar.directoryLayout': 'Directory Layout', + + 'skills.details.sidebar.downloadSkill': 'Download Skill', + + 'skills.details.sidebar.files': 'File Tree', + + 'skills.details.sidebar.installationConfig': 'Installation', + + 'skills.details.sidebar.installCommand': 'Install Command', + + 'skills.details.sidebar.platform.layout.lobehub': 'Skills are managed by LobeHub automatically', + + 'skills.details.sidebar.platform.layout.resourcesHint': 'other resources', + + 'skills.details.sidebar.platform.steps.claude': + 'Run the install command in your terminal to download and configure this skill for Claude Code.', + + 'skills.details.sidebar.platform.steps.cline': + 'Run the install command in your terminal to download and configure this skill for Cline.', + + 'skills.details.sidebar.platform.steps.codex': + 'Run the install command in your terminal to download and configure this skill for Codex.', + + 'skills.details.sidebar.platform.steps.cursor': + 'Run the install command in your terminal to download and configure this skill for Cursor.', + + 'skills.details.sidebar.platform.steps.lobehub': + 'Install directly from the LobeHub marketplace with one click.', + + 'skills.details.sidebar.platform.steps.vscode': + 'Run the install command in your terminal to download and configure this skill for VS Code.', + + 'skills.details.sidebar.platform.title': 'Install on {{platform}}', + + 'skills.details.sidebar.tags': 'Tags', + + 'skills.details.summary.title': 'Summary', + + 'skills.details.versions.empty': 'No historical versions yet', + + 'skills.details.versions.table.isLatest': 'Latest', + + 'skills.details.versions.table.publishAt': 'Published', + + 'skills.details.versions.table.version': 'Version', + + 'skills.details.versions.title': 'Version History', + + 'skills.hero.guide.agent': 'I am Agent', + + 'skills.hero.guide.human': 'I am Human', + + 'skills.sorts.createdAt': 'Recently Published', + + 'skills.sorts.installCount': 'Downloads', + + 'skills.sorts.name': 'Name', + + 'skills.sorts.stars': 'GitHub Stars', + + 'skills.sorts.updatedAt': 'Recently Updated', + 'tab.assistant': 'Agent', 'tab.home': 'Home', @@ -875,6 +1113,8 @@ export default { 'tab.provider': 'Provider', + 'tab.skill': 'Skills', + 'tab.user': 'User', 'user.agents': 'Agents', diff --git a/src/routes/(main)/community/(detail)/skill/features/DetailProvider.tsx b/src/routes/(main)/community/(detail)/skill/features/DetailProvider.tsx new file mode 100644 index 0000000000..3a39ef5bd8 --- /dev/null +++ b/src/routes/(main)/community/(detail)/skill/features/DetailProvider.tsx @@ -0,0 +1,19 @@ +'use client'; + +import { createContext, memo, type ReactNode, use } from 'react'; + +import { type DiscoverSkillDetail } from '@/types/discover'; + +export type DetailContextConfig = Partial; + +export const DetailContext = createContext({}); + +export const DetailProvider = memo<{ children: ReactNode; config?: DetailContextConfig }>( + ({ children, config = {} }) => { + return {children}; + }, +); + +export const useDetailContext = () => { + return use(DetailContext); +}; diff --git a/src/routes/(main)/community/(detail)/skill/features/Details/Installation/index.tsx b/src/routes/(main)/community/(detail)/skill/features/Details/Installation/index.tsx new file mode 100644 index 0000000000..56a2a71f72 --- /dev/null +++ b/src/routes/(main)/community/(detail)/skill/features/Details/Installation/index.tsx @@ -0,0 +1,21 @@ +'use client'; + +import { memo } from 'react'; + +import { useDetailContext } from '../../DetailProvider'; +import Platform from '../../Sidebar/Platform'; + +const Installation = memo<{ mobile?: boolean }>(({ mobile }) => { + const { identifier, downloadUrl } = useDetailContext(); + + return ( + + ); +}); + +export default Installation; diff --git a/src/routes/(main)/community/(detail)/skill/features/Details/Nav.tsx b/src/routes/(main)/community/(detail)/skill/features/Details/Nav.tsx new file mode 100644 index 0000000000..cccfdf4564 --- /dev/null +++ b/src/routes/(main)/community/(detail)/skill/features/Details/Nav.tsx @@ -0,0 +1,144 @@ +'use client'; + +import { Flexbox, Icon, Tabs, Tag } from '@lobehub/ui'; +import { SkillsIcon } from '@lobehub/ui/icons'; +import { createStaticStyles } from 'antd-style'; +import { BookOpenIcon, DownloadIcon, FileTextIcon, HistoryIcon, ListIcon } from 'lucide-react'; +import { memo } from 'react'; +import { useTranslation } from 'react-i18next'; +import urlJoin from 'url-join'; + +import { useDetailContext } from '../DetailProvider'; +import { SkillNavKey } from '../types'; + +export const styles = createStaticStyles(({ css, cssVar }) => ({ + link: css` + color: ${cssVar.colorTextDescription}; + + &:hover { + color: ${cssVar.colorInfo}; + } + `, + nav: css` + border-block-end: 1px solid ${cssVar.colorBorder}; + `, +})); + +const Nav = memo<{ + activeTab?: SkillNavKey; + mobile?: boolean; + setActiveTab?: (_tab: SkillNavKey) => void; +}>(({ mobile, setActiveTab, activeTab = SkillNavKey.Overview }) => { + const { t } = useTranslation('discover'); + const { versions, repository, homepage, github, resources } = useDetailContext(); + + const versionCount = versions?.length || 0; + const resourcesCount = Object.keys(resources || {}).length; + const source = homepage || repository; + const issueTarget = github?.url || repository; + + const nav = ( + , + key: SkillNavKey.Overview, + label: t('skills.details.overview.title'), + }, + { + icon: , + key: SkillNavKey.Installation, + label: t('skills.details.sidebar.installationConfig'), + }, + { + icon: , + key: SkillNavKey.Skill, + label: 'SKILL.md', + }, + { + icon: , + key: SkillNavKey.Resources, + label: + resourcesCount > 1 ? ( + + {t('skills.details.resources.title')} + {resourcesCount} + + ) : ( + t('skills.details.resources.title') + ), + }, + { + icon: , + key: SkillNavKey.Related, + label: t('skills.details.related.title'), + }, + { + icon: , + key: SkillNavKey.Version, + label: + versionCount > 1 ? ( + + {t('skills.details.versions.title')} + {versionCount} + + ) : ( + t('skills.details.versions.title') + ), + }, + ]} + onChange={(key) => setActiveTab?.(key as SkillNavKey)} + /> + ); + + return mobile ? ( + nav + ) : ( + + {nav} + + + {t('skills.details.nav.needHelp')} + + {source && ( + + {t('skills.details.nav.viewSourceCode')} + + )} + {issueTarget && ( + + {t('skills.details.nav.reportIssue')} + + )} + + + ); +}); + +export default Nav; diff --git a/src/routes/(main)/community/(detail)/skill/features/Details/Overview/index.tsx b/src/routes/(main)/community/(detail)/skill/features/Details/Overview/index.tsx new file mode 100644 index 0000000000..71c8f24e8b --- /dev/null +++ b/src/routes/(main)/community/(detail)/skill/features/Details/Overview/index.tsx @@ -0,0 +1,68 @@ +'use client'; + +import { Collapse, Flexbox, Markdown, ScrollShadow, Tag } from '@lobehub/ui'; +import qs from 'query-string'; +import { memo, type PropsWithChildren } from 'react'; +import { useTranslation } from 'react-i18next'; + +import List from '../../../../../(list)/skill/features/List'; +import Title from '../../../../../components/Title'; +import { useDetailContext } from '../../DetailProvider'; + +const Overview = memo(({ children }) => { + const { t } = useTranslation('discover'); + const { tags = [], description, overview, category, related } = useDetailContext(); + + return ( + + + {t('skills.details.summary.title')} + {overview?.summary || description || ''} + + + + {children} + + + ), + key: 'summary', + label: 'SKILL.md', + }, + ]} + padding={{ + body: 0, + }} + /> + {tags.length > 0 && ( + + {tags.map((tag) => ( + {tag} + ))} + + )} + {related && related.length > 0 && ( + + + {t('skills.details.related.listTitle')} + + + + )} + + ); +}); + +export default Overview; diff --git a/src/routes/(main)/community/(detail)/skill/features/Details/Related/index.tsx b/src/routes/(main)/community/(detail)/skill/features/Details/Related/index.tsx new file mode 100644 index 0000000000..034009bb99 --- /dev/null +++ b/src/routes/(main)/community/(detail)/skill/features/Details/Related/index.tsx @@ -0,0 +1,32 @@ +'use client'; + +import { Flexbox } from '@lobehub/ui'; +import qs from 'query-string'; +import { memo } from 'react'; +import { useTranslation } from 'react-i18next'; + +import List from '../../../../../(list)/skill/features/List'; +import Title from '../../../../../components/Title'; +import { useDetailContext } from '../../DetailProvider'; + +const Related = memo(() => { + const { t } = useTranslation('discover'); + const { related, category } = useDetailContext(); + + return ( + + + {t('skills.details.related.listTitle')} + + + + ); +}); + +export default Related; diff --git a/src/routes/(main)/community/(detail)/skill/features/Details/Resources/index.tsx b/src/routes/(main)/community/(detail)/skill/features/Details/Resources/index.tsx new file mode 100644 index 0000000000..789a58f390 --- /dev/null +++ b/src/routes/(main)/community/(detail)/skill/features/Details/Resources/index.tsx @@ -0,0 +1,123 @@ +'use client'; + +import { Block, Empty, Flexbox, MaterialFileTypeIcon, Text } from '@lobehub/ui'; +import { memo, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; +import urlJoin from 'url-join'; + +import InlineTable from '@/components/InlineTable'; + +import { useDetailContext } from '../../DetailProvider'; + +type ResourceMeta = { + fileHash?: string; + size?: number; +}; + +type ResourceItem = ResourceMeta & { + name: string; +}; + +const Resources = memo(() => { + const { t } = useTranslation('discover'); + const { resources, github, homepage, repository } = useDetailContext(); + const repoUrl = homepage || github?.url || repository; + + const dataSource = useMemo(() => { + return Object.entries((resources || {}) as Record) + .map(([name, meta]) => ({ + fileHash: meta?.fileHash, + name, + size: meta?.size, + })) + .sort((a, b) => a.name.localeCompare(b.name)); + }, [resources]); + + const getResourceLink = (filePath: string) => { + if (!repoUrl) return; + const encodedPath = filePath + .split('/') + .filter(Boolean) + .map((segment) => encodeURIComponent(segment)) + .join('/'); + return urlJoin(repoUrl, encodedPath); + }; + + if (dataSource.length === 0) { + return ( + + + + ); + } + + return ( + + { + const link = getResourceLink(text); + const node = ( + + + + {text} + + + ); + if (!link) { + return node; + } + + return ( + + {node} + + ); + }, + title: t('skills.details.resources.table.name'), + }, + { + align: 'end', + dataIndex: 'size', + key: 'size', + render: (value) => { + let size; + + if (typeof value !== 'number') { + size = '--'; + } else if (value < 1024) { + size = value + 'B'; + } else if (value < 1024 * 1024) { + size = (value / 1024).toFixed(2) + 'KB'; + } else { + size = (value / (1024 * 1024)).toFixed(2) + 'MB'; + } + + return ( + + {size} + + ); + }, + title: t('skills.details.resources.table.size'), + }, + ]} + /> + + ); +}); + +export default Resources; diff --git a/src/routes/(main)/community/(detail)/skill/features/Details/Versions/index.tsx b/src/routes/(main)/community/(detail)/skill/features/Details/Versions/index.tsx new file mode 100644 index 0000000000..c42a48e411 --- /dev/null +++ b/src/routes/(main)/community/(detail)/skill/features/Details/Versions/index.tsx @@ -0,0 +1,64 @@ +'use client'; + +import { Block, Flexbox, Tag } from '@lobehub/ui'; +import qs from 'query-string'; +import { memo } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Link, useLocation } from 'react-router-dom'; + +import InlineTable from '@/components/InlineTable'; +import PublishedTime from '@/components/PublishedTime'; + +import Title from '../../../../../components/Title'; +import { useDetailContext } from '../../DetailProvider'; + +const Versions = memo(() => { + const { t } = useTranslation('discover'); + const { versions = [] } = useDetailContext(); + const { pathname } = useLocation(); + + return ( + + {t('skills.details.versions.title')} + + ( + + + {record.version} + {record.isLatest && ( + {t('skills.details.versions.table.isLatest')} + )} + + + ), + title: t('skills.details.versions.table.version'), + }, + { + align: 'end', + dataIndex: 'createdAt', + render: (_, record) => , + title: t('skills.details.versions.table.publishAt'), + }, + ]} + dataSource={versions} + rowKey={'version'} + size={'middle'} + /> + + + ); +}); + +export default Versions; diff --git a/src/routes/(main)/community/(detail)/skill/features/Details/index.tsx b/src/routes/(main)/community/(detail)/skill/features/Details/index.tsx new file mode 100644 index 0000000000..47fa1f43cd --- /dev/null +++ b/src/routes/(main)/community/(detail)/skill/features/Details/index.tsx @@ -0,0 +1,57 @@ +'use client'; + +import { Flexbox, Markdown } from '@lobehub/ui'; +import { memo, useState } from 'react'; +import { useSearchParams } from 'react-router-dom'; + +import { useDetailContext } from '../DetailProvider'; +import Sidebar from '../Sidebar'; +import { SkillNavKey } from '../types'; +import Installation from './Installation'; +import Nav from './Nav'; +import Overview from './Overview'; +import Related from './Related'; +import Resources from './Resources'; +import Versions from './Versions'; + +const Details = memo<{ mobile?: boolean }>(({ mobile: isMobile }) => { + const [searchParams, setSearchParams] = useSearchParams(); + const activeTabParam = searchParams.get('activeTab') as SkillNavKey | null; + const [activeTab, setActiveTab] = useState(activeTabParam || SkillNavKey.Overview); + const { content } = useDetailContext(); + + const handleSetActiveTab = (tab: SkillNavKey) => { + setActiveTab(tab); + if (tab === SkillNavKey.Overview) { + searchParams.delete('activeTab'); + } else { + searchParams.set('activeTab', tab); + } + setSearchParams(searchParams, { replace: true }); + }; + + const skillContent = {content ?? ''}; + + return ( + +