diff --git a/dashboard/package.json b/dashboard/package.json
@@ -45,7 +45,6 @@
"@radix-ui/react-toggle-group": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.7",
"@react-hook/media-query": "^1.1.1",
- "@remix-run/router": "^1.15.3",
"@tailwindcss/aspect-ratio": "^0.4.2",
"@tailwindcss/forms": "^0.5.7",
"@tailwindcss/typography": "^0.5.10",
diff --git a/dashboard/pnpm-lock.yaml b/dashboard/pnpm-lock.yaml
@@ -95,9 +95,6 @@ dependencies:
'@react-hook/media-query':
specifier: ^1.1.1
version: 1.1.1(react@18.2.0)
- '@remix-run/router':
- specifier: ^1.15.3
- version: 1.15.3
'@tailwindcss/aspect-ratio':
specifier: ^0.4.2
version: 0.4.2(tailwindcss@3.4.1)
@@ -4633,6 +4630,8 @@ packages:
peerDependenciesMeta:
'@types/prettier':
optional: true
+ '@types/refractor':
+ optional: true
prettier:
optional: true
dependencies:
@@ -5512,11 +5511,6 @@ packages:
type-fest: 2.19.0
dev: false
- /@remix-run/router@1.15.3:
- resolution: {integrity: sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==}
- engines: {node: '>=14.0.0'}
- dev: false
-
/@rollup/rollup-android-arm-eabi@4.13.0:
resolution: {integrity: sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==}
cpu: [arm]
diff --git a/dashboard/public/locales/ckb.json b/dashboard/public/locales/ckb.json
@@ -0,0 +1,218 @@
+{
+ "name": "Naw",
+ "status": "Dox",
+ "address": "Edrês",
+ "users": "Bekarhêneran",
+ "nodes": "Girêkan",
+ "services": "Rajekan",
+ "hosts": "Hostkan",
+ "username": "Naw Bekarhêneran",
+ "password": "Têperrewişe",
+ "inbounds": "înbawendkan",
+ "submit": "Nardin",
+ "login": "Çûnejûrew",
+ "edit": "Desitkarîkirdn",
+ "actions": "Fermankan",
+ "settings": "Sazkarîyekan",
+ "logs": "Tomarekan",
+ "config": "Kanfîg",
+ "open": "Kirnewe",
+ "delete": "Sirrînewe",
+ "port": "Port",
+ "create": "Dirust bike",
+ "path": "Path",
+ "host": "Host",
+ "alpn": "ALPN",
+ "security": "Security",
+ "user_info": "Users Info",
+ "subscription": "Subscription",
+ "subscription_link": "Subscription Link",
+ "fingerprint": "Fingerprint",
+ "page": {
+ "settings": {
+ "certificate": {
+ "copy": "Copy Certificate",
+ "error": "Certificate Unavailable",
+ "copied": "Certificate Copied"
+ }
+ },
+ "login": {
+ "username": {
+ "error": {
+ "isRequired": "Username is required"
+ }
+ },
+ "password": {
+ "error": {
+ "is-required": "Password is required"
+ }
+ }
+ },
+ "nodes": {
+ "settings": {
+ "title": "Nodes Settings",
+ "detail": "Details",
+ "log-container": {
+ "title": "Marznode Xray config logs"
+ }
+ },
+ "dialogs": {
+ "creation": {
+ "title": "Nodes Creation"
+ },
+ "deletion": {
+ "title": "Nodes Deletion"
+ },
+ "edition": {
+ "title": "Nodes Edition"
+ }
+ },
+ "usage_coefficient": "Usage Coefficient",
+ "add_as_new_host": "Add as new hosts",
+ "certificate-alert": {
+ "title": "Nodes Certificate Configuration",
+ "desc": "If you aim to configure your nodes certificate, checkout settings page.",
+ "click": "Click Here"
+ }
+ },
+ "services": {
+ "settings": {
+ "title": "Servicecs Settings",
+ "detail": "Details"
+ },
+ "dialogs": {
+ "creation": {
+ "title": "Services Creation"
+ },
+ "deletion": {
+ "title": "Services Deletion"
+ },
+ "edition": {
+ "title": "Services Edition"
+ }
+ }
+ },
+ "users": {
+ "data_limit": "Data Limit",
+ "used_traffic": "Used Traffic",
+ "data_limit_reset_strategy": "Data Limit Reset Strategy",
+ "online_at": "Online At",
+ "expire_date": "Expire Date",
+ "unlimited": "Unlimited",
+ "determined_expire": "Determined",
+ "expire_method": "Expiration method",
+ "onhold_expire": "On Hold",
+ "reset_usage": "Reset Usage",
+ "revoke_subscription": "Revoke Subscription",
+ "on_hold_expire_duration": "On Hold",
+ "on_hold_timeout": "On Hold Timeout",
+ "settings": {
+ "subscription_link": {
+ "copied": "Subscription Link Copied",
+ "copy": "Copy Subscription Link",
+ "error": "Unable to copy Subscription Link"
+ }
+ },
+ "services-alert": {
+ "title": "No Service were found",
+ "desc": "Make sure you create services to enable your users with inbounds to connect with.",
+ "click": "Click Here"
+ },
+ "dialogs": {
+ "edition": {
+ "title": "Users Edition"
+ },
+ "creation": {
+ "title": "Users Creation"
+ },
+ "deletion": {
+ "title": "Users Deletion"
+ },
+ "mutation": {
+ "note": {
+ "desc": "Leave a note about your user"
+ }
+ }
+ }
+ },
+ "hosts": {
+ "allowinsecure": "Allow insecure",
+ "dialogs": {
+ "edition": {
+ "title": "Hosts Edition"
+ },
+ "creation": {
+ "title": "Hosts Creation"
+ },
+ "deletion": {
+ "title": "Hosts Deletion"
+ },
+ "mutation": {
+ "allowinsecure": {
+ "alert": "Due to security concerns, it is not recommended to allow Insecure"
+ }
+ }
+ }
+ }
+ },
+ "events": {
+ "delete": {
+ "error": "Failed to delete {{name}}",
+ "success": {
+ "title": "{{name}} is successfuly deleted",
+ "desc": ""
+ }
+ },
+ "create": {
+ "error": "Failed to create {{name}}",
+ "success": {
+ "title": "{{name}} is successfuly created",
+ "desc": ""
+ }
+ },
+ "update": {
+ "error": "Failed to update {{name}}",
+ "success": {
+ "title": "{{name}} is successfuly updated",
+ "desc": ""
+ }
+ },
+ "user_revoke": {
+ "error": "Failed to revoke {{name}} subscription",
+ "success": {
+ "title": "{{name}} is successfuly created",
+ "desc": ""
+ }
+ },
+ "user_reset": {
+ "error": "Failed to reset {{name}} data usage",
+ "success": {
+ "title": "{{name}} data usage is successfuly reseted",
+ "desc": ""
+ }
+ }
+ },
+ "delete-confirmation": {
+ "title": "Are you sure of this?",
+ "desc": "This action cannot be undone. This will permanently delete your account and remove your data from our servers."
+ },
+ "table": {
+ "row-per-page": "Rows per page",
+ "no-result": "No results",
+ "selected": "Selected",
+ "toggle-column": "Toggle columns",
+ "filter-placeholder": "Filter {{name}}"
+ },
+ "statuses": {
+ "active": "Active",
+ "connected": "Connected",
+ "healthy": "Healthy",
+ "disabled": "Disabled",
+ "expired": "Expired",
+ "on_hold": "On Hold",
+ "connecting": "Connecting",
+ "unhealthy": "Unhealthy",
+ "limited": "Limited",
+ "error": "Error"
+ }
+}
diff --git a/dashboard/public/locales/fa.json b/dashboard/public/locales/fa.json
@@ -0,0 +1,225 @@
+{
+ "name": "اسم",
+ "status": "حالت",
+ "address": "ادرس",
+ "users": "کاربر ها",
+ "nodes": "Nodes",
+ "services": "Services",
+ "hosts": "Hosts",
+ "username": "یوزرنیم",
+ "password": "Password",
+ "inbounds": "Inbounds",
+ "submit": "Submit",
+ "login": "Login",
+ "edit": "Edit",
+ "actions": "Actions",
+ "settings": "Settings",
+ "logs": "Logs",
+ "note": "Note",
+ "config": "Config",
+ "tag": "Tag",
+ "protocol": "Protocol",
+ "online": "Online",
+ "offline": "Offline",
+ "not_connected": "Not Connected",
+ "apply": "Apply",
+ "open": "Open",
+ "delete": "Delete",
+ "port": "Port",
+ "create": "Create",
+ "path": "Path",
+ "host": "Host",
+ "alpn": "ALPN",
+ "security": "Security",
+ "user_info": "Users Info",
+ "subscription": "Subscription",
+ "subscription_link": "Subscription Link",
+ "fingerprint": "Fingerprint",
+ "page": {
+ "settings": {
+ "certificate": {
+ "copy": "Copy Certificate",
+ "error": "Certificate Unavailable",
+ "copied": "Certificate Copied"
+ }
+ },
+ "login": {
+ "username": {
+ "error": {
+ "isRequired": "Username is required"
+ }
+ },
+ "password": {
+ "error": {
+ "is-required": "Password is required"
+ }
+ }
+ },
+ "nodes": {
+ "settings": {
+ "title": "Nodes Settings",
+ "detail": "Details",
+ "log-container": {
+ "title": "Marznode Xray config logs"
+ }
+ },
+ "dialogs": {
+ "creation": {
+ "title": "Nodes Creation"
+ },
+ "deletion": {
+ "title": "Nodes Deletion"
+ },
+ "edition": {
+ "title": "Nodes Edition"
+ }
+ },
+ "usage_coefficient": "Usage Coefficient",
+ "add_as_new_host": "Add as new hosts",
+ "certificate-alert": {
+ "title": "Nodes Certificate Configuration",
+ "desc": "If you aim to configure your nodes certificate, checkout settings page.",
+ "click": "Click Here"
+ }
+ },
+ "services": {
+ "settings": {
+ "title": "Servicecs Settings",
+ "detail": "Details"
+ },
+ "dialogs": {
+ "creation": {
+ "title": "Services Creation"
+ },
+ "deletion": {
+ "title": "Services Deletion"
+ },
+ "edition": {
+ "title": "Services Edition"
+ }
+ }
+ },
+ "users": {
+ "data_limit": "Data Limit",
+ "used_traffic": "Used Traffic",
+ "data_limit_reset_strategy": "Data Limit Reset Strategy",
+ "online_at": "Online At",
+ "expire_date": "Expire Date",
+ "unlimited": "Unlimited",
+ "determined_expire": "Determined",
+ "expire_method": "Expiration method",
+ "onhold_expire": "On Hold",
+ "reset_usage": "Reset Usage",
+ "revoke_subscription": "Revoke Subscription",
+ "on_hold_expire_duration": "On Hold",
+ "on_hold_timeout": "On Hold Timeout",
+ "settings": {
+ "subscription_link": {
+ "copied": "Subscription Link Copied",
+ "copy": "Copy Subscription Link",
+ "error": "Unable to copy Subscription Link"
+ }
+ },
+ "services-alert": {
+ "title": "No Service were found",
+ "desc": "Make sure you create services to enable your users with inbounds to connect with.",
+ "click": "Click Here"
+ },
+ "dialogs": {
+ "edition": {
+ "title": "Users Edition"
+ },
+ "creation": {
+ "title": "Users Creation"
+ },
+ "deletion": {
+ "title": "Users Deletion"
+ },
+ "mutation": {
+ "note": {
+ "desc": "Leave a note about your user"
+ }
+ }
+ }
+ },
+ "hosts": {
+ "allowinsecure": "Allow insecure",
+ "dialogs": {
+ "edition": {
+ "title": "Hosts Edition"
+ },
+ "creation": {
+ "title": "Hosts Creation"
+ },
+ "deletion": {
+ "title": "Hosts Deletion"
+ },
+ "mutation": {
+ "allowinsecure": {
+ "alert": "Due to security concerns, it is not recommended to allow Insecure"
+ }
+ }
+ }
+ }
+ },
+ "events": {
+ "delete": {
+ "error": "Failed to delete {{name}}",
+ "success": {
+ "title": "{{name}} is successfuly deleted",
+ "desc": ""
+ }
+ },
+ "create": {
+ "error": "Failed to create {{name}}",
+ "success": {
+ "title": "{{name}} is successfuly created",
+ "desc": ""
+ }
+ },
+ "update": {
+ "error": "Failed to update {{name}}",
+ "success": {
+ "title": "{{name}} is successfuly updated",
+ "desc": ""
+ }
+ },
+ "user_revoke": {
+ "error": "Failed to revoke {{name}} subscription",
+ "success": {
+ "title": "{{name}} is successfuly created",
+ "desc": ""
+ }
+ },
+ "user_reset": {
+ "error": "Failed to reset {{name}} data usage",
+ "success": {
+ "title": "{{name}} data usage is successfuly reseted",
+ "desc": ""
+ }
+ }
+ },
+ "delete-confirmation": {
+ "title": "Are you sure of this?",
+ "desc": "This action cannot be undone. This will permanently delete your account and remove your data from our servers."
+ },
+ "table": {
+ "row-per-page": "Rows per page",
+ "no-result": "No results",
+ "selected": "Selected",
+ "toggle-column": "Toggle columns",
+ "filter-placeholder": "Filter {{name}}"
+ },
+ "statuses": {
+ "active": "Active",
+ "connected": "Connected",
+ "healthy": "Healthy",
+ "disabled": "Disabled",
+ "expired": "Expired",
+ "on_hold": "On Hold",
+ "connecting": "Connecting",
+ "unhealthy": "Unhealthy",
+ "limited": "Limited",
+ "error": "Error"
+ }
+}
diff --git a/dashboard/public/locales/kmr.json b/dashboard/public/locales/kmr.json
@@ -0,0 +1,218 @@
+{
+ "name": "Naw",
+ "status": "Dox",
+ "address": "Edrês",
+ "users": "Bekarhêneran",
+ "nodes": "Girêkan",
+ "services": "Rajekan",
+ "hosts": "Hostkan",
+ "username": "Naw Bekarhêneran",
+ "password": "Têperrewişe",
+ "inbounds": "înbawendkan",
+ "submit": "Nardin",
+ "login": "Çûnejûrew",
+ "edit": "Desitkarîkirdn",
+ "actions": "Fermankan",
+ "settings": "Sazkarîyekan",
+ "logs": "Tomarekan",
+ "config": "Kanfîg",
+ "open": "Kirnewe",
+ "delete": "Sirrînewe",
+ "port": "Port",
+ "create": "Dirust bike",
+ "path": "Path",
+ "host": "Host",
+ "alpn": "ALPN",
+ "security": "Security",
+ "user_info": "Users Info",
+ "subscription": "Subscription",
+ "subscription_link": "Subscription Link",
+ "fingerprint": "Fingerprint",
+ "page": {
+ "settings": {
+ "certificate": {
+ "copy": "Copy Certificate",
+ "error": "Certificate Unavailable",
+ "copied": "Certificate Copied"
+ }
+ },
+ "login": {
+ "username": {
+ "error": {
+ "isRequired": "Username is required"
+ }
+ },
+ "password": {
+ "error": {
+ "is-required": "Password is required"
+ }
+ }
+ },
+ "nodes": {
+ "settings": {
+ "title": "Nodes Settings",
+ "detail": "Details",
+ "log-container": {
+ "title": "Marznode Xray config logs"
+ }
+ },
+ "dialogs": {
+ "creation": {
+ "title": "Nodes Creation"
+ },
+ "deletion": {
+ "title": "Nodes Deletion"
+ },
+ "edition": {
+ "title": "Nodes Edition"
+ }
+ },
+ "usage_coefficient": "Usage Coefficient",
+ "add_as_new_host": "Add as new hosts",
+ "certificate-alert": {
+ "title": "Nodes Certificate Configuration",
+ "desc": "If you aim to configure your nodes certificate, checkout settings page.",
+ "click": "Click Here"
+ }
+ },
+ "services": {
+ "settings": {
+ "title": "Servicecs Settings",
+ "detail": "Details"
+ },
+ "dialogs": {
+ "creation": {
+ "title": "Services Creation"
+ },
+ "deletion": {
+ "title": "Services Deletion"
+ },
+ "edition": {
+ "title": "Services Edition"
+ }
+ }
+ },
+ "users": {
+ "data_limit": "Data Limit",
+ "used_traffic": "Used Traffic",
+ "data_limit_reset_strategy": "Data Limit Reset Strategy",
+ "online_at": "Online At",
+ "expire_date": "Expire Date",
+ "unlimited": "Unlimited",
+ "determined_expire": "Determined",
+ "expire_method": "Expiration method",
+ "onhold_expire": "On Hold",
+ "reset_usage": "Reset Usage",
+ "revoke_subscription": "Revoke Subscription",
+ "on_hold_expire_duration": "On Hold",
+ "on_hold_timeout": "On Hold Timeout",
+ "settings": {
+ "subscription_link": {
+ "copied": "Subscription Link Copied",
+ "copy": "Copy Subscription Link",
+ "error": "Unable to copy Subscription Link"
+ }
+ },
+ "services-alert": {
+ "title": "No Service were found",
+ "desc": "Make sure you create services to enable your users with inbounds to connect with.",
+ "click": "Click Here"
+ },
+ "dialogs": {
+ "edition": {
+ "title": "Users Edition"
+ },
+ "creation": {
+ "title": "Users Creation"
+ },
+ "deletion": {
+ "title": "Users Deletion"
+ },
+ "mutation": {
+ "note": {
+ "desc": "Leave a note about your user"
+ }
+ }
+ }
+ },
+ "hosts": {
+ "allowinsecure": "Allow insecure",
+ "dialogs": {
+ "edition": {
+ "title": "Hosts Edition"
+ },
+ "creation": {
+ "title": "Hosts Creation"
+ },
+ "deletion": {
+ "title": "Hosts Deletion"
+ },
+ "mutation": {
+ "allowinsecure": {
+ "alert": "Due to security concerns, it is not recommended to allow Insecure"
+ }
+ }
+ }
+ }
+ },
+ "events": {
+ "delete": {
+ "error": "Failed to delete {{name}}",
+ "success": {
+ "title": "{{name}} is successfuly deleted",
+ "desc": ""
+ }
+ },
+ "create": {
+ "error": "Failed to create {{name}}",
+ "success": {
+ "title": "{{name}} is successfuly created",
+ "desc": ""
+ }
+ },
+ "update": {
+ "error": "Failed to update {{name}}",
+ "success": {
+ "title": "{{name}} is successfuly updated",
+ "desc": ""
+ }
+ },
+ "user_revoke": {
+ "error": "Failed to revoke {{name}} subscription",
+ "success": {
+ "title": "{{name}} is successfuly created",
+ "desc": ""
+ }
+ },
+ "user_reset": {
+ "error": "Failed to reset {{name}} data usage",
+ "success": {
+ "title": "{{name}} data usage is successfuly reseted",
+ "desc": ""
+ }
+ }
+ },
+ "delete-confirmation": {
+ "title": "Are you sure of this?",
+ "desc": "This action cannot be undone. This will permanently delete your account and remove your data from our servers."
+ },
+ "table": {
+ "row-per-page": "Rows per page",
+ "no-result": "No results",
+ "selected": "Selected",
+ "toggle-column": "Toggle columns",
+ "filter-placeholder": "Filter {{name}}"
+ },
+ "statuses": {
+ "active": "Active",
+ "connected": "Connected",
+ "healthy": "Healthy",
+ "disabled": "Disabled",
+ "expired": "Expired",
+ "on_hold": "On Hold",
+ "connecting": "Connecting",
+ "unhealthy": "Unhealthy",
+ "limited": "Limited",
+ "error": "Error"
+ }
+}
diff --git a/dashboard/public/locales/ku-sor-latin.json b/dashboard/public/locales/ku-sor-latin.json
@@ -1,118 +0,0 @@
-{
- "name": "Naw",
- "status": "Dox",
- "address": "Edrês",
- "users": "Bekarhêneran",
- "nodes": "Girêkan",
- "services": "Rajekan",
- "hosts": "Hostkan",
- "username": "Naw Bekarhêneran",
- "password": "Têperrewişe",
- "inbounds": "înbawendkan",
- "submit": "Nardin",
- "login": "Çûnejûrewe",
- "edit": "Desitkarîkirdn",
- "actions": "Firman",
- "settings": "Sazkarîyekan",
- "logs": "Tomarkan",
- "config": "Kanfîg",
- "open": "Kirnewe",
- "delete": "Sirrînewe",
- "port": "Port",
- "create": "Create",
- "page": {
- "settings": {
- "certificate": {
- "copy": "Copy Certificate",
- "error": "Certificate Unavailable",
- "copied": "Certificate Copied"
- }
- },
- "login": {
- "username": {
- "error": {
- "isRequired": "Username is required"
- }
- },
- "password": {
- "error": {
- "is-required": "Password is required"
- }
- }
- },
- "nodes": {
- "settings": {
- "title": "Nodes Settings",
- "detail": "Details",
- "log-container": {
- "title": "Marznode Xray config logs"
- }
- },
- "dialogs": {
- "creation": {
- "title": "Nodes Creation"
- },
- "deletion": {
- "title": "Nodes Deletion"
- },
- "edition": {
- "title": "Nodes Edition"
- }
- },
- "usage_coefficient": "Usage Coefficient",
- "add_as_new_host": "Add as new hosts",
- "certificate-alert": {
- "title": "Nodes Certificate Configuration",
- "desc": "If you aim to configure your nodes certificate, checkout settings page.",
- "click": "Click Here"
- }
- },
- "services": {
- "dialogs": {
- "creation": {
- "title": "Services Creation"
- },
- "deletion": {
- "title": "Services Deletion"
- },
- "edition": {
- "title": "Services Edition"
- }
- }
- }
- },
- "events": {
- "delete": {
- "error": "Failed to delete {{name}}",
- "success": {
- "title": "{{name}} is successfuly deleted",
- "desc": ""
- }
- },
- "create": {
- "error": "Failed to create {{name}}",
- "success": {
- "title": "{{name}} is successfuly created",
- "desc": ""
- }
- },
- "update": {
- "error": "Failed to update {{name}}",
- "success": {
- "title": "{{name}} is successfuly updated",
- "desc": ""
- }
- }
- },
- "delete-confirmation": {
- "title": "Are you sure of this?",
- "desc": "This action cannot be undone. This will permanently delete your account and remove your data from our servers."
- },
- "table": {
- "row-per-page": "Rows per page",
- "no-result": "No results",
- "selected": "Selected",
- "toggle-column": "Toggle columns",
- "filter-placeholder": "Filter {{name}}"
- }
-}
diff --git a/dashboard/public/locales/kur.json b/dashboard/public/locales/kur.json
@@ -0,0 +1,218 @@
+{
+ "name": "Naw",
+ "status": "Dox",
+ "address": "Edrês",
+ "users": "Bekarhêneran",
+ "nodes": "Girêkan",
+ "services": "Rajekan",
+ "hosts": "Hostkan",
+ "username": "Nawî Bekarhêneran",
+ "password": "Têperrewişe",
+ "inbounds": "înbawendkan",
+ "submit": "Nardin",
+ "login": "Çûnejûrew",
+ "edit": "Desitkarîkirdn",
+ "actions": "Fermankan",
+ "settings": "Sazkarîyekan",
+ "logs": "Tomarekan",
+ "config": "Kanfîg",
+ "open": "Kirnewe",
+ "delete": "Sirrînewe",
+ "port": "Port",
+ "create": "Dirust bike",
+ "path": "Path",
+ "host": "Host",
+ "alpn": "ALPN",
+ "security": "Security",
+ "user_info": "Users Info",
+ "subscription": "Subscription",
+ "subscription_link": "Subscription Link",
+ "fingerprint": "Fingerprint",
+ "page": {
+ "settings": {
+ "certificate": {
+ "copy": "Copy Certificate",
+ "error": "Certificate Unavailable",
+ "copied": "Certificate Copied"
+ }
+ },
+ "login": {
+ "username": {
+ "error": {
+ "isRequired": "Username is required"
+ }
+ },
+ "password": {
+ "error": {
+ "is-required": "Password is required"
+ }
+ }
+ },
+ "nodes": {
+ "settings": {
+ "title": "Nodes Settings",
+ "detail": "Details",
+ "log-container": {
+ "title": "Marznode Xray config logs"
+ }
+ },
+ "dialogs": {
+ "creation": {
+ "title": "Nodes Creation"
+ },
+ "deletion": {
+ "title": "Nodes Deletion"
+ },
+ "edition": {
+ "title": "Nodes Edition"
+ }
+ },
+ "usage_coefficient": "Usage Coefficient",
+ "add_as_new_host": "Add as new hosts",
+ "certificate-alert": {
+ "title": "Nodes Certificate Configuration",
+ "desc": "If you aim to configure your nodes certificate, checkout settings page.",
+ "click": "Click Here"
+ }
+ },
+ "services": {
+ "settings": {
+ "title": "Servicecs Settings",
+ "detail": "Details"
+ },
+ "dialogs": {
+ "creation": {
+ "title": "Services Creation"
+ },
+ "deletion": {
+ "title": "Services Deletion"
+ },
+ "edition": {
+ "title": "Services Edition"
+ }
+ }
+ },
+ "users": {
+ "data_limit": "Data Limit",
+ "used_traffic": "Used Traffic",
+ "data_limit_reset_strategy": "Data Limit Reset Strategy",
+ "online_at": "Online At",
+ "expire_date": "Expire Date",
+ "unlimited": "Unlimited",
+ "determined_expire": "Determined",
+ "expire_method": "Expiration method",
+ "onhold_expire": "On Hold",
+ "reset_usage": "Reset Usage",
+ "revoke_subscription": "Revoke Subscription",
+ "on_hold_expire_duration": "On Hold",
+ "on_hold_timeout": "On Hold Timeout",
+ "settings": {
+ "subscription_link": {
+ "copied": "Subscription Link Copied",
+ "copy": "Copy Subscription Link",
+ "error": "Unable to copy Subscription Link"
+ }
+ },
+ "services-alert": {
+ "title": "No Service were found",
+ "desc": "Make sure you create services to enable your users with inbounds to connect with.",
+ "click": "Click Here"
+ },
+ "dialogs": {
+ "edition": {
+ "title": "Users Edition"
+ },
+ "creation": {
+ "title": "Users Creation"
+ },
+ "deletion": {
+ "title": "Users Deletion"
+ },
+ "mutation": {
+ "note": {
+ "desc": "Leave a note about your user"
+ }
+ }
+ }
+ },
+ "hosts": {
+ "allowinsecure": "Allow insecure",
+ "dialogs": {
+ "edition": {
+ "title": "Hosts Edition"
+ },
+ "creation": {
+ "title": "Hosts Creation"
+ },
+ "deletion": {
+ "title": "Hosts Deletion"
+ },
+ "mutation": {
+ "allowinsecure": {
+ "alert": "Due to security concerns, it is not recommended to allow Insecure"
+ }
+ }
+ }
+ }
+ },
+ "events": {
+ "delete": {
+ "error": "Failed to delete {{name}}",
+ "success": {
+ "title": "{{name}} is successfuly deleted",
+ "desc": ""
+ }
+ },
+ "create": {
+ "error": "Failed to create {{name}}",
+ "success": {
+ "title": "{{name}} is successfuly created",
+ "desc": ""
+ }
+ },
+ "update": {
+ "error": "Failed to update {{name}}",
+ "success": {
+ "title": "{{name}} is successfuly updated",
+ "desc": ""
+ }
+ },
+ "user_revoke": {
+ "error": "Failed to revoke {{name}} subscription",
+ "success": {
+ "title": "{{name}} is successfuly created",
+ "desc": ""
+ }
+ },
+ "user_reset": {
+ "error": "Failed to reset {{name}} data usage",
+ "success": {
+ "title": "{{name}} data usage is successfuly reseted",
+ "desc": ""
+ }
+ }
+ },
+ "delete-confirmation": {
+ "title": "Are you sure of this?",
+ "desc": "This action cannot be undone. This will permanently delete your account and remove your data from our servers."
+ },
+ "table": {
+ "row-per-page": "Rows per page",
+ "no-result": "No results",
+ "selected": "Selected",
+ "toggle-column": "Toggle columns",
+ "filter-placeholder": "Filter {{name}}"
+ },
+ "statuses": {
+ "active": "Active",
+ "connected": "Connected",
+ "healthy": "Healthy",
+ "disabled": "Disabled",
+ "expired": "Expired",
+ "on_hold": "On Hold",
+ "connecting": "Connecting",
+ "unhealthy": "Unhealthy",
+ "limited": "Limited",
+ "error": "Error"
+ }
+}
diff --git a/dashboard/src/features/i18n/index.ts b/dashboard/src/features/i18n/index.ts
@@ -3,45 +3,41 @@ import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import HttpApi from 'i18next-http-backend';
import { initReactI18next } from 'react-i18next';
-import { joinPaths } from '@remix-run/router';
declare module 'i18next' {
- interface CustomTypeOptions {
- returnNull: false;
- }
+ interface CustomTypeOptions {
+ returnNull: false;
+ }
}
i18n
- .use(LanguageDetector)
- .use(initReactI18next)
- .use(HttpApi)
- .init(
- {
- debug: import.meta.env.NODE_ENV === 'development',
- returnNull: false,
- fallbackLng: 'en',
- interpolation: {
- escapeValue: false,
- },
- react: {
- useSuspense: false,
- },
- load: 'languageOnly',
- detection: {
- caches: ['localStorage', 'sessionStorage', 'cookie'],
- },
- backend: {
- loadPath: joinPaths([import.meta.env.BASE_URL, 'locales/{{lng}}.json']),
- },
- supportedLngs: ['en', 'ku-kur', 'ku-sor', 'ku-sor-latin', 'fa', 'ru'],
- },
- function() {
- dayjs.locale(i18n.language);
- }
- );
+ .use(LanguageDetector)
+ .use(HttpApi)
+ .use(initReactI18next)
+ .init({
+ debug: process.env.NODE_ENV === 'development',
+ fallbackLng: 'en',
+ interpolation: {
+ escapeValue: false,
+ },
+ react: {
+ useSuspense: false,
+ },
+ load: 'languageOnly',
+ detection: {
+ order: ['localStorage', 'sessionStorage', 'cookie', 'navigator'],
+ },
+ backend: {
+ loadPath: '/locales/{{lng}}.json',
+ },
+ supportedLngs: ['en', 'kur', 'kmr', 'ckb', 'fa', 'ru'],
+ })
+ .then(() => {
+ dayjs.locale(i18n.language);
+ });
i18n.on('languageChanged', (lng) => {
- dayjs.locale(lng);
+ dayjs.locale(lng);
});
export default i18n;
diff --git a/dashboard/src/features/language-switch/index.tsx b/dashboard/src/features/language-switch/index.tsx
@@ -4,40 +4,40 @@ import { FC } from "react";
import { useTranslation } from "react-i18next";
export const LanguageSwitch: FC = () => {
- const { i18n } = useTranslation();
+ const { i18n } = useTranslation();
- const changeLanguage = (lang: string) => {
- i18n.changeLanguage(lang);
- };
+ const changeLanguage = (lang: string) => {
+ i18n.changeLanguage(lang);
+ };
- return (
- <DropdownMenu>
- <DropdownMenuTrigger asChild>
- <Button variant="outline" className="bg-secondary-foreground text-primary-foreground " size="icon">
- <Languages className="h-[1rem] w-[1rem]" />
- <span className="sr-only">Toggle Language</span>
- </Button>
- </DropdownMenuTrigger>
- <DropdownMenuContent align="end">
- <DropdownMenuItem onClick={() => changeLanguage("en")}>
- English
- </DropdownMenuItem>
- <DropdownMenuItem onClick={() => changeLanguage("ku-kur")}>
- Kurdî (Kur)
- </DropdownMenuItem>
- <DropdownMenuItem onClick={() => changeLanguage("ku-sor-latin")}>
- Kurdî (Sor-Latin)
- </DropdownMenuItem>
- <DropdownMenuItem onClick={() => changeLanguage("ku-sor")}>
- Kurdî (Sor)
- </DropdownMenuItem>
- <DropdownMenuItem onClick={() => changeLanguage("fa")}>
- فارسی
- </DropdownMenuItem>
- <DropdownMenuItem onClick={() => changeLanguage("fa")}>
- Русский
- </DropdownMenuItem>
- </DropdownMenuContent>
- </DropdownMenu>
- );
+ return (
+ <DropdownMenu>
+ <DropdownMenuTrigger asChild>
+ <Button variant="outline" className="bg-secondary-foreground text-primary-foreground " size="icon">
+ <Languages className="h-[1rem] w-[1rem]" />
+ <span className="sr-only">Toggle Language</span>
+ </Button>
+ </DropdownMenuTrigger>
+ <DropdownMenuContent align="end">
+ <DropdownMenuItem onClick={() => changeLanguage("en")}>
+ English
+ </DropdownMenuItem>
+ <DropdownMenuItem onClick={() => changeLanguage("kmr")}>
+ Kurdî Kurmancî
+ </DropdownMenuItem>
+ <DropdownMenuItem onClick={() => changeLanguage("kur")}>
+ Kurdî Nawendî (Latin)
+ </DropdownMenuItem>
+ <DropdownMenuItem onClick={() => changeLanguage("ckb")}>
+ کوردی ناوەندی
+ </DropdownMenuItem>
+ <DropdownMenuItem onClick={() => changeLanguage("fa")}>
+ فارسی
+ </DropdownMenuItem>
+ <DropdownMenuItem onClick={() => changeLanguage("fa")}>
+ Русский
+ </DropdownMenuItem>
+ </DropdownMenuContent>
+ </DropdownMenu>
+ );
};