✨ feat(subscription): Refactor subscription handling and update imports for better organization
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
'use client';
|
||||
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { oAuthLogin } from '@/services/common/oauth';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
import { Icon } from '@workspace/ui/custom-components/icon';
|
||||
|
||||
const icons = {
|
||||
apple: 'uil:apple',
|
||||
google: 'logos:google-icon',
|
||||
facebook: 'logos:facebook',
|
||||
github: 'uil:github',
|
||||
telegram: 'logos:telegram',
|
||||
};
|
||||
|
||||
export function OAuthMethods() {
|
||||
const { common } = useGlobalStore();
|
||||
const { oauth_methods } = common;
|
||||
const OAUTH_METHODS = oauth_methods?.filter(
|
||||
(method) => !['mobile', 'email', 'device'].includes(method),
|
||||
);
|
||||
return (
|
||||
OAUTH_METHODS?.length > 0 && (
|
||||
<>
|
||||
<div className='after:border-border relative text-center text-sm after:absolute after:inset-0 after:top-1/2 after:z-0 after:flex after:items-center after:border-t'>
|
||||
<span className='bg-background text-muted-foreground relative z-10 px-2'>
|
||||
Or continue with
|
||||
</span>
|
||||
</div>
|
||||
<div className='mt-6 flex justify-center gap-4 *:size-12 *:p-2'>
|
||||
{OAUTH_METHODS?.map((method: any) => {
|
||||
return (
|
||||
<Button
|
||||
key={method}
|
||||
variant='ghost'
|
||||
size='icon'
|
||||
asChild
|
||||
onClick={async () => {
|
||||
const { data } = await oAuthLogin({
|
||||
method,
|
||||
redirect: `${window.location.origin}/oauth/${method}`,
|
||||
});
|
||||
if (data.data?.redirect) {
|
||||
window.location.href = data.data?.redirect;
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon icon={icons[method as keyof typeof icons]} />
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
+12
-15
@@ -2,8 +2,7 @@
|
||||
|
||||
import { Display } from '@/components/display';
|
||||
import { SubscribeDetail } from '@/components/subscribe/detail';
|
||||
import { getSubscription } from '@/services/common/common';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
import { Card, CardContent, CardFooter, CardHeader } from '@workspace/ui/components/card';
|
||||
import { Separator } from '@workspace/ui/components/separator';
|
||||
@@ -14,19 +13,15 @@ import { useTranslations } from 'next-intl';
|
||||
import Link from 'next/link';
|
||||
import { Key, ReactNode } from 'react';
|
||||
|
||||
export function ProductShowcase() {
|
||||
interface ProductShowcaseProps {
|
||||
subscriptionData: API.Subscribe[];
|
||||
}
|
||||
|
||||
export function Content({ subscriptionData }: ProductShowcaseProps) {
|
||||
const t = useTranslations('index');
|
||||
|
||||
const { data } = useQuery({
|
||||
queryKey: ['getSubscription'],
|
||||
queryFn: async () => {
|
||||
const { data } = await getSubscription({
|
||||
skipErrorHandler: true,
|
||||
});
|
||||
return data.data?.list || [];
|
||||
},
|
||||
});
|
||||
if (data?.length === 0) return null;
|
||||
const { user } = useGlobalStore();
|
||||
|
||||
return (
|
||||
<motion.section
|
||||
initial={{ opacity: 0 }}
|
||||
@@ -51,7 +46,7 @@ export function ProductShowcase() {
|
||||
{t('product_showcase_description')}
|
||||
</motion.p>
|
||||
<div className='mx-auto flex flex-wrap justify-center gap-8 overflow-x-auto overflow-y-hidden *:max-w-80 *:flex-auto'>
|
||||
{data?.map((item, index) => (
|
||||
{subscriptionData?.map((item, index) => (
|
||||
<motion.div
|
||||
key={item.id}
|
||||
initial={{ opacity: 0, y: 50 }}
|
||||
@@ -132,7 +127,9 @@ export function ProductShowcase() {
|
||||
className='absolute bottom-0 left-0 w-full rounded-b-xl rounded-t-none'
|
||||
asChild
|
||||
>
|
||||
<Link href='/subscribe'>{t('subscribe')}</Link>
|
||||
<Link href={user ? '/subscribe' : `/purchasing?id=${item.id}`}>
|
||||
{t('subscribe')}
|
||||
</Link>
|
||||
</Button>
|
||||
</motion.div>
|
||||
</CardFooter>
|
||||
@@ -0,0 +1,17 @@
|
||||
import { getSubscription } from '@/services/user/portal';
|
||||
import { Content } from './content';
|
||||
|
||||
export async function ProductShowcase() {
|
||||
try {
|
||||
const { data } = await getSubscription({
|
||||
skipErrorHandler: true,
|
||||
});
|
||||
const subscriptionList = data.data?.list || [];
|
||||
|
||||
if (subscriptionList.length === 0) return null;
|
||||
|
||||
return <Content subscriptionData={subscriptionList} />;
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { getAvailablePaymentMethods } from '@/services/user/payment';
|
||||
import { getAvailablePaymentMethods } from '@/services/user/portal';
|
||||
// import { getAvailablePaymentMethods } from '@/services/user/payment';
|
||||
// import { getAvailablePaymentMethods } from '@/services/user/payment';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Label } from '@workspace/ui/components/label';
|
||||
import { RadioGroup, RadioGroupItem } from '@workspace/ui/components/radio-group';
|
||||
@@ -11,22 +13,30 @@ import React, { memo } from 'react';
|
||||
interface PaymentMethodsProps {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
balance?: boolean;
|
||||
}
|
||||
|
||||
const PaymentMethods: React.FC<PaymentMethodsProps> = ({ value, onChange }) => {
|
||||
const PaymentMethods: React.FC<PaymentMethodsProps> = ({ value, onChange, balance = true }) => {
|
||||
const t = useTranslations('subscribe');
|
||||
|
||||
const { data } = useQuery({
|
||||
queryKey: ['getAvailablePaymentMethods'],
|
||||
queryKey: ['getAvailablePaymentMethods', { balance }],
|
||||
queryFn: async () => {
|
||||
const { data } = await getAvailablePaymentMethods();
|
||||
return data.data?.list || [];
|
||||
const methods = data.data?.list || [];
|
||||
if (!value && methods[0]?.mark) onChange(methods[0]?.mark);
|
||||
if (balance) return methods;
|
||||
return methods.filter((item) => item.mark !== 'balance');
|
||||
},
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<div className='font-semibold'>{t('paymentMethod')}</div>
|
||||
<RadioGroup className='grid grid-cols-5 gap-2' value={value} onValueChange={onChange}>
|
||||
<RadioGroup
|
||||
className='grid grid-cols-2 gap-2 md:grid-cols-5'
|
||||
value={value}
|
||||
onValueChange={onChange}
|
||||
>
|
||||
{data?.map((item) => (
|
||||
<div key={item.mark}>
|
||||
<RadioGroupItem value={item.mark} id={item.mark} className='peer sr-only' />
|
||||
|
||||
@@ -4,7 +4,8 @@ import CouponInput from '@/components/subscribe/coupon-input';
|
||||
import DurationSelector from '@/components/subscribe/duration-selector';
|
||||
import PaymentMethods from '@/components/subscribe/payment-methods';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { checkoutOrder, preCreateOrder, purchase } from '@/services/user/order';
|
||||
import { preCreateOrder, purchase } from '@/services/user/order';
|
||||
import { purchaseCheckout } from '@/services/user/portal';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
import { Card, CardContent } from '@workspace/ui/components/card';
|
||||
@@ -69,7 +70,7 @@ export default function Purchase({ subscribe, setSubscribe }: Readonly<PurchaseP
|
||||
const response = await purchase(params as API.PurchaseOrderRequest);
|
||||
const orderNo = response.data.data?.order_no;
|
||||
if (orderNo) {
|
||||
const { data } = await checkoutOrder({
|
||||
const { data } = await purchaseCheckout({
|
||||
orderNo,
|
||||
returnUrl: `${window.location.origin}/payment?order_no=${orderNo}`,
|
||||
});
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { checkoutOrder, recharge } from '@/services/user/order';
|
||||
import { recharge } from '@/services/user/order';
|
||||
import { getAvailablePaymentMethods } from '@/services/user/payment';
|
||||
import { purchaseCheckout } from '@/services/user/portal';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Button, ButtonProps } from '@workspace/ui/components/button';
|
||||
import {
|
||||
@@ -133,7 +134,7 @@ export default function Recharge(props: Readonly<ButtonProps>) {
|
||||
const response = await recharge(params);
|
||||
const orderNo = response.data.data?.order_no;
|
||||
if (orderNo) {
|
||||
const { data } = await checkoutOrder({
|
||||
const { data } = await purchaseCheckout({
|
||||
orderNo,
|
||||
returnUrl: `${window.location.origin}/payment?order_no=${orderNo}`,
|
||||
});
|
||||
|
||||
@@ -4,7 +4,8 @@ import CouponInput from '@/components/subscribe/coupon-input';
|
||||
import DurationSelector from '@/components/subscribe/duration-selector';
|
||||
import PaymentMethods from '@/components/subscribe/payment-methods';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { checkoutOrder, preCreateOrder, renewal } from '@/services/user/order';
|
||||
import { preCreateOrder, renewal } from '@/services/user/order';
|
||||
import { purchaseCheckout } from '@/services/user/portal';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
import { Card, CardContent } from '@workspace/ui/components/card';
|
||||
@@ -77,7 +78,7 @@ export default function Renewal({ id, subscribe }: Readonly<RenewalProps>) {
|
||||
const response = await renewal(params as API.RenewalOrderRequest);
|
||||
const orderNo = response.data.data?.order_no;
|
||||
if (orderNo) {
|
||||
const { data } = await checkoutOrder({
|
||||
const { data } = await purchaseCheckout({
|
||||
orderNo,
|
||||
returnUrl: `${window.location.origin}/payment?order_no=${orderNo}`,
|
||||
});
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
import { Display } from '@/components/display';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { checkoutOrder, resetTraffic } from '@/services/user/order';
|
||||
import { resetTraffic } from '@/services/user/order';
|
||||
import { purchaseCheckout } from '@/services/user/portal';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
import {
|
||||
Dialog,
|
||||
@@ -84,7 +85,7 @@ export default function ResetTraffic({ id, replacement }: Readonly<ResetTrafficP
|
||||
const response = await resetTraffic(params);
|
||||
const orderNo = response.data.data?.order_no;
|
||||
if (orderNo) {
|
||||
const { data } = await checkoutOrder({
|
||||
const { data } = await purchaseCheckout({
|
||||
orderNo,
|
||||
returnUrl: `${window.location.origin}/payment?order_no=${orderNo}`,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user