This repository has been archived on 2025-05-18. You can view files and clone it, but cannot push or open issues or pull requests.
2025-03-10 15:26:46 +08:00

126 lines
4.0 KiB
TypeScript

import { useState, useEffect } from 'react';
import './style.css';
import { usePackageStore, Package } from './store';
import { Link2, SquareArrowOutUpRight } from 'lucide-react';
import { useConfigStore } from '@/store/config';
export const PackageManager = () => {
const { shopPackages, installedPackages, getInstalledPackages, getShopPackages, uninstallPackage, installPackage } = usePackageStore();
const { pageApi, pageStoreApi } = useConfigStore();
useEffect(() => {
getInstalledPackages();
getShopPackages();
}, []);
const getPackageStatus = (pkg: Package): string => {
const installed = installedPackages.find((p) => p.user === pkg.user && p.key === pkg.key);
if (!installed) return 'not-installed';
if (installed.version !== pkg.version) return 'update-available';
return 'installed';
};
const handleInstall = (id: string) => {
const pkg = shopPackages.find((p) => p.id === id);
if (pkg) {
installPackage(pkg);
}
};
const handleUpdate = (id: string) => {
const pkg = shopPackages.find((p) => p.id === id);
if (pkg) {
installPackage(pkg);
}
};
const handleReinstall = (id: string) => {
const pkg = shopPackages.find((p) => p.id === id);
if (pkg) {
installPackage(pkg);
}
};
const handleUninstall = (id: string) => {
const pkg = shopPackages.find((p) => p.id === id);
if (pkg) {
uninstallPackage(pkg);
}
};
const getActionButton = (status: string, pkg: Package) => {
switch (status) {
case 'not-installed':
return (
<button className='button button-install' onClick={() => handleInstall(pkg.id)}>
Install
</button>
);
case 'update-available':
return (
<button className='button button-update' onClick={() => handleUpdate(pkg.id)}>
Update
</button>
);
case 'installed':
return (
<button className='button button-reinstall' onClick={() => handleReinstall(pkg.id)}>
Reinstall
</button>
);
}
};
const handleOpenWindow = (pkg: Package) => {
const baseUrl = pageStoreApi || 'https://kevisual.silkyai.cn';
const path = `/${pkg.user}/${pkg.key}`;
window.open(`${baseUrl}${path}`, '_blank');
};
const handleOpenClientWindow = (pkg: Package) => {
if (!pageApi) return;
const baseUrl = pageApi;
const path = `/${pkg.user}/${pkg.key}`;
window.open(`${baseUrl}${path}`, '_blank');
};
return (
<div id='app'>
<h1>Package Manager</h1>
<div className='package-list'>
{shopPackages.map((pkg) => {
const status = getPackageStatus(pkg);
const isInstalled = status !== 'not-installed';
return (
<div key={pkg.id} className='package-card'>
<h2>{pkg.title}</h2>
<p className='description'>{pkg.description}</p>
<div className='package-info'>
<span>Version: {pkg.version}</span>
<span>User: {pkg.user}</span>
</div>
<div className='actions'>
{getActionButton(status, pkg)}
{status !== 'not-installed' && (
<button className='button button-uninstall' onClick={() => handleUninstall(pkg.id)}>
Uninstall
</button>
)}
<div className='flex gap-2'>
<div className='cursor-pointer p-2 rounded-md bg-amber-500 text-white'>
<SquareArrowOutUpRight onClick={() => handleOpenWindow(pkg)} />
</div>
{pageApi && isInstalled && (
<div className='cursor-pointer p-2 rounded-md bg-amber-500 text-white'>
<Link2 onClick={() => handleOpenClientWindow(pkg)} />
</div>
)}
</div>
</div>
</div>
);
})}
</div>
</div>
);
};
export default PackageManager;