Files
users/components/dialogs/publish-api-dialog.tsx
v0 b17b488f8e refactor: restructure navigation and module layout
Reorganize navigation and module structure based on new requirements.

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
2026-01-31 04:32:36 +00:00

193 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { useState } from "react"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Textarea } from "@/components/ui/textarea"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Code, Plus, X } from "lucide-react"
interface PublishApiDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
}
export function PublishApiDialog({ open, onOpenChange }: PublishApiDialogProps) {
const [formData, setFormData] = useState({
name: "",
description: "",
endpoint: "/api/v1/",
method: "GET",
params: [] as { name: string; type: string; required: boolean; desc: string }[],
rateLimit: "1000",
})
const addParam = () => {
setFormData({
...formData,
params: [...formData.params, { name: "", type: "string", required: false, desc: "" }],
})
}
const removeParam = (index: number) => {
setFormData({
...formData,
params: formData.params.filter((_, i) => i !== index),
})
}
const handleSubmit = () => {
console.log("发布API:", formData)
onOpenChange(false)
}
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[600px]">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<Code className="w-5 h-5" />
API服务
</DialogTitle>
</DialogHeader>
<div className="space-y-4 py-4 max-h-[60vh] overflow-y-auto">
<div className="space-y-2">
<Label>API名称</Label>
<Input
placeholder="例如用户画像查询API"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
/>
</div>
<div className="space-y-2">
<Label>API描述</Label>
<Textarea
placeholder="描述API的功能和用途"
value={formData.description}
onChange={(e) => setFormData({ ...formData, description: e.target.value })}
/>
</div>
<div className="grid grid-cols-3 gap-4">
<div className="col-span-2 space-y-2">
<Label>Endpoint</Label>
<Input
placeholder="/api/v1/..."
value={formData.endpoint}
onChange={(e) => setFormData({ ...formData, endpoint: e.target.value })}
/>
</div>
<div className="space-y-2">
<Label>Method</Label>
<Select value={formData.method} onValueChange={(value) => setFormData({ ...formData, method: value })}>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="GET">GET</SelectItem>
<SelectItem value="POST">POST</SelectItem>
<SelectItem value="PUT">PUT</SelectItem>
<SelectItem value="DELETE">DELETE</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="space-y-2">
<div className="flex items-center justify-between">
<Label></Label>
<Button variant="outline" size="sm" onClick={addParam}>
<Plus className="w-3 h-3 mr-1" />
</Button>
</div>
{formData.params.length === 0 ? (
<div className="p-4 border border-dashed rounded-lg text-center text-gray-500 text-sm">
"添加参数"API参数
</div>
) : (
<div className="space-y-2">
{formData.params.map((param, index) => (
<div key={index} className="flex items-center gap-2 p-3 bg-gray-50 rounded-lg">
<Input
className="w-28"
placeholder="参数名"
value={param.name}
onChange={(e) => {
const newParams = [...formData.params]
newParams[index].name = e.target.value
setFormData({ ...formData, params: newParams })
}}
/>
<Select
value={param.type}
onValueChange={(value) => {
const newParams = [...formData.params]
newParams[index].type = value
setFormData({ ...formData, params: newParams })
}}
>
<SelectTrigger className="w-24">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="string">string</SelectItem>
<SelectItem value="number">number</SelectItem>
<SelectItem value="boolean">boolean</SelectItem>
<SelectItem value="array">array</SelectItem>
<SelectItem value="object">object</SelectItem>
</SelectContent>
</Select>
<Button
variant={param.required ? "default" : "outline"}
size="sm"
onClick={() => {
const newParams = [...formData.params]
newParams[index].required = !param.required
setFormData({ ...formData, params: newParams })
}}
>
{param.required ? "必填" : "可选"}
</Button>
<Input
className="flex-1"
placeholder="参数说明"
value={param.desc}
onChange={(e) => {
const newParams = [...formData.params]
newParams[index].desc = e.target.value
setFormData({ ...formData, params: newParams })
}}
/>
<Button variant="ghost" size="sm" onClick={() => removeParam(index)}>
<X className="w-4 h-4" />
</Button>
</div>
))}
</div>
)}
</div>
<div className="space-y-2">
<Label>/</Label>
<Input
type="number"
value={formData.rateLimit}
onChange={(e) => setFormData({ ...formData, rateLimit: e.target.value })}
/>
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => onOpenChange(false)}>
</Button>
<Button onClick={handleSubmit}>API</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}