'use client'; import React, { useEffect, useState, useCallback } from 'react'; import { Store, RefreshCw, Loader2, AlertCircle, Plus, Trash2, Download, Check, X, Globe, FolderOpen, } from 'lucide-react'; import { listMarketplaces, addMarketplace, removeMarketplace, updateMarketplace, listMarketplacePlugins, installMarketplacePlugin, uninstallPlugin, } from '@/lib/api'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Input } from '@/components/ui/input'; import type { Marketplace, MarketplacePlugin } from '@/types'; import { pickAppText } from '@/lib/i18n/core'; import { useAppI18n } from '@/lib/i18n/provider'; export default function MarketplacePage() { const { locale } = useAppI18n(); const [marketplaces, setMarketplaces] = useState([]); const [selectedMarketplace, setSelectedMarketplace] = useState(null); const [plugins, setPlugins] = useState([]); const [loading, setLoading] = useState(true); const [pluginsLoading, setPluginsLoading] = useState(false); const [error, setError] = useState(null); const [showAddForm, setShowAddForm] = useState(false); const [addSource, setAddSource] = useState(''); const [adding, setAdding] = useState(false); const [actionPlugin, setActionPlugin] = useState(null); const [updatingMarketplace, setUpdatingMarketplace] = useState(null); const loadMarketplaces = useCallback(async () => { setLoading(true); setError(null); try { const data = await listMarketplaces(); const list = Array.isArray(data) ? data : []; setMarketplaces(list); // Auto-select first marketplace if none selected or selected was removed if (list.length > 0) { setSelectedMarketplace((prev) => { if (prev && list.some((m) => m.name === prev)) return prev; return list[0].name; }); } else { setSelectedMarketplace(null); setPlugins([]); } } catch (err: any) { setError(err.message || pickAppText(locale, '加载市场失败', 'Failed to load marketplaces')); } finally { setLoading(false); } }, []); const loadPlugins = useCallback(async (marketplaceName: string) => { setPluginsLoading(true); try { const data = await listMarketplacePlugins(marketplaceName); setPlugins(Array.isArray(data) ? data : []); } catch (err: any) { setError(err.message || pickAppText(locale, '加载插件失败', 'Failed to load plugins')); } finally { setPluginsLoading(false); } }, []); useEffect(() => { loadMarketplaces(); }, [loadMarketplaces]); useEffect(() => { if (selectedMarketplace) { loadPlugins(selectedMarketplace); } }, [selectedMarketplace, loadPlugins]); const handleAdd = async () => { if (!addSource.trim()) return; setAdding(true); setError(null); try { const marketplace = await addMarketplace(addSource.trim()); setAddSource(''); setShowAddForm(false); await loadMarketplaces(); setSelectedMarketplace(marketplace.name); } catch (err: any) { setError(err.message || pickAppText(locale, '添加市场失败', 'Failed to add the marketplace')); } finally { setAdding(false); } }; const handleRemove = async (name: string) => { setError(null); try { await removeMarketplace(name); if (selectedMarketplace === name) { setSelectedMarketplace(null); setPlugins([]); } await loadMarketplaces(); } catch (err: any) { setError(err.message || pickAppText(locale, '移除市场失败', 'Failed to remove the marketplace')); } }; const handleUpdateMarketplace = async (name: string) => { setUpdatingMarketplace(name); setError(null); try { await updateMarketplace(name); await loadPlugins(name); } catch (err: any) { setError(err.message || pickAppText(locale, '更新市场失败', 'Failed to update the marketplace')); } finally { setUpdatingMarketplace(null); } }; const handleUpdatePlugin = async (marketplaceName: string, pluginName: string) => { setActionPlugin(pluginName); setError(null); try { await installMarketplacePlugin(marketplaceName, pluginName); await loadPlugins(marketplaceName); } catch (err: any) { setError(err.message || pickAppText(locale, '更新插件失败', 'Failed to update the plugin')); } finally { setActionPlugin(null); } }; const handleInstall = async (marketplaceName: string, pluginName: string) => { setActionPlugin(pluginName); setError(null); try { await installMarketplacePlugin(marketplaceName, pluginName); await loadPlugins(marketplaceName); } catch (err: any) { setError(err.message || pickAppText(locale, '安装插件失败', 'Failed to install the plugin')); } finally { setActionPlugin(null); } }; const handleUninstall = async (pluginName: string) => { setActionPlugin(pluginName); setError(null); try { await uninstallPlugin(pluginName); if (selectedMarketplace) { await loadPlugins(selectedMarketplace); } } catch (err: any) { setError(err.message || pickAppText(locale, '卸载插件失败', 'Failed to uninstall the plugin')); } finally { setActionPlugin(null); } }; const handleRefresh = async () => { await loadMarketplaces(); if (selectedMarketplace) { await loadPlugins(selectedMarketplace); } }; if (loading) { return (
); } return (
{/* Page header */}

{pickAppText(locale, '插件市场', 'Plugin marketplace')}

{pickAppText(locale, '浏览并安装已注册市场中的插件', 'Browse and install plugins from registered marketplaces')}

{/* Error */} {error && (
{error}
)} {/* Add marketplace form */} {showAddForm && (
setAddSource(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') handleAdd(); }} disabled={adding} className="flex-1" />
)} {/* Marketplace tabs */} {marketplaces.length > 0 && (
{marketplaces.map((marketplace) => (
))}
)} {/* Empty state */} {marketplaces.length === 0 && !error && (

{pickAppText(locale, '还没有注册任何市场', 'No marketplaces are registered yet')}

{pickAppText(locale, '点击上方的', 'Use the')}{pickAppText(locale, '添加市场', 'Add marketplace')}{pickAppText(locale, ',填入本地路径或 Git 地址即可开始使用。', ' action above and provide a local path or Git URL to get started.')}

)} {/* Plugin list */} {selectedMarketplace && ( <> {pluginsLoading ? (
) : plugins.length === 0 ? (

{pickAppText(locale, '暂无可用插件', 'No plugins available')}

{pickAppText(locale, '这个市场里暂时还没有插件。', 'There are no plugins in this marketplace yet.')}

) : (
{plugins.map((plugin) => (
{plugin.name} {plugin.installed && ( {pickAppText(locale, '已安装', 'Installed')} )}
{plugin.description && (

{plugin.description}

)}
{plugin.installed ? ( <> ) : ( )}
))}
)} )}
); }