| </> | </> | ||||
| )} | )} | ||||
| </div> | </div> | ||||
| {isAppsFull && <AppsFull />} | |||||
| {isAppsFull && <AppsFull loc='app-create' />} | |||||
| </Dialog> | </Dialog> | ||||
| </> | </> | ||||
| } | } |
| import React, { FC } from 'react' | |||||
| import type { FC } from 'react' | |||||
| import React from 'react' | |||||
| import Script from 'next/script' | import Script from 'next/script' | ||||
| import { IS_CE_EDITION } from '@/config' | |||||
| export enum GaType { | export enum GaType { | ||||
| admin = 'admin', | admin = 'admin', | ||||
| [GaType.webapp]: 'G-2MFWXK7WYT', | [GaType.webapp]: 'G-2MFWXK7WYT', | ||||
| } | } | ||||
| export interface IGAProps { | |||||
| export type IGAProps = { | |||||
| gaType: GaType | gaType: GaType | ||||
| } | } | ||||
| const GA: FC<IGAProps> = ({ | const GA: FC<IGAProps> = ({ | ||||
| gaType | |||||
| gaType, | |||||
| }) => { | }) => { | ||||
| if (IS_CE_EDITION) | |||||
| return null | |||||
| return ( | 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) | export default React.memo(GA) |
| import s from './style.module.css' | import s from './style.module.css' | ||||
| import GridMask from '@/app/components/base/grid-mask' | import GridMask from '@/app/components/base/grid-mask' | ||||
| const AppsFull: FC = () => { | |||||
| const AppsFull: FC<{ loc: string }> = ({ | |||||
| loc, | |||||
| }) => { | |||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| return ( | return ( | ||||
| <div>{t('billing.apps.fullTipLine2')}</div> | <div>{t('billing.apps.fullTipLine2')}</div> | ||||
| </div> | </div> | ||||
| <div className='flex'> | <div className='flex'> | ||||
| <UpgradeBtn /> | |||||
| <UpgradeBtn loc={loc} /> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <AppsInfo className='mt-4' /> | <AppsInfo className='mt-4' /> |
| <div>{t('billing.apps.fullTipLine2')}</div> | <div>{t('billing.apps.fullTipLine2')}</div> | ||||
| </div> | </div> | ||||
| <div className='flex mt-8'> | <div className='flex mt-8'> | ||||
| <UpgradeBtn /> | |||||
| <UpgradeBtn loc='app-create' /> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </GridMask> | </GridMask> |
| return ( | return ( | ||||
| <div> | <div> | ||||
| <PlanComp /> | |||||
| <PlanComp loc={'billing-page'} /> | |||||
| {enableBilling && isCurrentWorkspaceManager && billingUrl && ( | {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'> | <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'> | <div className='flex items-center'> |
| } | } | ||||
| type Props = { | type Props = { | ||||
| loc?: string | |||||
| loc: string | |||||
| } | } | ||||
| const PlanComp: FC<Props> = ({ | const PlanComp: FC<Props> = ({ | ||||
| <UpgradeBtn | <UpgradeBtn | ||||
| className='flex-shrink-0' | className='flex-shrink-0' | ||||
| isPlain={type !== Plan.sandbox} | isPlain={type !== Plan.sandbox} | ||||
| gaEventName='click_header_upgrade_btn' | |||||
| loc={loc} | |||||
| /> | /> | ||||
| )} | )} | ||||
| </div> | </div> | ||||
| isFull | isFull | ||||
| size='lg' | size='lg' | ||||
| isPlain={type !== Plan.sandbox} | isPlain={type !== Plan.sandbox} | ||||
| gaEventName='click_header_upgrade_btn' | |||||
| loc={loc} | |||||
| /> | /> | ||||
| )} | )} | ||||
| </div> | </div> |
| setLoading(true) | setLoading(true) | ||||
| try { | try { | ||||
| const res = await fetchSubscriptionUrls(plan, isYear ? 'year' : 'month') | 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 { | finally { | ||||
| setLoading(false) | setLoading(false) |
| isPlain?: boolean | isPlain?: boolean | ||||
| isShort?: boolean | isShort?: boolean | ||||
| onClick?: () => void | onClick?: () => void | ||||
| gaEventName?: string | |||||
| loc?: string | |||||
| } | } | ||||
| const PlainBtn = ({ className, onClick }: { className?: string; onClick: () => void }) => { | const PlainBtn = ({ className, onClick }: { className?: string; onClick: () => void }) => { | ||||
| isShort = false, | isShort = false, | ||||
| size = 'md', | size = 'md', | ||||
| onClick: _onClick, | onClick: _onClick, | ||||
| gaEventName, | |||||
| loc, | |||||
| }) => { | }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const { setShowPricingModal } = useModalContext() | const { setShowPricingModal } = useModalContext() | ||||
| const onClick = () => { | |||||
| if (gaEventName) | |||||
| (window as any).dataLayer.push({ event: gaEventName }) | |||||
| const handleClick = () => { | |||||
| if (_onClick) | if (_onClick) | ||||
| _onClick() | _onClick() | ||||
| else | else | ||||
| (setShowPricingModal as any)() | (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) | if (isPlain) | ||||
| return <PlainBtn onClick={onClick} className={className} /> | return <PlainBtn onClick={onClick} className={className} /> |
| <div>{t('billing.vectorSpace.fullTip')}</div> | <div>{t('billing.vectorSpace.fullTip')}</div> | ||||
| <div>{t('billing.vectorSpace.fullSolution')}</div> | <div>{t('billing.vectorSpace.fullSolution')}</div> | ||||
| </div> | </div> | ||||
| <UpgradeBtn /> | |||||
| <UpgradeBtn loc='knowledge-add-file' /> | |||||
| </div> | </div> | ||||
| <VectorSpaceInfo className='pt-4' /> | <VectorSpaceInfo className='pt-4' /> | ||||
| </div> | </div> |
| <div className='grow mx-3 text-[13px] font-medium text-gray-700'> | <div className='grow mx-3 text-[13px] font-medium text-gray-700'> | ||||
| {t('billing.plansCommon.documentProcessingPriorityUpgrade')} | {t('billing.plansCommon.documentProcessingPriorityUpgrade')} | ||||
| </div> | </div> | ||||
| <UpgradeBtn /> | |||||
| <UpgradeBtn loc='knowledge-speed-up' /> | |||||
| </div> | </div> | ||||
| ) | ) | ||||
| } | } |
| className='h-10 px-3 text-sm font-normal bg-gray-100 rounded-lg grow' | className='h-10 px-3 text-sm font-normal bg-gray-100 rounded-lg grow' | ||||
| /> | /> | ||||
| </div> | </div> | ||||
| {isAppsFull && <AppsFull />} | |||||
| {isAppsFull && <AppsFull loc='app-explore-create'/>} | |||||
| </div> | </div> | ||||
| <div className='flex flex-row-reverse'> | <div className='flex flex-row-reverse'> | ||||
| <Button disabled={isAppsFull} className='w-24 ml-2' type='primary' onClick={submit}>{t('common.operation.create')}</Button> | <Button disabled={isAppsFull} className='w-24 ml-2' type='primary' onClick={submit}>{t('common.operation.create')}</Button> |
| </div> | </div> | ||||
| {isMemberFull && ( | {isMemberFull && ( | ||||
| <UpgradeBtn className='mr-2' /> | |||||
| <UpgradeBtn className='mr-2' loc='member-invite' /> | |||||
| )} | )} | ||||
| <div className={ | <div className={ | ||||
| `shrink-0 flex items-center py-[7px] px-3 border-[0.5px] border-gray-200 | `shrink-0 flex items-center py-[7px] px-3 border-[0.5px] border-gray-200 |