Files
users/components/dialogs/upload-model-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

194 lines
7.4 KiB
TypeScript
Raw Permalink 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 { Upload, FileCode, CheckCircle } from "lucide-react"
interface UploadModelDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
}
export function UploadModelDialog({ open, onOpenChange }: UploadModelDialogProps) {
const [step, setStep] = useState(1)
const [formData, setFormData] = useState({
name: "",
category: "",
description: "",
inputFeatures: "",
outputFormat: "",
updateFrequency: "",
})
const [fileUploaded, setFileUploaded] = useState(false)
const handleFileUpload = () => {
setFileUploaded(true)
}
const handleSubmit = () => {
console.log("上传模型:", formData)
onOpenChange(false)
setStep(1)
setFileUploaded(false)
}
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[600px]">
<DialogHeader>
<DialogTitle></DialogTitle>
</DialogHeader>
<div className="flex items-center gap-4 mb-6">
{[1, 2, 3].map((s) => (
<div key={s} className="flex items-center gap-2">
<div
className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium ${step >= s ? "bg-blue-500 text-white" : "bg-gray-100 text-gray-500"}`}
>
{step > s ? <CheckCircle className="w-4 h-4" /> : s}
</div>
<span className={`text-sm ${step >= s ? "text-gray-900" : "text-gray-400"}`}>
{s === 1 ? "基本信息" : s === 2 ? "上传文件" : "配置参数"}
</span>
{s < 3 && <div className={`w-12 h-0.5 ${step > s ? "bg-blue-500" : "bg-gray-200"}`} />}
</div>
))}
</div>
{step === 1 && (
<div className="space-y-4">
<div className="space-y-2">
<Label></Label>
<Input
placeholder="输入模型名称"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
/>
</div>
<div className="space-y-2">
<Label></Label>
<Select
value={formData.category}
onValueChange={(value) => setFormData({ ...formData, category: value })}
>
<SelectTrigger>
<SelectValue placeholder="选择类别" />
</SelectTrigger>
<SelectContent>
<SelectItem value="clv">CLV模型</SelectItem>
<SelectItem value="rfm">RFM模型</SelectItem>
<SelectItem value="churn"></SelectItem>
<SelectItem value="segment"></SelectItem>
<SelectItem value="other"></SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label></Label>
<Textarea
placeholder="描述模型的功能和用途"
value={formData.description}
onChange={(e) => setFormData({ ...formData, description: e.target.value })}
/>
</div>
</div>
)}
{step === 2 && (
<div className="space-y-4">
<div
className={`border-2 border-dashed rounded-xl p-8 text-center cursor-pointer transition-colors ${fileUploaded ? "border-green-500 bg-green-50" : "border-gray-300 hover:border-blue-500"}`}
onClick={handleFileUpload}
>
{fileUploaded ? (
<div className="space-y-2">
<CheckCircle className="w-12 h-12 mx-auto text-green-500" />
<p className="text-green-600 font-medium">model_v1.0.pkl</p>
<p className="text-sm text-gray-500">12.5 MB</p>
</div>
) : (
<div className="space-y-2">
<Upload className="w-12 h-12 mx-auto text-gray-400" />
<p className="text-gray-600"></p>
<p className="text-sm text-gray-400"> .pkl, .h5, .pt, .onnx </p>
</div>
)}
</div>
<div className="p-4 bg-blue-50 rounded-xl">
<div className="flex items-start gap-3">
<FileCode className="w-5 h-5 text-blue-500 mt-0.5" />
<div>
<p className="text-sm font-medium text-blue-800"></p>
<ul className="text-xs text-blue-600 mt-1 space-y-1">
<li> pickle, HDF5, PyTorch, ONNX</li>
<li> 500MB</li>
<li> </li>
</ul>
</div>
</div>
</div>
</div>
)}
{step === 3 && (
<div className="space-y-4">
<div className="space-y-2">
<Label></Label>
<Input
placeholder="例如:消费金额,消费频次,最近购买"
value={formData.inputFeatures}
onChange={(e) => setFormData({ ...formData, inputFeatures: e.target.value })}
/>
</div>
<div className="space-y-2">
<Label></Label>
<Input
placeholder="例如:分数(0-100)"
value={formData.outputFormat}
onChange={(e) => setFormData({ ...formData, outputFormat: e.target.value })}
/>
</div>
<div className="space-y-2">
<Label></Label>
<Select
value={formData.updateFrequency}
onValueChange={(value) => setFormData({ ...formData, updateFrequency: value })}
>
<SelectTrigger>
<SelectValue placeholder="选择更新频率" />
</SelectTrigger>
<SelectContent>
<SelectItem value="realtime"></SelectItem>
<SelectItem value="daily"></SelectItem>
<SelectItem value="weekly"></SelectItem>
<SelectItem value="monthly"></SelectItem>
</SelectContent>
</Select>
</div>
</div>
)}
<DialogFooter>
{step > 1 && (
<Button variant="outline" onClick={() => setStep(step - 1)}>
</Button>
)}
{step < 3 ? (
<Button onClick={() => setStep(step + 1)} disabled={step === 2 && !fileUploaded}>
</Button>
) : (
<Button onClick={handleSubmit}></Button>
)}
</DialogFooter>
</DialogContent>
</Dialog>
)
}