mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-24 13:58:50 +08:00
feat: optional payment for frontend (#5056)
This commit is contained in:
@@ -28,6 +28,11 @@ const UserPlanButtonWithData = () => {
|
||||
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
if (plan === SubscriptionPlan.SelfHosted) {
|
||||
// Self hosted version doesn't have a payment apis.
|
||||
return <div className={styles.userPlanButton}>{plan}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip content={t['com.affine.payment.tag-tooltips']()} side="top">
|
||||
<div className={styles.userPlanButton} onClick={handleClick}>
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { useSelfHosted } from '../../../hooks/affine/use-server-flavor';
|
||||
import { useWorkspace } from '../../../hooks/use-workspace';
|
||||
import { DeleteLeaveWorkspace } from './delete-leave-workspace';
|
||||
import { ExportPanel } from './export';
|
||||
@@ -20,6 +21,7 @@ import type { WorkspaceSettingDetailProps } from './types';
|
||||
export const WorkspaceSettingDetail = (props: WorkspaceSettingDetailProps) => {
|
||||
const { workspaceId } = props;
|
||||
const t = useAFFiNEI18N();
|
||||
const isSelfHosted = useSelfHosted();
|
||||
const workspace = useWorkspace(workspaceId);
|
||||
const [name] = useBlockSuiteWorkspaceName(workspace.blockSuiteWorkspace);
|
||||
|
||||
@@ -56,7 +58,11 @@ export const WorkspaceSettingDetail = (props: WorkspaceSettingDetailProps) => {
|
||||
</SettingWrapper>
|
||||
<SettingWrapper title={t['com.affine.brand.affineCloud']()}>
|
||||
<PublishPanel workspace={workspace} {...props} />
|
||||
<MembersPanel workspace={workspace} {...props} />
|
||||
<MembersPanel
|
||||
workspace={workspace}
|
||||
upgradable={!isSelfHosted}
|
||||
{...props}
|
||||
/>
|
||||
</SettingWrapper>
|
||||
{storageAndExportSetting}
|
||||
<SettingWrapper>
|
||||
|
||||
+14
-8
@@ -51,6 +51,7 @@ enum MemberLimitCount {
|
||||
|
||||
const COUNT_PER_PAGE = 8;
|
||||
export interface MembersPanelProps extends WorkspaceSettingDetailProps {
|
||||
upgradable: boolean;
|
||||
workspace: AffineOfficialWorkspace;
|
||||
}
|
||||
type OnRevoke = (memberId: string) => void;
|
||||
@@ -70,6 +71,7 @@ const MembersPanelLocal = () => {
|
||||
export const CloudWorkspaceMembersPanel = ({
|
||||
workspace,
|
||||
isOwner,
|
||||
upgradable,
|
||||
}: MembersPanelProps) => {
|
||||
const workspaceId = workspace.id;
|
||||
const memberCount = useMemberCount(workspaceId);
|
||||
@@ -165,16 +167,20 @@ export const CloudWorkspaceMembersPanel = ({
|
||||
planName: plan,
|
||||
memberLimit,
|
||||
})}
|
||||
,
|
||||
<div className={style.goUpgradeWrapper} onClick={handleUpgrade}>
|
||||
<span className={style.goUpgrade}>
|
||||
{t['com.affine.payment.member.description.go-upgrade']()}
|
||||
</span>
|
||||
<ArrowRightBigIcon className={style.arrowRight} />
|
||||
</div>
|
||||
{upgradable ? (
|
||||
<>
|
||||
,
|
||||
<div className={style.goUpgradeWrapper} onClick={handleUpgrade}>
|
||||
<span className={style.goUpgrade}>
|
||||
{t['com.affine.payment.member.description.go-upgrade']()}
|
||||
</span>
|
||||
<ArrowRightBigIcon className={style.arrowRight} />
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
</span>
|
||||
);
|
||||
}, [handleUpgrade, memberLimit, plan, t]);
|
||||
}, [handleUpgrade, memberLimit, plan, t, upgradable]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
openSignOutModalAtom,
|
||||
} from '../../../../atoms';
|
||||
import { useCurrentUser } from '../../../../hooks/affine/use-current-user';
|
||||
import { useSelfHosted } from '../../../../hooks/affine/use-server-flavor';
|
||||
import { useUserSubscription } from '../../../../hooks/use-subscription';
|
||||
import { Upload } from '../../../pure/file-upload';
|
||||
import * as style from './style.css';
|
||||
@@ -167,6 +168,7 @@ export const AvatarAndName = () => {
|
||||
|
||||
const StoragePanel = () => {
|
||||
const t = useAFFiNEI18N();
|
||||
const isSelfHosted = useSelfHosted();
|
||||
|
||||
const { data } = useQuery({
|
||||
query: allBlobSizesQuery,
|
||||
@@ -175,6 +177,7 @@ const StoragePanel = () => {
|
||||
const [subscription] = useUserSubscription();
|
||||
const plan = subscription?.plan ?? SubscriptionPlan.Free;
|
||||
|
||||
// TODO(@JimmFly): get limit from user usage query directly after #4720 is merged
|
||||
const maxLimit = useMemo(() => {
|
||||
return bytes.parse(plan === SubscriptionPlan.Free ? '10GB' : '100GB');
|
||||
}, [plan]);
|
||||
@@ -199,6 +202,7 @@ const StoragePanel = () => {
|
||||
plan={plan}
|
||||
value={data.collectAllBlobSizes.size}
|
||||
onUpgrade={onUpgrade}
|
||||
upgradable={!isSelfHosted}
|
||||
/>
|
||||
</SettingRow>
|
||||
);
|
||||
|
||||
+15
-12
@@ -8,6 +8,7 @@ import {
|
||||
import type { ReactElement, SVGProps } from 'react';
|
||||
|
||||
import { useCurrentLoginStatus } from '../../../../hooks/affine/use-current-login-status';
|
||||
import { useSelfHosted } from '../../../../hooks/affine/use-server-flavor';
|
||||
import { AboutAffine } from './about';
|
||||
import { AppearanceSettings } from './appearance';
|
||||
import { BillingSettings } from './billing';
|
||||
@@ -36,6 +37,7 @@ export type GeneralSettingList = GeneralSettingListItem[];
|
||||
export const useGeneralSettingList = (): GeneralSettingList => {
|
||||
const t = useAFFiNEI18N();
|
||||
const status = useCurrentLoginStatus();
|
||||
const isSelfHosted = useSelfHosted();
|
||||
|
||||
const settings: GeneralSettingListItem[] = [
|
||||
{
|
||||
@@ -50,13 +52,6 @@ export const useGeneralSettingList = (): GeneralSettingList => {
|
||||
icon: KeyboardIcon,
|
||||
testId: 'shortcuts-panel-trigger',
|
||||
},
|
||||
{
|
||||
key: 'plans',
|
||||
title: t['com.affine.payment.title'](),
|
||||
icon: UpgradeIcon,
|
||||
testId: 'plans-panel-trigger',
|
||||
},
|
||||
|
||||
{
|
||||
key: 'plugins',
|
||||
title: 'Plugins',
|
||||
@@ -71,13 +66,21 @@ export const useGeneralSettingList = (): GeneralSettingList => {
|
||||
},
|
||||
];
|
||||
|
||||
if (status === 'authenticated') {
|
||||
if (!isSelfHosted) {
|
||||
settings.splice(3, 0, {
|
||||
key: 'billing',
|
||||
title: t['com.affine.payment.billing-setting.title'](),
|
||||
icon: PaymentIcon,
|
||||
testId: 'billing-panel-trigger',
|
||||
key: 'plans',
|
||||
title: t['com.affine.payment.title'](),
|
||||
icon: UpgradeIcon,
|
||||
testId: 'plans-panel-trigger',
|
||||
});
|
||||
if (status === 'authenticated') {
|
||||
settings.splice(3, 0, {
|
||||
key: 'billing',
|
||||
title: t['com.affine.payment.billing-setting.title'](),
|
||||
icon: PaymentIcon,
|
||||
testId: 'billing-panel-trigger',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return settings;
|
||||
|
||||
Reference in New Issue
Block a user