Skip to content

Commit 57bf9a5

Browse files
committed
feat(wizard): enhance BookCreationWizard with loading state management
- Added a loading state to the BookCreationWizard to prevent multiple create requests during the book creation process. - Introduced a ref to track the creation status, ensuring that the create function does not execute concurrently. - Updated the component to reflect the new loading state in the UI, improving user experience during book creation. - Cleaned up dependencies in PageGroupingMode and SectioningModeSelect to optimize performance.
1 parent 4ad1c7c commit 57bf9a5

4 files changed

Lines changed: 19 additions & 6 deletions

File tree

apps/studio/src/components/wizard/BookCreationWizard.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
import { useState, useEffect, type CSSProperties } from "react"
2+
import { useState, useEffect, useRef, type CSSProperties } from "react"
33
import { Trans, useLingui } from "@lingui/react/macro"
44
import { Eye, ArrowLeft, ArrowRight, Zap, Loader2 } from "lucide-react"
55
import { useStore } from "@tanstack/react-form"
@@ -200,6 +200,8 @@ export function BookCreationWizard() {
200200
const { apiKey, hasApiKey, azureKey, azureRegion, geminiKey } = useApiKey()
201201
const [previewOpen, setPreviewOpen] = useState(false)
202202
const [submitError, setSubmitError] = useState<string | null>(null)
203+
const [isCreating, setIsCreating] = useState(false)
204+
const creatingRef = useRef(false)
203205

204206
const values = useStore(form.store, (s) => s.values)
205207
const { file, renderStrategy, editingLanguage, outputLanguages, styleguide } = values
@@ -251,7 +253,10 @@ export function BookCreationWizard() {
251253
}
252254

253255
async function handleCreate() {
256+
if (creatingRef.current) return
257+
creatingRef.current = true
254258
setSubmitError(null)
259+
setIsCreating(true)
255260
try {
256261
const book = await createMutation.mutateAsync({
257262
label: values.label.trim(),
@@ -274,6 +279,8 @@ export function BookCreationWizard() {
274279

275280
navigate({ to: "/books/$label/$step", params: { label: book.label, step: "book" } })
276281
} catch (error) {
282+
creatingRef.current = false
283+
setIsCreating(false)
277284
setSubmitError(error instanceof Error ? error.message : t`Failed to create book.`)
278285
}
279286
}
@@ -343,8 +350,8 @@ export function BookCreationWizard() {
343350
key={currentStep}
344351
isLastStep={currentStep === STEPS.length}
345352
canContinue={canContinue}
346-
canCreate={canCreate && !createMutation.isPending}
347-
isCreating={createMutation.isPending}
353+
canCreate={canCreate && !isCreating}
354+
isCreating={isCreating}
348355
onBack={handleBack}
349356
onNext={handleNext}
350357
onCreate={handleCreate}

apps/studio/src/components/wizard/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ export function useDelayedPreviewFocus(focus: ImageProcessingPreviewFocus) {
8080
const { setPreviewFocus } = useWizard()
8181
const timerRef = useRef<ReturnType<typeof setTimeout>>(null)
8282

83+
useEffect(() => {
84+
return () => {
85+
if (timerRef.current) clearTimeout(timerRef.current)
86+
}
87+
}, [])
88+
8389
const onMouseEnter = useCallback(() => {
8490
timerRef.current = setTimeout(() => setPreviewFocus(focus), PREVIEW_HOVER_DELAY)
8591
}, [focus, setPreviewFocus])

apps/studio/src/components/wizard/step2LayoutOptions/PageGroupingMode.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export function PageGroupingMode() {
8888
{ value: "spread" as const, label: i18n._(GROUPING_OPTION_SPREAD_LABEL) },
8989
{ value: "single" as const, label: i18n._(GROUPING_OPTION_SINGLE_LABEL) },
9090
],
91-
[i18n, i18n.locale],
91+
[i18n.locale],
9292
)
9393

9494
const recommendedOption = recommended
@@ -108,7 +108,7 @@ export function PageGroupingMode() {
108108
Diagram: SingleDiagram,
109109
},
110110
],
111-
[i18n, i18n.locale],
111+
[i18n.locale],
112112
)
113113

114114
return (

apps/studio/src/components/wizard/step2LayoutOptions/SectioningModeSelect.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export function SectioningModeSelect({ id, value, onValueChange, recommended, pr
7373
label: i18n._(labelMsg),
7474
Icon,
7575
})),
76-
[i18n, i18n.locale],
76+
[i18n.locale],
7777
)
7878

7979
const selected = options.find((o) => o.value === value)

0 commit comments

Comments
 (0)