Compare commits

...

18 Commits

Author SHA1 Message Date
semantic-release-bot 5b64389544 🔖 chore(release): v1.0.0-beta.17 [skip ci]
# [1.0.0-beta.17](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.16...v1.0.0-beta.17) (2025-02-21)

### 🐛 Bug Fixes

* **auth**: Refactor reset password form to simplify code input and update placeholder text ([23833b4](https://github.com/perfect-panel/ppanel-web/commit/23833b4))
2025-02-21 13:26:11 +00:00
web@ppanel 23833b47d1 🐛 fix(auth): Refactor reset password form to simplify code input and update placeholder text 2025-02-21 20:23:30 +07:00
semantic-release-bot c3eff0a0e7 🔖 chore(release): v1.0.0-beta.16 [skip ci]
# [1.0.0-beta.16](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.15...v1.0.0-beta.16) (2025-02-21)

### 🐛 Bug Fixes

* **auth**: Simplify email verification code input rendering ([6f7bc37](https://github.com/perfect-panel/ppanel-web/commit/6f7bc37))
2025-02-21 13:18:47 +00:00
web@ppanel 6f7bc37233 🐛 fix(auth): Simplify email verification code input rendering 2025-02-21 20:16:02 +07:00
semantic-release-bot b2e8fadaf3 🔖 chore(release): v1.0.0-beta.15 [skip ci]
# [1.0.0-beta.15](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.14...v1.0.0-beta.15) (2025-02-21)

### 🐛 Bug Fixes

* **profile**: Restore filter to ensure only valid OAuth accounts are shown ([315c8f9](https://github.com/perfect-panel/ppanel-web/commit/315c8f9))
2025-02-21 12:59:02 +00:00
web@ppanel 315c8f9afe 🐛 fix(profile): Restore filter to ensure only valid OAuth accounts are shown 2025-02-21 19:55:24 +07:00
semantic-release-bot 0fb0d8bc11 🔖 chore(release): v1.0.0-beta.14 [skip ci]
# [1.0.0-beta.14](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.13...v1.0.0-beta.14) (2025-02-21)

### 🐛 Bug Fixes

* **locales**: Fixed description in multilingual files, updated text related to email registration functionality ([c356bc2](https://github.com/perfect-panel/ppanel-web/commit/c356bc2))
2025-02-21 07:07:36 +00:00
web@ppanel c356bc26ff 🐛 fix(locales): Fixed description in multilingual files, updated text related to email registration functionality 2025-02-21 14:04:15 +07:00
semantic-release-bot 23c974a94d 🔖 chore(release): v1.0.0-beta.13 [skip ci]
# [1.0.0-beta.13](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.12...v1.0.0-beta.13) (2025-02-21)

### 🐛 Bug Fixes

* **api**: Fix type error in API request and add return URL parameter ([ee286dd](https://github.com/perfect-panel/ppanel-web/commit/ee286dd))
2025-02-21 06:03:00 +00:00
web@ppanel ee286dd629 🐛 fix(api): Fix type error in API request and add return URL parameter 2025-02-21 12:59:23 +07:00
semantic-release-bot 4418c47f4f 🔖 chore(release): v1.0.0-beta.12 [skip ci]
# [1.0.0-beta.12](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.11...v1.0.0-beta.12) (2025-02-18)

### 🐛 Bug Fixes

* More bugs ([2d88a3a](https://github.com/perfect-panel/ppanel-web/commit/2d88a3a))
2025-02-18 14:57:24 +00:00
web@ppanel 2d88a3a81d 🐛 fix: More bugs 2025-02-18 21:53:24 +07:00
semantic-release-bot 1f29506179 🔖 chore(release): v1.0.0-beta.11 [skip ci]
# [1.0.0-beta.11](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.10...v1.0.0-beta.11) (2025-02-16)

### 🐛 Bug Fixes

* **email**: Update platform configuration handling to use current ref for consistency ([c90175b](https://github.com/perfect-panel/ppanel-web/commit/c90175b))
2025-02-16 12:09:00 +00:00
web@ppanel c90175b6eb 🐛 fix(email): Update platform configuration handling to use current ref for consistency 2025-02-16 19:06:17 +07:00
semantic-release-bot 5cf573ab03 🔖 chore(release): v1.0.0-beta.10 [skip ci]
# [1.0.0-beta.10](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.9...v1.0.0-beta.10) (2025-02-16)

### 🐛 Bug Fixes

* **subscribe**: Update forms to include refetch functionality and improve toast messages ([fc55e95](https://github.com/perfect-panel/ppanel-web/commit/fc55e95))
2025-02-16 10:14:25 +00:00
web@ppanel fc55e9544d 🐛 fix(subscribe): Update forms to include refetch functionality and improve toast messages 2025-02-16 17:08:34 +07:00
semantic-release-bot 855d1b096f 🔖 chore(release): v1.0.0-beta.9 [skip ci]
# [1.0.0-beta.9](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.8...v1.0.0-beta.9) (2025-02-15)

### 🐛 Bug Fixes

* **register**: Adjust user email verification logic to handle domain suffix checks correctly ([686aa2d](https://github.com/perfect-panel/ppanel-web/commit/686aa2d))
2025-02-15 15:02:16 +00:00
web@ppanel 686aa2d0ba 🐛 fix(register): Adjust user email verification logic to handle domain suffix checks correctly 2025-02-15 21:58:25 +07:00
80 changed files with 372 additions and 196 deletions
+94 -34
View File
@@ -1,48 +1,108 @@
<a name="readme-top"></a> <a name="readme-top"></a>
# Changelog # Changelog
# [1.0.0-beta.8](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.7...v1.0.0-beta.8) (2025-02-15) # [1.0.0-beta.17](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.16...v1.0.0-beta.17) (2025-02-21)
### ✨ Features
* **accounts**: Update third-party account binding and unbinding ([1841552](https://github.com/perfect-panel/ppanel-web/commit/1841552))
* **auth-control**: Adding phone number labels to mobile verification configurations in multiple languages ([046740f](https://github.com/perfect-panel/ppanel-web/commit/046740f))
* **auth-control**: Update general ([3883646](https://github.com/perfect-panel/ppanel-web/commit/3883646))
* **auth**: Add type parameter to SendCode and update related API typings ([4198871](https://github.com/perfect-panel/ppanel-web/commit/4198871))
* **auth**: Refactor mobile authentication config to support whitelist functionality ([c761ec7](https://github.com/perfect-panel/ppanel-web/commit/c761ec7))
* **device**: Modify IMEI to device identifier support ([e3f9ef6](https://github.com/perfect-panel/ppanel-web/commit/e3f9ef6))
* **imei**: Add IMEI related internationalization support and menu items ([13c3337](https://github.com/perfect-panel/ppanel-web/commit/13c3337))
* **locales**: Add kick offline confirmation and success messages in multiple languages ([5db5343](https://github.com/perfect-panel/ppanel-web/commit/5db5343))
* **locales**: Update 'sms' to 'mobile' in authentication methods across multiple languages ([fea2171](https://github.com/perfect-panel/ppanel-web/commit/fea2171))
* **log**: Add message log retrieval functionality and update related typings ([1c0ecae](https://github.com/perfect-panel/ppanel-web/commit/1c0ecae))
* **profile**: Update localization strings and enhance third-party account binding ([2d1effb](https://github.com/perfect-panel/ppanel-web/commit/2d1effb))
* **release**: Extend supported platforms for Docker images, closes [#9](https://github.com/perfect-panel/ppanel-web/issues/9) ([e3a31eb](https://github.com/perfect-panel/ppanel-web/commit/e3a31eb))
* **subscription**: Add delete user subscription functionality ([1fc3a10](https://github.com/perfect-panel/ppanel-web/commit/1fc3a10))
* **ui**: Update input components and enhance card minimum width for better layout ([8a02310](https://github.com/perfect-panel/ppanel-web/commit/8a02310))
* **user**: Add user Detail ([3a3d223](https://github.com/perfect-panel/ppanel-web/commit/3a3d223))
* **user**: Add User Detail ([fdaf11b](https://github.com/perfect-panel/ppanel-web/commit/fdaf11b))
### 🐛 Bug Fixes ### 🐛 Bug Fixes
* **auth-control**: Fix citation error for platform values ([c940f3c](https://github.com/perfect-panel/ppanel-web/commit/c940f3c)) * **auth**: Refactor reset password form to simplify code input and update placeholder text ([23833b4](https://github.com/perfect-panel/ppanel-web/commit/23833b4))
* **auth-control**: Fix citation error for platform values ([28813d2](https://github.com/perfect-panel/ppanel-web/commit/28813d2))
* **auth-control**: Rename phone_variable to phone_number in mobile verification configuration ([e5455aa](https://github.com/perfect-panel/ppanel-web/commit/e5455aa))
* **auth**: Update authentication configuration and localization strings ([47f2c58](https://github.com/perfect-panel/ppanel-web/commit/47f2c58))
* **locales**: Update expiration time description from minutes to seconds in multiple languages ([5bac933](https://github.com/perfect-panel/ppanel-web/commit/5bac933))
* **notify**: Ensure user info is updated after notification settings submission ([9bc3a94](https://github.com/perfect-panel/ppanel-web/commit/9bc3a94))
* **notify**: Set default values for notification settings to false ([3652819](https://github.com/perfect-panel/ppanel-web/commit/3652819))
* **third-party-accounts**: Remove mobile display logic from third-party accounts component ([b4946f7](https://github.com/perfect-panel/ppanel-web/commit/b4946f7))
* **third-party-accounts**: Update redirect property name in binding response handling ([012e83a](https://github.com/perfect-panel/ppanel-web/commit/012e83a))
* **user**: Refactor user form validation and reset password fields ([6733fc2](https://github.com/perfect-panel/ppanel-web/commit/6733fc2))
* **user**: Update locales ([4e7d249](https://github.com/perfect-panel/ppanel-web/commit/4e7d249))
* **user**: Update notification and verify code settings ([574b043](https://github.com/perfect-panel/ppanel-web/commit/574b043))
# [1.0.0-beta.16](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.15...v1.0.0-beta.16) (2025-02-21)
### 🐛 Bug Fixes
* **auth**: Simplify email verification code input rendering ([6f7bc37](https://github.com/perfect-panel/ppanel-web/commit/6f7bc37))
# [1.0.0-beta.15](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.14...v1.0.0-beta.15) (2025-02-21)
### 🐛 Bug Fixes
* **profile**: Restore filter to ensure only valid OAuth accounts are shown ([315c8f9](https://github.com/perfect-panel/ppanel-web/commit/315c8f9))
# [1.0.0-beta.14](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.13...v1.0.0-beta.14) (2025-02-21)
### 🐛 Bug Fixes
* **locales**: Fixed description in multilingual files, updated text related to email registration functionality ([c356bc2](https://github.com/perfect-panel/ppanel-web/commit/c356bc2))
# [1.0.0-beta.13](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.12...v1.0.0-beta.13) (2025-02-21)
### 🐛 Bug Fixes
* **api**: Fix type error in API request and add return URL parameter ([ee286dd](https://github.com/perfect-panel/ppanel-web/commit/ee286dd))
<a name="readme-top"></a>
# Changelog
# [1.0.0-beta.12](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.11...v1.0.0-beta.12) (2025-02-18)
### 🐛 Bug Fixes
- More bugs ([2d88a3a](https://github.com/perfect-panel/ppanel-web/commit/2d88a3a))
# [1.0.0-beta.11](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.10...v1.0.0-beta.11) (2025-02-16)
### 🐛 Bug Fixes
- **email**: Update platform configuration handling to use current ref for consistency ([c90175b](https://github.com/perfect-panel/ppanel-web/commit/c90175b))
# [1.0.0-beta.10](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.9...v1.0.0-beta.10) (2025-02-16)
### 🐛 Bug Fixes
- **subscribe**: Update forms to include refetch functionality and improve toast messages ([fc55e95](https://github.com/perfect-panel/ppanel-web/commit/fc55e95))
# [1.0.0-beta.9](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.8...v1.0.0-beta.9) (2025-02-15)
### 🐛 Bug Fixes
- **register**: Adjust user email verification logic to handle domain suffix checks correctly ([686aa2d](https://github.com/perfect-panel/ppanel-web/commit/686aa2d))
# [1.0.0-beta.8](https://github.com/perfect-panel/ppanel-web/compare/v1.0.0-beta.7...v1.0.0-beta.8) (2025-02-15)
### ✨ Features
- **accounts**: Update third-party account binding and unbinding ([1841552](https://github.com/perfect-panel/ppanel-web/commit/1841552))
- **auth-control**: Adding phone number labels to mobile verification configurations in multiple languages ([046740f](https://github.com/perfect-panel/ppanel-web/commit/046740f))
- **auth-control**: Update general ([3883646](https://github.com/perfect-panel/ppanel-web/commit/3883646))
- **auth**: Add type parameter to SendCode and update related API typings ([4198871](https://github.com/perfect-panel/ppanel-web/commit/4198871))
- **auth**: Refactor mobile authentication config to support whitelist functionality ([c761ec7](https://github.com/perfect-panel/ppanel-web/commit/c761ec7))
- **device**: Modify IMEI to device identifier support ([e3f9ef6](https://github.com/perfect-panel/ppanel-web/commit/e3f9ef6))
- **imei**: Add IMEI related internationalization support and menu items ([13c3337](https://github.com/perfect-panel/ppanel-web/commit/13c3337))
- **locales**: Add kick offline confirmation and success messages in multiple languages ([5db5343](https://github.com/perfect-panel/ppanel-web/commit/5db5343))
- **locales**: Update 'sms' to 'mobile' in authentication methods across multiple languages ([fea2171](https://github.com/perfect-panel/ppanel-web/commit/fea2171))
- **log**: Add message log retrieval functionality and update related typings ([1c0ecae](https://github.com/perfect-panel/ppanel-web/commit/1c0ecae))
- **profile**: Update localization strings and enhance third-party account binding ([2d1effb](https://github.com/perfect-panel/ppanel-web/commit/2d1effb))
- **release**: Extend supported platforms for Docker images, closes [#9](https://github.com/perfect-panel/ppanel-web/issues/9) ([e3a31eb](https://github.com/perfect-panel/ppanel-web/commit/e3a31eb))
- **subscription**: Add delete user subscription functionality ([1fc3a10](https://github.com/perfect-panel/ppanel-web/commit/1fc3a10))
- **ui**: Update input components and enhance card minimum width for better layout ([8a02310](https://github.com/perfect-panel/ppanel-web/commit/8a02310))
- **user**: Add user Detail ([3a3d223](https://github.com/perfect-panel/ppanel-web/commit/3a3d223))
- **user**: Add User Detail ([fdaf11b](https://github.com/perfect-panel/ppanel-web/commit/fdaf11b))
### 🐛 Bug Fixes
- **auth-control**: Fix citation error for platform values ([c940f3c](https://github.com/perfect-panel/ppanel-web/commit/c940f3c))
- **auth-control**: Fix citation error for platform values ([28813d2](https://github.com/perfect-panel/ppanel-web/commit/28813d2))
- **auth-control**: Rename phone_variable to phone_number in mobile verification configuration ([e5455aa](https://github.com/perfect-panel/ppanel-web/commit/e5455aa))
- **auth**: Update authentication configuration and localization strings ([47f2c58](https://github.com/perfect-panel/ppanel-web/commit/47f2c58))
- **locales**: Update expiration time description from minutes to seconds in multiple languages ([5bac933](https://github.com/perfect-panel/ppanel-web/commit/5bac933))
- **notify**: Ensure user info is updated after notification settings submission ([9bc3a94](https://github.com/perfect-panel/ppanel-web/commit/9bc3a94))
- **notify**: Set default values for notification settings to false ([3652819](https://github.com/perfect-panel/ppanel-web/commit/3652819))
- **third-party-accounts**: Remove mobile display logic from third-party accounts component ([b4946f7](https://github.com/perfect-panel/ppanel-web/commit/b4946f7))
- **third-party-accounts**: Update redirect property name in binding response handling ([012e83a](https://github.com/perfect-panel/ppanel-web/commit/012e83a))
- **user**: Refactor user form validation and reset password fields ([6733fc2](https://github.com/perfect-panel/ppanel-web/commit/6733fc2))
- **user**: Update locales ([4e7d249](https://github.com/perfect-panel/ppanel-web/commit/4e7d249))
- **user**: Update notification and verify code settings ([574b043](https://github.com/perfect-panel/ppanel-web/commit/574b043))
### 💄 Styles ### 💄 Styles
* **dashboard**: Enhance card components with full height and improved empty state handling ([7e1d551](https://github.com/perfect-panel/ppanel-web/commit/7e1d551)) - **dashboard**: Enhance card components with full height and improved empty state handling ([7e1d551](https://github.com/perfect-panel/ppanel-web/commit/7e1d551))
<a name="readme-top"></a> <a name="readme-top"></a>
+11 -14
View File
@@ -59,20 +59,6 @@ export default function ResetForm({
</FormItem> </FormItem>
)} )}
/> />
<FormField
control={form.control}
name='password'
render={({ field }) => (
<FormItem>
<FormControl>
<Input placeholder='Enter your password...' type='password' {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{auth?.email?.enable_verify && (
<FormField <FormField
control={form.control} control={form.control}
name='code' name='code'
@@ -99,7 +85,18 @@ export default function ResetForm({
</FormItem> </FormItem>
)} )}
/> />
<FormField
control={form.control}
name='password'
render={({ field }) => (
<FormItem>
<FormControl>
<Input placeholder='Enter your New password...' type='password' {...field} />
</FormControl>
<FormMessage />
</FormItem>
)} )}
/>
{verify.enable_reset_password_verify && ( {verify.enable_reset_password_verify && (
<FormField <FormField
control={form.control} control={form.control}
@@ -23,12 +23,12 @@ export default function Page() {
}, },
}); });
async function updateConfig(key: keyof API.UpdataAuthMethodConfigRequest, value: unknown) { async function updateConfig(key: keyof API.UpdateAuthMethodConfigRequest, value: unknown) {
try { try {
await updateAuthMethodConfig({ await updateAuthMethodConfig({
...data, ...data,
[key]: value, [key]: value,
} as API.UpdataAuthMethodConfigRequest); } as API.UpdateAuthMethodConfigRequest);
toast.success(t('saveSuccess')); toast.success(t('saveSuccess'));
refetch(); refetch();
} catch (error) { } catch (error) {
@@ -21,12 +21,12 @@ export default function Page() {
}, },
}); });
async function updateConfig(key: keyof API.UpdataAuthMethodConfigRequest, value: unknown) { async function updateConfig(key: keyof API.UpdateAuthMethodConfigRequest, value: unknown) {
try { try {
await updateAuthMethodConfig({ await updateAuthMethodConfig({
...data, ...data,
[key]: value, [key]: value,
} as API.UpdataAuthMethodConfigRequest); } as API.UpdateAuthMethodConfigRequest);
toast.success(t('saveSuccess')); toast.success(t('saveSuccess'));
refetch(); refetch();
} catch (error) { } catch (error) {
@@ -48,7 +48,7 @@ export default function Page() {
await updateAuthMethodConfig({ await updateAuthMethodConfig({
...ref.current, ...ref.current,
[key]: value, [key]: value,
} as API.UpdataAuthMethodConfigRequest); } as API.UpdateAuthMethodConfigRequest);
toast.success(t('saveSuccess')); toast.success(t('saveSuccess'));
refetch(); refetch();
} catch (error) { } catch (error) {
@@ -159,7 +159,7 @@ export default function Page() {
updateConfig('config', { updateConfig('config', {
...data?.config, ...data?.config,
platform_config: { platform_config: {
...data?.platform_config, ...ref.current?.config?.platform_config,
port: value, port: value,
}, },
}) })
@@ -181,7 +181,7 @@ export default function Page() {
updateConfig('config', { updateConfig('config', {
...data?.config, ...data?.config,
platform_config: { platform_config: {
...data?.platform_config, ...ref.current?.config?.platform_config,
ssl: checked, ssl: checked,
}, },
}) })
@@ -202,7 +202,7 @@ export default function Page() {
updateConfig('config', { updateConfig('config', {
...data?.config, ...data?.config,
platform_config: { platform_config: {
...data?.platform_config, ...ref.current?.config?.platform_config,
user: value, user: value,
}, },
}) })
@@ -224,7 +224,7 @@ export default function Page() {
updateConfig('config', { updateConfig('config', {
...data?.config, ...data?.config,
platform_config: { platform_config: {
...data?.platform_config, ...ref.current?.config?.platform_config,
pass: value, pass: value,
}, },
}) })
@@ -245,7 +245,7 @@ export default function Page() {
updateConfig('config', { updateConfig('config', {
...data?.config, ...data?.config,
platform_config: { platform_config: {
...data?.platform_config, ...ref.current?.config?.platform_config,
from: value, from: value,
}, },
}) })
@@ -22,12 +22,12 @@ export default function Page() {
}, },
}); });
async function updateConfig(key: keyof API.UpdataAuthMethodConfigRequest, value: unknown) { async function updateConfig(key: keyof API.UpdateAuthMethodConfigRequest, value: unknown) {
try { try {
await updateAuthMethodConfig({ await updateAuthMethodConfig({
...data, ...data,
[key]: value, [key]: value,
} as API.UpdataAuthMethodConfigRequest); } as API.UpdateAuthMethodConfigRequest);
toast.success(t('saveSuccess')); toast.success(t('saveSuccess'));
refetch(); refetch();
} catch (error) { } catch (error) {
@@ -51,7 +51,7 @@ export function Verify() {
<TableCell className='text-right'> <TableCell className='text-right'>
<EnhancedInput <EnhancedInput
placeholder={t('inputPlaceholder')} placeholder={t('inputPlaceholder')}
defaultValue={data?.turnstile_site_key} value={data?.turnstile_site_key}
onValueBlur={(value) => updateConfig('turnstile_site_key', value)} onValueBlur={(value) => updateConfig('turnstile_site_key', value)}
/> />
</TableCell> </TableCell>
@@ -64,7 +64,7 @@ export function Verify() {
<TableCell className='text-right'> <TableCell className='text-right'>
<EnhancedInput <EnhancedInput
placeholder={t('inputPlaceholder')} placeholder={t('inputPlaceholder')}
defaultValue={data?.turnstile_secret} value={data?.turnstile_secret}
onValueBlur={(value) => updateConfig('turnstile_secret', value)} onValueBlur={(value) => updateConfig('turnstile_secret', value)}
/> />
</TableCell> </TableCell>
@@ -22,12 +22,12 @@ export default function Page() {
}, },
}); });
async function updateConfig(key: keyof API.UpdataAuthMethodConfigRequest, value: unknown) { async function updateConfig(key: keyof API.UpdateAuthMethodConfigRequest, value: unknown) {
try { try {
await updateAuthMethodConfig({ await updateAuthMethodConfig({
...data, ...data,
[key]: value, [key]: value,
} as API.UpdataAuthMethodConfigRequest); } as API.UpdateAuthMethodConfigRequest);
toast.success(t('saveSuccess')); toast.success(t('saveSuccess'));
refetch(); refetch();
} catch (error) { } catch (error) {
@@ -22,12 +22,12 @@ export default function Page() {
}, },
}); });
async function updateConfig(key: keyof API.UpdataAuthMethodConfigRequest, value: unknown) { async function updateConfig(key: keyof API.UpdateAuthMethodConfigRequest, value: unknown) {
try { try {
await updateAuthMethodConfig({ await updateAuthMethodConfig({
...data, ...data,
[key]: value, [key]: value,
} as API.UpdataAuthMethodConfigRequest); } as API.UpdateAuthMethodConfigRequest);
toast.success(t('saveSuccess')); toast.success(t('saveSuccess'));
refetch(); refetch();
} catch (error) { } catch (error) {
@@ -61,7 +61,7 @@ export default function Page() {
await updateAuthMethodConfig({ await updateAuthMethodConfig({
...data, ...data,
[key]: value, [key]: value,
} as API.UpdataAuthMethodConfigRequest); } as API.UpdateAuthMethodConfigRequest);
toast.success(t('updateSuccess')); toast.success(t('updateSuccess'));
refetch(); refetch();
} catch (error) { } catch (error) {
@@ -22,12 +22,12 @@ export default function Page() {
}, },
}); });
async function updateConfig(key: keyof API.UpdataAuthMethodConfigRequest, value: unknown) { async function updateConfig(key: keyof API.UpdateAuthMethodConfigRequest, value: unknown) {
try { try {
await updateAuthMethodConfig({ await updateAuthMethodConfig({
...data, ...data,
[key]: value, [key]: value,
} as API.UpdataAuthMethodConfigRequest); } as API.UpdateAuthMethodConfigRequest);
toast.success(t('saveSuccess')); toast.success(t('saveSuccess'));
refetch(); refetch();
} catch (error) { } catch (error) {
@@ -30,7 +30,7 @@ export default function SubscribeConfig() {
...data, ...data,
[key]: value, [key]: value,
} as API.SubscribeConfig); } as API.SubscribeConfig);
toast.success(t('saveSuccess')); toast.success(t('updateSuccess'));
refetch(); refetch();
} catch (error) { } catch (error) {
/* empty */ /* empty */
@@ -105,7 +105,7 @@ export default function SubscribeForm<T extends Record<string, any>>({
server_group: z.array(z.number()).optional().default([]), server_group: z.array(z.number()).optional().default([]),
server: z.array(z.number()).optional().default([]), server: z.array(z.number()).optional().default([]),
deduction_ratio: z.number().optional().default(0), deduction_ratio: z.number().optional().default(0),
purchase_with_discount: z.boolean().optional().default(false), allow_deduction: z.boolean().optional().default(false),
reset_cycle: z.number().optional().default(0), reset_cycle: z.number().optional().default(0),
renewal_reset: z.boolean().optional().default(false), renewal_reset: z.boolean().optional().default(false),
}); });
@@ -639,7 +639,7 @@ export default function SubscribeForm<T extends Record<string, any>>({
/> />
<FormField <FormField
control={form.control} control={form.control}
name='purchase_with_discount' name='allow_deduction'
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<div className='flex items-center justify-between'> <div className='flex items-center justify-between'>
@@ -13,7 +13,7 @@ import { useTranslations } from 'next-intl';
import { useState } from 'react'; import { useState } from 'react';
import { toast } from 'sonner'; import { toast } from 'sonner';
export function AuthMethodsForm({ user }: { user: API.User }) { export function AuthMethodsForm({ user, refetch }: { user: API.User; refetch: () => void }) {
const t = useTranslations('user'); const t = useTranslations('user');
const [emailChanges, setEmailChanges] = useState<Record<string, string>>({}); const [emailChanges, setEmailChanges] = useState<Record<string, string>>({});
@@ -33,6 +33,7 @@ export function AuthMethodsForm({ user }: { user: API.User }) {
auth_identifier: email, auth_identifier: email,
}); });
toast.success(t('updateSuccess')); toast.success(t('updateSuccess'));
refetch();
}; };
const handleCreateEmail = async (email: string) => { const handleCreateEmail = async (email: string) => {
@@ -42,6 +43,7 @@ export function AuthMethodsForm({ user }: { user: API.User }) {
auth_identifier: email, auth_identifier: email,
}); });
toast.success(t('createSuccess')); toast.success(t('createSuccess'));
refetch();
}; };
const handleEmailChange = (authType: string, value: string) => { const handleEmailChange = (authType: string, value: string) => {
@@ -37,7 +37,7 @@ const basicInfoSchema = z.object({
type BasicInfoValues = z.infer<typeof basicInfoSchema>; type BasicInfoValues = z.infer<typeof basicInfoSchema>;
export function BasicInfoForm({ user }: { user: API.User }) { export function BasicInfoForm({ user, refetch }: { user: API.User; refetch: () => void }) {
const t = useTranslations('user'); const t = useTranslations('user');
const { common } = useGlobalStore(); const { common } = useGlobalStore();
@@ -64,6 +64,7 @@ export function BasicInfoForm({ user }: { user: API.User }) {
...data, ...data,
} as API.UpdateUserBasiceInfoRequest); } as API.UpdateUserBasiceInfoRequest);
toast.success(t('updateSuccess')); toast.success(t('updateSuccess'));
refetch();
} }
return ( return (
@@ -10,7 +10,7 @@ import { NotifySettingsForm } from './notify-settings-form';
export function UserProfileForm() { export function UserProfileForm() {
const { id } = useParams<{ id: string }>(); const { id } = useParams<{ id: string }>();
const { data: user } = useQuery({ const { data: user, refetch } = useQuery({
queryKey: ['user', id], queryKey: ['user', id],
queryFn: async () => { queryFn: async () => {
const { data } = await getUserDetail({ const { data } = await getUserDetail({
@@ -25,13 +25,13 @@ export function UserProfileForm() {
return ( return (
<div className='grid gap-4 md:grid-cols-2 xl:grid-cols-3'> <div className='grid gap-4 md:grid-cols-2 xl:grid-cols-3'>
<div className='md:col-span-2 xl:col-span-1'> <div className='md:col-span-2 xl:col-span-1'>
<BasicInfoForm user={user} /> <BasicInfoForm user={user} refetch={refetch} />
</div> </div>
<div> <div>
<NotifySettingsForm user={user} /> <NotifySettingsForm user={user} refetch={refetch} />
</div> </div>
<div> <div>
<AuthMethodsForm user={user} /> <AuthMethodsForm user={user} refetch={refetch} />
</div> </div>
</div> </div>
); );
@@ -20,7 +20,7 @@ const notifySettingsSchema = z.object({
type NotifySettingsValues = z.infer<typeof notifySettingsSchema>; type NotifySettingsValues = z.infer<typeof notifySettingsSchema>;
export function NotifySettingsForm({ user }: { user: API.User }) { export function NotifySettingsForm({ user, refetch }: { user: API.User; refetch: () => void }) {
const t = useTranslations('user'); const t = useTranslations('user');
const form = useForm<NotifySettingsValues>({ const form = useForm<NotifySettingsValues>({
@@ -39,6 +39,7 @@ export function NotifySettingsForm({ user }: { user: API.User }) {
user_id: user.id, user_id: user.id,
}); });
toast.success(t('updateSuccess')); toast.success(t('updateSuccess'));
refetch();
} }
return ( return (
@@ -143,7 +143,7 @@ export function SubscriptionDetail({
header: 'ID', header: 'ID',
}, },
{ {
accessorKey: 'imei', accessorKey: 'identifier',
header: 'IMEI', header: 'IMEI',
}, },
{ {
@@ -182,7 +182,7 @@ export function SubscriptionDetail({
}} }}
actions={{ actions={{
render: (row) => { render: (row) => {
if (!row.imei) return []; if (!row.identifier) return [];
return [ return [
<ConfirmButton <ConfirmButton
key='offline' key='offline'
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "Ověření e-mailu", "emailVerification": "Ověření e-mailu",
"emailVerificationDescription": "Když je povoleno, uživatelé budou muset ověřit svůj e-mail", "emailVerificationDescription": "Když je povoleno, uživatelé budou muset ověřit svůj e-mail",
"enable": "Povolit", "enable": "Povolit",
"enableDescription": "Po povolení budou povoleny funkce registrace, přihlášení, připojení a odpojení mobilního telefonu", "enableDescription": "Po aktivaci budou povoleny funkce registrace e-mailem, přihlášení, propojení a odpojení.",
"expiration_email_template": "Šablona oznámení o vypršení platnosti", "expiration_email_template": "Šablona oznámení o vypršení platnosti",
"expiration_email_templateDescription": "Zástupné symboly {after}.variable{before} budou nahrazeny skutečnými daty. Ujistěte se, že tyto proměnné zachováte.", "expiration_email_templateDescription": "Zástupné symboly {after}.variable{before} budou nahrazeny skutečnými daty. Ujistěte se, že tyto proměnné zachováte.",
"failed": "Neúspěch", "failed": "Neúspěch",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "E-Mail-Verifizierung", "emailVerification": "E-Mail-Verifizierung",
"emailVerificationDescription": "Wenn aktiviert, müssen Benutzer ihre E-Mail-Adresse verifizieren", "emailVerificationDescription": "Wenn aktiviert, müssen Benutzer ihre E-Mail-Adresse verifizieren",
"enable": "Aktivieren", "enable": "Aktivieren",
"enableDescription": "Nach der Aktivierung werden die Funktionen zur Registrierung, Anmeldung, Bindung und Entbindung von Mobiltelefonen aktiviert", "enableDescription": "Nach der Aktivierung werden die Funktionen zur E-Mail-Registrierung, Anmeldung, Bindung und Entbindung aktiviert.",
"expiration_email_template": "Vorlage für Ablaufbenachrichtigung", "expiration_email_template": "Vorlage für Ablaufbenachrichtigung",
"expiration_email_templateDescription": "Die Platzhalter {after}.variable{before} werden durch tatsächliche Daten ersetzt. Stellen Sie sicher, dass Sie diese Variablen beibehalten.", "expiration_email_templateDescription": "Die Platzhalter {after}.variable{before} werden durch tatsächliche Daten ersetzt. Stellen Sie sicher, dass Sie diese Variablen beibehalten.",
"failed": "Fehlgeschlagen", "failed": "Fehlgeschlagen",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "Email Verification", "emailVerification": "Email Verification",
"emailVerificationDescription": "When enabled, users will need to verify their email", "emailVerificationDescription": "When enabled, users will need to verify their email",
"enable": "Enable", "enable": "Enable",
"enableDescription": "After enabling, mobile phone registration, login, binding, and unbinding functions will be enabled", "enableDescription": "After enabling, email registration, login, binding, and unbinding functions will be enabled",
"expiration_email_template": "Expiration Notice Template", "expiration_email_template": "Expiration Notice Template",
"expiration_email_templateDescription": "The {after}.variable{before} placeholders will be replaced with actual data. Ensure to keep these variables.", "expiration_email_templateDescription": "The {after}.variable{before} placeholders will be replaced with actual data. Ensure to keep these variables.",
"failed": "Failed", "failed": "Failed",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "Verificación de correo electrónico", "emailVerification": "Verificación de correo electrónico",
"emailVerificationDescription": "Cuando esté habilitado, los usuarios deberán verificar su correo electrónico", "emailVerificationDescription": "Cuando esté habilitado, los usuarios deberán verificar su correo electrónico",
"enable": "Habilitar", "enable": "Habilitar",
"enableDescription": "Después de habilitar, se activarán las funciones de registro, inicio de sesión, vinculación y desvinculación de teléfonos móviles", "enableDescription": "Después de habilitar, se activarán las funciones de registro por correo electrónico, inicio de sesión, vinculación y desvinculación.",
"expiration_email_template": "Plantilla de Aviso de Vencimiento", "expiration_email_template": "Plantilla de Aviso de Vencimiento",
"expiration_email_templateDescription": "Los marcadores de posición {after}.variable{before} serán reemplazados con datos reales. Asegúrate de mantener estas variables.", "expiration_email_templateDescription": "Los marcadores de posición {after}.variable{before} serán reemplazados con datos reales. Asegúrate de mantener estas variables.",
"failed": "Fallido", "failed": "Fallido",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "Verificación de Correo Electrónico", "emailVerification": "Verificación de Correo Electrónico",
"emailVerificationDescription": "Cuando esté habilitado, los usuarios deberán verificar su correo electrónico", "emailVerificationDescription": "Cuando esté habilitado, los usuarios deberán verificar su correo electrónico",
"enable": "Habilitar", "enable": "Habilitar",
"enableDescription": "Después de habilitar, se activarán las funciones de registro, inicio de sesión, vinculación y desvinculación de teléfonos móviles", "enableDescription": "Después de habilitar, se activarán las funciones de registro por correo electrónico, inicio de sesión, vinculación y desvinculación.",
"expiration_email_template": "Plantilla de Aviso de Vencimiento", "expiration_email_template": "Plantilla de Aviso de Vencimiento",
"expiration_email_templateDescription": "Los marcadores de posición {after}.variable{before} serán reemplazados con datos reales. Asegúrate de mantener estas variables.", "expiration_email_templateDescription": "Los marcadores de posición {after}.variable{before} serán reemplazados con datos reales. Asegúrate de mantener estas variables.",
"failed": "Fallido", "failed": "Fallido",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "تأیید ایمیل", "emailVerification": "تأیید ایمیل",
"emailVerificationDescription": "هنگامی که فعال شود، کاربران باید ایمیل خود را تأیید کنند", "emailVerificationDescription": "هنگامی که فعال شود، کاربران باید ایمیل خود را تأیید کنند",
"enable": "فعال کردن", "enable": "فعال کردن",
"enableDescription": "پس از فعال‌سازی، عملکردهای ثبت‌نام، ورود، اتصال و قطع اتصال تلفن همراه فعال خواهند شد", "enableDescription": "پس از فعال‌سازی، ثبت‌نام ایمیلی، ورود، پیوند و جداسازی عملکردها فعال خواهند شد",
"expiration_email_template": "قالب اطلاعیه انقضا", "expiration_email_template": "قالب اطلاعیه انقضا",
"expiration_email_templateDescription": "جای‌گذاری‌های {after}.variable{before} با داده‌های واقعی جایگزین خواهند شد. اطمینان حاصل کنید که این متغیرها را حفظ کنید.", "expiration_email_templateDescription": "جای‌گذاری‌های {after}.variable{before} با داده‌های واقعی جایگزین خواهند شد. اطمینان حاصل کنید که این متغیرها را حفظ کنید.",
"failed": "ناموفق", "failed": "ناموفق",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "Sähköpostin vahvistus", "emailVerification": "Sähköpostin vahvistus",
"emailVerificationDescription": "Kun tämä on käytössä, käyttäjien on vahvistettava sähköpostinsa", "emailVerificationDescription": "Kun tämä on käytössä, käyttäjien on vahvistettava sähköpostinsa",
"enable": "Ota käyttöön", "enable": "Ota käyttöön",
"enableDescription": "Kun otat tämän käyttöön, matkapuhelimen rekisteröinti-, kirjautumis-, sitomis- ja purkutoiminnot otetaan käyttöön", "enableDescription": "Kun tämä on otettu käyttöön, sähköpostirekisteröinti, kirjautuminen, liittäminen ja irrottaminen aktivoituvat.",
"expiration_email_template": "Vanhentumisilmoituksen malli", "expiration_email_template": "Vanhentumisilmoituksen malli",
"expiration_email_templateDescription": "Paikkamerkit {after}.variable{before} korvataan todellisilla tiedoilla. Varmista, että pidät nämä muuttujat.", "expiration_email_templateDescription": "Paikkamerkit {after}.variable{before} korvataan todellisilla tiedoilla. Varmista, että pidät nämä muuttujat.",
"failed": "Epäonnistui", "failed": "Epäonnistui",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "Vérification de l'email", "emailVerification": "Vérification de l'email",
"emailVerificationDescription": "Lorsqu'elle est activée, les utilisateurs devront vérifier leur adresse e-mail", "emailVerificationDescription": "Lorsqu'elle est activée, les utilisateurs devront vérifier leur adresse e-mail",
"enable": "Activer", "enable": "Activer",
"enableDescription": "Après activation, les fonctions d'enregistrement, de connexion, de liaison et de déliaison par téléphone mobile seront activées", "enableDescription": "Après activation, les fonctions d'enregistrement par e-mail, de connexion, de liaison et de délégation seront activées",
"expiration_email_template": "Modèle d'avis d'expiration", "expiration_email_template": "Modèle d'avis d'expiration",
"expiration_email_templateDescription": "Les espaces réservés {after}.variable{before} seront remplacés par des données réelles. Assurez-vous de conserver ces variables.", "expiration_email_templateDescription": "Les espaces réservés {after}.variable{before} seront remplacés par des données réelles. Assurez-vous de conserver ces variables.",
"failed": "Échoué", "failed": "Échoué",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "ईमेल सत्यापन", "emailVerification": "ईमेल सत्यापन",
"emailVerificationDescription": "सक्षम होने पर, उपयोगकर्ताओं को अपने ईमेल की पुष्टि करनी होगी", "emailVerificationDescription": "सक्षम होने पर, उपयोगकर्ताओं को अपने ईमेल की पुष्टि करनी होगी",
"enable": "सक्षम करें", "enable": "सक्षम करें",
"enableDescription": "सक्षम करने के बाद, मोबाइल फोन पंजीकरण, लॉगिन, बाइंडिंग, और अनबाइंडिंग कार्यक्षमताएँ सक्षम हो जाएँगी", "enableDescription": "सक्षम करने के बाद, ईमेल पंजीकरण, लॉगिन, बाइंडिंग और अनबाइंडिंग कार्यक्षमताएँ सक्षम होगी",
"expiration_email_template": "समाप्ति सूचना टेम्पलेट", "expiration_email_template": "समाप्ति सूचना टेम्पलेट",
"expiration_email_templateDescription": "{after}.variable{before} प्लेसहोल्डर को वास्तविक डेटा से बदला जाएगा। सुनिश्चित करें कि इन वेरिएबल्स को बनाए रखें।", "expiration_email_templateDescription": "{after}.variable{before} प्लेसहोल्डर को वास्तविक डेटा से बदला जाएगा। सुनिश्चित करें कि इन वेरिएबल्स को बनाए रखें।",
"failed": "असफल", "failed": "असफल",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "Email ellenőrzés", "emailVerification": "Email ellenőrzés",
"emailVerificationDescription": "Ha engedélyezve van, a felhasználóknak ellenőrizniük kell az e-mail címüket", "emailVerificationDescription": "Ha engedélyezve van, a felhasználóknak ellenőrizniük kell az e-mail címüket",
"enable": "Engedélyez", "enable": "Engedélyez",
"enableDescription": "A bekapcsolás után a mobiltelefon regisztráció, bejelentkezés, kötés és oldás funkciók elérhetővé válnak", "enableDescription": "A funkció engedélyezése után az e-mailes regisztráció, bejelentkezés, kötés és leválasztás lehetőségei elérhetővé válnak.",
"expiration_email_template": "Lejárati Értesítő Sablon", "expiration_email_template": "Lejárati Értesítő Sablon",
"expiration_email_templateDescription": "A {after}.variable{before} helyőrzőket tényleges adatokkal fogjuk helyettesíteni. Ügyeljen arra, hogy ezeket a változókat megtartsa.", "expiration_email_templateDescription": "A {after}.variable{before} helyőrzőket tényleges adatokkal fogjuk helyettesíteni. Ügyeljen arra, hogy ezeket a változókat megtartsa.",
"failed": "Sikertelen", "failed": "Sikertelen",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "メール確認", "emailVerification": "メール確認",
"emailVerificationDescription": "有効にすると、ユーザーはメールを確認する必要があります", "emailVerificationDescription": "有効にすると、ユーザーはメールを確認する必要があります",
"enable": "有効にする", "enable": "有効にする",
"enableDescription": "有効にすると、携帯電話の登録、ログイン、バインディング、バインディング解除の機能が有効になります", "enableDescription": "有効にすると、メールによる登録、ログイン、バインディング、およびバインディング解除の機能が有効になります",
"expiration_email_template": "有効期限通知テンプレート", "expiration_email_template": "有効期限通知テンプレート",
"expiration_email_templateDescription": "{after}.variable{before} のプレースホルダーは実際のデータに置き換えられます。これらの変数を必ず保持してください。", "expiration_email_templateDescription": "{after}.variable{before} のプレースホルダーは実際のデータに置き換えられます。これらの変数を必ず保持してください。",
"failed": "失敗しました", "failed": "失敗しました",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "이메일 인증", "emailVerification": "이메일 인증",
"emailVerificationDescription": "활성화되면 사용자는 이메일을 인증해야 합니다", "emailVerificationDescription": "활성화되면 사용자는 이메일을 인증해야 합니다",
"enable": "사용", "enable": "사용",
"enableDescription": "활성화 후, 휴대폰 등록, 로그인, 연결 및 연결 해제 기능이 활성화됩니다", "enableDescription": "활성화하면 이메일 등록, 로그인, 바인딩 및 바인딩 해제 기능이 활성화됩니다.",
"expiration_email_template": "만료 알림 템플릿", "expiration_email_template": "만료 알림 템플릿",
"expiration_email_templateDescription": "{after}.variable{before} 자리표시는 실제 데이터로 대체됩니다. 이 변수를 반드시 유지하십시오.", "expiration_email_templateDescription": "{after}.variable{before} 자리표시는 실제 데이터로 대체됩니다. 이 변수를 반드시 유지하십시오.",
"failed": "실패", "failed": "실패",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "E-postbekreftelse", "emailVerification": "E-postbekreftelse",
"emailVerificationDescription": "Når aktivert, må brukere bekrefte e-posten sin", "emailVerificationDescription": "Når aktivert, må brukere bekrefte e-posten sin",
"enable": "Aktiver", "enable": "Aktiver",
"enableDescription": "Etter aktivering vil funksjonene for registrering, innlogging, binding og frakobling av mobiltelefon bli aktivert", "enableDescription": "Etter aktivering vil funksjonene for e-postregistrering, innlogging, binding og avbinding bli aktivert",
"expiration_email_template": "Utløpsvarsel Mal", "expiration_email_template": "Utløpsvarsel Mal",
"expiration_email_templateDescription": "Plassholderne {after}.variable{before} vil bli erstattet med faktiske data. Sørg for å beholde disse variablene.", "expiration_email_templateDescription": "Plassholderne {after}.variable{before} vil bli erstattet med faktiske data. Sørg for å beholde disse variablene.",
"failed": "Mislyktes", "failed": "Mislyktes",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "Weryfikacja e-maila", "emailVerification": "Weryfikacja e-maila",
"emailVerificationDescription": "Po włączeniu użytkownicy będą musieli zweryfikować swój adres e-mail", "emailVerificationDescription": "Po włączeniu użytkownicy będą musieli zweryfikować swój adres e-mail",
"enable": "Włącz", "enable": "Włącz",
"enableDescription": "Po włączeniu zostaną aktywowane funkcje rejestracji, logowania, powiązania i odwiązania telefonu komórkowego", "enableDescription": "Po włączeniu funkcji rejestracji, logowania, powiązania i odłączenia konta e-mail będą dostępne",
"expiration_email_template": "Szablon Powiadomienia o Wygaśnięciu", "expiration_email_template": "Szablon Powiadomienia o Wygaśnięciu",
"expiration_email_templateDescription": "Elementy zastępcze {after}.variable{before} zostaną zastąpione rzeczywistymi danymi. Upewnij się, że te zmienne zostaną zachowane.", "expiration_email_templateDescription": "Elementy zastępcze {after}.variable{before} zostaną zastąpione rzeczywistymi danymi. Upewnij się, że te zmienne zostaną zachowane.",
"failed": "Niepowodzenie", "failed": "Niepowodzenie",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "Verificação de Email", "emailVerification": "Verificação de Email",
"emailVerificationDescription": "Quando ativado, os usuários precisarão verificar seu e-mail", "emailVerificationDescription": "Quando ativado, os usuários precisarão verificar seu e-mail",
"enable": "Habilitar", "enable": "Habilitar",
"enableDescription": "Após a ativação, as funções de registro, login, vinculação e desvinculação de telefone celular serão ativadas", "enableDescription": "Após a ativação, as funções de registro por e-mail, login, vinculação e desvinculação serão habilitadas",
"expiration_email_template": "Modelo de Aviso de Expiração", "expiration_email_template": "Modelo de Aviso de Expiração",
"expiration_email_templateDescription": "Os marcadores {after}.variable{before} serão substituídos por dados reais. Certifique-se de manter essas variáveis.", "expiration_email_templateDescription": "Os marcadores {after}.variable{before} serão substituídos por dados reais. Certifique-se de manter essas variáveis.",
"failed": "Falhou", "failed": "Falhou",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "Verificare Email", "emailVerification": "Verificare Email",
"emailVerificationDescription": "Când este activată, utilizatorii vor trebui să-și verifice emailul", "emailVerificationDescription": "Când este activată, utilizatorii vor trebui să-și verifice emailul",
"enable": "Activează", "enable": "Activează",
"enableDescription": "După activare, funcțiile de înregistrare, autentificare, asociere și disociere a telefonului mobil vor fi activate", "enableDescription": "După activare, funcțiile de înregistrare prin email, autentificare, legare și delegare vor fi activate.",
"expiration_email_template": "Șablon de Notificare a Expirării", "expiration_email_template": "Șablon de Notificare a Expirării",
"expiration_email_templateDescription": "Locurile rezervate {after}.variable{before} vor fi înlocuite cu date reale. Asigurați-vă că păstrați aceste variabile.", "expiration_email_templateDescription": "Locurile rezervate {after}.variable{before} vor fi înlocuite cu date reale. Asigurați-vă că păstrați aceste variabile.",
"failed": "Eșuat", "failed": "Eșuat",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "Подтверждение электронной почты", "emailVerification": "Подтверждение электронной почты",
"emailVerificationDescription": "Когда включено, пользователям необходимо будет подтвердить свой адрес электронной почты", "emailVerificationDescription": "Когда включено, пользователям необходимо будет подтвердить свой адрес электронной почты",
"enable": "Включить", "enable": "Включить",
"enableDescription": "После включения будут доступны функции регистрации, входа, привязки и отвязки мобильного телефона", "enableDescription": "После включения будут активированы функции регистрации по электронной почте, входа в систему, привязки и отвязки.",
"expiration_email_template": "Шаблон уведомления об истечении срока", "expiration_email_template": "Шаблон уведомления об истечении срока",
"expiration_email_templateDescription": "Заполнители {after}.variable{before} будут заменены фактическими данными. Убедитесь, что эти переменные сохранены.", "expiration_email_templateDescription": "Заполнители {after}.variable{before} будут заменены фактическими данными. Убедитесь, что эти переменные сохранены.",
"failed": "Не удалось", "failed": "Не удалось",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "การยืนยันอีเมล", "emailVerification": "การยืนยันอีเมล",
"emailVerificationDescription": "เมื่อเปิดใช้งาน ผู้ใช้จะต้องยืนยันอีเมลของตน", "emailVerificationDescription": "เมื่อเปิดใช้งาน ผู้ใช้จะต้องยืนยันอีเมลของตน",
"enable": "เปิดใช้งาน", "enable": "เปิดใช้งาน",
"enableDescription": "หลังจากเปิดใช้งานแล้ว ฟังก์ชันการลงทะเบียน การเข้าสู่ระบบ การผูกบัญชี และการยกเลิกการผูกบัญชีด้วยโทรศัพท์มือถือจะถูกเปิดใช้งาน", "enableDescription": "หลังจากเปิดใช้งาน ฟังก์ชันการลงทะเบียนทางอีเมล การเข้าสู่ระบบ การผูก และการยกเลิกการผูก จะถูกเปิดใช้งาน",
"expiration_email_template": "เทมเพลตแจ้งเตือนการหมดอายุ", "expiration_email_template": "เทมเพลตแจ้งเตือนการหมดอายุ",
"expiration_email_templateDescription": "ตัวแปร {after}.variable{before} จะถูกแทนที่ด้วยข้อมูลจริง โปรดตรวจสอบให้แน่ใจว่าเก็บตัวแปรเหล่านี้ไว้", "expiration_email_templateDescription": "ตัวแปร {after}.variable{before} จะถูกแทนที่ด้วยข้อมูลจริง โปรดตรวจสอบให้แน่ใจว่าเก็บตัวแปรเหล่านี้ไว้",
"failed": "ล้มเหลว", "failed": "ล้มเหลว",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "E-posta Doğrulama", "emailVerification": "E-posta Doğrulama",
"emailVerificationDescription": "Etkinleştirildiğinde, kullanıcıların e-posta adreslerini doğrulamaları gerekecek", "emailVerificationDescription": "Etkinleştirildiğinde, kullanıcıların e-posta adreslerini doğrulamaları gerekecek",
"enable": "Etkinleştir", "enable": "Etkinleştir",
"enableDescription": "Etkinleştirildikten sonra, cep telefonu kaydı, giriş, bağlama ve bağlantı kesme işlevleri etkinleştirilecektir", "enableDescription": "Etkinleştirildikten sonra, e-posta kaydı, giriş, bağlama ve ayırma işlevleri etkinleştirilecektir.",
"expiration_email_template": "Süre Sonu Bildirimi Şablonu", "expiration_email_template": "Süre Sonu Bildirimi Şablonu",
"expiration_email_templateDescription": "{after}.variable{before} yer tutucuları gerçek verilerle değiştirilecektir. Bu değişkenleri koruduğunuzdan emin olun.", "expiration_email_templateDescription": "{after}.variable{before} yer tutucuları gerçek verilerle değiştirilecektir. Bu değişkenleri koruduğunuzdan emin olun.",
"failed": "Başarısız", "failed": "Başarısız",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "Підтвердження електронної пошти", "emailVerification": "Підтвердження електронної пошти",
"emailVerificationDescription": "Коли ввімкнено, користувачам потрібно буде підтвердити свою електронну пошту", "emailVerificationDescription": "Коли ввімкнено, користувачам потрібно буде підтвердити свою електронну пошту",
"enable": "Увімкнути", "enable": "Увімкнути",
"enableDescription": "Після увімкнення будуть доступні функції реєстрації, входу, прив'язки та відв'язки мобільного телефону", "enableDescription": "Після активації будуть доступні функції реєстрації електронною поштою, входу, прив'язки та відв'язки.",
"expiration_email_template": "Шаблон повідомлення про закінчення терміну дії", "expiration_email_template": "Шаблон повідомлення про закінчення терміну дії",
"expiration_email_templateDescription": "Заповнювачі {after}.variable{before} будуть замінені на фактичні дані. Переконайтеся, що зберегли ці змінні.", "expiration_email_templateDescription": "Заповнювачі {after}.variable{before} будуть замінені на фактичні дані. Переконайтеся, що зберегли ці змінні.",
"failed": "Не вдалося", "failed": "Не вдалося",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "Xác minh Email", "emailVerification": "Xác minh Email",
"emailVerificationDescription": "Khi được bật, người dùng sẽ cần xác minh email của họ", "emailVerificationDescription": "Khi được bật, người dùng sẽ cần xác minh email của họ",
"enable": "Kích hoạt", "enable": "Kích hoạt",
"enableDescription": "Sau khi kích hoạt, các chức năng đăng ký, đăng nhập, liên kết và hủy liên kết điện thoại di động sẽ được kích hoạt", "enableDescription": "Sau khi kích hoạt, các chức năng đăng ký email, đăng nhập, liên kết và hủy liên kết sẽ được bật",
"expiration_email_template": "Mẫu Thông Báo Hết Hạn", "expiration_email_template": "Mẫu Thông Báo Hết Hạn",
"expiration_email_templateDescription": "Các chỗ chèn {after}.variable{before} sẽ được thay thế bằng dữ liệu thực tế. Đảm bảo giữ nguyên các biến này.", "expiration_email_templateDescription": "Các chỗ chèn {after}.variable{before} sẽ được thay thế bằng dữ liệu thực tế. Đảm bảo giữ nguyên các biến này.",
"failed": "Thất bại", "failed": "Thất bại",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "电子邮件验证", "emailVerification": "电子邮件验证",
"emailVerificationDescription": "启用后,用户需要验证他们的电子邮件", "emailVerificationDescription": "启用后,用户需要验证他们的电子邮件",
"enable": "启用", "enable": "启用",
"enableDescription": "启用后,将启用手机注册、登录、绑定和解绑功能", "enableDescription": "启用后,将启用电子邮件注册、登录、绑定和解绑功能",
"expiration_email_template": "到期通知模板", "expiration_email_template": "到期通知模板",
"expiration_email_templateDescription": "{after}.variable{before} 占位符将被实际数据替换。请确保保留这些变量。", "expiration_email_templateDescription": "{after}.variable{before} 占位符将被实际数据替换。请确保保留这些变量。",
"failed": "失败", "failed": "失败",
+1 -1
View File
@@ -6,7 +6,7 @@
"emailVerification": "電郵驗證", "emailVerification": "電郵驗證",
"emailVerificationDescription": "啟用後,用戶需要驗證他們的電郵", "emailVerificationDescription": "啟用後,用戶需要驗證他們的電郵",
"enable": "啟用", "enable": "啟用",
"enableDescription": "啟用後,將啟用手機註冊、登、綁定和解綁功能", "enableDescription": "啟用後,將開啟電子郵件註冊、登、綁定及解除綁定功能",
"expiration_email_template": "到期通知範本", "expiration_email_template": "到期通知範本",
"expiration_email_templateDescription": "{after}.variable{before} 佔位符將被實際數據替換。請確保保留這些變數。", "expiration_email_templateDescription": "{after}.variable{before} 佔位符將被實際數據替換。請確保保留這些變數。",
"failed": "失敗", "failed": "失敗",
+1 -1
View File
@@ -19,7 +19,7 @@ export async function getAuthMethodConfig(
/** Update auth method config PUT /v1/admin/auth-method/config */ /** Update auth method config PUT /v1/admin/auth-method/config */
export async function updateAuthMethodConfig( export async function updateAuthMethodConfig(
body: API.UpdataAuthMethodConfigRequest, body: API.UpdateAuthMethodConfigRequest,
options?: { [key: string]: any }, options?: { [key: string]: any },
) { ) {
return request<API.Response & { data?: API.AuthMethodConfig }>('/v1/admin/auth-method/config', { return request<API.Response & { data?: API.AuthMethodConfig }>('/v1/admin/auth-method/config', {
+8 -8
View File
@@ -1177,13 +1177,6 @@ declare namespace API {
security_config: SecurityConfig; security_config: SecurityConfig;
}; };
type UpdataAuthMethodConfigRequest = {
id: number;
method: string;
config: Record<string, any>;
enabled: boolean;
};
type UpdateAlipayF2fRequest = { type UpdateAlipayF2fRequest = {
id: number; id: number;
name: string; name: string;
@@ -1230,6 +1223,13 @@ declare namespace API {
application_id: number; application_id: number;
}; };
type UpdateAuthMethodConfigRequest = {
id: number;
method: string;
config: Record<string, any>;
enabled: boolean;
};
type UpdateCouponRequest = { type UpdateCouponRequest = {
id: number; id: number;
name: string; name: string;
@@ -1440,7 +1440,7 @@ declare namespace API {
type UserDevice = { type UserDevice = {
id: number; id: number;
ip: string; ip: string;
imei: string; identifier: string;
user_agent: string; user_agent: string;
online: boolean; online: boolean;
enabled: boolean; enabled: boolean;
+1 -1
View File
@@ -628,7 +628,7 @@ declare namespace API {
type UserDevice = { type UserDevice = {
id: number; id: number;
ip: string; ip: string;
imei: string; identifier: string;
user_agent: string; user_agent: string;
online: boolean; online: boolean;
enabled: boolean; enabled: boolean;
+1 -1
View File
@@ -50,7 +50,7 @@ export default function Page() {
enabled: !!orderNo && data?.status === 1, enabled: !!orderNo && data?.status === 1,
queryKey: ['checkoutOrder', orderNo], queryKey: ['checkoutOrder', orderNo],
queryFn: async () => { queryFn: async () => {
const { data } = await checkoutOrder({ orderNo: orderNo! }); const { data } = await checkoutOrder({ orderNo: orderNo!, returnUrl: window.location.href });
return data?.data; return data?.data;
}, },
}); });
@@ -202,8 +202,7 @@ export default function ThirdPartyAccounts() {
name: 'Device', name: 'Device',
type: 'OAuth', type: 'OAuth',
}, },
]; ].filter((account) => oauth_methods?.includes(account.id));
// .filter((account) => oauth_methods?.includes(account.id));
const [editValues, setEditValues] = useState<Record<string, any>>({}); const [editValues, setEditValues] = useState<Record<string, any>>({});
+3 -4
View File
@@ -31,11 +31,10 @@ export default function RegisterForm({
const handleCheckUser = async (email: string) => { const handleCheckUser = async (email: string) => {
try { try {
if (!auth.email.enable_verify) return true;
const domain = email.split('@')[1]; const domain = email.split('@')[1];
const isValid = const isValid = auth.email?.domain_suffix_list.split('\n').includes(domain || '');
!auth.email.enable_verify || return isValid;
auth.email?.domain_suffix_list.split('\n').includes(domain || '');
return !isValid;
} catch (error) { } catch (error) {
console.log('Error checking user:', error); console.log('Error checking user:', error);
return false; return false;
-3
View File
@@ -59,8 +59,6 @@ export default function ResetForm({
</FormItem> </FormItem>
)} )}
/> />
{auth?.email?.enable_verify && (
<FormField <FormField
control={form.control} control={form.control}
name='code' name='code'
@@ -88,7 +86,6 @@ export default function ResetForm({
</FormItem> </FormItem>
)} )}
/> />
)}
<FormField <FormField
control={form.control} control={form.control}
name='password' name='password'
+1 -1
View File
@@ -42,7 +42,7 @@ export function Hero() {
<HoverBorderGradient <HoverBorderGradient
containerClassName='rounded-full' containerClassName='rounded-full'
as='button' as='button'
className='bg-background text-foreground flex items-center space-x-2' className='m-0.5 flex items-center space-x-2 text-white'
> >
{t('started')} {t('started')}
</HoverBorderGradient> </HoverBorderGradient>
@@ -125,7 +125,7 @@ export function ProductShowcase() {
className='pb-4 text-2xl font-semibold sm:text-3xl' className='pb-4 text-2xl font-semibold sm:text-3xl'
> >
<Display type='currency' value={item.unit_price} /> <Display type='currency' value={item.unit_price} />
<span className='text-base font-medium'>/{t('per_month')}</span> <span className='text-base font-medium'>/{t(item.unit_time)}</span>
</motion.h2> </motion.h2>
<motion.div> <motion.div>
<Button <Button
@@ -71,6 +71,7 @@ export default function Purchase({ subscribe, setSubscribe }: Readonly<PurchaseP
if (orderNo) { if (orderNo) {
const { data } = await checkoutOrder({ const { data } = await checkoutOrder({
orderNo, orderNo,
returnUrl: window.location.href,
}); });
const type = data.data?.type; const type = data.data?.type;
const checkout_url = data.data?.checkout_url; const checkout_url = data.data?.checkout_url;
@@ -135,6 +135,7 @@ export default function Recharge(props: Readonly<ButtonProps>) {
if (orderNo) { if (orderNo) {
const { data } = await checkoutOrder({ const { data } = await checkoutOrder({
orderNo, orderNo,
returnUrl: window.location.href,
}); });
const type = data.data?.type; const type = data.data?.type;
const checkout_url = data.data?.checkout_url; const checkout_url = data.data?.checkout_url;
@@ -79,6 +79,7 @@ export default function Renewal({ id, subscribe }: Readonly<RenewalProps>) {
if (orderNo) { if (orderNo) {
const { data } = await checkoutOrder({ const { data } = await checkoutOrder({
orderNo, orderNo,
returnUrl: window.location.href,
}); });
const type = data.data?.type; const type = data.data?.type;
const checkout_url = data.data?.checkout_url; const checkout_url = data.data?.checkout_url;
@@ -86,6 +86,7 @@ export default function ResetTraffic({ id, replacement }: Readonly<ResetTrafficP
if (orderNo) { if (orderNo) {
const { data } = await checkoutOrder({ const { data } = await checkoutOrder({
orderNo, orderNo,
returnUrl: window.location.href,
}); });
const type = data.data?.type; const type = data.data?.type;
const checkout_url = data.data?.checkout_url; const checkout_url = data.data?.checkout_url;
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Den",
"Hour": "Hodina",
"Minute": "Minuta",
"Month": "Měsíc",
"NoLimit": "Žádný limit",
"Year": "Rok",
"global_map_description": "Prozkoumejte bezproblémové globální připojení. Vyberte si síťové služby, které vyhovují vašim potřebám, a zůstaňte připojeni kdykoli a kdekoli.", "global_map_description": "Prozkoumejte bezproblémové globální připojení. Vyberte si síťové služby, které vyhovují vašim potřebám, a zůstaňte připojeni kdykoli a kdekoli.",
"global_map_itle": "Globální propojení, snadno a bez starostí", "global_map_itle": "Globální propojení, snadno a bez starostí",
"locations": "Oblasti", "locations": "Oblasti",
"per_month": "měsíčně",
"product_showcase_description": "Nechte nás vybrat ten nejvhodnější balíček pro vás a s radostí ho prozkoumejte.", "product_showcase_description": "Nechte nás vybrat ten nejvhodnější balíček pro vás a s radostí ho prozkoumejte.",
"product_showcase_title": "Vyberte si svůj balíček", "product_showcase_title": "Vyberte si svůj balíček",
"servers": "servery", "servers": "servery",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Tag",
"Hour": "Stunde",
"Minute": "Minute",
"Month": "Monat",
"NoLimit": "Keine Begrenzung",
"Year": "Jahr",
"global_map_description": "Entdecken Sie nahtlose globale Verbindungen. Wählen Sie den Netzwerkdienst, der Ihren Bedürfnissen entspricht, und bleiben Sie jederzeit und überall verbunden.", "global_map_description": "Entdecken Sie nahtlose globale Verbindungen. Wählen Sie den Netzwerkdienst, der Ihren Bedürfnissen entspricht, und bleiben Sie jederzeit und überall verbunden.",
"global_map_itle": "Weltweit verbunden, sorgenfrei", "global_map_itle": "Weltweit verbunden, sorgenfrei",
"locations": "Standorte", "locations": "Standorte",
"per_month": "Pro Monat",
"product_showcase_description": "Lassen Sie uns das für Sie am besten geeignete Paket auswählen und es mit Freude erkunden.", "product_showcase_description": "Lassen Sie uns das für Sie am besten geeignete Paket auswählen und es mit Freude erkunden.",
"product_showcase_title": "Wählen Sie Ihr Paket", "product_showcase_title": "Wählen Sie Ihr Paket",
"servers": "Server", "servers": "Server",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Day",
"Hour": "Hour",
"Minute": "Minute",
"Month": "Month",
"NoLimit": "No Limit",
"Year": "Year",
"global_map_description": "Explore seamless global connectivity. Choose network services that suit your needs and stay connected anytime, anywhere.", "global_map_description": "Explore seamless global connectivity. Choose network services that suit your needs and stay connected anytime, anywhere.",
"global_map_itle": "Global Connection, Easy and Worry-free", "global_map_itle": "Global Connection, Easy and Worry-free",
"locations": "Locations", "locations": "Locations",
"per_month": "Per Month",
"product_showcase_description": "Let us help you select the package that best suits you and enjoy exploring it.", "product_showcase_description": "Let us help you select the package that best suits you and enjoy exploring it.",
"product_showcase_title": "Choose Your Package", "product_showcase_title": "Choose Your Package",
"servers": "Servers", "servers": "Servers",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Día",
"Hour": "Hora",
"Minute": "Minuto",
"Month": "Mes",
"NoLimit": "Sin Límite",
"Year": "Año",
"global_map_description": "Explora una conexión global sin interrupciones. Elige el servicio de red que se adapte a tus necesidades y mantente conectado en cualquier momento y lugar.", "global_map_description": "Explora una conexión global sin interrupciones. Elige el servicio de red que se adapte a tus necesidades y mantente conectado en cualquier momento y lugar.",
"global_map_itle": "Conexión global, fácil y sin preocupaciones", "global_map_itle": "Conexión global, fácil y sin preocupaciones",
"locations": "Ubicaciones", "locations": "Ubicaciones",
"per_month": "Por mes",
"product_showcase_description": "Permítanos elegir el paquete que mejor se adapte a usted y disfrútelo explorando con alegría.", "product_showcase_description": "Permítanos elegir el paquete que mejor se adapte a usted y disfrútelo explorando con alegría.",
"product_showcase_title": "Elija su paquete", "product_showcase_title": "Elija su paquete",
"servers": "servidores", "servers": "servidores",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Día",
"Hour": "Hora",
"Minute": "Minuto",
"Month": "Mes",
"NoLimit": "Sin Límite",
"Year": "Año",
"global_map_description": "Explora una conexión global sin interrupciones. Elige el servicio de red que se adapte a tus necesidades y mantente conectado en cualquier momento y lugar.", "global_map_description": "Explora una conexión global sin interrupciones. Elige el servicio de red que se adapte a tus necesidades y mantente conectado en cualquier momento y lugar.",
"global_map_itle": "Conexión global, fácil y sin preocupaciones", "global_map_itle": "Conexión global, fácil y sin preocupaciones",
"locations": "Ubicaciones", "locations": "Ubicaciones",
"per_month": "Por mes",
"product_showcase_description": "Permítanos elegir el paquete que mejor se adapte a usted y explorelo con alegría.", "product_showcase_description": "Permítanos elegir el paquete que mejor se adapte a usted y explorelo con alegría.",
"product_showcase_title": "Elija su paquete", "product_showcase_title": "Elija su paquete",
"servers": "servidores", "servers": "servidores",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "روز",
"Hour": "ساعت",
"Minute": "دقیقه",
"Month": "ماه",
"NoLimit": "بدون محدودیت",
"Year": "سال",
"global_map_description": "اتصال جهانی بدون درز را کاوش کنید. خدمات شبکه‌ای را انتخاب کنید که با نیازهای شما سازگار باشد و در هر زمان و هر مکان متصل بمانید.", "global_map_description": "اتصال جهانی بدون درز را کاوش کنید. خدمات شبکه‌ای را انتخاب کنید که با نیازهای شما سازگار باشد و در هر زمان و هر مکان متصل بمانید.",
"global_map_itle": "ارتباط جهانی، آسان و بدون نگرانی", "global_map_itle": "ارتباط جهانی، آسان و بدون نگرانی",
"locations": "مکان‌ها", "locations": "مکان‌ها",
"per_month": "در ماه",
"product_showcase_description": "بگذارید به شما در انتخاب بسته‌ای که بهترین تناسب را با شما دارد کمک کنیم و از کاوش در آن لذت ببرید.", "product_showcase_description": "بگذارید به شما در انتخاب بسته‌ای که بهترین تناسب را با شما دارد کمک کنیم و از کاوش در آن لذت ببرید.",
"product_showcase_title": "بسته خود را انتخاب کنید", "product_showcase_title": "بسته خود را انتخاب کنید",
"servers": "سرورها", "servers": "سرورها",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Päivä",
"Hour": "Tunti",
"Minute": "Minuutti",
"Month": "Kuukausi",
"NoLimit": "Ei rajoituksia",
"Year": "Vuosi",
"global_map_description": "Tutustu saumattomaan maailmanlaajuiseen yhteyteen. Valitse tarpeitasi vastaava verkkopalvelu ja pysy yhteydessä missä ja milloin tahansa.", "global_map_description": "Tutustu saumattomaan maailmanlaajuiseen yhteyteen. Valitse tarpeitasi vastaava verkkopalvelu ja pysy yhteydessä missä ja milloin tahansa.",
"global_map_itle": "Maailmanlaajuinen yhteys, vaivaton ja huoleton", "global_map_itle": "Maailmanlaajuinen yhteys, vaivaton ja huoleton",
"locations": "Alueet", "locations": "Alueet",
"per_month": "kuukaudessa",
"product_showcase_description": "Anna meidän valita sinulle sopivin paketti ja tutustu siihen iloisesti.", "product_showcase_description": "Anna meidän valita sinulle sopivin paketti ja tutustu siihen iloisesti.",
"product_showcase_title": "Valitse pakettisi", "product_showcase_title": "Valitse pakettisi",
"servers": "palvelimet", "servers": "palvelimet",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Jour",
"Hour": "Heure",
"Minute": "Minute",
"Month": "Mois",
"NoLimit": "Pas de limite",
"Year": "Année",
"global_map_description": "Explorez une connexion mondiale sans couture. Choisissez le service réseau qui répond à vos besoins et restez connecté à tout moment et en tout lieu.", "global_map_description": "Explorez une connexion mondiale sans couture. Choisissez le service réseau qui répond à vos besoins et restez connecté à tout moment et en tout lieu.",
"global_map_itle": "Connexion mondiale, simplicité assurée", "global_map_itle": "Connexion mondiale, simplicité assurée",
"locations": "Régions", "locations": "Régions",
"per_month": "Par mois",
"product_showcase_description": "Laissez-nous choisir le forfait qui vous convient le mieux et explorez-le avec joie.", "product_showcase_description": "Laissez-nous choisir le forfait qui vous convient le mieux et explorez-le avec joie.",
"product_showcase_title": "Choisissez votre forfait", "product_showcase_title": "Choisissez votre forfait",
"servers": "serveurs", "servers": "serveurs",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "दिन",
"Hour": "घंटा",
"Minute": "मिनट",
"Month": "महिना",
"NoLimit": "कोई सीमा नहीं",
"Year": "साल",
"global_map_description": "निर्बाध वैश्विक कनेक्शन का अन्वेषण करें। अपनी आवश्यकताओं के अनुसार नेटवर्क सेवा का चयन करें और कहीं भी, कभी भी जुड़े रहें।", "global_map_description": "निर्बाध वैश्विक कनेक्शन का अन्वेषण करें। अपनी आवश्यकताओं के अनुसार नेटवर्क सेवा का चयन करें और कहीं भी, कभी भी जुड़े रहें।",
"global_map_itle": "वैश्विक कनेक्टिविटी, सरल और निश्चिंत", "global_map_itle": "वैश्विक कनेक्टिविटी, सरल और निश्चिंत",
"locations": "क्षेत्र", "locations": "क्षेत्र",
"per_month": "प्रति माह",
"product_showcase_description": "आइए हम आपके लिए सबसे उपयुक्त पैकेज का चयन करें और इसे खुशी से अन्वेषण करें।", "product_showcase_description": "आइए हम आपके लिए सबसे उपयुक्त पैकेज का चयन करें और इसे खुशी से अन्वेषण करें।",
"product_showcase_title": "अपना पैकेज चुनें", "product_showcase_title": "अपना पैकेज चुनें",
"servers": "सर्वर", "servers": "सर्वर",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Nap",
"Hour": "Óra",
"Minute": "Perc",
"Month": "Hónap",
"NoLimit": "Nincs Korlát",
"Year": "Év",
"global_map_description": "Fedezze fel a zökkenőmentes globális kapcsolatot. Válassza ki az igényeinek megfelelő hálózati szolgáltatást, és maradjon kapcsolatban bárhol, bármikor.", "global_map_description": "Fedezze fel a zökkenőmentes globális kapcsolatot. Válassza ki az igényeinek megfelelő hálózati szolgáltatást, és maradjon kapcsolatban bárhol, bármikor.",
"global_map_itle": "Globális összeköttetés, könnyedén és gondtalanul", "global_map_itle": "Globális összeköttetés, könnyedén és gondtalanul",
"locations": "Helyszínek", "locations": "Helyszínek",
"per_month": "Havonta",
"product_showcase_description": "Válasszuk ki az Ön számára legmegfelelőbb csomagot, és fedezze fel örömmel.", "product_showcase_description": "Válasszuk ki az Ön számára legmegfelelőbb csomagot, és fedezze fel örömmel.",
"product_showcase_title": "Válassza ki a csomagját", "product_showcase_title": "Válassza ki a csomagját",
"servers": "szerverek", "servers": "szerverek",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "日",
"Hour": "時間",
"Minute": "分",
"Month": "月",
"NoLimit": "制限なし",
"Year": "年",
"global_map_description": "シームレスなグローバル接続を探索しましょう。あなたのニーズに合ったネットワークサービスを選び、いつでもどこでも接続を維持しましょう。", "global_map_description": "シームレスなグローバル接続を探索しましょう。あなたのニーズに合ったネットワークサービスを選び、いつでもどこでも接続を維持しましょう。",
"global_map_itle": "世界をつなぎ、安心を提供", "global_map_itle": "世界をつなぎ、安心を提供",
"locations": "地域", "locations": "地域",
"per_month": "毎月",
"product_showcase_description": "あなたに最適なプランを選び、楽しく探求しましょう。", "product_showcase_description": "あなたに最適なプランを選び、楽しく探求しましょう。",
"product_showcase_title": "プランを選択", "product_showcase_title": "プランを選択",
"servers": "サーバー", "servers": "サーバー",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "일",
"Hour": "시간",
"Minute": "분",
"Month": "월",
"NoLimit": "제한 없음",
"Year": "년",
"global_map_description": "원활한 글로벌 연결을 탐색하세요. 필요에 맞는 네트워크 서비스를 선택하여 언제 어디서나 연결을 유지하세요.", "global_map_description": "원활한 글로벌 연결을 탐색하세요. 필요에 맞는 네트워크 서비스를 선택하여 언제 어디서나 연결을 유지하세요.",
"global_map_itle": "글로벌 연결, 편안하고 걱정 없는", "global_map_itle": "글로벌 연결, 편안하고 걱정 없는",
"locations": "지역", "locations": "지역",
"per_month": "매월",
"product_showcase_description": "가장 적합한 패키지를 선택하여 기쁘게 탐험해 보세요.", "product_showcase_description": "가장 적합한 패키지를 선택하여 기쁘게 탐험해 보세요.",
"product_showcase_title": "패키지를 선택하세요", "product_showcase_title": "패키지를 선택하세요",
"servers": "서버", "servers": "서버",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Dag",
"Hour": "Time",
"Minute": "Minutt",
"Month": "Måned",
"NoLimit": "Ingen grense",
"Year": "År",
"global_map_description": "Utforsk sømløs global tilkobling. Velg nettverkstjenester som passer dine behov, og hold deg tilkoblet uansett hvor du er.", "global_map_description": "Utforsk sømløs global tilkobling. Velg nettverkstjenester som passer dine behov, og hold deg tilkoblet uansett hvor du er.",
"global_map_itle": "Global tilkobling, enkelt og bekymringsløst", "global_map_itle": "Global tilkobling, enkelt og bekymringsløst",
"locations": "områder", "locations": "områder",
"per_month": "per måned",
"product_showcase_description": "La oss velge den pakken som passer best for deg, og utforsk den med glede.", "product_showcase_description": "La oss velge den pakken som passer best for deg, og utforsk den med glede.",
"product_showcase_title": "Velg din pakke", "product_showcase_title": "Velg din pakke",
"servers": "servere", "servers": "servere",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Dzień",
"Hour": "Godzina",
"Minute": "Minuta",
"Month": "Miesiąc",
"NoLimit": "Bez ograniczeń",
"Year": "Rok",
"global_map_description": "Odkryj bezproblemowe globalne połączenia. Wybierz usługi sieciowe, które spełniają Twoje potrzeby i pozostań w kontakcie zawsze i wszędzie.", "global_map_description": "Odkryj bezproblemowe globalne połączenia. Wybierz usługi sieciowe, które spełniają Twoje potrzeby i pozostań w kontakcie zawsze i wszędzie.",
"global_map_itle": "Globalne połączenie, bezproblemowe i łatwe", "global_map_itle": "Globalne połączenie, bezproblemowe i łatwe",
"locations": "Regiony", "locations": "Regiony",
"per_month": "Miesięcznie",
"product_showcase_description": "Pozwól nam wybrać dla Ciebie najlepszy pakiet i ciesz się jego odkrywaniem.", "product_showcase_description": "Pozwól nam wybrać dla Ciebie najlepszy pakiet i ciesz się jego odkrywaniem.",
"product_showcase_title": "Wybierz swój pakiet", "product_showcase_title": "Wybierz swój pakiet",
"servers": "serwery", "servers": "serwery",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Dia",
"Hour": "Hora",
"Minute": "Minuto",
"Month": "Mês",
"NoLimit": "Sem Limite",
"Year": "Ano",
"global_map_description": "Explore uma conexão global sem interrupções. Escolha o serviço de rede que atenda às suas necessidades e mantenha-se conectado a qualquer hora e em qualquer lugar.", "global_map_description": "Explore uma conexão global sem interrupções. Escolha o serviço de rede que atenda às suas necessidades e mantenha-se conectado a qualquer hora e em qualquer lugar.",
"global_map_itle": "Conexão Global, Fácil e Sem Preocupações", "global_map_itle": "Conexão Global, Fácil e Sem Preocupações",
"locations": "localizações", "locations": "localizações",
"per_month": "por mês",
"product_showcase_description": "Vamos escolher o pacote que mais se adequa a você e explorá-lo com alegria.", "product_showcase_description": "Vamos escolher o pacote que mais se adequa a você e explorá-lo com alegria.",
"product_showcase_title": "Escolha seu plano", "product_showcase_title": "Escolha seu plano",
"servers": "servidores", "servers": "servidores",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Zi",
"Hour": "Oră",
"Minute": "Minut",
"Month": "Lună",
"NoLimit": "Fără Limită",
"Year": "An",
"global_map_description": "Explorați o conexiune globală fără cusur. Alegeți serviciul de rețea care se potrivește nevoilor dumneavoastră și rămâneți conectat oriunde și oricând.", "global_map_description": "Explorați o conexiune globală fără cusur. Alegeți serviciul de rețea care se potrivește nevoilor dumneavoastră și rămâneți conectat oriunde și oricând.",
"global_map_itle": "Conectare globală, fără griji", "global_map_itle": "Conectare globală, fără griji",
"locations": "Regiuni", "locations": "Regiuni",
"per_month": "pe lună",
"product_showcase_description": "Permiteți-ne să alegem pachetul care vi se potrivește cel mai bine și să-l explorați cu bucurie.", "product_showcase_description": "Permiteți-ne să alegem pachetul care vi se potrivește cel mai bine și să-l explorați cu bucurie.",
"product_showcase_title": "Alegeți-vă pachetul", "product_showcase_title": "Alegeți-vă pachetul",
"servers": "servere", "servers": "servere",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "День",
"Hour": "Час",
"Minute": "Минута",
"Month": "Месяц",
"NoLimit": "Без ограничения",
"Year": "Год",
"global_map_description": "Исследуйте бесшовные глобальные соединения. Выбирайте сетевые услуги, соответствующие вашим потребностям, и оставайтесь на связи в любое время и в любом месте.", "global_map_description": "Исследуйте бесшовные глобальные соединения. Выбирайте сетевые услуги, соответствующие вашим потребностям, и оставайтесь на связи в любое время и в любом месте.",
"global_map_itle": "Глобальная связь, легко и без забот", "global_map_itle": "Глобальная связь, легко и без забот",
"locations": "регионы", "locations": "регионы",
"per_month": "Ежемесячно",
"product_showcase_description": "Позвольте нам выбрать наиболее подходящий для вас пакет и с удовольствием его исследовать.", "product_showcase_description": "Позвольте нам выбрать наиболее подходящий для вас пакет и с удовольствием его исследовать.",
"product_showcase_title": "Выберите ваш пакет", "product_showcase_title": "Выберите ваш пакет",
"servers": "Серверы", "servers": "Серверы",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "วัน",
"Hour": "ชั่วโมง",
"Minute": "นาที",
"Month": "เดือน",
"NoLimit": "ไม่มีขีดจำกัด",
"Year": "ปี",
"global_map_description": "สำรวจการเชื่อมต่อทั่วโลกที่ไร้รอยต่อ เลือกบริการเครือข่ายที่ตรงกับความต้องการของคุณ เพื่อให้คุณเชื่อมต่อได้ทุกที่ทุกเวลา", "global_map_description": "สำรวจการเชื่อมต่อทั่วโลกที่ไร้รอยต่อ เลือกบริการเครือข่ายที่ตรงกับความต้องการของคุณ เพื่อให้คุณเชื่อมต่อได้ทุกที่ทุกเวลา",
"global_map_itle": "เชื่อมต่อทั่วโลกได้อย่างง่ายดายและไร้กังวล", "global_map_itle": "เชื่อมต่อทั่วโลกได้อย่างง่ายดายและไร้กังวล",
"locations": "ภูมิภาค", "locations": "ภูมิภาค",
"per_month": "ต่อเดือน",
"product_showcase_description": "ให้เราช่วยคุณเลือกแพ็คเกจที่เหมาะสมที่สุด แล้วสนุกไปกับการสำรวจมันอย่างมีความสุข", "product_showcase_description": "ให้เราช่วยคุณเลือกแพ็คเกจที่เหมาะสมที่สุด แล้วสนุกไปกับการสำรวจมันอย่างมีความสุข",
"product_showcase_title": "เลือกแพ็กเกจของคุณ", "product_showcase_title": "เลือกแพ็กเกจของคุณ",
"servers": "เซิร์ฟเวอร์", "servers": "เซิร์ฟเวอร์",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Gün",
"Hour": "Saat",
"Minute": "Dakika",
"Month": "Ay",
"NoLimit": "Sınırsız",
"Year": "Yıl",
"global_map_description": "Kesintisiz küresel bağlantıyı keşfedin. İhtiyaçlarınıza uygun ağ hizmetini seçin ve her zaman, her yerde bağlantıda kalın.", "global_map_description": "Kesintisiz küresel bağlantıyı keşfedin. İhtiyaçlarınıza uygun ağ hizmetini seçin ve her zaman, her yerde bağlantıda kalın.",
"global_map_itle": "Küresel Bağlantı, Kolay ve Huzurlu", "global_map_itle": "Küresel Bağlantı, Kolay ve Huzurlu",
"locations": "Bölgeler", "locations": "Bölgeler",
"per_month": "ayda",
"product_showcase_description": "Sizin için en uygun paketi seçelim ve keyifle keşfedin.", "product_showcase_description": "Sizin için en uygun paketi seçelim ve keyifle keşfedin.",
"product_showcase_title": "Paketinizi Seçin", "product_showcase_title": "Paketinizi Seçin",
"servers": "sunucular", "servers": "sunucular",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "День",
"Hour": "Година",
"Minute": "Хвилина",
"Month": "Місяць",
"NoLimit": "Без обмежень",
"Year": "Рік",
"global_map_description": "Досліджуйте безшовне глобальне з'єднання. Оберіть мережеві послуги, що відповідають вашим потребам, та залишайтеся на зв'язку будь-де і будь-коли.", "global_map_description": "Досліджуйте безшовне глобальне з'єднання. Оберіть мережеві послуги, що відповідають вашим потребам, та залишайтеся на зв'язку будь-де і будь-коли.",
"global_map_itle": "Глобальне з'єднання, легко та без турбот", "global_map_itle": "Глобальне з'єднання, легко та без турбот",
"locations": "Регіони", "locations": "Регіони",
"per_month": "щомісяця",
"product_showcase_description": "Давайте оберемо найкращий пакет для вас і з радістю дослідимо його.", "product_showcase_description": "Давайте оберемо найкращий пакет для вас і з радістю дослідимо його.",
"product_showcase_title": "Виберіть свій пакет", "product_showcase_title": "Виберіть свій пакет",
"servers": "сервери", "servers": "сервери",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "Ngày",
"Hour": "Giờ",
"Minute": "Phút",
"Month": "Tháng",
"NoLimit": "Không giới hạn",
"Year": "Năm",
"global_map_description": "Khám phá kết nối toàn cầu liền mạch. Chọn dịch vụ mạng phù hợp với nhu cầu của bạn, duy trì kết nối mọi lúc mọi nơi.", "global_map_description": "Khám phá kết nối toàn cầu liền mạch. Chọn dịch vụ mạng phù hợp với nhu cầu của bạn, duy trì kết nối mọi lúc mọi nơi.",
"global_map_itle": "Kết nối toàn cầu, dễ dàng và không lo lắng", "global_map_itle": "Kết nối toàn cầu, dễ dàng và không lo lắng",
"locations": "Khu vực", "locations": "Khu vực",
"per_month": "Hàng tháng",
"product_showcase_description": "Hãy để chúng tôi chọn gói phù hợp nhất cho bạn và khám phá nó một cách vui vẻ.", "product_showcase_description": "Hãy để chúng tôi chọn gói phù hợp nhất cho bạn và khám phá nó một cách vui vẻ.",
"product_showcase_title": "Chọn gói của bạn", "product_showcase_title": "Chọn gói của bạn",
"servers": "máy chủ", "servers": "máy chủ",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "天",
"Hour": "小时",
"Minute": "分钟",
"Month": "月",
"NoLimit": "无限制",
"Year": "年",
"global_map_description": "探索无缝的全球连接。选择符合您需求的网络服务,随时随地保持连接。", "global_map_description": "探索无缝的全球连接。选择符合您需求的网络服务,随时随地保持连接。",
"global_map_itle": "全球互联,轻松无忧", "global_map_itle": "全球互联,轻松无忧",
"locations": "地区", "locations": "地区",
"per_month": "每月",
"product_showcase_description": "让我们选择最适合您的套餐,快乐地探索它。", "product_showcase_description": "让我们选择最适合您的套餐,快乐地探索它。",
"product_showcase_title": "选择您的套餐", "product_showcase_title": "选择您的套餐",
"servers": "服务器", "servers": "服务器",
+6 -1
View File
@@ -1,8 +1,13 @@
{ {
"Day": "日",
"Hour": "小時",
"Minute": "分鐘",
"Month": "月",
"NoLimit": "無限制",
"Year": "年",
"global_map_description": "探索無縫的全球連接。選擇符合您需求的網路服務,隨時隨地保持連接。", "global_map_description": "探索無縫的全球連接。選擇符合您需求的網路服務,隨時隨地保持連接。",
"global_map_itle": "全球互聯,輕鬆無憂", "global_map_itle": "全球互聯,輕鬆無憂",
"locations": "地區", "locations": "地區",
"per_month": "每月",
"product_showcase_description": "讓我們選擇最適合您的套餐,快樂地探索它。", "product_showcase_description": "讓我們選擇最適合您的套餐,快樂地探索它。",
"product_showcase_title": "選擇您的方案", "product_showcase_title": "選擇您的方案",
"servers": "伺服器", "servers": "伺服器",
+1 -1
View File
@@ -628,7 +628,7 @@ declare namespace API {
type UserDevice = { type UserDevice = {
id: number; id: number;
ip: string; ip: string;
imei: string; identifier: string;
user_agent: string; user_agent: string;
online: boolean; online: boolean;
enabled: boolean; enabled: boolean;
+2 -1
View File
@@ -91,6 +91,7 @@ declare namespace API {
type CheckoutOrderRequest = { type CheckoutOrderRequest = {
orderNo: string; orderNo: string;
returnUrl?: string;
}; };
type CheckoutOrderResponse = { type CheckoutOrderResponse = {
@@ -828,7 +829,7 @@ declare namespace API {
type UserDevice = { type UserDevice = {
id: number; id: number;
ip: string; ip: string;
imei: string; identifier: string;
user_agent: string; user_agent: string;
online: boolean; online: boolean;
enabled: boolean; enabled: boolean;
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "ppanel-web", "name": "ppanel-web",
"version": "1.0.0-beta.8", "version": "1.0.0-beta.17",
"private": true, "private": true,
"homepage": "https://github.com/perfect-panel/ppanel-web", "homepage": "https://github.com/perfect-panel/ppanel-web",
"bugs": { "bugs": {