Compare commits

...

40 Commits

Author SHA1 Message Date
semantic-release-bot d10ecc9fdf 🔖 chore(release): v1.0.0-beta.28 [skip ci]
# [1.0.0-beta.28](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.27...v1.0.0-beta.28) (2025-03-13)

###  Features

* **input**: Add minimum value constraint and enhance number handling in EnhancedInput ([94822d9](https://github.com/perfect-panel/ppanel-web/commit/94822d9))
2025-03-13 10:35:19 +00:00
web@ppanel 94822d902f feat(input): Add minimum value constraint and enhance number handling in EnhancedInput 2025-03-13 17:32:36 +07:00
semantic-release-bot 85fdc36c14 🔖 chore(release): v1.0.0-beta.27 [skip ci]
# [1.0.0-beta.27](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.26...v1.0.0-beta.27) (2025-03-13)

### ♻ Code Refactoring

* **payment**: Reconstruct the payment page ([7109472](https://github.com/perfect-panel/ppanel-web/commit/7109472))
* Enhance user navigation dropdown ui and styling ([d2732e6](https://github.com/perfect-panel/ppanel-web/commit/d2732e6))

###  Features

* **cdn**: Add CDN URL configuration and update related references ([0c90733](https://github.com/perfect-panel/ppanel-web/commit/0c90733))
* **payment**: Add bank card payment ([7fa3a57](https://github.com/perfect-panel/ppanel-web/commit/7fa3a57))
* **subscription**:  Improve layout and organization of subscription detail tabs ([e4630f8](https://github.com/perfect-panel/ppanel-web/commit/e4630f8))
* **subscription**: Refactor subscription handling and update imports for better organization ([2215c7f](https://github.com/perfect-panel/ppanel-web/commit/2215c7f))

### 🎫 Chores

* **merge**: Bump version to 1.0.0-beta.26 and update changelog ([3222016](https://github.com/perfect-panel/ppanel-web/commit/3222016))

### 🐛 Bug Fixes

* **affiliate**: Update user identifier ([35f92c9](https://github.com/perfect-panel/ppanel-web/commit/35f92c9))
* **changelog**: Update change log style ([cfa3fc0](https://github.com/perfect-panel/ppanel-web/commit/cfa3fc0))
* **payment**: Add notification URL field to payment management interface ([5c710e1](https://github.com/perfect-panel/ppanel-web/commit/5c710e1))
* **payment**: Fix payment related type definitions and update payment method references ([c3138a8](https://github.com/perfect-panel/ppanel-web/commit/c3138a8))
* **payment**: Refactor purchaseCheckout usage and remove redundant code ([a5e2079](https://github.com/perfect-panel/ppanel-web/commit/a5e2079))
* **payment**: Update checkout type from 'link' to 'url' for consistency ([136a1ab](https://github.com/perfect-panel/ppanel-web/commit/136a1ab))
* **payment**: Update payment information ([70d6a38](https://github.com/perfect-panel/ppanel-web/commit/70d6a38))
* **payment**: Update payment method update logic to include row data ([6752420](https://github.com/perfect-panel/ppanel-web/commit/6752420))
* **purchasing**: Update payment type to lowercase and add optional chaining for discounts ([c06ea49](https://github.com/perfect-panel/ppanel-web/commit/c06ea49))
* **ui**: Improve dashboard layout and enhance button functionality; open checkout URLs in a new tab ([fc0da76](https://github.com/perfect-panel/ppanel-web/commit/fc0da76))
* **ui**: Multiple display bugs ([f5d8fd3](https://github.com/perfect-panel/ppanel-web/commit/f5d8fd3))
2025-03-13 04:27:12 +00:00
web@ppanel cfa3fc024d 🐛 fix(changelog): Update change log style 2025-03-13 11:23:14 +07:00
web@ppanel c06ea49d6f 🐛 fix(purchasing): Update payment type to lowercase and add optional chaining for discounts 2025-03-13 00:06:42 +07:00
web@ppanel c3138a863d 🐛 fix(payment): Fix payment related type definitions and update payment method references 2025-03-12 21:17:04 +07:00
web@ppanel 7fa3a57df4 feat(payment): Add bank card payment 2025-03-12 17:15:32 +07:00
web@ppanel 70d6a38a29 🐛 fix(payment): Update payment information 2025-03-12 13:43:06 +07:00
web@ppanel 5c710e1add 🐛 fix(payment): Add notification URL field to payment management interface 2025-03-11 21:22:18 +07:00
web@ppanel 6752420ba5 🐛 fix(payment): Update payment method update logic to include row data 2025-03-11 21:15:07 +07:00
web@ppanel 710947209a ♻️ refactor(payment): Reconstruct the payment page 2025-03-11 20:06:12 +07:00
web@ppanel fc0da761b5 🐛 fix(ui): Improve dashboard layout and enhance button functionality; open checkout URLs in a new tab 2025-03-10 18:32:07 +07:00
web@ppanel 136a1abd8b 🐛 fix(payment): Update checkout type from 'link' to 'url' for consistency 2025-03-08 20:10:45 +07:00
web@ppanel a5e2079ddc 🐛 fix(payment): Refactor purchaseCheckout usage and remove redundant code 2025-03-08 20:04:33 +07:00
web@ppanel 35f92c9329 🐛 fix(affiliate): Update user identifier 2025-03-08 15:43:20 +07:00
web@ppanel f5d8fd3b65 🐛 fix(ui): Multiple display bugs 2025-03-08 14:46:20 +07:00
web@ppanel 0c907337e1 feat(cdn): Add CDN URL configuration and update related references 2025-03-08 12:54:58 +07:00
web@ppanel e4630f8ca9 feat(subscription): Improve layout and organization of subscription detail tabs 2025-03-08 12:43:57 +07:00
web@ppanel 2215c7f2b9 feat(subscription): Refactor subscription handling and update imports for better organization 2025-03-08 12:36:25 +07:00
semantic-release-bot 3222016799 🔧 chore(merge): Bump version to 1.0.0-beta.26 and update changelog 2025-03-08 12:36:02 +07:00
web@ppanel d0a04679ce Merge pull request #12 from turbolnk-com/develop
♻️ refactor: Enhance user navigation dropdown ui and styling
2025-03-07 11:46:01 +07:00
turbolnk d2732e650b ♻️ refactor: Enhance user navigation dropdown ui and styling 2025-03-06 09:34:39 +08:00
semantic-release-bot 79edea7973 🔖 chore(release): v1.0.0-beta.26 [skip ci]
# [1.0.0-beta.26](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.25...v1.0.0-beta.26) (2025-03-02)

### 🐛 Bug Fixes

* **icon**: Comment out unused icon collection imports ([f17bf8d](https://github.com/perfect-panel/ppanel-web/commit/f17bf8d))
2025-03-02 16:40:10 +00:00
web@ppanel f17bf8db6e 🐛 fix(icon): Comment out unused icon collection imports 2025-03-02 23:37:15 +07:00
semantic-release-bot 047a69886e 🔖 chore(release): v1.0.0-beta.25 [skip ci]
# [1.0.0-beta.25](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.24...v1.0.0-beta.25) (2025-03-01)

###  Features

* **auth**: Add privacy policy link to the footer ([8e16ef1](https://github.com/perfect-panel/ppanel-web/commit/8e16ef1))

### 🐛 Bug Fixes

* **dashboard**: Display subscription creation date in user dashboard ([d0e6df0](https://github.com/perfect-panel/ppanel-web/commit/d0e6df0))
* **request**: Add error code 40005 to trigger logout ([71bf002](https://github.com/perfect-panel/ppanel-web/commit/71bf002))
* **subscribe**: Update payment return URL ([2b80496](https://github.com/perfect-panel/ppanel-web/commit/2b80496))
2025-03-01 12:59:06 +00:00
web@ppanel 71bf002370 🐛 fix(request): Add error code 40005 to trigger logout 2025-03-01 19:55:55 +07:00
web@ppanel d0e6df044e 🐛 fix(dashboard): Display subscription creation date in user dashboard 2025-03-01 19:55:31 +07:00
web@ppanel 8e16ef17ed feat(auth): Add privacy policy link to the footer 2025-03-01 19:40:45 +07:00
web@ppanel 2b80496637 🐛 fix(subscribe): Update payment return URL 2025-03-01 19:35:32 +07:00
semantic-release-bot 01a3aa02ec 🔖 chore(release): v1.0.0-beta.24 [skip ci]
# [1.0.0-beta.24](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.23...v1.0.0-beta.24) (2025-02-27)

### ♻ Code Refactoring

* **ui**: Optimize document display ([2ca2992](https://github.com/perfect-panel/ppanel-web/commit/2ca2992))
* Reduce code complexity and improve readability ([e11f18c](https://github.com/perfect-panel/ppanel-web/commit/e11f18c))

###  Features

* **loading**: Add loading components and integrate them in Providers ([d5847fa](https://github.com/perfect-panel/ppanel-web/commit/d5847fa))

### 🎫 Chores

* **merge**: Add advertising module and device settings ([0130e02](https://github.com/perfect-panel/ppanel-web/commit/0130e02))

### 🐛 Bug Fixes

* **locales**: Order recharge related fields ([35210fe](https://github.com/perfect-panel/ppanel-web/commit/35210fe))
2025-02-27 08:02:53 +00:00
web@ppanel 35210fe8cf 🐛 fix(locales): Order recharge related fields 2025-02-27 14:53:19 +07:00
web@ppanel d5847faeda feat(loading): Add loading components and integrate them in Providers 2025-02-27 14:44:30 +07:00
web@ppanel 0130e02ffd 🔧 chore(merge): Add advertising module and device settings 2025-02-27 13:46:51 +07:00
web@ppanel c2b858e3fe Merge pull request #11 from turbolnk-com/develop
♻️ refactor(ui): Optimize document display
2025-02-25 18:35:05 +07:00
turbolnk e11f18c034 ♻️ refactor: Reduce code complexity and improve readability 2025-02-25 19:31:32 +08:00
turbolnk 2ca299224d ♻️ refactor(ui): Optimize document display 2025-02-25 18:38:25 +08:00
semantic-release-bot cf1d66d07e 🔖 chore(release): v1.0.0-beta.23 [skip ci]
# [1.0.0-beta.23](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.22...v1.0.0-beta.23) (2025-02-24)

### 🐛 Bug Fixes

* **auth**: Update email verification logic to use domain suffix check ([62662bb](https://github.com/perfect-panel/ppanel-web/commit/62662bb))
2025-02-24 05:10:30 +00:00
web@ppanel 62662bb79c 🐛 fix(auth): Update email verification logic to use domain suffix check 2025-02-24 12:07:41 +07:00
semantic-release-bot c0fb34fa50 🔖 chore(release): v1.0.0-beta.22 [skip ci]
# [1.0.0-beta.22](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.21...v1.0.0-beta.22) (2025-02-23)

### 🐛 Bug Fixes

* **locales**: Removed language file import to clean up unnecessary language support ([68f6ab2](https://github.com/perfect-panel/ppanel-web/commit/68f6ab2))
2025-02-23 15:06:05 +00:00
web@ppanel 68f6ab2e6c 🐛 fix(locales): Removed language file import to clean up unnecessary language support 2025-02-23 22:03:15 +07:00
305 changed files with 7010 additions and 2760 deletions
+103 -5
View File
@@ -1,19 +1,117 @@
<a name="readme-top"></a> <a name="readme-top"></a>
# Changelog # Changelog
# [1.0.0-beta.21](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.20...v1.0.0-beta.21) (2025-02-23) # [1.0.0-beta.28](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.27...v1.0.0-beta.28) (2025-03-13)
### ✨ Features ### ✨ Features
* **privacy-policy**: Add privacy policy related text and links ([baa68f0](https://github.com/perfect-panel/ppanel-web/commit/baa68f0)) * **input**: Add minimum value constraint and enhance number handling in EnhancedInput ([94822d9](https://github.com/perfect-panel/ppanel-web/commit/94822d9))
# [1.0.0-beta.27](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.26...v1.0.0-beta.27) (2025-03-13)
### ♻ Code Refactoring
* **payment**: Reconstruct the payment page ([7109472](https://github.com/perfect-panel/ppanel-web/commit/7109472))
* Enhance user navigation dropdown ui and styling ([d2732e6](https://github.com/perfect-panel/ppanel-web/commit/d2732e6))
### ✨ Features
* **cdn**: Add CDN URL configuration and update related references ([0c90733](https://github.com/perfect-panel/ppanel-web/commit/0c90733))
* **payment**: Add bank card payment ([7fa3a57](https://github.com/perfect-panel/ppanel-web/commit/7fa3a57))
* **subscription**: Improve layout and organization of subscription detail tabs ([e4630f8](https://github.com/perfect-panel/ppanel-web/commit/e4630f8))
* **subscription**: Refactor subscription handling and update imports for better organization ([2215c7f](https://github.com/perfect-panel/ppanel-web/commit/2215c7f))
### 🎫 Chores
* **merge**: Bump version to 1.0.0-beta.26 and update changelog ([3222016](https://github.com/perfect-panel/ppanel-web/commit/3222016))
### 🐛 Bug Fixes ### 🐛 Bug Fixes
* **locales**: Removed multilingual files to clean up unnecessary language support ([5b151cd](https://github.com/perfect-panel/ppanel-web/commit/5b151cd)) * **affiliate**: Update user identifier ([35f92c9](https://github.com/perfect-panel/ppanel-web/commit/35f92c9))
* **locales**: Update custom HTML description in language file, ([87381da](https://github.com/perfect-panel/ppanel-web/commit/87381da)) * **changelog**: Update change log style ([cfa3fc0](https://github.com/perfect-panel/ppanel-web/commit/cfa3fc0))
* **table**: Update privacy policy tab translation key and remove unnecessary requestType from OAuth callback ([14b3af5](https://github.com/perfect-panel/ppanel-web/commit/14b3af5)) * **payment**: Add notification URL field to payment management interface ([5c710e1](https://github.com/perfect-panel/ppanel-web/commit/5c710e1))
* **payment**: Fix payment related type definitions and update payment method references ([c3138a8](https://github.com/perfect-panel/ppanel-web/commit/c3138a8))
* **payment**: Refactor purchaseCheckout usage and remove redundant code ([a5e2079](https://github.com/perfect-panel/ppanel-web/commit/a5e2079))
* **payment**: Update checkout type from 'link' to 'url' for consistency ([136a1ab](https://github.com/perfect-panel/ppanel-web/commit/136a1ab))
* **payment**: Update payment information ([70d6a38](https://github.com/perfect-panel/ppanel-web/commit/70d6a38))
* **payment**: Update payment method update logic to include row data ([6752420](https://github.com/perfect-panel/ppanel-web/commit/6752420))
* **purchasing**: Update payment type to lowercase and add optional chaining for discounts ([c06ea49](https://github.com/perfect-panel/ppanel-web/commit/c06ea49))
* **ui**: Improve dashboard layout and enhance button functionality; open checkout URLs in a new tab ([fc0da76](https://github.com/perfect-panel/ppanel-web/commit/fc0da76))
* **ui**: Multiple display bugs ([f5d8fd3](https://github.com/perfect-panel/ppanel-web/commit/f5d8fd3))
<a name="readme-top"></a>
# Changelog
# [1.0.0-beta.26](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.25...v1.0.0-beta.26) (2025-03-02)
### 🐛 Bug Fixes
- **icon**: Comment out unused icon collection imports ([f17bf8d](https://github.com/perfect-panel/ppanel-web/commit/f17bf8d))
# [1.0.0-beta.25](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.24...v1.0.0-beta.25) (2025-03-01)
### ✨ Features
- **auth**: Add privacy policy link to the footer ([8e16ef1](https://github.com/perfect-panel/ppanel-web/commit/8e16ef1))
### 🐛 Bug Fixes
- **dashboard**: Display subscription creation date in user dashboard ([d0e6df0](https://github.com/perfect-panel/ppanel-web/commit/d0e6df0))
- **request**: Add error code 40005 to trigger logout ([71bf002](https://github.com/perfect-panel/ppanel-web/commit/71bf002))
- **subscribe**: Update payment return URL ([2b80496](https://github.com/perfect-panel/ppanel-web/commit/2b80496))
# [1.0.0-beta.24](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.23...v1.0.0-beta.24) (2025-02-27)
### ♻ Code Refactoring
- **ui**: Optimize document display ([2ca2992](https://github.com/perfect-panel/ppanel-web/commit/2ca2992))
- Reduce code complexity and improve readability ([e11f18c](https://github.com/perfect-panel/ppanel-web/commit/e11f18c))
### ✨ Features
- **loading**: Add loading components and integrate them in Providers ([d5847fa](https://github.com/perfect-panel/ppanel-web/commit/d5847fa))
### 🎫 Chores
- **merge**: Add advertising module and device settings ([0130e02](https://github.com/perfect-panel/ppanel-web/commit/0130e02))
### 🐛 Bug Fixes
- **locales**: Order recharge related fields ([35210fe](https://github.com/perfect-panel/ppanel-web/commit/35210fe))
<a name="readme-top"></a>
# Changelog
# [1.0.0-beta.23](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.22...v1.0.0-beta.23) (2025-02-24)
### 🐛 Bug Fixes
- **auth**: Update email verification logic to use domain suffix check ([62662bb](https://github.com/perfect-panel/ppanel-web/commit/62662bb))
# [1.0.0-beta.22](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.21...v1.0.0-beta.22) (2025-02-23)
### 🐛 Bug Fixes
- **locales**: Removed language file import to clean up unnecessary language support ([68f6ab2](https://github.com/perfect-panel/ppanel-web/commit/68f6ab2))
# [1.0.0-beta.21](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.20...v1.0.0-beta.21) (2025-02-23)
### ✨ Features
- **privacy-policy**: Add privacy policy related text and links ([baa68f0](https://github.com/perfect-panel/ppanel-web/commit/baa68f0))
### 🐛 Bug Fixes
- **locales**: Removed multilingual files to clean up unnecessary language support ([5b151cd](https://github.com/perfect-panel/ppanel-web/commit/5b151cd))
- **locales**: Update custom HTML description in language file, ([87381da](https://github.com/perfect-panel/ppanel-web/commit/87381da))
- **table**: Update privacy policy tab translation key and remove unnecessary requestType from OAuth callback ([14b3af5](https://github.com/perfect-panel/ppanel-web/commit/14b3af5))
<a name="readme-top"></a> <a name="readme-top"></a>
@@ -31,7 +31,7 @@ export default function RegisterForm({
const handleCheckUser = async (email: string) => { const handleCheckUser = async (email: string) => {
try { try {
if (!auth.email.enable_verify) return true; if (!auth.email.enable_domain_suffix) return true;
const domain = email.split('@')[1]; const domain = email.split('@')[1];
const isValid = auth.email?.domain_suffix_list.split('\n').includes(domain || ''); const isValid = auth.email?.domain_suffix_list.split('\n').includes(domain || '');
return isValid; return isValid;
+299
View File
@@ -0,0 +1,299 @@
'use client';
import { zodResolver } from '@hookform/resolvers/zod';
import { Button } from '@workspace/ui/components/button';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@workspace/ui/components/form';
import { RadioGroup, RadioGroupItem } from '@workspace/ui/components/radio-group';
import { ScrollArea } from '@workspace/ui/components/scroll-area';
import {
Sheet,
SheetContent,
SheetFooter,
SheetHeader,
SheetTitle,
SheetTrigger,
} from '@workspace/ui/components/sheet';
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
import { Icon } from '@workspace/ui/custom-components/icon';
import { useTranslations } from 'next-intl';
import { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
const formSchema = z.object({
title: z.string(),
type: z.enum(['image', 'video']),
content: z.string(),
description: z.string(),
target_url: z.string().url(),
start_time: z.number(),
end_time: z.number(),
});
interface AdsFormProps<T> {
onSubmit: (data: T) => Promise<boolean> | boolean;
initialValues?: T;
loading?: boolean;
trigger: string;
title: string;
}
export default function AdsForm<T extends Record<string, any>>({
onSubmit,
initialValues,
loading,
trigger,
title,
}: AdsFormProps<T>) {
const t = useTranslations('ads');
const [open, setOpen] = useState(false);
const form = useForm({
resolver: zodResolver(formSchema),
defaultValues: {
...initialValues,
} as any,
});
useEffect(() => {
form?.reset(initialValues);
}, [form, initialValues]);
const type = form.watch('type');
const startTime = form.watch('start_time');
const renderContentField = () => {
return (
<FormField
control={form.control}
name='content'
render={({ field }) => (
<FormItem>
<FormLabel>{t('form.content')}</FormLabel>
<FormControl>
<EnhancedInput
placeholder={
type === 'image'
? 'https://example.com/image.jpg'
: 'https://example.com/video.mp4'
}
value={field.value}
onValueChange={(value) => {
form.setValue('content', value);
}}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
);
};
async function handleSubmit(data: { [x: string]: any }) {
const bool = await onSubmit(data as T);
if (bool) setOpen(false);
}
return (
<Sheet open={open} onOpenChange={setOpen}>
<SheetTrigger asChild>
<Button
onClick={() => {
form.reset();
setOpen(true);
}}
>
{trigger}
</Button>
</SheetTrigger>
<SheetContent className='w-[500px] max-w-full md:max-w-screen-md'>
<SheetHeader>
<SheetTitle>{title}</SheetTitle>
</SheetHeader>
<ScrollArea className='-mx-6 h-[calc(100vh-48px-36px-36px-env(safe-area-inset-top))]'>
<Form {...form}>
<form onSubmit={form.handleSubmit(handleSubmit)} className='space-y-4 px-6 pt-4'>
<FormField
control={form.control}
name='title'
render={({ field }) => (
<FormItem>
<FormLabel>{t('form.title')}</FormLabel>
<FormControl>
<EnhancedInput
placeholder={t('form.enterTitle')}
value={field.value}
onValueChange={(value) => {
form.setValue(field.name, value);
}}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name='type'
render={({ field }) => (
<FormItem>
<FormLabel>{t('form.type')}</FormLabel>
<FormControl>
<RadioGroup
defaultValue={field.value}
onValueChange={(value) => {
form.setValue(field.name, value);
}}
className='flex gap-4'
>
<FormItem className='flex items-center space-x-3 space-y-0'>
<FormControl>
<RadioGroupItem value='image' />
</FormControl>
<FormLabel className='font-normal'>{t('form.typeImage')}</FormLabel>
</FormItem>
<FormItem className='flex items-center space-x-3 space-y-0'>
<FormControl>
<RadioGroupItem value='video' />
</FormControl>
<FormLabel className='font-normal'>{t('form.typeVideo')}</FormLabel>
</FormItem>
</RadioGroup>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{renderContentField()}
<FormField
control={form.control}
name='description'
render={({ field }) => (
<FormItem>
<FormLabel>{t('form.description')}</FormLabel>
<FormControl>
<EnhancedInput
placeholder={t('form.enterDescription')}
value={field.value}
onValueChange={(value) => {
form.setValue(field.name, value);
}}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name='target_url'
render={({ field }) => (
<FormItem>
<FormLabel>{t('form.targetUrl')}</FormLabel>
<FormControl>
<EnhancedInput
placeholder={t('form.enterTargetUrl')}
value={field.value}
onValueChange={(value) => {
form.setValue(field.name, value);
}}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name='start_time'
render={({ field }) => (
<FormItem>
<FormLabel>{t('form.startTime')}</FormLabel>
<FormControl>
<EnhancedInput
type='datetime-local'
placeholder={t('form.enterStartTime')}
value={field.value ? new Date(field.value).toISOString().slice(0, 16) : ''}
min={Number(new Date().toISOString().slice(0, 16))}
onValueChange={(value) => {
const timestamp = value ? new Date(value).getTime() : 0;
form.setValue(field.name, timestamp);
const endTime = form.getValues('end_time');
if (endTime && timestamp > endTime) {
form.setValue('end_time', '');
}
}}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name='end_time'
render={({ field }) => {
return (
<FormItem>
<FormLabel>{t('form.endTime')}</FormLabel>
<FormControl>
<EnhancedInput
type='datetime-local'
placeholder={t('form.enterEndTime')}
value={
field.value ? new Date(field.value).toISOString().slice(0, 16) : ''
}
min={Number(
startTime
? new Date(startTime).toISOString().slice(0, 16)
: new Date().toISOString().slice(0, 16),
)}
disabled={!startTime}
onValueChange={(value) => {
const timestamp = value ? new Date(value).getTime() : 0;
if (!startTime || timestamp < startTime) return;
form.setValue(field.name, timestamp);
}}
/>
</FormControl>
<FormMessage />
</FormItem>
);
}}
/>
</form>
</Form>
</ScrollArea>
<SheetFooter className='flex-row justify-end gap-2 pt-3'>
<Button
variant='outline'
disabled={loading}
onClick={() => {
setOpen(false);
}}
>
{t('form.cancel')}
</Button>
<Button disabled={loading} onClick={form.handleSubmit(handleSubmit)}>
{loading && <Icon icon='mdi:loading' className='mr-2 animate-spin' />}
{t('form.confirm')}
</Button>
</SheetFooter>
</SheetContent>
</Sheet>
);
}
+162
View File
@@ -0,0 +1,162 @@
'use client';
import { ProTable, ProTableActions } from '@/components/pro-table';
import { createAds, deleteAds, getAdsList, updateAds } from '@/services/admin/ads';
import { Badge } from '@workspace/ui/components/badge';
import { Button } from '@workspace/ui/components/button';
import { Switch } from '@workspace/ui/components/switch';
import { ConfirmButton } from '@workspace/ui/custom-components/confirm-button';
import { formatDate } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl';
import { useRef, useState } from 'react';
import { toast } from 'sonner';
import AdsForm from './ads-form';
export default function Page() {
const t = useTranslations('ads');
const [loading, setLoading] = useState(false);
const ref = useRef<ProTableActions>(null);
return (
<ProTable<API.Ads, Record<string, unknown>>
action={ref}
header={{
toolbar: (
<AdsForm<API.CreateAdsRequest>
trigger={t('create')}
title={t('createAds')}
loading={loading}
onSubmit={async (values) => {
setLoading(true);
try {
await createAds({
...values,
status: 0,
});
toast.success(t('createSuccess'));
ref.current?.refresh();
setLoading(false);
return true;
} catch (error) {
setLoading(false);
return false;
}
}}
/>
),
}}
params={[
{
key: 'search',
},
{
key: 'status',
placeholder: t('status'),
options: [
{ label: t('enabled'), value: '1' },
{ label: t('disabled'), value: '0' },
],
},
]}
request={async (pagination, filters) => {
const { data } = await getAdsList({
...pagination,
...filters,
});
return {
list: data.data?.list || [],
total: data.data?.total || 0,
};
}}
columns={[
{
accessorKey: 'status',
header: t('status'),
cell: ({ row }) => {
return (
<Switch
defaultChecked={row.getValue('status') === 1}
onCheckedChange={async (checked) => {
await updateAds({
...row.original,
status: checked ? 1 : 0,
});
ref.current?.refresh();
}}
/>
);
},
},
{
accessorKey: 'title',
header: t('title'),
},
{
accessorKey: 'type',
header: t('type'),
cell: ({ row }) => {
const type = row.original.type;
return <Badge>{type}</Badge>;
},
},
{
accessorKey: 'target_url',
header: t('targetUrl'),
},
{
accessorKey: 'description',
header: t('form.description'),
},
{
accessorKey: 'period',
header: t('validityPeriod'),
cell: ({ row }) => {
const { start_time, end_time } = row.original;
return (
<>
{formatDate(start_time)} - {formatDate(end_time)}
</>
);
},
},
]}
actions={{
render: (row) => [
<AdsForm<API.UpdateAdsRequest>
key='edit'
trigger={t('edit')}
title={t('editAds')}
loading={loading}
initialValues={row}
onSubmit={async (values) => {
setLoading(true);
try {
await updateAds({ ...row, ...values });
toast.success(t('updateSuccess'));
ref.current?.refresh();
setLoading(false);
return true;
} catch (error) {
setLoading(false);
return false;
}
}}
/>,
<ConfirmButton
key='delete'
trigger={<Button variant='destructive'>{t('delete')}</Button>}
title={t('confirmDelete')}
description={t('deleteWarning')}
onConfirm={async () => {
await deleteAds({ id: row.id });
toast.success(t('deleteSuccess'));
ref.current?.refresh();
}}
cancelText={t('cancel')}
confirmText={t('confirm')}
/>,
],
}}
/>
);
}
@@ -5,7 +5,10 @@ import { useQuery } from '@tanstack/react-query';
import { Label } from '@workspace/ui/components/label'; import { Label } from '@workspace/ui/components/label';
import { Switch } from '@workspace/ui/components/switch'; import { Switch } from '@workspace/ui/components/switch';
import { Table, TableBody, TableCell, TableRow } from '@workspace/ui/components/table'; import { Table, TableBody, TableCell, TableRow } from '@workspace/ui/components/table';
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
import { DicesIcon } from 'lucide-react';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { uid } from 'radash';
import { toast } from 'sonner'; import { toast } from 'sonner';
export default function Page() { export default function Page() {
@@ -49,6 +52,89 @@ export default function Page() {
/> />
</TableCell> </TableCell>
</TableRow> </TableRow>
<TableRow>
<TableCell>
<Label>{t('showAds')}</Label>
<p className='text-muted-foreground text-xs'>{t('showAdsDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<Switch
checked={data?.config?.show_ads}
onCheckedChange={(checked) => {
updateConfig('config', {
...data?.config,
show_ads: checked,
});
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('blockVirtualMachine')}</Label>
<p className='text-muted-foreground text-xs'>{t('blockVirtualMachineDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<Switch
checked={data?.config?.only_real_device}
onCheckedChange={(checked) => {
updateConfig('config', {
...data?.config,
only_real_device: checked,
});
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('enableSecurity')}</Label>
<p className='text-muted-foreground text-xs'>{t('enableSecurityDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<Switch
checked={data?.config?.enable_security}
onCheckedChange={(checked) => {
updateConfig('config', {
...data?.config,
enable_security: checked,
});
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('communicationKey')}</Label>
<p className='text-muted-foreground text-xs'>{t('communicationKeyDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
value={data?.config?.security_secret}
onValueBlur={(value) => {
updateConfig('config', {
...data?.config,
security_secret: value,
});
}}
suffix={
<div className='bg-muted flex h-9 items-center text-nowrap px-3'>
<DicesIcon
onClick={() => {
const id = uid(32).toLowerCase();
const formatted = `${id.slice(0, 8)}-${id.slice(8, 12)}-${id.slice(12, 16)}-${id.slice(16, 20)}-${id.slice(20)}`;
updateConfig('config', {
...data?.config,
security_secret: formatted,
});
}}
className='cursor-pointer'
/>
</div>
}
/>
</TableCell>
</TableRow>
</TableBody> </TableBody>
</Table> </Table>
); );
+1 -1
View File
@@ -116,7 +116,7 @@ export default function Page(props: any) {
<ul className='grid gap-3'> <ul className='grid gap-3'>
<li className='flex items-center justify-between'> <li className='flex items-center justify-between'>
<span className='text-muted-foreground'>{t('method')}</span> <span className='text-muted-foreground'>{t('method')}</span>
<span>{t(`methods.${row.original.method}`)}</span> <span>{row.original?.payment?.name || row.original?.payment?.platform}</span>
</li> </li>
</ul> </ul>
</HoverCardContent> </HoverCardContent>
@@ -1,256 +0,0 @@
'use client';
import { getAlipayF2FPaymentConfig, updateAlipayF2FPaymentConfig } from '@/services/admin/payment';
import { useQuery } from '@tanstack/react-query';
import { Label } from '@workspace/ui/components/label';
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from '@workspace/ui/components/select';
import { Switch } from '@workspace/ui/components/switch';
import { Table, TableBody, TableCell, TableRow } from '@workspace/ui/components/table';
import { Textarea } from '@workspace/ui/components/textarea';
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
import { unitConversion } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl';
import { toast } from 'sonner';
export default function AlipayF2F() {
const t = useTranslations('payment');
const { data, refetch } = useQuery({
queryKey: ['getAlipayF2FPaymentConfig'],
queryFn: async () => {
const { data } = await getAlipayF2FPaymentConfig();
return data.data;
},
});
async function updateConfig(key: string, value: unknown) {
if (data?.[key] === value) return;
try {
await updateAlipayF2FPaymentConfig({
...data,
[key]: value,
} as API.UpdateAlipayF2fRequest);
toast.success(t('saveSuccess'));
refetch();
} catch (error) {
/* empty */
}
}
return (
<Table>
<TableBody>
<TableRow>
<TableCell>
<Label>{t('enable')}</Label>
<p className='text-muted-foreground text-xs'>{t('enableDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<Switch
checked={data?.enable}
onCheckedChange={(checked) => {
updateConfig('enable', checked);
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('alipayf2f.sandbox')}</Label>
<p className='text-muted-foreground text-xs'>{t('alipayf2f.sandboxDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<Switch
checked={data?.config.sandbox}
onCheckedChange={(checked) => {
updateConfig('config', {
...data?.config,
sandbox: checked,
});
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('showName')}</Label>
<p className='text-muted-foreground text-xs'>{t('showNameDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.name}
onValueBlur={(value) => updateConfig('name', value)}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('iconUrl')}</Label>
<p className='text-muted-foreground text-xs'>{t('iconUrlDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.icon_url}
onValueBlur={(value) => updateConfig('icon', value)}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('notifyUrl')}</Label>
<p className='text-muted-foreground text-xs'>{t('notifyUrlDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.domain}
onValueBlur={(value) => updateConfig('domain', value)}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('feeMode')}</Label>
<p className='text-muted-foreground text-xs'>{t('feeModeDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<Select
value={String(data?.fee_mode)}
onValueChange={(value) => {
updateConfig('fee_mode', Number(value));
}}
>
<SelectTrigger>
<SelectValue placeholder='请选择' />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value='0'>{t('feeModeItems.0')}</SelectItem>
<SelectItem value='1'>{t('feeModeItems.1')}</SelectItem>
<SelectItem value='2'>{t('feeModeItems.2')}</SelectItem>
<SelectItem value='3'>{t('feeModeItems.3')}</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('feePercent')}</Label>
<p className='text-muted-foreground text-xs'>{t('feePercentDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
type='number'
min={0}
max={100}
maxLength={3}
value={data?.fee_percent}
onValueBlur={(value) => updateConfig('fee_percent', value)}
suffix='%'
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('fixedFee')}</Label>
<p className='text-muted-foreground text-xs'>{t('fixedFeeDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
min={0}
value={data?.fee_amount}
formatInput={(value) => unitConversion('centsToDollars', value)}
formatOutput={(value) => unitConversion('dollarsToCents', value)}
onValueBlur={(value) => updateConfig('fee_amount', value)}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('alipayf2f.appId')}</Label>
<p className='text-muted-foreground text-xs' />
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.config.app_id}
onValueBlur={(value) =>
updateConfig('config', {
...data?.config,
app_id: value,
})
}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('alipayf2f.privateKey')}</Label>
<p className='text-muted-foreground text-xs' />
</TableCell>
<TableCell className='text-right'>
<Textarea
placeholder={t('inputPlaceholder')}
defaultValue={data?.config.private_key}
onBlur={(e) => {
updateConfig('config', {
...data?.config,
private_key: e.target.value,
});
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('alipayf2f.publicKey')}</Label>
<p className='text-muted-foreground text-xs' />
</TableCell>
<TableCell className='text-right'>
<Textarea
placeholder={t('inputPlaceholder')}
defaultValue={data?.config.public_key}
onBlur={(e) => {
updateConfig('config', {
...data?.config,
public_key: e.target.value,
});
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('alipayf2f.invoiceName')}</Label>
<p className='text-muted-foreground text-xs' />
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('alipayf2f.invoiceNameDescription')}
value={data?.config.invoice_name}
onValueBlur={(value) =>
updateConfig('config', {
...data?.config,
invoice_name: value,
})
}
/>
</TableCell>
</TableRow>
</TableBody>
</Table>
);
}
-221
View File
@@ -1,221 +0,0 @@
'use client';
import { getEpayPaymentConfig, updateEpayPaymentConfig } from '@/services/admin/payment';
import { useQuery } from '@tanstack/react-query';
import { Label } from '@workspace/ui/components/label';
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from '@workspace/ui/components/select';
import { Switch } from '@workspace/ui/components/switch';
import { Table, TableBody, TableCell, TableRow } from '@workspace/ui/components/table';
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
import { unitConversion } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl';
import { toast } from 'sonner';
export default function Epay() {
const t = useTranslations('payment');
const { data, refetch } = useQuery({
queryKey: ['getEpayPaymentConfig'],
queryFn: async () => {
const { data } = await getEpayPaymentConfig();
return data.data;
},
});
async function updateConfig(key: string, value: unknown) {
if (data?.[key] === value) return;
try {
await updateEpayPaymentConfig({
...data,
[key]: value,
} as API.UpdateEpayRequest);
toast.success(t('saveSuccess'));
refetch();
} catch (error) {
/* empty */
}
}
return (
<Table>
<TableBody>
<TableRow>
<TableCell>
<Label>{t('enable')}</Label>
<p className='text-muted-foreground text-xs'>{t('enableDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<Switch
checked={data?.enable}
onCheckedChange={(checked) => {
updateConfig('enable', checked);
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('showName')}</Label>
<p className='text-muted-foreground text-xs'>{t('showNameDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.name}
onValueBlur={(value) => updateConfig('name', value)}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('iconUrl')}</Label>
<p className='text-muted-foreground text-xs'>{t('iconUrlDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.icon}
onValueBlur={(value) => updateConfig('icon', value)}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('notifyUrl')}</Label>
<p className='text-muted-foreground text-xs'>{t('notifyUrlDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.domain}
onValueBlur={(value) => updateConfig('domain', value)}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('feeMode')}</Label>
<p className='text-muted-foreground text-xs'>{t('feeModeDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<Select
value={String(data?.fee_mode)}
onValueChange={(value) => {
updateConfig('fee_mode', Number(value));
}}
>
<SelectTrigger>
<SelectValue placeholder='请选择' />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value='0'>{t('feeModeItems.0')}</SelectItem>
<SelectItem value='1'>{t('feeModeItems.1')}</SelectItem>
<SelectItem value='2'>{t('feeModeItems.2')}</SelectItem>
<SelectItem value='3'>{t('feeModeItems.3')}</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('feePercent')}</Label>
<p className='text-muted-foreground text-xs'>{t('feePercentDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
type='number'
min={0}
max={100}
maxLength={3}
value={data?.fee_percent}
onValueBlur={(value) => updateConfig('fee_percent', value)}
suffix='%'
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('fixedFee')}</Label>
<p className='text-muted-foreground text-xs'>{t('fixedFeeDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
type='number'
min={0}
value={data?.fee_amount}
formatInput={(value) => unitConversion('centsToDollars', value)}
formatOutput={(value) => unitConversion('dollarsToCents', value)}
onValueBlur={(value) => updateConfig('fee_amount', value)}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('epay.url')}</Label>
<p className='text-muted-foreground text-xs' />
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.config.url}
onValueBlur={(value) =>
updateConfig('config', {
...data?.config,
url: value,
})
}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('epay.pid')}</Label>
<p className='text-muted-foreground text-xs' />
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.config.pid}
onValueBlur={(value) =>
updateConfig('config', {
...data?.config,
pid: value,
})
}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('epay.key')}</Label>
<p className='text-muted-foreground text-xs' />
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.config.key}
onValueBlur={(value) =>
updateConfig('config', {
...data?.config,
key: value,
})
}
/>
</TableCell>
</TableRow>
</TableBody>
</Table>
);
}
+3 -26
View File
@@ -1,34 +1,11 @@
import Billing from '@/components/billing'; import Billing from '@/components/billing';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@workspace/ui/components/tabs'; import PaymentTable from './payment-table';
import AlipayF2F from './alipayf2f';
import Epay from './epay';
import StripeAlipay from './stripe-alipay';
import StripeWeChatPay from './stripe-wechat-pay';
export default async function Page() { export default async function Page() {
return ( return (
<> <>
<Tabs defaultValue='Epay'> <PaymentTable />
<TabsList className='h-full flex-wrap'> <div className='mt-5 flex flex-col gap-3'>
<TabsTrigger value='Epay'>Epay</TabsTrigger>
<TabsTrigger value='Stripe-Alipay'>Stripe(AliPay)</TabsTrigger>
<TabsTrigger value='Strip-WeChatPay'>Stripe(WeChatPay)</TabsTrigger>
<TabsTrigger value='AlipayF2F'>AlipayF2F</TabsTrigger>
</TabsList>
<TabsContent value='Epay'>
<Epay />
</TabsContent>
<TabsContent value='Stripe-Alipay'>
<StripeAlipay />
</TabsContent>
<TabsContent value='Strip-WeChatPay'>
<StripeWeChatPay />
</TabsContent>
<TabsContent value='AlipayF2F'>
<AlipayF2F />
</TabsContent>
</Tabs>
<div className='flex flex-col gap-3'>
<Billing type='payment' /> <Billing type='payment' />
</div> </div>
</> </>
@@ -0,0 +1,415 @@
'use client';
import useGlobalStore from '@/config/use-global';
import { getPaymentPlatform } from '@/services/admin/payment';
import { zodResolver } from '@hookform/resolvers/zod';
import { useQuery } from '@tanstack/react-query';
import { Button } from '@workspace/ui/components/button';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@workspace/ui/components/form';
import { RadioGroup, RadioGroupItem } from '@workspace/ui/components/radio-group';
import { ScrollArea } from '@workspace/ui/components/scroll-area';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@workspace/ui/components/select';
import {
Sheet,
SheetContent,
SheetFooter,
SheetHeader,
SheetTitle,
SheetTrigger,
} from '@workspace/ui/components/sheet';
import { MarkdownEditor } from '@workspace/ui/custom-components/editor';
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
import { Icon } from '@workspace/ui/custom-components/icon';
import { unitConversion } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl';
import { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import * as z from 'zod';
interface PaymentFormProps<T> {
trigger: React.ReactNode;
title: string;
loading?: boolean;
initialValues?: T;
onSubmit: (values: T) => Promise<boolean>;
}
export default function PaymentForm<T>({
trigger,
title,
loading,
initialValues,
onSubmit,
}: PaymentFormProps<T>) {
const t = useTranslations('payment');
const { common } = useGlobalStore();
const { currency } = common;
const [open, setOpen] = useState(false);
const { data: platformData } = useQuery({
queryKey: ['getPaymentPlatform'],
queryFn: async () => {
const { data } = await getPaymentPlatform();
return data?.data?.list || [];
},
});
const formSchema = z.object({
name: z.string().min(1, { message: t('nameRequired') }),
platform: z.string().optional(),
icon: z.string().optional(),
domain: z.string().optional(),
config: z.any(),
fee_mode: z.coerce.number().min(0).max(2),
fee_percent: z.coerce.number().optional(),
fee_amount: z.coerce.number().optional(),
description: z.string().optional(),
});
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
name: '',
platform: '',
icon: '',
domain: '',
config: {},
fee_mode: 0,
fee_percent: 0,
fee_amount: 0,
...(initialValues as any),
},
});
const feeMode = form.watch('fee_mode');
const platformValue = form.watch('platform');
const configValues = form.watch('config');
const currentPlatform = platformData?.find((p) => p.platform === platformValue);
const currentFieldDescriptions = currentPlatform?.platform_field_description || {};
const configFields = Object.keys(currentFieldDescriptions) || [];
const platformUrl = currentPlatform?.platform_url || '';
useEffect(() => {
if (feeMode === 0) {
form.setValue('fee_amount', 0);
form.setValue('fee_percent', 0);
} else if (feeMode === 1) {
form.setValue('fee_amount', 0);
} else if (feeMode === 2) {
form.setValue('fee_percent', 0);
}
}, [feeMode, form]);
const handleClose = () => {
form.reset();
setOpen(false);
};
const handleSubmit = async (values: z.infer<typeof formSchema>) => {
const cleanedValues = { ...values };
if (values.fee_mode === 0) {
cleanedValues.fee_amount = undefined;
cleanedValues.fee_percent = undefined;
} else if (values.fee_mode === 1) {
cleanedValues.fee_amount = undefined;
} else if (values.fee_mode === 2) {
cleanedValues.fee_percent = undefined;
}
const success = await onSubmit(cleanedValues as unknown as T);
if (success) {
handleClose();
}
};
const openPlatformUrl = () => {
if (platformUrl) {
window.open(platformUrl, '_blank');
}
};
return (
<Sheet open={open} onOpenChange={setOpen}>
<SheetTrigger asChild>{trigger}</SheetTrigger>
<SheetContent className='w-[550px] max-w-full md:max-w-screen-md'>
<SheetHeader>
<SheetTitle>{title}</SheetTitle>
</SheetHeader>
<ScrollArea className='-mx-6 h-[calc(100vh-48px-36px-36px-env(safe-area-inset-top))]'>
<Form {...form}>
<form onSubmit={form.handleSubmit(handleSubmit)} className='space-y-6 px-6 pt-4'>
{/* 基本信息分组 */}
<div className='space-y-4'>
<div className='grid grid-cols-1 gap-4 sm:grid-cols-2'>
<FormField
control={form.control}
name='name'
render={({ field }) => (
<FormItem>
<FormLabel>{t('name')}</FormLabel>
<FormControl>
<EnhancedInput
placeholder={t('namePlaceholder')}
value={field.value}
onValueChange={(value) => form.setValue('name', value as string)}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name='icon'
render={({ field }) => (
<FormItem>
<FormLabel>{t('icon')}</FormLabel>
<FormControl>
<EnhancedInput
placeholder={t('iconPlaceholder')}
value={field.value}
onValueChange={(value) => form.setValue('icon', value as string)}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<FormField
control={form.control}
name='domain'
render={({ field }) => (
<FormItem>
<FormLabel>{t('domain')}</FormLabel>
<FormControl>
<EnhancedInput
placeholder={t('domainPlaceholder', { example: 'http(s)://example.com' })}
value={field.value}
onValueChange={(value) => form.setValue('domain', value as string)}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<div className='space-y-4'>
<FormField
control={form.control}
name='fee_mode'
render={({ field }) => (
<FormItem>
<FormLabel>{t('handlingFee')}</FormLabel>
<FormControl>
<RadioGroup
onValueChange={(value) => field.onChange(parseInt(value))}
value={field.value.toString()}
className='flex flex-wrap gap-4'
>
<FormItem className='flex items-center space-x-2'>
<FormControl>
<RadioGroupItem value='0' />
</FormControl>
<FormLabel className='!mt-0 cursor-pointer'>{t('noFee')}</FormLabel>
</FormItem>
<FormItem className='flex items-center space-x-2'>
<FormControl>
<RadioGroupItem value='1' />
</FormControl>
<FormLabel className='!mt-0 cursor-pointer'>
{t('percentFee')}
</FormLabel>
</FormItem>
<FormItem className='flex items-center space-x-2'>
<FormControl>
<RadioGroupItem value='2' />
</FormControl>
<FormLabel className='!mt-0 cursor-pointer'>{t('fixedFee')}</FormLabel>
</FormItem>
</RadioGroup>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{feeMode === 1 && (
<div className='grid grid-cols-1 sm:w-1/2'>
<FormField
control={form.control}
name='fee_percent'
render={({ field }) => (
<FormItem>
<FormLabel>{t('feePercent')}</FormLabel>
<FormControl>
<EnhancedInput
type='number'
step='0.01'
suffix='%'
value={field.value}
onValueChange={field.onChange}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
)}
{feeMode === 2 && (
<div className='grid grid-cols-1 sm:w-1/2'>
<FormField
control={form.control}
name='fee_amount'
render={({ field }) => (
<FormItem>
<FormLabel>{t('feeAmount')}</FormLabel>
<FormControl>
<EnhancedInput
type='number'
step='0.01'
prefix={currency.currency_symbol}
suffix={currency.currency_unit}
value={unitConversion('centsToDollars', field.value)}
onValueChange={(value) =>
field.onChange(unitConversion('dollarsToCents', value))
}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
)}
</div>
<div className='space-y-4'>
{(!platformValue || platformData?.find((p) => p.platform === platformValue)) && (
<FormField
control={form.control}
name='platform'
render={({ field }) => (
<FormItem>
<FormLabel>{t('platform')}</FormLabel>
<Select
onValueChange={(value) => {
form.setValue('platform', value as string);
form.setValue('config', {});
}}
defaultValue={field.value}
value={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue placeholder={t('selectPlatform')} />
</SelectTrigger>
</FormControl>
<SelectContent>
{platformData?.map((platform) => (
<SelectItem key={platform.platform} value={platform.platform}>
{platform.platform}
</SelectItem>
))}
</SelectContent>
</Select>
{platformUrl ? (
<div className='mt-1 flex justify-end'>
<Button
variant='ghost'
size='sm'
className='h-6 px-2 text-xs'
onClick={openPlatformUrl}
>
<Icon icon='tabler:external-link' className='mr-1 h-3 w-3' />
{t('applyForPayment')}
</Button>
</div>
) : (
<div className='mt-1 h-6'></div>
)}
<FormMessage />
</FormItem>
)}
/>
)}
{configFields.length > 0 && (
<div className='mt-4 space-y-4'>
{configFields.map((fieldKey) => (
<FormItem key={fieldKey}>
<FormLabel>{currentFieldDescriptions[fieldKey]}</FormLabel>
<FormControl>
<EnhancedInput
placeholder={t('configPlaceholder', {
field: currentFieldDescriptions[fieldKey],
})}
value={
configValues && configValues[fieldKey] !== undefined
? configValues[fieldKey]
: ''
}
onValueChange={(value) => {
const newConfig = { ...configValues };
newConfig[fieldKey] = value;
form.setValue('config', newConfig);
}}
/>
</FormControl>
</FormItem>
))}
</div>
)}
<FormField
control={form.control}
name='description'
render={({ field }) => (
<FormItem>
<FormLabel>{t('description')}</FormLabel>
<FormControl>
<MarkdownEditor
value={field.value}
onChange={(value) => form.setValue(field.name, value as string)}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</form>
</Form>
</ScrollArea>
<SheetFooter className='flex-row justify-end gap-2 pt-3'>
<Button variant='outline' disabled={loading} onClick={handleClose}>
{t('cancel')}
</Button>
<Button disabled={loading} onClick={form.handleSubmit(handleSubmit)}>
{loading && <Icon icon='mdi:loading' className='mr-2 animate-spin' />}
{t('submit')}
</Button>
</SheetFooter>
</SheetContent>
</Sheet>
);
}
@@ -0,0 +1,222 @@
'use client';
import { Display } from '@/components/display';
import { ProTable, ProTableActions } from '@/components/pro-table';
import {
createPaymentMethod,
deletePaymentMethod,
getPaymentMethodList,
updatePaymentMethod,
} from '@/services/admin/payment';
import { Avatar, AvatarFallback, AvatarImage } from '@workspace/ui/components/avatar';
import { Badge } from '@workspace/ui/components/badge';
import { Button } from '@workspace/ui/components/button';
import { Switch } from '@workspace/ui/components/switch';
import { ConfirmButton } from '@workspace/ui/custom-components/confirm-button';
import { useTranslations } from 'next-intl';
import { useRef, useState } from 'react';
import { toast } from 'sonner';
import PaymentForm from './payment-form';
export default function PaymentTable() {
const t = useTranslations('payment');
const [loading, setLoading] = useState(false);
const ref = useRef<ProTableActions>(null);
return (
<ProTable<API.PaymentConfig, { search: string }>
action={ref}
header={{
title: t('paymentManagement'),
toolbar: (
<PaymentForm<API.CreatePaymentMethodRequest>
trigger={<Button>{t('create')}</Button>}
title={t('createPayment')}
loading={loading}
onSubmit={async (values) => {
setLoading(true);
try {
await createPaymentMethod({
...values,
enable: false,
});
toast.success(t('createSuccess'));
ref.current?.refresh();
setLoading(false);
return true;
} catch (error) {
setLoading(false);
return false;
}
}}
/>
),
}}
columns={[
{
accessorKey: 'enable',
header: t('enable'),
cell: ({ row }) => {
return (
<Switch
checked={Boolean(row.getValue('enable'))}
onCheckedChange={async (checked) => {
await updatePaymentMethod({
...row.original,
enable: checked,
});
ref.current?.refresh();
}}
/>
);
},
},
{
accessorKey: 'icon',
header: t('icon'),
cell: ({ row }) => {
const icon = row.getValue('icon') as string;
return (
<Avatar className='h-8 w-8'>
{icon ? <AvatarImage src={icon} alt={row.getValue('name')} /> : null}
<AvatarFallback>
{(row.getValue('name') as string)?.charAt(0) || '?'}
</AvatarFallback>
</Avatar>
);
},
},
{
accessorKey: 'name',
header: t('name'),
},
{
accessorKey: 'platform',
header: t('platform'),
cell: ({ row }) => <Badge>{t(row.getValue('platform'))}</Badge>,
},
{
accessorKey: 'notify_url',
header: t('notify_url'),
},
{
accessorKey: 'fee',
header: t('handlingFee'),
cell: ({ row }) => {
const feeMode = row.original.fee_mode;
if (feeMode === 1) {
return <Badge>{row.original.fee_percent}%</Badge>;
} else if (feeMode === 2) {
return (
<Badge>
<Display value={row.original.fee_amount} type='currency' />
</Badge>
);
}
return '--';
},
},
]}
params={[
{
key: 'search',
placeholder: t('searchPlaceholder'),
},
]}
request={async (pagination, filter) => {
const { data } = await getPaymentMethodList({
...pagination,
...filter,
});
return {
list: data?.data?.list || [],
total: data?.data?.total || 0,
};
}}
actions={{
render: (row) => [
<PaymentForm<API.UpdatePaymentMethodRequest>
key='edit'
trigger={<Button>{t('edit')}</Button>}
title={t('editPayment')}
loading={loading}
initialValues={row}
onSubmit={async (values) => {
setLoading(true);
try {
await updatePaymentMethod({
...row,
...values,
});
toast.success(t('updateSuccess'));
ref.current?.refresh();
setLoading(false);
return true;
} catch (error) {
setLoading(false);
return false;
}
}}
/>,
<ConfirmButton
key='delete'
trigger={<Button variant='destructive'>{t('delete')}</Button>}
title={t('confirmDelete')}
description={t('deleteWarning')}
onConfirm={async () => {
await deletePaymentMethod({
id: row.id,
});
toast.success(t('deleteSuccess'));
ref.current?.refresh();
}}
cancelText={t('cancel')}
confirmText={t('confirm')}
/>,
<Button
key='copy'
variant='outline'
onClick={async () => {
setLoading(true);
try {
const { id, ...params } = row;
await createPaymentMethod({
...params,
enable: false,
});
toast.success(t('copySuccess'));
ref.current?.refresh();
setLoading(false);
return true;
} catch (error) {
setLoading(false);
return false;
}
}}
>
{t('copy')}
</Button>,
],
batchRender(rows) {
return [
<ConfirmButton
key='delete'
trigger={<Button variant='destructive'>{t('batchDelete')}</Button>}
title={t('confirmDelete')}
description={t('deleteWarning')}
onConfirm={async () => {
for (const row of rows) {
await deletePaymentMethod({ id: row.id });
}
toast.success(t('deleteSuccess'));
ref.current?.refresh();
}}
cancelText={t('cancel')}
confirmText={t('confirm')}
/>,
];
},
}}
/>
);
}
@@ -1,232 +0,0 @@
'use client';
import {
getStripeAlipayPaymentConfig,
updateStripeAlipayPaymentConfig,
} from '@/services/admin/payment';
import { useQuery } from '@tanstack/react-query';
import { Label } from '@workspace/ui/components/label';
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from '@workspace/ui/components/select';
import { Switch } from '@workspace/ui/components/switch';
import { Table, TableBody, TableCell, TableRow } from '@workspace/ui/components/table';
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
import { unitConversion } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl';
import { toast } from 'sonner';
export default function Stripe() {
const t = useTranslations('payment');
const { data, refetch } = useQuery({
queryKey: ['getStripeAlipayPaymentConfig'],
queryFn: async () => {
const { data } = await getStripeAlipayPaymentConfig();
return data.data;
},
});
async function updateConfig(key: string, value: unknown) {
if (data?.[key] === value) return;
try {
await updateStripeAlipayPaymentConfig({
...data,
mark: 'stripe_alipay',
[key]: value,
} as any);
toast.success(t('saveSuccess'));
refetch();
} catch (error) {
/* empty */
}
}
return (
<Table>
<TableBody>
<TableRow>
<TableCell>
<Label>{t('aliPay')}</Label>
<p className='text-muted-foreground text-xs'>{t('enableDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<Switch
checked={data?.enable}
onCheckedChange={async (checked) => {
updateConfig('enable', checked);
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('showName')}</Label>
<p className='text-muted-foreground text-xs'>{t('showNameDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.name}
onValueBlur={(value) => {
updateConfig('name', value);
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('iconUrl')}</Label>
<p className='text-muted-foreground text-xs'>{t('iconUrlDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.icon}
onValueBlur={(value) => {
updateConfig('icon', value);
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('notifyUrl')}</Label>
<p className='text-muted-foreground text-xs'>{t('notifyUrlDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.domain}
onValueBlur={(value) => {
updateConfig('domain', value);
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('feeMode')}</Label>
<p className='text-muted-foreground text-xs'>{t('feeModeDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<Select
value={String(data?.fee_mode)}
onValueChange={(value) => {
updateConfig('fee_mode', Number(value));
}}
>
<SelectTrigger>
<SelectValue placeholder='请选择' />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value='0'>{t('feeModeItems.0')}</SelectItem>
<SelectItem value='1'>{t('feeModeItems.1')}</SelectItem>
<SelectItem value='2'>{t('feeModeItems.2')}</SelectItem>
<SelectItem value='3'>{t('feeModeItems.3')}</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('feePercent')}</Label>
<p className='text-muted-foreground text-xs'>{t('feePercentDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
type='number'
min={0}
max={100}
value={data?.fee_percent}
onValueBlur={(value) => {
updateConfig('fee_percent', value);
}}
suffix='%'
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('fixedFee')}</Label>
<p className='text-muted-foreground text-xs'>{t('fixedFeeDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
type='number'
min={0}
value={data?.fee_amount}
formatInput={(value) => unitConversion('centsToDollars', value)}
formatOutput={(value) => unitConversion('dollarsToCents', value)}
onValueBlur={(value) => updateConfig('fee_amount', value)}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('stripe.publicKey')}</Label>
<p className='text-muted-foreground text-xs' />
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.config.public_key}
onValueBlur={(value) => {
updateConfig('config', {
...data?.config,
public_key: value,
});
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('stripe.secretKey')}</Label>
<p className='text-muted-foreground text-xs' />
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.config.secret_key}
onValueBlur={(value) => {
updateConfig('config', {
...data?.config,
secret_key: value,
});
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('stripe.webhookSecret')}</Label>
<p className='text-muted-foreground text-xs' />
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.config.webhook_secret}
onValueBlur={(value) => {
updateConfig('config', {
...data?.config,
webhook_secret: value,
});
}}
/>
</TableCell>
</TableRow>
</TableBody>
</Table>
);
}
@@ -1,232 +0,0 @@
'use client';
import {
getStripeWeChatPayPaymentConfig,
updateStripeWeChatPayPaymentConfig,
} from '@/services/admin/payment';
import { useQuery } from '@tanstack/react-query';
import { Label } from '@workspace/ui/components/label';
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from '@workspace/ui/components/select';
import { Switch } from '@workspace/ui/components/switch';
import { Table, TableBody, TableCell, TableRow } from '@workspace/ui/components/table';
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
import { unitConversion } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl';
import { toast } from 'sonner';
export default function StripeWeChatPay() {
const t = useTranslations('payment');
const { data, refetch } = useQuery({
queryKey: ['getStripeWeChatPayPaymentConfig'],
queryFn: async () => {
const { data } = await getStripeWeChatPayPaymentConfig();
return data.data;
},
});
async function updateConfig(key: string, value: unknown) {
if (data?.[key] === value) return;
try {
await updateStripeWeChatPayPaymentConfig({
...data,
mark: 'stripe_wechat_pay',
[key]: value,
} as any);
toast.success(t('saveSuccess'));
refetch();
} catch (error) {
/* empty */
}
}
return (
<Table>
<TableBody>
<TableRow>
<TableCell>
<Label>{t('wechatPay')}</Label>
<p className='text-muted-foreground text-xs'>{t('enableDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<Switch
checked={data?.enable}
onCheckedChange={async (checked) => {
updateConfig('enable', checked);
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('showName')}</Label>
<p className='text-muted-foreground text-xs'>{t('showNameDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.name}
onValueBlur={(value) => {
updateConfig('name', value);
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('iconUrl')}</Label>
<p className='text-muted-foreground text-xs'>{t('iconUrlDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.icon}
onValueBlur={(value) => {
updateConfig('icon', value);
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('notifyUrl')}</Label>
<p className='text-muted-foreground text-xs'>{t('notifyUrlDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.domain}
onValueBlur={(value) => {
updateConfig('domain', value);
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('feeMode')}</Label>
<p className='text-muted-foreground text-xs'>{t('feeModeDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<Select
value={String(data?.fee_mode)}
onValueChange={(value) => {
updateConfig('fee_mode', Number(value));
}}
>
<SelectTrigger>
<SelectValue placeholder='请选择' />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value='0'>{t('feeModeItems.0')}</SelectItem>
<SelectItem value='1'>{t('feeModeItems.1')}</SelectItem>
<SelectItem value='2'>{t('feeModeItems.2')}</SelectItem>
<SelectItem value='3'>{t('feeModeItems.3')}</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('feePercent')}</Label>
<p className='text-muted-foreground text-xs'>{t('feePercentDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
type='number'
min={0}
max={100}
value={data?.fee_percent}
onValueBlur={(value) => {
updateConfig('fee_percent', value);
}}
suffix='%'
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('fixedFee')}</Label>
<p className='text-muted-foreground text-xs'>{t('fixedFeeDescription')}</p>
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
type='number'
min={0}
value={data?.fee_amount}
formatInput={(value) => unitConversion('centsToDollars', value)}
formatOutput={(value) => unitConversion('dollarsToCents', value)}
onValueBlur={(value) => updateConfig('fee_amount', value)}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('stripe.publicKey')}</Label>
<p className='text-muted-foreground text-xs' />
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.config.public_key}
onValueBlur={(value) => {
updateConfig('config', {
...data?.config,
public_key: value,
});
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('stripe.secretKey')}</Label>
<p className='text-muted-foreground text-xs' />
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.config.secret_key}
onValueBlur={(value) => {
updateConfig('config', {
...data?.config,
secret_key: value,
});
}}
/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Label>{t('stripe.webhookSecret')}</Label>
<p className='text-muted-foreground text-xs' />
</TableCell>
<TableCell className='text-right'>
<EnhancedInput
placeholder={t('inputPlaceholder')}
value={data?.config.webhook_secret}
onValueBlur={(value) => {
updateConfig('config', {
...data?.config,
webhook_secret: value,
});
}}
/>
</TableCell>
</TableRow>
</TableBody>
</Table>
);
}
@@ -113,6 +113,7 @@ export function BasicInfoForm({ user, refetch }: { user: API.User; refetch: () =
<FormControl> <FormControl>
<EnhancedInput <EnhancedInput
type='number' type='number'
min={0}
value={field.value} value={field.value}
prefix={currency?.currency_symbol ?? '$'} prefix={currency?.currency_symbol ?? '$'}
formatInput={(value) => unitConversion('centsToDollars', value)} formatInput={(value) => unitConversion('centsToDollars', value)}
@@ -136,6 +137,7 @@ export function BasicInfoForm({ user, refetch }: { user: API.User; refetch: () =
<FormControl> <FormControl>
<EnhancedInput <EnhancedInput
type='number' type='number'
min={0}
value={field.value} value={field.value}
prefix={currency?.currency_symbol ?? '$'} prefix={currency?.currency_symbol ?? '$'}
formatInput={(value) => unitConversion('centsToDollars', value)} formatInput={(value) => unitConversion('centsToDollars', value)}
@@ -159,6 +161,7 @@ export function BasicInfoForm({ user, refetch }: { user: API.User; refetch: () =
<FormControl> <FormControl>
<EnhancedInput <EnhancedInput
type='number' type='number'
min={0}
value={field.value} value={field.value}
prefix={currency?.currency_symbol ?? '$'} prefix={currency?.currency_symbol ?? '$'}
formatInput={(value) => unitConversion('centsToDollars', value)} formatInput={(value) => unitConversion('centsToDollars', value)}
@@ -57,150 +57,154 @@ export function SubscriptionDetail({
{t('onlineDevices')} {t('onlineDevices')}
</TabsTrigger> </TabsTrigger>
</TabsList> </TabsList>
<TabsContent value='logs'> <div className='mt-4 max-h-[60dvh] overflow-y-auto'>
<ProTable<API.UserSubscribeLog, Record<string, unknown>> <TabsContent value='logs'>
columns={[ <ProTable<API.UserSubscribeLog, Record<string, unknown>>
{ columns={[
accessorKey: 'ip', {
header: 'IP', accessorKey: 'ip',
}, header: 'IP',
{ },
accessorKey: 'user_agent', {
header: t('userAgent'), accessorKey: 'user_agent',
}, header: t('userAgent'),
{ },
accessorKey: 'token', {
header: t('token'), accessorKey: 'token',
}, header: t('token'),
{ },
accessorKey: 'created_at', {
header: t('time'), accessorKey: 'created_at',
cell: ({ row }) => formatDate(row.getValue('created_at')), header: t('time'),
}, cell: ({ row }) => formatDate(row.getValue('created_at')),
]} },
request={async (pagination) => { ]}
const { data } = await getUserSubscribeLogs({ request={async (pagination) => {
user_id: userId, const { data } = await getUserSubscribeLogs({
subscribe_id: subscriptionId, user_id: userId,
...pagination, subscribe_id: subscriptionId,
}); ...pagination,
return { });
list: data.data?.list || [], return {
total: data.data?.total || 0, list: data.data?.list || [],
}; total: data.data?.total || 0,
}} };
/> }}
</TabsContent> />
<TabsContent value='traffic'> </TabsContent>
<ProTable<API.TrafficLog, Record<string, unknown>> <TabsContent value='traffic'>
columns={[ <ProTable<API.TrafficLog, Record<string, unknown>>
{ columns={[
accessorKey: 'download', {
header: t('download'), accessorKey: 'download',
cell: ({ row }) => <Display type='traffic' value={row.getValue('download')} />, header: t('download'),
}, cell: ({ row }) => (
{ <Display type='traffic' value={row.getValue('download')} />
accessorKey: 'upload', ),
header: t('upload'), },
cell: ({ row }) => <Display type='traffic' value={row.getValue('upload')} />, {
}, accessorKey: 'upload',
{ header: t('upload'),
accessorKey: 'timestamp', cell: ({ row }) => <Display type='traffic' value={row.getValue('upload')} />,
header: t('time'), },
cell: ({ row }) => formatDate(row.getValue('timestamp')), {
}, accessorKey: 'timestamp',
]} header: t('time'),
request={async (pagination) => { cell: ({ row }) => formatDate(row.getValue('timestamp')),
const { data } = await getUserSubscribeTrafficLogs({ },
user_id: userId, ]}
subscribe_id: subscriptionId, request={async (pagination) => {
...pagination, const { data } = await getUserSubscribeTrafficLogs({
}); user_id: userId,
return { subscribe_id: subscriptionId,
list: data.data?.list || [], ...pagination,
total: data.data?.total || 0, } as API.GetUserSubscribeTrafficLogsParams);
}; return {
}} list: data.data?.list || [],
/> total: data.data?.total || 0,
</TabsContent> };
<TabsContent value='devices'> }}
<ProTable<API.UserDevice, Record<string, unknown>> />
columns={[ </TabsContent>
{ <TabsContent value='devices'>
accessorKey: 'enabled', <ProTable<API.UserDevice, Record<string, unknown>>
header: t('enable'), columns={[
cell: ({ row }) => ( {
<Switch accessorKey: 'enabled',
checked={row.getValue('enabled')} header: t('enable'),
onChange={(checked) => { cell: ({ row }) => (
console.log('Switch:', checked); <Switch
}} checked={row.getValue('enabled')}
/> onChange={(checked) => {
), console.log('Switch:', checked);
}, }}
{ />
accessorKey: 'id', ),
header: 'ID', },
}, {
{ accessorKey: 'id',
accessorKey: 'identifier', header: 'ID',
header: 'IMEI', },
}, {
{ accessorKey: 'identifier',
accessorKey: 'user_agent', header: 'IMEI',
header: t('userAgent'), },
}, {
{ accessorKey: 'user_agent',
accessorKey: 'ip', header: t('userAgent'),
header: 'IP', },
}, {
{ accessorKey: 'ip',
accessorKey: 'online', header: 'IP',
header: t('loginStatus'), },
cell: ({ row }) => ( {
<Badge variant={row.getValue('online') ? 'default' : 'destructive'}> accessorKey: 'online',
{row.getValue('online') ? t('online') : t('offline')} header: t('loginStatus'),
</Badge> cell: ({ row }) => (
), <Badge variant={row.getValue('online') ? 'default' : 'destructive'}>
}, {row.getValue('online') ? t('online') : t('offline')}
{ </Badge>
accessorKey: 'updated_at', ),
header: t('lastSeen'), },
cell: ({ row }) => formatDate(row.getValue('updated_at')), {
}, accessorKey: 'updated_at',
]} header: t('lastSeen'),
request={async (pagination) => { cell: ({ row }) => formatDate(row.getValue('updated_at')),
const { data } = await getUserSubscribeDevices({ },
user_id: userId, ]}
subscribe_id: subscriptionId, request={async (pagination) => {
...pagination, const { data } = await getUserSubscribeDevices({
}); user_id: userId,
return { subscribe_id: subscriptionId,
list: data.data?.list || [], ...pagination,
total: data.data?.total || 0, });
}; return {
}} list: data.data?.list || [],
actions={{ total: data.data?.total || 0,
render: (row) => { };
if (!row.identifier) return []; }}
return [ actions={{
<ConfirmButton render: (row) => {
key='offline' if (!row.identifier) return [];
trigger={<Button variant='destructive'>{t('confirmOffline')}</Button>} return [
title={t('confirmOffline')} <ConfirmButton
description={t('kickOfflineConfirm', { ip: row.ip })} key='offline'
onConfirm={async () => { trigger={<Button variant='destructive'>{t('confirmOffline')}</Button>}
await kickOfflineByUserDevice({ id: row.id }); title={t('confirmOffline')}
toast.success(t('kickOfflineSuccess')); description={t('kickOfflineConfirm', { ip: row.ip })}
}} onConfirm={async () => {
cancelText={t('cancel')} await kickOfflineByUserDevice({ id: row.id });
confirmText={t('confirm')} toast.success(t('kickOfflineSuccess'));
/>, }}
]; cancelText={t('cancel')}
}, confirmText={t('confirm')}
}} />,
/> ];
</TabsContent> },
}}
/>
</TabsContent>
</div>
</Tabs> </Tabs>
</div> </div>
</DialogContent> </DialogContent>
+6 -1
View File
@@ -61,6 +61,11 @@ export const navs = [
icon: 'flat-color-icons:lock-portrait', icon: 'flat-color-icons:lock-portrait',
items: AuthControl, items: AuthControl,
}, },
{
title: 'ADS Config',
url: '/dashboard/ads',
icon: 'flat-color-icons:electrical-sensor',
},
{ {
title: 'Payment Config', title: 'Payment Config',
url: '/dashboard/payment', url: '/dashboard/payment',
@@ -115,7 +120,7 @@ export const navs = [
{ {
title: 'Announcement Management', title: 'Announcement Management',
url: '/dashboard/announcement', url: '/dashboard/announcement',
icon: 'flat-color-icons:news', icon: 'flat-color-icons:advertising',
}, },
{ {
title: 'Ticket Management', title: 'Ticket Management',
+1
View File
@@ -63,6 +63,7 @@ export const useGlobalStore = create<GlobalStore>((set) => ({
verify_code_interval: 60, verify_code_interval: 60,
}, },
oauth_methods: [], oauth_methods: [],
web_ad: false,
}, },
user: undefined, user: undefined,
setCommon: (common) => setCommon: (common) =>
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Zrušit",
"confirm": "Potvrdit",
"confirmDelete": "Potvrdit smazání",
"create": "Vytvořit inzerát",
"createAds": "Vytvořit reklamu",
"createSuccess": "Úspěšně vytvořeno",
"delete": "Smazat",
"deleteSuccess": "Úspěšně smazáno",
"deleteWarning": "Opravdu chcete smazat tento inzerát?",
"disabled": "Deaktivováno",
"edit": "Upravit",
"editAds": "Upravit reklamu",
"enabled": "Aktivováno",
"form": {
"cancel": "Zrušit",
"confirm": "Potvrdit",
"content": "Obsah",
"description": "Popis",
"endTime": "Čas ukončení",
"enterContent": "Prosím zadejte obsah inzerátu",
"enterDescription": "Prosím zadejte popis inzerátu",
"enterEndTime": "Prosím vyberte čas ukončení",
"enterStartTime": "Prosím vyberte čas zahájení",
"enterTargetUrl": "Prosím zadejte cílovou URL",
"enterTitle": "Prosím zadejte název inzerátu",
"startTime": "Čas zahájení",
"targetUrl": "Cílová URL",
"title": "Název",
"type": "Typ inzerátu",
"typeImage": "Obrázek",
"typeVideo": "Video"
},
"status": "Stav",
"targetUrl": "Cílová URL",
"title": "Název",
"type": "Typ",
"updateSuccess": "Úspěšně aktualizováno",
"validityPeriod": "Doba platnosti"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Blokovat virtuální stroj",
"blockVirtualMachineDescription": "Pokud je povoleno, zařízení nebudou moci běžet na virtuálních strojích nebo emulátorech",
"communicationKey": "Komunikační klíč",
"communicationKeyDescription": "Komunikační klíč se používá pro bezpečnou komunikaci mezi zařízeními a servery",
"enable": "Povolit", "enable": "Povolit",
"enableDescription": "Po povolení jsou podporovány různé identifikátory zařízení, jako jsou IMEI/IDFA/IDFV/AndroidID/Mac adresa pro přihlášení a registraci" "enableDescription": "Po povolení jsou podporovány různé identifikátory zařízení, jako jsou IMEI/IDFA/IDFV/AndroidID/Mac adresa pro přihlášení a registraci",
"enableSecurity": "Povolit šifrování komunikace",
"enableSecurityDescription": "Pokud je povoleno, komunikace mezi zařízeními a servery bude šifrována",
"saveFailed": "Uložení se nezdařilo",
"saveSuccess": "Uložení bylo úspěšné",
"showAds": "Zobrazit reklamy",
"showAdsDescription": "Pokud je povoleno, na zařízeních se budou zobrazovat reklamy"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "Konfigurace ADS",
"Announcement Management": "Správa oznámení", "Announcement Management": "Správa oznámení",
"Apple": "Apple ID", "Apple": "Apple ID",
"Auth Control": "Řízení ověřování", "Auth Control": "Řízení ověřování",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Platba Alipay", "AlipayF2F": "Alipay Osobně",
"alipayf2f": { "EPay": "EPay",
"appId": "ID aplikace Alipay", "Stripe": "Stripe",
"invoiceName": "Název vlastního produktu", "applyForPayment": "Žádat o platbu",
"invoiceNameDescription": "Bude zobrazeno na faktuře Alipay", "balance": "Zůstatek",
"privateKey": "Soukromý klíč Alipay", "batchDelete": "Hromadné smazání",
"publicKey": "Veřejný klíč Alipay", "cancel": "Zrušit",
"sandbox": "Režim sandbox", "config": "Nastavení",
"sandboxDescription": "Povolte režim sandbox pro testování plateb" "configInfo": "Informace o nastavení",
}, "configPlaceholder": "Vyplňte prosím poskytnutou konfiguraci {field}",
"confirm": "Potvrdit",
"confirmDelete": "Potvrdit smazání",
"copy": "Kopírovat",
"copySuccess": "Úspěšně zkopírováno",
"create": "Přidat platební metodu",
"createPayment": "Přidat platební metodu",
"createSuccess": "Úspěšně vytvořeno",
"delete": "Smazat",
"deleteSuccess": "Úspěšně smazáno",
"deleteWarning": "Opravdu chcete smazat tuto platební metodu? Tuto akci nelze vrátit zpět.",
"description": "Popis",
"descriptionPlaceholder": "Zadejte popis platební metody",
"domain": "Doména",
"domainPlaceholder": "volitelné, např. {example}",
"edit": "Upravit",
"editPayment": "Upravit platební metodu",
"enable": "Povolit", "enable": "Povolit",
"enableDescription": "Povolit tento způsob platby", "feeAmount": "Pevná částka",
"epay": {
"key": "KLÍČ",
"pid": "PID",
"url": "URL"
},
"feeMode": "Způsob účtování", "feeMode": "Způsob účtování",
"feeModeDescription": "Způsob účtování dodatečných poplatků",
"feeModeItems": ["Bez poplatku", "Procento", "Pevná částka", "Obojí výše uvedené"],
"feePercent": "Procentuální poplatek (volitelně)", "feePercent": "Procentuální poplatek (volitelně)",
"feePercentDescription": "Přidání poplatku k částce objednávky",
"fixedFee": "Pevný poplatek (volitelný)", "fixedFee": "Pevný poplatek (volitelný)",
"fixedFeeDescription": "Přidání pevného poplatku k částce objednávky", "handlingFee": "Poplatek za zpracování",
"iconUrl": "URL ikony (volitelné)", "icon": "Ikona",
"iconUrlDescription": "Používá se pro zobrazení na frontendu", "iconPlaceholder": "Zadejte URL ikony",
"inputPlaceholder": "Prosím zadejte", "mark": "Identifikátor",
"key": "KLÍČ", "markPlaceholder": "Zadejte identifikátor platební metody",
"notifyUrl": "Vlastní oznámení URL (volitelné)", "name": "Název",
"notifyUrlDescription": "Oznámení brány budou odeslána na tuto doménu", "namePlaceholder": "Zadejte název platební metody",
"payForRecommendations": "Zaplatit za doporučení", "nameRequired": "Název je povinný",
"pid": "PID", "noFee": "Žádný poplatek",
"saveSuccess": "Uložení bylo úspěšné", "notify_url": "URL pro oznámení",
"showName": "Zobrazit název", "paymentManagement": "Správa plateb",
"showNameDescription": "Používá se pro zobrazení na frontendu", "percentFee": "Procento",
"stripe": { "platform": "Platforma",
"publicKey": "VEŘEJNÝ KLÍČ", "searchPlaceholder": "Zadejte hledané výrazy",
"secretKey": "TAJNÝ KLÍČ", "selectPlatform": "Vyberte platformu",
"webhookSecret": "PODPIS WEBHOOK KLÍČE" "selectType": "Vyberte typ platby",
}, "submit": "Odeslat",
"url": "URL", "type": "Typ",
"wechatPay": "WeChat Pay" "updateSuccess": "Úspěšně aktualizováno"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Abbrechen",
"confirm": "Bestätigen",
"confirmDelete": "Löschen bestätigen",
"create": "Anzeige erstellen",
"createAds": "Anzeige erstellen",
"createSuccess": "Erfolgreich erstellt",
"delete": "Löschen",
"deleteSuccess": "Erfolgreich gelöscht",
"deleteWarning": "Sind Sie sicher, dass Sie diese Anzeige löschen möchten?",
"disabled": "Deaktiviert",
"edit": "Bearbeiten",
"editAds": "Anzeige bearbeiten",
"enabled": "Aktiviert",
"form": {
"cancel": "Abbrechen",
"confirm": "Bestätigen",
"content": "Inhalt",
"description": "Beschreibung",
"endTime": "Endzeit",
"enterContent": "Bitte geben Sie den Anzeigeninhalt ein",
"enterDescription": "Bitte geben Sie die Anzeigenbeschreibung ein",
"enterEndTime": "Bitte wählen Sie die Endzeit aus",
"enterStartTime": "Bitte wählen Sie die Startzeit aus",
"enterTargetUrl": "Bitte geben Sie die Ziel-URL ein",
"enterTitle": "Bitte geben Sie den Anzeigentitel ein",
"startTime": "Startzeit",
"targetUrl": "Ziel-URL",
"title": "Titel",
"type": "Anzeigentyp",
"typeImage": "Bild",
"typeVideo": "Video"
},
"status": "Status",
"targetUrl": "Ziel-URL",
"title": "Titel",
"type": "Typ",
"updateSuccess": "Erfolgreich aktualisiert",
"validityPeriod": "Gültigkeitsdauer"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Virtuelle Maschine blockieren",
"blockVirtualMachineDescription": "Wenn aktiviert, wird verhindert, dass Geräte auf virtuellen Maschinen oder Emulatoren ausgeführt werden.",
"communicationKey": "Kommunikationsschlüssel",
"communicationKeyDescription": "Der Kommunikationsschlüssel wird für die sichere Kommunikation zwischen Geräten und Servern verwendet.",
"enable": "Aktivieren", "enable": "Aktivieren",
"enableDescription": "Nach der Aktivierung werden mehrere Geräteidentifikatoren wie IMEI/IDFA/IDFV/AndroidID/Mac-Adresse für die Anmeldung und Registrierung unterstützt." "enableDescription": "Nach der Aktivierung werden mehrere Geräteidentifikatoren wie IMEI/IDFA/IDFV/AndroidID/Mac-Adresse für die Anmeldung und Registrierung unterstützt.",
"enableSecurity": "Kommunikationsverschlüsselung aktivieren",
"enableSecurityDescription": "Wenn aktiviert, wird die Kommunikation zwischen Geräten und Servern verschlüsselt.",
"saveFailed": "Speichern fehlgeschlagen",
"saveSuccess": "Speichern erfolgreich",
"showAds": "Werbung anzeigen",
"showAdsDescription": "Wenn aktiviert, werden auf den Geräten Anzeigen angezeigt."
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "ADS-Konfiguration",
"Announcement Management": "Ankündigungsverwaltung", "Announcement Management": "Ankündigungsverwaltung",
"Apple": "Apple-ID", "Apple": "Apple-ID",
"Auth Control": "Authentifizierungskontrolle", "Auth Control": "Authentifizierungskontrolle",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Alipay-Zahlung", "AlipayF2F": "Alipay Gesicht zu Gesicht",
"alipayf2f": { "EPay": "EPay",
"appId": "Alipay Anwendungs-ID", "Stripe": "Stripe",
"invoiceName": "Benutzerdefinierter Produktname", "applyForPayment": "Zahlung beantragen",
"invoiceNameDescription": "Wird in der Alipay-Rechnung angezeigt", "balance": "Guthaben",
"privateKey": "Alipay Privatschlüssel", "batchDelete": "Massenlöschung",
"publicKey": "Alipay Öffentlicher Schlüssel", "cancel": "Abbrechen",
"sandbox": "Sandbox-Modus", "config": "Konfiguration",
"sandboxDescription": "Aktivieren Sie den Sandbox-Modus, um Zahlungen zu testen" "configInfo": "Konfigurationsinformationen",
}, "configPlaceholder": "Bitte füllen Sie die bereitgestellte {field} Konfiguration aus",
"confirm": "Bestätigen",
"confirmDelete": "Löschen bestätigen",
"copy": "Kopieren",
"copySuccess": "Erfolgreich kopiert",
"create": "Zahlungsmethode hinzufügen",
"createPayment": "Zahlungsmethode hinzufügen",
"createSuccess": "Erfolgreich erstellt",
"delete": "Löschen",
"deleteSuccess": "Erfolgreich gelöscht",
"deleteWarning": "Sind Sie sicher, dass Sie diese Zahlungsmethode löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.",
"description": "Beschreibung",
"descriptionPlaceholder": "Geben Sie die Beschreibung der Zahlungsmethode ein",
"domain": "Domain",
"domainPlaceholder": "optional, z.B. {example}",
"edit": "Bearbeiten",
"editPayment": "Zahlungsmethode bearbeiten",
"enable": "Aktivieren", "enable": "Aktivieren",
"enableDescription": "Diese Zahlungsmethode aktivieren", "feeAmount": "Fester Betrag",
"epay": {
"key": "SCHLÜSSEL",
"pid": "PID",
"url": "URL"
},
"feeMode": "Gebührenmodus", "feeMode": "Gebührenmodus",
"feeModeDescription": "Gebührenmodus für zusätzliche Gebühren",
"feeModeItems": ["Keine Gebühr", "Prozentsatz", "Fester Betrag", "Beides"],
"feePercent": "Prozentgebühr (optional)", "feePercent": "Prozentgebühr (optional)",
"feePercentDescription": "Gebühren werden zusätzlich zum Bestellbetrag hinzugefügt",
"fixedFee": "Feste Gebühr (optional)", "fixedFee": "Feste Gebühr (optional)",
"fixedFeeDescription": "Feste Gebühr zusätzlich zum Bestellbetrag hinzufügen", "handlingFee": "Bearbeitungsgebühr",
"iconUrl": "Symbol-URL (optional)", "icon": "Symbol",
"iconUrlDescription": "Zur Anzeige im Frontend verwendet", "iconPlaceholder": "Geben Sie die URL des Symbols ein",
"inputPlaceholder": "Bitte eingeben", "mark": "Kennung",
"key": "SCHLÜSSEL", "markPlaceholder": "Geben Sie die Kennung der Zahlungsmethode ein",
"notifyUrl": "Benutzerdefinierte Benachrichtigungs-URL (optional)", "name": "Name",
"notifyUrlDescription": "Gateway-Benachrichtigungen werden an diese Domain gesendet", "namePlaceholder": "Geben Sie den Namen der Zahlungsmethode ein",
"payForRecommendations": "Für Empfehlungen bezahlen", "nameRequired": "Name ist erforderlich",
"pid": "PID", "noFee": "Keine Gebühr",
"saveSuccess": "Erfolgreich gespeichert", "notify_url": "Benachrichtigungs-URL",
"showName": "Anzeigename", "paymentManagement": "Zahlungsverwaltung",
"showNameDescription": "Zur Anzeige im Frontend verwendet", "percentFee": "Prozentsatz",
"stripe": { "platform": "Plattform",
"publicKey": "ÖFFENTLICHER SCHLÜSSEL", "searchPlaceholder": "Suchbegriffe eingeben",
"secretKey": "GEHEIMER SCHLÜSSEL", "selectPlatform": "Plattform auswählen",
"webhookSecret": "WEBHOOK-SCHLÜSSEL-SIGNATUR" "selectType": "Zahlungsart auswählen",
}, "submit": "Einreichen",
"url": "URL", "type": "Typ",
"wechatPay": "WeChat Pay" "updateSuccess": "Erfolgreich aktualisiert"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Cancel",
"confirm": "Confirm",
"confirmDelete": "Confirm Delete",
"create": "Create Ad",
"createAds": "Create Advertisement",
"createSuccess": "Successfully created",
"delete": "Delete",
"deleteSuccess": "Successfully deleted",
"deleteWarning": "Are you sure you want to delete this ad?",
"disabled": "Disabled",
"edit": "Edit",
"editAds": "Edit Advertisement",
"enabled": "Enabled",
"form": {
"cancel": "Cancel",
"confirm": "Confirm",
"content": "Content",
"description": "Description",
"endTime": "End Time",
"enterContent": "Please enter ad content",
"enterDescription": "Please enter ad description",
"enterEndTime": "Please select end time",
"enterStartTime": "Please select start time",
"enterTargetUrl": "Please enter target URL",
"enterTitle": "Please enter ad title",
"startTime": "Start Time",
"targetUrl": "Target URL",
"title": "Title",
"type": "Ad Type",
"typeImage": "Image",
"typeVideo": "Video"
},
"status": "Status",
"targetUrl": "Target URL",
"title": "Title",
"type": "Type",
"updateSuccess": "Successfully updated",
"validityPeriod": "Validity Period"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Block Virtual Machine",
"blockVirtualMachineDescription": "When enabled, devices will be prevented from running on virtual machines or emulators",
"communicationKey": "Communication Key",
"communicationKeyDescription": "Communication key is used for secure communication between devices and servers",
"enable": "Enable", "enable": "Enable",
"enableDescription": "After enabling, multiple device identifiers such as IMEI/IDFA/IDFV/AndroidID/Mac address are supported for login and registration" "enableDescription": "After enabling, multiple device identifiers such as IMEI/IDFA/IDFV/AndroidID/Mac address are supported for login and registration",
"enableSecurity": "Enable Communication Encryption",
"enableSecurityDescription": "When enabled, the communication between devices and servers will be encrypted",
"saveFailed": "Save failed",
"saveSuccess": "Save successful",
"showAds": "Show Advertisements",
"showAdsDescription": "When enabled, advertisements will be displayed on devices"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "ADS Config",
"Announcement Management": "Announcement Management", "Announcement Management": "Announcement Management",
"Apple": "Apple ID", "Apple": "Apple ID",
"Auth Control": "Auth Control", "Auth Control": "Auth Control",
+48 -40
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Alipay payment", "AlipayF2F": "Alipay Face to Face",
"alipayf2f": { "EPay": "EPay",
"appId": "Alipay App ID", "Stripe": "Stripe",
"invoiceName": "Custom Product Name", "applyForPayment": "Apply for Payment",
"invoiceNameDescription": "Will be displayed on Alipay bill", "balance": "Balance",
"privateKey": "Alipay Private Key", "batchDelete": "Batch Delete",
"publicKey": "Alipay Public Key", "cancel": "Cancel",
"sandbox": "Sandbox Mode", "config": "Configuration",
"sandboxDescription": "Enable sandbox mode to test payments" "configInfo": "Configuration Information",
}, "configPlaceholder": "Please fill in the provided {field} configuration",
"confirm": "Confirm",
"confirmDelete": "Confirm Delete",
"copy": "Copy",
"copySuccess": "Copied successfully",
"create": "Add Payment Method",
"createPayment": "Add Payment Method",
"createSuccess": "Created successfully",
"delete": "Delete",
"deleteSuccess": "Deleted successfully",
"deleteWarning": "Are you sure you want to delete this payment method? This action cannot be undone.",
"description": "Description",
"descriptionPlaceholder": "Enter payment method description",
"domain": "Domain",
"domainPlaceholder": "optional, e.g. {example}",
"edit": "Edit",
"editPayment": "Edit Payment Method",
"enable": "Enable", "enable": "Enable",
"enableDescription": "Enable this payment method", "feeAmount": "Fixed Amount",
"epay": {
"key": "KEY",
"pid": "PID",
"url": "URL"
},
"feeMode": "Fee Mode", "feeMode": "Fee Mode",
"feeModeDescription": "Fee charging method for additional fees", "feePercent": "Fee Percentage",
"feeModeItems": ["No Fee", "Percentage", "Fixed Amount", "Both"], "fixedFee": "Fixed Amount",
"feePercent": "Percentage Fee (optional)", "handlingFee": "Handling Fee",
"feePercentDescription": "Add fee on top of order amount", "icon": "Icon",
"fixedFee": "Fixed Fee (optional)", "iconPlaceholder": "Enter icon URL",
"fixedFeeDescription": "Add fixed fee on top of order amount", "mark": "Identifier",
"iconUrl": "Icon URL (optional)", "markPlaceholder": "Enter payment method identifier",
"iconUrlDescription": "Used for frontend display", "name": "Name",
"inputPlaceholder": "Please enter", "namePlaceholder": "Enter payment method name",
"key": "KEY", "nameRequired": "Name is required",
"notifyUrl": "Custom Notification Domain (optional)", "noFee": "No Fee",
"notifyUrlDescription": "Gateway notifications will be sent to this domain", "notify_url": "Notify URL",
"payForRecommendations": "Pay for Recommendations", "paymentManagement": "Payment Management",
"pid": "PID", "percentFee": "Percentage",
"saveSuccess": "Save Successful", "platform": "Platform",
"showName": "Display Name", "searchPlaceholder": "Enter search terms",
"showNameDescription": "Used for frontend display", "selectPlatform": "Select Platform",
"stripe": { "selectType": "Select payment type",
"publicKey": "PUBLIC KEY", "submit": "Submit",
"secretKey": "SECRET KEY", "type": "Type",
"webhookSecret": "WEBHOOK Secret Key" "updateSuccess": "Updated successfully"
},
"url": "URL",
"wechatPay": "WeChat Pay"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Cancelar",
"confirm": "Confirmar",
"confirmDelete": "Confirmar eliminación",
"create": "Crear anuncio",
"createAds": "Crear publicidad",
"createSuccess": "Creado con éxito",
"delete": "Eliminar",
"deleteSuccess": "Eliminado con éxito",
"deleteWarning": "¿Está seguro de que desea eliminar este anuncio?",
"disabled": "Deshabilitado",
"edit": "Editar",
"editAds": "Editar publicidad",
"enabled": "Habilitado",
"form": {
"cancel": "Cancelar",
"confirm": "Confirmar",
"content": "Contenido",
"description": "Descripción",
"endTime": "Hora de finalización",
"enterContent": "Por favor, introduzca el contenido del anuncio",
"enterDescription": "Por favor, introduzca la descripción del anuncio",
"enterEndTime": "Por favor, seleccione la hora de finalización",
"enterStartTime": "Por favor, seleccione la hora de inicio",
"enterTargetUrl": "Por favor, introduzca la URL de destino",
"enterTitle": "Por favor, introduzca el título del anuncio",
"startTime": "Hora de inicio",
"targetUrl": "URL de destino",
"title": "Título",
"type": "Tipo de anuncio",
"typeImage": "Imagen",
"typeVideo": "Vídeo"
},
"status": "Estado",
"targetUrl": "URL de destino",
"title": "Título",
"type": "Tipo",
"updateSuccess": "Actualizado con éxito",
"validityPeriod": "Período de validez"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Bloquear Máquina Virtual",
"blockVirtualMachineDescription": "Cuando está habilitado, se evitará que los dispositivos se ejecuten en máquinas virtuales o emuladores",
"communicationKey": "Clave de Comunicación",
"communicationKeyDescription": "La clave de comunicación se utiliza para la comunicación segura entre dispositivos y servidores",
"enable": "Habilitar", "enable": "Habilitar",
"enableDescription": "Después de habilitar, se admiten múltiples identificadores de dispositivos como IMEI/IDFA/IDFV/AndroidID/dirección MAC para el inicio de sesión y el registro" "enableDescription": "Después de habilitar, se admiten múltiples identificadores de dispositivos como IMEI/IDFA/IDFV/AndroidID/dirección MAC para el inicio de sesión y el registro",
"enableSecurity": "Habilitar Cifrado de Comunicación",
"enableSecurityDescription": "Cuando está habilitado, la comunicación entre dispositivos y servidores será cifrada",
"saveFailed": "Error al guardar",
"saveSuccess": "Guardado exitoso",
"showAds": "Mostrar Anuncios",
"showAdsDescription": "Cuando está habilitado, se mostrarán anuncios en los dispositivos"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "Configuración de ADS",
"Announcement Management": "Gestión de Anuncios", "Announcement Management": "Gestión de Anuncios",
"Apple": "ID de Apple", "Apple": "ID de Apple",
"Auth Control": "Control de Autenticación", "Auth Control": "Control de Autenticación",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Pago con Alipay", "AlipayF2F": "Alipay Cara a Cara",
"alipayf2f": { "EPay": "EPay",
"appId": "ID de la aplicación de Alipay", "Stripe": "Stripe",
"invoiceName": "Nombre personalizado del producto", "applyForPayment": "Solicitar Pago",
"invoiceNameDescription": "Se mostrará en la factura de Alipay", "balance": "Saldo",
"privateKey": "Clave privada de Alipay", "batchDelete": "Eliminar en Lote",
"publicKey": "Clave pública de Alipay", "cancel": "Cancelar",
"sandbox": "Modo sandbox", "config": "Configuración",
"sandboxDescription": "Habilitar el modo sandbox para probar el pago" "configInfo": "Información de Configuración",
}, "configPlaceholder": "Por favor, complete la configuración de {field} proporcionada",
"confirm": "Confirmar",
"confirmDelete": "Confirmar Eliminación",
"copy": "Copiar",
"copySuccess": "Copiado con éxito",
"create": "Agregar Método de Pago",
"createPayment": "Agregar Método de Pago",
"createSuccess": "Creado con éxito",
"delete": "Eliminar",
"deleteSuccess": "Eliminado con éxito",
"deleteWarning": "¿Está seguro de que desea eliminar este método de pago? Esta acción no se puede deshacer.",
"description": "Descripción",
"descriptionPlaceholder": "Ingrese la descripción del método de pago",
"domain": "Dominio",
"domainPlaceholder": "opcional, p. ej. {example}",
"edit": "Editar",
"editPayment": "Editar Método de Pago",
"enable": "Habilitar", "enable": "Habilitar",
"enableDescription": "Habilitar este método de pago", "feeAmount": "Monto Fijo",
"epay": {
"key": "CLAVE",
"pid": "PID",
"url": "URL"
},
"feeMode": "Modo de cobro", "feeMode": "Modo de cobro",
"feeModeDescription": "Modo de cobro de tarifas adicionales",
"feeModeItems": ["Sin tarifa", "Porcentaje", "Cantidad fija", "Ambos anteriores"],
"feePercent": "Porcentaje de tarifa (opcional)", "feePercent": "Porcentaje de tarifa (opcional)",
"feePercentDescription": "Se añade una tarifa sobre el monto del pedido",
"fixedFee": "Tarifa fija (opcional)", "fixedFee": "Tarifa fija (opcional)",
"fixedFeeDescription": "Se añade una tarifa fija sobre el monto del pedido", "handlingFee": "Tarifa de manejo",
"iconUrl": "URL del icono (opcional)", "icon": "Ícono",
"iconUrlDescription": "Usado para mostrar en el frontend", "iconPlaceholder": "Ingrese la URL del ícono",
"inputPlaceholder": "Por favor, introduzca", "mark": "Identificador",
"key": "CLAVE", "markPlaceholder": "Ingrese el identificador del método de pago",
"notifyUrl": "Dominio de notificación personalizado (opcional)", "name": "Nombre",
"notifyUrlDescription": "La notificación del gateway se enviará a este dominio", "namePlaceholder": "Ingrese el nombre del método de pago",
"payForRecommendations": "Pagar por recomendaciones", "nameRequired": "El nombre es obligatorio",
"pid": "PID", "noFee": "Sin Tarifa",
"saveSuccess": "Guardado exitosamente", "notify_url": "URL de notificación",
"showName": "Mostrar nombre", "paymentManagement": "Gestión de Pagos",
"showNameDescription": "Usado para mostrar en el frontend", "percentFee": "Porcentaje",
"stripe": { "platform": "Plataforma",
"publicKey": "CLAVE PÚBLICA", "searchPlaceholder": "Ingrese términos de búsqueda",
"secretKey": "CLAVE SECRETA", "selectPlatform": "Seleccionar Plataforma",
"webhookSecret": "FIRMA DE CLAVE WEBHOOK" "selectType": "Seleccionar tipo de pago",
}, "submit": "Enviar",
"url": "URL", "type": "Tipo",
"wechatPay": "Pago con WeChat" "updateSuccess": "Actualizado con éxito"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Cancelar",
"confirm": "Confirmar",
"confirmDelete": "Confirmar Eliminación",
"create": "Crear Anuncio",
"createAds": "Crear Publicidad",
"createSuccess": "Creado con éxito",
"delete": "Eliminar",
"deleteSuccess": "Eliminado con éxito",
"deleteWarning": "¿Está seguro de que desea eliminar este anuncio?",
"disabled": "Deshabilitado",
"edit": "Editar",
"editAds": "Editar Publicidad",
"enabled": "Habilitado",
"form": {
"cancel": "Cancelar",
"confirm": "Confirmar",
"content": "Contenido",
"description": "Descripción",
"endTime": "Hora de Finalización",
"enterContent": "Por favor ingrese el contenido del anuncio",
"enterDescription": "Por favor ingrese la descripción del anuncio",
"enterEndTime": "Por favor seleccione la hora de finalización",
"enterStartTime": "Por favor seleccione la hora de inicio",
"enterTargetUrl": "Por favor ingrese la URL de destino",
"enterTitle": "Por favor ingrese el título del anuncio",
"startTime": "Hora de Inicio",
"targetUrl": "URL de Destino",
"title": "Título",
"type": "Tipo de Anuncio",
"typeImage": "Imagen",
"typeVideo": "Video"
},
"status": "Estado",
"targetUrl": "URL de Destino",
"title": "Título",
"type": "Tipo",
"updateSuccess": "Actualizado con éxito",
"validityPeriod": "Período de Validez"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Bloquear Máquina Virtual",
"blockVirtualMachineDescription": "Cuando está habilitado, se evitará que los dispositivos se ejecuten en máquinas virtuales o emuladores",
"communicationKey": "Clave de Comunicación",
"communicationKeyDescription": "La clave de comunicación se utiliza para la comunicación segura entre dispositivos y servidores",
"enable": "Habilitar", "enable": "Habilitar",
"enableDescription": "Después de habilitar, se admiten múltiples identificadores de dispositivos como IMEI/IDFA/IDFV/AndroidID/dirección Mac para iniciar sesión y registrarse" "enableDescription": "Después de habilitar, se admiten múltiples identificadores de dispositivos como IMEI/IDFA/IDFV/AndroidID/dirección Mac para iniciar sesión y registrarse",
"enableSecurity": "Habilitar Cifrado de Comunicación",
"enableSecurityDescription": "Cuando está habilitado, la comunicación entre dispositivos y servidores será cifrada",
"saveFailed": "Error al guardar",
"saveSuccess": "Guardado exitoso",
"showAds": "Mostrar Anuncios",
"showAdsDescription": "Cuando está habilitado, se mostrarán anuncios en los dispositivos"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "Configuración de ADS",
"Announcement Management": "Gestión de Anuncios", "Announcement Management": "Gestión de Anuncios",
"Apple": "ID de Apple", "Apple": "ID de Apple",
"Auth Control": "Control de Autenticación", "Auth Control": "Control de Autenticación",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Pago con Alipay", "AlipayF2F": "Alipay Cara a Cara",
"alipayf2f": { "EPay": "EPay",
"appId": "ID de la aplicación de Alipay", "Stripe": "Stripe",
"invoiceName": "Nombre personalizado del producto", "applyForPayment": "Solicitar Pago",
"invoiceNameDescription": "Se mostrará en la factura de Alipay", "balance": "Saldo",
"privateKey": "Clave privada de Alipay", "batchDelete": "Eliminar en Lote",
"publicKey": "Clave pública de Alipay", "cancel": "Cancelar",
"sandbox": "Modo sandbox", "config": "Configuración",
"sandboxDescription": "Habilitar el modo sandbox para probar el pago" "configInfo": "Información de Configuración",
}, "configPlaceholder": "Por favor, complete la configuración de {field} proporcionada",
"confirm": "Confirmar",
"confirmDelete": "Confirmar Eliminación",
"copy": "Copiar",
"copySuccess": "Copiado con éxito",
"create": "Agregar Método de Pago",
"createPayment": "Agregar Método de Pago",
"createSuccess": "Creado con éxito",
"delete": "Eliminar",
"deleteSuccess": "Eliminado con éxito",
"deleteWarning": "¿Está seguro de que desea eliminar este método de pago? Esta acción no se puede deshacer.",
"description": "Descripción",
"descriptionPlaceholder": "Ingresa la descripción del método de pago",
"domain": "Dominio",
"domainPlaceholder": "opcional, p. ej. {example}",
"edit": "Editar",
"editPayment": "Editar Método de Pago",
"enable": "Habilitar", "enable": "Habilitar",
"enableDescription": "Habilitar este método de pago", "feeAmount": "Monto Fijo",
"epay": {
"key": "CLAVE",
"pid": "PID",
"url": "URL"
},
"feeMode": "Modo de cobro", "feeMode": "Modo de cobro",
"feeModeDescription": "Modo de cobro de tarifas adicionales",
"feeModeItems": ["Sin tarifa", "Porcentaje", "Cantidad fija", "Ambos"],
"feePercent": "Porcentaje de tarifa (opcional)", "feePercent": "Porcentaje de tarifa (opcional)",
"feePercentDescription": "Se añade una tarifa sobre el monto del pedido",
"fixedFee": "Cuota fija (opcional)", "fixedFee": "Cuota fija (opcional)",
"fixedFeeDescription": "Agregar una tarifa fija sobre el monto del pedido", "handlingFee": "Cargo por manejo",
"iconUrl": "URL del ícono (opcional)", "icon": "Ícono",
"iconUrlDescription": "Usado para mostrar en el frontend", "iconPlaceholder": "Ingrese la URL del ícono",
"inputPlaceholder": "Por favor ingrese", "mark": "Identificador",
"key": "LLAVE", "markPlaceholder": "Ingrese el identificador del método de pago",
"notifyUrl": "Dominio de notificación personalizado (opcional)", "name": "Nombre",
"notifyUrlDescription": "La notificación del gateway se enviará a este dominio", "namePlaceholder": "Ingrese el nombre del método de pago",
"payForRecommendations": "Pagar por recomendaciones", "nameRequired": "El nombre es obligatorio",
"pid": "PID", "noFee": "Sin Tarifa",
"saveSuccess": "Guardado exitoso", "notify_url": "URL de notificación",
"showName": "Mostrar nombre", "paymentManagement": "Gestión de Pagos",
"showNameDescription": "Usado para mostrar en el frontend", "percentFee": "Porcentaje",
"stripe": { "platform": "Plataforma",
"publicKey": "CLAVE PÚBLICA", "searchPlaceholder": "Ingrese términos de búsqueda",
"secretKey": "CLAVE SECRETA", "selectPlatform": "Seleccionar Plataforma",
"webhookSecret": "FIRMA DE SECRETO DE WEBHOOK" "selectType": "Seleccionar tipo de pago",
}, "submit": "Enviar",
"url": "URL", "type": "Tipo",
"wechatPay": "WeChat Pay" "updateSuccess": "Actualizado con éxito"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "لغو",
"confirm": "تأیید",
"confirmDelete": "تأیید حذف",
"create": "ایجاد آگهی",
"createAds": "ایجاد تبلیغ",
"createSuccess": "با موفقیت ایجاد شد",
"delete": "حذف",
"deleteSuccess": "با موفقیت حذف شد",
"deleteWarning": "آیا مطمئن هستید که می‌خواهید این آگهی را حذف کنید؟",
"disabled": "غیرفعال",
"edit": "ویرایش",
"editAds": "ویرایش تبلیغ",
"enabled": "فعال",
"form": {
"cancel": "لغو",
"confirm": "تأیید",
"content": "محتوا",
"description": "توضیحات",
"endTime": "زمان پایان",
"enterContent": "لطفاً محتوای آگهی را وارد کنید",
"enterDescription": "لطفاً توضیحات آگهی را وارد کنید",
"enterEndTime": "لطفاً زمان پایان را انتخاب کنید",
"enterStartTime": "لطفاً زمان شروع را انتخاب کنید",
"enterTargetUrl": "لطفاً URL هدف را وارد کنید",
"enterTitle": "لطفاً عنوان آگهی را وارد کنید",
"startTime": "زمان شروع",
"targetUrl": "URL هدف",
"title": "عنوان",
"type": "نوع آگهی",
"typeImage": "تصویر",
"typeVideo": "ویدیو"
},
"status": "وضعیت",
"targetUrl": "URL هدف",
"title": "عنوان",
"type": "نوع",
"updateSuccess": "با موفقیت به‌روزرسانی شد",
"validityPeriod": "مدت اعتبار"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "مسدود کردن ماشین مجازی",
"blockVirtualMachineDescription": "هنگامی که فعال باشد، دستگاه‌ها از اجرای ماشین‌های مجازی یا شبیه‌سازها جلوگیری خواهند شد",
"communicationKey": "کلید ارتباطی",
"communicationKeyDescription": "کلید ارتباطی برای ارتباط امن بین دستگاه‌ها و سرورها استفاده می‌شود",
"enable": "فعال کردن", "enable": "فعال کردن",
"enableDescription": "پس از فعال‌سازی، شناسه‌های دستگاه‌های مختلف مانند IMEI/IDFA/IDFV/AndroidID/آدرس مک برای ورود و ثبت‌نام پشتیبانی می‌شوند" "enableDescription": "پس از فعال‌سازی، شناسه‌های دستگاه‌های مختلف مانند IMEI/IDFA/IDFV/AndroidID/آدرس مک برای ورود و ثبت‌نام پشتیبانی می‌شوند",
"enableSecurity": "فعال‌سازی رمزنگاری ارتباطات",
"enableSecurityDescription": "هنگامی که فعال باشد، ارتباط بین دستگاه‌ها و سرورها رمزنگاری خواهد شد",
"saveFailed": "ذخیره‌سازی ناموفق بود",
"saveSuccess": "ذخیره‌سازی با موفقیت انجام شد",
"showAds": "نمایش تبلیغات",
"showAdsDescription": "هنگامی که فعال باشد، تبلیغات بر روی دستگاه‌ها نمایش داده خواهد شد"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "تنظیمات ADS",
"Announcement Management": "مدیریت اطلاعیه‌ها", "Announcement Management": "مدیریت اطلاعیه‌ها",
"Apple": "شناسه اپل", "Apple": "شناسه اپل",
"Auth Control": "کنترل احراز هویت", "Auth Control": "کنترل احراز هویت",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "پرداخت علی‌پی", "AlipayF2F": "علی‌پی چهره به چهره",
"alipayf2f": { "EPay": "ای‌پی",
"appId": "شناسه برنامه Alipay", "Stripe": "استرایپ",
"invoiceName": "نام محصول سفارشی", "applyForPayment": "درخواست پرداخت",
"invoiceNameDescription": "در صورتحساب Alipay نمایش داده خواهد شد", "balance": "موجودی",
"privateKey": "کلید خصوصی Alipay", "batchDelete": "حذف دسته‌ای",
"publicKey": "کلید عمومی Alipay", "cancel": "لغو",
"sandbox": "حالت Sandbox", "config": "پیکربندی",
"sandboxDescription": "حالت sandbox را برای آزمایش پرداخت‌ها فعال کنید" "configInfo": "اطلاعات پیکربندی",
}, "configPlaceholder": "لطفاً پیکربندی {field} ارائه شده را پر کنید",
"confirm": "تأیید",
"confirmDelete": "تأیید حذف",
"copy": "کپی",
"copySuccess": "با موفقیت کپی شد",
"create": "افزودن روش پرداخت",
"createPayment": "افزودن روش پرداخت",
"createSuccess": "با موفقیت ایجاد شد",
"delete": "حذف",
"deleteSuccess": "با موفقیت حذف شد",
"deleteWarning": "آیا مطمئن هستید که می‌خواهید این روش پرداخت را حذف کنید؟ این عمل قابل بازگشت نیست.",
"description": "توضیحات",
"descriptionPlaceholder": "توضیحات روش پرداخت را وارد کنید",
"domain": "دامنه",
"domainPlaceholder": "اختیاری، به عنوان مثال {example}",
"edit": "ویرایش",
"editPayment": "ویرایش روش پرداخت",
"enable": "فعال کردن", "enable": "فعال کردن",
"enableDescription": "این روش پرداخت را فعال کنید", "feeAmount": "مقدار ثابت",
"epay": {
"key": "کلید",
"pid": "شناسه محصول",
"url": "نشانی وب"
},
"feeMode": "حالت هزینه", "feeMode": "حالت هزینه",
"feeModeDescription": "روش دریافت هزینه برای هزینه‌های اضافی",
"feeModeItems": ["بدون هزینه", "درصدی", "مبلغ ثابت", "هر دو"],
"feePercent": "درصد کارمزد (اختیاری)", "feePercent": "درصد کارمزد (اختیاری)",
"feePercentDescription": "افزودن کارمزد به مبلغ سفارش",
"fixedFee": "هزینه ثابت (اختیاری)", "fixedFee": "هزینه ثابت (اختیاری)",
"fixedFeeDescription": "افزودن هزینه ثابت به مبلغ سفارش", "handlingFee": "هزینه خدمات",
"iconUrl": درس آیکون (اختیاری)", "icon": یکون",
"iconUrlDescription": "برای نمایش در رابط کاربری استفاده می‌شود", "iconPlaceholder": "آدرس URL آیکون را وارد کنید",
"inputPlaceholder": "لطفاً وارد کنید", "mark": "شناسه",
"key": "کلید", "markPlaceholder": "شناسه روش پرداخت را وارد کنید",
"notifyUrl": "دامنه اعلان سفارشی (اختیاری)", "name": "نام",
"notifyUrlDescription": "اعلان‌های درگاه به این دامنه ارسال خواهند شد", "namePlaceholder": "نام روش پرداخت را وارد کنید",
"payForRecommendations": "پرداخت برای توصیه‌ها", "nameRequired": "نام الزامی است",
"pid": "شناسه فرآیند", "noFee": "بدون هزینه",
"saveSuccess": "ذخیره با موفقیت انجام شد", "notify_url": "آدرس اطلاع‌رسانی",
"showName": "نمایش نام", "paymentManagement": "مدیریت پرداخت",
"showNameDescription": "برای نمایش در قسمت جلویی استفاده می‌شود", "percentFee": "درصد",
"stripe": { "platform": "پلتفرم",
"publicKey": "کلید عمومی", "searchPlaceholder": "عبارات جستجو را وارد کنید",
"secretKey": "کلید مخفی", "selectPlatform": "انتخاب پلتفرم",
"webhookSecret": "کلید مخفی وب‌هوک" "selectType": "انتخاب نوع پرداخت",
}, "submit": "ارسال",
"url": "آدرس اینترنتی", "type": "نوع",
"wechatPay": "وی‌چت پی" "updateSuccess": "با موفقیت به‌روزرسانی شد"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Peruuta",
"confirm": "Vahvista",
"confirmDelete": "Vahvista poisto",
"create": "Luo ilmoitus",
"createAds": "Luo mainos",
"createSuccess": "Luonti onnistui",
"delete": "Poista",
"deleteSuccess": "Poisto onnistui",
"deleteWarning": "Oletko varma, että haluat poistaa tämän ilmoituksen?",
"disabled": "Pois käytöstä",
"edit": "Muokkaa",
"editAds": "Muokkaa mainosta",
"enabled": "Käytössä",
"form": {
"cancel": "Peruuta",
"confirm": "Vahvista",
"content": "Sisältö",
"description": "Kuvaus",
"endTime": "Loppuaika",
"enterContent": "Ole hyvä ja syötä mainoksen sisältö",
"enterDescription": "Ole hyvä ja syötä mainoksen kuvaus",
"enterEndTime": "Ole hyvä ja valitse loppuaika",
"enterStartTime": "Ole hyvä ja valitse aloitusaika",
"enterTargetUrl": "Ole hyvä ja syötä kohde-URL",
"enterTitle": "Ole hyvä ja syötä mainoksen otsikko",
"startTime": "Aloitusaika",
"targetUrl": "Kohde-URL",
"title": "Otsikko",
"type": "Mainostyyppi",
"typeImage": "Kuva",
"typeVideo": "Video"
},
"status": "Tila",
"targetUrl": "Kohde-URL",
"title": "Otsikko",
"type": "Tyyppi",
"updateSuccess": "Päivitys onnistui",
"validityPeriod": "Voimassaoloaika"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Estä virtuaalikone",
"blockVirtualMachineDescription": "Kun tämä on käytössä, laitteiden käyttö virtuaalikoneissa tai emulaattoreissa estetään",
"communicationKey": "Viestintäavain",
"communicationKeyDescription": "Viestintäavain käytetään turvalliseen viestintään laitteiden ja palvelimien välillä",
"enable": "Ota käyttöön", "enable": "Ota käyttöön",
"enableDescription": "Kun otat käyttöön, useita laiteidentifikaattoreita, kuten IMEI/IDFA/IDFV/AndroidID/Mac-osoite, tuetaan kirjautumiseen ja rekisteröitymiseen." "enableDescription": "Kun otat käyttöön, useita laiteidentifikaattoreita, kuten IMEI/IDFA/IDFV/AndroidID/Mac-osoite, tuetaan kirjautumiseen ja rekisteröitymiseen.",
"enableSecurity": "Ota käyttöön viestinnän salaus",
"enableSecurityDescription": "Kun tämä on käytössä, laitteiden ja palvelimien välinen viestintä salataan",
"saveFailed": "Tallennus epäonnistui",
"saveSuccess": "Tallennus onnistui",
"showAds": "Näytä mainoksia",
"showAdsDescription": "Kun tämä on käytössä, mainoksia näytetään laitteilla"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "ADS-asetukset",
"Announcement Management": "Ilmoitusten hallinta", "Announcement Management": "Ilmoitusten hallinta",
"Apple": "Apple ID", "Apple": "Apple ID",
"Auth Control": "Todennuksen hallinta", "Auth Control": "Todennuksen hallinta",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Alipay-maksu", "AlipayF2F": "Alipay Kasvokkain",
"alipayf2f": { "EPay": "EPay",
"appId": "Alipay-sovelluksen ID", "Stripe": "Stripe",
"invoiceName": "Mukautettu tuotteen nimi", "applyForPayment": "Hae maksua",
"invoiceNameDescription": "Näkyy Alipay-laskussa", "balance": "Saldo",
"privateKey": "Alipay-yksityinen avain", "batchDelete": "Ryhmän poisto",
"publicKey": "Alipay-julkinen avain", "cancel": "Peruuta",
"sandbox": "Hiekkalaatikkotila", "config": "Konfiguraatio",
"sandboxDescription": "Ota hiekkalaatikkotila käyttöön maksujen testaamiseksi" "configInfo": "Konfiguraatio tiedot",
}, "configPlaceholder": "Täytä annettu {field} konfiguraatio",
"confirm": "Vahvista",
"confirmDelete": "Vahvista poisto",
"copy": "Kopioi",
"copySuccess": "Kopiointi onnistui",
"create": "Lisää maksutapa",
"createPayment": "Lisää maksutapa",
"createSuccess": "Luonti onnistui",
"delete": "Poista",
"deleteSuccess": "Poisto onnistui",
"deleteWarning": "Oletko varma, että haluat poistaa tämän maksutavan? Tätä toimintoa ei voi peruuttaa.",
"description": "Kuvaus",
"descriptionPlaceholder": "Syötä maksutavan kuvaus",
"domain": "Verkkotunnus",
"domainPlaceholder": "valinnainen, esim. {esimerkki}",
"edit": "Muokkaa",
"editPayment": "Muokkaa maksutapaa",
"enable": "Ota käyttöön", "enable": "Ota käyttöön",
"enableDescription": "Ota tämä maksutapa käyttöön", "feeAmount": "Kiinteä summa",
"epay": {
"key": "AVAIN",
"pid": "PID",
"url": "URL"
},
"feeMode": "Maksutapa", "feeMode": "Maksutapa",
"feeModeDescription": "Lisämaksun veloitustapa",
"feeModeItems": ["Ei käsittelymaksua", "Prosenttiosuus", "Kiinteä summa", "Molemmat yllä olevat"],
"feePercent": "Prosenttiosuusmaksu (valinnainen)", "feePercent": "Prosenttiosuusmaksu (valinnainen)",
"feePercentDescription": "Lisätään maksu tilauksen summan päälle",
"fixedFee": "Kiinteä maksu (valinnainen)", "fixedFee": "Kiinteä maksu (valinnainen)",
"fixedFeeDescription": "Lisää kiinteä maksu tilauksen summan päälle", "handlingFee": "Käsittelymaksu",
"iconUrl": "Kuvakkeen URL (valinnainen)", "icon": "Ikoni",
"iconUrlDescription": "Käytetään etunäytössä", "iconPlaceholder": "Syötä ikonin URL-osoite",
"inputPlaceholder": "Kirjoita tähän", "mark": "Tunniste",
"key": "AVAIN", "markPlaceholder": "Syötä maksutavan tunniste",
"notifyUrl": "Mukautettu ilmoitusalue (valinnainen)", "name": "Nimi",
"notifyUrlDescription": "Yhdyskäytävän ilmoitus lähetetään tähän verkkotunnukseen", "namePlaceholder": "Syötä maksutavan nimi",
"payForRecommendations": "Maksa suosituksista", "nameRequired": "Nimi on pakollinen",
"pid": "PID", "noFee": "Ei maksua",
"saveSuccess": "Tallennus onnistui", "notify_url": "Ilmoitus-URL",
"showName": "Näytä nimi", "paymentManagement": "Maksujen hallinta",
"showNameDescription": "Näytetään käyttöliittymässä", "percentFee": "Prosentti",
"stripe": { "platform": "Alusta",
"publicKey": "JULKINEN AVAIN", "searchPlaceholder": "Syötä hakusanat",
"secretKey": "SALAINEN AVAIN", "selectPlatform": "Valitse alusta",
"webhookSecret": "WEBHOOK-SALAINEN ALLEKIRJOITUS" "selectType": "Valitse maksutyyppi",
}, "submit": "Lähetä",
"url": "URL", "type": "Tyyppi",
"wechatPay": "WeChat-maksu" "updateSuccess": "Päivitys onnistui"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Annuler",
"confirm": "Confirmer",
"confirmDelete": "Confirmer la suppression",
"create": "Créer une annonce",
"createAds": "Créer une publicité",
"createSuccess": "Créé avec succès",
"delete": "Supprimer",
"deleteSuccess": "Supprimé avec succès",
"deleteWarning": "Êtes-vous sûr de vouloir supprimer cette annonce ?",
"disabled": "Désactivé",
"edit": "Modifier",
"editAds": "Modifier la publicité",
"enabled": "Activé",
"form": {
"cancel": "Annuler",
"confirm": "Confirmer",
"content": "Contenu",
"description": "Description",
"endTime": "Heure de fin",
"enterContent": "Veuillez entrer le contenu de l'annonce",
"enterDescription": "Veuillez entrer la description de l'annonce",
"enterEndTime": "Veuillez sélectionner l'heure de fin",
"enterStartTime": "Veuillez sélectionner l'heure de début",
"enterTargetUrl": "Veuillez entrer l'URL cible",
"enterTitle": "Veuillez entrer le titre de l'annonce",
"startTime": "Heure de début",
"targetUrl": "URL cible",
"title": "Titre",
"type": "Type d'annonce",
"typeImage": "Image",
"typeVideo": "Vidéo"
},
"status": "Statut",
"targetUrl": "URL cible",
"title": "Titre",
"type": "Type",
"updateSuccess": "Mis à jour avec succès",
"validityPeriod": "Période de validité"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Bloquer la machine virtuelle",
"blockVirtualMachineDescription": "Lorsqu'il est activé, les appareils seront empêchés de fonctionner sur des machines virtuelles ou des émulateurs",
"communicationKey": "Clé de communication",
"communicationKeyDescription": "La clé de communication est utilisée pour une communication sécurisée entre les appareils et les serveurs",
"enable": "Activer", "enable": "Activer",
"enableDescription": "Après activation, plusieurs identifiants de périphériques tels que IMEI/IDFA/IDFV/AndroidID/adresse Mac sont pris en charge pour la connexion et l'enregistrement" "enableDescription": "Après activation, plusieurs identifiants de périphériques tels que IMEI/IDFA/IDFV/AndroidID/adresse Mac sont pris en charge pour la connexion et l'enregistrement",
"enableSecurity": "Activer le chiffrement de la communication",
"enableSecurityDescription": "Lorsqu'il est activé, la communication entre les appareils et les serveurs sera chiffrée",
"saveFailed": "Échec de l'enregistrement",
"saveSuccess": "Enregistrement réussi",
"showAds": "Afficher les publicités",
"showAdsDescription": "Lorsqu'il est activé, des publicités seront affichées sur les appareils"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "Configuration ADS",
"Announcement Management": "Gestion des annonces", "Announcement Management": "Gestion des annonces",
"Apple": "Identifiant Apple", "Apple": "Identifiant Apple",
"Auth Control": "Contrôle d'authentification", "Auth Control": "Contrôle d'authentification",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Paiement par Alipay", "AlipayF2F": "Alipay Face à Face",
"alipayf2f": { "EPay": "EPay",
"appId": "ID de l'application Alipay", "Stripe": "Stripe",
"invoiceName": "Nom personnalisé du produit", "applyForPayment": "Demander un paiement",
"invoiceNameDescription": "S'affichera sur la facture Alipay", "balance": "Solde",
"privateKey": "Clé privée Alipay", "batchDelete": "Suppression par lot",
"publicKey": "Clé publique Alipay", "cancel": "Annuler",
"sandbox": "Mode bac à sable", "config": "Configuration",
"sandboxDescription": "Activez le mode bac à sable pour tester le paiement" "configInfo": "Informations de configuration",
}, "configPlaceholder": "Veuillez remplir la configuration {field} fournie",
"confirm": "Confirmer",
"confirmDelete": "Confirmer la suppression",
"copy": "Copier",
"copySuccess": "Copié avec succès",
"create": "Ajouter un mode de paiement",
"createPayment": "Ajouter un mode de paiement",
"createSuccess": "Créé avec succès",
"delete": "Supprimer",
"deleteSuccess": "Supprimé avec succès",
"deleteWarning": "Êtes-vous sûr de vouloir supprimer ce mode de paiement ? Cette action ne peut pas être annulée.",
"description": "Description",
"descriptionPlaceholder": "Entrez la description du mode de paiement",
"domain": "Domaine",
"domainPlaceholder": "facultatif, par exemple {exemple}",
"edit": "Modifier",
"editPayment": "Modifier le mode de paiement",
"enable": "Activer", "enable": "Activer",
"enableDescription": "Activer ce mode de paiement", "feeAmount": "Montant fixe",
"epay": {
"key": "CLÉ",
"pid": "PID",
"url": "URL"
},
"feeMode": "Mode de facturation", "feeMode": "Mode de facturation",
"feeModeDescription": "Mode de facturation des frais supplémentaires",
"feeModeItems": ["Pas de frais", "Pourcentage", "Montant fixe", "Les deux ci-dessus"],
"feePercent": "Pourcentage de frais (optionnel)", "feePercent": "Pourcentage de frais (optionnel)",
"feePercentDescription": "Ajouter des frais au montant de la commande",
"fixedFee": "Frais fixes (optionnel)", "fixedFee": "Frais fixes (optionnel)",
"fixedFeeDescription": "Ajouter des frais fixes au montant de la commande", "handlingFee": "Frais de traitement",
"iconUrl": "URL de l'icône (facultatif)", "icon": "Icône",
"iconUrlDescription": "Utilisé pour l'affichage frontal", "iconPlaceholder": "Entrez l'URL de l'icône",
"inputPlaceholder": "Veuillez entrer", "mark": "Identifiant",
"key": "CLÉ", "markPlaceholder": "Entrez l'identifiant du mode de paiement",
"notifyUrl": "Domaine de notification personnalisé (facultatif)", "name": "Nom",
"notifyUrlDescription": "Les notifications de la passerelle seront envoyées à ce domaine", "namePlaceholder": "Entrez le nom du mode de paiement",
"payForRecommendations": "Payer pour les recommandations", "nameRequired": "Le nom est requis",
"pid": "PID", "noFee": "Pas de frais",
"saveSuccess": "Enregistrement réussi", "notify_url": "URL de notification",
"showName": "Afficher le nom", "paymentManagement": "Gestion des paiements",
"showNameDescription": "Utilisé pour l'affichage frontal", "percentFee": "Pourcentage",
"stripe": { "platform": "Plateforme",
"publicKey": "CLÉ PUBLIQUE", "searchPlaceholder": "Entrez des termes de recherche",
"secretKey": "CLÉ SECRÈTE", "selectPlatform": "Sélectionner la plateforme",
"webhookSecret": "SIGNATURE DE CLÉ WEBHOOK" "selectType": "Sélectionner le type de paiement",
}, "submit": "Soumettre",
"url": "URL", "type": "Type",
"wechatPay": "Paiement WeChat" "updateSuccess": "Mis à jour avec succès"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "रद्द करें",
"confirm": "पुष्टि करें",
"confirmDelete": "हटाने की पुष्टि करें",
"create": "विज्ञापन बनाएं",
"createAds": "विज्ञापन बनाएं",
"createSuccess": "सफलता से बनाया गया",
"delete": "हटाएं",
"deleteSuccess": "सफलता से हटाया गया",
"deleteWarning": "क्या आप वास्तव में इस विज्ञापन को हटाना चाहते हैं?",
"disabled": "अक्षम",
"edit": "संपादित करें",
"editAds": "विज्ञापन संपादित करें",
"enabled": "सक्षम",
"form": {
"cancel": "रद्द करें",
"confirm": "पुष्टि करें",
"content": "सामग्री",
"description": "विवरण",
"endTime": "समाप्ति समय",
"enterContent": "कृपया विज्ञापन सामग्री दर्ज करें",
"enterDescription": "कृपया विज्ञापन विवरण दर्ज करें",
"enterEndTime": "कृपया समाप्ति समय चुनें",
"enterStartTime": "कृपया प्रारंभ समय चुनें",
"enterTargetUrl": "कृपया लक्षित URL दर्ज करें",
"enterTitle": "कृपया विज्ञापन शीर्षक दर्ज करें",
"startTime": "प्रारंभ समय",
"targetUrl": "लक्षित URL",
"title": "शीर्षक",
"type": "विज्ञापन प्रकार",
"typeImage": "छवि",
"typeVideo": "वीडियो"
},
"status": "स्थिति",
"targetUrl": "लक्षित URL",
"title": "शीर्षक",
"type": "प्रकार",
"updateSuccess": "सफलता से अपडेट किया गया",
"validityPeriod": "वैधता अवधि"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "वर्चुअल मशीन को ब्लॉक करें",
"blockVirtualMachineDescription": "जब सक्षम किया जाता है, तो उपकरणों को वर्चुअल मशीनों या एमुलेटर्स पर चलने से रोका जाएगा",
"communicationKey": "संचार कुंजी",
"communicationKeyDescription": "संचार कुंजी का उपयोग उपकरणों और सर्वरों के बीच सुरक्षित संचार के लिए किया जाता है",
"enable": "सक्रिय करें", "enable": "सक्रिय करें",
"enableDescription": "सक्रिय करने के बाद, लॉगिन और पंजीकरण के लिए IMEI/IDFA/IDFV/AndroidID/Mac पता जैसे कई डिवाइस पहचानकर्ताओं का समर्थन किया जाता है" "enableDescription": "सक्रिय करने के बाद, लॉगिन और पंजीकरण के लिए IMEI/IDFA/IDFV/AndroidID/Mac पता जैसे कई डिवाइस पहचानकर्ताओं का समर्थन किया जाता है",
"enableSecurity": "संचार एन्क्रिप्शन सक्षम करें",
"enableSecurityDescription": "जब सक्षम किया जाता है, तो उपकरणों और सर्वरों के बीच का संचार एन्क्रिप्ट किया जाएगा",
"saveFailed": "सहेजना विफल",
"saveSuccess": "सहेजना सफल",
"showAds": "विज्ञापन दिखाएँ",
"showAdsDescription": "जब सक्षम किया जाता है, तो उपकरणों पर विज्ञापन प्रदर्शित किए जाएंगे"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "एडीएस कॉन्फ़िग",
"Announcement Management": "घोषणा प्रबंधन", "Announcement Management": "घोषणा प्रबंधन",
"Apple": "एप्पल आईडी", "Apple": "एप्पल आईडी",
"Auth Control": "प्रमाणिकरण नियंत्रण", "Auth Control": "प्रमाणिकरण नियंत्रण",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "अलीपे भुगतान", "AlipayF2F": "अलीपे फेस टू फेस",
"alipayf2f": { "EPay": "ईपे",
"appId": "अलीपे एप्लिकेशन आईडी", "Stripe": "स्ट्राइप",
"invoiceName": "कस्टम उत्पाद नाम", "applyForPayment": "भुगतान के लिए आवेदन करें",
"invoiceNameDescription": "अलीपे बिल में प्रदर्शित होगा", "balance": "शेष",
"privateKey": "अलीपे निजी कुंजी", "batchDelete": "बैच हटाएं",
"publicKey": "अलीपे सार्वजनिक कुंजी", "cancel": "रद्द करें",
"sandbox": "सैंडबॉक्स मोड", "config": "कॉन्फ़िगरेशन",
"sandboxDescription": "भुगतान का परीक्षण करने के लिए सैंडबॉक्स मोड सक्षम करें" "configInfo": "कॉन्फ़िगरेशन जानकारी",
}, "configPlaceholder": "कृपया प्रदान किए गए {field} कॉन्फ़िगरेशन को भरें",
"confirm": "पुष्टि करें",
"confirmDelete": "हटाने की पुष्टि करें",
"copy": "कॉपी करें",
"copySuccess": "सफलता से कॉपी किया गया",
"create": "भुगतान विधि जोड़ें",
"createPayment": "भुगतान विधि जोड़ें",
"createSuccess": "सफलता से बनाया गया",
"delete": "हटाएं",
"deleteSuccess": "सफलता से हटाया गया",
"deleteWarning": "क्या आप वास्तव में इस भुगतान विधि को हटाना चाहते हैं? यह क्रिया पूर्ववत नहीं की जा सकती।",
"description": "विवरण",
"descriptionPlaceholder": "भुगतान विधि का विवरण दर्ज करें",
"domain": "डोमेन",
"domainPlaceholder": "वैकल्पिक, जैसे कि {example}",
"edit": "संपादित करें",
"editPayment": "भुगतान विधि संपादित करें",
"enable": "सक्षम करें", "enable": "सक्षम करें",
"enableDescription": "इस भुगतान विधि को सक्षम करें", "feeAmount": "निश्चित राशि",
"epay": {
"key": "कुंजी",
"pid": "पीआईडी",
"url": "यूआरएल"
},
"feeMode": "शुल्क मोड", "feeMode": "शुल्क मोड",
"feeModeDescription": "अतिरिक्त शुल्क की वसूली का तरीका",
"feeModeItems": ["कोई शुल्क नहीं", "प्रतिशत", "निश्चित राशि", "उपरोक्त दोनों"],
"feePercent": "प्रतिशत शुल्क (वैकल्पिक)", "feePercent": "प्रतिशत शुल्क (वैकल्पिक)",
"feePercentDescription": "ऑर्डर राशि के ऊपर शुल्क जोड़ा जाएगा",
"fixedFee": "निश्चित शुल्क (वैकल्पिक)", "fixedFee": "निश्चित शुल्क (वैकल्पिक)",
"fixedFeeDescription": "ऑर्डर राशि के ऊपर एक निश्चित शुल्क जोड़ा जाता है", "handlingFee": "हैंडलिंग शुल्क",
"iconUrl": "आइकन URL (वैकल्पिक)", "icon": "चिन्ह",
"iconUrlDescription": "फ्रंटएंड प्रदर्शन के लिए उपयोग किया जाता है", "iconPlaceholder": "चिन्ह URL दर्ज करें",
"inputPlaceholder": "कृपया दर्ज करें", "mark": "पहचानकर्ता",
"key": "कुंजी", "markPlaceholder": "भुगतान विधि पहचानकर्ता दर्ज करें",
"notifyUrl": "कस्टम अधिसूचना डोमेन (वैकल्पिक)", "name": "नाम",
"notifyUrlDescription": "गेटवे सूचना इस डोमेन पर भेजी जाएगी", "namePlaceholder": "भुगतान विधि का नाम दर्ज करें",
"payForRecommendations": "सिफारिशों के लिए भुगतान करें", "nameRequired": "नाम आवश्यक है",
"pid": "पीआईडी", "noFee": "कोई शुल्क नहीं",
"saveSuccess": "सहेजा गया", "notify_url": "सूचना URL",
"showName": "नाम दिखाएं", "paymentManagement": "भुगतान प्रबंधन",
"showNameDescription": "फ्रंटएंड प्रदर्शन के लिए उपयोग किया जाता है", "percentFee": "प्रतिशत",
"stripe": { "platform": "प्लेटफ़ॉर्म",
"publicKey": "सार्वजनिक कुंजी", "searchPlaceholder": "खोज शब्द दर्ज करें",
"secretKey": "गुप्त कुंजी", "selectPlatform": "प्लेटफ़ॉर्म चुनें",
"webhookSecret": "वेबहुक कुंजी हस्ताक्षर" "selectType": "भुगतान प्रकार चुनें",
}, "submit": "जमा करें",
"url": "यूआरएल", "type": "प्रकार",
"wechatPay": "वीचैट पे" "updateSuccess": "सफलता से अपडेट किया गया"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Mégse",
"confirm": "Megerősítés",
"confirmDelete": "Törlés megerősítése",
"create": "Hirdetés létrehozása",
"createAds": "Hirdetés létrehozása",
"createSuccess": "Sikeresen létrehozva",
"delete": "Törlés",
"deleteSuccess": "Sikeresen törölve",
"deleteWarning": "Biztosan törölni szeretné ezt a hirdetést?",
"disabled": "Letiltva",
"edit": "Szerkesztés",
"editAds": "Hirdetés szerkesztése",
"enabled": "Engedélyezve",
"form": {
"cancel": "Mégse",
"confirm": "Megerősítés",
"content": "Tartalom",
"description": "Leírás",
"endTime": "Befejezési idő",
"enterContent": "Kérjük, adja meg a hirdetés tartalmát",
"enterDescription": "Kérjük, adja meg a hirdetés leírását",
"enterEndTime": "Kérjük, válassza ki a befejezési időt",
"enterStartTime": "Kérjük, válassza ki a kezdési időt",
"enterTargetUrl": "Kérjük, adja meg a cél URL-t",
"enterTitle": "Kérjük, adja meg a hirdetés címét",
"startTime": "Kezdési idő",
"targetUrl": "Cél URL",
"title": "Cím",
"type": "Hirdetés típusa",
"typeImage": "Kép",
"typeVideo": "Videó"
},
"status": "Állapot",
"targetUrl": "Cél URL",
"title": "Cím",
"type": "Típus",
"updateSuccess": "Sikeresen frissítve",
"validityPeriod": "Érvényességi időszak"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Virtuális gép blokkolása",
"blockVirtualMachineDescription": "Ha engedélyezve van, az eszközök nem fognak tudni virtuális gépeken vagy emulátorokon futni",
"communicationKey": "Kommunikációs kulcs",
"communicationKeyDescription": "A kommunikációs kulcs a biztonságos kommunikációhoz szükséges az eszközök és a szerverek között",
"enable": "Engedélyezés", "enable": "Engedélyezés",
"enableDescription": "Engedélyezés után több eszközazonosító, például IMEI/IDFA/IDFV/AndroidID/Mac-cím támogatott a bejelentkezéshez és a regisztrációhoz." "enableDescription": "Engedélyezés után több eszközazonosító, például IMEI/IDFA/IDFV/AndroidID/Mac-cím támogatott a bejelentkezéshez és a regisztrációhoz.",
"enableSecurity": "Kommunikációs titkosítás engedélyezése",
"enableSecurityDescription": "Ha engedélyezve van, az eszközök és a szerverek közötti kommunikáció titkosítva lesz",
"saveFailed": "Mentés sikertelen",
"saveSuccess": "Mentés sikeres",
"showAds": "Hirdetések megjelenítése",
"showAdsDescription": "Ha engedélyezve van, hirdetések fognak megjelenni az eszközökön"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "ADS konfiguráció",
"Announcement Management": "Hirdetménykezelés", "Announcement Management": "Hirdetménykezelés",
"Apple": "Apple ID", "Apple": "Apple ID",
"Auth Control": "Hitelesítési vezérlés", "Auth Control": "Hitelesítési vezérlés",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Alipay fizetés", "AlipayF2F": "Alipay Személyesen",
"alipayf2f": { "EPay": "EPay",
"appId": "Alipay alkalmazásazonosító", "Stripe": "Stripe",
"invoiceName": "Egyedi terméknév", "applyForPayment": "Kérjen kifizetést",
"invoiceNameDescription": "A számlán az Alipay-ben fog megjelenni", "balance": "Egyenleg",
"privateKey": "Alipay privát kulcs", "batchDelete": "Tömeges törlés",
"publicKey": "Alipay nyilvános kulcs", "cancel": "Mégse",
"sandbox": "Tesztkörnyezet", "config": "Beállítások",
"sandboxDescription": "Tesztkörnyezet engedélyezése a fizetések teszteléséhez" "configInfo": "Beállítási információk",
}, "configPlaceholder": "Kérjük, töltse ki a megadott {field} beállítást",
"confirm": "Megerősít",
"confirmDelete": "Törlés megerősítése",
"copy": "Másolás",
"copySuccess": "Sikeresen másolva",
"create": "Fizetési mód hozzáadása",
"createPayment": "Fizetési mód hozzáadása",
"createSuccess": "Sikeresen létrehozva",
"delete": "Törlés",
"deleteSuccess": "Sikeresen törölve",
"deleteWarning": "Biztosan törölni szeretné ezt a fizetési módot? Ez a művelet nem vonható vissza.",
"description": "Leírás",
"descriptionPlaceholder": "Írja be a fizetési mód leírását",
"domain": "Domain",
"domainPlaceholder": "opcionális, pl. {példa}",
"edit": "Szerkesztés",
"editPayment": "Fizetési mód szerkesztése",
"enable": "Engedélyezés", "enable": "Engedélyezés",
"enableDescription": "Engedélyezze ezt a fizetési módot", "feeAmount": "Fix összeg",
"epay": {
"key": "KULCS",
"pid": "PID",
"url": "URL"
},
"feeMode": "Díjfizetési mód", "feeMode": "Díjfizetési mód",
"feeModeDescription": "További díjak felszámításának módja",
"feeModeItems": ["Nincs díj", "Százalékos", "Fix összeg", "Mindkettő"],
"feePercent": "Díjszázalék (opcionális)", "feePercent": "Díjszázalék (opcionális)",
"feePercentDescription": "Díj hozzáadása a rendelés összegéhez",
"fixedFee": "Fix díj (opcionális)", "fixedFee": "Fix díj (opcionális)",
"fixedFeeDescription": "Rögzített díj hozzáadása a rendelés összegéhez", "handlingFee": "Kezelési díj",
"iconUrl": "Ikon URL (opcionális)", "icon": "Ikon",
"iconUrlDescription": "Előnézeti kép megjelenítéséhez", "iconPlaceholder": "Adja meg az ikon URL-jét",
"inputPlaceholder": "Kérjük, írja be", "mark": "Azonosító",
"key": "KULCS", "markPlaceholder": "Adja meg a fizetési mód azonosítóját",
"notifyUrl": "Egyéni értesítési domain (opcionális)", "name": "Név",
"notifyUrlDescription": "A kapu értesítéseket erre a tartományra küldi", "namePlaceholder": "Adja meg a fizetési mód nevét",
"payForRecommendations": "Fizetés ajánlásokért", "nameRequired": "A név megadása kötelező",
"pid": "PID", "noFee": "Nincs díj",
"saveSuccess": "Sikeres mentés", "notify_url": "Értesítési URL",
"showName": "Megjelenítési név", "paymentManagement": "Fizetéskezelés",
"showNameDescription": "Előnézet megjelenítésére használatos", "percentFee": "Százalékos díj",
"stripe": { "platform": "Platform",
"publicKey": "NYILVÁNOS KULCS", "searchPlaceholder": "Adja meg a keresési kifejezéseket",
"secretKey": "TITKOS KULCS", "selectPlatform": "Válassza ki a platformot",
"webhookSecret": "WEBHOOK TITKOS ALÁÍRÁS" "selectType": "Válassza ki a fizetési típust",
}, "submit": "Beküldés",
"url": "URL", "type": "Típus",
"wechatPay": "WeChat fizetés" "updateSuccess": "Sikeresen frissítve"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "キャンセル",
"confirm": "確認",
"confirmDelete": "削除を確認",
"create": "広告を作成",
"createAds": "広告を作成",
"createSuccess": "作成に成功しました",
"delete": "削除",
"deleteSuccess": "削除に成功しました",
"deleteWarning": "この広告を削除してもよろしいですか?",
"disabled": "無効",
"edit": "編集",
"editAds": "広告を編集",
"enabled": "有効",
"form": {
"cancel": "キャンセル",
"confirm": "確認",
"content": "コンテンツ",
"description": "説明",
"endTime": "終了時間",
"enterContent": "広告の内容を入力してください",
"enterDescription": "広告の説明を入力してください",
"enterEndTime": "終了時間を選択してください",
"enterStartTime": "開始時間を選択してください",
"enterTargetUrl": "ターゲットURLを入力してください",
"enterTitle": "広告のタイトルを入力してください",
"startTime": "開始時間",
"targetUrl": "ターゲットURL",
"title": "タイトル",
"type": "広告の種類",
"typeImage": "画像",
"typeVideo": "動画"
},
"status": "ステータス",
"targetUrl": "ターゲットURL",
"title": "タイトル",
"type": "種類",
"updateSuccess": "更新に成功しました",
"validityPeriod": "有効期限"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "仮想マシンをブロック",
"blockVirtualMachineDescription": "有効にすると、デバイスは仮想マシンやエミュレーター上での実行が禁止されます",
"communicationKey": "通信キー",
"communicationKeyDescription": "通信キーは、デバイスとサーバー間の安全な通信に使用されます",
"enable": "有効化", "enable": "有効化",
"enableDescription": "有効化後、ログインおよび登録のために、IMEI/IDFA/IDFV/AndroidID/Macアドレスなどの複数のデバイス識別子がサポートされます。" "enableDescription": "有効化後、ログインおよび登録のために、IMEI/IDFA/IDFV/AndroidID/Macアドレスなどの複数のデバイス識別子がサポートされます。",
"enableSecurity": "通信暗号化を有効にする",
"enableSecurityDescription": "有効にすると、デバイスとサーバー間の通信が暗号化されます",
"saveFailed": "保存に失敗しました",
"saveSuccess": "保存に成功しました",
"showAds": "広告を表示",
"showAdsDescription": "有効にすると、デバイスに広告が表示されます"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "ADS設定",
"Announcement Management": "お知らせ管理", "Announcement Management": "お知らせ管理",
"Apple": "Apple ID", "Apple": "Apple ID",
"Auth Control": "認証管理", "Auth Control": "認証管理",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "アリペイ決済", "AlipayF2F": "アリペイ対面",
"alipayf2f": { "EPay": "EPay",
"appId": "支付宝アプリID", "Stripe": "ストライプ",
"invoiceName": "カスタム製品名", "applyForPayment": "支払いを申請する",
"invoiceNameDescription": "支付宝の請求書に表示されます", "balance": "残高",
"privateKey": "支付宝プライベートキー", "batchDelete": "一括削除",
"publicKey": "支付宝パブリックキー", "cancel": "キャンセル",
"sandbox": "サンドボックスモード", "config": "設定",
"sandboxDescription": "支払いをテストするためにサンドボックスモードを有効にします" "configInfo": "設定情報",
}, "configPlaceholder": "提供された{field}の設定を入力してください",
"confirm": "確認",
"confirmDelete": "削除を確認",
"copy": "コピー",
"copySuccess": "コピー成功",
"create": "支払い方法を追加",
"createPayment": "支払い方法を追加",
"createSuccess": "作成成功",
"delete": "削除",
"deleteSuccess": "削除成功",
"deleteWarning": "この支払い方法を削除してもよろしいですか?この操作は元に戻せません。",
"description": "説明",
"descriptionPlaceholder": "支払い方法の説明を入力してください",
"domain": "ドメイン",
"domainPlaceholder": "任意、例:{example}",
"edit": "編集",
"editPayment": "支払い方法を編集",
"enable": "有効", "enable": "有効",
"enableDescription": "この支払い方法を有効にする", "feeAmount": "固定額",
"epay": {
"key": "キー",
"pid": "PID",
"url": "URL"
},
"feeMode": "料金方式", "feeMode": "料金方式",
"feeModeDescription": "追加手数料の課金方式",
"feeModeItems": ["手数料なし", "パーセンテージ", "固定金額", "上記の2つ"],
"feePercent": "パーセンテージ手数料(オプション)", "feePercent": "パーセンテージ手数料(オプション)",
"feePercentDescription": "注文金額に追加される手数料",
"fixedFee": "固定料金(オプション)", "fixedFee": "固定料金(オプション)",
"fixedFeeDescription": "注文金額に固定料金を追加する", "handlingFee": "手数料",
"iconUrl": "アイコンURL(任意)", "icon": "アイコン",
"iconUrlDescription": "フロントエンド表示用", "iconPlaceholder": "アイコンのURLを入力してください",
"inputPlaceholder": "入力してください", "mark": "識別子",
"key": "キー", "markPlaceholder": "支払い方法の識別子を入力してください",
"notifyUrl": "カスタム通知ドメイン(オプション)", "name": "名前",
"notifyUrlDescription": "ゲートウェイ通知はこのドメインに送信されます", "namePlaceholder": "支払い方法の名前を入力してください",
"payForRecommendations": "おすすめの支払い", "nameRequired": "名前は必須です",
"pid": "PID", "noFee": "手数料なし",
"saveSuccess": "保存が成功しました", "notify_url": "通知URL",
"showName": "表示名", "paymentManagement": "支払い管理",
"showNameDescription": "フロントエンド表示用", "percentFee": "パーセンテージ",
"stripe": { "platform": "プラットフォーム",
"publicKey": "パブリックキー", "searchPlaceholder": "検索用語を入力してください",
"secretKey": "シークレットキー", "selectPlatform": "プラットフォームを選択",
"webhookSecret": "WEBHOOK シークレットサイン" "selectType": "支払いタイプを選択",
}, "submit": "送信",
"url": "URL", "type": "タイプ",
"wechatPay": "WeChatペイ" "updateSuccess": "更新成功"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "취소",
"confirm": "확인",
"confirmDelete": "삭제 확인",
"create": "광고 만들기",
"createAds": "광고 생성",
"createSuccess": "성공적으로 생성되었습니다",
"delete": "삭제",
"deleteSuccess": "성공적으로 삭제되었습니다",
"deleteWarning": "이 광고를 삭제하시겠습니까?",
"disabled": "비활성화됨",
"edit": "편집",
"editAds": "광고 편집",
"enabled": "활성화됨",
"form": {
"cancel": "취소",
"confirm": "확인",
"content": "내용",
"description": "설명",
"endTime": "종료 시간",
"enterContent": "광고 내용을 입력하세요",
"enterDescription": "광고 설명을 입력하세요",
"enterEndTime": "종료 시간을 선택하세요",
"enterStartTime": "시작 시간을 선택하세요",
"enterTargetUrl": "대상 URL을 입력하세요",
"enterTitle": "광고 제목을 입력하세요",
"startTime": "시작 시간",
"targetUrl": "대상 URL",
"title": "제목",
"type": "광고 유형",
"typeImage": "이미지",
"typeVideo": "비디오"
},
"status": "상태",
"targetUrl": "대상 URL",
"title": "제목",
"type": "유형",
"updateSuccess": "성공적으로 업데이트되었습니다",
"validityPeriod": "유효 기간"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "가상 머신 차단",
"blockVirtualMachineDescription": "활성화되면, 장치가 가상 머신이나 에뮬레이터에서 실행되는 것을 방지합니다.",
"communicationKey": "통신 키",
"communicationKeyDescription": "통신 키는 장치와 서버 간의 안전한 통신을 위해 사용됩니다.",
"enable": "활성화", "enable": "활성화",
"enableDescription": "활성화 후 IMEI/IDFA/IDFV/AndroidID/Mac 주소와 같은 여러 장치 식별자를 사용하여 로그인 및 등록할 수 있습니다." "enableDescription": "활성화 후 IMEI/IDFA/IDFV/AndroidID/Mac 주소와 같은 여러 장치 식별자를 사용하여 로그인 및 등록할 수 있습니다.",
"enableSecurity": "통신 암호화 활성화",
"enableSecurityDescription": "활성화되면, 장치와 서버 간의 통신이 암호화됩니다.",
"saveFailed": "저장 실패",
"saveSuccess": "저장 성공",
"showAds": "광고 표시",
"showAdsDescription": "활성화되면, 장치에 광고가 표시됩니다."
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "ADS 구성",
"Announcement Management": "공지 관리", "Announcement Management": "공지 관리",
"Apple": "Apple ID", "Apple": "Apple ID",
"Auth Control": "인증 제어", "Auth Control": "인증 제어",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "알리페이 결제", "AlipayF2F": "알리페이 대면 결제",
"alipayf2f": { "EPay": "이페이",
"appId": "알리페이 애플리케이션 ID", "Stripe": "스트라이프",
"invoiceName": "사용자 정의 제품 이름", "applyForPayment": "결제 신청",
"invoiceNameDescription": "알리페이 청구서에 표시됩니다", "balance": "잔액",
"privateKey": "알리페이 개인 키", "batchDelete": "일괄 삭제",
"publicKey": "알리페이 공개 키", "cancel": "취소",
"sandbox": "샌드박스 모드", "config": "설정",
"sandboxDescription": "결제를 테스트하기 위해 샌드박스 모드를 활성화합니다" "configInfo": "설정 정보",
}, "configPlaceholder": "{field} 설정을 입력해 주세요",
"confirm": "확인",
"confirmDelete": "삭제 확인",
"copy": "복사",
"copySuccess": "복사 성공",
"create": "결제 수단 추가",
"createPayment": "결제 수단 추가",
"createSuccess": "생성 성공",
"delete": "삭제",
"deleteSuccess": "삭제 성공",
"deleteWarning": "이 결제 수단을 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.",
"description": "설명",
"descriptionPlaceholder": "결제 수단 설명을 입력하세요",
"domain": "도메인",
"domainPlaceholder": "선택 사항, 예: {example}",
"edit": "편집",
"editPayment": "결제 수단 편집",
"enable": "사용", "enable": "사용",
"enableDescription": "이 결제 수단을 활성화합니다", "feeAmount": "고정 금액",
"epay": {
"key": "키",
"pid": "PID",
"url": "URL"
},
"feeMode": "요금 방식", "feeMode": "요금 방식",
"feeModeDescription": "추가 수수료의 부과 방식",
"feeModeItems": ["수수료 없음", "백분율", "고정 금액", "이상 두 가지"],
"feePercent": "수수료 비율(선택 사항)", "feePercent": "수수료 비율(선택 사항)",
"feePercentDescription": "주문 금액에 추가 요금 부과",
"fixedFee": "고정 수수료(선택 사항)", "fixedFee": "고정 수수료(선택 사항)",
"fixedFeeDescription": "주문 금액에 고정 요금 추가", "handlingFee": "수수료",
"iconUrl": "아이콘 URL(선택 사항)", "icon": "아이콘",
"iconUrlDescription": "프론트엔드 표시용", "iconPlaceholder": "아이콘 URL 입력",
"inputPlaceholder": "입력하세요", "mark": "식별자",
"key": "키", "markPlaceholder": "결제 수단 식별자 입력",
"notifyUrl": "사용자 정의 알림 도메인 (선택 사항)", "name": "이름",
"notifyUrlDescription": "게이트웨이 알림이 이 도메인으로 전송됩니다", "namePlaceholder": "결제 수단 이름 입력",
"payForRecommendations": "추천에 대한 지불", "nameRequired": "이름은 필수입니다",
"pid": "PID", "noFee": "수수료 없음",
"saveSuccess": "저장 성공", "notify_url": "알림 URL",
"showName": "이름 표시", "paymentManagement": "결제 관리",
"showNameDescription": "프론트엔드 표시용", "percentFee": "백분율",
"stripe": { "platform": "플랫폼",
"publicKey": "공개 키", "searchPlaceholder": "검색어 입력",
"secretKey": "비밀 키", "selectPlatform": "플랫폼 선택",
"webhookSecret": "웹훅 비밀 서명" "selectType": "결제 유형 선택",
}, "submit": "제출",
"url": "URL", "type": "유형",
"wechatPay": "위챗페이" "updateSuccess": "업데이트 성공"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Avbryt",
"confirm": "Bekreft",
"confirmDelete": "Bekreft sletting",
"create": "Opprett annonse",
"createAds": "Opprett annonse",
"createSuccess": "Opprettet med suksess",
"delete": "Slett",
"deleteSuccess": "Slettet med suksess",
"deleteWarning": "Er du sikker på at du vil slette denne annonsen?",
"disabled": "Deaktivert",
"edit": "Rediger",
"editAds": "Rediger annonse",
"enabled": "Aktivert",
"form": {
"cancel": "Avbryt",
"confirm": "Bekreft",
"content": "Innhold",
"description": "Beskrivelse",
"endTime": "Sluttid",
"enterContent": "Vennligst skriv inn annonseinnhold",
"enterDescription": "Vennligst skriv inn annonsebeskrivelse",
"enterEndTime": "Vennligst velg sluttid",
"enterStartTime": "Vennligst velg starttid",
"enterTargetUrl": "Vennligst skriv inn mål-URL",
"enterTitle": "Vennligst skriv inn annonsetittel",
"startTime": "Starttid",
"targetUrl": "Mål-URL",
"title": "Tittel",
"type": "Annonsetype",
"typeImage": "Bilde",
"typeVideo": "Video"
},
"status": "Status",
"targetUrl": "Mål-URL",
"title": "Tittel",
"type": "Type",
"updateSuccess": "Oppdatert med suksess",
"validityPeriod": "Gyldighetsperiode"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Blokker virtuell maskin",
"blockVirtualMachineDescription": "Når aktivert, vil enheter bli forhindret fra å kjøre på virtuelle maskiner eller emulatorer",
"communicationKey": "Kommunikasjonsnøkkel",
"communicationKeyDescription": "Kommunikasjonsnøkkelen brukes for sikker kommunikasjon mellom enheter og servere",
"enable": "Aktiver", "enable": "Aktiver",
"enableDescription": "Etter aktivering støttes flere enhetsidentifikatorer som IMEI/IDFA/IDFV/AndroidID/Mac-adresse for pålogging og registrering" "enableDescription": "Etter aktivering støttes flere enhetsidentifikatorer som IMEI/IDFA/IDFV/AndroidID/Mac-adresse for pålogging og registrering",
"enableSecurity": "Aktiver kommunikasjonskryptering",
"enableSecurityDescription": "Når aktivert, vil kommunikasjonen mellom enheter og servere bli kryptert",
"saveFailed": "Lagring mislyktes",
"saveSuccess": "Lagring vellykket",
"showAds": "Vis annonser",
"showAdsDescription": "Når aktivert, vil annonser bli vist på enhetene"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "ADS-konfigurasjon",
"Announcement Management": "Kunngjøringsadministrasjon", "Announcement Management": "Kunngjøringsadministrasjon",
"Apple": "Apple-ID", "Apple": "Apple-ID",
"Auth Control": "Autentiseringskontroll", "Auth Control": "Autentiseringskontroll",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Betaling med Alipay", "AlipayF2F": "Alipay Ansikt-til-Ansikt",
"alipayf2f": { "EPay": "EPay",
"appId": "Alipay-applikasjons-ID", "Stripe": "Stripe",
"invoiceName": "Tilpasset produktnavn", "applyForPayment": "Søk om betaling",
"invoiceNameDescription": "Vil vises på Alipay-fakturaen", "balance": "Saldo",
"privateKey": "Alipay privat nøkkel", "batchDelete": "Slett i batch",
"publicKey": "Alipay offentlig nøkkel", "cancel": "Avbryt",
"sandbox": "Sandkassemodus", "config": "Konfigurasjon",
"sandboxDescription": "Aktiver sandkassemodus for å teste betaling" "configInfo": "Konfigurasjonsinformasjon",
}, "configPlaceholder": "Vennligst fyll inn den angitte {field} konfigurasjonen",
"confirm": "Bekreft",
"confirmDelete": "Bekreft sletting",
"copy": "Kopier",
"copySuccess": "Kopiert med suksess",
"create": "Legg til betalingsmetode",
"createPayment": "Legg til betalingsmetode",
"createSuccess": "Opprettet med suksess",
"delete": "Slett",
"deleteSuccess": "Slettet med suksess",
"deleteWarning": "Er du sikker på at du vil slette denne betalingsmetoden? Denne handlingen kan ikke angres.",
"description": "Beskrivelse",
"descriptionPlaceholder": "Skriv inn beskrivelse av betalingsmetode",
"domain": "Domene",
"domainPlaceholder": "valgfritt, f.eks. {example}",
"edit": "Rediger",
"editPayment": "Rediger betalingsmetode",
"enable": "Aktiver", "enable": "Aktiver",
"enableDescription": "Aktiver denne betalingsmetoden", "feeAmount": "Fast beløp",
"epay": {
"key": "NØKKEL",
"pid": "PID",
"url": "URL"
},
"feeMode": "Avgiftsmåte", "feeMode": "Avgiftsmåte",
"feeModeDescription": "Gebyrmodus for ekstra avgifter",
"feeModeItems": ["Ingen gebyr", "Prosentandel", "Fast beløp", "Begge ovennevnte"],
"feePercent": "Prosentavgift (valgfritt)", "feePercent": "Prosentavgift (valgfritt)",
"feePercentDescription": "Legg til et gebyr på toppen av ordrebeløpet",
"fixedFee": "Fast gebyr (valgfritt)", "fixedFee": "Fast gebyr (valgfritt)",
"fixedFeeDescription": "Legg til et fast gebyr i tillegg til ordrebeløpet", "handlingFee": "Håndteringsgebyr",
"iconUrl": "Ikon URL (valgfritt)", "icon": "Ikon",
"iconUrlDescription": "Brukes for visning på frontend", "iconPlaceholder": "Skriv inn ikon-URL",
"inputPlaceholder": "Vennligst skriv inn", "mark": "Identifikator",
"key": "NØKKEL", "markPlaceholder": "Skriv inn identifikator for betalingsmetode",
"notifyUrl": "Tilpasset varslingsdomene (valgfritt)", "name": "Navn",
"notifyUrlDescription": "Gateway-varsler vil bli sendt til dette domenet", "namePlaceholder": "Skriv inn navn på betalingsmetode",
"payForRecommendations": "Betal for anbefalinger", "nameRequired": "Navn er påkrevd",
"pid": "PID", "noFee": "Ingen gebyr",
"saveSuccess": "Lagring vellykket", "notify_url": "Varslings-URL",
"showName": "Vis navn", "paymentManagement": "Betalingsadministrasjon",
"showNameDescription": "Brukes for visning på frontend", "percentFee": "Prosentandel",
"stripe": { "platform": "Plattform",
"publicKey": "OFFENTLIG NØKKEL", "searchPlaceholder": "Skriv inn søkeord",
"secretKey": "HEMMELIG NØKKEL", "selectPlatform": "Velg plattform",
"webhookSecret": "WEBHOOK SIGNATUR" "selectType": "Velg betalingstype",
}, "submit": "Send inn",
"url": "URL", "type": "Type",
"wechatPay": "WeChat-betaling" "updateSuccess": "Oppdatert med suksess"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Anuluj",
"confirm": "Potwierdź",
"confirmDelete": "Potwierdź usunięcie",
"create": "Utwórz reklamę",
"createAds": "Utwórz ogłoszenie",
"createSuccess": "Pomyślnie utworzono",
"delete": "Usuń",
"deleteSuccess": "Pomyślnie usunięto",
"deleteWarning": "Czy na pewno chcesz usunąć tę reklamę?",
"disabled": "Wyłączone",
"edit": "Edytuj",
"editAds": "Edytuj ogłoszenie",
"enabled": "Włączone",
"form": {
"cancel": "Anuluj",
"confirm": "Potwierdź",
"content": "Treść",
"description": "Opis",
"endTime": "Czas zakończenia",
"enterContent": "Proszę wprowadzić treść reklamy",
"enterDescription": "Proszę wprowadzić opis reklamy",
"enterEndTime": "Proszę wybrać czas zakończenia",
"enterStartTime": "Proszę wybrać czas rozpoczęcia",
"enterTargetUrl": "Proszę wprowadzić docelowy URL",
"enterTitle": "Proszę wprowadzić tytuł reklamy",
"startTime": "Czas rozpoczęcia",
"targetUrl": "Docelowy URL",
"title": "Tytuł",
"type": "Typ reklamy",
"typeImage": "Obraz",
"typeVideo": "Wideo"
},
"status": "Status",
"targetUrl": "Docelowy URL",
"title": "Tytuł",
"type": "Typ",
"updateSuccess": "Pomyślnie zaktualizowano",
"validityPeriod": "Okres ważności"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Zablokuj maszynę wirtualną",
"blockVirtualMachineDescription": "Po włączeniu urządzenia nie będą mogły działać na maszynach wirtualnych lub emulatorach",
"communicationKey": "Klucz komunikacji",
"communicationKeyDescription": "Klucz komunikacji jest używany do bezpiecznej komunikacji między urządzeniami a serwerami",
"enable": "Włącz", "enable": "Włącz",
"enableDescription": "Po włączeniu obsługiwane są różne identyfikatory urządzeń, takie jak IMEI/IDFA/IDFV/AndroidID/adres MAC do logowania i rejestracji" "enableDescription": "Po włączeniu obsługiwane są różne identyfikatory urządzeń, takie jak IMEI/IDFA/IDFV/AndroidID/adres MAC do logowania i rejestracji",
"enableSecurity": "Włącz szyfrowanie komunikacji",
"enableSecurityDescription": "Po włączeniu komunikacja między urządzeniami a serwerami będzie szyfrowana",
"saveFailed": "Zapis nie powiódł się",
"saveSuccess": "Zapisano pomyślnie",
"showAds": "Wyświetl reklamy",
"showAdsDescription": "Po włączeniu na urządzeniach będą wyświetlane reklamy"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "Konfiguracja ADS",
"Announcement Management": "Zarządzanie ogłoszeniami", "Announcement Management": "Zarządzanie ogłoszeniami",
"Apple": "Identyfikator Apple", "Apple": "Identyfikator Apple",
"Auth Control": "Kontrola autoryzacji", "Auth Control": "Kontrola autoryzacji",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Płatność Alipay", "AlipayF2F": "Alipay Twarzą w Twarz",
"alipayf2f": { "EPay": "EPay",
"appId": "ID aplikacji Alipay", "Stripe": "Stripe",
"invoiceName": "Niestandardowa nazwa produktu", "applyForPayment": "Złóż wniosek o płatność",
"invoiceNameDescription": "Będzie wyświetlana na rachunku Alipay", "balance": "Saldo",
"privateKey": "Klucz prywatny Alipay", "batchDelete": "Usuwanie zbiorcze",
"publicKey": "Klucz publiczny Alipay", "cancel": "Anuluj",
"sandbox": "Tryb piaskownicy", "config": "Konfiguracja",
"sandboxDescription": "Włącz tryb piaskownicy, aby przetestować płatności" "configInfo": "Informacje o konfiguracji",
}, "configPlaceholder": "Proszę wypełnić konfigurację {field}",
"confirm": "Potwierdź",
"confirmDelete": "Potwierdź usunięcie",
"copy": "Kopiuj",
"copySuccess": "Skopiowano pomyślnie",
"create": "Dodaj metodę płatności",
"createPayment": "Dodaj metodę płatności",
"createSuccess": "Utworzono pomyślnie",
"delete": "Usuń",
"deleteSuccess": "Usunięto pomyślnie",
"deleteWarning": "Czy na pewno chcesz usunąć tę metodę płatności? Ta akcja jest nieodwracalna.",
"description": "Opis",
"descriptionPlaceholder": "Wprowadź opis metody płatności",
"domain": "Domena",
"domainPlaceholder": "opcjonalnie, np. {example}",
"edit": "Edytuj",
"editPayment": "Edytuj metodę płatności",
"enable": "Włącz", "enable": "Włącz",
"enableDescription": "Włącz tę metodę płatności", "feeAmount": "Kwota stała",
"epay": {
"key": "KLUCZ",
"pid": "PID",
"url": "URL"
},
"feeMode": "Sposób naliczania opłat", "feeMode": "Sposób naliczania opłat",
"feeModeDescription": "Sposób naliczania dodatkowej opłaty",
"feeModeItems": ["Bez opłaty", "Procent", "Stała kwota", "Oba powyższe"],
"feePercent": "Procentowa opłata (opcjonalnie)", "feePercent": "Procentowa opłata (opcjonalnie)",
"feePercentDescription": "Dodaj opłatę do kwoty zamówienia",
"fixedFee": "Stała opłata (opcjonalnie)", "fixedFee": "Stała opłata (opcjonalnie)",
"fixedFeeDescription": "Dodaj stałą opłatę do kwoty zamówienia", "handlingFee": "Opłata manipulacyjna",
"iconUrl": "URL ikony (opcjonalnie)", "icon": "Ikona",
"iconUrlDescription": "Używane do wyświetlania na froncie", "iconPlaceholder": "Wprowadź URL ikony",
"inputPlaceholder": "Wprowadź tekst", "mark": "Identyfikator",
"key": "KLUCZ", "markPlaceholder": "Wprowadź identyfikator metody płatności",
"notifyUrl": "Niestandardowa domena powiadomień (opcjonalnie)", "name": "Nazwa",
"notifyUrlDescription": "Powiadomienie bramki zostanie wysłane na tę domenę", "namePlaceholder": "Wprowadź nazwę metody płatności",
"payForRecommendations": "Zapłać za rekomendacje", "nameRequired": "Nazwa jest wymagana",
"pid": "PID", "noFee": "Brak opłaty",
"saveSuccess": "Zapisano pomyślnie", "notify_url": "URL powiadomienia",
"showName": "Pokaż nazwę", "paymentManagement": "Zarządzanie płatnościami",
"showNameDescription": "Używane do wyświetlania na froncie", "percentFee": "Procent",
"stripe": { "platform": "Platforma",
"publicKey": "KLUCZ PUBLICZNY", "searchPlaceholder": "Wprowadź hasła do wyszukiwania",
"secretKey": "KLUCZ TAJNY", "selectPlatform": "Wybierz platformę",
"webhookSecret": "PODPIS KLUCZA WEBHOOK" "selectType": "Wybierz typ płatności",
}, "submit": "Wyślij",
"url": "URL", "type": "Typ",
"wechatPay": "WeChat Pay" "updateSuccess": "Zaktualizowano pomyślnie"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Cancelar",
"confirm": "Confirmar",
"confirmDelete": "Confirmar Exclusão",
"create": "Criar Anúncio",
"createAds": "Criar Anúncio",
"createSuccess": "Criado com sucesso",
"delete": "Excluir",
"deleteSuccess": "Excluído com sucesso",
"deleteWarning": "Você tem certeza de que deseja excluir este anúncio?",
"disabled": "Desativado",
"edit": "Editar",
"editAds": "Editar Anúncio",
"enabled": "Ativado",
"form": {
"cancel": "Cancelar",
"confirm": "Confirmar",
"content": "Conteúdo",
"description": "Descrição",
"endTime": "Hora de Término",
"enterContent": "Por favor, insira o conteúdo do anúncio",
"enterDescription": "Por favor, insira a descrição do anúncio",
"enterEndTime": "Por favor, selecione a hora de término",
"enterStartTime": "Por favor, selecione a hora de início",
"enterTargetUrl": "Por favor, insira a URL de destino",
"enterTitle": "Por favor, insira o título do anúncio",
"startTime": "Hora de Início",
"targetUrl": "URL de Destino",
"title": "Título",
"type": "Tipo de Anúncio",
"typeImage": "Imagem",
"typeVideo": "Vídeo"
},
"status": "Status",
"targetUrl": "URL de Destino",
"title": "Título",
"type": "Tipo",
"updateSuccess": "Atualizado com sucesso",
"validityPeriod": "Período de Validade"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Bloquear Máquina Virtual",
"blockVirtualMachineDescription": "Quando ativado, os dispositivos serão impedidos de rodar em máquinas virtuais ou emuladores",
"communicationKey": "Chave de Comunicação",
"communicationKeyDescription": "A chave de comunicação é usada para comunicação segura entre dispositivos e servidores",
"enable": "Ativar", "enable": "Ativar",
"enableDescription": "Após a ativação, múltiplos identificadores de dispositivo, como IMEI/IDFA/IDFV/AndroidID/endereço Mac, são suportados para login e registro" "enableDescription": "Após a ativação, múltiplos identificadores de dispositivo, como IMEI/IDFA/IDFV/AndroidID/endereço Mac, são suportados para login e registro",
"enableSecurity": "Ativar Criptografia de Comunicação",
"enableSecurityDescription": "Quando ativado, a comunicação entre dispositivos e servidores será criptografada",
"saveFailed": "Falha ao salvar",
"saveSuccess": "Salvo com sucesso",
"showAds": "Mostrar Anúncios",
"showAdsDescription": "Quando ativado, anúncios serão exibidos nos dispositivos"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "Configuração ADS",
"Announcement Management": "Gerenciamento de Anúncios", "Announcement Management": "Gerenciamento de Anúncios",
"Apple": "ID Apple", "Apple": "ID Apple",
"Auth Control": "Controle de Autenticação", "Auth Control": "Controle de Autenticação",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Pagamento com Alipay", "AlipayF2F": "Alipay Face a Face",
"alipayf2f": { "EPay": "EPay",
"appId": "ID do aplicativo Alipay", "Stripe": "Stripe",
"invoiceName": "Nome personalizado do produto", "applyForPayment": "Solicitar Pagamento",
"invoiceNameDescription": "Será exibido na fatura do Alipay", "balance": "Saldo",
"privateKey": "Chave privada do Alipay", "batchDelete": "Excluir em Lote",
"publicKey": "Chave pública do Alipay", "cancel": "Cancelar",
"sandbox": "Modo sandbox", "config": "Configuração",
"sandboxDescription": "Ative o modo sandbox para testar pagamentos" "configInfo": "Informações de Configuração",
}, "configPlaceholder": "Por favor, preencha a configuração de {field} fornecida",
"confirm": "Confirmar",
"confirmDelete": "Confirmar Exclusão",
"copy": "Copiar",
"copySuccess": "Copiado com sucesso",
"create": "Adicionar Método de Pagamento",
"createPayment": "Adicionar Método de Pagamento",
"createSuccess": "Criado com sucesso",
"delete": "Excluir",
"deleteSuccess": "Excluído com sucesso",
"deleteWarning": "Você tem certeza de que deseja excluir este método de pagamento? Esta ação não pode ser desfeita.",
"description": "Descrição",
"descriptionPlaceholder": "Insira a descrição do método de pagamento",
"domain": "Domínio",
"domainPlaceholder": "opcional, por exemplo, {exemplo}",
"edit": "Editar",
"editPayment": "Editar Método de Pagamento",
"enable": "Habilitar", "enable": "Habilitar",
"enableDescription": "Ativar este método de pagamento", "feeAmount": "Valor Fixo",
"epay": {
"key": "CHAVE",
"pid": "PID",
"url": "URL"
},
"feeMode": "Modo de Cobrança", "feeMode": "Modo de Cobrança",
"feeModeDescription": "Modo de cobrança de taxas adicionais",
"feeModeItems": ["Sem taxa", "Porcentagem", "Valor fixo", "Ambos os anteriores"],
"feePercent": "Percentual de taxa (opcional)", "feePercent": "Percentual de taxa (opcional)",
"feePercentDescription": "Adicionar taxa sobre o valor do pedido",
"fixedFee": "Taxa fixa (opcional)", "fixedFee": "Taxa fixa (opcional)",
"fixedFeeDescription": "Adicionar uma taxa fixa sobre o valor do pedido", "handlingFee": "Taxa de Manipulação",
"iconUrl": "URL do ícone (opcional)", "icon": "Ícone",
"iconUrlDescription": "Usado para exibição no front-end", "iconPlaceholder": "Digite a URL do ícone",
"inputPlaceholder": "Por favor, insira", "mark": "Identificador",
"key": "CHAVE", "markPlaceholder": "Digite o identificador do método de pagamento",
"notifyUrl": "Domínio de notificação personalizado (opcional)", "name": "Nome",
"notifyUrlDescription": "A notificação do gateway será enviada para este domínio", "namePlaceholder": "Digite o nome do método de pagamento",
"payForRecommendations": "Pagar por recomendações", "nameRequired": "O nome é obrigatório",
"pid": "PID", "noFee": "Sem Taxa",
"saveSuccess": "Salvo com sucesso", "notify_url": "URL de Notificação",
"showName": "Mostrar Nome", "paymentManagement": "Gerenciamento de Pagamento",
"showNameDescription": "Usado para exibição no front-end", "percentFee": "Porcentagem",
"stripe": { "platform": "Plataforma",
"publicKey": "CHAVE PÚBLICA", "searchPlaceholder": "Digite os termos de pesquisa",
"secretKey": "CHAVE SECRETA", "selectPlatform": "Selecionar Plataforma",
"webhookSecret": "ASSINATURA DA CHAVE DO WEBHOOK" "selectType": "Selecionar tipo de pagamento",
}, "submit": "Enviar",
"url": "URL", "type": "Tipo",
"wechatPay": "WeChat Pay" "updateSuccess": "Atualizado com sucesso"
} }
+1 -1
View File
@@ -10,7 +10,6 @@ export default getRequestConfig(async () => {
const locale = cookieLocale || defaultLocale || NEXT_PUBLIC_DEFAULT_LANGUAGE; const locale = cookieLocale || defaultLocale || NEXT_PUBLIC_DEFAULT_LANGUAGE;
const messages = { const messages = {
'language': (await import(`./${locale}/language.json`)).default,
'menu': (await import(`./${locale}/menu.json`)).default, 'menu': (await import(`./${locale}/menu.json`)).default,
'auth': (await import(`./${locale}/auth.json`)).default, 'auth': (await import(`./${locale}/auth.json`)).default,
'common': (await import(`./${locale}/common.json`)).default, 'common': (await import(`./${locale}/common.json`)).default,
@@ -24,6 +23,7 @@ export default getRequestConfig(async () => {
'facebook': (await import(`./${locale}/facebook.json`)).default, 'facebook': (await import(`./${locale}/facebook.json`)).default,
'github': (await import(`./${locale}/github.json`)).default, 'github': (await import(`./${locale}/github.json`)).default,
'device': (await import(`./${locale}/device.json`)).default, 'device': (await import(`./${locale}/device.json`)).default,
'ads': (await import(`./${locale}/ads.json`)).default,
'payment': (await import(`./${locale}/payment.json`)).default, 'payment': (await import(`./${locale}/payment.json`)).default,
'server': (await import(`./${locale}/server.json`)).default, 'server': (await import(`./${locale}/server.json`)).default,
'subscribe': (await import(`./${locale}/subscribe.json`)).default, 'subscribe': (await import(`./${locale}/subscribe.json`)).default,
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Anulează",
"confirm": "Confirmă",
"confirmDelete": "Confirmă ștergerea",
"create": "Creează anunț",
"createAds": "Creează publicitate",
"createSuccess": "Creat cu succes",
"delete": "Șterge",
"deleteSuccess": "Șters cu succes",
"deleteWarning": "Ești sigur că vrei să ștergi acest anunț?",
"disabled": "Dezactivat",
"edit": "Editează",
"editAds": "Editează publicitate",
"enabled": "Activat",
"form": {
"cancel": "Anulează",
"confirm": "Confirmă",
"content": "Conținut",
"description": "Descriere",
"endTime": "Ora de încheiere",
"enterContent": "Te rugăm să introduci conținutul anunțului",
"enterDescription": "Te rugăm să introduci descrierea anunțului",
"enterEndTime": "Te rugăm să selectezi ora de încheiere",
"enterStartTime": "Te rugăm să selectezi ora de început",
"enterTargetUrl": "Te rugăm să introduci URL-ul țintă",
"enterTitle": "Te rugăm să introduci titlul anunțului",
"startTime": "Ora de început",
"targetUrl": "URL țintă",
"title": "Titlu",
"type": "Tip anunț",
"typeImage": "Imagine",
"typeVideo": "Video"
},
"status": "Stare",
"targetUrl": "URL țintă",
"title": "Titlu",
"type": "Tip",
"updateSuccess": "Actualizat cu succes",
"validityPeriod": "Perioada de valabilitate"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Blochează Mașina Virtuală",
"blockVirtualMachineDescription": "Când este activat, dispozitivele vor fi împiedicate să ruleze pe mașini virtuale sau emulatoare",
"communicationKey": "Cheia de Comunicare",
"communicationKeyDescription": "Cheia de comunicare este utilizată pentru comunicarea securizată între dispozitive și servere",
"enable": "Activare", "enable": "Activare",
"enableDescription": "După activare, sunt acceptate mai multe identificatoare de dispozitive, cum ar fi IMEI/IDFA/IDFV/AndroidID/adresa Mac pentru autentificare și înregistrare." "enableDescription": "După activare, sunt acceptate mai multe identificatoare de dispozitive, cum ar fi IMEI/IDFA/IDFV/AndroidID/adresa Mac pentru autentificare și înregistrare.",
"enableSecurity": "Activează Criptarea Comunicației",
"enableSecurityDescription": "Când este activat, comunicația între dispozitive și servere va fi criptată",
"saveFailed": "Salvarea a eșuat",
"saveSuccess": "Salvarea a fost reușită",
"showAds": "Afișează Reclame",
"showAdsDescription": "Când este activat, reclamele vor fi afișate pe dispozitive"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "Configurație ADS",
"Announcement Management": "Managementul Anunțurilor", "Announcement Management": "Managementul Anunțurilor",
"Apple": "ID Apple", "Apple": "ID Apple",
"Auth Control": "Control Autentificare", "Auth Control": "Control Autentificare",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Plată cu Alipay", "AlipayF2F": "Alipay Față în Față",
"alipayf2f": { "EPay": "EPay",
"appId": "ID aplicație Alipay", "Stripe": "Stripe",
"invoiceName": "Nume personalizat produs", "applyForPayment": "Solicită Plată",
"invoiceNameDescription": "Va apărea în factura Alipay", "balance": "Sold",
"privateKey": "Cheie privată Alipay", "batchDelete": "Ștergere în Lot",
"publicKey": "Cheie publică Alipay", "cancel": "Anulează",
"sandbox": "Modul sandbox", "config": "Configurare",
"sandboxDescription": "Activează modul sandbox pentru a testa plățile" "configInfo": "Informații de Configurare",
}, "configPlaceholder": "Te rugăm să completezi configurația {field} furnizată",
"confirm": "Confirmă",
"confirmDelete": "Confirmă Ștergerea",
"copy": "Copiază",
"copySuccess": "Copiat cu succes",
"create": "Adaugă Metodă de Plată",
"createPayment": "Adaugă Metodă de Plată",
"createSuccess": "Creat cu succes",
"delete": "Șterge",
"deleteSuccess": "Șters cu succes",
"deleteWarning": "Ești sigur că vrei să ștergi această metodă de plată? Această acțiune nu poate fi anulată.",
"description": "Descriere",
"descriptionPlaceholder": "Introduceți descrierea metodei de plată",
"domain": "Domeniu",
"domainPlaceholder": "opțional, de exemplu {example}",
"edit": "Editează",
"editPayment": "Editează Metodă de Plată",
"enable": "Activare", "enable": "Activare",
"enableDescription": "Activează această metodă de plată", "feeAmount": "Sumă Fixă",
"epay": {
"key": "CHEIE",
"pid": "PID",
"url": "URL"
},
"feeMode": "Mod de taxare", "feeMode": "Mod de taxare",
"feeModeDescription": "Modul de taxare a comisioanelor suplimentare",
"feeModeItems": ["Fără comision", "Procentaj", "Sumă fixă", "Ambele"],
"feePercent": "Taxă procentuală (opțional)", "feePercent": "Taxă procentuală (opțional)",
"feePercentDescription": "Se adaugă o taxă peste suma comenzii",
"fixedFee": "Taxă fixă (opțional)", "fixedFee": "Taxă fixă (opțional)",
"fixedFeeDescription": "Adăugarea unei taxe fixe peste suma comenzii", "handlingFee": "Taxă de manipulare",
"iconUrl": "URL pictogramă (opțional)", "icon": "Iconiță",
"iconUrlDescription": "Utilizat pentru afișarea în front-end", "iconPlaceholder": "Introdu URL-ul iconiței",
"inputPlaceholder": "Introduceți", "mark": "Identificator",
"key": "CHEIE", "markPlaceholder": "Introdu identificatorul metodei de plată",
"notifyUrl": "Domeniu de notificare personalizat (opțional)", "name": "Nume",
"notifyUrlDescription": "Notificările de la gateway vor fi trimise la acest domeniu", "namePlaceholder": "Introdu numele metodei de pla",
"payForRecommendations": "Plătește pentru recomandări", "nameRequired": "Numele este necesar",
"pid": "PID", "noFee": "Fără Taxă",
"saveSuccess": "Salvare reușită", "notify_url": "URL de notificare",
"showName": "Afișează Numele", "paymentManagement": "Gestionare Plăți",
"showNameDescription": "Utilizat pentru afișarea în interfața utilizatorului", "percentFee": "Procentaj",
"stripe": { "platform": "Platformă",
"publicKey": "CHEIE PUBLICĂ", "searchPlaceholder": "Introdu termeni de căutare",
"secretKey": "CHEIE SECRETĂ", "selectPlatform": "Selectează Platforma",
"webhookSecret": "SEMNĂTURA CHEII WEBHOOK" "selectType": "Selectează tipul de plată",
}, "submit": "Trimite",
"url": "URL", "type": "Tip",
"wechatPay": "Plată WeChat" "updateSuccess": "Actualizat cu succes"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Отмена",
"confirm": "Подтвердить",
"confirmDelete": "Подтвердить удаление",
"create": "Создать объявление",
"createAds": "Создать рекламу",
"createSuccess": "Успешно создано",
"delete": "Удалить",
"deleteSuccess": "Успешно удалено",
"deleteWarning": "Вы уверены, что хотите удалить это объявление?",
"disabled": "Отключено",
"edit": "Редактировать",
"editAds": "Редактировать рекламу",
"enabled": "Включено",
"form": {
"cancel": "Отмена",
"confirm": "Подтвердить",
"content": "Содержимое",
"description": "Описание",
"endTime": "Время окончания",
"enterContent": "Пожалуйста, введите содержимое объявления",
"enterDescription": "Пожалуйста, введите описание объявления",
"enterEndTime": "Пожалуйста, выберите время окончания",
"enterStartTime": "Пожалуйста, выберите время начала",
"enterTargetUrl": "Пожалуйста, введите целевой URL",
"enterTitle": "Пожалуйста, введите заголовок объявления",
"startTime": "Время начала",
"targetUrl": "Целевой URL",
"title": "Заголовок",
"type": "Тип объявления",
"typeImage": "Изображение",
"typeVideo": "Видео"
},
"status": "Статус",
"targetUrl": "Целевой URL",
"title": "Заголовок",
"type": "Тип",
"updateSuccess": "Успешно обновлено",
"validityPeriod": "Срок действия"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Блокировать виртуальную машину",
"blockVirtualMachineDescription": "При включении устройства не смогут работать на виртуальных машинах или эмуляторах",
"communicationKey": "Ключ связи",
"communicationKeyDescription": "Ключ связи используется для безопасной связи между устройствами и серверами",
"enable": "Включить", "enable": "Включить",
"enableDescription": "После включения поддерживаются несколько идентификаторов устройств, таких как IMEI/IDFA/IDFV/AndroidID/Mac-адрес для входа и регистрации" "enableDescription": "После включения поддерживаются несколько идентификаторов устройств, таких как IMEI/IDFA/IDFV/AndroidID/Mac-адрес для входа и регистрации",
"enableSecurity": "Включить шифрование связи",
"enableSecurityDescription": "При включении связь между устройствами и серверами будет зашифрована",
"saveFailed": "Не удалось сохранить",
"saveSuccess": "Сохранение успешно",
"showAds": "Показать рекламу",
"showAdsDescription": "При включении реклама будет отображаться на устройствах"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "Конфигурация ADS",
"Announcement Management": "Управление объявлениями", "Announcement Management": "Управление объявлениями",
"Apple": "Apple ID", "Apple": "Apple ID",
"Auth Control": "Управление аутентификацией", "Auth Control": "Управление аутентификацией",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Оплата через Alipay", "AlipayF2F": "Alipay Лицом к Лицу",
"alipayf2f": { "EPay": "EPay",
"appId": "ID приложения Alipay", "Stripe": "Stripe",
"invoiceName": "Пользовательское название продукта", "applyForPayment": "Подать заявку на оплату",
"invoiceNameDescription": "Будет отображаться в счете Alipay", "balance": "Баланс",
"privateKey": "Приватный ключ Alipay", "batchDelete": "Пакетное удаление",
"publicKey": "Публичный ключ Alipay", "cancel": "Отмена",
"sandbox": "Режим песочницы", "config": "Конфигурация",
"sandboxDescription": "Включите режим песочницы для тестирования платежей" "configInfo": "Информация о конфигурации",
}, "configPlaceholder": "Пожалуйста, заполните предоставленную конфигурацию {field}",
"confirm": "Подтвердить",
"confirmDelete": "Подтвердить удаление",
"copy": "Копировать",
"copySuccess": "Успешно скопировано",
"create": "Добавить способ оплаты",
"createPayment": "Добавить способ оплаты",
"createSuccess": "Успешно создано",
"delete": "Удалить",
"deleteSuccess": "Успешно удалено",
"deleteWarning": "Вы уверены, что хотите удалить этот способ оплаты? Это действие нельзя отменить.",
"description": "Описание",
"descriptionPlaceholder": "Введите описание метода оплаты",
"domain": "Домен",
"domainPlaceholder": "необязательно, например, {example}",
"edit": "Редактировать",
"editPayment": "Редактировать способ оплаты",
"enable": "Включить", "enable": "Включить",
"enableDescription": "Включить этот способ оплаты", "feeAmount": "Фиксированная сумма",
"epay": {
"key": "КЛЮЧ",
"pid": "PID",
"url": "URL"
},
"feeMode": "Способ оплаты", "feeMode": "Способ оплаты",
"feeModeDescription": "Способ взимания дополнительной комиссии",
"feeModeItems": ["Без комиссии", "Процент", "Фиксированная сумма", "Оба вышеуказанных"],
"feePercent": "Процентная комиссия (необязательно)", "feePercent": "Процентная комиссия (необязательно)",
"feePercentDescription": "Добавление комиссии к сумме заказа",
"fixedFee": "Фиксированная плата (по желанию)", "fixedFee": "Фиксированная плата (по желанию)",
"fixedFeeDescription": "Добавление фиксированной платы к сумме заказа", "handlingFee": "Плата за обработку",
"iconUrl": "URL значка (необязательно)", "icon": "Иконка",
"iconUrlDescription": "Используется для отображения на фронтенде", "iconPlaceholder": "Введите URL иконки",
"inputPlaceholder": "Пожалуйста, введите", "mark": "Идентификатор",
"key": "КЛЮЧ", "markPlaceholder": "Введите идентификатор способа оплаты",
"notifyUrl": "Пользовательский домен уведомлений (необязательно)", "name": "Название",
"notifyUrlDescription": "Уведомление шлюза будет отправлено на этот домен", "namePlaceholder": "Введите название способа оплаты",
"payForRecommendations": "Оплатить рекомендации", "nameRequired": "Название обязательно",
"pid": "PID", "noFee": "Без комиссии",
"saveSuccess": "Сохранение успешно", "notify_url": "URL уведомления",
"showName": "Показать имя", "paymentManagement": "Управление платежами",
"showNameDescription": "Используется для отображения на фронтенде", "percentFee": "Процент",
"stripe": { "platform": "Платформа",
"publicKey": "ОТКРЫТЫЙ КЛЮЧ", "searchPlaceholder": "Введите поисковые запросы",
"secretKey": "СЕКРЕТНЫЙ КЛЮЧ", "selectPlatform": "Выберите платформу",
"webhookSecret": "СЕКРЕТ ПОДПИСИ ВЕБХУКА" "selectType": "Выберите тип оплаты",
}, "submit": "Отправить",
"url": "URL", "type": "Тип",
"wechatPay": "WeChat Pay" "updateSuccess": "Успешно обновлено"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "ยกเลิก",
"confirm": "ยืนยัน",
"confirmDelete": "ยืนยันการลบ",
"create": "สร้างโฆษณา",
"createAds": "สร้างโฆษณา",
"createSuccess": "สร้างสำเร็จ",
"delete": "ลบ",
"deleteSuccess": "ลบสำเร็จ",
"deleteWarning": "คุณแน่ใจหรือว่าต้องการลบโฆษณานี้?",
"disabled": "ปิดใช้งาน",
"edit": "แก้ไข",
"editAds": "แก้ไขโฆษณา",
"enabled": "เปิดใช้งาน",
"form": {
"cancel": "ยกเลิก",
"confirm": "ยืนยัน",
"content": "เนื้อหา",
"description": "คำอธิบาย",
"endTime": "เวลาสิ้นสุด",
"enterContent": "กรุณาใส่เนื้อหาโฆษณา",
"enterDescription": "กรุณาใส่คำอธิบายโฆษณา",
"enterEndTime": "กรุณาเลือกเวลาสิ้นสุด",
"enterStartTime": "กรุณาเลือกเวลาเริ่มต้น",
"enterTargetUrl": "กรุณาใส่ URL เป้าหมาย",
"enterTitle": "กรุณาใส่ชื่อโฆษณา",
"startTime": "เวลาเริ่มต้น",
"targetUrl": "URL เป้าหมาย",
"title": "ชื่อ",
"type": "ประเภทโฆษณา",
"typeImage": "ภาพ",
"typeVideo": "วิดีโอ"
},
"status": "สถานะ",
"targetUrl": "URL เป้าหมาย",
"title": "ชื่อ",
"type": "ประเภท",
"updateSuccess": "อัปเดตสำเร็จ",
"validityPeriod": "ระยะเวลาที่ใช้ได้"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "บล็อกเครื่องเสมือน",
"blockVirtualMachineDescription": "เมื่อเปิดใช้งาน อุปกรณ์จะไม่สามารถทำงานบนเครื่องเสมือนหรืออีมูเลเตอร์ได้",
"communicationKey": "กุญแจการสื่อสาร",
"communicationKeyDescription": "กุญแจการสื่อสารใช้สำหรับการสื่อสารที่ปลอดภัยระหว่างอุปกรณ์และเซิร์ฟเวอร์",
"enable": "เปิดใช้งาน", "enable": "เปิดใช้งาน",
"enableDescription": "หลังจากเปิดใช้งาน จะรองรับการเข้าสู่ระบบและการลงทะเบียนด้วยตัวระบุอุปกรณ์หลายตัว เช่น IMEI/IDFA/IDFV/AndroidID/ที่อยู่ Mac" "enableDescription": "หลังจากเปิดใช้งาน จะรองรับการเข้าสู่ระบบและการลงทะเบียนด้วยตัวระบุอุปกรณ์หลายตัว เช่น IMEI/IDFA/IDFV/AndroidID/ที่อยู่ Mac",
"enableSecurity": "เปิดใช้งานการเข้ารหัสการสื่อสาร",
"enableSecurityDescription": "เมื่อเปิดใช้งาน การสื่อสารระหว่างอุปกรณ์และเซิร์ฟเวอร์จะถูกเข้ารหัส",
"saveFailed": "การบันทึกล้มเหลว",
"saveSuccess": "การบันทึกสำเร็จ",
"showAds": "แสดงโฆษณา",
"showAdsDescription": "เมื่อเปิดใช้งาน โฆษณาจะถูกแสดงบนอุปกรณ์"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "การตั้งค่า ADS",
"Announcement Management": "การจัดการประกาศ", "Announcement Management": "การจัดการประกาศ",
"Apple": "Apple ID", "Apple": "Apple ID",
"Auth Control": "การควบคุมการยืนยันตัวตน", "Auth Control": "การควบคุมการยืนยันตัวตน",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "ชำระเงินผ่านอาลีเพย์", "AlipayF2F": "Alipay แบบพบหน้า",
"alipayf2f": { "EPay": "EPay",
"appId": "รหัสแอปพลิเคชัน Alipay", "Stripe": "Stripe",
"invoiceName": "ชื่อผลิตภัณฑ์ที่กำหนดเอง", "applyForPayment": "ขอชำระเงิน",
"invoiceNameDescription": "จะแสดงในใบแจ้งหนี้ของ Alipay", "balance": "ยอดคงเหลือ",
"privateKey": "กุญแจส่วนตัวของ Alipay", "batchDelete": "ลบเป็นชุด",
"publicKey": "กุญแจสาธารณะของ Alipay", "cancel": "ยกเลิก",
"sandbox": "โหมดแซนด์บ็อกซ์", "config": "การตั้งค่า",
"sandboxDescription": "เปิดใช้งานโหมดแซนด์บ็อกซ์เพื่อทดสอบการชำระเงิน" "configInfo": "ข้อมูลการตั้งค่า",
}, "configPlaceholder": "กรุณากรอกการตั้งค่า {field} ที่ให้มา",
"confirm": "ยืนยัน",
"confirmDelete": "ยืนยันการลบ",
"copy": "คัดลอก",
"copySuccess": "คัดลอกสำเร็จ",
"create": "เพิ่มวิธีการชำระเงิน",
"createPayment": "เพิ่มวิธีการชำระเงิน",
"createSuccess": "สร้างสำเร็จ",
"delete": "ลบ",
"deleteSuccess": "ลบสำเร็จ",
"deleteWarning": "คุณแน่ใจหรือไม่ว่าต้องการลบวิธีการชำระเงินนี้? การกระทำนี้ไม่สามารถย้อนกลับได้",
"description": "คำอธิบาย",
"descriptionPlaceholder": "กรอกคำอธิบายวิธีการชำระเงิน",
"domain": "โดเมน",
"domainPlaceholder": "ไม่บังคับ เช่น {example}",
"edit": "แก้ไข",
"editPayment": "แก้ไขวิธีการชำระเงิน",
"enable": "เปิดใช้งาน", "enable": "เปิดใช้งาน",
"enableDescription": "เปิดใช้งานวิธีการชำระเงินนี้", "feeAmount": "จำนวนคงที่",
"epay": {
"key": "คีย์",
"pid": "พีไอดี",
"url": "ยูอาร์แอล"
},
"feeMode": "วิธีการคิดค่าบริการ", "feeMode": "วิธีการคิดค่าบริการ",
"feeModeDescription": "วิธีการคิดค่าธรรมเนียมเพิ่มเติม",
"feeModeItems": ["ไม่มีค่าธรรมเนียม", "เปอร์เซ็นต์", "จำนวนเงินคงที่", "ทั้งสองอย่าง"],
"feePercent": "เปอร์เซ็นต์ค่าธรรมเนียม (ไม่บังคับ)", "feePercent": "เปอร์เซ็นต์ค่าธรรมเนียม (ไม่บังคับ)",
"feePercentDescription": "เพิ่มค่าธรรมเนียมจากยอดสั่งซื้อ",
"fixedFee": "ค่าธรรมเนียมคงที่ (ไม่บังคับ)", "fixedFee": "ค่าธรรมเนียมคงที่ (ไม่บังคับ)",
"fixedFeeDescription": "เพิ่มค่าธรรมเนียมคงที่เหนือจำนวนเงินในคำสั่งซื้อ", "handlingFee": "ค่าธรรมเนียมการจัดการ",
"iconUrl": "URL ไอคอน (ไม่บังคับ)", "icon": "ไอคอน",
"iconUrlDescription": "ใช้สำหรับแสดงผลด้านหน้า", "iconPlaceholder": "กรอก URL ไอคอน",
"inputPlaceholder": "กรุณาใส่ข้อมูล", "mark": "ตัวระบุ",
"key": "กุญแจ", "markPlaceholder": "กรอกตัวระบุวิธีการชำระเงิน",
"notifyUrl": "โดเมนการแจ้งเตือนที่กำหนดเอง (ไม่บังคับ)", "name": "ชื่อ",
"notifyUrlDescription": "การแจ้งเตือนเกตเวย์จะถูกส่งไปยังโดเมนนี้", "namePlaceholder": "กรอกชื่อวิธีการชำระเงิน",
"payForRecommendations": "ชำระเงินสำหรับคำแนะนำ", "nameRequired": "ชื่อเป็นสิ่งจำเป็น",
"pid": "PID", "noFee": "ไม่มีค่าธรรมเนียม",
"saveSuccess": "บันทึกสำเร็จ", "notify_url": "URL การแจ้งเตือน",
"showName": "แสดงชื่อ", "paymentManagement": "การจัดการการชำระเงิน",
"showNameDescription": "ใช้สำหรับแสดงผลด้านหน้า", "percentFee": "เปอร์เซ็นต์",
"stripe": { "platform": "แพลตฟอร์ม",
"publicKey": "PUBLIC KEY", "searchPlaceholder": "กรอกคำค้นหา",
"secretKey": "SECRET KEY", "selectPlatform": "เลือกแพลตฟอร์ม",
"webhookSecret": "WEBHOOK คีย์ลับ" "selectType": "เลือกประเภทการชำระเงิน",
}, "submit": "ส่ง",
"url": "URL", "type": "ประเภท",
"wechatPay": "วีแชทเพย์" "updateSuccess": "อัปเดตสำเร็จ"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "İptal",
"confirm": "Onayla",
"confirmDelete": "Silmeyi Onayla",
"create": "Reklam Oluştur",
"createAds": "Reklam Oluştur",
"createSuccess": "Başarıyla oluşturuldu",
"delete": "Sil",
"deleteSuccess": "Başarıyla silindi",
"deleteWarning": "Bu reklamı silmek istediğinize emin misiniz?",
"disabled": "Devre Dışı",
"edit": "Düzenle",
"editAds": "Reklamı Düzenle",
"enabled": "Etkin",
"form": {
"cancel": "İptal",
"confirm": "Onayla",
"content": "İçerik",
"description": "Açıklama",
"endTime": "Bitiş Zamanı",
"enterContent": "Lütfen reklam içeriğini girin",
"enterDescription": "Lütfen reklam açıklamasını girin",
"enterEndTime": "Lütfen bitiş zamanını seçin",
"enterStartTime": "Lütfen başlangıç zamanını seçin",
"enterTargetUrl": "Lütfen hedef URL'yi girin",
"enterTitle": "Lütfen reklam başlığını girin",
"startTime": "Başlangıç Zamanı",
"targetUrl": "Hedef URL",
"title": "Başlık",
"type": "Reklam Türü",
"typeImage": "Görüntü",
"typeVideo": "Video"
},
"status": "Durum",
"targetUrl": "Hedef URL",
"title": "Başlık",
"type": "Tür",
"updateSuccess": "Başarıyla güncellendi",
"validityPeriod": "Geçerlilik Süresi"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Sanal Makineyi Engelle",
"blockVirtualMachineDescription": "Etkinleştirildiğinde, cihazların sanal makinelerde veya emülatörlerde çalışması engellenecektir",
"communicationKey": "İletişim Anahtarı",
"communicationKeyDescription": "İletişim anahtarı, cihazlar ve sunucular arasında güvenli iletişim için kullanılır",
"enable": "Etkinleştir", "enable": "Etkinleştir",
"enableDescription": "Etkinleştirildikten sonra, giriş ve kayıt için IMEI/IDFA/IDFV/AndroidID/Mac adresi gibi birden fazla cihaz tanımlayıcısı desteklenir." "enableDescription": "Etkinleştirildikten sonra, giriş ve kayıt için IMEI/IDFA/IDFV/AndroidID/Mac adresi gibi birden fazla cihaz tanımlayıcısı desteklenir.",
"enableSecurity": "İletişim Şifrelemesini Etkinleştir",
"enableSecurityDescription": "Etkinleştirildiğinde, cihazlar ve sunucular arasındaki iletişim şifrelenmiş olacaktır",
"saveFailed": "Kaydetme başarısız oldu",
"saveSuccess": "Başarıyla kaydedildi",
"showAds": "Reklamları Göster",
"showAdsDescription": "Etkinleştirildiğinde, cihazlarda reklamlar görüntülenecektir"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "ADS Yapılandırması",
"Announcement Management": "Duyuru Yönetimi", "Announcement Management": "Duyuru Yönetimi",
"Apple": "Apple Kimliği", "Apple": "Apple Kimliği",
"Auth Control": "Yetki Kontrolü", "Auth Control": "Yetki Kontrolü",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Alipay ile ödeme", "AlipayF2F": "Alipay Yüz Yüze",
"alipayf2f": { "EPay": "EPay",
"appId": "Alipay Uygulama Kimliği", "Stripe": "Stripe",
"invoiceName": "Özel Ürün Adı", "applyForPayment": "Ödeme Başvurusu",
"invoiceNameDescription": "Alipay faturasına gösterilecektir", "balance": "Bakiye",
"privateKey": "Alipay Özel Anahtarı", "batchDelete": "Toplu Sil",
"publicKey": "Alipay Genel Anahtarı", "cancel": "İptal",
"sandbox": "Sandbox Modu", "config": "Yapılandırma",
"sandboxDescription": "Ödemeyi test etmek için sandbox modunu etkinleştirin" "configInfo": "Yapılandırma Bilgisi",
}, "configPlaceholder": "Lütfen sağlanan {field} yapılandırmasını doldurun",
"confirm": "Onayla",
"confirmDelete": "Silme İşlemini Onayla",
"copy": "Kopyala",
"copySuccess": "Başarıyla kopyalandı",
"create": "Ödeme Yöntemi Ekle",
"createPayment": "Ödeme Yöntemi Ekle",
"createSuccess": "Başarıyla oluşturuldu",
"delete": "Sil",
"deleteSuccess": "Başarıyla silindi",
"deleteWarning": "Bu ödeme yöntemini silmek istediğinize emin misiniz? Bu işlem geri alınamaz.",
"description": "Açıklama",
"descriptionPlaceholder": "Ödeme yöntemi açıklamasını girin",
"domain": "Alan Adı",
"domainPlaceholder": "isteğe bağlı, örn. {example}",
"edit": "Düzenle",
"editPayment": "Ödeme Yöntemini Düzenle",
"enable": "Etkinleştir", "enable": "Etkinleştir",
"enableDescription": "Bu ödeme yöntemini etkinleştir", "feeAmount": "Sabit Tutar",
"epay": {
"key": "ANAHTAR",
"pid": "PID",
"url": "URL"
},
"feeMode": "Ücretlendirme Modu", "feeMode": "Ücretlendirme Modu",
"feeModeDescription": "Ekstra ücretin tahsilat yöntemi",
"feeModeItems": ["Ücretsiz", "Yüzde", "Sabit Tutar", "Her İkisi"],
"feePercent": "Yüzde Ücreti (isteğe bağlı)", "feePercent": "Yüzde Ücreti (isteğe bağlı)",
"feePercentDescription": "Sipariş tutarının üzerine eklenen ücret",
"fixedFee": "Sabit Ücret (isteğe bağlı)", "fixedFee": "Sabit Ücret (isteğe bağlı)",
"fixedFeeDescription": "Sipariş tutarına ek olarak sabit ücret eklenir", "handlingFee": "İşlem Ücreti",
"iconUrl": "Simge URL'si (isteğe bağlı)", "icon": "Simge",
"iconUrlDescription": "Ön uçta görüntüleme için kullanılır", "iconPlaceholder": "Simge URL'sini girin",
"inputPlaceholder": "Lütfen girin", "mark": "Tanımlayıcı",
"key": "ANAHTAR", "markPlaceholder": "Ödeme yöntemi tanımlayıcısını girin",
"notifyUrl": "Özel bildirim alanı (isteğe bağlı)", "name": "İsim",
"notifyUrlDescription": "Ağ geçidi bildirimi bu alana gönderilecektir", "namePlaceholder": "Ödeme yöntemi adını girin",
"payForRecommendations": "Öneriler için ödeme yap", "nameRequired": "İsim gereklidir",
"pid": "PID", "noFee": "Ücret Yok",
"saveSuccess": "Başarıyla kaydedildi", "notify_url": "Bildirim URL'si",
"showName": "Görünen Ad", "paymentManagement": "Ödeme Yönetimi",
"showNameDescription": "Ön uçta görüntüleme için kullanılır", "percentFee": "Yüzde",
"stripe": { "platform": "Platform",
"publicKey": "GENEL ANAHTAR", "searchPlaceholder": "Arama terimlerini girin",
"secretKey": "GİZLİ ANAHTAR", "selectPlatform": "Platform Seçin",
"webhookSecret": "WEBHOOK GİZLİ İMZA" "selectType": "Ödeme türünü seçin",
}, "submit": "Gönder",
"url": "URL", "type": "Tür",
"wechatPay": "WeChat Pay" "updateSuccess": "Başarıyla güncellendi"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Скасувати",
"confirm": "Підтвердити",
"confirmDelete": "Підтвердити видалення",
"create": "Створити оголошення",
"createAds": "Створити рекламу",
"createSuccess": "Успішно створено",
"delete": "Видалити",
"deleteSuccess": "Успішно видалено",
"deleteWarning": "Ви впевнені, що хочете видалити це оголошення?",
"disabled": "Вимкнено",
"edit": "Редагувати",
"editAds": "Редагувати рекламу",
"enabled": "Увімкнено",
"form": {
"cancel": "Скасувати",
"confirm": "Підтвердити",
"content": "Зміст",
"description": "Опис",
"endTime": "Час закінчення",
"enterContent": "Будь ласка, введіть зміст оголошення",
"enterDescription": "Будь ласка, введіть опис оголошення",
"enterEndTime": "Будь ласка, виберіть час закінчення",
"enterStartTime": "Будь ласка, виберіть час початку",
"enterTargetUrl": "Будь ласка, введіть цільовий URL",
"enterTitle": "Будь ласка, введіть заголовок оголошення",
"startTime": "Час початку",
"targetUrl": "Цільовий URL",
"title": "Заголовок",
"type": "Тип оголошення",
"typeImage": "Зображення",
"typeVideo": "Відео"
},
"status": "Статус",
"targetUrl": "Цільовий URL",
"title": "Заголовок",
"type": "Тип",
"updateSuccess": "Успішно оновлено",
"validityPeriod": "Термін дії"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Блокувати віртуальну машину",
"blockVirtualMachineDescription": "При увімкненні пристрої не зможуть працювати на віртуальних машинах або емуляторах",
"communicationKey": "Ключ зв'язку",
"communicationKeyDescription": "Ключ зв'язку використовується для безпечного зв'язку між пристроями та серверами",
"enable": "Увімкнути", "enable": "Увімкнути",
"enableDescription": "Після увімкнення підтримуються кілька ідентифікаторів пристроїв, таких як IMEI/IDFA/IDFV/AndroidID/Mac-адреса для входу та реєстрації" "enableDescription": "Після увімкнення підтримуються кілька ідентифікаторів пристроїв, таких як IMEI/IDFA/IDFV/AndroidID/Mac-адреса для входу та реєстрації",
"enableSecurity": "Увімкнути шифрування зв'язку",
"enableSecurityDescription": "При увімкненні зв'язок між пристроями та серверами буде зашифровано",
"saveFailed": "Не вдалося зберегти",
"saveSuccess": "Збережено успішно",
"showAds": "Показувати рекламу",
"showAdsDescription": "При увімкненні на пристроях буде відображатися реклама"
} }
+1
View File
@@ -1,4 +1,5 @@
{ {
"ADS Config": "Конфігурація ADS",
"Announcement Management": "Управління оголошеннями", "Announcement Management": "Управління оголошеннями",
"Apple": "Apple ID", "Apple": "Apple ID",
"Auth Control": "Контроль автентифікації", "Auth Control": "Контроль автентифікації",
+46 -38
View File
@@ -1,44 +1,52 @@
{ {
"aliPay": "Оплата через Alipay", "AlipayF2F": "Alipay Face to Face",
"alipayf2f": { "EPay": "EPay",
"appId": "Ідентифікатор додатку Alipay", "Stripe": "Stripe",
"invoiceName": "Назва продукту на замовлення", "applyForPayment": "Подати заявку на оплату",
"invoiceNameDescription": "Буде відображено у рахунку Alipay", "balance": "Баланс",
"privateKey": "Приватний ключ Alipay", "batchDelete": "Пакетне видалення",
"publicKey": "Публічний ключ Alipay", "cancel": "Скасувати",
"sandbox": "Режим пісочниці", "config": "Налаштування",
"sandboxDescription": "Увімкніть режим пісочниці для тестування платежів" "configInfo": "Інформація про налаштування",
}, "configPlaceholder": "Будь ласка, заповніть надану конфігурацію {field}",
"confirm": "Підтвердити",
"confirmDelete": "Підтвердити видалення",
"copy": "Копіювати",
"copySuccess": "Успішно скопійовано",
"create": "Додати спосіб оплати",
"createPayment": "Додати спосіб оплати",
"createSuccess": "Успішно створено",
"delete": "Видалити",
"deleteSuccess": "Успішно видалено",
"deleteWarning": "Ви впевнені, що хочете видалити цей спосіб оплати? Цю дію не можна скасувати.",
"description": "Опис",
"descriptionPlaceholder": "Введіть опис способу оплати",
"domain": "Домен",
"domainPlaceholder": "необов'язково, наприклад, {example}",
"edit": "Редагувати",
"editPayment": "Редагувати спосіб оплати",
"enable": "Увімкнути", "enable": "Увімкнути",
"enableDescription": "Увімкнути цей спосіб оплати", "feeAmount": "Фіксована сума",
"epay": {
"key": "КЛЮЧ",
"pid": "PID",
"url": "URL"
},
"feeMode": "Спосіб оплати", "feeMode": "Спосіб оплати",
"feeModeDescription": "Спосіб стягнення додаткової комісії",
"feeModeItems": ["Без комісії", "Відсоток", "Фіксована сума", "Обидва варіанти"],
"feePercent": "Відсоткова комісія (необов'язково)", "feePercent": "Відсоткова комісія (необов'язково)",
"feePercentDescription": "Додати комісію до суми замовлення",
"fixedFee": "Фіксована плата (необов'язково)", "fixedFee": "Фіксована плата (необов'язково)",
"fixedFeeDescription": "Додати фіксовану плату до суми замовлення", "handlingFee": "Плата за обробку",
"iconUrl": "URL значка (необов'язково)", "icon": "Іконка",
"iconUrlDescription": "Використовується для відображення на фронтенді", "iconPlaceholder": "Введіть URL іконки",
"inputPlaceholder": "Введіть, будь ласка", "mark": "Ідентифікатор",
"key": "КЛЮЧ", "markPlaceholder": "Введіть ідентифікатор способу оплати",
"notifyUrl": "Користувацька область сповіщень (необов'язково)", "name": "Назва",
"notifyUrlDescription": "Сповіщення шлюзу буде надіслано на цей домен", "namePlaceholder": "Введіть назву способу оплати",
"payForRecommendations": "Оплатити рекомендації", "nameRequired": "Назва є обов'язковою",
"pid": "PID", "noFee": "Без комісії",
"saveSuccess": "Збережено успішно", "notify_url": "URL сповіщення",
"showName": "Показати ім'я", "paymentManagement": "Управління платежами",
"showNameDescription": "Використовується для відображення на фронтенді", "percentFee": "Відсоток",
"stripe": { "platform": "Платформа",
"publicKey": "ПУБЛІЧНИЙ КЛЮЧ", "searchPlaceholder": "Введіть пошукові терміни",
"secretKey": "СЕКРЕТНИЙ КЛЮЧ", "selectPlatform": "Виберіть платформу",
"webhookSecret": "ПІДПИС ВЕБХУКА" "selectType": "Виберіть тип оплати",
}, "submit": "Надіслати",
"url": "URL", "type": "Тип",
"wechatPay": "WeChat Pay" "updateSuccess": "Успішно оновлено"
} }
+40
View File
@@ -0,0 +1,40 @@
{
"cancel": "Hủy",
"confirm": "Xác nhận",
"confirmDelete": "Xác nhận xóa",
"create": "Tạo quảng cáo",
"createAds": "Tạo quảng cáo",
"createSuccess": "Tạo thành công",
"delete": "Xóa",
"deleteSuccess": "Xóa thành công",
"deleteWarning": "Bạn có chắc chắn muốn xóa quảng cáo này không?",
"disabled": "Đã tắt",
"edit": "Chỉnh sửa",
"editAds": "Chỉnh sửa quảng cáo",
"enabled": "Đã bật",
"form": {
"cancel": "Hủy",
"confirm": "Xác nhận",
"content": "Nội dung",
"description": "Mô tả",
"endTime": "Thời gian kết thúc",
"enterContent": "Vui lòng nhập nội dung quảng cáo",
"enterDescription": "Vui lòng nhập mô tả quảng cáo",
"enterEndTime": "Vui lòng chọn thời gian kết thúc",
"enterStartTime": "Vui lòng chọn thời gian bắt đầu",
"enterTargetUrl": "Vui lòng nhập URL mục tiêu",
"enterTitle": "Vui lòng nhập tiêu đề quảng cáo",
"startTime": "Thời gian bắt đầu",
"targetUrl": "URL mục tiêu",
"title": "Tiêu đề",
"type": "Loại quảng cáo",
"typeImage": "Hình ảnh",
"typeVideo": "Video"
},
"status": "Trạng thái",
"targetUrl": "URL mục tiêu",
"title": "Tiêu đề",
"type": "Loại",
"updateSuccess": "Cập nhật thành công",
"validityPeriod": "Thời gian hiệu lực"
}
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"blockVirtualMachine": "Chặn Máy Ảo",
"blockVirtualMachineDescription": "Khi được kích hoạt, các thiết bị sẽ không thể chạy trên máy ảo hoặc trình giả lập",
"communicationKey": "Khóa Giao Tiếp",
"communicationKeyDescription": "Khóa giao tiếp được sử dụng để bảo mật giao tiếp giữa các thiết bị và máy chủ",
"enable": "Kích hoạt", "enable": "Kích hoạt",
"enableDescription": "Sau khi kích hoạt, nhiều định danh thiết bị như IMEI/IDFA/IDFV/AndroidID/Địa chỉ Mac sẽ được hỗ trợ cho việc đăng nhập và đăng ký" "enableDescription": "Sau khi kích hoạt, nhiều định danh thiết bị như IMEI/IDFA/IDFV/AndroidID/Địa chỉ Mac sẽ được hỗ trợ cho việc đăng nhập và đăng ký",
"enableSecurity": "Kích Hoạt Mã Hóa Giao Tiếp",
"enableSecurityDescription": "Khi được kích hoạt, giao tiếp giữa các thiết bị và máy chủ sẽ được mã hóa",
"saveFailed": "Lưu không thành công",
"saveSuccess": "Lưu thành công",
"showAds": "Hiển Thị Quảng Cáo",
"showAdsDescription": "Khi được kích hoạt, quảng cáo sẽ được hiển thị trên các thiết bị"
} }

Some files were not shown because too many files have changed in this diff Show More