Merge remote-tracking branch 'origin/main' into cloudflare
This commit is contained in:
commit
b0a065ced9
@ -592,7 +592,7 @@
|
|||||||
},
|
},
|
||||||
"price": "Price:",
|
"price": "Price:",
|
||||||
"periodStartDate": "Period start date:",
|
"periodStartDate": "Period start date:",
|
||||||
"nextBillingDate": "Next billing date:",
|
"periodEndDate": "Period end date:",
|
||||||
"trialEnds": "Trial ends:",
|
"trialEnds": "Trial ends:",
|
||||||
"freePlanMessage": "You are currently on the free plan with limited features",
|
"freePlanMessage": "You are currently on the free plan with limited features",
|
||||||
"lifetimeMessage": "You have lifetime access to all premium features",
|
"lifetimeMessage": "You have lifetime access to all premium features",
|
||||||
|
@ -592,7 +592,7 @@
|
|||||||
},
|
},
|
||||||
"price": "价格:",
|
"price": "价格:",
|
||||||
"periodStartDate": "周期开始日期:",
|
"periodStartDate": "周期开始日期:",
|
||||||
"nextBillingDate": "下次账单日期:",
|
"periodEndDate": "周期结束日期:",
|
||||||
"trialEnds": "试用结束日期:",
|
"trialEnds": "试用结束日期:",
|
||||||
"freePlanMessage": "您当前使用的是功能有限的免费方案",
|
"freePlanMessage": "您当前使用的是功能有限的免费方案",
|
||||||
"lifetimeMessage": "您拥有所有高级功能的终身使用权限",
|
"lifetimeMessage": "您拥有所有高级功能的终身使用权限",
|
||||||
|
@ -17,7 +17,7 @@ import { Input } from '@/components/ui/input';
|
|||||||
import { websiteConfig } from '@/config/website';
|
import { websiteConfig } from '@/config/website';
|
||||||
import { LocaleLink } from '@/i18n/navigation';
|
import { LocaleLink } from '@/i18n/navigation';
|
||||||
import { authClient } from '@/lib/auth-client';
|
import { authClient } from '@/lib/auth-client';
|
||||||
import { getUrlWithLocaleInCallbackUrl } from '@/lib/urls/urls';
|
import { getUrlWithLocale } from '@/lib/urls/urls';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { DEFAULT_LOGIN_REDIRECT, Routes } from '@/routes';
|
import { DEFAULT_LOGIN_REDIRECT, Routes } from '@/routes';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
@ -45,10 +45,10 @@ export const LoginForm = ({
|
|||||||
const paramCallbackUrl = searchParams.get('callbackUrl');
|
const paramCallbackUrl = searchParams.get('callbackUrl');
|
||||||
// Use prop callback URL or param callback URL if provided, otherwise use the default login redirect
|
// Use prop callback URL or param callback URL if provided, otherwise use the default login redirect
|
||||||
const locale = useLocale();
|
const locale = useLocale();
|
||||||
const defaultCallbackUrl = getUrlWithLocaleInCallbackUrl(
|
const defaultCallbackUrl = getUrlWithLocale(DEFAULT_LOGIN_REDIRECT, locale);
|
||||||
DEFAULT_LOGIN_REDIRECT,
|
// console.log('login form, propCallbackUrl', propCallbackUrl);
|
||||||
locale
|
// console.log('login form, paramCallbackUrl', paramCallbackUrl);
|
||||||
);
|
// console.log('login form, defaultCallbackUrl', defaultCallbackUrl);
|
||||||
const callbackUrl = propCallbackUrl || paramCallbackUrl || defaultCallbackUrl;
|
const callbackUrl = propCallbackUrl || paramCallbackUrl || defaultCallbackUrl;
|
||||||
console.log('login form, callbackUrl', callbackUrl);
|
console.log('login form, callbackUrl', callbackUrl);
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import {
|
|||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { websiteConfig } from '@/config/website';
|
import { websiteConfig } from '@/config/website';
|
||||||
import { authClient } from '@/lib/auth-client';
|
import { authClient } from '@/lib/auth-client';
|
||||||
import { getUrlWithLocaleInCallbackUrl } from '@/lib/urls/urls';
|
import { getUrlWithLocale } from '@/lib/urls/urls';
|
||||||
import { DEFAULT_LOGIN_REDIRECT, Routes } from '@/routes';
|
import { DEFAULT_LOGIN_REDIRECT, Routes } from '@/routes';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { EyeIcon, EyeOffIcon, Loader2Icon } from 'lucide-react';
|
import { EyeIcon, EyeOffIcon, Loader2Icon } from 'lucide-react';
|
||||||
@ -40,10 +40,10 @@ export const RegisterForm = ({
|
|||||||
const paramCallbackUrl = searchParams.get('callbackUrl');
|
const paramCallbackUrl = searchParams.get('callbackUrl');
|
||||||
// Use prop callback URL or param callback URL if provided, otherwise use the default login redirect
|
// Use prop callback URL or param callback URL if provided, otherwise use the default login redirect
|
||||||
const locale = useLocale();
|
const locale = useLocale();
|
||||||
const defaultCallbackUrl = getUrlWithLocaleInCallbackUrl(
|
const defaultCallbackUrl = getUrlWithLocale(DEFAULT_LOGIN_REDIRECT, locale);
|
||||||
DEFAULT_LOGIN_REDIRECT,
|
// console.log('register form, propCallbackUrl', propCallbackUrl);
|
||||||
locale
|
// console.log('register form, paramCallbackUrl', paramCallbackUrl);
|
||||||
);
|
// console.log('register form, defaultCallbackUrl', defaultCallbackUrl);
|
||||||
const callbackUrl = propCallbackUrl || paramCallbackUrl || defaultCallbackUrl;
|
const callbackUrl = propCallbackUrl || paramCallbackUrl || defaultCallbackUrl;
|
||||||
console.log('register form, callbackUrl', callbackUrl);
|
console.log('register form, callbackUrl', callbackUrl);
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import { GoogleIcon } from '@/components/icons/google';
|
|||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { websiteConfig } from '@/config/website';
|
import { websiteConfig } from '@/config/website';
|
||||||
import { authClient } from '@/lib/auth-client';
|
import { authClient } from '@/lib/auth-client';
|
||||||
import { getUrlWithLocaleInCallbackUrl } from '@/lib/urls/urls';
|
import { getUrlWithLocale } from '@/lib/urls/urls';
|
||||||
import { DEFAULT_LOGIN_REDIRECT, Routes } from '@/routes';
|
import { DEFAULT_LOGIN_REDIRECT, Routes } from '@/routes';
|
||||||
import { Loader2Icon } from 'lucide-react';
|
import { Loader2Icon } from 'lucide-react';
|
||||||
import { useLocale, useTranslations } from 'next-intl';
|
import { useLocale, useTranslations } from 'next-intl';
|
||||||
@ -37,10 +37,7 @@ export const SocialLoginButton = ({
|
|||||||
const paramCallbackUrl = searchParams.get('callbackUrl');
|
const paramCallbackUrl = searchParams.get('callbackUrl');
|
||||||
// Use prop callback URL or param callback URL if provided, otherwise use the default login redirect
|
// Use prop callback URL or param callback URL if provided, otherwise use the default login redirect
|
||||||
const locale = useLocale();
|
const locale = useLocale();
|
||||||
const defaultCallbackUrl = getUrlWithLocaleInCallbackUrl(
|
const defaultCallbackUrl = getUrlWithLocale(DEFAULT_LOGIN_REDIRECT, locale);
|
||||||
DEFAULT_LOGIN_REDIRECT,
|
|
||||||
locale
|
|
||||||
);
|
|
||||||
const callbackUrl = propCallbackUrl || paramCallbackUrl || defaultCallbackUrl;
|
const callbackUrl = propCallbackUrl || paramCallbackUrl || defaultCallbackUrl;
|
||||||
const [isLoading, setIsLoading] = useState<'google' | 'github' | null>(null);
|
const [isLoading, setIsLoading] = useState<'google' | 'github' | null>(null);
|
||||||
console.log('social login button, callbackUrl', callbackUrl);
|
console.log('social login button, callbackUrl', callbackUrl);
|
||||||
|
@ -60,23 +60,21 @@ export default function BillingCard() {
|
|||||||
const isFreePlan = currentPlanWithTranslations?.isFree || false;
|
const isFreePlan = currentPlanWithTranslations?.isFree || false;
|
||||||
const isLifetimeMember = currentPlanWithTranslations?.isLifetime || false;
|
const isLifetimeMember = currentPlanWithTranslations?.isLifetime || false;
|
||||||
|
|
||||||
// Get subscription price details
|
|
||||||
const currentPrice =
|
|
||||||
subscription &&
|
|
||||||
currentPlanWithTranslations?.prices.find(
|
|
||||||
(price) => price.priceId === subscription?.priceId
|
|
||||||
);
|
|
||||||
|
|
||||||
// Get current period start date
|
// Get current period start date
|
||||||
const currentPeriodStart = subscription?.currentPeriodStart
|
const currentPeriodStart = subscription?.currentPeriodStart
|
||||||
? formatDate(subscription.currentPeriodStart)
|
? formatDate(subscription.currentPeriodStart)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
// Format next billing date if subscription is active
|
// Get current period end date
|
||||||
const nextBillingDate = subscription?.currentPeriodEnd
|
const currentPeriodEnd = subscription?.currentPeriodEnd
|
||||||
? formatDate(subscription.currentPeriodEnd)
|
? formatDate(subscription.currentPeriodEnd)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
// Get current trial end date
|
||||||
|
const trialEndDate = subscription?.trialEndDate
|
||||||
|
? formatDate(subscription.trialEndDate)
|
||||||
|
: null;
|
||||||
|
|
||||||
// Retry payment data fetching
|
// Retry payment data fetching
|
||||||
const handleRetry = useCallback(() => {
|
const handleRetry = useCallback(() => {
|
||||||
// console.log('handleRetry, refetch payment info');
|
// console.log('handleRetry, refetch payment info');
|
||||||
@ -229,36 +227,25 @@ export default function BillingCard() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Subscription plan message */}
|
{/* Subscription plan message */}
|
||||||
{subscription && currentPrice && (
|
{subscription && (
|
||||||
<div className="text-sm text-muted-foreground space-y-2">
|
<div className="text-sm text-muted-foreground space-y-2">
|
||||||
{/* <div>
|
|
||||||
{t('price')}{' '}
|
|
||||||
{formatPrice(currentPrice.amount, currentPrice.currency)} /{' '}
|
|
||||||
{currentPrice.interval === PlanIntervals.MONTH
|
|
||||||
? t('interval.month')
|
|
||||||
: currentPrice.interval === PlanIntervals.YEAR
|
|
||||||
? t('interval.year')
|
|
||||||
: t('interval.oneTime')}
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
{currentPeriodStart && (
|
{currentPeriodStart && (
|
||||||
<div className="text-muted-foreground">
|
<div className="text-muted-foreground">
|
||||||
{t('periodStartDate')} {currentPeriodStart}
|
{t('periodStartDate')} {currentPeriodStart}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{nextBillingDate && (
|
{currentPeriodEnd && (
|
||||||
<div className="text-muted-foreground">
|
<div className="text-muted-foreground">
|
||||||
{t('nextBillingDate')} {nextBillingDate}
|
{t('periodEndDate')} {currentPeriodEnd}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{subscription.status === 'trialing' &&
|
{subscription.status === 'trialing' && trialEndDate && (
|
||||||
subscription.currentPeriodEnd && (
|
<div className="text-amber-600">
|
||||||
<div className="text-amber-600">
|
{t('trialEnds')} {trialEndDate}
|
||||||
{t('trialEnds')} {formatDate(subscription.currentPeriodEnd)}
|
</div>
|
||||||
</div>
|
)}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
@ -35,7 +35,7 @@ export function getUrlWithLocale(url: string, locale?: Locale | null): string {
|
|||||||
* Input: http://localhost:3000/api/auth/reset-password/token?callbackURL=/auth/reset-password
|
* Input: http://localhost:3000/api/auth/reset-password/token?callbackURL=/auth/reset-password
|
||||||
* Output: http://localhost:3000/api/auth/reset-password/token?callbackURL=/zh/auth/reset-password
|
* Output: http://localhost:3000/api/auth/reset-password/token?callbackURL=/zh/auth/reset-password
|
||||||
*
|
*
|
||||||
* http://localhost:3000/api/auth/verify-email?token=eyJhbGciOiJIUzI1NiJ9&callbackURL=/dashboard
|
* Input: http://localhost:3000/api/auth/verify-email?token=eyJhbGciOiJIUzI1NiJ9&callbackURL=/dashboard
|
||||||
* Output: http://localhost:3000/api/auth/verify-email?token=eyJhbGciOiJIUzI1NiJ9&callbackURL=/zh/dashboard
|
* Output: http://localhost:3000/api/auth/verify-email?token=eyJhbGciOiJIUzI1NiJ9&callbackURL=/zh/dashboard
|
||||||
*
|
*
|
||||||
* @param url - The original URL with callbackURL parameter
|
* @param url - The original URL with callbackURL parameter
|
||||||
|
Loading…
Reference in New Issue
Block a user