Save workspace changes
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
|
||||
export default function UploadActions({
|
||||
step = 1,
|
||||
canStart = false,
|
||||
canContinue = false,
|
||||
canPublish = false,
|
||||
canGoBack = false,
|
||||
canReset = true,
|
||||
canCancel = false,
|
||||
canRetry = false,
|
||||
isUploading = false,
|
||||
isProcessing = false,
|
||||
isPublishing = false,
|
||||
isCancelling = false,
|
||||
disableReason = 'Complete required fields',
|
||||
onStart,
|
||||
onContinue,
|
||||
onPublish,
|
||||
onBack,
|
||||
onCancel,
|
||||
onReset,
|
||||
onRetry,
|
||||
onSaveDraft,
|
||||
showSaveDraft = false,
|
||||
mobileSticky = true,
|
||||
resetLabel = 'Reset',
|
||||
publishLabel = 'Publish',
|
||||
}) {
|
||||
const [confirmCancel, setConfirmCancel] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!confirmCancel) return
|
||||
const timer = window.setTimeout(() => setConfirmCancel(false), 3200)
|
||||
return () => window.clearTimeout(timer)
|
||||
}, [confirmCancel])
|
||||
|
||||
const handleCancel = () => {
|
||||
if (!canCancel || isCancelling) return
|
||||
if (!confirmCancel) {
|
||||
setConfirmCancel(true)
|
||||
return
|
||||
}
|
||||
setConfirmCancel(false)
|
||||
onCancel?.()
|
||||
}
|
||||
|
||||
const renderPrimary = () => {
|
||||
if (step === 1) {
|
||||
const disabled = !canStart || isUploading || isProcessing || isCancelling
|
||||
const label = isUploading ? 'Uploading…' : isProcessing ? 'Processing…' : 'Start upload'
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
disabled={disabled}
|
||||
title={disabled ? disableReason : 'Start upload'}
|
||||
onClick={() => onStart?.()}
|
||||
className={`btn-primary text-sm ${disabled ? 'cursor-not-allowed opacity-60' : ''}`}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
if (step === 2) {
|
||||
const disabled = !canContinue
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
disabled={disabled}
|
||||
title={disabled ? disableReason : 'Continue to Publish'}
|
||||
onClick={() => onContinue?.()}
|
||||
className={`btn-primary text-sm ${disabled ? 'cursor-not-allowed opacity-60' : ''}`}
|
||||
>
|
||||
Continue to Publish
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
const disabled = !canPublish || isPublishing
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
disabled={disabled}
|
||||
title={disabled ? disableReason : publishLabel}
|
||||
onClick={() => onPublish?.()}
|
||||
className={`btn-primary text-sm ${disabled ? 'cursor-not-allowed opacity-60' : ''}`}
|
||||
>
|
||||
{isPublishing ? `${publishLabel}…` : publishLabel}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<footer data-testid="wizard-action-bar" className={`${mobileSticky ? 'sticky bottom-0 z-20 px-4 pb-3 lg:static lg:px-0 lg:pb-0' : ''}`}>
|
||||
<div className="mx-auto w-full max-w-4xl rounded-[24px] border border-white/10 bg-[#08111c]/88 p-3 shadow-[0_-12px_32px_rgba(2,8,23,0.65)] backdrop-blur-sm sm:p-4 lg:shadow-none">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<div className="text-xs uppercase tracking-[0.18em] text-white/35">
|
||||
{step === 1 ? 'Step 1 of 3' : step === 2 ? 'Step 2 of 3' : 'Step 3 of 3'}
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center justify-end gap-2.5">
|
||||
{canGoBack && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onBack?.()}
|
||||
className="btn-secondary text-sm"
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
)}
|
||||
|
||||
{showSaveDraft && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onSaveDraft?.()}
|
||||
className="btn-secondary text-sm"
|
||||
>
|
||||
Save draft
|
||||
</button>
|
||||
)}
|
||||
|
||||
{step === 1 && canCancel && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleCancel}
|
||||
disabled={isCancelling}
|
||||
title={confirmCancel ? 'Click again to confirm cancel' : 'Cancel current upload'}
|
||||
className="btn-secondary text-sm disabled:cursor-not-allowed disabled:opacity-60"
|
||||
>
|
||||
{isCancelling ? 'Cancelling…' : confirmCancel ? 'Cancel upload?' : 'Cancel'}
|
||||
</button>
|
||||
)}
|
||||
|
||||
{canRetry && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onRetry?.()}
|
||||
className="btn-secondary text-sm"
|
||||
>
|
||||
Retry
|
||||
</button>
|
||||
)}
|
||||
|
||||
{canReset && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onReset?.()}
|
||||
className="btn-secondary text-sm"
|
||||
>
|
||||
{resetLabel}
|
||||
</button>
|
||||
)}
|
||||
|
||||
{renderPrimary()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user