|
@@ -0,0 +1,167 @@
|
|
|
|
|
+import { useCallback } from 'react';
|
|
|
|
|
+
|
|
|
|
|
+import { Trans, useTranslation } from 'react-i18next';
|
|
|
|
|
+
|
|
|
|
|
+import LoginForm from '@/components/LoginForm';
|
|
|
|
|
+import { useAppUrls } from '@/hooks/useAppUrls';
|
|
|
|
|
+import { dialogModel } from '@/models/dialogModel';
|
|
|
|
|
+import { fetchPayOrderCreate } from '@/services/config';
|
|
|
|
|
+import { getToken } from '@/utils/authUtils';
|
|
|
|
|
+import { currentUnixTimestamp } from '@/utils/timeUtils';
|
|
|
|
|
+
|
|
|
|
|
+import { PayWaitingContent } from './PayWaitingContent';
|
|
|
|
|
+import type { Plan } from '../../useService';
|
|
|
|
|
+
|
|
|
|
|
+const ORDER_TYPE_PLAN = 1;
|
|
|
|
|
+
|
|
|
|
|
+export interface UseActionReturn {
|
|
|
|
|
+ handlePayNow: () => void;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export interface UseActionParams {
|
|
|
|
|
+ selectedPlan: Plan | null;
|
|
|
|
|
+ selectedPayMethod: string | null;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function useAction({ selectedPlan, selectedPayMethod }: UseActionParams): UseActionReturn {
|
|
|
|
|
+ const { t } = useTranslation();
|
|
|
|
|
+ const { openDialog, closeDialog } = dialogModel.useModel();
|
|
|
|
|
+ const { deeplinkUrl, downloadUrlByPlatform } = useAppUrls();
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ const handlePayNow = useCallback(() => {
|
|
|
|
|
+ if (!selectedPlan || !selectedPayMethod) return;
|
|
|
|
|
+ console.log('🚀 ~ useAction.tsx:30 ~ useAction ~ downloadUrlByPlatform:', downloadUrlByPlatform);
|
|
|
|
|
+ console.log('🚀 ~ useAction.tsx:30 ~ useAction ~ deeplinkUrl:', deeplinkUrl);
|
|
|
|
|
+ const token = getToken();
|
|
|
|
|
+ const expired =
|
|
|
|
|
+ !token?.accessExpires || (token.accessExpires ?? 0) - currentUnixTimestamp() <= 0;
|
|
|
|
|
+ if (!token?.accessToken || expired) {
|
|
|
|
|
+ const id = openDialog({
|
|
|
|
|
+ title: t('pages.pricing.payFlow.loginTitle'),
|
|
|
|
|
+ content: (
|
|
|
|
|
+ <div className="flex flex-col gap-2">
|
|
|
|
|
+ <p className="text-white/80 text-sm mb-2">
|
|
|
|
|
+ <Trans
|
|
|
|
|
+ i18nKey="pages.pricing.payFlow.loginPrompt"
|
|
|
|
|
+ components={{
|
|
|
|
|
+ linkText: (() => {
|
|
|
|
|
+ const Wrap = ({
|
|
|
|
|
+ children,
|
|
|
|
|
+ }: {
|
|
|
|
|
+ children?: React.ReactNode;
|
|
|
|
|
+ }) =>
|
|
|
|
|
+ deeplinkUrl ? (
|
|
|
|
|
+ <a
|
|
|
|
|
+ href={deeplinkUrl}
|
|
|
|
|
+ className="text-[#0EA5E9] hover:underline"
|
|
|
|
|
+ target="_blank"
|
|
|
|
|
+ rel="noopener noreferrer"
|
|
|
|
|
+ >
|
|
|
|
|
+ {children}
|
|
|
|
|
+ </a>
|
|
|
|
|
+ ) : (
|
|
|
|
|
+ <span>{children}</span>
|
|
|
|
|
+ );
|
|
|
|
|
+ return <Wrap />;
|
|
|
|
|
+ })(),
|
|
|
|
|
+ downloadLink: (() => {
|
|
|
|
|
+ const Wrap = ({
|
|
|
|
|
+ children,
|
|
|
|
|
+ }: {
|
|
|
|
|
+ children?: React.ReactNode;
|
|
|
|
|
+ }) =>
|
|
|
|
|
+ downloadUrlByPlatform ? (
|
|
|
|
|
+ <a
|
|
|
|
|
+ href={downloadUrlByPlatform}
|
|
|
|
|
+ className="text-[#0EA5E9] hover:underline"
|
|
|
|
|
+ target="_blank"
|
|
|
|
|
+ rel="noopener noreferrer"
|
|
|
|
|
+ >
|
|
|
|
|
+ {children}
|
|
|
|
|
+ </a>
|
|
|
|
|
+ ) : (
|
|
|
|
|
+ <span>{children}</span>
|
|
|
|
|
+ );
|
|
|
|
|
+ return <Wrap />;
|
|
|
|
|
+ })(),
|
|
|
|
|
+ }}
|
|
|
|
|
+ />
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <LoginForm onSuccess={() => closeDialog(id)} />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ ),
|
|
|
|
|
+ maskClosable: true,
|
|
|
|
|
+ });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ fetchPayOrderCreate({
|
|
|
|
|
+ orderType: ORDER_TYPE_PLAN,
|
|
|
|
|
+ payType: selectedPayMethod,
|
|
|
|
|
+ channelItemId: selectedPlan.id,
|
|
|
|
|
+ })
|
|
|
|
|
+ .then((res) => {
|
|
|
|
|
+ const order = res?.data?.userPayOrder;
|
|
|
|
|
+ if (!order?.payUrl || !order?.orderId) return;
|
|
|
|
|
+
|
|
|
|
|
+ openDialog({
|
|
|
|
|
+ title: t('pages.pricing.payFlow.goToPayTitle'),
|
|
|
|
|
+ content: (
|
|
|
|
|
+ <p className="text-white/90 text-sm leading-[1.43]">
|
|
|
|
|
+ {t('pages.pricing.payFlow.goToPayDesc')}
|
|
|
|
|
+ </p>
|
|
|
|
|
+ ),
|
|
|
|
|
+ buttons: [
|
|
|
|
|
+ {
|
|
|
|
|
+ label: t('pages.pricing.payFlow.goToPayButton'),
|
|
|
|
|
+ variant: 'primary',
|
|
|
|
|
+ onClick: (
|
|
|
|
|
+ _e: React.MouseEvent<HTMLButtonElement>,
|
|
|
|
|
+ dialogId: string
|
|
|
|
|
+ ) => {
|
|
|
|
|
+ window.open(order.payUrl, '_blank');
|
|
|
|
|
+ closeDialog(dialogId);
|
|
|
|
|
+ const waitId = openDialog({
|
|
|
|
|
+ title: t('pages.pricing.payFlow.waitingTitle'),
|
|
|
|
|
+ content: (
|
|
|
|
|
+ <PayWaitingContent
|
|
|
|
|
+ orderId={order.orderId}
|
|
|
|
|
+ onClose={() => closeDialog(waitId)}
|
|
|
|
|
+ />
|
|
|
|
|
+ ),
|
|
|
|
|
+ buttons: [
|
|
|
|
|
+ {
|
|
|
|
|
+ label: t('pages.pricing.payFlow.closeWaiting'),
|
|
|
|
|
+ variant: 'secondary',
|
|
|
|
|
+ onClick: (
|
|
|
|
|
+ _e: React.MouseEvent<HTMLButtonElement>,
|
|
|
|
|
+ dialogId: string
|
|
|
|
|
+ ) => {
|
|
|
|
|
+ closeDialog(dialogId);
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ maskClosable: false,
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ maskClosable: true,
|
|
|
|
|
+ });
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(() => {});
|
|
|
|
|
+ }, [
|
|
|
|
|
+ selectedPlan,
|
|
|
|
|
+ selectedPayMethod,
|
|
|
|
|
+ t,
|
|
|
|
|
+ openDialog,
|
|
|
|
|
+ closeDialog,
|
|
|
|
|
+ deeplinkUrl,
|
|
|
|
|
+ downloadUrlByPlatform,
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ handlePayNow,
|
|
|
|
|
+ };
|
|
|
|
|
+}
|