refactor(frontend): Extracted useQuery and useMutation from the main branch (#12031)

Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com>
This commit is contained in:
Abhay Mishra 2025-12-15 22:07:52 +05:30 committed by GitHub
parent 5c377f303f
commit a12170e4c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 105 additions and 77 deletions

View File

@ -1,24 +1,14 @@
import { useMutation } from "@tanstack/react-query";
import { Trans, useTranslation } from "react-i18next"; import { Trans, useTranslation } from "react-i18next";
import { I18nKey } from "#/i18n/declaration"; import { I18nKey } from "#/i18n/declaration";
import OpenHandsLogo from "#/assets/branding/openhands-logo.svg?react"; import OpenHandsLogo from "#/assets/branding/openhands-logo.svg?react";
import { ModalBackdrop } from "#/components/shared/modals/modal-backdrop"; import { ModalBackdrop } from "#/components/shared/modals/modal-backdrop";
import { ModalBody } from "#/components/shared/modals/modal-body"; import { ModalBody } from "#/components/shared/modals/modal-body";
import BillingService from "#/api/billing-service/billing-service.api";
import { BrandButton } from "../settings/brand-button"; import { BrandButton } from "../settings/brand-button";
import { displayErrorToast } from "#/utils/custom-toast-handlers"; import { useCreateBillingSession } from "#/hooks/mutation/use-create-billing-session";
export function SetupPaymentModal() { export function SetupPaymentModal() {
const { t } = useTranslation(); const { t } = useTranslation();
const { mutate, isPending } = useMutation({ const { mutate, isPending } = useCreateBillingSession();
mutationFn: BillingService.createBillingSessionResponse,
onSuccess: (data) => {
window.location.href = data;
},
onError: () => {
displayErrorToast(t(I18nKey.BILLING$ERROR_WHILE_CREATING_SESSION));
},
});
return ( return (
<ModalBackdrop> <ModalBackdrop>

View File

@ -13,10 +13,8 @@ import { CreateApiKeyModal } from "./create-api-key-modal";
import { DeleteApiKeyModal } from "./delete-api-key-modal"; import { DeleteApiKeyModal } from "./delete-api-key-modal";
import { NewApiKeyModal } from "./new-api-key-modal"; import { NewApiKeyModal } from "./new-api-key-modal";
import { useApiKeys } from "#/hooks/query/use-api-keys"; import { useApiKeys } from "#/hooks/query/use-api-keys";
import { import { useLlmApiKey } from "#/hooks/query/use-llm-api-key";
useLlmApiKey, import { useRefreshLlmApiKey } from "#/hooks/mutation/use-refresh-llm-api-key";
useRefreshLlmApiKey,
} from "#/hooks/query/use-llm-api-key";
interface LlmApiKeyManagerProps { interface LlmApiKeyManagerProps {
llmApiKey: { key: string | null } | undefined; llmApiKey: { key: string | null } | undefined;

View File

@ -0,0 +1,54 @@
import { useMutation } from "@tanstack/react-query";
import { usePostHog } from "posthog-js/react";
import { useNavigate } from "react-router";
import { openHands } from "#/api/open-hands-axios";
import { handleCaptureConsent } from "#/utils/handle-capture-consent";
import { useTracking } from "#/hooks/use-tracking";
interface AcceptTosVariables {
redirectUrl: string;
}
interface AcceptTosResponse {
redirect_url?: string;
}
export const useAcceptTos = () => {
const posthog = usePostHog();
const navigate = useNavigate();
const { trackUserSignupCompleted } = useTracking();
return useMutation({
mutationFn: async ({ redirectUrl }: AcceptTosVariables) => {
// Set consent for analytics
handleCaptureConsent(posthog, true);
// Call the API to record TOS acceptance in the database
return openHands.post<AcceptTosResponse>("/api/accept_tos", {
redirect_url: redirectUrl,
});
},
onSuccess: (response, { redirectUrl }) => {
// Track user signup completion
trackUserSignupCompleted();
// Get the redirect URL from the response
const finalRedirectUrl = response.data.redirect_url || redirectUrl;
// Check if the redirect URL is an external URL (starts with http or https)
if (
finalRedirectUrl.startsWith("http://") ||
finalRedirectUrl.startsWith("https://")
) {
// For external URLs, redirect using window.location
window.location.href = finalRedirectUrl;
} else {
// For internal routes, use navigate
navigate(finalRedirectUrl);
}
},
onError: () => {
window.location.href = "/";
},
});
};

View File

@ -0,0 +1,19 @@
import { useMutation } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";
import { I18nKey } from "#/i18n/declaration";
import BillingService from "#/api/billing-service/billing-service.api";
import { displayErrorToast } from "#/utils/custom-toast-handlers";
export const useCreateBillingSession = () => {
const { t } = useTranslation();
return useMutation({
mutationFn: BillingService.createBillingSessionResponse,
onSuccess: (data) => {
window.location.href = data;
},
onError: () => {
displayErrorToast(t(I18nKey.BILLING$ERROR_WHILE_CREATING_SESSION));
},
});
};

View File

@ -0,0 +1,23 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { openHands } from "#/api/open-hands-axios";
import {
LLM_API_KEY_QUERY_KEY,
LlmApiKeyResponse,
} from "#/hooks/query/use-llm-api-key";
export function useRefreshLlmApiKey() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async () => {
const { data } = await openHands.post<LlmApiKeyResponse>(
"/api/keys/llm/byor/refresh",
);
return data;
},
onSuccess: () => {
// Invalidate the LLM API key query to trigger a refetch
queryClient.invalidateQueries({ queryKey: [LLM_API_KEY_QUERY_KEY] });
},
});
}

View File

@ -1,4 +1,4 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { openHands } from "#/api/open-hands-axios"; import { openHands } from "#/api/open-hands-axios";
import { useConfig } from "./use-config"; import { useConfig } from "./use-config";
@ -23,20 +23,3 @@ export function useLlmApiKey() {
gcTime: 1000 * 60 * 15, // 15 minutes gcTime: 1000 * 60 * 15, // 15 minutes
}); });
} }
export function useRefreshLlmApiKey() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async () => {
const { data } = await openHands.post<LlmApiKeyResponse>(
"/api/keys/llm/byor/refresh",
);
return data;
},
onSuccess: () => {
// Invalidate the LLM API key query to trigger a refetch
queryClient.invalidateQueries({ queryKey: [LLM_API_KEY_QUERY_KEY] });
},
});
}

