diff --git a/chatdesk-ui/app/[locale]/setup/page.tsx b/chatdesk-ui/app/[locale]/setup/page.tsx index 244cd8d..4cd2b6b 100644 --- a/chatdesk-ui/app/[locale]/setup/page.tsx +++ b/chatdesk-ui/app/[locale]/setup/page.tsx @@ -87,6 +87,10 @@ export default function SetupPage() { const [perplexityAPIKey, setPerplexityAPIKey] = useState("") const [openrouterAPIKey, setOpenrouterAPIKey] = useState("") + // 只允许点击一次 + const [isSubmitting, setIsSubmitting] = useState(false) + + useEffect(() => { ;(async () => { //const supabaseClient = await supabase(); // Await the client creation @@ -131,7 +135,10 @@ export default function SetupPage() { const handleShouldProceed = (proceed: boolean) => { if (proceed) { if (currentStep === SETUP_STEP_COUNT) { - handleSaveSetupSetting() + //handleSaveSetupSetting() + if (!isSubmitting) { + handleSaveSetupSetting() + } } else { setCurrentStep(currentStep + 1) } @@ -140,72 +147,148 @@ export default function SetupPage() { } } - const handleSaveSetupSetting = async () => { - const session = (await supabase.auth.getSession()).data.session - if (!session) { - return router.push(getLocalizedPath("login")) - } + // const handleSaveSetupSetting = async () => { - const user = session.user - const profile = await getProfileByUserId(user.id) + // const session = (await supabase.auth.getSession()).data.session + // if (!session) { + // return router.push(getLocalizedPath("login")) + // } - const updateProfilePayload: TablesUpdate<"profiles"> = { - ...profile, - has_onboarded: true, - display_name: displayName, - username, - openai_api_key: openaiAPIKey, - openai_organization_id: openaiOrgID, - anthropic_api_key: anthropicAPIKey, - google_gemini_api_key: googleGeminiAPIKey, - mistral_api_key: mistralAPIKey, - groq_api_key: groqAPIKey, - perplexity_api_key: perplexityAPIKey, - openrouter_api_key: openrouterAPIKey, - use_azure_openai: useAzureOpenai, - azure_openai_api_key: azureOpenaiAPIKey, - azure_openai_endpoint: azureOpenaiEndpoint, - azure_openai_35_turbo_id: azureOpenai35TurboID, - azure_openai_45_turbo_id: azureOpenai45TurboID, - azure_openai_45_vision_id: azureOpenai45VisionID, - azure_openai_embeddings_id: azureOpenaiEmbeddingsID - } + // const user = session.user + // const profile = await getProfileByUserId(user.id) - const updatedProfile = await updateProfile(profile.id, updateProfilePayload) - setProfile(updatedProfile) + // const updateProfilePayload: TablesUpdate<"profiles"> = { + // ...profile, + // has_onboarded: true, + // display_name: displayName, + // username, + // openai_api_key: openaiAPIKey, + // openai_organization_id: openaiOrgID, + // anthropic_api_key: anthropicAPIKey, + // google_gemini_api_key: googleGeminiAPIKey, + // mistral_api_key: mistralAPIKey, + // groq_api_key: groqAPIKey, + // perplexity_api_key: perplexityAPIKey, + // openrouter_api_key: openrouterAPIKey, + // use_azure_openai: useAzureOpenai, + // azure_openai_api_key: azureOpenaiAPIKey, + // azure_openai_endpoint: azureOpenaiEndpoint, + // azure_openai_35_turbo_id: azureOpenai35TurboID, + // azure_openai_45_turbo_id: azureOpenai45TurboID, + // azure_openai_45_vision_id: azureOpenai45VisionID, + // azure_openai_embeddings_id: azureOpenaiEmbeddingsID + // } - const workspaces = await getWorkspacesByUserId(profile.user_id) - const homeWorkspace = workspaces.find(w => w.is_home) + // const updatedProfile = await updateProfile(profile.id, updateProfilePayload) + // setProfile(updatedProfile) + + // const workspaces = await getWorkspacesByUserId(profile.user_id) + // const homeWorkspace = workspaces.find(w => w.is_home) - if (!homeWorkspace) { - throw new Error("Home workspace not found for user during setup. This should not happen.") + // if (!homeWorkspace) { + // throw new Error("Home workspace not found for user during setup. This should not happen.") + // } + + // const baseUrl = typeof window !== "undefined" + // ? `http://${window.location.hostname}:30000/v1` + // : "http://localhost:30000/v1" + + // if (typeof window !== "undefined") { + // await createModel( + // { + // user_id: profile.user_id, + // name: "Default", + // model_id: "GPT", + // base_url: baseUrl, + // api_key: "token-abc123", + // description: "Default LLM model created during onboarding", + // context_length: 131072 + // }, + // homeWorkspace.id + // ) + // } + + // // There will always be a home workspace + // setSelectedWorkspace(homeWorkspace!) + // setWorkspaces(workspaces) + + // return router.push(getLocalizedPath(`${homeWorkspace?.id}/chat`)) + // } + + const handleSaveSetupSetting = async () => { + if (isSubmitting) return + setIsSubmitting(true) + + try { + const session = (await supabase.auth.getSession()).data.session + if (!session) { + return router.push(getLocalizedPath("login")) + } + + const user = session.user + const profile = await getProfileByUserId(user.id) + + const updateProfilePayload: TablesUpdate<"profiles"> = { + ...profile, + has_onboarded: true, + display_name: displayName, + username, + openai_api_key: openaiAPIKey, + openai_organization_id: openaiOrgID, + anthropic_api_key: anthropicAPIKey, + google_gemini_api_key: googleGeminiAPIKey, + mistral_api_key: mistralAPIKey, + groq_api_key: groqAPIKey, + perplexity_api_key: perplexityAPIKey, + openrouter_api_key: openrouterAPIKey, + use_azure_openai: useAzureOpenai, + azure_openai_api_key: azureOpenaiAPIKey, + azure_openai_endpoint: azureOpenaiEndpoint, + azure_openai_35_turbo_id: azureOpenai35TurboID, + azure_openai_45_turbo_id: azureOpenai45TurboID, + azure_openai_45_vision_id: azureOpenai45VisionID, + azure_openai_embeddings_id: azureOpenaiEmbeddingsID + } + + const updatedProfile = await updateProfile(profile.id, updateProfilePayload) + setProfile(updatedProfile) + + const workspaces = await getWorkspacesByUserId(profile.user_id) + const homeWorkspace = workspaces.find(w => w.is_home) + + if (!homeWorkspace) { + throw new Error("Home workspace not found.") + } + + const baseUrl = typeof window !== "undefined" + ? `http://${window.location.hostname}:30000/v1` + : "http://localhost:30000/v1" + + if (typeof window !== "undefined") { + await createModel( + { + user_id: profile.user_id, + name: "Default", + model_id: "GPT", + base_url: baseUrl, + api_key: "token-abc123", + description: "Default LLM model created during onboarding", + context_length: 131072 + }, + homeWorkspace.id + ) + } + + setSelectedWorkspace(homeWorkspace) + setWorkspaces(workspaces) + + router.push(getLocalizedPath(`${homeWorkspace.id}/chat`)) + } catch (err) { + console.error("Setup failed:", err) + setIsSubmitting(false) // 失败后允许重试 } - - const baseUrl = typeof window !== "undefined" - ? `http://${window.location.hostname}:30000/v1` - : "http://localhost:30000/v1" - - if (typeof window !== "undefined") { - await createModel( - { - user_id: profile.user_id, - name: "Default", - model_id: "GPT", - base_url: baseUrl, - api_key: "token-abc123", - description: "Default LLM model created during onboarding", - context_length: 131072 - }, - homeWorkspace.id - ) - } - - // There will always be a home workspace - setSelectedWorkspace(homeWorkspace!) - setWorkspaces(workspaces) - - return router.push(getLocalizedPath(`${homeWorkspace?.id}/chat`)) } + const renderStep = (stepNum: number) => { switch (stepNum) { @@ -285,7 +368,8 @@ export default function SetupPage() { stepNum={currentStep} stepTitle={t("setup.SetupComplete")} onShouldProceed={handleShouldProceed} - showNextButton={true} + //showNextButton={true} + showNextButton={!isSubmitting} // 禁用按钮 showBackButton={true} > diff --git a/chatdesk-ui/components/setup/step-container.tsx b/chatdesk-ui/components/setup/step-container.tsx index f2ad0e2..3cdae77 100644 --- a/chatdesk-ui/components/setup/step-container.tsx +++ b/chatdesk-ui/components/setup/step-container.tsx @@ -80,6 +80,7 @@ export const StepContainer: FC = ({ ref={buttonRef} size="sm" onClick={() => onShouldProceed(true)} + disabled={!showNextButton} > {t("setup.next")}