| @@ -212,7 +212,7 @@ const NewAppDialog = ({ show, onSuccess, onClose }: NewAppDialogProps) => { | |||
| </> | |||
| )} | |||
| </div> | |||
| {isAppsFull && <AppsFull />} | |||
| {isAppsFull && <AppsFull loc='app-create' />} | |||
| </Dialog> | |||
| </> | |||
| } | |||
| @@ -1,5 +1,7 @@ | |||
| import React, { FC } from 'react' | |||
| import type { FC } from 'react' | |||
| import React from 'react' | |||
| import Script from 'next/script' | |||
| import { IS_CE_EDITION } from '@/config' | |||
| export enum GaType { | |||
| admin = 'admin', | |||
| @@ -11,27 +13,34 @@ const gaIdMaps = { | |||
| [GaType.webapp]: 'G-2MFWXK7WYT', | |||
| } | |||
| export interface IGAProps { | |||
| export type IGAProps = { | |||
| gaType: GaType | |||
| } | |||
| const GA: FC<IGAProps> = ({ | |||
| gaType | |||
| gaType, | |||
| }) => { | |||
| if (IS_CE_EDITION) | |||
| return null | |||
| return ( | |||
| <Script | |||
| id="gtag-base" | |||
| strategy="beforeInteractive" | |||
| dangerouslySetInnerHTML={{ | |||
| __html: ` | |||
| (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': | |||
| new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], | |||
| j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= | |||
| 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); | |||
| })(window,document,'script','dataLayer', '${gaIdMaps[gaType]}'); | |||
| <> | |||
| <Script strategy="beforeInteractive" async src={`https://www.googletagmanager.com/gtag/js?id=${gaIdMaps[gaType]}`}></Script> | |||
| <Script | |||
| id="ga-init" | |||
| dangerouslySetInnerHTML={{ | |||
| __html: ` | |||
| window.dataLayer = window.dataLayer || []; | |||
| function gtag(){dataLayer.push(arguments);} | |||
| gtag('js', new Date()); | |||
| gtag('config', '${gaIdMaps[gaType]}'); | |||
| `, | |||
| }} /> | |||
| }} | |||
| > | |||
| </Script> | |||
| </> | |||
| ) | |||
| } | |||
| export default React.memo(GA) | |||
| @@ -8,7 +8,9 @@ import AppsInfo from '../usage-info/apps-info' | |||
| import s from './style.module.css' | |||
| import GridMask from '@/app/components/base/grid-mask' | |||
| const AppsFull: FC = () => { | |||
| const AppsFull: FC<{ loc: string }> = ({ | |||
| loc, | |||
| }) => { | |||
| const { t } = useTranslation() | |||
| return ( | |||
| @@ -20,7 +22,7 @@ const AppsFull: FC = () => { | |||
| <div>{t('billing.apps.fullTipLine2')}</div> | |||
| </div> | |||
| <div className='flex'> | |||
| <UpgradeBtn /> | |||
| <UpgradeBtn loc={loc} /> | |||
| </div> | |||
| </div> | |||
| <AppsInfo className='mt-4' /> | |||
| @@ -18,7 +18,7 @@ const AppsFull: FC = () => { | |||
| <div>{t('billing.apps.fullTipLine2')}</div> | |||
| </div> | |||
| <div className='flex mt-8'> | |||
| <UpgradeBtn /> | |||
| <UpgradeBtn loc='app-create' /> | |||
| </div> | |||
| </div> | |||
| </GridMask> | |||
| @@ -26,7 +26,7 @@ const Billing: FC = () => { | |||
| return ( | |||
| <div> | |||
| <PlanComp /> | |||
| <PlanComp loc={'billing-page'} /> | |||
| {enableBilling && isCurrentWorkspaceManager && billingUrl && ( | |||
| <a className='mt-5 flex px-6 justify-between h-12 items-center bg-gray-50 rounded-xl cursor-pointer' href={billingUrl} target='_blank'> | |||
| <div className='flex items-center'> | |||
| @@ -29,7 +29,7 @@ const typeStyle = { | |||
| } | |||
| type Props = { | |||
| loc?: string | |||
| loc: string | |||
| } | |||
| const PlanComp: FC<Props> = ({ | |||
| @@ -69,7 +69,7 @@ const PlanComp: FC<Props> = ({ | |||
| <UpgradeBtn | |||
| className='flex-shrink-0' | |||
| isPlain={type !== Plan.sandbox} | |||
| gaEventName='click_header_upgrade_btn' | |||
| loc={loc} | |||
| /> | |||
| )} | |||
| </div> | |||
| @@ -84,7 +84,7 @@ const PlanComp: FC<Props> = ({ | |||
| isFull | |||
| size='lg' | |||
| isPlain={type !== Plan.sandbox} | |||
| gaEventName='click_header_upgrade_btn' | |||
| loc={loc} | |||
| /> | |||
| )} | |||
| </div> | |||
| @@ -141,8 +141,18 @@ const PlanItem: FC<Props> = ({ | |||
| setLoading(true) | |||
| try { | |||
| const res = await fetchSubscriptionUrls(plan, isYear ? 'year' : 'month') | |||
| window.location.href = res.url | |||
| if ((window as any).gtag) { | |||
| (window as any).gtag('event', 'click_pay_btn', { | |||
| plan, | |||
| interval: isYear ? 'year' : 'month', | |||
| event_callback: () => { | |||
| window.location.href = res.url | |||
| }, | |||
| }) | |||
| } | |||
| else { | |||
| window.location.href = res.url | |||
| } | |||
| } | |||
| finally { | |||
| setLoading(false) | |||
| @@ -15,7 +15,7 @@ type Props = { | |||
| isPlain?: boolean | |||
| isShort?: boolean | |||
| onClick?: () => void | |||
| gaEventName?: string | |||
| loc?: string | |||
| } | |||
| const PlainBtn = ({ className, onClick }: { className?: string; onClick: () => void }) => { | |||
| @@ -40,18 +40,27 @@ const UpgradeBtn: FC<Props> = ({ | |||
| isShort = false, | |||
| size = 'md', | |||
| onClick: _onClick, | |||
| gaEventName, | |||
| loc, | |||
| }) => { | |||
| const { t } = useTranslation() | |||
| const { setShowPricingModal } = useModalContext() | |||
| const onClick = () => { | |||
| if (gaEventName) | |||
| (window as any).dataLayer.push({ event: gaEventName }) | |||
| const handleClick = () => { | |||
| if (_onClick) | |||
| _onClick() | |||
| else | |||
| (setShowPricingModal as any)() | |||
| } | |||
| const onClick = () => { | |||
| if (loc && (window as any).gtag) { | |||
| (window as any).gtag('event', 'click_upgrade_btn', { | |||
| loc, | |||
| event_callback: handleClick, | |||
| }) | |||
| } | |||
| else { | |||
| handleClick() | |||
| } | |||
| } | |||
| if (isPlain) | |||
| return <PlainBtn onClick={onClick} className={className} /> | |||
| @@ -22,7 +22,7 @@ const VectorSpaceFull: FC = () => { | |||
| <div>{t('billing.vectorSpace.fullTip')}</div> | |||
| <div>{t('billing.vectorSpace.fullSolution')}</div> | |||
| </div> | |||
| <UpgradeBtn /> | |||
| <UpgradeBtn loc='knowledge-add-file' /> | |||
| </div> | |||
| <VectorSpaceInfo className='pt-4' /> | |||
| </div> | |||
| @@ -206,7 +206,7 @@ const EmbeddingProcess: FC<Props> = ({ datasetId, batchId, documents = [], index | |||
| <div className='grow mx-3 text-[13px] font-medium text-gray-700'> | |||
| {t('billing.plansCommon.documentProcessingPriorityUpgrade')} | |||
| </div> | |||
| <UpgradeBtn /> | |||
| <UpgradeBtn loc='knowledge-speed-up' /> | |||
| </div> | |||
| ) | |||
| } | |||
| @@ -68,7 +68,7 @@ const CreateAppModal = ({ | |||
| className='h-10 px-3 text-sm font-normal bg-gray-100 rounded-lg grow' | |||
| /> | |||
| </div> | |||
| {isAppsFull && <AppsFull />} | |||
| {isAppsFull && <AppsFull loc='app-explore-create'/>} | |||
| </div> | |||
| <div className='flex flex-row-reverse'> | |||
| <Button disabled={isAppsFull} className='w-24 ml-2' type='primary' onClick={submit}>{t('common.operation.create')}</Button> | |||
| @@ -71,7 +71,7 @@ const MembersPage = () => { | |||
| </div> | |||
| {isMemberFull && ( | |||
| <UpgradeBtn className='mr-2' /> | |||
| <UpgradeBtn className='mr-2' loc='member-invite' /> | |||
| )} | |||
| <div className={ | |||
| `shrink-0 flex items-center py-[7px] px-3 border-[0.5px] border-gray-200 | |||