11import { useQuery } from "@tanstack/react-query" ;
22import { HomeLayout } from "fumadocs-ui/layouts/home" ;
33import { LoaderCircle , WandSparklesIcon } from "lucide-react" ;
4- import { useState , useTransition } from "react" ;
4+ import { useRef , useState } from "react" ;
55import { useForm } from "react-hook-form" ;
66import { useTranslation } from "react-i18next" ;
77import { toast } from "sonner" ;
@@ -68,38 +68,41 @@ export default function ProbeShellGenerator() {
6868 > ( ) ;
6969 const [ generateResult , setGenerateResult ] = useState < ProbeShellResult > ( ) ;
7070 const [ packMethod , setPackMethod ] = useState < string > ( "" ) ;
71- const [ isActionPending , startTransition ] = useTransition ( ) ;
71+ const submitLockRef = useRef ( false ) ;
7272
7373 const onSubmit = async ( data : ProbeShellFormSchema ) => {
74- startTransition ( async ( ) => {
75- try {
76- const postData = transformToProbePostData ( data ) ;
77- const response = await fetch ( `${ env . API_URL } /api/probe/generate` , {
78- method : "POST" ,
79- headers : {
80- "Content-Type" : "application/json" ,
81- } ,
82- body : JSON . stringify ( postData ) ,
83- } ) ;
74+ if ( submitLockRef . current ) return ;
75+ submitLockRef . current = true ;
8476
85- if ( ! response . ok ) {
86- const json : APIErrorResponse = await response . json ( ) ;
87- toast . error ( t ( "toast.generateError" , { error : json . error } ) ) ;
88- return ;
89- }
77+ try {
78+ const postData = transformToProbePostData ( data ) ;
79+ const response = await fetch ( `${ env . API_URL } /api/probe/generate` , {
80+ method : "POST" ,
81+ headers : {
82+ "Content-Type" : "application/json" ,
83+ } ,
84+ body : JSON . stringify ( postData ) ,
85+ } ) ;
9086
91- const result = ( await response . json ( ) ) as ProbeShellGenerateResponse ;
92- setGenerateResult ( result . probeShellResult ) ;
93- setPackResult ( result . packResult ) ;
94- setAllPackResults ( result . allPackResults ) ;
95- setPackMethod ( data . packingMethod ) ;
96- toast . success ( t ( "toast.generateSuccess" ) ) ;
97- } catch ( error ) {
98- toast . error (
99- t ( "toast.generateError" , { error : ( error as Error ) . message } ) ,
100- ) ;
87+ if ( ! response . ok ) {
88+ const json : APIErrorResponse = await response . json ( ) ;
89+ toast . error ( t ( "toast.generateError" , { error : json . error } ) ) ;
90+ return ;
10191 }
102- } ) ;
92+
93+ const result = ( await response . json ( ) ) as ProbeShellGenerateResponse ;
94+ setGenerateResult ( result . probeShellResult ) ;
95+ setPackResult ( result . packResult ) ;
96+ setAllPackResults ( result . allPackResults ) ;
97+ setPackMethod ( data . packingMethod ) ;
98+ toast . success ( t ( "toast.generateSuccess" ) ) ;
99+ } catch ( error ) {
100+ toast . error (
101+ t ( "toast.generateError" , { error : ( error as Error ) . message } ) ,
102+ ) ;
103+ } finally {
104+ submitLockRef . current = false ;
105+ }
103106 } ;
104107 return (
105108 < HomeLayout { ...baseOptions ( ) } links = { siteConfig . navLinks } >
@@ -111,8 +114,12 @@ export default function ProbeShellGenerator() {
111114 < div className = "w-full xl:w-1/2 flex flex-col gap-2" >
112115 < MainConfigCard form = { form } servers = { serverConfig } />
113116 < PackageConfigCard form = { form } packerConfig = { packerConfig } />
114- < Button className = "w-full" type = "submit" disabled = { isActionPending } >
115- { isActionPending ? (
117+ < Button
118+ className = "w-full"
119+ type = "submit"
120+ disabled = { form . formState . isSubmitting }
121+ >
122+ { form . formState . isSubmitting ? (
116123 < LoaderCircle className = "animate-spin" />
117124 ) : (
118125 < WandSparklesIcon />
0 commit comments