View File

@ -1,66 +1,27 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useNavigate, useSearchParams } from "react-router"; import { useSearchParams } from "react-router";
import { useMutation } from "@tanstack/react-query";
import { usePostHog } from "posthog-js/react";
import { I18nKey } from "#/i18n/declaration"; import { I18nKey } from "#/i18n/declaration";
import OpenHandsLogo from "#/assets/branding/openhands-logo.svg?react"; import OpenHandsLogo from "#/assets/branding/openhands-logo.svg?react";
import { TOSCheckbox } from "#/components/features/waitlist/tos-checkbox"; import { TOSCheckbox } from "#/components/features/waitlist/tos-checkbox";
import { BrandButton } from "#/components/features/settings/brand-button"; import { BrandButton } from "#/components/features/settings/brand-button";
import { handleCaptureConsent } from "#/utils/handle-capture-consent";
import { openHands } from "#/api/open-hands-axios";
import { ModalBackdrop } from "#/components/shared/modals/modal-backdrop"; import { ModalBackdrop } from "#/components/shared/modals/modal-backdrop";
import { useTracking } from "#/hooks/use-tracking"; import { useAcceptTos } from "#/hooks/mutation/use-accept-tos";
export default function AcceptTOS() { export default function AcceptTOS() {
const posthog = usePostHog();
const { t } = useTranslation(); const { t } = useTranslation();
const navigate = useNavigate();
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const [isTosAccepted, setIsTosAccepted] = React.useState(false); const [isTosAccepted, setIsTosAccepted] = React.useState(false);
const { trackUserSignupCompleted } = useTracking();
// Get the redirect URL from the query parameters // Get the redirect URL from the query parameters
const redirectUrl = searchParams.get("redirect_url") || "/"; const redirectUrl = searchParams.get("redirect_url") || "/";
// Use mutation for accepting TOS // Use mutation for accepting TOS
const { mutate: acceptTOS, isPending: isSubmitting } = useMutation({ const { mutate: acceptTOS, isPending: isSubmitting } = useAcceptTos();
mutationFn: async () => {
// Set consent for analytics
handleCaptureConsent(posthog, true);
// Call the API to record TOS acceptance in the database
return openHands.post("/api/accept_tos", {
redirect_url: redirectUrl,
});
},
onSuccess: (response) => {
// Track user signup completion
trackUserSignupCompleted();
// Get the redirect URL from the response
const finalRedirectUrl = response.data.redirect_url || redirectUrl;
// Check if the redirect URL is an external URL (starts with http or https)
if (
finalRedirectUrl.startsWith("http://") ||
finalRedirectUrl.startsWith("https://")
) {
// For external URLs, redirect using window.location
window.location.href = finalRedirectUrl;
} else {
// For internal routes, use navigate
navigate(finalRedirectUrl);
}
},
onError: () => {
window.location.href = "/";
},
});
const handleAcceptTOS = () => { const handleAcceptTOS = () => {
if (isTosAccepted && !isSubmitting) { if (isTosAccepted && !isSubmitting) {
acceptTOS(); acceptTOS({ redirectUrl });
} }
}; };