mirror of
https://github.com/yusufipk/RepoHub.git
synced 2026-09-11 18:46:07 +00:00
feat: add comprehensive Windows PowerShell script usage instructions
- Enhanced ScriptPreview with detailed Windows-specific installation steps including execution policy handling and winget availability checks - Added localization support for all script preview UI elements and Windows usage instructions - Improved script generator with automatic unblocking, admin privilege warnings, and winget validation
This commit is contained in:
@@ -5,6 +5,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { GeneratedScript, SelectedPackage, Platform } from '@/types'
|
||||
import { Download, Copy, Check, Terminal, Shield } from 'lucide-react'
|
||||
import { useLocale } from '@/contexts/LocaleContext'
|
||||
|
||||
interface ScriptPreviewProps {
|
||||
generatedScript: GeneratedScript | null
|
||||
@@ -20,6 +21,7 @@ export function ScriptPreview({
|
||||
onClose
|
||||
}: ScriptPreviewProps) {
|
||||
const [copied, setCopied] = useState(false)
|
||||
const { t } = useLocale()
|
||||
|
||||
if (!generatedScript || !selectedPlatform) {
|
||||
return null
|
||||
@@ -40,7 +42,8 @@ export function ScriptPreview({
|
||||
const url = URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = `install-packages-${selectedPlatform?.id || 'unknown'}.sh`
|
||||
const ext = getScriptExtension()
|
||||
a.download = `install-packages-${selectedPlatform?.id || 'unknown'}${ext}`
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
document.body.removeChild(a)
|
||||
@@ -71,58 +74,58 @@ export function ScriptPreview({
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black/50 flex items-center justify-center p-4 z-50">
|
||||
<Card className="w-full max-w-4xl max-h-[90vh] overflow-hidden">
|
||||
<Card className="w-full max-w-4xl max-h-[90vh] overflow-auto">
|
||||
<CardHeader>
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<CardTitle className="flex items-center space-x-2">
|
||||
<Terminal className="h-5 w-5" />
|
||||
<span>Installation Script</span>
|
||||
<span>{t('script.title')}</span>
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
Idempotent script for {selectedPlatform?.name || 'Unknown Platform'} using {selectedPlatform?.packageManager || 'Unknown Package Manager'}
|
||||
{t('script.description')} {selectedPlatform?.name || 'Unknown Platform'}
|
||||
</CardDescription>
|
||||
</div>
|
||||
<Button variant="outline" onClick={onClose}>
|
||||
Close
|
||||
{t('common.close')}
|
||||
</Button>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<CardContent className="space-y-4 overflow-y-auto max-h-[70vh] pr-2">
|
||||
{/* Script Info */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="p-3 bg-secondary rounded-lg">
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<Shield className="h-4 w-4 text-green-600" />
|
||||
<span className="font-medium text-sm">Official Repositories</span>
|
||||
<span className="font-medium text-sm">{t('script.official_repos')}</span>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
All packages from trusted sources
|
||||
{t('script.official_repos_desc')}
|
||||
</p>
|
||||
</div>
|
||||
<div className="p-3 bg-secondary rounded-lg">
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<Terminal className="h-4 w-4 text-blue-600" />
|
||||
<span className="font-medium text-sm">Idempotent</span>
|
||||
<span className="font-medium text-sm">{t('script.idempotent')}</span>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Safe to run multiple times
|
||||
{t('script.idempotent_desc')}
|
||||
</p>
|
||||
</div>
|
||||
<div className="p-3 bg-secondary rounded-lg">
|
||||
<div className="flex items-center space-x-2 mb-1">
|
||||
<Download className="h-4 w-4 text-purple-600" />
|
||||
<span className="font-medium text-sm">{selectedPackages.length} Packages</span>
|
||||
<span className="font-medium text-sm">{selectedPackages.length} {t('script.packages_count')}</span>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Ready for installation
|
||||
{t('script.packages_count_desc')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Package List */}
|
||||
<div>
|
||||
<h4 className="font-medium mb-2">Included Packages:</h4>
|
||||
<h4 className="font-medium mb-2">{t('script.included_packages')}</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{selectedPackages.map((pkg) => (
|
||||
<span
|
||||
@@ -138,7 +141,7 @@ export function ScriptPreview({
|
||||
{/* Script Content */}
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<h4 className="font-medium">Script Content:</h4>
|
||||
<h4 className="font-medium">{t('script.script_content')}</h4>
|
||||
<div className="flex space-x-2">
|
||||
<Button variant="outline" size="sm" onClick={handleCopy}>
|
||||
{copied ? (
|
||||
@@ -146,11 +149,11 @@ export function ScriptPreview({
|
||||
) : (
|
||||
<Copy className="h-4 w-4 mr-2" />
|
||||
)}
|
||||
{copied ? 'Copied!' : 'Copy'}
|
||||
{copied ? t('script.copied') : t('script.copy')}
|
||||
</Button>
|
||||
<Button size="sm" onClick={handleDownload}>
|
||||
<Download className="h-4 w-4 mr-2" />
|
||||
Download {getScriptExtension()}
|
||||
{t('script.download')} {getScriptExtension()}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -163,13 +166,50 @@ export function ScriptPreview({
|
||||
|
||||
{/* Usage Instructions */}
|
||||
<div className="p-4 bg-blue-50 border border-blue-200 rounded-lg">
|
||||
<h4 className="font-medium text-blue-900 mb-2">How to use:</h4>
|
||||
<ol className="text-sm text-blue-800 space-y-1 list-decimal list-inside">
|
||||
<li>Download the script file to your target machine</li>
|
||||
<li>Make it executable (for Linux/macOS): <code className="bg-blue-100 px-1 rounded">chmod +x install-packages-{selectedPlatform?.id || 'unknown'}{getScriptExtension()}</code></li>
|
||||
<li>Run the script with appropriate permissions</li>
|
||||
<li>The script will automatically handle repository setup and package installation</li>
|
||||
</ol>
|
||||
<h4 className="font-medium text-blue-900 mb-2">{t('script.usage')}</h4>
|
||||
{selectedPlatform?.id === 'windows' ? (
|
||||
<ol className="text-sm text-blue-800 space-y-2 list-decimal list-inside">
|
||||
<li>
|
||||
{t('script.windows_usage.download_intro')}
|
||||
<code className="bg-blue-100 px-1 mx-1 rounded">{t('script.windows_usage.file_name')}</code>)
|
||||
</li>
|
||||
<li>
|
||||
{t('script.windows_usage.open_powershell_intro')}
|
||||
<code className="bg-blue-100 px-1 mx-1 rounded">{t('script.windows_usage.disabled_error')}</code>,
|
||||
{t('script.windows_usage.run_one')}
|
||||
<div className="mt-1 space-y-1">
|
||||
<div>
|
||||
• {t('script.windows_usage.persistent_title')}
|
||||
<code className="block bg-blue-100 px-2 py-1 mt-1 rounded">{t('script.windows_usage.persistent_cmd')}</code>
|
||||
{t('script.windows_usage.then_run')} <code className="bg-blue-100 px-1 rounded">{t('script.windows_usage.then_run_cmd')}</code>
|
||||
</div>
|
||||
<div>
|
||||
• {t('script.windows_usage.onetime_title')}
|
||||
<code className="block bg-blue-100 px-2 py-1 mt-1 rounded">{t('script.windows_usage.onetime_cmd')}</code>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
{t('script.windows_usage.unblock_title')}
|
||||
<code className="block bg-blue-100 px-2 py-1 mt-1 rounded">{t('script.windows_usage.unblock_cmd')}</code>
|
||||
</li>
|
||||
<li>
|
||||
{t('script.windows_usage.winget_title')}
|
||||
<span className="block mt-1">{t('script.windows_usage.store_link_label')}: ms-windows-store://pdp/?productId=9NBLGGH4NNS1</span>
|
||||
<span className="block">{t('script.windows_usage.direct_link_label')}: https://aka.ms/getwinget</span>
|
||||
</li>
|
||||
</ol>
|
||||
) : (
|
||||
<ol className="text-sm text-blue-800 space-y-2 list-decimal list-inside">
|
||||
<li>{t('script.usage_steps.0')}</li>
|
||||
<li>
|
||||
{t('script.usage_steps.1')}
|
||||
<code className="block bg-blue-100 px-2 py-1 mt-1 rounded">chmod +x install-packages-{selectedPlatform?.id || 'unknown'}{getScriptExtension()}</code>
|
||||
</li>
|
||||
<li>{t('script.usage_steps.2')}</li>
|
||||
<li>{t('script.usage_steps.3')}</li>
|
||||
</ol>
|
||||
)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
Reference in New Issue
Block a user