初始提交: ScriptForge 脚本快速转运行链接服务
Some checks failed
Release / build-and-release (push) Failing after 1m31s
Some checks failed
Release / build-and-release (push) Failing after 1m31s
- Go 后端 (Gin + GORM + SQLite) 提供 API 和纯文本脚本服务 - Vite + React + TypeScript + Tailwind 前端 - 单二进制部署 (Go embed 前端静态文件) - Gitea Actions CI/CD: 打标签自动构建多平台 Release - 支持 bash/zsh/sh/fish/python3/node/ruby/php 8种运行环境 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
79
frontend/src/pages/ScriptDetail.tsx
Normal file
79
frontend/src/pages/ScriptDetail.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useParams, Link } from 'react-router-dom'
|
||||
import ScriptViewer from '../components/ScriptViewer'
|
||||
import CommandCard from '../components/CommandCard'
|
||||
import { getScript } from '../lib/api'
|
||||
import { ScriptDetail as ScriptDetailType } from '../types'
|
||||
|
||||
export default function ScriptDetail() {
|
||||
const { id } = useParams<{ id: string }>()
|
||||
const [script, setScript] = useState<ScriptDetailType | null>(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (!id) return
|
||||
getScript(id)
|
||||
.then(setScript)
|
||||
.catch((e) => setError(e instanceof Error ? e.message : '加载失败'))
|
||||
.finally(() => setLoading(false))
|
||||
}, [id])
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex justify-center py-20">
|
||||
<div className="animate-pulse text-gray-500">加载中...</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (error || !script) {
|
||||
return (
|
||||
<div className="text-center py-20">
|
||||
<div className="text-6xl mb-4">😕</div>
|
||||
<h2 className="text-xl font-bold mb-2">脚本不存在或已过期</h2>
|
||||
<p className="text-gray-400 mb-6">{error}</p>
|
||||
<Link to="/" className="text-blue-400 hover:underline">
|
||||
创建新脚本
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const command = `curl ${window.location.origin}/raw/${script.id} | ${script.runtime}`
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mb-6">
|
||||
<Link to="/" className="text-sm text-gray-500 hover:text-blue-400 transition-colors">
|
||||
← 返回首页
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<h1 className="text-2xl font-bold font-mono">{script.id}</h1>
|
||||
<span className="px-2 py-0.5 bg-blue-600/20 text-blue-400 text-xs rounded-full border border-blue-600/30">
|
||||
{script.runtime}
|
||||
</span>
|
||||
<span className="text-xs text-gray-500">
|
||||
{new Date(script.expires_at).toLocaleString('zh-CN')} 过期
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<ScriptViewer content={script.content} runtime={script.runtime} />
|
||||
|
||||
<div className="mt-8">
|
||||
<CommandCard command={command} />
|
||||
</div>
|
||||
|
||||
<div className="mt-8 text-center">
|
||||
<Link
|
||||
to={`/s/${script.id}/delete`}
|
||||
className="text-xs text-gray-600 hover:text-red-400 transition-colors"
|
||||
>
|
||||
删除此脚本
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user