121 lines
3.8 KiB
TypeScript
121 lines
3.8 KiB
TypeScript
|
'use client'
|
||
|
|
||
|
import { useState } from 'react'
|
||
|
import { ServerPack } from '@/utils/yamlParser'
|
||
|
import { Button } from '@/components/ui/button'
|
||
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'
|
||
|
|
||
|
export default function PackCard({ pack }: { pack: ServerPack }) {
|
||
|
const [composeYaml, setComposeYaml] = useState('')
|
||
|
const [startCommand, setStartCommand] = useState('')
|
||
|
|
||
|
const generateComposeYaml = () => {
|
||
|
const yaml = `
|
||
|
version: '3'
|
||
|
services:
|
||
|
minecraft:
|
||
|
image: ${pack.dockerImage}:${pack.imageVersion}
|
||
|
ports:
|
||
|
- 25565:25565
|
||
|
environment:
|
||
|
EULA: "TRUE"
|
||
|
TYPE: ${pack.core}
|
||
|
VERSION: ${pack.minecraftVersion}
|
||
|
JAVA_VERSION: ${pack.javaVersion}
|
||
|
volumes:
|
||
|
- ./data:/data
|
||
|
restart: unless-stopped
|
||
|
`
|
||
|
setComposeYaml(yaml.trim())
|
||
|
}
|
||
|
|
||
|
const generateStartCommand = () => {
|
||
|
const command = `
|
||
|
docker run -d \\
|
||
|
--name minecraft-server \\
|
||
|
-p 25565:25565 \\
|
||
|
-e EULA=TRUE \\
|
||
|
-e TYPE=${pack.core} \\
|
||
|
-e VERSION=${pack.minecraftVersion} \\
|
||
|
-e JAVA_VERSION=${pack.javaVersion} \\
|
||
|
-v $(pwd)/data:/data \\
|
||
|
${pack.dockerImage}:${pack.imageVersion}
|
||
|
`
|
||
|
setStartCommand(command.trim())
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
<div className="bg-white shadow-lg rounded-lg overflow-hidden">
|
||
|
<div className="p-6">
|
||
|
<h2 className="text-2xl font-bold mb-2">{pack.name}</h2>
|
||
|
<p className="text-gray-600 mb-4">{pack.description}</p>
|
||
|
<div className="grid grid-cols-2 gap-4 mb-4">
|
||
|
<InfoItem label="Category" value={pack.category} />
|
||
|
<InfoItem label="Core" value={pack.core} />
|
||
|
<InfoItem label="Java Version" value={pack.javaVersion} />
|
||
|
<InfoItem label="Minecraft Version" value={pack.minecraftVersion} />
|
||
|
<InfoItem label="Docker Image" value={`${pack.dockerImage}:${pack.imageVersion}`} />
|
||
|
</div>
|
||
|
<div className="mb-4">
|
||
|
<h3 className="font-semibold mb-2">Mods:</h3>
|
||
|
<ul className="list-disc list-inside">
|
||
|
{pack.mods.map((mod, index) => (
|
||
|
<li key={index}>{mod}</li>
|
||
|
))}
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div className="mb-4">
|
||
|
<h3 className="font-semibold mb-2">Plugins:</h3>
|
||
|
<ul className="list-disc list-inside">
|
||
|
{pack.plugins.map((plugin, index) => (
|
||
|
<li key={index}>{plugin}</li>
|
||
|
))}
|
||
|
</ul>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div className="bg-gray-100 px-6 py-4 flex justify-between">
|
||
|
<Dialog>
|
||
|
<DialogTrigger asChild>
|
||
|
<Button onClick={generateComposeYaml} className="bg-blue-500 hover:bg-blue-700">
|
||
|
生成 docker-compose.yaml
|
||
|
</Button>
|
||
|
</DialogTrigger>
|
||
|
<DialogContent>
|
||
|
<DialogHeader>
|
||
|
<DialogTitle>Docker Compose YAML</DialogTitle>
|
||
|
</DialogHeader>
|
||
|
<pre className="bg-gray-100 p-4 rounded-md overflow-x-auto">
|
||
|
<code>{composeYaml}</code>
|
||
|
</pre>
|
||
|
</DialogContent>
|
||
|
</Dialog>
|
||
|
<Dialog>
|
||
|
<DialogTrigger asChild>
|
||
|
<Button onClick={generateStartCommand} className="bg-green-500 hover:bg-green-700">
|
||
|
生成启动命令
|
||
|
</Button>
|
||
|
</DialogTrigger>
|
||
|
<DialogContent>
|
||
|
<DialogHeader>
|
||
|
<DialogTitle>Docker Start Command</DialogTitle>
|
||
|
</DialogHeader>
|
||
|
<pre className="bg-gray-100 p-4 rounded-md overflow-x-auto">
|
||
|
<code>{startCommand}</code>
|
||
|
</pre>
|
||
|
</DialogContent>
|
||
|
</Dialog>
|
||
|
</div>
|
||
|
</div>
|
||
|
)
|
||
|
}
|
||
|
|
||
|
function InfoItem({ label, value }: { label: string; value: string }) {
|
||
|
return (
|
||
|
<div>
|
||
|
<h3 className="font-semibold">{label}:</h3>
|
||
|
<p className="text-gray-700">{value}</p>
|
||
|
</div>
|
||
|
)
|
||
|
}
|
||
|
|