✨ feat(subscribe): Add subscription credits
This commit is contained in:
parent
701cdee6de
commit
5bc7905a52
4
apps/admin/services/admin/typings.d.ts
vendored
4
apps/admin/services/admin/typings.d.ts
vendored
@ -556,6 +556,8 @@ declare namespace API {
|
||||
trade_no: string;
|
||||
status: number;
|
||||
subscribe_id: number;
|
||||
subscription_discount_id: number;
|
||||
subscription_discount_price: number;
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
};
|
||||
@ -577,6 +579,8 @@ declare namespace API {
|
||||
status: number;
|
||||
subscribe_id: number;
|
||||
subscribe: Subscribe;
|
||||
subscription_discount_id: number;
|
||||
subscription_discount_price: number;
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
};
|
||||
|
||||
4
apps/admin/services/common/typings.d.ts
vendored
4
apps/admin/services/common/typings.d.ts
vendored
@ -173,6 +173,8 @@ declare namespace API {
|
||||
trade_no: string;
|
||||
status: number;
|
||||
subscribe_id: number;
|
||||
subscription_discount_id: number;
|
||||
subscription_discount_price: number;
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
};
|
||||
@ -194,6 +196,8 @@ declare namespace API {
|
||||
status: number;
|
||||
subscribe_id: number;
|
||||
subscribe: Subscribe;
|
||||
subscription_discount_id: number;
|
||||
subscription_discount_price: number;
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
};
|
||||
|
||||
@ -26,7 +26,7 @@ import { Button } from '@workspace/ui/components/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card';
|
||||
import { Separator } from '@workspace/ui/components/separator';
|
||||
import { Tabs, TabsList, TabsTrigger } from '@workspace/ui/components/tabs';
|
||||
import { getNextResetDate, isBrowser } from '@workspace/ui/utils';
|
||||
import { isBrowser } from '@workspace/ui/utils';
|
||||
import { differenceInDays } from 'date-fns';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import Image from 'next/image';
|
||||
@ -35,12 +35,12 @@ import { QRCodeCanvas } from 'qrcode.react';
|
||||
import { useState } from 'react';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
import Renewal from '@/components/subscribe/renewal';
|
||||
import ResetTraffic from '@/components/subscribe/reset-traffic';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { getStat } from '@/services/common/common';
|
||||
import { getPlatform } from '@/utils/common';
|
||||
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||
import Renewal from '../order/renewal';
|
||||
import ResetTraffic from '../order/reset-traffic';
|
||||
import Subscribe from '../subscribe/page';
|
||||
|
||||
export default function Content() {
|
||||
@ -173,15 +173,14 @@ export default function Content() {
|
||||
</li>
|
||||
<li>
|
||||
<span className='text-muted-foreground'>{t('nextResetDays')}</span>
|
||||
<span className='text-2xl font-semibold'>
|
||||
{differenceInDays(getNextResetDate(item.start_time), new Date()) ||
|
||||
t('unknown')}
|
||||
</span>
|
||||
<span className='text-2xl font-semibold'>{t('unknown')}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className='text-muted-foreground'>{t('expirationDays')}</span>
|
||||
<span className='text-2xl font-semibold'>
|
||||
{differenceInDays(new Date(item.expire_time), new Date()) || t('unknown')}
|
||||
{item.expire_time
|
||||
? differenceInDays(new Date(item.expire_time), new Date()) || t('unknown')
|
||||
: t('noLimit')}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@ -1,235 +0,0 @@
|
||||
'use client';
|
||||
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { checkoutOrder, preCreateOrder, purchase } from '@/services/user/order';
|
||||
import { getAvailablePaymentMethods } from '@/services/user/payment';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Badge } from '@workspace/ui/components/badge';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
import { Card, CardContent } from '@workspace/ui/components/card';
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@workspace/ui/components/dialog';
|
||||
import { Input } from '@workspace/ui/components/input';
|
||||
import { Label } from '@workspace/ui/components/label';
|
||||
import { RadioGroup, RadioGroupItem } from '@workspace/ui/components/radio-group';
|
||||
import { Separator } from '@workspace/ui/components/separator';
|
||||
import { LoaderCircle } from 'lucide-react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import Image from 'next/legacy/image';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useState, useTransition } from 'react';
|
||||
|
||||
import { SubscribeBilling } from '../subscribe/billing';
|
||||
import { SubscribeDetail } from '../subscribe/detail';
|
||||
|
||||
export default function Purchase({
|
||||
subscribe,
|
||||
setSubscribe,
|
||||
}: {
|
||||
subscribe?: API.Subscribe;
|
||||
setSubscribe: (subscribe?: API.Subscribe) => void;
|
||||
}) {
|
||||
const t = useTranslations('order');
|
||||
|
||||
const { getUserInfo } = useGlobalStore();
|
||||
const router = useRouter();
|
||||
const [params, setParams] = useState<API.PurchaseOrderRequest>({
|
||||
quantity: 1,
|
||||
subscribe_id: subscribe?.id as number,
|
||||
payment: 'balance',
|
||||
coupon: '',
|
||||
});
|
||||
const [loading, startTransition] = useTransition();
|
||||
|
||||
const { data: order } = useQuery({
|
||||
queryKey: ['preCreateOrder', params],
|
||||
queryFn: async () => {
|
||||
const { data } = await preCreateOrder({
|
||||
...params,
|
||||
subscribe_id: subscribe?.id as number,
|
||||
});
|
||||
return data.data;
|
||||
},
|
||||
enabled: !!params?.subscribe_id,
|
||||
});
|
||||
const { data: paymentMethods } = useQuery({
|
||||
queryKey: ['getAvailablePaymentMethods'],
|
||||
queryFn: async () => {
|
||||
const { data } = await getAvailablePaymentMethods();
|
||||
return data.data?.list || [];
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (subscribe) {
|
||||
setParams((prev) => ({
|
||||
...prev,
|
||||
quantity: 1,
|
||||
subscribe_id: subscribe?.id,
|
||||
}));
|
||||
}
|
||||
}, [subscribe]);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={!!subscribe?.id}
|
||||
onOpenChange={(open) => {
|
||||
if (!open) setSubscribe(undefined);
|
||||
}}
|
||||
>
|
||||
<DialogContent className='flex h-full max-w-screen-lg flex-col overflow-hidden border-none p-0 md:h-auto'>
|
||||
<DialogHeader className='p-6 pb-0'>
|
||||
<DialogTitle>{t('buySubscription')}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className='grid w-full flex-grow gap-3 overflow-auto p-6 pt-0 lg:grid-cols-2'>
|
||||
<Card className='border-transparent shadow-none md:border-inherit md:shadow'>
|
||||
<CardContent className='grid gap-3 p-0 text-sm md:p-6'>
|
||||
<SubscribeDetail
|
||||
subscribe={{
|
||||
...subscribe,
|
||||
quantity: params.quantity,
|
||||
}}
|
||||
/>
|
||||
<Separator />
|
||||
<SubscribeBilling
|
||||
order={{
|
||||
...order,
|
||||
quantity: params.quantity,
|
||||
unit_price: subscribe?.unit_price,
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<div className='flex flex-col justify-between text-sm'>
|
||||
<div className='grid gap-3'>
|
||||
<div className='font-semibold'>{t('purchaseDuration')}</div>
|
||||
<RadioGroup
|
||||
value={String(params.quantity)}
|
||||
onValueChange={(value) => {
|
||||
setParams({
|
||||
...params,
|
||||
quantity: Number(value),
|
||||
});
|
||||
}}
|
||||
className='flex flex-wrap gap-0.5 *:w-20 md:gap-2'
|
||||
>
|
||||
{subscribe?.unit_time !== 'Minute' && (
|
||||
<div className='relative'>
|
||||
<RadioGroupItem value='1' id='1' className='peer sr-only' />
|
||||
<Label
|
||||
htmlFor='1'
|
||||
className='border-muted bg-popover hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary relative flex h-full flex-col items-center justify-center gap-2 rounded-md border-2 p-2'
|
||||
>
|
||||
1 / {t(subscribe?.unit_time || 'Month')}
|
||||
</Label>
|
||||
</div>
|
||||
)}
|
||||
{subscribe?.discount?.map((item) => (
|
||||
<div key={item.quantity}>
|
||||
<RadioGroupItem
|
||||
value={String(item.quantity)}
|
||||
id={String(item.quantity)}
|
||||
className='peer sr-only'
|
||||
/>
|
||||
<Label
|
||||
htmlFor={String(item.quantity)}
|
||||
className='border-muted bg-popover hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary relative flex h-full flex-col items-center justify-center gap-2 rounded-md border-2 p-2'
|
||||
>
|
||||
{item.quantity} / {t(subscribe?.unit_time || 'Month')}
|
||||
{item.discount < 100 && (
|
||||
<Badge variant='destructive'>-{100 - item.discount}%</Badge>
|
||||
)}
|
||||
</Label>
|
||||
</div>
|
||||
))}
|
||||
</RadioGroup>
|
||||
<div className='flex'>
|
||||
<Input
|
||||
placeholder={t('enterCoupon')}
|
||||
value={params.coupon}
|
||||
onChange={(e) => {
|
||||
setParams({
|
||||
...params,
|
||||
coupon: e.target.value.trim(),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='font-semibold'>{t('paymentMethod')}</div>
|
||||
<RadioGroup
|
||||
className='mb-6 grid grid-cols-5 gap-2'
|
||||
value={params.payment}
|
||||
onValueChange={(value) => {
|
||||
setParams({
|
||||
...params,
|
||||
payment: value,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{paymentMethods?.map((item) => {
|
||||
return (
|
||||
<div key={item.mark}>
|
||||
<RadioGroupItem value={item.mark} id={item.mark} className='peer sr-only' />
|
||||
<Label
|
||||
htmlFor={item.mark}
|
||||
className='border-muted bg-popover hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary flex flex-col items-center justify-between rounded-md border-2 py-2'
|
||||
>
|
||||
<div className='mb-3 size-12'>
|
||||
<Image
|
||||
src={item.icon || `/payment/${item.mark}.svg`}
|
||||
width={48}
|
||||
height={48}
|
||||
alt={item.name!}
|
||||
/>
|
||||
</div>
|
||||
<span className='w-full overflow-hidden text-ellipsis whitespace-nowrap text-center'>
|
||||
{item.name || t(`methods.${item.mark}`)}
|
||||
</span>
|
||||
</Label>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</RadioGroup>
|
||||
</div>
|
||||
<Button
|
||||
className='fixed bottom-0 left-0 w-full rounded-none md:relative md:mt-6'
|
||||
disabled={loading}
|
||||
onClick={async () => {
|
||||
startTransition(async () => {
|
||||
try {
|
||||
const response = await purchase(params);
|
||||
const orderNo = response.data.data?.order_no;
|
||||
if (orderNo) {
|
||||
const { data } = await checkoutOrder({
|
||||
orderNo,
|
||||
});
|
||||
const type = data.data?.type;
|
||||
const checkout_url = data.data?.checkout_url;
|
||||
if (type === 'link') {
|
||||
const width = 600;
|
||||
const height = 800;
|
||||
const left = (screen.width - width) / 2;
|
||||
const top = (screen.height - height) / 2;
|
||||
window.open(
|
||||
checkout_url,
|
||||
'newWindow',
|
||||
`width=${width},height=${height},top=${top},left=${left},menubar=0,scrollbars=1,resizable=1,status=1,titlebar=0,toolbar=0,location=1`,
|
||||
);
|
||||
}
|
||||
getUserInfo();
|
||||
router.push(`/payment?order_no=${orderNo}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
{loading && <LoaderCircle className='mr-2 animate-spin' />}
|
||||
{t('buyNow')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@ -1,236 +0,0 @@
|
||||
'use client';
|
||||
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { checkoutOrder, preCreateOrder, renewal } from '@/services/user/order';
|
||||
import { getAvailablePaymentMethods } from '@/services/user/payment';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Badge } from '@workspace/ui/components/badge';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
import { Card, CardContent } from '@workspace/ui/components/card';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from '@workspace/ui/components/dialog';
|
||||
import { Input } from '@workspace/ui/components/input';
|
||||
import { Label } from '@workspace/ui/components/label';
|
||||
import { RadioGroup, RadioGroupItem } from '@workspace/ui/components/radio-group';
|
||||
import { Separator } from '@workspace/ui/components/separator';
|
||||
import { LoaderCircle } from 'lucide-react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import Image from 'next/legacy/image';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useState, useTransition } from 'react';
|
||||
|
||||
import { SubscribeBilling } from '../subscribe/billing';
|
||||
import { SubscribeDetail } from '../subscribe/detail';
|
||||
|
||||
export default function Renewal({ token, subscribe }: { token: string; subscribe: API.Subscribe }) {
|
||||
const t = useTranslations('order');
|
||||
const { getUserInfo } = useGlobalStore();
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
const router = useRouter();
|
||||
const [params, setParams] = useState<API.RenewalOrderRequest>({
|
||||
quantity: 1,
|
||||
subscribe_id: subscribe.id,
|
||||
payment: 'balance',
|
||||
coupon: '',
|
||||
subscribe_token: token,
|
||||
});
|
||||
const [loading, startTransition] = useTransition();
|
||||
|
||||
const { data: order } = useQuery({
|
||||
queryKey: ['preCreateOrder', params],
|
||||
queryFn: async () => {
|
||||
const { data } = await preCreateOrder({
|
||||
...params,
|
||||
subscribe_id: subscribe.id,
|
||||
});
|
||||
return data.data;
|
||||
},
|
||||
enabled: !!subscribe.id && open,
|
||||
});
|
||||
|
||||
const { data: paymentMethods } = useQuery({
|
||||
queryKey: ['getAvailablePaymentMethods'],
|
||||
queryFn: async () => {
|
||||
const { data } = await getAvailablePaymentMethods();
|
||||
return data.data?.list || [];
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (subscribe.id && token) {
|
||||
setParams((prev) => ({
|
||||
...prev,
|
||||
quantity: 1,
|
||||
subscribe_id: subscribe.id,
|
||||
subscribe_token: token,
|
||||
}));
|
||||
}
|
||||
}, [subscribe.id, token]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger asChild>
|
||||
<Button size='sm'>{t('renew')}</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className='flex h-full max-w-screen-lg flex-col overflow-hidden md:h-auto'>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('renewSubscription')}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className='grid w-full gap-3 lg:grid-cols-2'>
|
||||
<Card className='border-transparent shadow-none md:border-inherit md:shadow'>
|
||||
<CardContent className='grid gap-3 p-0 text-sm md:p-6'>
|
||||
<SubscribeDetail
|
||||
subscribe={{
|
||||
...subscribe,
|
||||
quantity: params.quantity,
|
||||
}}
|
||||
/>
|
||||
<Separator />
|
||||
<SubscribeBilling
|
||||
order={{
|
||||
...order,
|
||||
quantity: params.quantity,
|
||||
unit_price: subscribe?.unit_price,
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<div className='flex flex-col justify-between text-sm'>
|
||||
<div className='grid gap-3'>
|
||||
<div className='font-semibold'>{t('purchaseDuration')}</div>
|
||||
<RadioGroup
|
||||
value={String(params.quantity)}
|
||||
onValueChange={(value) => {
|
||||
setParams({
|
||||
...params,
|
||||
quantity: Number(value),
|
||||
});
|
||||
}}
|
||||
className='flex flex-wrap gap-2'
|
||||
>
|
||||
{subscribe?.unit_time !== 'Minute' && (
|
||||
<div className='relative'>
|
||||
<RadioGroupItem value='1' id='1' className='peer sr-only' />
|
||||
<Label
|
||||
htmlFor='1'
|
||||
className='border-muted bg-popover hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary relative flex h-full flex-col items-center justify-center gap-2 rounded-md border-2 p-2'
|
||||
>
|
||||
1 / {t(subscribe?.unit_time || 'Month')}
|
||||
</Label>
|
||||
</div>
|
||||
)}
|
||||
{subscribe?.discount?.map((item) => (
|
||||
<div key={item.quantity}>
|
||||
<RadioGroupItem
|
||||
value={String(item.quantity)}
|
||||
id={String(item.quantity)}
|
||||
className='peer sr-only'
|
||||
/>
|
||||
<Label
|
||||
htmlFor={String(item.quantity)}
|
||||
className='border-muted bg-popover hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary relative flex h-full flex-col items-center justify-center gap-2 rounded-md border-2 p-2'
|
||||
>
|
||||
{item.quantity} / {t(subscribe?.unit_time || 'Month')}
|
||||
{item.discount < 100 && (
|
||||
<Badge variant='destructive'>-{100 - item.discount}%</Badge>
|
||||
)}
|
||||
</Label>
|
||||
</div>
|
||||
))}
|
||||
</RadioGroup>
|
||||
<div className='flex'>
|
||||
<Input
|
||||
placeholder={t('enterCoupon')}
|
||||
value={params.coupon}
|
||||
onChange={(e) => {
|
||||
setParams({
|
||||
...params,
|
||||
coupon: e.target.value.trim(),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='font-semibold'>{t('paymentMethod')}</div>
|
||||
<RadioGroup
|
||||
className='grid grid-cols-5 gap-2'
|
||||
value={params.payment}
|
||||
onValueChange={(value) => {
|
||||
setParams({
|
||||
...params,
|
||||
payment: value,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{paymentMethods?.map((item) => {
|
||||
return (
|
||||
<div key={item.mark}>
|
||||
<RadioGroupItem value={item.mark} id={item.mark} className='peer sr-only' />
|
||||
<Label
|
||||
htmlFor={item.mark}
|
||||
className='border-muted bg-popover hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary flex flex-col items-center justify-between rounded-md border-2 py-2'
|
||||
>
|
||||
<div className='mb-3 size-12'>
|
||||
<Image
|
||||
src={item.icon || `/payment/${item.mark}.svg`}
|
||||
width={48}
|
||||
height={48}
|
||||
alt={item.name!}
|
||||
/>
|
||||
</div>
|
||||
<span className='w-full overflow-hidden text-ellipsis whitespace-nowrap text-center'>
|
||||
{item.name || t(`methods.${item.mark}`)}
|
||||
</span>
|
||||
</Label>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</RadioGroup>
|
||||
</div>
|
||||
<Button
|
||||
className='fixed bottom-0 left-0 w-full rounded-none md:relative md:mt-6'
|
||||
disabled={loading}
|
||||
onClick={async () => {
|
||||
startTransition(async () => {
|
||||
try {
|
||||
const response = await renewal(params);
|
||||
const orderNo = response.data.data?.order_no;
|
||||
if (orderNo) {
|
||||
const { data } = await checkoutOrder({
|
||||
orderNo,
|
||||
});
|
||||
const type = data.data?.type;
|
||||
const checkout_url = data.data?.checkout_url;
|
||||
if (type === 'link') {
|
||||
const width = 600;
|
||||
const height = 800;
|
||||
const left = (screen.width - width) / 2;
|
||||
const top = (screen.height - height) / 2;
|
||||
window.open(
|
||||
checkout_url,
|
||||
'newWindow',
|
||||
`width=${width},height=${height},top=${top},left=${left},menubar=0,scrollbars=1,resizable=1,status=1,titlebar=0,toolbar=0,location=1`,
|
||||
);
|
||||
}
|
||||
getUserInfo();
|
||||
router.push(`/payment?order_no=${orderNo}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
{loading && <LoaderCircle className='mr-2 animate-spin' />}
|
||||
{t('buyNow')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { Display } from '@/components/display';
|
||||
import { SubscribeBilling } from '@/components/subscribe/billing';
|
||||
import { SubscribeDetail } from '@/components/subscribe/detail';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { checkoutOrder, queryOrderDetail } from '@/services/user/order';
|
||||
import { Icon } from '@iconify/react';
|
||||
@ -22,9 +24,6 @@ import { useTranslations } from 'next-intl';
|
||||
import Link from 'next/link';
|
||||
import { QRCodeCanvas } from 'qrcode.react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { SubscribeBilling } from '../subscribe/billing';
|
||||
import { SubscribeDetail } from '../subscribe/detail';
|
||||
import StripePayment from './stripe';
|
||||
|
||||
export default function Page() {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { Display } from '@/components/display';
|
||||
import Recharge from '@/components/subscribe/recharge';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { Icon } from '@iconify/react';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
@ -16,7 +17,6 @@ import { isBrowser } from '@workspace/ui/utils';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||
import { toast } from 'sonner';
|
||||
import Recharge from './order/recharge';
|
||||
|
||||
export function SidebarRight({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
const { user } = useGlobalStore();
|
||||
|
||||
@ -13,8 +13,8 @@ import { useTranslations } from 'next-intl';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { Empty } from '@/components/empty';
|
||||
import Purchase from '../order/purchase';
|
||||
import { SubscribeDetail } from './detail';
|
||||
import { SubscribeDetail } from '@/components/subscribe/detail';
|
||||
import Purchase from '@/components/subscribe/purchase';
|
||||
|
||||
export default function Page() {
|
||||
const t = useTranslations('subscribe');
|
||||
@ -112,7 +112,7 @@ export default function Page() {
|
||||
<SubscribeDetail
|
||||
subscribe={{
|
||||
...item,
|
||||
name: null,
|
||||
name: undefined,
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
|
||||
@ -9,8 +9,8 @@ import { useTranslations } from 'next-intl';
|
||||
import { useRef } from 'react';
|
||||
|
||||
import { Empty } from '@/components/empty';
|
||||
import Recharge from '@/components/subscribe/recharge';
|
||||
import { formatDate } from '@workspace/ui/utils';
|
||||
import Recharge from '../order/recharge';
|
||||
|
||||
export default function Page() {
|
||||
const t = useTranslations('wallet');
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { SubscribeDetail } from '@/app/(main)/(user)/subscribe/detail';
|
||||
import { Display } from '@/components/display';
|
||||
import { SubscribeDetail } from '@/components/subscribe/detail';
|
||||
import { getSubscription } from '@/services/common/common';
|
||||
import { Icon } from '@iconify/react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
@ -112,7 +112,7 @@ export function ProductShowcase() {
|
||||
<SubscribeDetail
|
||||
subscribe={{
|
||||
...item,
|
||||
name: null,
|
||||
name: undefined,
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
|
||||
@ -4,22 +4,17 @@ import { Display } from '@/components/display';
|
||||
import { Separator } from '@workspace/ui/components/separator';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
interface SubscribeBillingProps {
|
||||
order?: {
|
||||
type?: number;
|
||||
subscribe_id?: number;
|
||||
quantity?: number;
|
||||
price?: number;
|
||||
discount?: number;
|
||||
coupon_discount?: number;
|
||||
fee_amount?: number;
|
||||
amount?: number;
|
||||
unit_price?: number;
|
||||
unit_time?: number;
|
||||
};
|
||||
}
|
||||
|
||||
export function SubscribeBilling({ order }: SubscribeBillingProps) {
|
||||
export function SubscribeBilling({
|
||||
order,
|
||||
}: {
|
||||
order?: Partial<
|
||||
API.OrderDetail & {
|
||||
unit_price: number;
|
||||
unit_time: number;
|
||||
subscribe_discount: number;
|
||||
}
|
||||
>;
|
||||
}) {
|
||||
const t = useTranslations('subscribe');
|
||||
|
||||
return (
|
||||
@ -52,6 +47,14 @@ export function SubscribeBilling({ order }: SubscribeBillingProps) {
|
||||
<Display type='currency' value={order?.coupon_discount} />
|
||||
</span>
|
||||
</li>
|
||||
{order?.subscribe_discount && (
|
||||
<li>
|
||||
<span className='text-muted-foreground'>{t('subscriptionDiscount')}</span>
|
||||
<span>
|
||||
<Display type='currency' value={order?.subscribe_discount} />
|
||||
</span>
|
||||
</li>
|
||||
)}
|
||||
<li>
|
||||
<span className='text-muted-foreground'>{t('billing.fee')}</span>
|
||||
<span>
|
||||
27
apps/user/components/subscribe/coupon-input.tsx
Normal file
27
apps/user/components/subscribe/coupon-input.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
'use client';
|
||||
|
||||
import { Input } from '@workspace/ui/components/input';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import React from 'react';
|
||||
|
||||
interface CouponInputProps {
|
||||
coupon?: string;
|
||||
onChange: (value: string) => void;
|
||||
}
|
||||
|
||||
const CouponInput: React.FC<CouponInputProps> = ({ coupon, onChange }) => {
|
||||
const t = useTranslations('subscribe');
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='font-semibold'>{t('coupon')}</div>
|
||||
<Input
|
||||
placeholder={t('enterCoupon')}
|
||||
value={coupon}
|
||||
onChange={(e) => onChange(e.target.value.trim())}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default CouponInput;
|
||||
@ -3,18 +3,16 @@
|
||||
import { Display } from '@/components/display';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
interface SubscribeDetailProps {
|
||||
subscribe?: {
|
||||
traffic?: number | null;
|
||||
speed_limit?: number | null;
|
||||
device_limit?: number | null;
|
||||
name?: string | null;
|
||||
quantity?: number | null;
|
||||
unit_price?: number | null;
|
||||
};
|
||||
}
|
||||
|
||||
export function SubscribeDetail({ subscribe }: SubscribeDetailProps) {
|
||||
export function SubscribeDetail({
|
||||
subscribe,
|
||||
}: {
|
||||
subscribe?: Partial<
|
||||
API.Subscribe & {
|
||||
name: string;
|
||||
quantity: number;
|
||||
}
|
||||
>;
|
||||
}) {
|
||||
const t = useTranslations('subscribe.detail');
|
||||
|
||||
return (
|
||||
69
apps/user/components/subscribe/duration-selector.tsx
Normal file
69
apps/user/components/subscribe/duration-selector.tsx
Normal file
@ -0,0 +1,69 @@
|
||||
'use client';
|
||||
|
||||
import { Badge } from '@workspace/ui/components/badge';
|
||||
import { Label } from '@workspace/ui/components/label';
|
||||
import { RadioGroup, RadioGroupItem } from '@workspace/ui/components/radio-group';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
interface DurationSelectorProps {
|
||||
quantity: number;
|
||||
unitTime?: string;
|
||||
discounts?: Array<{ quantity: number; discount: number }>;
|
||||
onChange: (value: number) => void;
|
||||
}
|
||||
|
||||
const DurationSelector: React.FC<DurationSelectorProps> = ({
|
||||
quantity,
|
||||
unitTime = 'Month',
|
||||
discounts = [],
|
||||
onChange,
|
||||
}) => {
|
||||
const t = useTranslations('subscribe');
|
||||
const handleChange = useCallback(
|
||||
(value: string) => {
|
||||
onChange(Number(value));
|
||||
},
|
||||
[onChange],
|
||||
);
|
||||
|
||||
const DurationOption: React.FC<{ value: string; label: string; discount?: number }> = ({
|
||||
value,
|
||||
label,
|
||||
discount,
|
||||
}) => (
|
||||
<div className='relative'>
|
||||
<RadioGroupItem value={value} id={value} className='peer sr-only' />
|
||||
<Label
|
||||
htmlFor={value}
|
||||
className='border-muted bg-popover hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary relative flex h-full flex-col items-center justify-center gap-2 rounded-md border-2 p-2'
|
||||
>
|
||||
{label}
|
||||
{discount && <Badge variant='destructive'>-{discount}%</Badge>}
|
||||
</Label>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='font-semibold'>{t('purchaseDuration')}</div>
|
||||
<RadioGroup
|
||||
value={String(quantity)}
|
||||
onValueChange={handleChange}
|
||||
className='flex flex-wrap gap-3'
|
||||
>
|
||||
{unitTime !== 'Minute' && <DurationOption value='1' label={`1 / ${t(unitTime)}`} />}
|
||||
{discounts?.map((item) => (
|
||||
<DurationOption
|
||||
key={item.quantity}
|
||||
value={String(item.quantity)}
|
||||
label={`${item.quantity} / ${t(unitTime)}`}
|
||||
discount={100 - item.discount}
|
||||
/>
|
||||
))}
|
||||
</RadioGroup>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DurationSelector;
|
||||
56
apps/user/components/subscribe/payment-methods.tsx
Normal file
56
apps/user/components/subscribe/payment-methods.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
'use client';
|
||||
|
||||
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';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import Image from 'next/image';
|
||||
import React, { memo } from 'react';
|
||||
|
||||
interface PaymentMethodsProps {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
}
|
||||
|
||||
const PaymentMethods: React.FC<PaymentMethodsProps> = ({ value, onChange }) => {
|
||||
const t = useTranslations('subscribe');
|
||||
|
||||
const { data } = useQuery({
|
||||
queryKey: ['getAvailablePaymentMethods'],
|
||||
queryFn: async () => {
|
||||
const { data } = await getAvailablePaymentMethods();
|
||||
return data.data?.list || [];
|
||||
},
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<div className='font-semibold'>{t('paymentMethod')}</div>
|
||||
<RadioGroup className='mb-6 grid grid-cols-5 gap-2' value={value} onValueChange={onChange}>
|
||||
{data?.map((item) => (
|
||||
<div key={item.mark}>
|
||||
<RadioGroupItem value={item.mark} id={item.mark} className='peer sr-only' />
|
||||
<Label
|
||||
htmlFor={item.mark}
|
||||
className='border-muted bg-popover hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary flex flex-col items-center justify-between rounded-md border-2 py-2'
|
||||
>
|
||||
<div className='mb-3 size-12'>
|
||||
<Image
|
||||
src={item.icon || `/payment/${item.mark}.svg`}
|
||||
width={48}
|
||||
height={48}
|
||||
alt={item.name || t(`methods.${item.mark}`)}
|
||||
/>
|
||||
</div>
|
||||
<span className='w-full overflow-hidden text-ellipsis whitespace-nowrap text-center'>
|
||||
{item.name || t(`methods.${item.mark}`)}
|
||||
</span>
|
||||
</Label>
|
||||
</div>
|
||||
))}
|
||||
</RadioGroup>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(PaymentMethods);
|
||||
170
apps/user/components/subscribe/purchase.tsx
Normal file
170
apps/user/components/subscribe/purchase.tsx
Normal file
@ -0,0 +1,170 @@
|
||||
'use client';
|
||||
|
||||
import CouponInput from '@/components/subscribe/coupon-input';
|
||||
import DurationSelector from '@/components/subscribe/duration-selector';
|
||||
import PaymentMethods from '@/components/subscribe/payment-methods';
|
||||
import SubscribeSelector from '@/components/subscribe/subscribe-selector';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { checkoutOrder, preCreateOrder, purchase } from '@/services/user/order';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
import { Card, CardContent } from '@workspace/ui/components/card';
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@workspace/ui/components/dialog';
|
||||
import { Separator } from '@workspace/ui/components/separator';
|
||||
import { LoaderCircle } from 'lucide-react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useCallback, useEffect, useState, useTransition } from 'react';
|
||||
import { SubscribeBilling } from './billing';
|
||||
import { SubscribeDetail } from './detail';
|
||||
|
||||
export default function Purchase({
|
||||
subscribe,
|
||||
setSubscribe,
|
||||
}: {
|
||||
subscribe?: API.Subscribe;
|
||||
setSubscribe: (subscribe?: API.Subscribe) => void;
|
||||
}) {
|
||||
const t = useTranslations('subscribe');
|
||||
const { getUserInfo } = useGlobalStore();
|
||||
const router = useRouter();
|
||||
const [params, setParams] = useState<Partial<API.PurchaseOrderRequest>>({
|
||||
quantity: 1,
|
||||
subscribe_id: 0,
|
||||
payment: 'balance',
|
||||
coupon: '',
|
||||
});
|
||||
const [loading, startTransition] = useTransition();
|
||||
|
||||
const { data: order } = useQuery({
|
||||
enabled: !!subscribe?.id,
|
||||
queryKey: ['preCreateOrder', params],
|
||||
queryFn: async () => {
|
||||
const { data } = await preCreateOrder({
|
||||
...params,
|
||||
subscribe_id: subscribe?.id as number,
|
||||
} as API.PurchaseOrderRequest);
|
||||
return data.data;
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (subscribe) {
|
||||
setParams((prev) => ({
|
||||
...prev,
|
||||
quantity: 1,
|
||||
subscribe_id: subscribe?.id,
|
||||
}));
|
||||
}
|
||||
}, [subscribe]);
|
||||
|
||||
const handleChange = useCallback((field: keyof typeof params, value: string | number) => {
|
||||
setParams((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const handleSubmit = useCallback(async () => {
|
||||
startTransition(async () => {
|
||||
try {
|
||||
const response = await purchase(params as API.PurchaseOrderRequest);
|
||||
const orderNo = response.data.data?.order_no;
|
||||
if (orderNo) {
|
||||
const { data } = await checkoutOrder({
|
||||
orderNo,
|
||||
});
|
||||
const type = data.data?.type;
|
||||
const checkout_url = data.data?.checkout_url;
|
||||
if (type === 'link') {
|
||||
const width = 600;
|
||||
const height = 800;
|
||||
const left = (screen.width - width) / 2;
|
||||
const top = (screen.height - height) / 2;
|
||||
window.open(
|
||||
checkout_url,
|
||||
'newWindow',
|
||||
`width=${width},height=${height},top=${top},left=${left},menubar=0,scrollbars=1,resizable=1,status=1,titlebar=0,toolbar=0,location=1`,
|
||||
);
|
||||
}
|
||||
getUserInfo();
|
||||
router.push(`/payment?order_no=${orderNo}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
}, [params, router]);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={!!subscribe?.id}
|
||||
onOpenChange={(open) => {
|
||||
if (!open) setSubscribe(undefined);
|
||||
}}
|
||||
>
|
||||
<DialogContent className='flex h-full max-w-screen-lg flex-col overflow-hidden border-none p-0 md:h-auto'>
|
||||
<DialogHeader className='p-6 pb-0'>
|
||||
<DialogTitle>{t('buySubscription')}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className='grid w-full flex-grow gap-3 overflow-auto p-6 pt-0 lg:grid-cols-2'>
|
||||
<Card className='border-transparent shadow-none md:border-inherit md:shadow'>
|
||||
<CardContent className='grid gap-3 p-0 text-sm md:p-6'>
|
||||
<SubscribeDetail
|
||||
subscribe={{
|
||||
...subscribe,
|
||||
quantity: params.quantity,
|
||||
}}
|
||||
/>
|
||||
<Separator />
|
||||
<SubscribeBilling
|
||||
order={{
|
||||
...order,
|
||||
quantity: params.quantity,
|
||||
unit_price: subscribe?.unit_price,
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<div className='flex flex-col justify-between text-sm'>
|
||||
<div className='grid gap-3'>
|
||||
<DurationSelector
|
||||
quantity={params.quantity!}
|
||||
unitTime={subscribe?.unit_time}
|
||||
discounts={subscribe?.discount}
|
||||
onChange={(value) => {
|
||||
handleChange('quantity', value);
|
||||
}}
|
||||
/>
|
||||
<CouponInput
|
||||
coupon={params.coupon}
|
||||
onChange={(value) => handleChange('coupon', value)}
|
||||
/>
|
||||
<SubscribeSelector
|
||||
value={params.discount_subscribe_id}
|
||||
data={order?.discount_list || []}
|
||||
onChange={(value) => {
|
||||
handleChange('discount_subscribe_id', value);
|
||||
}}
|
||||
/>
|
||||
<PaymentMethods
|
||||
value={params.payment!}
|
||||
onChange={(value) => {
|
||||
handleChange('payment', value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
className='fixed bottom-0 left-0 w-full rounded-none md:relative md:mt-6'
|
||||
disabled={loading}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
{loading && <LoaderCircle className='mr-2 animate-spin' />}
|
||||
{t('buyNow')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@ -24,7 +24,7 @@ import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useState, useTransition } from 'react';
|
||||
|
||||
export default function Recharge(props: ButtonProps) {
|
||||
const t = useTranslations('order');
|
||||
const t = useTranslations('subscribe');
|
||||
const { common } = useGlobalStore();
|
||||
const { currency } = common;
|
||||
|
||||
@ -62,7 +62,7 @@ export default function Recharge(props: ButtonProps) {
|
||||
<DialogContent className='flex h-full flex-col overflow-hidden md:h-auto'>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('balanceRecharge')}</DialogTitle>
|
||||
<DialogDescription>{t('description')}</DialogDescription>
|
||||
<DialogDescription>{t('rechargeDescription')}</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className='flex flex-col justify-between text-sm'>
|
||||
<div className='grid gap-3'>
|
||||
171
apps/user/components/subscribe/renewal.tsx
Normal file
171
apps/user/components/subscribe/renewal.tsx
Normal file
@ -0,0 +1,171 @@
|
||||
'use client';
|
||||
|
||||
import CouponInput from '@/components/subscribe/coupon-input';
|
||||
import DurationSelector from '@/components/subscribe/duration-selector';
|
||||
import PaymentMethods from '@/components/subscribe/payment-methods';
|
||||
import SubscribeSelector from '@/components/subscribe/subscribe-selector';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { checkoutOrder, preCreateOrder, renewal } from '@/services/user/order';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
import { Card, CardContent } from '@workspace/ui/components/card';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from '@workspace/ui/components/dialog';
|
||||
import { Separator } from '@workspace/ui/components/separator';
|
||||
import { LoaderCircle } from 'lucide-react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useCallback, useEffect, useState, useTransition } from 'react';
|
||||
import { SubscribeBilling } from './billing';
|
||||
import { SubscribeDetail } from './detail';
|
||||
|
||||
export default function Renewal({ token, subscribe }: { token: string; subscribe: API.Subscribe }) {
|
||||
const t = useTranslations('subscribe');
|
||||
const { getUserInfo } = useGlobalStore();
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
const router = useRouter();
|
||||
const [params, setParams] = useState<Partial<API.RenewalOrderRequest>>({
|
||||
quantity: 1,
|
||||
subscribe_id: subscribe.id,
|
||||
payment: 'balance',
|
||||
coupon: '',
|
||||
subscribe_token: token,
|
||||
});
|
||||
const [loading, startTransition] = useTransition();
|
||||
|
||||
const { data: order } = useQuery({
|
||||
enabled: !!subscribe.id && open,
|
||||
queryKey: ['preCreateOrder', params],
|
||||
queryFn: async () => {
|
||||
const { data } = await preCreateOrder({
|
||||
...params,
|
||||
subscribe_id: subscribe.id,
|
||||
} as API.PurchaseOrderRequest);
|
||||
return data.data;
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (subscribe.id && token) {
|
||||
setParams((prev) => ({
|
||||
...prev,
|
||||
quantity: 1,
|
||||
subscribe_id: subscribe.id,
|
||||
subscribe_token: token,
|
||||
}));
|
||||
}
|
||||
}, [subscribe.id, token]);
|
||||
|
||||
const handleChange = useCallback((field: keyof typeof params, value: string | number) => {
|
||||
setParams((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const handleSubmit = useCallback(async () => {
|
||||
startTransition(async () => {
|
||||
try {
|
||||
const response = await renewal(params as API.RenewalOrderRequest);
|
||||
const orderNo = response.data.data?.order_no;
|
||||
if (orderNo) {
|
||||
const { data } = await checkoutOrder({
|
||||
orderNo,
|
||||
});
|
||||
const type = data.data?.type;
|
||||
const checkout_url = data.data?.checkout_url;
|
||||
if (type === 'link') {
|
||||
const width = 600;
|
||||
const height = 800;
|
||||
const left = (screen.width - width) / 2;
|
||||
const top = (screen.height - height) / 2;
|
||||
window.open(
|
||||
checkout_url,
|
||||
'newWindow',
|
||||
`width=${width},height=${height},top=${top},left=${left},menubar=0,scrollbars=1,resizable=1,status=1,titlebar=0,toolbar=0,location=1`,
|
||||
);
|
||||
}
|
||||
getUserInfo();
|
||||
router.push(`/payment?order_no=${orderNo}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
}, [params, router]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger asChild>
|
||||
<Button size='sm'>{t('renew')}</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className='flex h-full max-w-screen-lg flex-col overflow-hidden md:h-auto'>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('renewSubscription')}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className='grid w-full gap-3 lg:grid-cols-2'>
|
||||
<Card className='border-transparent shadow-none md:border-inherit md:shadow'>
|
||||
<CardContent className='grid gap-3 p-0 text-sm md:p-6'>
|
||||
<SubscribeDetail
|
||||
subscribe={{
|
||||
...subscribe,
|
||||
quantity: params.quantity,
|
||||
}}
|
||||
/>
|
||||
<Separator />
|
||||
<SubscribeBilling
|
||||
order={{
|
||||
...order,
|
||||
quantity: params.quantity,
|
||||
unit_price: subscribe?.unit_price,
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<div className='flex flex-col justify-between text-sm'>
|
||||
<div className='grid gap-3'>
|
||||
<DurationSelector
|
||||
quantity={params.quantity!}
|
||||
unitTime={subscribe?.unit_time}
|
||||
discounts={subscribe?.discount}
|
||||
onChange={(value) => {
|
||||
handleChange('quantity', value);
|
||||
}}
|
||||
/>
|
||||
<CouponInput
|
||||
coupon={params.coupon}
|
||||
onChange={(value) => handleChange('coupon', value)}
|
||||
/>
|
||||
<SubscribeSelector
|
||||
value={params.discount_subscribe_id}
|
||||
data={order?.discount_list || []}
|
||||
onChange={(value) => {
|
||||
handleChange('discount_subscribe_id', value);
|
||||
}}
|
||||
/>
|
||||
<PaymentMethods
|
||||
value={params.payment!}
|
||||
onChange={(value) => {
|
||||
handleChange('payment', value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
className='fixed bottom-0 left-0 w-full rounded-none md:relative md:mt-6'
|
||||
disabled={loading}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
{loading && <LoaderCircle className='mr-2 animate-spin' />}
|
||||
{t('buyNow')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@ -31,7 +31,7 @@ export default function ResetTraffic({
|
||||
token: string;
|
||||
replacement?: number;
|
||||
}) {
|
||||
const t = useTranslations('order');
|
||||
const t = useTranslations('subscribe');
|
||||
const { getUserInfo } = useGlobalStore();
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
const router = useRouter();
|
||||
78
apps/user/components/subscribe/subscribe-selector.tsx
Normal file
78
apps/user/components/subscribe/subscribe-selector.tsx
Normal file
@ -0,0 +1,78 @@
|
||||
'use client';
|
||||
|
||||
import { Display } from '@/components/display';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { Combobox } from '@workspace/ui/custom-components/combobox';
|
||||
import { formatDate } from '@workspace/ui/utils';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
|
||||
interface SubscribeSelectorProps {
|
||||
value?: number;
|
||||
data: API.SubscribeDiscountInfo[];
|
||||
onChange: (value: number) => void;
|
||||
}
|
||||
|
||||
const SubscribeSelector: React.FC<SubscribeSelectorProps> = ({ value, data, onChange }) => {
|
||||
const t = useTranslations('subscribe');
|
||||
const { common } = useGlobalStore();
|
||||
const singleModel = common.subscribe.single_model;
|
||||
|
||||
useEffect(() => {
|
||||
if (singleModel && data.length > 0 && data[0]) {
|
||||
onChange(data[0].id);
|
||||
}
|
||||
}, [data, singleModel, onChange, value]);
|
||||
|
||||
const handleChange = useCallback(
|
||||
(selectedValue: number) => {
|
||||
if (singleModel) {
|
||||
if (selectedValue) {
|
||||
onChange(selectedValue);
|
||||
}
|
||||
} else {
|
||||
onChange(selectedValue);
|
||||
}
|
||||
},
|
||||
[singleModel, onChange],
|
||||
);
|
||||
|
||||
const options = useMemo(() => {
|
||||
return data.map((item) => ({
|
||||
children: (
|
||||
<div className='flex w-full items-center justify-between px-2 py-1.5'>
|
||||
<div className='mr-2 flex flex-col overflow-hidden'>
|
||||
<span className='truncate text-sm font-medium'>{item.name}</span>
|
||||
<time
|
||||
className='text-muted-foreground truncate text-xs'
|
||||
title={formatDate(new Date(item.expire_time))}
|
||||
>
|
||||
{formatDate(new Date(item.expire_time), false)}
|
||||
</time>
|
||||
</div>
|
||||
<span className='text-muted-foreground flex-shrink-0 text-sm' title='Price'>
|
||||
<Display value={item.price} type='currency' />
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
}));
|
||||
}, [data]);
|
||||
|
||||
if (!data.length) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='font-semibold'>{t('subscriptionDiscount')}</div>
|
||||
<Combobox<number, false>
|
||||
placeholder={t('selectSubscription')}
|
||||
options={options}
|
||||
value={value}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SubscribeSelector;
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Tato aplikace momentálně nepodporuje spuštění, prosím importujte ručně, adresa předplatného byla automaticky zkopírována",
|
||||
"mySubscriptions": "Moje předplatné",
|
||||
"nextResetDays": "Příští reset/den",
|
||||
"noLimit": "Bez omezení",
|
||||
"prompt": "Výzva",
|
||||
"purchaseSubscription": "Zakoupit předplatné",
|
||||
"qrCode": "QR kód",
|
||||
|
||||
@ -1,21 +1,10 @@
|
||||
{
|
||||
"Day": "Den",
|
||||
"Hour": "Hodina",
|
||||
"Minute": "Minuta",
|
||||
"Month": "Měsíc",
|
||||
"Year": "Rok",
|
||||
"balanceRecharge": "Doplnění zůstatku",
|
||||
"buyNow": "Koupit nyní",
|
||||
"buySubscription": "Koupit předplatné",
|
||||
"cancel": "Zrušit",
|
||||
"createdAt": "Datum vytvoření",
|
||||
"description": "Jedním kliknutím dobijete, snadno a rychle",
|
||||
"detail": "Detail",
|
||||
"enterAmount": "Zadejte částku k dobití",
|
||||
"enterCoupon": "Zadejte slevový kód",
|
||||
"goToPayment": "Přejít k platbě",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (tváří v tvář)",
|
||||
"alipay_f2f": "Alipay (Tváří v tvář)",
|
||||
"balance": "Zůstatek",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "Platební metoda",
|
||||
"paymentSuccess": "Platba úspěšná",
|
||||
"productList": "Seznam produktů",
|
||||
"purchaseDuration": "Doba nákupu",
|
||||
"recharge": "dobít",
|
||||
"rechargeAmount": "Částka dobití",
|
||||
"rechargeNow": "Dobít nyní",
|
||||
"renew": "Obnovit",
|
||||
"renewSubscription": "Obnovit předplatné",
|
||||
"resetPrice": "Obnovit cenu",
|
||||
"resetTraffic": "Obnovit přenos dat",
|
||||
"resetTrafficDescription": "Obnoví se pouze měsíční přenos dat",
|
||||
"resetTrafficTitle": "Obnovit přenos dat",
|
||||
"scanToPay": "Prosím, naskenujte kód pro platbu",
|
||||
"status": {
|
||||
"0": "Stav",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Hodina",
|
||||
"Minute": "Minuta",
|
||||
"Month": "Měsíc",
|
||||
"NoLimit": "Bez omezení",
|
||||
"Year": "Rok",
|
||||
"all": "Vše",
|
||||
"balanceRecharge": "Dobití zůstatku",
|
||||
"billing": {
|
||||
"billingTitle": "Faktura za zboží",
|
||||
"couponDiscount": "Sleva z kupónu",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Celková cena"
|
||||
},
|
||||
"buy": "Koupit",
|
||||
"buyNow": "Koupit nyní",
|
||||
"buySubscription": "Koupit předplatné",
|
||||
"category": "Kategorie",
|
||||
"coupon": "Kupón",
|
||||
"detail": {
|
||||
"availableTraffic": "Dostupný provoz",
|
||||
"connectedDevices": "Počet současně připojených IP",
|
||||
"connectionSpeed": "Rychlost připojení",
|
||||
"productDetail": "Detaily produktu"
|
||||
},
|
||||
"enterAmount": "Zadejte částku dobití",
|
||||
"enterCoupon": "Zadejte kód kupónu",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (tváří v tvář)",
|
||||
"balance": "Zůstatek",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Platební metoda",
|
||||
"productDescription": "Popis produktu",
|
||||
"products": "Produkty"
|
||||
"products": "Produkty",
|
||||
"purchaseDuration": "Doba nákupu",
|
||||
"recharge": "Dobít",
|
||||
"rechargeAmount": "Částka dobití",
|
||||
"rechargeDescription": "Jedním kliknutím dobijete, snadné ovládání",
|
||||
"rechargeNow": "Dobít nyní",
|
||||
"renew": "Obnovit",
|
||||
"renewSubscription": "Obnovit předplatné",
|
||||
"resetPrice": "Obnovit cenu",
|
||||
"resetTraffic": "Obnovit provoz",
|
||||
"resetTrafficDescription": "Obnovit provoz pouze pro aktuální měsíc",
|
||||
"resetTrafficTitle": "Obnovit provoz",
|
||||
"selectSubscription": "Vyberte předplatné",
|
||||
"subscriptionDiscount": "Sleva na předplatné"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Diese App unterstützt derzeit keine Aktivierung. Bitte manuell importieren, die Abonnementadresse wurde automatisch kopiert.",
|
||||
"mySubscriptions": "Meine Abonnements",
|
||||
"nextResetDays": "Nächster Reset/Tage",
|
||||
"noLimit": "Kein Limit",
|
||||
"prompt": "Aufforderung",
|
||||
"purchaseSubscription": "Abonnement kaufen",
|
||||
"qrCode": "QR-Code",
|
||||
|
||||
@ -1,23 +1,12 @@
|
||||
{
|
||||
"Day": "Tag",
|
||||
"Hour": "Stunde",
|
||||
"Minute": "Minute",
|
||||
"Month": "Monat",
|
||||
"Year": "Jahr",
|
||||
"balanceRecharge": "Guthaben aufladen",
|
||||
"buyNow": "Jetzt kaufen",
|
||||
"buySubscription": "Abonnement kaufen",
|
||||
"cancel": "Abbrechen",
|
||||
"createdAt": "Erstellungszeitpunkt",
|
||||
"description": "Mit einem Klick aufladen, ganz einfach erledigt",
|
||||
"detail": "Einzelheiten",
|
||||
"enterAmount": "Bitte geben Sie den Aufladebetrag ein",
|
||||
"enterCoupon": "Bitte geben Sie den Rabattcode ein",
|
||||
"goToPayment": "Zur Zahlung gehen",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (Face-to-Face)",
|
||||
"alipay_f2f": "Alipay (Face to Face)",
|
||||
"balance": "Guthaben",
|
||||
"epay": "E-Pay",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "Zahlungsmethode",
|
||||
"paymentSuccess": "Zahlung erfolgreich",
|
||||
"productList": "Produktliste",
|
||||
"purchaseDuration": "Kaufdauer",
|
||||
"recharge": "Aufladen",
|
||||
"rechargeAmount": "Aufladebetrag",
|
||||
"rechargeNow": "Jetzt aufladen",
|
||||
"renew": "Erneuern",
|
||||
"renewSubscription": "Abonnement verlängern",
|
||||
"resetPrice": "Preis zurücksetzen",
|
||||
"resetTraffic": "Datenverkehr zurücksetzen",
|
||||
"resetTrafficDescription": "Setzt nur den Datenverkehr des aktuellen Monats zurück",
|
||||
"resetTrafficTitle": "Datenverkehr zurücksetzen",
|
||||
"scanToPay": "Bitte scannen Sie zum Bezahlen",
|
||||
"status": {
|
||||
"0": "Status",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Stunde",
|
||||
"Minute": "Minute",
|
||||
"Month": "Monat",
|
||||
"NoLimit": "Kein Limit",
|
||||
"Year": "Jahr",
|
||||
"all": "Alle",
|
||||
"balanceRecharge": "Guthaben aufladen",
|
||||
"billing": {
|
||||
"billingTitle": "Produktrechnung",
|
||||
"couponDiscount": "Rabattcode-Rabatt",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Gesamtpreis"
|
||||
},
|
||||
"buy": "Kaufen",
|
||||
"buyNow": "Jetzt kaufen",
|
||||
"buySubscription": "Abonnement kaufen",
|
||||
"category": "Kategorie",
|
||||
"coupon": "Gutschein",
|
||||
"detail": {
|
||||
"availableTraffic": "Verfügbares Datenvolumen",
|
||||
"connectedDevices": "Gleichzeitig verbundene IP-Anzahl",
|
||||
"connectionSpeed": "Verbindungsgeschwindigkeit",
|
||||
"productDetail": "Produktdetails"
|
||||
},
|
||||
"enterAmount": "Geben Sie den Aufladebetrag ein",
|
||||
"enterCoupon": "Gutscheincode eingeben",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (Face-to-Face)",
|
||||
"balance": "Guthaben",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Zahlungsmethode",
|
||||
"productDescription": "Produktbeschreibung",
|
||||
"products": "Produkte"
|
||||
"products": "Produkte",
|
||||
"purchaseDuration": "Kaufdauer",
|
||||
"recharge": "Aufladen",
|
||||
"rechargeAmount": "Aufladebetrag",
|
||||
"rechargeDescription": "Ein-Klick-Aufladung, einfach zu handhaben",
|
||||
"rechargeNow": "Jetzt aufladen",
|
||||
"renew": "Erneuern",
|
||||
"renewSubscription": "Abonnement erneuern",
|
||||
"resetPrice": "Preis zurücksetzen",
|
||||
"resetTraffic": "Datenverkehr zurücksetzen",
|
||||
"resetTrafficDescription": "Verkehr nur für den aktuellen Monat zurücksetzen",
|
||||
"resetTrafficTitle": "Datenverkehr zurücksetzen",
|
||||
"selectSubscription": "Abonnement auswählen",
|
||||
"subscriptionDiscount": "Abonnementrabatt"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "This app does not support activation. Please import manually. The subscription address has been copied.",
|
||||
"mySubscriptions": "My Subscriptions",
|
||||
"nextResetDays": "Next Reset in Days",
|
||||
"noLimit": "No Limit",
|
||||
"prompt": "Prompt",
|
||||
"purchaseSubscription": "Purchase Subscription",
|
||||
"qrCode": "QR Code",
|
||||
|
||||
@ -1,18 +1,7 @@
|
||||
{
|
||||
"Day": "Day",
|
||||
"Hour": "Hour",
|
||||
"Minute": "Minute",
|
||||
"Month": "Month",
|
||||
"Year": "Year",
|
||||
"balanceRecharge": "Balance Recharge",
|
||||
"buyNow": "Buy Now",
|
||||
"buySubscription": "Buy Subscription",
|
||||
"cancel": "Cancel",
|
||||
"createdAt": "Created At",
|
||||
"description": "One-click recharge, easy to handle",
|
||||
"detail": "Detail",
|
||||
"enterAmount": "Enter recharge amount",
|
||||
"enterCoupon": "Enter Coupon Code",
|
||||
"goToPayment": "Go to Payment",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (Face to Face)",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "Payment Method",
|
||||
"paymentSuccess": "Payment Success",
|
||||
"productList": "Product List",
|
||||
"purchaseDuration": "Purchase Duration",
|
||||
"recharge": "Recharge",
|
||||
"rechargeAmount": "Recharge Amount",
|
||||
"rechargeNow": "Recharge Now",
|
||||
"renew": "Renew",
|
||||
"renewSubscription": "Renew Subscription",
|
||||
"resetPrice": "Reset Price",
|
||||
"resetTraffic": "Reset Traffic",
|
||||
"resetTrafficDescription": "Reset traffic for the current month only",
|
||||
"resetTrafficTitle": "Reset Traffic",
|
||||
"scanToPay": "Scan to Pay",
|
||||
"status": {
|
||||
"0": "Status",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Hour",
|
||||
"Minute": "Minute",
|
||||
"Month": "Month",
|
||||
"NoLimit": "No Limit",
|
||||
"Year": "Year",
|
||||
"all": "All",
|
||||
"balanceRecharge": "Balance Recharge",
|
||||
"billing": {
|
||||
"billingTitle": "Product Billing",
|
||||
"couponDiscount": "Coupon Discount",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Total"
|
||||
},
|
||||
"buy": "Buy",
|
||||
"buyNow": "Buy Now",
|
||||
"buySubscription": "Buy Subscription",
|
||||
"category": "Category",
|
||||
"coupon": "Coupon",
|
||||
"detail": {
|
||||
"availableTraffic": "Available Traffic",
|
||||
"connectedDevices": "Connected Devices",
|
||||
"connectionSpeed": "Connection Speed",
|
||||
"productDetail": "Product Details"
|
||||
},
|
||||
"enterAmount": "Enter recharge amount",
|
||||
"enterCoupon": "Enter Coupon Code",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (Face to Face)",
|
||||
"balance": "Balance",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Payment Method",
|
||||
"productDescription": "Product Description",
|
||||
"products": "Products"
|
||||
"products": "Products",
|
||||
"purchaseDuration": "Purchase Duration",
|
||||
"recharge": "Recharge",
|
||||
"rechargeAmount": "Recharge Amount",
|
||||
"rechargeDescription": "One-click recharge, easy to handle",
|
||||
"rechargeNow": "Recharge Now",
|
||||
"renew": "Renew",
|
||||
"renewSubscription": "Renew Subscription",
|
||||
"resetPrice": "Reset Price",
|
||||
"resetTraffic": "Reset Traffic",
|
||||
"resetTrafficDescription": "Reset traffic for the current month only",
|
||||
"resetTrafficTitle": "Reset Traffic",
|
||||
"selectSubscription": "Select Subscription",
|
||||
"subscriptionDiscount": "Subscription Discount"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Esta aplicación no admite la activación por el momento. Por favor, importe manualmente. La dirección de suscripción ha sido copiada automáticamente.",
|
||||
"mySubscriptions": "Mis suscripciones",
|
||||
"nextResetDays": "Próximo reinicio/días",
|
||||
"noLimit": "Sin límite",
|
||||
"prompt": "sugerencia",
|
||||
"purchaseSubscription": "Comprar suscripción",
|
||||
"qrCode": "Código QR",
|
||||
|
||||
@ -1,21 +1,10 @@
|
||||
{
|
||||
"Day": "Día",
|
||||
"Hour": "Hora",
|
||||
"Minute": "Minuto",
|
||||
"Month": "Mes",
|
||||
"Year": "Año",
|
||||
"balanceRecharge": "Recarga de saldo",
|
||||
"buyNow": "Comprar ahora",
|
||||
"buySubscription": "Comprar suscripción",
|
||||
"cancel": "Cancelar",
|
||||
"createdAt": "Fecha de creación",
|
||||
"description": "Recarga con un clic, fácil y rápido",
|
||||
"detail": "Detalles",
|
||||
"enterAmount": "Por favor, introduzca el importe de recarga",
|
||||
"enterCoupon": "Introduce el código de descuento",
|
||||
"goToPayment": "Ir a pagar",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (cara a cara)",
|
||||
"alipay_f2f": "Alipay (Cara a Cara)",
|
||||
"balance": "Saldo",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
@ -28,19 +17,9 @@
|
||||
"orderNumber": "Número de pedido",
|
||||
"payment": "Ir a pagar",
|
||||
"paymentAmount": "Monto de pago",
|
||||
"paymentMethod": "Método de pago",
|
||||
"paymentMethod": "Método de Pago",
|
||||
"paymentSuccess": "Pago exitoso",
|
||||
"productList": "Lista de productos",
|
||||
"purchaseDuration": "Duración de la compra",
|
||||
"recharge": "recargar",
|
||||
"rechargeAmount": "Monto de recarga",
|
||||
"rechargeNow": "Recargar ahora",
|
||||
"renew": "renovar",
|
||||
"renewSubscription": "Renovar suscripción",
|
||||
"resetPrice": "Restablecer precio",
|
||||
"resetTraffic": "Restablecer tráfico",
|
||||
"resetTrafficDescription": "Solo se restablece el tráfico del mes actual",
|
||||
"resetTrafficTitle": "Restablecer tráfico",
|
||||
"scanToPay": "Por favor, escanee para pagar",
|
||||
"status": {
|
||||
"0": "estado",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Hora",
|
||||
"Minute": "Minuto",
|
||||
"Month": "Mes",
|
||||
"NoLimit": "Sin Límite",
|
||||
"Year": "Año",
|
||||
"all": "todo",
|
||||
"balanceRecharge": "Recarga de Saldo",
|
||||
"billing": {
|
||||
"billingTitle": "Factura de productos",
|
||||
"couponDiscount": "Descuento por cupón",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Precio total"
|
||||
},
|
||||
"buy": "Comprar",
|
||||
"buyNow": "Comprar ahora",
|
||||
"buySubscription": "Comprar suscripción",
|
||||
"category": "categoría",
|
||||
"coupon": "Cupón",
|
||||
"detail": {
|
||||
"availableTraffic": "Tráfico disponible",
|
||||
"connectedDevices": "Número de IPs conectadas simultáneamente",
|
||||
"connectionSpeed": "Velocidad de conexión",
|
||||
"productDetail": "Detalles del producto"
|
||||
},
|
||||
"enterAmount": "Ingrese el monto de recarga",
|
||||
"enterCoupon": "Introduce el código de cupón",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (cara a cara)",
|
||||
"balance": "Saldo",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Método de Pago",
|
||||
"productDescription": "Descripción del producto",
|
||||
"products": "productos"
|
||||
"products": "productos",
|
||||
"purchaseDuration": "Duración de la Compra",
|
||||
"recharge": "Recargar",
|
||||
"rechargeAmount": "Monto de Recarga",
|
||||
"rechargeDescription": "Recarga con un clic, fácil de manejar",
|
||||
"rechargeNow": "Recargar Ahora",
|
||||
"renew": "Renovar",
|
||||
"renewSubscription": "Renovar suscripción",
|
||||
"resetPrice": "Restablecer Precio",
|
||||
"resetTraffic": "Restablecer Tráfico",
|
||||
"resetTrafficDescription": "Restablecer el tráfico solo para el mes actual",
|
||||
"resetTrafficTitle": "Restablecer Tráfico",
|
||||
"selectSubscription": "Seleccionar suscripción",
|
||||
"subscriptionDiscount": "Descuento de Suscripción"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Esta aplicación no admite la activación por el momento, por favor importe manualmente, la dirección de suscripción se ha copiado automáticamente",
|
||||
"mySubscriptions": "Mis suscripciones",
|
||||
"nextResetDays": "Próximo reinicio/días",
|
||||
"noLimit": "Sin Límite",
|
||||
"prompt": "Sugerencia",
|
||||
"purchaseSubscription": "Comprar suscripción",
|
||||
"qrCode": "Código QR",
|
||||
|
||||
@ -1,21 +1,10 @@
|
||||
{
|
||||
"Day": "Día",
|
||||
"Hour": "Hora",
|
||||
"Minute": "Minuto",
|
||||
"Month": "Mes",
|
||||
"Year": "Año",
|
||||
"balanceRecharge": "Recarga de saldo",
|
||||
"buyNow": "Compra ahora",
|
||||
"buySubscription": "Comprar suscripción",
|
||||
"cancel": "Cancelar",
|
||||
"createdAt": "Fecha de creación",
|
||||
"description": "Recarga con un clic, fácil y rápido",
|
||||
"detail": "Detalles",
|
||||
"enterAmount": "Por favor, ingrese el monto a recargar",
|
||||
"enterCoupon": "Ingrese el código de descuento",
|
||||
"goToPayment": "Ir a pagar",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (cara a cara)",
|
||||
"alipay_f2f": "Alipay (Cara a Cara)",
|
||||
"balance": "Saldo",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
@ -28,19 +17,9 @@
|
||||
"orderNumber": "Número de pedido",
|
||||
"payment": "Ir a pagar",
|
||||
"paymentAmount": "Monto de pago",
|
||||
"paymentMethod": "Método de pago",
|
||||
"paymentMethod": "Método de Pago",
|
||||
"paymentSuccess": "Pago exitoso",
|
||||
"productList": "Lista de productos",
|
||||
"purchaseDuration": "Duración de compra",
|
||||
"recharge": "Recargar",
|
||||
"rechargeAmount": "Monto de recarga",
|
||||
"rechargeNow": "Recargar ahora",
|
||||
"renew": "Renovar",
|
||||
"renewSubscription": "Renovar suscripción",
|
||||
"resetPrice": "Restablecer precio",
|
||||
"resetTraffic": "Restablecer tráfico",
|
||||
"resetTrafficDescription": "Solo se restablece el tráfico del mes actual",
|
||||
"resetTrafficTitle": "Restablecer tráfico",
|
||||
"scanToPay": "Por favor, escanee para pagar",
|
||||
"status": {
|
||||
"0": "Estado",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Hora",
|
||||
"Minute": "Minuto",
|
||||
"Month": "Mes",
|
||||
"NoLimit": "Sin Límite",
|
||||
"Year": "Año",
|
||||
"all": "Todo",
|
||||
"balanceRecharge": "Recarga de Saldo",
|
||||
"billing": {
|
||||
"billingTitle": "Factura de Producto",
|
||||
"couponDiscount": "Descuento de Cupón",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Total"
|
||||
},
|
||||
"buy": "Comprar",
|
||||
"buyNow": "Comprar Ahora",
|
||||
"buySubscription": "Comprar Suscripción",
|
||||
"category": "Categoría",
|
||||
"coupon": "Cupón",
|
||||
"detail": {
|
||||
"availableTraffic": "Tráfico disponible",
|
||||
"connectedDevices": "Número de IPs conectadas simultáneamente",
|
||||
"connectionSpeed": "Velocidad de conexión",
|
||||
"productDetail": "Detalles del producto"
|
||||
},
|
||||
"enterAmount": "Ingresa el monto de recarga",
|
||||
"enterCoupon": "Ingresa el código de cupón",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (cara a cara)",
|
||||
"balance": "Saldo",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Método de Pago",
|
||||
"productDescription": "Descripción del producto",
|
||||
"products": "productos"
|
||||
"products": "productos",
|
||||
"purchaseDuration": "Duración de la Compra",
|
||||
"recharge": "Recargar",
|
||||
"rechargeAmount": "Monto de Recarga",
|
||||
"rechargeDescription": "Recarga con un clic, fácil de manejar",
|
||||
"rechargeNow": "Recargar Ahora",
|
||||
"renew": "Renovar",
|
||||
"renewSubscription": "Renovar Suscripción",
|
||||
"resetPrice": "Restablecer Precio",
|
||||
"resetTraffic": "Restablecer Tráfico",
|
||||
"resetTrafficDescription": "Restablecer el tráfico solo para el mes actual",
|
||||
"resetTrafficTitle": "Restablecer Tráfico",
|
||||
"selectSubscription": "Seleccionar Suscripción",
|
||||
"subscriptionDiscount": "Descuento por Suscripción"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "این برنامه از فعالسازی پشتیبانی نمیکند. لطفاً به صورت دستی وارد کنید. آدرس اشتراک کپی شده است.",
|
||||
"mySubscriptions": "اشتراکهای من",
|
||||
"nextResetDays": "روزهای باقیمانده تا بازنشانی بعدی",
|
||||
"noLimit": "بدون محدودیت",
|
||||
"prompt": "پیشنهاد",
|
||||
"purchaseSubscription": "خرید اشتراک",
|
||||
"qrCode": "کد QR",
|
||||
|
||||
@ -1,18 +1,7 @@
|
||||
{
|
||||
"Day": "روز",
|
||||
"Hour": "ساعت",
|
||||
"Minute": "دقیقه",
|
||||
"Month": "ماه",
|
||||
"Year": "سال",
|
||||
"balanceRecharge": "شارژ موجودی",
|
||||
"buyNow": "خرید کنید",
|
||||
"buySubscription": "خرید اشتراک",
|
||||
"cancel": "لغو",
|
||||
"createdAt": "ایجاد شده در",
|
||||
"description": "شارژ با یک کلیک، آسان برای استفاده",
|
||||
"detail": "جزئیات",
|
||||
"enterAmount": "مبلغ شارژ را وارد کنید",
|
||||
"enterCoupon": "کد تخفیف را وارد کنید",
|
||||
"goToPayment": "برو به پرداخت",
|
||||
"methods": {
|
||||
"alipay_f2f": "علیپی (رو در رو)",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "روش پرداخت",
|
||||
"paymentSuccess": "پرداخت موفق",
|
||||
"productList": "فهرست محصولات",
|
||||
"purchaseDuration": "مدت خرید",
|
||||
"recharge": "شارژ مجدد",
|
||||
"rechargeAmount": "مبلغ شارژ",
|
||||
"rechargeNow": "اکنون شارژ کنید",
|
||||
"renew": "تجدید",
|
||||
"renewSubscription": "تمدید اشتراک",
|
||||
"resetPrice": "بازنشانی قیمت",
|
||||
"resetTraffic": "بازنشانی ترافیک",
|
||||
"resetTrafficDescription": "بازنشانی ترافیک فقط برای ماه جاری",
|
||||
"resetTrafficTitle": "بازنشانی ترافیک",
|
||||
"scanToPay": "اسکن برای پرداخت",
|
||||
"status": {
|
||||
"0": "وضعیت",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "ساعت",
|
||||
"Minute": "دقیقه",
|
||||
"Month": "ماه",
|
||||
"NoLimit": "بدون محدودیت",
|
||||
"Year": "سال",
|
||||
"all": "همه",
|
||||
"balanceRecharge": "شارژ موجودی",
|
||||
"billing": {
|
||||
"billingTitle": "صورتحساب محصول",
|
||||
"couponDiscount": "تخفیف کوپن",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "جمع کل"
|
||||
},
|
||||
"buy": "خرید",
|
||||
"buyNow": "خرید کنید",
|
||||
"buySubscription": "خرید اشتراک",
|
||||
"category": "دستهبندی",
|
||||
"coupon": "کوپن",
|
||||
"detail": {
|
||||
"availableTraffic": "ترافیک موجود",
|
||||
"connectedDevices": "دستگاههای متصل",
|
||||
"connectionSpeed": "سرعت اتصال",
|
||||
"productDetail": "جزئیات محصول"
|
||||
},
|
||||
"enterAmount": "مبلغ شارژ را وارد کنید",
|
||||
"enterCoupon": "کد تخفیف را وارد کنید",
|
||||
"methods": {
|
||||
"alipay_f2f": "علیپی (رو در رو)",
|
||||
"balance": "موجودی",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "استرایپ (علیپی)",
|
||||
"stripe_wechat_pay": "استرایپ (ویچت)"
|
||||
},
|
||||
"paymentMethod": "روش پرداخت",
|
||||
"productDescription": "توضیحات محصول",
|
||||
"products": "محصولات"
|
||||
"products": "محصولات",
|
||||
"purchaseDuration": "مدت خرید",
|
||||
"recharge": "شارژ مجدد",
|
||||
"rechargeAmount": "مبلغ شارژ",
|
||||
"rechargeDescription": "شارژ با یک کلیک، آسان و راحت",
|
||||
"rechargeNow": "اکنون شارژ کنید",
|
||||
"renew": "تجدید",
|
||||
"renewSubscription": "تمدید اشتراک",
|
||||
"resetPrice": "بازنشانی قیمت",
|
||||
"resetTraffic": "بازنشانی ترافیک",
|
||||
"resetTrafficDescription": "بازنشانی ترافیک فقط برای ماه جاری",
|
||||
"resetTrafficTitle": "بازنشانی ترافیک",
|
||||
"selectSubscription": "انتخاب اشتراک",
|
||||
"subscriptionDiscount": "تخفیف اشتراک"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Tämä sovellus ei tue herätystä tällä hetkellä, tuo manuaalisesti, tilausosoite on kopioitu automaattisesti",
|
||||
"mySubscriptions": "Omat tilaukset",
|
||||
"nextResetDays": "Seuraava nollaus/päivää",
|
||||
"noLimit": "Ei rajoitusta",
|
||||
"prompt": "kehotus",
|
||||
"purchaseSubscription": "Osta tilaus",
|
||||
"qrCode": "QR-koodi",
|
||||
|
||||
@ -1,23 +1,12 @@
|
||||
{
|
||||
"Day": "Päivä",
|
||||
"Hour": "Tunti",
|
||||
"Minute": "Minuutti",
|
||||
"Month": "Kuukausi",
|
||||
"Year": "Vuosi",
|
||||
"balanceRecharge": "Saldon lataus",
|
||||
"buyNow": "Osta nyt",
|
||||
"buySubscription": "Osta tilaus",
|
||||
"cancel": "Peruuta",
|
||||
"createdAt": "Luontiaika",
|
||||
"description": "Yhdellä painalluksella lataus, helppoa ja vaivatonta",
|
||||
"detail": "Yksityiskohdat",
|
||||
"enterAmount": "Syötä ladattava summa",
|
||||
"enterCoupon": "Syötä alennuskoodi",
|
||||
"goToPayment": "Siirry maksamaan",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (kasvokkain)",
|
||||
"alipay_f2f": "Alipay (Kasvokkain)",
|
||||
"balance": "Saldo",
|
||||
"epay": "Helppo maksaminen",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "Maksutapa",
|
||||
"paymentSuccess": "Maksu onnistui",
|
||||
"productList": "Tuotelista",
|
||||
"purchaseDuration": "Ostoajan kesto",
|
||||
"recharge": "Lataa saldoa",
|
||||
"rechargeAmount": "Lataussumma",
|
||||
"rechargeNow": "Lataa nyt",
|
||||
"renew": "uudista",
|
||||
"renewSubscription": "Uudista tilaus",
|
||||
"resetPrice": "Nollaa hinta",
|
||||
"resetTraffic": "Nollaa liikenne",
|
||||
"resetTrafficDescription": "Vain kuluvan kuukauden liikenne nollataan",
|
||||
"resetTrafficTitle": "Nollaa liikenne",
|
||||
"scanToPay": "Ole hyvä ja skannaa maksaaksesi",
|
||||
"status": {
|
||||
"0": "Tila",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Tunti",
|
||||
"Minute": "Minuutti",
|
||||
"Month": "Kuukausi",
|
||||
"NoLimit": "Ei rajoitusta",
|
||||
"Year": "Vuosi",
|
||||
"all": "kaikki",
|
||||
"balanceRecharge": "Saldon Lataus",
|
||||
"billing": {
|
||||
"billingTitle": "Tuotelasku",
|
||||
"couponDiscount": "Alennuskoodin alennus",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Kokonaishinta"
|
||||
},
|
||||
"buy": "Osta",
|
||||
"buyNow": "Osta nyt",
|
||||
"buySubscription": "Osta tilaus",
|
||||
"category": "Kategoria",
|
||||
"coupon": "Kuponki",
|
||||
"detail": {
|
||||
"availableTraffic": "Käytettävissä oleva liikenne",
|
||||
"connectedDevices": "Samanaikaisesti yhdistetyt IP-osoitteet",
|
||||
"connectionSpeed": "Yhteysnopeus",
|
||||
"productDetail": "Tuotteen tiedot"
|
||||
},
|
||||
"enterAmount": "Syötä latausmäärä",
|
||||
"enterCoupon": "Syötä alennuskoodi",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (kasvokkain)",
|
||||
"balance": "Saldo",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Maksutapa",
|
||||
"productDescription": "Tuotteen kuvaus",
|
||||
"products": "tuotteet"
|
||||
"products": "tuotteet",
|
||||
"purchaseDuration": "Ostoajan kesto",
|
||||
"recharge": "Lataa saldoa",
|
||||
"rechargeAmount": "Latausmäärä",
|
||||
"rechargeDescription": "Yhden klikkauksen lataus, helppo käsitellä",
|
||||
"rechargeNow": "Lataa nyt",
|
||||
"renew": "Uudista",
|
||||
"renewSubscription": "Uudista tilaus",
|
||||
"resetPrice": "Nollaa hinta",
|
||||
"resetTraffic": "Nollaa liikenne",
|
||||
"resetTrafficDescription": "Nollaa liikenne vain kuluvan kuukauden osalta",
|
||||
"resetTrafficTitle": "Nollaa liikenne",
|
||||
"selectSubscription": "Valitse tilaus",
|
||||
"subscriptionDiscount": "Tilauksen alennus"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Cette application ne prend pas encore en charge l'activation, veuillez importer manuellement, l'adresse d'abonnement a été copiée automatiquement",
|
||||
"mySubscriptions": "Mes abonnements",
|
||||
"nextResetDays": "Prochain réinitialisation/jours",
|
||||
"noLimit": "Pas de limite",
|
||||
"prompt": "invite",
|
||||
"purchaseSubscription": "Acheter un abonnement",
|
||||
"qrCode": "Code QR",
|
||||
|
||||
@ -1,21 +1,10 @@
|
||||
{
|
||||
"Day": "Jour",
|
||||
"Hour": "Heure",
|
||||
"Minute": "Minute",
|
||||
"Month": "Mois",
|
||||
"Year": "Année",
|
||||
"balanceRecharge": "Recharge de solde",
|
||||
"buyNow": "Acheter maintenant",
|
||||
"buySubscription": "Acheter un abonnement",
|
||||
"cancel": "Annuler",
|
||||
"createdAt": "Date de création",
|
||||
"description": "Recharge en un clic, facile et rapide",
|
||||
"detail": "Détails",
|
||||
"enterAmount": "Veuillez entrer le montant à recharger",
|
||||
"enterCoupon": "Veuillez entrer le code de réduction",
|
||||
"goToPayment": "Aller au paiement",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (face à face)",
|
||||
"alipay_f2f": "Alipay (Face à Face)",
|
||||
"balance": "Solde",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
@ -28,19 +17,9 @@
|
||||
"orderNumber": "Numéro de commande",
|
||||
"payment": "Payer",
|
||||
"paymentAmount": "Montant du paiement",
|
||||
"paymentMethod": "Moyen de paiement",
|
||||
"paymentMethod": "Méthode de paiement",
|
||||
"paymentSuccess": "Paiement réussi",
|
||||
"productList": "Liste des produits",
|
||||
"purchaseDuration": "Durée d'achat",
|
||||
"recharge": "Recharger",
|
||||
"rechargeAmount": "Montant de la recharge",
|
||||
"rechargeNow": "Rechargez maintenant",
|
||||
"renew": "Renouveler",
|
||||
"renewSubscription": "Renouveler l'abonnement",
|
||||
"resetPrice": "Réinitialiser le prix",
|
||||
"resetTraffic": "Réinitialiser le trafic",
|
||||
"resetTrafficDescription": "Réinitialiser uniquement le trafic du mois en cours",
|
||||
"resetTrafficTitle": "Réinitialiser le trafic",
|
||||
"scanToPay": "Veuillez scanner pour payer",
|
||||
"status": {
|
||||
"0": "Statut",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Heure",
|
||||
"Minute": "Minute",
|
||||
"Month": "Mois",
|
||||
"NoLimit": "Pas de limite",
|
||||
"Year": "Année",
|
||||
"all": "Tout",
|
||||
"balanceRecharge": "Recharge de Solde",
|
||||
"billing": {
|
||||
"billingTitle": "Facture des produits",
|
||||
"couponDiscount": "Réduction du code promo",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Prix total"
|
||||
},
|
||||
"buy": "Acheter",
|
||||
"buyNow": "Acheter maintenant",
|
||||
"buySubscription": "Acheter un abonnement",
|
||||
"category": "Catégorie",
|
||||
"coupon": "Coupon",
|
||||
"detail": {
|
||||
"availableTraffic": "Trafic disponible",
|
||||
"connectedDevices": "Nombre d'IP connectées simultanément",
|
||||
"connectionSpeed": "Vitesse de connexion",
|
||||
"productDetail": "Détails du produit"
|
||||
},
|
||||
"enterAmount": "Entrez le montant de la recharge",
|
||||
"enterCoupon": "Entrez le code promo",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (face à face)",
|
||||
"balance": "Solde",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Méthode de paiement",
|
||||
"productDescription": "Description du produit",
|
||||
"products": "produits"
|
||||
"products": "produits",
|
||||
"purchaseDuration": "Durée d'achat",
|
||||
"recharge": "Recharger",
|
||||
"rechargeAmount": "Montant de la Recharge",
|
||||
"rechargeDescription": "Recharge en un clic, facile à gérer",
|
||||
"rechargeNow": "Rechargez maintenant",
|
||||
"renew": "Renouveler",
|
||||
"renewSubscription": "Renouveler l'abonnement",
|
||||
"resetPrice": "Réinitialiser le prix",
|
||||
"resetTraffic": "Réinitialiser le trafic",
|
||||
"resetTrafficDescription": "Réinitialiser le trafic pour le mois en cours uniquement",
|
||||
"resetTrafficTitle": "Réinitialiser le trafic",
|
||||
"selectSubscription": "Sélectionner l'abonnement",
|
||||
"subscriptionDiscount": "Remise sur l'abonnement"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "यह ऐप फिलहाल जागृत करने का समर्थन नहीं करता है, कृपया मैन्युअल रूप से आयात करें, सदस्यता पता स्वचालित रूप से कॉपी कर लिया गया है।",
|
||||
"mySubscriptions": "मेरी सदस्यताएँ",
|
||||
"nextResetDays": "अगली रीसेट/दिन",
|
||||
"noLimit": "कोई सीमा नहीं",
|
||||
"prompt": "प्रॉम्प्ट",
|
||||
"purchaseSubscription": "सदस्यता खरीदें",
|
||||
"qrCode": "क्यूआर कोड",
|
||||
|
||||
@ -1,23 +1,12 @@
|
||||
{
|
||||
"Day": "दिन",
|
||||
"Hour": "घंटा",
|
||||
"Minute": "मिनट",
|
||||
"Month": "महीना",
|
||||
"Year": "वर्ष",
|
||||
"balanceRecharge": "शेष राशि रिचार्ज",
|
||||
"buyNow": "अभी खरीदें",
|
||||
"buySubscription": "सदस्यता खरीदें",
|
||||
"cancel": "रद्द करें",
|
||||
"createdAt": "निर्माण समय",
|
||||
"description": "एक क्लिक में रिचार्ज, आसानी से पूरा करें",
|
||||
"detail": "विवरण",
|
||||
"enterAmount": "कृपया रिचार्ज राशि दर्ज करें",
|
||||
"enterCoupon": "कृपया कूपन कोड दर्ज करें",
|
||||
"goToPayment": "भुगतान के लिए जाएं",
|
||||
"methods": {
|
||||
"alipay_f2f": "अलीपे (सामना-सामना)",
|
||||
"balance": "शेष राशि",
|
||||
"epay": "ई-पे",
|
||||
"balance": "शेष",
|
||||
"epay": "ईपे",
|
||||
"stripe_alipay": "स्ट्राइप (अलीपे)",
|
||||
"stripe_wechat_pay": "स्ट्राइप (वीचैट)"
|
||||
},
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "भुगतान विधि",
|
||||
"paymentSuccess": "भुगतान सफल",
|
||||
"productList": "उत्पाद सूची",
|
||||
"purchaseDuration": "खरीद की अवधि",
|
||||
"recharge": "रिचार्ज",
|
||||
"rechargeAmount": "रिचार्ज राशि",
|
||||
"rechargeNow": "अभी रिचार्ज करें",
|
||||
"renew": "नवीनीकरण",
|
||||
"renewSubscription": "सदस्यता नवीनीकरण",
|
||||
"resetPrice": "मूल्य रीसेट करें",
|
||||
"resetTraffic": "ट्रैफ़िक रीसेट करें",
|
||||
"resetTrafficDescription": "केवल इस महीने की ट्रैफिक को रीसेट करें",
|
||||
"resetTrafficTitle": "ट्रैफ़िक रीसेट करें",
|
||||
"scanToPay": "कृपया स्कैन करके भुगतान करें",
|
||||
"status": {
|
||||
"0": "स्थिति",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "घंटा",
|
||||
"Minute": "मिनट",
|
||||
"Month": "महीना",
|
||||
"NoLimit": "कोई सीमा नहीं",
|
||||
"Year": "वर्ष",
|
||||
"all": "सभी",
|
||||
"balanceRecharge": "बैलेंस रिचार्ज",
|
||||
"billing": {
|
||||
"billingTitle": "उत्पाद बिल",
|
||||
"couponDiscount": "कूपन छूट",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "कुल मूल्य"
|
||||
},
|
||||
"buy": "खरीदें",
|
||||
"buyNow": "अभी खरीदें",
|
||||
"buySubscription": "सदस्यता खरीदें",
|
||||
"category": "श्रेणी",
|
||||
"coupon": "कूपन",
|
||||
"detail": {
|
||||
"availableTraffic": "उपलब्ध ट्रैफ़िक",
|
||||
"connectedDevices": "समानांतर कनेक्टेड IP संख्या",
|
||||
"connectionSpeed": "कनेक्शन गति",
|
||||
"productDetail": "उत्पाद विवरण"
|
||||
},
|
||||
"enterAmount": "रिचार्ज राशि दर्ज करें",
|
||||
"enterCoupon": "कूपन कोड दर्ज करें",
|
||||
"methods": {
|
||||
"alipay_f2f": "अलीपे (सामना-सामना)",
|
||||
"balance": "शेष राशि",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "स्ट्राइप (अलीपे)",
|
||||
"stripe_wechat_pay": "स्ट्राइप (वीचैट)"
|
||||
},
|
||||
"paymentMethod": "भुगतान विधि",
|
||||
"productDescription": "उत्पाद विवरण",
|
||||
"products": "उत्पाद"
|
||||
"products": "उत्पाद",
|
||||
"purchaseDuration": "खरीद अवधि",
|
||||
"recharge": "रिचार्ज",
|
||||
"rechargeAmount": "रिचार्ज राशि",
|
||||
"rechargeDescription": "एक-क्लिक रिचार्ज, आसान प्रबंधन",
|
||||
"rechargeNow": "अभी रिचार्ज करें",
|
||||
"renew": "नवीनीकरण करें",
|
||||
"renewSubscription": "सदस्यता नवीनीकरण करें",
|
||||
"resetPrice": "मूल्य रीसेट करें",
|
||||
"resetTraffic": "ट्रैफ़िक रीसेट करें",
|
||||
"resetTrafficDescription": "केवल वर्तमान माह के लिए ट्रैफिक रीसेट करें",
|
||||
"resetTrafficTitle": "ट्रैफ़िक रीसेट करें",
|
||||
"selectSubscription": "सदस्यता चुनें",
|
||||
"subscriptionDiscount": "सदस्यता छूट"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Ez az alkalmazás jelenleg nem támogatja az ébresztést, kérjük, importálja manuálisan, az előfizetési cím automatikusan másolva lett",
|
||||
"mySubscriptions": "Előfizetéseim",
|
||||
"nextResetDays": "Következő visszaállítás/nap",
|
||||
"noLimit": "Nincs korlát",
|
||||
"prompt": "figyelmeztetés",
|
||||
"purchaseSubscription": "Előfizetés vásárlása",
|
||||
"qrCode": "QR-kód",
|
||||
|
||||
@ -1,21 +1,10 @@
|
||||
{
|
||||
"Day": "Nap",
|
||||
"Hour": "Óra",
|
||||
"Minute": "Perc",
|
||||
"Month": "Hónap",
|
||||
"Year": "Év",
|
||||
"balanceRecharge": "Egyenleg feltöltése",
|
||||
"buyNow": "Vásároljon most",
|
||||
"buySubscription": "Előfizetés vásárlása",
|
||||
"cancel": "Mégse",
|
||||
"createdAt": "Létrehozás ideje",
|
||||
"description": "Egy kattintásos feltöltés, könnyedén megoldva",
|
||||
"detail": "Részletek",
|
||||
"enterAmount": "Kérjük, adja meg a feltöltendő összeget",
|
||||
"enterCoupon": "Kérjük, adja meg a kuponkódot",
|
||||
"goToPayment": "Tovább a fizetéshez",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (szemtől szemben)",
|
||||
"alipay_f2f": "Alipay (Személyes)",
|
||||
"balance": "Egyenleg",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "Fizetési mód",
|
||||
"paymentSuccess": "Fizetés sikeres",
|
||||
"productList": "Terméklista",
|
||||
"purchaseDuration": "Vásárlási időtartam",
|
||||
"recharge": "feltöltés",
|
||||
"rechargeAmount": "Feltöltési összeg",
|
||||
"rechargeNow": "Tölts fel most",
|
||||
"renew": "megújítás",
|
||||
"renewSubscription": "Előfizetés megújítása",
|
||||
"resetPrice": "Ár visszaállítása",
|
||||
"resetTraffic": "Forgalom visszaállítása",
|
||||
"resetTrafficDescription": "Csak a havi forgalom lesz visszaállítva",
|
||||
"resetTrafficTitle": "Forgalom visszaállítása",
|
||||
"scanToPay": "Kérjük, olvassa be a kódot a fizetéshez",
|
||||
"status": {
|
||||
"0": "Állapot",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Óra",
|
||||
"Minute": "Perc",
|
||||
"Month": "Hónap",
|
||||
"NoLimit": "Nincs korlát",
|
||||
"Year": "Év",
|
||||
"all": "Összes",
|
||||
"balanceRecharge": "Egyenlegfeltöltés",
|
||||
"billing": {
|
||||
"billingTitle": "Termékszámla",
|
||||
"couponDiscount": "Kuponkedvezmény",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Teljes ár"
|
||||
},
|
||||
"buy": "vásárlás",
|
||||
"buyNow": "Vásárolja meg most",
|
||||
"buySubscription": "Előfizetés vásárlása",
|
||||
"category": "kategória",
|
||||
"coupon": "Kupon",
|
||||
"detail": {
|
||||
"availableTraffic": "Elérhető forgalom",
|
||||
"connectedDevices": "Egyidejűleg csatlakoztatott IP-k száma",
|
||||
"connectionSpeed": "Kapcsolati sebesség",
|
||||
"productDetail": "Termék részletei"
|
||||
},
|
||||
"enterAmount": "Adja meg a feltöltési összeget",
|
||||
"enterCoupon": "Adja meg a kuponkódot",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (szemtől szemben)",
|
||||
"balance": "Egyenleg",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Fizetési mód",
|
||||
"productDescription": "Termékleírás",
|
||||
"products": "termékek"
|
||||
"products": "termékek",
|
||||
"purchaseDuration": "Vásárlási időtartam",
|
||||
"recharge": "Feltöltés",
|
||||
"rechargeAmount": "Feltöltési összeg",
|
||||
"rechargeDescription": "Egy kattintásos feltöltés, könnyen kezelhető",
|
||||
"rechargeNow": "Töltsd fel most",
|
||||
"renew": "Megújít",
|
||||
"renewSubscription": "Előfizetés megújítása",
|
||||
"resetPrice": "Ár visszaállítása",
|
||||
"resetTraffic": "Forgalom visszaállítása",
|
||||
"resetTrafficDescription": "Forgalmi adatok visszaállítása csak az aktuális hónapra",
|
||||
"resetTrafficTitle": "Forgalom visszaállítása",
|
||||
"selectSubscription": "Előfizetés kiválasztása",
|
||||
"subscriptionDiscount": "Előfizetési kedvezmény"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "このアプリは現在起動をサポートしていません。手動でインポートしてください。サブスクリプションアドレスは自動的にコピーされました。",
|
||||
"mySubscriptions": "私の購読",
|
||||
"nextResetDays": "次のリセット/日",
|
||||
"noLimit": "無制限",
|
||||
"prompt": "プロンプト",
|
||||
"purchaseSubscription": "サブスクリプションを購入",
|
||||
"qrCode": "QRコード",
|
||||
|
||||
@ -1,25 +1,14 @@
|
||||
{
|
||||
"Day": "日",
|
||||
"Hour": "時",
|
||||
"Minute": "分",
|
||||
"Month": "月",
|
||||
"Year": "年",
|
||||
"balanceRecharge": "残高チャージ",
|
||||
"buyNow": "今すぐ購入",
|
||||
"buySubscription": "サブスクリプションを購入",
|
||||
"cancel": "キャンセル",
|
||||
"createdAt": "作成日時",
|
||||
"description": "ワンクリックでチャージ、簡単に完了",
|
||||
"detail": "詳細",
|
||||
"enterAmount": "チャージ金額を入力してください",
|
||||
"enterCoupon": "クーポンコードを入力してください",
|
||||
"goToPayment": "支払いに進む",
|
||||
"methods": {
|
||||
"alipay_f2f": "支付宝(対面)",
|
||||
"alipay_f2f": "アリペイ(対面)",
|
||||
"balance": "残高",
|
||||
"epay": "イージーペイ",
|
||||
"stripe_alipay": "Stripe(支付宝)",
|
||||
"stripe_wechat_pay": "Stripe(微信)"
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "ストライプ(アリペイ)",
|
||||
"stripe_wechat_pay": "ストライプ(WeChat)"
|
||||
},
|
||||
"name": "名前",
|
||||
"orderClosed": "注文は締め切られました",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "支払い方法",
|
||||
"paymentSuccess": "支払い成功",
|
||||
"productList": "製品リスト",
|
||||
"purchaseDuration": "購入期間",
|
||||
"recharge": "チャージ",
|
||||
"rechargeAmount": "チャージ金額",
|
||||
"rechargeNow": "今すぐチャージ",
|
||||
"renew": "更新",
|
||||
"renewSubscription": "サブスクリプションを更新する",
|
||||
"resetPrice": "リセット価格",
|
||||
"resetTraffic": "トラフィックをリセット",
|
||||
"resetTrafficDescription": "今月のトラフィックのみリセットされます",
|
||||
"resetTrafficTitle": "トラフィックのリセット",
|
||||
"scanToPay": "スキャンしてお支払いください",
|
||||
"status": {
|
||||
"0": "状態",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "時",
|
||||
"Minute": "分",
|
||||
"Month": "月",
|
||||
"NoLimit": "無制限",
|
||||
"Year": "年",
|
||||
"all": "すべて",
|
||||
"balanceRecharge": "残高チャージ",
|
||||
"billing": {
|
||||
"billingTitle": "商品請求書",
|
||||
"couponDiscount": "クーポン割引",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "合計"
|
||||
},
|
||||
"buy": "購入",
|
||||
"buyNow": "今すぐ購入",
|
||||
"buySubscription": "サブスクリプションを購入",
|
||||
"category": "カテゴリー",
|
||||
"coupon": "クーポン",
|
||||
"detail": {
|
||||
"availableTraffic": "利用可能なトラフィック",
|
||||
"connectedDevices": "同時接続 IP 数",
|
||||
"connectionSpeed": "接続速度",
|
||||
"productDetail": "商品詳細"
|
||||
},
|
||||
"enterAmount": "リチャージ金額を入力してください",
|
||||
"enterCoupon": "クーポンコードを入力",
|
||||
"methods": {
|
||||
"alipay_f2f": "支付宝(対面)",
|
||||
"balance": "残高",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe(支付宝)",
|
||||
"stripe_wechat_pay": "Stripe(微信)"
|
||||
},
|
||||
"paymentMethod": "支払い方法",
|
||||
"productDescription": "商品説明",
|
||||
"products": "商品"
|
||||
"products": "商品",
|
||||
"purchaseDuration": "購入期間",
|
||||
"recharge": "リチャージ",
|
||||
"rechargeAmount": "リチャージ金額",
|
||||
"rechargeDescription": "ワンクリックでリチャージ、簡単に操作",
|
||||
"rechargeNow": "今すぐリチャージ",
|
||||
"renew": "更新",
|
||||
"renewSubscription": "サブスクリプションを更新する",
|
||||
"resetPrice": "価格をリセット",
|
||||
"resetTraffic": "トラフィックをリセット",
|
||||
"resetTrafficDescription": "今月のみのトラフィックをリセットする",
|
||||
"resetTrafficTitle": "トラフィックをリセット",
|
||||
"selectSubscription": "サブスクリプションを選択",
|
||||
"subscriptionDiscount": "サブスクリプション割引"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "이 앱은 현재 호출을 지원하지 않습니다. 수동으로 가져오세요. 구독 주소가 자동으로 복사되었습니다.",
|
||||
"mySubscriptions": "내 구독",
|
||||
"nextResetDays": "다음 초기화/일",
|
||||
"noLimit": "제한 없음",
|
||||
"prompt": "프롬프트",
|
||||
"purchaseSubscription": "구독 구매",
|
||||
"qrCode": "QR코드",
|
||||
|
||||
@ -1,25 +1,14 @@
|
||||
{
|
||||
"Day": "일",
|
||||
"Hour": "시",
|
||||
"Minute": "분",
|
||||
"Month": "월",
|
||||
"Year": "년",
|
||||
"balanceRecharge": "잔액 충전",
|
||||
"buyNow": "지금 구매",
|
||||
"buySubscription": "구독 구매",
|
||||
"cancel": "취소",
|
||||
"createdAt": "생성 시간",
|
||||
"description": "원클릭 충전, 간편하게 해결",
|
||||
"detail": "세부사항",
|
||||
"enterAmount": "충전 금액을 입력하세요",
|
||||
"enterCoupon": "할인 코드를 입력하세요",
|
||||
"goToPayment": "결제하기",
|
||||
"methods": {
|
||||
"alipay_f2f": "알리페이(대면)",
|
||||
"alipay_f2f": "알리페이 (대면 결제)",
|
||||
"balance": "잔액",
|
||||
"epay": "이페이",
|
||||
"stripe_alipay": "Stripe(알리페이)",
|
||||
"stripe_wechat_pay": "Stripe(위챗)"
|
||||
"stripe_alipay": "스트라이프 (알리페이)",
|
||||
"stripe_wechat_pay": "스트라이프 (위챗페이)"
|
||||
},
|
||||
"name": "이름",
|
||||
"orderClosed": "주문이 종료되었습니다",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "결제 수단",
|
||||
"paymentSuccess": "결제 성공",
|
||||
"productList": "제품 목록",
|
||||
"purchaseDuration": "구매 기간",
|
||||
"recharge": "충전",
|
||||
"rechargeAmount": "충전 금액",
|
||||
"rechargeNow": "지금 충전하기",
|
||||
"renew": "갱신",
|
||||
"renewSubscription": "구독 갱신",
|
||||
"resetPrice": "가격 재설정",
|
||||
"resetTraffic": "트래픽 재설정",
|
||||
"resetTrafficDescription": "이번 달의 트래픽만 초기화됩니다.",
|
||||
"resetTrafficTitle": "트래픽 재설정",
|
||||
"scanToPay": "스캔하여 결제하세요",
|
||||
"status": {
|
||||
"0": "상태",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "시",
|
||||
"Minute": "분",
|
||||
"Month": "월",
|
||||
"NoLimit": "제한 없음",
|
||||
"Year": "년",
|
||||
"all": "전체",
|
||||
"balanceRecharge": "잔액 충전",
|
||||
"billing": {
|
||||
"billingTitle": "상품 청구서",
|
||||
"couponDiscount": "할인 코드 혜택",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "총액"
|
||||
},
|
||||
"buy": "구매",
|
||||
"buyNow": "지금 구매",
|
||||
"buySubscription": "구독 구매",
|
||||
"category": "카테고리",
|
||||
"coupon": "쿠폰",
|
||||
"detail": {
|
||||
"availableTraffic": "사용 가능한 트래픽",
|
||||
"connectedDevices": "동시 연결 IP 수",
|
||||
"connectionSpeed": "연결 속도",
|
||||
"productDetail": "제품 세부 정보"
|
||||
},
|
||||
"enterAmount": "충전 금액을 입력하세요",
|
||||
"enterCoupon": "쿠폰 코드 입력",
|
||||
"methods": {
|
||||
"alipay_f2f": "알리페이(대면)",
|
||||
"balance": "잔액",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe(알리페이)",
|
||||
"stripe_wechat_pay": "Stripe(위챗)"
|
||||
},
|
||||
"paymentMethod": "결제 수단",
|
||||
"productDescription": "제품 설명",
|
||||
"products": "상품"
|
||||
"products": "상품",
|
||||
"purchaseDuration": "구매 기간",
|
||||
"recharge": "충전",
|
||||
"rechargeAmount": "충전 금액",
|
||||
"rechargeDescription": "원클릭 충전, 간편하게 처리",
|
||||
"rechargeNow": "지금 충전하기",
|
||||
"renew": "갱신",
|
||||
"renewSubscription": "구독 갱신",
|
||||
"resetPrice": "가격 재설정",
|
||||
"resetTraffic": "트래픽 재설정",
|
||||
"resetTrafficDescription": "현재 월에 대한 트래픽만 재설정",
|
||||
"resetTrafficTitle": "트래픽 재설정",
|
||||
"selectSubscription": "구독 선택",
|
||||
"subscriptionDiscount": "구독 할인"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Denne appen støtter foreløpig ikke oppstart, vennligst importer manuelt, abonnementsadressen er automatisk kopiert",
|
||||
"mySubscriptions": "Mine abonnementer",
|
||||
"nextResetDays": "Neste tilbakestilling/dager",
|
||||
"noLimit": "Ingen grense",
|
||||
"prompt": "Hint",
|
||||
"purchaseSubscription": "Kjøp abonnement",
|
||||
"qrCode": "QR-kode",
|
||||
|
||||
@ -1,23 +1,12 @@
|
||||
{
|
||||
"Day": "Dag",
|
||||
"Hour": "Time",
|
||||
"Minute": "Minutt",
|
||||
"Month": "Måned",
|
||||
"Year": "År",
|
||||
"balanceRecharge": "Saldoopplading",
|
||||
"buyNow": "Kjøp nå",
|
||||
"buySubscription": "Kjøp abonnement",
|
||||
"cancel": "Avbryt",
|
||||
"createdAt": "Opprettet",
|
||||
"description": "Énkel påfylling med ett klikk",
|
||||
"detail": "Detaljer",
|
||||
"enterAmount": "Vennligst skriv inn beløpet for påfylling",
|
||||
"enterCoupon": "Vennligst skriv inn rabattkoden",
|
||||
"goToPayment": "Gå til betaling",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (ansikt til ansikt)",
|
||||
"alipay_f2f": "Alipay (Ansikt til ansikt)",
|
||||
"balance": "Balanse",
|
||||
"epay": "Enkel betaling",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "Betalingsmetode",
|
||||
"paymentSuccess": "Betaling vellykket",
|
||||
"productList": "Produktliste",
|
||||
"purchaseDuration": "Kjøpsvarighet",
|
||||
"recharge": "lade opp",
|
||||
"rechargeAmount": "Ladebeløp",
|
||||
"rechargeNow": "Lad opp nå",
|
||||
"renew": "fornye",
|
||||
"renewSubscription": "Forny abonnement",
|
||||
"resetPrice": "Tilbakestill pris",
|
||||
"resetTraffic": "Tilbakestill trafikk",
|
||||
"resetTrafficDescription": "Tilbakestiller kun trafikken for inneværende måned",
|
||||
"resetTrafficTitle": "Tilbakestill trafikk",
|
||||
"scanToPay": "Vennligst skann for å betale",
|
||||
"status": {
|
||||
"0": "Status",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Time",
|
||||
"Minute": "Minutt",
|
||||
"Month": "Måned",
|
||||
"NoLimit": "Ingen grense",
|
||||
"Year": "År",
|
||||
"all": "Alle",
|
||||
"balanceRecharge": "Saldoopplading",
|
||||
"billing": {
|
||||
"billingTitle": "Varefaktura",
|
||||
"couponDiscount": "Rabattkode rabatt",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Totalpris"
|
||||
},
|
||||
"buy": "Kjøp",
|
||||
"buyNow": "Kjøp Nå",
|
||||
"buySubscription": "Kjøp abonnement",
|
||||
"category": "Kategori",
|
||||
"coupon": "Kupong",
|
||||
"detail": {
|
||||
"availableTraffic": "Tilgjengelig trafikk",
|
||||
"connectedDevices": "Samtidig tilkoblede IP-er",
|
||||
"connectionSpeed": "Tilkoblingshastighet",
|
||||
"productDetail": "Produktdetaljer"
|
||||
},
|
||||
"enterAmount": "Skriv inn påfyllingsbeløp",
|
||||
"enterCoupon": "Skriv inn kupongkode",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (ansikt til ansikt)",
|
||||
"balance": "Balanse",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Betalingsmetode",
|
||||
"productDescription": "Produktbeskrivelse",
|
||||
"products": "Produkter"
|
||||
"products": "Produkter",
|
||||
"purchaseDuration": "Kjøpsvarighet",
|
||||
"recharge": "Lad opp",
|
||||
"rechargeAmount": "Påfyllingsbeløp",
|
||||
"rechargeDescription": "Ett-klikks opplading, enkelt å håndtere",
|
||||
"rechargeNow": "Lad opp nå",
|
||||
"renew": "Forny",
|
||||
"renewSubscription": "Forny abonnement",
|
||||
"resetPrice": "Tilbakestill pris",
|
||||
"resetTraffic": "Tilbakestill trafikk",
|
||||
"resetTrafficDescription": "Tilbakestill trafikk kun for inneværende måned",
|
||||
"resetTrafficTitle": "Nullstill trafikk",
|
||||
"selectSubscription": "Velg abonnement",
|
||||
"subscriptionDiscount": "Abonnementsrabatt"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Ta aplikacja tymczasowo nie obsługuje wywoływania, proszę zaimportować ręcznie, adres subskrypcji został automatycznie skopiowany",
|
||||
"mySubscriptions": "Moje subskrypcje",
|
||||
"nextResetDays": "Następny reset/dni",
|
||||
"noLimit": "Bez limitu",
|
||||
"prompt": "Podpowiedź",
|
||||
"purchaseSubscription": "Zakup subskrypcji",
|
||||
"qrCode": "Kod QR",
|
||||
|
||||
@ -1,21 +1,10 @@
|
||||
{
|
||||
"Day": "Dzień",
|
||||
"Hour": "Godzina",
|
||||
"Minute": "Minuta",
|
||||
"Month": "Miesiąc",
|
||||
"Year": "Rok",
|
||||
"balanceRecharge": "Doładowanie salda",
|
||||
"buyNow": "Kup teraz",
|
||||
"buySubscription": "Kup subskrypcję",
|
||||
"cancel": "Anuluj",
|
||||
"createdAt": "Czas utworzenia",
|
||||
"description": "Jedno kliknięcie doładowania, łatwe do załatwienia",
|
||||
"detail": "Szczegóły",
|
||||
"enterAmount": "Wprowadź kwotę doładowania",
|
||||
"enterCoupon": "Wprowadź kod rabatowy",
|
||||
"goToPayment": "Przejdź do płatności",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (twarzą w twarz)",
|
||||
"alipay_f2f": "Alipay (Twarzą w twarz)",
|
||||
"balance": "Saldo",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "Metoda płatności",
|
||||
"paymentSuccess": "Płatność zakończona sukcesem",
|
||||
"productList": "Lista produktów",
|
||||
"purchaseDuration": "Czas zakupu",
|
||||
"recharge": "doładowanie",
|
||||
"rechargeAmount": "Kwota doładowania",
|
||||
"rechargeNow": "Doładuj teraz",
|
||||
"renew": "odnów",
|
||||
"renewSubscription": "Odnów subskrypcję",
|
||||
"resetPrice": "Zresetuj cenę",
|
||||
"resetTraffic": "Zresetuj ruch",
|
||||
"resetTrafficDescription": "Resetuj tylko miesięczny transfer danych",
|
||||
"resetTrafficTitle": "Zresetuj ruch",
|
||||
"scanToPay": "Zeskanuj kod, aby zapłacić",
|
||||
"status": {
|
||||
"0": "Status",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Godzina",
|
||||
"Minute": "Minuta",
|
||||
"Month": "Miesiąc",
|
||||
"NoLimit": "Bez limitu",
|
||||
"Year": "Rok",
|
||||
"all": "Wszystko",
|
||||
"balanceRecharge": "Doładowanie salda",
|
||||
"billing": {
|
||||
"billingTitle": "Rachunek za produkt",
|
||||
"couponDiscount": "Zniżka z kodu rabatowego",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Suma"
|
||||
},
|
||||
"buy": "Kup",
|
||||
"buyNow": "Kup Teraz",
|
||||
"buySubscription": "Kup Subskrypcję",
|
||||
"category": "kategoria",
|
||||
"coupon": "Kupon",
|
||||
"detail": {
|
||||
"availableTraffic": "Dostępny ruch",
|
||||
"connectedDevices": "Liczba jednocześnie podłączonych IP",
|
||||
"connectionSpeed": "Prędkość połączenia",
|
||||
"productDetail": "Szczegóły produktu"
|
||||
},
|
||||
"enterAmount": "Wprowadź kwotę doładowania",
|
||||
"enterCoupon": "Wprowadź kod kuponu",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (twarzą w twarz)",
|
||||
"balance": "Saldo",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Metoda płatności",
|
||||
"productDescription": "Opis produktu",
|
||||
"products": "Produkty"
|
||||
"products": "Produkty",
|
||||
"purchaseDuration": "Czas trwania zakupu",
|
||||
"recharge": "Doładowanie",
|
||||
"rechargeAmount": "Kwota doładowania",
|
||||
"rechargeDescription": "Jedno kliknięcie doładowania, łatwe w obsłudze",
|
||||
"rechargeNow": "Doładuj teraz",
|
||||
"renew": "Odnów",
|
||||
"renewSubscription": "Odnów subskrypcję",
|
||||
"resetPrice": "Zresetuj cenę",
|
||||
"resetTraffic": "Zresetuj ruch",
|
||||
"resetTrafficDescription": "Zresetuj ruch tylko na bieżący miesiąc",
|
||||
"resetTrafficTitle": "Zresetuj Ruch",
|
||||
"selectSubscription": "Wybierz subskrypcję",
|
||||
"subscriptionDiscount": "Zniżka na subskrypcję"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Este aplicativo não suporta ativação no momento, por favor, importe manualmente. O endereço de assinatura foi copiado automaticamente.",
|
||||
"mySubscriptions": "Minhas assinaturas",
|
||||
"nextResetDays": "Próxima redefinição/dias",
|
||||
"noLimit": "Sem Limite",
|
||||
"prompt": "Sugestão",
|
||||
"purchaseSubscription": "Comprar Assinatura",
|
||||
"qrCode": "Código QR",
|
||||
|
||||
@ -1,21 +1,10 @@
|
||||
{
|
||||
"Day": "Dia",
|
||||
"Hour": "Hora",
|
||||
"Minute": "Minuto",
|
||||
"Month": "Mês",
|
||||
"Year": "Ano",
|
||||
"balanceRecharge": "Recarga de Saldo",
|
||||
"buyNow": "Compre Agora",
|
||||
"buySubscription": "Comprar Assinatura",
|
||||
"cancel": "Cancelar",
|
||||
"createdAt": "Data de Criação",
|
||||
"description": "Recarga com um clique, fácil e rápido",
|
||||
"detail": "Detalhes",
|
||||
"enterAmount": "Por favor, insira o valor de recarga",
|
||||
"enterCoupon": "Insira o código de desconto",
|
||||
"goToPayment": "Ir para o pagamento",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (face a face)",
|
||||
"alipay_f2f": "Alipay (Face a Face)",
|
||||
"balance": "Saldo",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "Método de Pagamento",
|
||||
"paymentSuccess": "Pagamento bem-sucedido",
|
||||
"productList": "Lista de Produtos",
|
||||
"purchaseDuration": "Duração da compra",
|
||||
"recharge": "recarregar",
|
||||
"rechargeAmount": "Valor de recarga",
|
||||
"rechargeNow": "Recarregar agora",
|
||||
"renew": "renovar",
|
||||
"renewSubscription": "Renovar Assinatura",
|
||||
"resetPrice": "Redefinir Preço",
|
||||
"resetTraffic": "Redefinir Tráfego",
|
||||
"resetTrafficDescription": "Apenas redefine o tráfego do mês atual, ok?",
|
||||
"resetTrafficTitle": "Redefinir Tráfego",
|
||||
"scanToPay": "Por favor, escaneie para pagar",
|
||||
"status": {
|
||||
"0": "status",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Hora",
|
||||
"Minute": "Minuto",
|
||||
"Month": "Mês",
|
||||
"NoLimit": "Sem Limite",
|
||||
"Year": "Ano",
|
||||
"all": "todos",
|
||||
"balanceRecharge": "Recarga de Saldo",
|
||||
"billing": {
|
||||
"billingTitle": "Fatura do Produto",
|
||||
"couponDiscount": "Desconto do Cupom",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Preço Total"
|
||||
},
|
||||
"buy": "Comprar",
|
||||
"buyNow": "Compre Agora",
|
||||
"buySubscription": "Comprar Assinatura",
|
||||
"category": "categoria",
|
||||
"coupon": "Cupom",
|
||||
"detail": {
|
||||
"availableTraffic": "Tráfego disponível",
|
||||
"connectedDevices": "Dispositivos conectados simultaneamente",
|
||||
"connectionSpeed": "Velocidade de conexão",
|
||||
"productDetail": "Detalhes do produto"
|
||||
},
|
||||
"enterAmount": "Digite o valor da recarga",
|
||||
"enterCoupon": "Insira o Código do Cupom",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (cara a cara)",
|
||||
"balance": "Saldo",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Método de Pagamento",
|
||||
"productDescription": "Descrição do produto",
|
||||
"products": "produtos"
|
||||
"products": "produtos",
|
||||
"purchaseDuration": "Duração da Compra",
|
||||
"recharge": "Recarregar",
|
||||
"rechargeAmount": "Valor de Recarga",
|
||||
"rechargeDescription": "Recarga com um clique, fácil de manusear",
|
||||
"rechargeNow": "Recarregar Agora",
|
||||
"renew": "Renovar",
|
||||
"renewSubscription": "Renovar Assinatura",
|
||||
"resetPrice": "Redefinir Preço",
|
||||
"resetTraffic": "Redefinir Tráfego",
|
||||
"resetTrafficDescription": "Redefinir o tráfego apenas para o mês atual",
|
||||
"resetTrafficTitle": "Redefinir Tráfego",
|
||||
"selectSubscription": "Selecionar Assinatura",
|
||||
"subscriptionDiscount": "Desconto na Assinatura"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Această aplicație nu suportă momentan activarea, vă rugăm să importați manual, adresa de abonament a fost copiată automat",
|
||||
"mySubscriptions": "Abonamentele mele",
|
||||
"nextResetDays": "Următoarea resetare/zile",
|
||||
"noLimit": "Fără limită",
|
||||
"prompt": "Sfat",
|
||||
"purchaseSubscription": "Achiziționează abonament",
|
||||
"qrCode": "cod QR",
|
||||
|
||||
@ -1,21 +1,10 @@
|
||||
{
|
||||
"Day": "Zi",
|
||||
"Hour": "Oră",
|
||||
"Minute": "Minută",
|
||||
"Month": "Lună",
|
||||
"Year": "An",
|
||||
"balanceRecharge": "Reîncărcare sold",
|
||||
"buyNow": "Cumpără acum",
|
||||
"buySubscription": "Cumpără abonament",
|
||||
"cancel": "Anulare",
|
||||
"createdAt": "Data creării",
|
||||
"description": "Reîncărcare cu un singur clic, ușor de realizat",
|
||||
"detail": "Detalii",
|
||||
"enterAmount": "Introduceți suma de reîncărcare",
|
||||
"enterCoupon": "Introduceți codul de reducere",
|
||||
"goToPayment": "Mergi la plată",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (față în față)",
|
||||
"alipay_f2f": "Alipay (Față în Față)",
|
||||
"balance": "Sold",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "Metodă de plată",
|
||||
"paymentSuccess": "Plata a fost efectuată cu succes",
|
||||
"productList": "Listă de produse",
|
||||
"purchaseDuration": "Durata achiziției",
|
||||
"recharge": "reîncărcare",
|
||||
"rechargeAmount": "Suma de reîncărcare",
|
||||
"rechargeNow": "Reîncarcă acum",
|
||||
"renew": "reînnoire",
|
||||
"renewSubscription": "Reînnoiește abonamentul",
|
||||
"resetPrice": "Resetează prețul",
|
||||
"resetTraffic": "Resetează traficul",
|
||||
"resetTrafficDescription": "Resetează doar traficul din această lună",
|
||||
"resetTrafficTitle": "Resetează traficul",
|
||||
"scanToPay": "Vă rugăm să scanați pentru a plăti",
|
||||
"status": {
|
||||
"0": "stare",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Oră",
|
||||
"Minute": "Minut",
|
||||
"Month": "Lună",
|
||||
"NoLimit": "Fără limită",
|
||||
"Year": "An",
|
||||
"all": "Toate",
|
||||
"balanceRecharge": "Reîncărcare Sold",
|
||||
"billing": {
|
||||
"billingTitle": "Factură produs",
|
||||
"couponDiscount": "Reducere cupon",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Total"
|
||||
},
|
||||
"buy": "Cumpără",
|
||||
"buyNow": "Cumpără acum",
|
||||
"buySubscription": "Cumpără Abonament",
|
||||
"category": "categorie",
|
||||
"coupon": "Cupon",
|
||||
"detail": {
|
||||
"availableTraffic": "Trafic disponibil",
|
||||
"connectedDevices": "Număr de IP-uri conectate simultan",
|
||||
"connectionSpeed": "Viteza de conectare",
|
||||
"productDetail": "Detalii produs"
|
||||
},
|
||||
"enterAmount": "Introduceți suma de reîncărcare",
|
||||
"enterCoupon": "Introduceți codul cuponului",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (față în față)",
|
||||
"balance": "Sold",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Metodă de plată",
|
||||
"productDescription": "Descrierea produsului",
|
||||
"products": "produse"
|
||||
"products": "produse",
|
||||
"purchaseDuration": "Durata Achiziției",
|
||||
"recharge": "Reîncărcare",
|
||||
"rechargeAmount": "Sumă Reîncărcare",
|
||||
"rechargeDescription": "Reîncărcare cu un singur clic, ușor de gestionat",
|
||||
"rechargeNow": "Reîncarcă acum",
|
||||
"renew": "Reînnoiește",
|
||||
"renewSubscription": "Reînnoiește Abonamentul",
|
||||
"resetPrice": "Resetează Prețul",
|
||||
"resetTraffic": "Resetează Traficul",
|
||||
"resetTrafficDescription": "Resetează traficul doar pentru luna curentă",
|
||||
"resetTrafficTitle": "Resetează Traficul",
|
||||
"selectSubscription": "Selectați Abonamentul",
|
||||
"subscriptionDiscount": "Reducere la abonament"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Это приложение временно не поддерживает вызов, пожалуйста, импортируйте вручную, адрес подписки уже скопирован",
|
||||
"mySubscriptions": "Мои подписки",
|
||||
"nextResetDays": "Следующее сброс/дней",
|
||||
"noLimit": "Без ограничений",
|
||||
"prompt": "Подсказка",
|
||||
"purchaseSubscription": "Купить подписку",
|
||||
"qrCode": "QR-код",
|
||||
|
||||
@ -1,21 +1,10 @@
|
||||
{
|
||||
"Day": "День",
|
||||
"Hour": "Час",
|
||||
"Minute": "минута",
|
||||
"Month": "Месяц",
|
||||
"Year": "Год",
|
||||
"balanceRecharge": "Пополнение баланса",
|
||||
"buyNow": "Купить сейчас",
|
||||
"buySubscription": "Купить подписку",
|
||||
"cancel": "Отмена",
|
||||
"createdAt": "Время создания",
|
||||
"description": "Одним нажатием пополните баланс, легко и просто",
|
||||
"detail": "Подробности",
|
||||
"enterAmount": "Введите сумму пополнения",
|
||||
"enterCoupon": "Введите промокод",
|
||||
"goToPayment": "Перейти к оплате",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (лицом к лицу)",
|
||||
"alipay_f2f": "Alipay (Лицом к лицу)",
|
||||
"balance": "Баланс",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "Способ оплаты",
|
||||
"paymentSuccess": "Оплата успешно завершена",
|
||||
"productList": "Список продуктов",
|
||||
"purchaseDuration": "Продолжительность покупки",
|
||||
"recharge": "Пополнение",
|
||||
"rechargeAmount": "Сумма пополнения",
|
||||
"rechargeNow": "Пополнить сейчас",
|
||||
"renew": "обновить",
|
||||
"renewSubscription": "Продлить подписку",
|
||||
"resetPrice": "Сбросить цену",
|
||||
"resetTraffic": "Сбросить трафик",
|
||||
"resetTrafficDescription": "Сбросить только месячный трафик",
|
||||
"resetTrafficTitle": "Сброс трафика",
|
||||
"scanToPay": "Пожалуйста, отсканируйте для оплаты",
|
||||
"status": {
|
||||
"0": "Статус",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Час",
|
||||
"Minute": "минута",
|
||||
"Month": "Месяц",
|
||||
"NoLimit": "Без ограничений",
|
||||
"Year": "Год",
|
||||
"all": "все",
|
||||
"balanceRecharge": "Пополнение баланса",
|
||||
"billing": {
|
||||
"billingTitle": "Счет за товар",
|
||||
"couponDiscount": "Скидка по промокоду",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Итоговая цена"
|
||||
},
|
||||
"buy": "Купить",
|
||||
"buyNow": "Купить сейчас",
|
||||
"buySubscription": "Купить подписку",
|
||||
"category": "категория",
|
||||
"coupon": "Купон",
|
||||
"detail": {
|
||||
"availableTraffic": "Доступный трафик",
|
||||
"connectedDevices": "Количество одновременно подключенных IP",
|
||||
"connectionSpeed": "Скорость соединения",
|
||||
"productDetail": "Детали продукта"
|
||||
},
|
||||
"enterAmount": "Введите сумму пополнения",
|
||||
"enterCoupon": "Введите промокод",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay(лицом к лицу)",
|
||||
"balance": "Баланс",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe(Alipay)",
|
||||
"stripe_wechat_pay": "Stripe(WeChat)"
|
||||
},
|
||||
"paymentMethod": "Способ оплаты",
|
||||
"productDescription": "Описание товара",
|
||||
"products": "товары"
|
||||
"products": "товары",
|
||||
"purchaseDuration": "Продолжительность покупки",
|
||||
"recharge": "Пополнение",
|
||||
"rechargeAmount": "Сумма пополнения",
|
||||
"rechargeDescription": "Одним нажатием пополните баланс, легко и удобно",
|
||||
"rechargeNow": "Пополнить сейчас",
|
||||
"renew": "Обновить",
|
||||
"renewSubscription": "Продлить подписку",
|
||||
"resetPrice": "Сбросить цену",
|
||||
"resetTraffic": "Сбросить трафик",
|
||||
"resetTrafficDescription": "Сбросить трафик только за текущий месяц",
|
||||
"resetTrafficTitle": "Сбросить трафик",
|
||||
"selectSubscription": "Выберите подписку",
|
||||
"subscriptionDiscount": "Скидка на подписку"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "แอปนี้ยังไม่รองรับการเปิดใช้งาน กรุณานำเข้าด้วยตนเอง ที่อยู่การสมัครสมาชิกได้ถูกคัดลอกอัตโนมัติแล้ว",
|
||||
"mySubscriptions": "การสมัครสมาชิกของฉัน",
|
||||
"nextResetDays": "รีเซ็ตครั้งถัดไป/วัน",
|
||||
"noLimit": "ไม่จำกัด",
|
||||
"prompt": "คำแนะนำ",
|
||||
"purchaseSubscription": "ซื้อการสมัครสมาชิก",
|
||||
"qrCode": "คิวอาร์โค้ด",
|
||||
|
||||
@ -1,25 +1,14 @@
|
||||
{
|
||||
"Day": "วัน",
|
||||
"Hour": "ชั่วโมง",
|
||||
"Minute": "นาที",
|
||||
"Month": "เดือน",
|
||||
"Year": "ปี",
|
||||
"balanceRecharge": "เติมเงินยอดคงเหลือ",
|
||||
"buyNow": "ซื้อทันที",
|
||||
"buySubscription": "ซื้อการสมัครสมาชิก",
|
||||
"cancel": "ยกเลิก",
|
||||
"createdAt": "เวลาที่สร้าง",
|
||||
"description": "เติมเงินง่าย ๆ เพียงคลิกเดียว",
|
||||
"detail": "รายละเอียด",
|
||||
"enterAmount": "กรุณาใส่จำนวนเงินที่ต้องการเติม",
|
||||
"enterCoupon": "กรุณาใส่รหัสส่วนลด",
|
||||
"goToPayment": "ไปที่การชำระเงิน",
|
||||
"methods": {
|
||||
"alipay_f2f": "อาลีเพย์ (เผชิญหน้า)",
|
||||
"balance": "ยอดคงเหลือ",
|
||||
"epay": "อีเพย์",
|
||||
"stripe_alipay": "Stripe (อาลีเพย์)",
|
||||
"stripe_wechat_pay": "Stripe (วีแชท)"
|
||||
"stripe_alipay": "สไตรป์ (อาลีเพย์)",
|
||||
"stripe_wechat_pay": "สไตรป์ (วีแชท)"
|
||||
},
|
||||
"name": "ชื่อ",
|
||||
"orderClosed": "คำสั่งซื้อถูกปิดแล้ว",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "วิธีการชำระเงิน",
|
||||
"paymentSuccess": "ชำระเงินสำเร็จ",
|
||||
"productList": "รายการสินค้า",
|
||||
"purchaseDuration": "ระยะเวลาการซื้อ",
|
||||
"recharge": "เติมเงิน",
|
||||
"rechargeAmount": "จำนวนเงินที่เติม",
|
||||
"rechargeNow": "เติมเงินทันที",
|
||||
"renew": "ต่ออายุ",
|
||||
"renewSubscription": "ต่ออายุการสมัครสมาชิก",
|
||||
"resetPrice": "รีเซ็ตราคา",
|
||||
"resetTraffic": "รีเซ็ตการใช้งานข้อมูล",
|
||||
"resetTrafficDescription": "รีเซ็ตเฉพาะปริมาณข้อมูลของเดือนนี้เท่านั้น",
|
||||
"resetTrafficTitle": "รีเซ็ตการใช้งานข้อมูล",
|
||||
"scanToPay": "กรุณาสแกนเพื่อชำระเงิน",
|
||||
"status": {
|
||||
"0": "สถานะ",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "ชั่วโมง",
|
||||
"Minute": "นาที",
|
||||
"Month": "เดือน",
|
||||
"NoLimit": "ไม่จำกัด",
|
||||
"Year": "ปี",
|
||||
"all": "ทั้งหมด",
|
||||
"balanceRecharge": "เติมเงินยอดคงเหลือ",
|
||||
"billing": {
|
||||
"billingTitle": "ใบแจ้งหนี้สินค้า",
|
||||
"couponDiscount": "ส่วนลดคูปอง",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "ราคารวม"
|
||||
},
|
||||
"buy": "ซื้อ",
|
||||
"buyNow": "ซื้อเลย",
|
||||
"buySubscription": "ซื้อการสมัครสมาชิก",
|
||||
"category": "หมวดหมู่",
|
||||
"coupon": "คูปอง",
|
||||
"detail": {
|
||||
"availableTraffic": "ปริมาณข้อมูลที่ใช้ได้",
|
||||
"connectedDevices": "จำนวนอุปกรณ์ที่เชื่อมต่อพร้อมกัน",
|
||||
"connectionSpeed": "ความเร็วในการเชื่อมต่อ",
|
||||
"productDetail": "รายละเอียดสินค้า"
|
||||
},
|
||||
"enterAmount": "กรอกจำนวนเงินที่ต้องการเติม",
|
||||
"enterCoupon": "กรอกรหัสคูปอง",
|
||||
"methods": {
|
||||
"alipay_f2f": "อาลีเพย์ (เผชิญหน้า)",
|
||||
"balance": "ยอดคงเหลือ",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (อาลีเพย์)",
|
||||
"stripe_wechat_pay": "Stripe (วีแชท)"
|
||||
},
|
||||
"paymentMethod": "วิธีการชำระเงิน",
|
||||
"productDescription": "รายละเอียดสินค้า",
|
||||
"products": "สินค้า"
|
||||
"products": "สินค้า",
|
||||
"purchaseDuration": "ระยะเวลาการซื้อ",
|
||||
"recharge": "เติมเงิน",
|
||||
"rechargeAmount": "จำนวนเงินเติม",
|
||||
"rechargeDescription": "เติมเงินง่าย ๆ เพียงคลิกเดียว สะดวกสบาย",
|
||||
"rechargeNow": "เติมเงินทันที",
|
||||
"renew": "ต่ออายุ",
|
||||
"renewSubscription": "ต่ออายุการสมัครสมาชิก",
|
||||
"resetPrice": "รีเซ็ตราคา",
|
||||
"resetTraffic": "รีเซ็ตการจราจร",
|
||||
"resetTrafficDescription": "รีเซ็ตการใช้งานข้อมูลสำหรับเดือนปัจจุบันเท่านั้น",
|
||||
"resetTrafficTitle": "รีเซ็ตการจราจร",
|
||||
"selectSubscription": "เลือกการสมัครสมาชิก",
|
||||
"subscriptionDiscount": "ส่วนลดการสมัครสมาชิก"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Bu uygulama şu anda uyandırmayı desteklemiyor, lütfen elle içe aktarın, abone adresi otomatik olarak kopyalandı",
|
||||
"mySubscriptions": "Aboneliklerim",
|
||||
"nextResetDays": "Sonraki Sıfırlama/Gün",
|
||||
"noLimit": "Sınırsız",
|
||||
"prompt": "istem",
|
||||
"purchaseSubscription": "Abonelik Satın Al",
|
||||
"qrCode": "QR kodu",
|
||||
|
||||
@ -1,25 +1,14 @@
|
||||
{
|
||||
"Day": "Gün",
|
||||
"Hour": "Saat",
|
||||
"Minute": "Dakika",
|
||||
"Month": "Ay",
|
||||
"Year": "Yıl",
|
||||
"balanceRecharge": "Bakiye Yükleme",
|
||||
"buyNow": "Şimdi Satın Al",
|
||||
"buySubscription": "Abonelik Satın Al",
|
||||
"cancel": "İptal",
|
||||
"createdAt": "Oluşturulma Zamanı",
|
||||
"description": "Tek tıkla yükleme, kolayca halledin",
|
||||
"detail": "Detaylar",
|
||||
"enterAmount": "Lütfen yükleme miktarını girin",
|
||||
"enterCoupon": "Lütfen indirim kodunu girin",
|
||||
"goToPayment": "Ödemeye Git",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay(Yüz Yüze)",
|
||||
"alipay_f2f": "Alipay (Yüz Yüze)",
|
||||
"balance": "Bakiye",
|
||||
"epay": "Kolay Ödeme",
|
||||
"stripe_alipay": "Stripe(Alipay)",
|
||||
"stripe_wechat_pay": "Stripe(WeChat)"
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"name": "Adı",
|
||||
"orderClosed": "Sipariş kapatıldı",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "Ödeme Yöntemi",
|
||||
"paymentSuccess": "Ödeme Başarılı",
|
||||
"productList": "Ürün Listesi",
|
||||
"purchaseDuration": "Satın Alma Süresi",
|
||||
"recharge": "şarj et",
|
||||
"rechargeAmount": "Yükleme Tutarı",
|
||||
"rechargeNow": "Şimdi Yükle",
|
||||
"renew": "yenile",
|
||||
"renewSubscription": "Aboneliği Yenile",
|
||||
"resetPrice": "Fiyatı Sıfırla",
|
||||
"resetTraffic": "Trafiği Sıfırla",
|
||||
"resetTrafficDescription": "Sadece bu ayın trafiğini sıfırlayın",
|
||||
"resetTrafficTitle": "Trafiği Sıfırla",
|
||||
"scanToPay": "Lütfen tarayıcı ile ödeme yapın",
|
||||
"status": {
|
||||
"0": "Durum",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Saat",
|
||||
"Minute": "Dakika",
|
||||
"Month": "Ay",
|
||||
"NoLimit": "Sınır Yok",
|
||||
"Year": "Yıl",
|
||||
"all": "Tümü",
|
||||
"balanceRecharge": "Bakiye Yükleme",
|
||||
"billing": {
|
||||
"billingTitle": "Ürün Faturası",
|
||||
"couponDiscount": "Kupon İndirimi",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Toplam Fiyat"
|
||||
},
|
||||
"buy": "satın al",
|
||||
"buyNow": "Şimdi Satın Al",
|
||||
"buySubscription": "Abonelik Satın Al",
|
||||
"category": "kategori",
|
||||
"coupon": "Kupon",
|
||||
"detail": {
|
||||
"availableTraffic": "Kullanılabilir Trafik",
|
||||
"connectedDevices": "Eşzamanlı Bağlı IP Sayısı",
|
||||
"connectionSpeed": "Bağlantı Hızı",
|
||||
"productDetail": "Ürün Detayları"
|
||||
},
|
||||
"enterAmount": "Yükleme tutarını girin",
|
||||
"enterCoupon": "Kupon Kodunu Girin",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay(Yüz Yüze)",
|
||||
"balance": "Bakiye",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe(Alipay)",
|
||||
"stripe_wechat_pay": "Stripe(WeChat)"
|
||||
},
|
||||
"paymentMethod": "Ödeme Yöntemi",
|
||||
"productDescription": "Ürün Açıklaması",
|
||||
"products": "ürünler"
|
||||
"products": "ürünler",
|
||||
"purchaseDuration": "Satın Alma Süresi",
|
||||
"recharge": "Yeniden Yükle",
|
||||
"rechargeAmount": "Yükleme Tutarı",
|
||||
"rechargeDescription": "Tek tıkla şarj, kolay kullanım",
|
||||
"rechargeNow": "Şimdi Yükle",
|
||||
"renew": "Yenile",
|
||||
"renewSubscription": "Aboneliği Yenile",
|
||||
"resetPrice": "Fiyatı Sıfırla",
|
||||
"resetTraffic": "Trafiği Sıfırla",
|
||||
"resetTrafficDescription": "Yalnızca mevcut ay için trafiği sıfırla",
|
||||
"resetTrafficTitle": "Trafiği Sıfırla",
|
||||
"selectSubscription": "Abonelik Seç",
|
||||
"subscriptionDiscount": "Abonelik İndirimi"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Цей додаток тимчасово не підтримує виклик, будь ласка, імпортуйте вручну, адресу підписки вже скопійовано",
|
||||
"mySubscriptions": "Мої підписки",
|
||||
"nextResetDays": "Наступне скидання/днів",
|
||||
"noLimit": "Без обмежень",
|
||||
"prompt": "підказка",
|
||||
"purchaseSubscription": "Придбати підписку",
|
||||
"qrCode": "QR-код",
|
||||
|
||||
@ -1,25 +1,14 @@
|
||||
{
|
||||
"Day": "День",
|
||||
"Hour": "Година",
|
||||
"Minute": "Хвилина",
|
||||
"Month": "Місяць",
|
||||
"Year": "Рік",
|
||||
"balanceRecharge": "Поповнення балансу",
|
||||
"buyNow": "Купити зараз",
|
||||
"buySubscription": "Придбати підписку",
|
||||
"cancel": "Скасувати",
|
||||
"createdAt": "Час створення",
|
||||
"description": "Одним натисканням поповнити рахунок, легко та швидко",
|
||||
"detail": "Деталі",
|
||||
"enterAmount": "Введіть суму поповнення",
|
||||
"enterCoupon": "Введіть код знижки",
|
||||
"goToPayment": "Перейти до оплати",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay(обличчям до обличчя)",
|
||||
"alipay_f2f": "Alipay (Обличчям до обличчя)",
|
||||
"balance": "Баланс",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe(Alipay)",
|
||||
"stripe_wechat_pay": "Stripe(WeChat)"
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"name": "Назва",
|
||||
"orderClosed": "Замовлення закрито",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "Спосіб оплати",
|
||||
"paymentSuccess": "Оплата успішна",
|
||||
"productList": "Список продуктів",
|
||||
"purchaseDuration": "Тривалість покупки",
|
||||
"recharge": "Поповнення",
|
||||
"rechargeAmount": "Сума поповнення",
|
||||
"rechargeNow": "Поповнити зараз",
|
||||
"renew": "продовжити",
|
||||
"renewSubscription": "Поновити підписку",
|
||||
"resetPrice": "Скинути ціну",
|
||||
"resetTraffic": "Скинути трафік",
|
||||
"resetTrafficDescription": "Скидання лише місячного трафіку",
|
||||
"resetTrafficTitle": "Скинути трафік",
|
||||
"scanToPay": "Будь ласка, відскануйте для оплати",
|
||||
"status": {
|
||||
"0": "Статус",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Година",
|
||||
"Minute": "хвилина",
|
||||
"Month": "Місяць",
|
||||
"NoLimit": "Без обмежень",
|
||||
"Year": "Рік",
|
||||
"all": "всі",
|
||||
"balanceRecharge": "Поповнення балансу",
|
||||
"billing": {
|
||||
"billingTitle": "Рахунок за товар",
|
||||
"couponDiscount": "Знижка за промокодом",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Загальна сума"
|
||||
},
|
||||
"buy": "Купити",
|
||||
"buyNow": "Купити зараз",
|
||||
"buySubscription": "Купити підписку",
|
||||
"category": "категорія",
|
||||
"coupon": "Купон",
|
||||
"detail": {
|
||||
"availableTraffic": "Доступний трафік",
|
||||
"connectedDevices": "Кількість одночасно підключених IP",
|
||||
"connectionSpeed": "Швидкість з'єднання",
|
||||
"productDetail": "Деталі товару"
|
||||
},
|
||||
"enterAmount": "Введіть суму поповнення",
|
||||
"enterCoupon": "Введіть код купона",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (обличчям до обличчя)",
|
||||
"balance": "Баланс",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Спосіб оплати",
|
||||
"productDescription": "Опис товару",
|
||||
"products": "товари"
|
||||
"products": "товари",
|
||||
"purchaseDuration": "Тривалість покупки",
|
||||
"recharge": "Поповнення",
|
||||
"rechargeAmount": "Сума поповнення",
|
||||
"rechargeDescription": "Одним натисканням поповнити рахунок, легко впоратися",
|
||||
"rechargeNow": "Поповнити зараз",
|
||||
"renew": "Оновити",
|
||||
"renewSubscription": "Поновити підписку",
|
||||
"resetPrice": "Скинути ціну",
|
||||
"resetTraffic": "Скинути трафік",
|
||||
"resetTrafficDescription": "Скинути трафік лише для поточного місяця",
|
||||
"resetTrafficTitle": "Скинути трафік",
|
||||
"selectSubscription": "Виберіть підписку",
|
||||
"subscriptionDiscount": "Знижка на підписку"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "Ứng dụng này hiện không hỗ trợ kích hoạt, vui lòng nhập thủ công, địa chỉ đăng ký đã được sao chép tự động",
|
||||
"mySubscriptions": "Đăng ký của tôi",
|
||||
"nextResetDays": "Lần đặt lại tiếp theo/ngày",
|
||||
"noLimit": "Không Giới Hạn",
|
||||
"prompt": "gợi ý",
|
||||
"purchaseSubscription": "Mua đăng ký",
|
||||
"qrCode": "Mã QR",
|
||||
|
||||
@ -1,23 +1,12 @@
|
||||
{
|
||||
"Day": "Ngày",
|
||||
"Hour": "Giờ",
|
||||
"Minute": "Phút",
|
||||
"Month": "Tháng",
|
||||
"Year": "Năm",
|
||||
"balanceRecharge": "Nạp tiền số dư",
|
||||
"buyNow": "Mua ngay",
|
||||
"buySubscription": "Mua đăng ký",
|
||||
"cancel": "Hủy",
|
||||
"createdAt": "Thời gian tạo",
|
||||
"description": "Nạp tiền chỉ với một cú nhấp, dễ dàng hoàn tất",
|
||||
"detail": "Chi tiết",
|
||||
"enterAmount": "Vui lòng nhập số tiền nạp",
|
||||
"enterCoupon": "Vui lòng nhập mã giảm giá",
|
||||
"goToPayment": "Đi đến thanh toán",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (mặt đối mặt)",
|
||||
"alipay_f2f": "Alipay (Giao dịch trực tiếp)",
|
||||
"balance": "Số dư",
|
||||
"epay": "Thanh toán dễ dàng",
|
||||
"epay": "Epay",
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
@ -28,19 +17,9 @@
|
||||
"orderNumber": "Số đơn hàng",
|
||||
"payment": "Thanh toán",
|
||||
"paymentAmount": "Số tiền thanh toán",
|
||||
"paymentMethod": "Phương thức thanh toán",
|
||||
"paymentMethod": "Phương Thức Thanh Toán",
|
||||
"paymentSuccess": "Thanh toán thành công",
|
||||
"productList": "Danh sách sản phẩm",
|
||||
"purchaseDuration": "Thời gian mua",
|
||||
"recharge": "Nạp tiền",
|
||||
"rechargeAmount": "Số tiền nạp",
|
||||
"rechargeNow": "Nạp tiền ngay",
|
||||
"renew": "Gia hạn",
|
||||
"renewSubscription": "Gia hạn đăng ký",
|
||||
"resetPrice": "Đặt lại giá",
|
||||
"resetTraffic": "Đặt lại lưu lượng",
|
||||
"resetTrafficDescription": "Chỉ đặt lại lưu lượng tháng này thôi nhé",
|
||||
"resetTrafficTitle": "Đặt lại lưu lượng",
|
||||
"scanToPay": "Vui lòng quét mã để thanh toán",
|
||||
"status": {
|
||||
"0": "Trạng thái",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "Giờ",
|
||||
"Minute": "Phút",
|
||||
"Month": "Tháng",
|
||||
"NoLimit": "Không Giới Hạn",
|
||||
"Year": "Năm",
|
||||
"all": "Tất cả",
|
||||
"balanceRecharge": "Nạp Tiền Số Dư",
|
||||
"billing": {
|
||||
"billingTitle": "Hóa đơn sản phẩm",
|
||||
"couponDiscount": "Ưu đãi mã giảm giá",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "Tổng giá"
|
||||
},
|
||||
"buy": "Mua",
|
||||
"buyNow": "Mua Ngay",
|
||||
"buySubscription": "Mua Gói Đăng Ký",
|
||||
"category": "thể loại",
|
||||
"coupon": "Phiếu giảm giá",
|
||||
"detail": {
|
||||
"availableTraffic": "Lưu lượng khả dụng",
|
||||
"connectedDevices": "Số IP kết nối đồng thời",
|
||||
"connectionSpeed": "Tốc độ kết nối",
|
||||
"productDetail": "Chi tiết sản phẩm"
|
||||
},
|
||||
"enterAmount": "Nhập số tiền nạp",
|
||||
"enterCoupon": "Nhập Mã Phiếu Giảm Giá",
|
||||
"methods": {
|
||||
"alipay_f2f": "Alipay (mặt đối mặt)",
|
||||
"balance": "Số dư",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe (Alipay)",
|
||||
"stripe_wechat_pay": "Stripe (WeChat)"
|
||||
},
|
||||
"paymentMethod": "Phương thức thanh toán",
|
||||
"productDescription": "Mô tả sản phẩm",
|
||||
"products": "Sản phẩm"
|
||||
"products": "Sản phẩm",
|
||||
"purchaseDuration": "Thời Gian Mua Hàng",
|
||||
"recharge": "Nạp tiền",
|
||||
"rechargeAmount": "Số Tiền Nạp",
|
||||
"rechargeDescription": "Nạp tiền chỉ với một cú nhấp, dễ dàng xử lý",
|
||||
"rechargeNow": "Nạp Ngay",
|
||||
"renew": "Gia hạn",
|
||||
"renewSubscription": "Gia hạn đăng ký",
|
||||
"resetPrice": "Đặt lại giá",
|
||||
"resetTraffic": "Đặt lại Lưu lượng",
|
||||
"resetTrafficDescription": "Đặt lại lưu lượng truy cập chỉ cho tháng hiện tại",
|
||||
"resetTrafficTitle": "Đặt lại Lưu lượng",
|
||||
"selectSubscription": "Chọn Gói Đăng Ký",
|
||||
"subscriptionDiscount": "Giảm giá Đăng ký"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "该应用暂不支持唤起,请手动导入,已自动复制订阅地址",
|
||||
"mySubscriptions": "我的订阅",
|
||||
"nextResetDays": "下次重置/天",
|
||||
"noLimit": "无限制",
|
||||
"prompt": "提示",
|
||||
"purchaseSubscription": "购买订阅",
|
||||
"qrCode": "二维码",
|
||||
|
||||
@ -1,25 +1,14 @@
|
||||
{
|
||||
"Day": "天",
|
||||
"Hour": "时",
|
||||
"Minute": "分",
|
||||
"Month": "月",
|
||||
"Year": "年",
|
||||
"balanceRecharge": "余额充值",
|
||||
"buyNow": "立即购买",
|
||||
"buySubscription": "购买订阅",
|
||||
"cancel": "取消",
|
||||
"createdAt": "创建时间",
|
||||
"description": "一键充值,轻松搞定",
|
||||
"detail": "详情",
|
||||
"enterAmount": "请输入充值金额",
|
||||
"enterCoupon": "请输入折扣码",
|
||||
"goToPayment": "前往支付",
|
||||
"methods": {
|
||||
"alipay_f2f": "支付宝(面对面)",
|
||||
"alipay_f2f": "支付宝(面对面)",
|
||||
"balance": "余额",
|
||||
"epay": "易支付",
|
||||
"stripe_alipay": "Stripe(支付宝)",
|
||||
"stripe_wechat_pay": "Stripe(微信)"
|
||||
"epay": "电子支付",
|
||||
"stripe_alipay": "Stripe(支付宝)",
|
||||
"stripe_wechat_pay": "Stripe(微信支付)"
|
||||
},
|
||||
"name": "名称",
|
||||
"orderClosed": "订单已关闭",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "支付方式",
|
||||
"paymentSuccess": "支付成功",
|
||||
"productList": "产品列表",
|
||||
"purchaseDuration": "购买时长",
|
||||
"recharge": "充值",
|
||||
"rechargeAmount": "充值金额",
|
||||
"rechargeNow": "立即充值",
|
||||
"renew": "续费",
|
||||
"renewSubscription": "续费订阅",
|
||||
"resetPrice": "重置价格",
|
||||
"resetTraffic": "重置流量",
|
||||
"resetTrafficDescription": "仅重置当月流量哦",
|
||||
"resetTrafficTitle": "重置流量",
|
||||
"scanToPay": "请扫码支付",
|
||||
"status": {
|
||||
"0": "状态",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "时",
|
||||
"Minute": "分",
|
||||
"Month": "月",
|
||||
"NoLimit": "无限制",
|
||||
"Year": "年",
|
||||
"all": "全部",
|
||||
"balanceRecharge": "余额充值",
|
||||
"billing": {
|
||||
"billingTitle": "商品账单",
|
||||
"couponDiscount": "折扣码优惠",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "总价"
|
||||
},
|
||||
"buy": "购买",
|
||||
"buyNow": "立即购买",
|
||||
"buySubscription": "购买订阅",
|
||||
"category": "类别",
|
||||
"coupon": "优惠券",
|
||||
"detail": {
|
||||
"availableTraffic": "可用流量",
|
||||
"connectedDevices": "同时连接 IP 数",
|
||||
"connectionSpeed": "连接速度",
|
||||
"productDetail": "商品详情"
|
||||
},
|
||||
"enterAmount": "输入充值金额",
|
||||
"enterCoupon": "输入优惠券代码",
|
||||
"methods": {
|
||||
"alipay_f2f": "支付宝(面对面)",
|
||||
"balance": "余额",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe(支付宝)",
|
||||
"stripe_wechat_pay": "Stripe(微信)"
|
||||
},
|
||||
"paymentMethod": "支付方式",
|
||||
"productDescription": "商品描述",
|
||||
"products": "商品"
|
||||
"products": "商品",
|
||||
"purchaseDuration": "购买时长",
|
||||
"recharge": "充值",
|
||||
"rechargeAmount": "充值金额",
|
||||
"rechargeDescription": "一键充值,轻松处理",
|
||||
"rechargeNow": "立即充值",
|
||||
"renew": "续订",
|
||||
"renewSubscription": "续订",
|
||||
"resetPrice": "重置价格",
|
||||
"resetTraffic": "重置流量",
|
||||
"resetTrafficDescription": "仅重置本月的流量",
|
||||
"resetTrafficTitle": "重置流量",
|
||||
"selectSubscription": "选择订阅",
|
||||
"subscriptionDiscount": "订阅折扣"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"manualImportMessage": "該應用暫不支援喚起,請手動導入,已自動複製訂閱地址",
|
||||
"mySubscriptions": "我的訂閱",
|
||||
"nextResetDays": "下次重置/天",
|
||||
"noLimit": "無限制",
|
||||
"prompt": "提示",
|
||||
"purchaseSubscription": "購買訂閱",
|
||||
"qrCode": "QR碼",
|
||||
|
||||
@ -1,25 +1,14 @@
|
||||
{
|
||||
"Day": "日",
|
||||
"Hour": "時",
|
||||
"Minute": "分鐘",
|
||||
"Month": "月",
|
||||
"Year": "年",
|
||||
"balanceRecharge": "餘額儲值",
|
||||
"buyNow": "立即購買",
|
||||
"buySubscription": "購買訂閱",
|
||||
"cancel": "取消",
|
||||
"createdAt": "建立時間",
|
||||
"description": "一鍵充值,輕鬆搞定",
|
||||
"detail": "詳情",
|
||||
"enterAmount": "請輸入充值金額",
|
||||
"enterCoupon": "請輸入折扣碼",
|
||||
"goToPayment": "前往付款",
|
||||
"methods": {
|
||||
"alipay_f2f": "支付寶(面對面)",
|
||||
"alipay_f2f": "支付寶(面對面)",
|
||||
"balance": "餘額",
|
||||
"epay": "易支付",
|
||||
"stripe_alipay": "Stripe(支付寶)",
|
||||
"stripe_wechat_pay": "Stripe(微信)"
|
||||
"epay": "電子支付",
|
||||
"stripe_alipay": "Stripe(支付寶)",
|
||||
"stripe_wechat_pay": "Stripe(微信支付)"
|
||||
},
|
||||
"name": "名稱",
|
||||
"orderClosed": "訂單已關閉",
|
||||
@ -31,16 +20,6 @@
|
||||
"paymentMethod": "付款方式",
|
||||
"paymentSuccess": "付款成功",
|
||||
"productList": "產品列表",
|
||||
"purchaseDuration": "購買時長",
|
||||
"recharge": "儲值",
|
||||
"rechargeAmount": "儲值金額",
|
||||
"rechargeNow": "立即儲值",
|
||||
"renew": "續費",
|
||||
"renewSubscription": "續費訂閱",
|
||||
"resetPrice": "重設價格",
|
||||
"resetTraffic": "重設流量",
|
||||
"resetTrafficDescription": "僅重置當月流量哦",
|
||||
"resetTrafficTitle": "重設流量",
|
||||
"scanToPay": "請掃碼支付",
|
||||
"status": {
|
||||
"0": "狀態",
|
||||
|
||||
@ -3,8 +3,10 @@
|
||||
"Hour": "時",
|
||||
"Minute": "分鐘",
|
||||
"Month": "月",
|
||||
"NoLimit": "無限制",
|
||||
"Year": "年",
|
||||
"all": "全部",
|
||||
"balanceRecharge": "餘額充值",
|
||||
"billing": {
|
||||
"billingTitle": "商品帳單",
|
||||
"couponDiscount": "折扣碼優惠",
|
||||
@ -15,13 +17,18 @@
|
||||
"total": "總價"
|
||||
},
|
||||
"buy": "購買",
|
||||
"buyNow": "立即購買",
|
||||
"buySubscription": "購買訂閱",
|
||||
"category": "類別",
|
||||
"coupon": "優惠券",
|
||||
"detail": {
|
||||
"availableTraffic": "可用流量",
|
||||
"connectedDevices": "同時連接 IP 數",
|
||||
"connectionSpeed": "連接速度",
|
||||
"productDetail": "商品詳情"
|
||||
},
|
||||
"enterAmount": "輸入充值金額",
|
||||
"enterCoupon": "輸入優惠券代碼",
|
||||
"methods": {
|
||||
"alipay_f2f": "支付寶(面對面)",
|
||||
"balance": "餘額",
|
||||
@ -29,6 +36,20 @@
|
||||
"stripe_alipay": "Stripe(支付寶)",
|
||||
"stripe_wechat_pay": "Stripe(微信)"
|
||||
},
|
||||
"paymentMethod": "付款方式",
|
||||
"productDescription": "商品描述",
|
||||
"products": "產品"
|
||||
"products": "產品",
|
||||
"purchaseDuration": "購買期限",
|
||||
"recharge": "充值",
|
||||
"rechargeAmount": "充值金額",
|
||||
"rechargeDescription": "一鍵充值,輕鬆處理",
|
||||
"rechargeNow": "立即充值",
|
||||
"renew": "續期",
|
||||
"renewSubscription": "續訂",
|
||||
"resetPrice": "重設價格",
|
||||
"resetTraffic": "重設流量",
|
||||
"resetTrafficDescription": "僅重設本月的流量",
|
||||
"resetTrafficTitle": "重設流量",
|
||||
"selectSubscription": "選擇訂閱",
|
||||
"subscriptionDiscount": "訂閱折扣"
|
||||
}
|
||||
|
||||
4
apps/user/services/common/typings.d.ts
vendored
4
apps/user/services/common/typings.d.ts
vendored
@ -173,6 +173,8 @@ declare namespace API {
|
||||
trade_no: string;
|
||||
status: number;
|
||||
subscribe_id: number;
|
||||
subscription_discount_id: number;
|
||||
subscription_discount_price: number;
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
};
|
||||
@ -194,6 +196,8 @@ declare namespace API {
|
||||
status: number;
|
||||
subscribe_id: number;
|
||||
subscribe: Subscribe;
|
||||
subscription_discount_id: number;
|
||||
subscription_discount_price: number;
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
};
|
||||
|
||||
14
apps/user/services/user/typings.d.ts
vendored
14
apps/user/services/user/typings.d.ts
vendored
@ -195,6 +195,8 @@ declare namespace API {
|
||||
trade_no: string;
|
||||
status: number;
|
||||
subscribe_id: number;
|
||||
subscription_discount_id: number;
|
||||
subscription_discount_price: number;
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
};
|
||||
@ -216,6 +218,8 @@ declare namespace API {
|
||||
status: number;
|
||||
subscribe_id: number;
|
||||
subscribe: Subscribe;
|
||||
subscription_discount_id: number;
|
||||
subscription_discount_price: number;
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
};
|
||||
@ -240,6 +244,7 @@ declare namespace API {
|
||||
coupon: string;
|
||||
coupon_discount: number;
|
||||
fee_amount: number;
|
||||
discount_list: SubscribeDiscountInfo[];
|
||||
};
|
||||
|
||||
type PreRenewalOrderResponse = {
|
||||
@ -251,6 +256,7 @@ declare namespace API {
|
||||
quantity: number;
|
||||
payment: string;
|
||||
coupon?: string;
|
||||
discount_subscribe_id: number;
|
||||
};
|
||||
|
||||
type PurchaseOrderResponse = {
|
||||
@ -364,6 +370,7 @@ declare namespace API {
|
||||
payment: string;
|
||||
coupon?: string;
|
||||
subscribe_token: string;
|
||||
discount_subscribe_id: number;
|
||||
};
|
||||
|
||||
type RenewalOrderResponse = {
|
||||
@ -496,6 +503,13 @@ declare namespace API {
|
||||
discount: number;
|
||||
};
|
||||
|
||||
type SubscribeDiscountInfo = {
|
||||
id: number;
|
||||
name: string;
|
||||
price: number;
|
||||
expire_time: string;
|
||||
};
|
||||
|
||||
type SubscribeGroup = {
|
||||
id: number;
|
||||
name: string;
|
||||
|
||||
@ -17,6 +17,7 @@ import * as React from 'react';
|
||||
export type Option<T = string> = {
|
||||
value: T;
|
||||
label: string;
|
||||
children?: React.ReactNode;
|
||||
};
|
||||
|
||||
// Conditional types to determine the value type for onChange
|
||||
@ -98,11 +99,11 @@ export function Combobox<T, M extends boolean = false>({
|
||||
<CommandList>
|
||||
{options.map((option) => (
|
||||
<CommandItem
|
||||
key={String(option.label)}
|
||||
key={String(option.label + option.value)}
|
||||
value={option.label}
|
||||
onSelect={() => handleSelect(option.value)}
|
||||
>
|
||||
{option.label}
|
||||
{option.children || option.label}
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
'ml-auto h-4 w-4',
|
||||
|
||||
@ -1,32 +1,9 @@
|
||||
import { startOfMonth } from 'date-fns';
|
||||
|
||||
export * from '@workspace/ui/utils/countries';
|
||||
export * from '@workspace/ui/utils/formatting';
|
||||
export * from '@workspace/ui/utils/unit-conversions';
|
||||
|
||||
export const isBrowser = () => typeof window !== 'undefined';
|
||||
|
||||
export function getNextResetDate(startDate: Date | number) {
|
||||
const time = new Date(startDate);
|
||||
const resetDay = time.getDate();
|
||||
const currentDate = new Date();
|
||||
if (isNaN(time.getTime())) {
|
||||
throw new Error('Invalid start date');
|
||||
}
|
||||
if (currentDate.getDate() >= resetDay) {
|
||||
const startOfMonthNextReset = startOfMonth(currentDate);
|
||||
startOfMonthNextReset.setMonth(startOfMonthNextReset.getMonth() + 1);
|
||||
startOfMonthNextReset.setDate(resetDay);
|
||||
startOfMonthNextReset.setHours(time.getHours());
|
||||
startOfMonthNextReset.setMinutes(time.getMinutes());
|
||||
startOfMonthNextReset.setSeconds(time.getSeconds());
|
||||
return startOfMonthNextReset;
|
||||
} else {
|
||||
time.setMonth(currentDate.getMonth());
|
||||
return time;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the full domain or root domain from a URL.
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user