diff --git a/web/app/(commonLayout)/apps/Apps.tsx b/web/app/(commonLayout)/apps/Apps.tsx index 4ad79e8295..b8f8d9b7fd 100644 --- a/web/app/(commonLayout)/apps/Apps.tsx +++ b/web/app/(commonLayout)/apps/Apps.tsx @@ -1,6 +1,7 @@ 'use client' -import { useEffect, useRef } from 'react' +import { useEffect, useRef, useState } from 'react' +import { useRouter, useSearchParams } from 'next/navigation' import useSWRInfinite from 'swr/infinite' import { debounce } from 'lodash-es' import { useTranslation } from 'react-i18next' @@ -10,6 +11,8 @@ import type { AppListResponse } from '@/models/app' import { fetchAppList } from '@/service/apps' import { useAppContext, useSelector } from '@/context/app-context' import { NEED_REFRESH_APP_LIST_KEY } from '@/config' +import { ProviderEnum } from '@/app/components/header/account-setting/model-page/declarations' +import Confirm from '@/app/components/base/confirm/common' const getKey = (pageIndex: number, previousPageData: AppListResponse) => { if (!pageIndex || previousPageData.has_more) @@ -24,6 +27,11 @@ const Apps = () => { const loadingStateRef = useRef(false) const pageContainerRef = useSelector(state => state.pageContainerRef) const anchorRef = useRef(null) + const searchParams = useSearchParams() + const router = useRouter() + const payProviderName = searchParams.get('provider_name') + const payStatus = searchParams.get('payment_result') + const [showPayStatusModal, setShowPayStatusModal] = useState(false) useEffect(() => { document.title = `${t('app.title')} - Dify` @@ -31,6 +39,8 @@ const Apps = () => { localStorage.removeItem(NEED_REFRESH_APP_LIST_KEY) mutate() } + if (payProviderName === ProviderEnum.anthropic && (payStatus === 'succeeded' || payStatus === 'cancelled')) + setShowPayStatusModal(true) }, []) useEffect(() => { @@ -51,6 +61,11 @@ const Apps = () => { return () => pageContainerRef.current?.removeEventListener('scroll', onScroll) }, []) + const handleCancelShowPayStatusModal = () => { + setShowPayStatusModal(false) + router.replace('/', { forceOptimisticNavigation: false }) + } + return ( ) } diff --git a/web/app/components/base/confirm/common.module.css b/web/app/components/base/confirm/common.module.css index 5c3e8443e7..98c8cd5bb9 100644 --- a/web/app/components/base/confirm/common.module.css +++ b/web/app/components/base/confirm/common.module.css @@ -1,3 +1,7 @@ -.wrapper { +.wrapper-danger { background: linear-gradient(180deg, rgba(217, 45, 32, 0.05) 0%, rgba(217, 45, 32, 0.00) 24.02%), #F9FAFB; +} + +.wrapper-success { + background: linear-gradient(180deg, rgba(3, 152, 85, 0.05) 0%, rgba(3, 152, 85, 0.00) 22.44%), #F9FAFB; } \ No newline at end of file diff --git a/web/app/components/base/confirm/common.tsx b/web/app/components/base/confirm/common.tsx index 9bd73a86fd..f2c8776cbf 100644 --- a/web/app/components/base/confirm/common.tsx +++ b/web/app/components/base/confirm/common.tsx @@ -5,6 +5,7 @@ import s from './common.module.css' import Modal from '@/app/components/base/modal' import { XClose } from '@/app/components/base/icons/src/vender/line/general' import { AlertCircle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback' +import { CheckCircle } from '@/app/components/base/icons/src/vender/solid/general' import Button from '@/app/components/base/button' type ConfirmCommonProps = { @@ -13,7 +14,10 @@ type ConfirmCommonProps = { onCancel: () => void title: string desc?: string - onConfirm: () => void + onConfirm?: () => void + showOperate?: boolean + showOperateCancel?: boolean + confirmText?: string } const ConfirmCommon: FC = ({ @@ -23,6 +27,9 @@ const ConfirmCommon: FC = ({ title, desc, onConfirm, + showOperate = true, + showOperateCancel = true, + confirmText, }) => { const { t } = useTranslation() @@ -31,11 +38,15 @@ const ConfirmCommon: FC = ({ icon: , confirmText: t('common.operation.remove'), }, + success: { + icon: , + confirmText: t('common.operation.ok'), + }, } return ( {}} className='!w-[480px] !max-w-[480px] !p-0 !rounded-2xl'> -
+
@@ -46,21 +57,29 @@ const ConfirmCommon: FC = ({ { desc &&
{desc}
} -
- - -
+ { + showOperate && ( +
+ { + showOperateCancel && ( + + ) + } + +
+ ) + }
) diff --git a/web/app/components/header/account-setting/model-page/model-card/Quota.tsx b/web/app/components/header/account-setting/model-page/model-card/Quota.tsx index de21737bd3..0a0fd5a1c2 100644 --- a/web/app/components/header/account-setting/model-page/model-card/Quota.tsx +++ b/web/app/components/header/account-setting/model-page/model-card/Quota.tsx @@ -6,6 +6,7 @@ import Tooltip from '@/app/components/base/tooltip' import { InfoCircle } from '@/app/components/base/icons/src/vender/line/general' import { getPayUrl } from '@/service/common' import Button from '@/app/components/base/button' +import { formatNumber } from '@/utils/format' type QuotaProps = { currentProvider: Provider @@ -49,10 +50,10 @@ const Quota: FC = ({ const renderQuota = () => { if (systemPaid?.is_valid) - return systemPaid.quota_limit - systemPaid.quota_used + return formatNumber(systemPaid.quota_limit - systemPaid.quota_used) if (systemTrial.is_valid) - return systemTrial.quota_limit - systemTrial.quota_used + return formatNumber(systemTrial.quota_limit - systemTrial.quota_used) } const renderUnit = () => { if (systemPaid?.is_valid) diff --git a/web/i18n/lang/common.en.ts b/web/i18n/lang/common.en.ts index 277526e07e..e3f91d843e 100644 --- a/web/i18n/lang/common.en.ts +++ b/web/i18n/lang/common.en.ts @@ -28,6 +28,7 @@ const translation = { setup: 'Setup', getForFree: 'Get for free', reload: 'Reload', + ok: 'OK', }, placeholder: { input: 'Please enter', @@ -41,6 +42,8 @@ const translation = { modifiedSuccessfully: 'Modified successfully', modificationFailed: 'Modification failed', copySuccessfully: 'Copied successfully', + paySucceeded: 'Payment succeeded', + payCancelled: 'Payment cancelled', }, model: { params: { diff --git a/web/i18n/lang/common.zh.ts b/web/i18n/lang/common.zh.ts index 9e51c8abaa..70287db8ab 100644 --- a/web/i18n/lang/common.zh.ts +++ b/web/i18n/lang/common.zh.ts @@ -28,6 +28,7 @@ const translation = { setup: '设置', getForFree: '免费获取', reload: '刷新', + ok: '好的', }, placeholder: { input: '请输入', @@ -41,6 +42,8 @@ const translation = { modifiedSuccessfully: '修改成功', modificationFailed: '修改失败', copySuccessfully: '复制成功', + paySucceeded: '已支付成功', + payCancelled: '已取消支付', }, model: { params: {