add saving
This commit is contained in:
parent
7ccd6e80ca
commit
d1207f0541
@ -10,6 +10,7 @@ import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import { LoadingSpinner } from '@/components/ui/loading-spinner'
|
||||
import { FullScreenLoading } from '@/components/ui/full-screen-loading'
|
||||
import { VersionTimeline, VersionTimelineRef } from '@/components/studio/VersionTimeline'
|
||||
import {
|
||||
Play,
|
||||
@ -70,6 +71,10 @@ export default function PromptPage({ params }: PromptPageProps) {
|
||||
const [originalTitle, setOriginalTitle] = useState('')
|
||||
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false)
|
||||
const [isDuplicating, setIsDuplicating] = useState(false)
|
||||
const [fullScreenLoading, setFullScreenLoading] = useState({
|
||||
isVisible: false,
|
||||
message: ''
|
||||
})
|
||||
const versionTimelineRef = useRef<VersionTimelineRef>(null)
|
||||
|
||||
useEffect(() => {
|
||||
@ -163,6 +168,11 @@ export default function PromptPage({ params }: PromptPageProps) {
|
||||
if (!user || !promptId) return
|
||||
|
||||
setIsSaving(true)
|
||||
setFullScreenLoading({
|
||||
isVisible: true,
|
||||
message: '正在保存提示词...'
|
||||
})
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/prompts/${promptId}`, {
|
||||
method: 'PUT',
|
||||
@ -198,6 +208,10 @@ export default function PromptPage({ params }: PromptPageProps) {
|
||||
console.error('Failed to save prompt:', error)
|
||||
} finally {
|
||||
setIsSaving(false)
|
||||
setFullScreenLoading({
|
||||
isVisible: false,
|
||||
message: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,6 +263,11 @@ export default function PromptPage({ params }: PromptPageProps) {
|
||||
if (!user || !prompt) return
|
||||
|
||||
setIsDuplicating(true)
|
||||
setFullScreenLoading({
|
||||
isVisible: true,
|
||||
message: '正在复制提示词...'
|
||||
})
|
||||
|
||||
try {
|
||||
// 创建新的prompt,使用当前显示的内容
|
||||
const duplicatedPrompt = {
|
||||
@ -267,13 +286,30 @@ export default function PromptPage({ params }: PromptPageProps) {
|
||||
|
||||
if (response.ok) {
|
||||
const newPrompt = await response.json()
|
||||
// 跳转到新创建的prompt页面
|
||||
|
||||
// 先隐藏加载遮罩,然后跳转
|
||||
setFullScreenLoading({
|
||||
isVisible: false,
|
||||
message: ''
|
||||
})
|
||||
|
||||
// 延迟跳转以确保遮罩动画完成
|
||||
setTimeout(() => {
|
||||
router.push(`/studio/${newPrompt.id}`)
|
||||
}, 300)
|
||||
} else {
|
||||
console.error('Failed to duplicate prompt')
|
||||
setFullScreenLoading({
|
||||
isVisible: false,
|
||||
message: ''
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error duplicating prompt:', error)
|
||||
setFullScreenLoading({
|
||||
isVisible: false,
|
||||
message: ''
|
||||
})
|
||||
} finally {
|
||||
setIsDuplicating(false)
|
||||
}
|
||||
@ -553,6 +589,12 @@ export default function PromptPage({ params }: PromptPageProps) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Full Screen Loading */}
|
||||
<FullScreenLoading
|
||||
isVisible={fullScreenLoading.isVisible}
|
||||
message={fullScreenLoading.message}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
66
src/components/ui/full-screen-loading.tsx
Normal file
66
src/components/ui/full-screen-loading.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import { LoadingSpinner } from './loading-spinner'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
interface FullScreenLoadingProps {
|
||||
isVisible: boolean
|
||||
message?: string
|
||||
onComplete?: () => void
|
||||
}
|
||||
|
||||
export function FullScreenLoading({
|
||||
isVisible,
|
||||
message = '正在处理中...',
|
||||
onComplete
|
||||
}: FullScreenLoadingProps) {
|
||||
// 禁止页面滚动
|
||||
useEffect(() => {
|
||||
if (isVisible) {
|
||||
document.body.style.overflow = 'hidden'
|
||||
} else {
|
||||
document.body.style.overflow = 'unset'
|
||||
}
|
||||
|
||||
return () => {
|
||||
document.body.style.overflow = 'unset'
|
||||
}
|
||||
}, [isVisible])
|
||||
|
||||
// 自动调用完成回调
|
||||
useEffect(() => {
|
||||
if (!isVisible && onComplete) {
|
||||
const timer = setTimeout(onComplete, 300) // 等待退出动画完成
|
||||
return () => clearTimeout(timer)
|
||||
}
|
||||
}, [isVisible, onComplete])
|
||||
|
||||
if (!isVisible) return null
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
"fixed inset-0 z-[9999] flex items-center justify-center",
|
||||
"bg-black/50 backdrop-blur-sm",
|
||||
"animate-in fade-in duration-200"
|
||||
)}>
|
||||
<div className={cn(
|
||||
"bg-background rounded-lg border border-border shadow-2xl",
|
||||
"p-8 mx-4 max-w-sm w-full",
|
||||
"animate-in zoom-in-95 duration-200"
|
||||
)}>
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
<LoadingSpinner size="lg" />
|
||||
<div className="text-center">
|
||||
<p className="text-foreground font-medium">{message}</p>
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
请稍候...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default FullScreenLoading
|
Loading…
Reference in New Issue
Block a user