mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-11-26 02:51:57 +03:00
chore(server): remove useless free subscription enum (#6634)
This commit is contained in:
parent
657a5250ad
commit
098e717688
@ -56,7 +56,10 @@ export class UserSubscriptionType implements Partial<UserSubscription> {
|
||||
@Field({ name: 'id' })
|
||||
stripeSubscriptionId!: string;
|
||||
|
||||
@Field(() => SubscriptionPlan)
|
||||
@Field(() => SubscriptionPlan, {
|
||||
description:
|
||||
"The 'Free' plan just exists to be a placeholder and for the type convenience of frontend.\nThere won't actually be a subscription with plan 'Free'",
|
||||
})
|
||||
plan!: SubscriptionPlan;
|
||||
|
||||
@Field(() => SubscriptionRecurring)
|
||||
|
@ -443,6 +443,11 @@ type UserSubscription {
|
||||
end: DateTime!
|
||||
id: String!
|
||||
nextBillAt: DateTime
|
||||
|
||||
"""
|
||||
The 'Free' plan just exists to be a placeholder and for the type convenience of frontend.
|
||||
There won't actually be a subscription with plan 'Free'
|
||||
"""
|
||||
plan: SubscriptionPlan!
|
||||
recurring: SubscriptionRecurring!
|
||||
start: DateTime!
|
||||
|
@ -21,7 +21,7 @@ export const UserPlanButton = () => {
|
||||
serverConfigService.serverConfig.features$.map(r => r?.payment)
|
||||
);
|
||||
const plan = useLiveData(
|
||||
subscriptionService.subscription.primary$.map(subscription =>
|
||||
subscriptionService.subscription.pro$.map(subscription =>
|
||||
subscription !== null ? subscription?.plan : null
|
||||
)
|
||||
);
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Button, ErrorMessage, Skeleton, Tooltip } from '@affine/component';
|
||||
import { SubscriptionPlan } from '@affine/graphql';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import { cssVar } from '@toeverything/theme';
|
||||
@ -45,15 +44,14 @@ export const StorageProgress = ({ onUpgrade }: StorageProgressProgress) => {
|
||||
subscription.revalidate();
|
||||
}, [subscription]);
|
||||
|
||||
const primarySubscription = useLiveData(subscription.primary$);
|
||||
const isFreeUser =
|
||||
!primarySubscription || primarySubscription?.plan === SubscriptionPlan.Free;
|
||||
const proSubscription = useLiveData(subscription.pro$);
|
||||
const isFreeUser = !proSubscription;
|
||||
const quotaName = useLiveData(
|
||||
quota.quota$.map(q => (q !== null ? q?.humanReadable.name : null))
|
||||
);
|
||||
|
||||
const loading =
|
||||
primarySubscription === null || percent === null || quotaName === null;
|
||||
proSubscription === null || percent === null || quotaName === null;
|
||||
const loadError = useLiveData(quota.error$);
|
||||
|
||||
const buttonType = useMemo(() => {
|
||||
|
@ -96,47 +96,39 @@ const SubscriptionSettings = () => {
|
||||
subscriptionService.prices.revalidate();
|
||||
}, [subscriptionService]);
|
||||
|
||||
const primarySubscription = useLiveData(
|
||||
subscriptionService.subscription.primary$
|
||||
);
|
||||
const proSubscription = useLiveData(subscriptionService.subscription.pro$);
|
||||
const proPrice = useLiveData(subscriptionService.prices.proPrice$);
|
||||
|
||||
const currentPlan =
|
||||
primarySubscription === null
|
||||
? null
|
||||
: primarySubscription?.plan ?? SubscriptionPlan.Free;
|
||||
|
||||
const [openCancelModal, setOpenCancelModal] = useState(false);
|
||||
|
||||
const recurring =
|
||||
primarySubscription?.recurring ?? SubscriptionRecurring.Monthly;
|
||||
|
||||
const setOpenSettingModalAtom = useSetAtom(openSettingModalAtom);
|
||||
|
||||
const currentPlan = proSubscription?.plan ?? SubscriptionPlan.Free;
|
||||
const currentRecurring =
|
||||
proSubscription?.recurring ?? SubscriptionRecurring.Monthly;
|
||||
|
||||
const gotoPlansSetting = useCallback(() => {
|
||||
mixpanel.track('Button', {
|
||||
resolve: 'ChangePlan',
|
||||
currentPlan: currentPlan,
|
||||
currentPlan: proSubscription?.plan,
|
||||
});
|
||||
setOpenSettingModalAtom({
|
||||
open: true,
|
||||
activeTab: 'plans',
|
||||
});
|
||||
}, [currentPlan, setOpenSettingModalAtom]);
|
||||
}, [proSubscription, setOpenSettingModalAtom]);
|
||||
|
||||
const amount = currentPlan
|
||||
? currentPlan === SubscriptionPlan.Free
|
||||
? '0'
|
||||
: proPrice
|
||||
? recurring === SubscriptionRecurring.Monthly
|
||||
? String((proPrice.amount ?? 0) / 100)
|
||||
: String((proPrice.yearlyAmount ?? 0) / 100)
|
||||
: '?'
|
||||
: '?';
|
||||
const amount = proSubscription
|
||||
? proPrice
|
||||
? proSubscription.recurring === SubscriptionRecurring.Monthly
|
||||
? String((proPrice.amount ?? 0) / 100)
|
||||
: String((proPrice.yearlyAmount ?? 0) / 100)
|
||||
: '?'
|
||||
: '0';
|
||||
|
||||
return (
|
||||
<div className={styles.subscription}>
|
||||
{currentPlan !== null ? (
|
||||
{/* loaded */}
|
||||
{proSubscription !== null ? (
|
||||
<div className={styles.planCard}>
|
||||
<div className={styles.currentPlan}>
|
||||
<SettingRow
|
||||
@ -144,7 +136,7 @@ const SubscriptionSettings = () => {
|
||||
name={t['com.affine.payment.billing-setting.current-plan']()}
|
||||
desc={
|
||||
<Trans
|
||||
i18nKey={getMessageKey(currentPlan, recurring)}
|
||||
i18nKey={getMessageKey(currentPlan, currentRecurring)}
|
||||
values={{
|
||||
planName: currentPlan,
|
||||
}}
|
||||
@ -168,7 +160,7 @@ const SubscriptionSettings = () => {
|
||||
${amount}
|
||||
<span className={styles.billingFrequency}>
|
||||
/
|
||||
{recurring === SubscriptionRecurring.Monthly
|
||||
{currentRecurring === SubscriptionRecurring.Monthly
|
||||
? t['com.affine.payment.billing-setting.month']()
|
||||
: t['com.affine.payment.billing-setting.year']()}
|
||||
</span>
|
||||
@ -179,8 +171,8 @@ const SubscriptionSettings = () => {
|
||||
)}
|
||||
|
||||
<AIPlanCard />
|
||||
{primarySubscription !== null ? (
|
||||
primarySubscription?.status === SubscriptionStatus.Active && (
|
||||
{proSubscription !== null ? (
|
||||
proSubscription?.status === SubscriptionStatus.Active && (
|
||||
<>
|
||||
<SettingRow
|
||||
className={styles.paymentMethod}
|
||||
@ -191,26 +183,26 @@ const SubscriptionSettings = () => {
|
||||
>
|
||||
<PaymentMethodUpdater />
|
||||
</SettingRow>
|
||||
{primarySubscription.nextBillAt && (
|
||||
{proSubscription.nextBillAt && (
|
||||
<SettingRow
|
||||
name={t['com.affine.payment.billing-setting.renew-date']()}
|
||||
desc={t[
|
||||
'com.affine.payment.billing-setting.renew-date.description'
|
||||
]({
|
||||
renewDate: new Date(
|
||||
primarySubscription.nextBillAt
|
||||
proSubscription.nextBillAt
|
||||
).toLocaleDateString(),
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
{primarySubscription.canceledAt ? (
|
||||
{proSubscription.canceledAt ? (
|
||||
<SettingRow
|
||||
name={t['com.affine.payment.billing-setting.expiration-date']()}
|
||||
desc={t[
|
||||
'com.affine.payment.billing-setting.expiration-date.description'
|
||||
]({
|
||||
expirationDate: new Date(
|
||||
primarySubscription.end
|
||||
proSubscription.end
|
||||
).toLocaleDateString(),
|
||||
})}
|
||||
>
|
||||
@ -322,9 +314,9 @@ const PlanAction = ({
|
||||
type="primary"
|
||||
onClick={gotoPlansSetting}
|
||||
>
|
||||
{plan === SubscriptionPlan.Free
|
||||
? t['com.affine.payment.billing-setting.upgrade']()
|
||||
: t['com.affine.payment.billing-setting.change-plan']()}
|
||||
{plan === SubscriptionPlan.Pro
|
||||
? t['com.affine.payment.billing-setting.change-plan']()
|
||||
: t['com.affine.payment.billing-setting.upgrade']()}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
@ -36,9 +36,7 @@ const Settings = () => {
|
||||
const scrollWrapper = useRef<HTMLDivElement>(null);
|
||||
|
||||
const subscriptionService = useService(SubscriptionService);
|
||||
const primarySubscription = useLiveData(
|
||||
subscriptionService.subscription.primary$
|
||||
);
|
||||
const proSubscription = useLiveData(subscriptionService.subscription.pro$);
|
||||
const prices = useLiveData(subscriptionService.prices.prices$);
|
||||
|
||||
useEffect(() => {
|
||||
@ -62,13 +60,13 @@ const Settings = () => {
|
||||
});
|
||||
|
||||
const [recurring, setRecurring] = useState<SubscriptionRecurring>(
|
||||
primarySubscription?.recurring ?? SubscriptionRecurring.Yearly
|
||||
proSubscription?.recurring ?? SubscriptionRecurring.Yearly
|
||||
);
|
||||
|
||||
const currentPlan = primarySubscription?.plan ?? SubscriptionPlan.Free;
|
||||
const isCanceled = !!primarySubscription?.canceledAt;
|
||||
const currentPlan = proSubscription?.plan ?? SubscriptionPlan.Free;
|
||||
const isCanceled = !!proSubscription?.canceledAt;
|
||||
const currentRecurring =
|
||||
primarySubscription?.recurring ?? SubscriptionRecurring.Monthly;
|
||||
proSubscription?.recurring ?? SubscriptionRecurring.Monthly;
|
||||
|
||||
const yearlyDiscount = (
|
||||
planDetail.get(SubscriptionPlan.Pro) as FixedPrice | undefined
|
||||
|
@ -32,15 +32,13 @@ export const PlanCard = (props: PlanCardProps) => {
|
||||
const loggedIn =
|
||||
useLiveData(useService(AuthService).session.status$) === 'authenticated';
|
||||
const subscriptionService = useService(SubscriptionService);
|
||||
const primarySubscription = useLiveData(
|
||||
subscriptionService.subscription.primary$
|
||||
);
|
||||
const currentPlan = primarySubscription?.plan ?? SubscriptionPlan.Free;
|
||||
const proSubscription = useLiveData(subscriptionService.subscription.pro$);
|
||||
const currentPlan = proSubscription?.plan ?? SubscriptionPlan.Free;
|
||||
|
||||
const isCurrent =
|
||||
loggedIn &&
|
||||
detail.plan === currentPlan &&
|
||||
recurring === primarySubscription?.recurring;
|
||||
recurring === proSubscription?.recurring;
|
||||
const isPro = detail.plan === SubscriptionPlan.Pro;
|
||||
|
||||
return (
|
||||
@ -93,7 +91,7 @@ const ActionButton = ({ detail, recurring }: PlanCardProps) => {
|
||||
useLiveData(useService(AuthService).session.status$) === 'authenticated';
|
||||
const subscriptionService = useService(SubscriptionService);
|
||||
const primarySubscription = useLiveData(
|
||||
subscriptionService.subscription.primary$
|
||||
subscriptionService.subscription.pro$
|
||||
);
|
||||
const currentPlan = primarySubscription?.plan ?? SubscriptionPlan.Free;
|
||||
const currentRecurring = primarySubscription?.recurring;
|
||||
|
@ -24,7 +24,7 @@ import { useRevokeMemberPermission } from '@affine/core/hooks/affine/use-revoke-
|
||||
import { WorkspacePermissionService } from '@affine/core/modules/permissions';
|
||||
import { WorkspaceQuotaService } from '@affine/core/modules/quota';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { Permission, SubscriptionPlan } from '@affine/graphql';
|
||||
import { Permission } from '@affine/graphql';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { MoreVerticalIcon } from '@blocksuite/icons';
|
||||
import {
|
||||
@ -98,7 +98,7 @@ export const CloudWorkspaceMembersPanel = () => {
|
||||
const workspaceQuota = useLiveData(workspaceQuotaService.quota.quota$);
|
||||
const subscriptionService = useService(SubscriptionService);
|
||||
const plan = useLiveData(
|
||||
subscriptionService.subscription.primary$.map(s => s?.plan)
|
||||
subscriptionService.subscription.pro$.map(s => s?.plan)
|
||||
);
|
||||
const isLimited = workspaceQuota
|
||||
? checkMemberCountLimit(memberCount, workspaceQuota.memberLimit)
|
||||
@ -206,7 +206,7 @@ export const CloudWorkspaceMembersPanel = () => {
|
||||
<Button onClick={openModal}>{t['Invite Members']()}</Button>
|
||||
{isLimited ? (
|
||||
<MemberLimitModal
|
||||
isFreePlan={plan === SubscriptionPlan.Free}
|
||||
isFreePlan={!!plan}
|
||||
open={open}
|
||||
plan={workspaceQuota?.humanReadable.name ?? ''}
|
||||
quota={workspaceQuota?.humanReadable.memberLimit ?? ''}
|
||||
|
@ -21,8 +21,7 @@ const UserInfo = () => {
|
||||
useEffect(() => {
|
||||
subscription.revalidate();
|
||||
}, [subscription]);
|
||||
const primary = useLiveData(subscription.primary$);
|
||||
const plan = primary?.plan;
|
||||
const plan = useLiveData(subscription.pro$)?.plan;
|
||||
|
||||
if (!user) {
|
||||
// TODO: loading UI
|
||||
|
@ -28,34 +28,11 @@ export class Subscription extends Entity {
|
||||
isRevalidating$ = new LiveData(false);
|
||||
error$ = new LiveData<any | null>(null);
|
||||
|
||||
/**
|
||||
* Primary subscription is the subscription that is not AI.
|
||||
*/
|
||||
primary$ = this.subscription$.map(subscriptions =>
|
||||
subscriptions
|
||||
? subscriptions.find(sub => sub.plan !== SubscriptionPlan.AI)
|
||||
: null
|
||||
);
|
||||
isFree$ = this.subscription$.map(subscriptions =>
|
||||
subscriptions
|
||||
? subscriptions.some(sub => sub.plan === SubscriptionPlan.Free)
|
||||
: null
|
||||
);
|
||||
isPro$ = this.subscription$.map(subscriptions =>
|
||||
subscriptions
|
||||
? subscriptions.some(sub => sub.plan === SubscriptionPlan.Pro)
|
||||
: null
|
||||
);
|
||||
pro$ = this.subscription$.map(subscriptions =>
|
||||
subscriptions
|
||||
? subscriptions.find(sub => sub.plan === SubscriptionPlan.Pro)
|
||||
: null
|
||||
);
|
||||
isSelfHosted$ = this.subscription$.map(subscriptions =>
|
||||
subscriptions
|
||||
? subscriptions.some(sub => sub.plan === SubscriptionPlan.SelfHosted)
|
||||
: null
|
||||
);
|
||||
ai$ = this.subscription$.map(subscriptions =>
|
||||
subscriptions
|
||||
? subscriptions.find(sub => sub.plan === SubscriptionPlan.AI)
|
||||
|
Loading…
Reference in New Issue
Block a user