fix(core): adjust onetime subscription ui for billing and pricing (#8591)

close AF-1534
This commit is contained in:
CatsJuice 2024-10-25 03:59:05 +00:00
parent 8f694aceb7
commit 829361a910
No known key found for this signature in database
GPG Key ID: 1C1E76924FAFDDE4
4 changed files with 60 additions and 42 deletions

View File

@ -42,6 +42,7 @@ import { AICancel, AIResume, AISubscribe } from '../plans/ai/actions';
import { AIRedeemCodeButton } from '../plans/ai/actions/redeem';
import { BelieverCard } from '../plans/lifetime/believer-card';
import { BelieverBenefits } from '../plans/lifetime/benefits';
import { RedeemCode } from '../plans/plan-card';
import * as styles from './style.css';
const DescriptionI18NKey = {
@ -146,20 +147,23 @@ const SubscriptionSettings = () => {
spreadCol={false}
name={t['com.affine.payment.billing-setting.current-plan']()}
desc={
<Trans
i18nKey={getMessageKey(currentPlan, currentRecurring)}
values={{
planName: currentPlan,
}}
components={{
1: (
<span
onClick={gotoCloudPlansSetting}
className={styles.currentPlanName}
/>
),
}}
/>
<>
<Trans
i18nKey={getMessageKey(currentPlan, currentRecurring)}
values={{
planName: currentPlan,
}}
components={{
1: (
<span
onClick={gotoCloudPlansSetting}
className={styles.currentPlanName}
/>
),
}}
/>
<CloudExpirationInfo />
</>
}
/>
<PlanAction
@ -196,28 +200,6 @@ const SubscriptionSettings = () => {
>
<PaymentMethodUpdater />
</SettingRow>
{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(
proSubscription.nextBillAt
).toLocaleDateString(),
})}
/>
)}
{isOnetime && proSubscription.end && (
<SettingRow
name={t['com.affine.payment.billing-setting.due-date']()}
desc={t[
'com.affine.payment.billing-setting.due-date.description'
]({
dueDate: new Date(proSubscription.end).toLocaleDateString(),
})}
/>
)}
{isBeliever || isOnetime ? null : proSubscription.end &&
proSubscription.canceledAt ? (
<SettingRow
@ -263,6 +245,34 @@ const SubscriptionSettings = () => {
);
};
const CloudExpirationInfo = () => {
const t = useI18n();
const subscriptionService = useService(SubscriptionService);
const subscription = useLiveData(subscriptionService.subscription.pro$);
let text = '';
if (subscription?.nextBillAt) {
text = t['com.affine.payment.billing-setting.renew-date.description']({
renewDate: i18nTime(subscription.nextBillAt, {
absolute: { accuracy: 'day' },
}),
});
} else if (subscription?.end) {
text = t['com.affine.payment.billing-setting.due-date.description']({
dueDate: i18nTime(subscription.end, {
absolute: { accuracy: 'day' },
}),
});
}
return text ? (
<>
<br />
{text}
</>
) : null;
};
const TypeFormLink = () => {
const t = useI18n();
const subscriptionService = useService(SubscriptionService);
@ -375,7 +385,7 @@ const AIPlanCard = ({ onClick }: { onClick: () => void }) => {
absolute: { accuracy: 'day' },
}),
})
) : subscription?.canceledAt && subscription.end ? (
) : (isOnetime || subscription?.canceledAt) && subscription.end ? (
t['com.affine.payment.ai.billing-tip.end-at']({
end: i18nTime(subscription.end, { absolute: { accuracy: 'day' } }),
})
@ -422,6 +432,13 @@ const PlanAction = ({
}) => {
const t = useI18n();
const subscription = useService(SubscriptionService).subscription;
const isOnetimePro = useLiveData(subscription.isOnetimePro$);
if (isOnetimePro) {
return <RedeemCode variant="primary" className={styles.planAction} />;
}
return (
<Button
className={styles.planAction}

View File

@ -21,6 +21,7 @@ export const currentPlan = style({
flex: '1 0 0',
});
export const planAction = style({
width: 'auto',
marginTop: '8px',
});
export const planPrice = style({

View File

@ -174,6 +174,9 @@ export const CloudPlans = () => {
const prices = useLiveData(subscriptionService.prices.prices$);
const loggedIn = useLiveData(authService.session.status$) === 'authenticated';
const proSubscription = useLiveData(subscriptionService.subscription.pro$);
const isOnetimePro = useLiveData(
subscriptionService.subscription.isOnetimePro$
);
const [recurring, setRecurring] = useState<SubscriptionRecurring>(
proSubscription?.recurring ?? SubscriptionRecurring.Yearly
@ -334,7 +337,7 @@ export const CloudPlans = () => {
toggle={cloudToggle}
scroll={cloudScroll}
scrollRef={scrollWrapper}
lifetime={<LifetimePlan />}
lifetime={isOnetimePro ? null : <LifetimePlan />}
/>
);
};

View File

@ -4,7 +4,7 @@ import { SubscriptionRecurring } from '@affine/graphql';
import { Trans, useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
import { RedeemCode, Upgrade } from '../plan-card';
import { Upgrade } from '../plan-card';
import { BelieverCard } from './believer-card';
import { BelieverBenefits } from './benefits';
import * as styles from './style.css';
@ -17,7 +17,6 @@ export const LifetimePlan = () => {
subscriptionService.prices.readableLifetimePrice$
);
const isBeliever = useLiveData(subscriptionService.subscription.isBeliever$);
const isOnetime = useLiveData(subscriptionService.subscription.isOnetimePro$);
if (!readableLifetimePrice) return null;
@ -37,8 +36,6 @@ export const LifetimePlan = () => {
<Button className={styles.purchase} size="default" disabled>
{t['com.affine.payment.lifetime.purchased']()}
</Button>
) : isOnetime ? (
<RedeemCode className={styles.purchase} size="default" />
) : (
<Upgrade
className={styles.purchase}