🌐i18n support

This commit is contained in:
jarvis2f 2024-03-25 16:09:27 +08:00
parent f09608fa42
commit 523bc81b66
150 changed files with 2237 additions and 373 deletions

4
global.d.ts vendored Normal file
View File

@ -0,0 +1,4 @@
// Use type safe message keys with `next-intl`
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
type Messages = typeof import("./messages/en.json");
type IntlMessages = Messages;

719
messages/en.json Normal file
View File

@ -0,0 +1,719 @@
{
"admin-config": {},
"admin-config-[classify]": {},
"admin-config-code-input-dialog": {
"edit": "Edit",
"preview": "Preview"
},
"admin-config-config-field": {
"save": "Save"
},
"admin-config-config-list": {},
"admin-config-cron-input": {
"after": "After",
"any_value": "Any Value",
"day": "Day",
"hide": "Hide",
"hour": "Hour",
"minute": "Minute",
"month": "Month",
"more": "More",
"next": "Next",
"possible_values": "Possible Values",
"step": "Step",
"value_in_range": "Value in Range",
"value_separator": "Value Separator",
"week": "Week"
},
"admin-config-layout": {
"general": "General",
"general_config_etc": "general config, etc.",
"including_log_config": "Including log config",
"log_config": "Log Config",
"node_related_config": "Node Related Config",
"payment_records": "Payment Records",
"recharge_code": "Recharge Code",
"system_config": "System Config",
"website_system_config": "Website System Config",
"withdrawal_records": "Withdrawal Records"
},
"admin-config-payment": {},
"admin-config-payment-info": {},
"admin-config-payment-table": {
"info": "Info",
"received_amount": "Received Amount",
"recharge_amount": "Recharge Amount",
"reset": "Reset",
"status": "Status",
"user": "User"
},
"admin-config-recharge-code": {
"balance": "Balance",
"batch_generate_export_recharge_code": "Batch generate and export recharge code",
"manage_recharge_code": "Manage Recharge Code",
"personal_center": "Personal Center",
"recharge_code": "Recharge Code",
"recharge_code_in": "Recharge code in",
"recharge_use": "Recharge Use"
},
"admin-config-recharge-code-table": {
"add": "Add",
"amount": "Amount",
"cancel": "Cancel",
"confirm_delete_recharge_code": "Are you sure you want to delete this recharge code?",
"continue": "Continue",
"create_recharge_code": "Create Recharge Code",
"export_after_creation": "Export after creation",
"pieces": "pieces",
"quantity": "Quantity",
"recharge_code": "Recharge Code",
"reset": "Reset",
"save": "Save",
"total": "Total",
"usage_status": "Usage Status",
"used": "Used",
"used_by": "Used By",
"user": "User",
"yuan": "yuan"
},
"admin-config-traffic-price-config": {
"price": "Price",
"unit": "Unit"
},
"admin-config-withdraw": {},
"admin-config-withdrawal-table": {
"address": "Address",
"operation_successful": "Operation Successful",
"reset": "Reset",
"status": "Status",
"user": "User",
"user_wallet_balance_updated": "User wallet earnings balance has been automatically updated",
"withdrawal_amount": "Withdrawal Amount",
"withdrawal_status_updated": "Withdrawal status has been updated"
},
"admin-log": {
"logs": "Logs"
},
"admin-log-log": {
"copied_to_clipboard": "Copied to clipboard"
},
"admin-log-log-delete": {
"cancel": "Cancel",
"confirm_delete_all_logs": "Are you sure you want to delete all logs?",
"continue": "Continue"
},
"admin-log-log-glance": {},
"admin-log-log-search-keyword": {
"advanced_search": "Advanced Search",
"array_index_is": "Array index is",
"array_index_with": "Array index with",
"default_fuzzy_search": "Default fuzzy search",
"field": "Field",
"for_example": "For example",
"format": "Format",
"of": "of",
"query": "Query",
"search": "Search",
"separated": "separated",
"support": "Support",
"syntax": "Syntax",
"with": "with",
"wrapped": "wrapped"
},
"admin-log-log-toolbar": {
"add_log_display_field_config": "Add log display field configuration",
"new_logs_available": "New logs available",
"reset": "Reset"
},
"admin-log-logs": {},
"admin-users": {
"users": "Users"
},
"admin-users-user-role-setting": {
"modify_role": "Modify Role",
"relogin_required_after_modification": "Relogin required after modification"
},
"admin-users-user-status": {
"activate_user": "Activate this user",
"ban_user": "Ban this user"
},
"admin-users-user-table": {
"email": "Email",
"filter_name": "Filter Name",
"info": "Info",
"operation": "Operation",
"reset": "Reset",
"role": "Role",
"status": "Status"
},
"agent": {},
"agent-[agentId]-config-base": {
"basic_info": "Basic Info",
"server": "Server"
},
"agent-[agentId]-config-other": {
"other_settings": "Other Settings",
"server": "Server"
},
"agent-[agentId]-forward": {
"forward": "Forward",
"server": "Server"
},
"agent-[agentId]-install": {
"install": "Install",
"server": "Server"
},
"agent-[agentId]-layout": {
"server": "Server"
},
"agent-[agentId]-loading": {},
"agent-[agentId]-log": {
"logs": "Logs",
"server": "Server"
},
"agent-[agentId]-status": {
"address": "Address",
"bandwidth": "Bandwidth",
"info": "Info",
"last_response": "Last Response",
"memory": "Memory",
"node_version": "Node Version",
"price": "Price",
"server": "Server",
"status": "Status",
"system": "System",
"traffic": "Traffic",
"unknown": "Unknown"
},
"agent-agent-command": {
"enter_command": "Enter command",
"execute": "Execute",
"execute_command": "Execute Command",
"execution_result": "Execution Result",
"failed": "Failed",
"success": "Success",
"type": "Type"
},
"agent-agent-config": {
"server_basic_info_settings": "Server Basic Info Settings"
},
"agent-agent-delete": {
"all_forwarding_stopped": "All forwarding will be stopped.",
"all_related_data_deleted": "And all related data will be deleted.",
"cancel": "Cancel",
"confirm_delete_server": "Are you sure you want to delete this server?",
"continue": "Continue",
"operation_irreversible": "This action cannot be undone.",
"server_deleted_from_system": "This server will be deleted from the system."
},
"agent-agent-form": {
"description": "Description",
"name": "Name",
"save": "Save",
"server_description": "Server Description",
"server_name": "Server Name",
"share": "Share",
"share_with_other_users": "Share with other users",
"used_to_distinguish_servers": "Used to distinguish different servers"
},
"agent-agent-install": {
"after_installation": "After installation",
"click": "click",
"copy_command_below_to_install": "Copy the command below to install",
"copy_command_below_to_uninstall": "Copy the command below to uninstall",
"execute_in_installation_directory": "Please execute in the installation directory",
"if_installation_command_leaked": "If the installation command is leaked",
"install": "Install",
"server_status_will_change": "the server status will change",
"successful_log_message": "You will see a successful log message",
"uninstall": "Uninstall",
"uninstall_deletes_all_configs_and_files": "Uninstalling will delete all configurations and files under the installation directory",
"update": "Update",
"version": "Version",
"view_installation_progress_on_logs_page": "You can view the installation progress on the logs page"
},
"agent-agent-list": {},
"agent-agent-list-aside": {
"add_server": "Add Server",
"offline_servers": "Offline Servers",
"online_servers": "Online Servers",
"search_server": "Search Server",
"unknown_servers": "Unknown Servers",
"add_tips": "Click save to view the sidebar server list.Add Relay Server, Save to receive an installation command, Copy and execute it on the server"
},
"agent-agent-menu": {
"basic_info": "Basic Info",
"config": "Config",
"forward": "Forward",
"install": "Install",
"log_config_etc": "Log config, etc.",
"logs": "Logs",
"other_settings": "Other Settings",
"port": "Port",
"price": "Price",
"remarks_etc": "Remarks, etc.",
"server_name": "Server Name",
"status": "Status"
},
"agent-agent-price": {},
"agent-agent-resizable-layout": {},
"agent-bandwidth-usage": {
"download": "Download",
"upload": "Upload"
},
"agent-cpu-usage": {},
"agent-mem-usage": {},
"agent-traffic-usage": {
"download": "Download",
"upload": "Upload"
},
"auth-error": {
"access_denied": "Access Denied",
"an_error_occurred": "Whoops! Something went wrong.",
"back_to_signin": "Back to Sign In",
"check_details_provided_are_correct": "Check that the details you provided are correct.",
"check_information_provided_is_correct": "Please check that the information you provided is correct.",
"check_server_logs_for_more_info": "Check the server logs for more information.",
"email_could_not_be_sent": "The email could not be sent.",
"it_may_have_been_used_or_expired": "It may have been used already or it may have expired.",
"not_authorized_to_signin": "You are not authorized to sign in.",
"please_signin_to_access_this_page": "Please sign in to access this page.",
"server_error": "Server Error",
"server_misconfigured": "There's a problem with the server configuration.",
"signin_link_no_longer_valid": "The sign-in link is no longer valid.",
"oauth_account_not_linked": "To confirm your identity, please sign in with the same account you originally used.",
"try_signing_in_with_different_account": "Try signing in with a different account.",
"unable_to_signin": "Unable to Sign In",
"user_disabled": "User Disabled",
"your_account_has_been_disabled": "Your account has been disabled."
},
"auth-layout": {},
"auth-new": {
"create_password": "Create Password",
"create_password_for_account": "Create a password for your account",
"skip_password_tips": "Skip password setup and sign in directly",
"create_password_tips": "Create a password for your account, so you can sign in with your email address and password."
},
"auth-signin": {
"and": "and",
"by_continuing_you_agree_to_our": "By continuing, you agree to our",
"continue": "Continue",
"create_an_account": "Create an Account",
"enter_email_signin_or_register": "Enter your email to sign in or create an account.",
"or_use": "Or use",
"password_signin": "Sign in with Password",
"privacy_policy": "Privacy Policy",
"registration_closed": "Registration is currently closed.",
"signin": "Sign In",
"terms_of_service": "Terms of Service",
"your_email_address": "Your Email Address"
},
"auth-signin-credential": {
"and": "and",
"back_to_signup": "Back to Sign Up",
"by_continuing_you_agree_to_our": "By continuing, you agree to our",
"enter_valid_email_address": "Please enter a valid email address.",
"enter_your_password": "Please enter your password.",
"password_signin": "Sign in with Password",
"privacy_policy": "Privacy Policy",
"signin": "Sign In",
"terms_of_service": "Terms of Service",
"your_email_address": "Your Email Address",
"your_password": "Your Password"
},
"auth-signout": {
"confirm": "Confirm",
"confirm_sign_out": "Sure you wanna sign out?"
},
"auth-verify": {},
"dashboard": {
"announcement": "Announcement",
"balance": "Balance",
"earnings": "Earnings",
"no_announcement": "No announcement",
"recent_days_traffic_usage": "Recent 7 days of traffic usage",
"system_running_normally": "System is running normally",
"system_status": "System Status",
"traffic_usage": "Traffic Usage",
"yesterday_consumption": "Yesterday's Consumption",
"yesterday_earnings": "Yesterday's Earnings"
},
"dashboard-system-status": {
"download": "Download",
"memory": "Memory",
"network": "Network",
"upload": "Upload"
},
"dashboard-traffic-usage": {
"used_traffic": "Used Traffic"
},
"forward": {
"forward": "Forward"
},
"forward-forward-delete": {
"all_related_data_deleted": "and all related data will be deleted.",
"cancel": "Cancel",
"confirm_delete_forward_config": "Are you sure you want to delete this forwarding configuration?",
"continue": "Continue",
"delete_entire_network_on_networking_page": "you should go to the networking page to delete the entire network",
"forwarding_stopped": "Forwarding will be stopped",
"if_forward_created_through_networking": "If this forwarding was created through networking",
"operation_irreversible": "This action cannot be undone."
},
"forward-forward-modify-remark": {
"cancel": "Cancel",
"enter_remark_here": "Enter your remark here",
"save": "Save",
"update_forward_remark": "Update Forward Remark"
},
"forward-forward-new": {
"can_be": "Can be",
"enter_forwarding_info": "Please fill in the forwarding information",
"forwarding_method": "Forwarding Method",
"forwarding_target": "Forwarding Target",
"limit_range": "Limit Range",
"more_config": "More Config",
"new_forward": "New Forward",
"no_available_servers": "No available servers",
"or_domain_name": "or domain name",
"relay_server": "Relay Server",
"remark": "Remark",
"reset": "Reset",
"save": "Save",
"select_forwarding_method": "Please select a forwarding method",
"select_relay_server": "Please select a relay server",
"server": "Server",
"server_port": "Server Port",
"target_port": "Target Port"
},
"forward-forward-new-gost": {
"channel": "Channel",
"enable_after_selection": "Enable after selection",
"multiplexing": "Multiplexing",
"protocol": "Protocol",
"relay_data_channel": "Relay Data Channel",
"relay_data_protocol": "Relay Data Protocol"
},
"forward-forward-reset-traffic": {
"cancel": "Cancel",
"confirm_reset_forward_traffic": "Are you sure you want to reset the traffic for this forwarding configuration?",
"continue": "Continue",
"operation_irreversible": "This action cannot be undone.",
"used_traffic_reset": "Used traffic will be reset"
},
"forward-forward-table": {
"add": "Add",
"delete": "Delete",
"modify_remark": "Modify Remark",
"remark": "Remark",
"reset": "Reset",
"reset_traffic": "Reset Traffic",
"server": "Server",
"status": "Status",
"target": "Target",
"used_traffic": "Used Traffic",
"user": "User"
},
"global_theme-provider": {},
"global_monthly-traffic-usage": {
"january": "January",
"february": "February",
"march": "March",
"april": "April",
"may": "May",
"june": "June",
"july": "July",
"august": "August",
"september": "September",
"october": "October",
"november": "November",
"december": "December",
"upload": "Upload",
"download": "Download"
},
"global_user-column": {},
"global_channel-selector": {
"select-a-channel": "Select a channel",
"search": "Search",
"no-data": "No data"
},
"global_search-empty-state": {},
"global_update-password-dialog": {
"change-password": "Change Password",
"set-password": "Set Password",
"update-password": "Update Password"
},
"global_resizable-layout": {},
"global_traffic": {},
"global_code-input": {
"format": "Format"
},
"global_update-password-form": {
"password-must-be-at-least": "Password must be at least",
"characters-long": "characters long",
"and-contain-at-least": "and contain at least",
"letters-and": "letters and",
"numbers": "numbers",
"passwords-do-not-match": "Passwords do not match",
"please-enter-your-old-password": "Please enter your old password",
"old-password": "Old Password",
"password": "Password",
"confirm-password": "Confirm Password",
"save": "Save"
},
"global_locale-switcher": {
"label": "Change language",
"locale": "{locale, select, zh {🇨🇳 简体中文} en {🇺🇸 English} other {Unknown}}"
},
"global_faceted-filter": {},
"global_logo": {},
"global_id": {
"created-at": "Created at"
},
"global_menu": {
"personal-center": "Personal Center",
"balance": "Balance",
"logout": "Logout",
"dashboard": "Dashboard",
"forward": "Forward",
"agent": "Agent",
"network": "Network",
"ticket": "Ticket",
"manage": "Manage",
"users": "Users",
"statistics": "Statistics",
"system": "System",
"log": "Log",
"config": "Config"
},
"global_table-faceted-filter": {},
"global_loading": {},
"global_table": {
"no-data": "No data"
},
"global_sidebar-nav": {},
"global_welcome": {},
"global_table-view-options": {},
"index": {
"Dashboard": "Dashboard",
"Sign In": "Sign In",
"Welcome": "Welcome"
},
"network": {
"networking": "Nope"
},
"network-[networkId]": {
"networking": "Nope"
},
"network-agent-edge": {
"random": "Random"
},
"network-agent-edge-forward-settings": {
"channel": "Channel",
"default_random": "Default Random",
"enter_port_to_forward": "Enter the port you need to forward",
"forwarding_method": "Forwarding Method",
"forwarding_method_required": "Forwarding method is required",
"forwarding_port": "Forwarding Port",
"forwarding_port_required": "Forwarding port is required",
"listening_port": "Listening Port",
"listening_port_greater_than": "Listening port must be greater than",
"listening_port_less_than": "Listening port must be less than",
"port_range": "Port Range",
"relay_settings": "Relay Settings",
"target_port_greater_than": "Target port must be greater than",
"target_port_less_than": "Target port must be less than"
},
"network-agent-edge-test": {
"avg_delay": "Avg Delay",
"diagnose_relayed_network_connection": "Diagnose relayed network connection",
"execution_result": "Execution Result",
"failed": "Failed",
"max_delay": "Max Delay",
"min_delay": "Min Delay",
"network_diagnostics": "Network Diagnostics",
"packet_loss_rate": "Packet Loss Rate",
"start": "Start",
"test": "Test",
"test_method": "Test Method"
},
"network-agent-edge-toolbar": {},
"network-agent-node": {},
"network-external-node": {},
"network-external-node-new": {
"address": "Address",
"address_or_domain_name": "address or domain name",
"create": "Create",
"create_external_node": "Create External Node",
"enter_external_node": "Enter external node",
"enter_external_node_name": "Enter external node name",
"enter_node_address": "Enter node address",
"enter_node_name": "Enter node name",
"enter_valid_address": "Please enter a valid address.",
"name": "Name",
"support": "Support",
"used_to_identify_node": "Used to identify this node"
},
"network-network-command": {
"add_external_node": "Add External Node",
"added": "Added",
"operation": "Operation",
"search_add_server": "Search and add server"
},
"network-network-delete": {
"all_forwarding_stopped": "All forwarding will be stopped.",
"all_related_data_deleted": "And all related data will be deleted.",
"cancel": "Cancel",
"confirm_delete_network_config": "Are you sure you want to delete this network configuration?",
"continue": "Continue",
"network_config_deleted_from_system": "This network configuration will be deleted from the system.",
"operation_irreversible": "This action cannot be undone."
},
"network-network-edit": {
"apply_to_network": "Apply to Network",
"cancel": "Cancel",
"network_name": "Network Name",
"please_operate_with_caution": "Please proceed with caution.",
"save": "Save",
"save_as_new_network_config": "Save as New Network Config",
"this_will_overwrite_current_network_config": "This will overwrite the current network configuration.",
"update_network_config": "Update Network Config"
},
"network-network-flow": {
"new_network": "New Network"
},
"network-network-selector": {},
"network-network-table": {
"copy_entrance_address": "Copy Entrance Address",
"create_new_network": "Create New Network",
"creator": "Creator",
"filter_name": "Filter Name",
"name": "Name",
"node_info": "Node Info",
"nodes": "Nodes",
"reset": "Reset",
"traffic": "Traffic"
},
"ticket": {
"tickets": "Tickets"
},
"ticket-[ticketId]": {
"created_at": "Created At",
"ticket": "Ticket"
},
"ticket-markdown-input": {
"edit": "Edit",
"preview": "Preview"
},
"ticket-new": {
"create_ticket": "Create Ticket",
"ticket": "Ticket"
},
"ticket-new-ticket-form": {
"briefly_describe_problem": "Please briefly describe your problem",
"characters": "characters",
"content": "Content",
"format": "format",
"max_length": "Max length",
"save": "Save",
"support": "Support",
"title": "Title"
},
"ticket-ticket-close": {
"cancel": "Cancel",
"close": "Close",
"confirm_close_ticket": "Are you sure you want to close this ticket?",
"continue": "Continue"
},
"ticket-ticket-reply": {
"reply": "Reply"
},
"ticket-ticket-status-badge": {},
"ticket-ticket-table": {
"create_new_ticket": "Create New Ticket",
"creator": "Creator",
"reset": "Reset",
"status": "Status",
"title": "Title"
},
"user-[userId]": {
"profile": "Profile",
"relogin_required_to_take_effect": "Requires re-login to take effect",
"set_name_avatar": "Set your name and avatar"
},
"user-[userId]-account": {
"account": "Account",
"email": "Email",
"password": "Password",
"password_not_set": "Password not set",
"view_update_account_info": "View and update your account information"
},
"user-[userId]-balance": {
"available_balance": "Available Balance",
"earnings_amount": "Earnings Amount"
},
"user-[userId]-balance-log": {
"balance": "Balance",
"balance_history": "Balance History",
"change_amount": "Change Amount",
"other_info": "Other Info",
"time": "Time"
},
"user-[userId]-layout": {
"account": "Account",
"balance": "Balance",
"manage_account_settings_email_preferences": "Manage your account settings and set email preferences",
"personal_center": "Personal Center",
"profile": "Profile",
"user_center": "User Center"
},
"user-[userId]-profile-form": {
"avatar": "Avatar",
"avatar_link": "Avatar Link",
"name": "Name",
"name_displayed_in_profile": "Name displayed in your profile",
"save": "Save"
},
"user-[userId]-recharge-balance": {
"balance_recharge": "Balance Recharge",
"enter_recharge_code": "Enter recharge code",
"recharge": "Recharge",
"recharge_code": "Recharge Code"
},
"user-[userId]-recharge-depay": {
"after_clicking_confirm": "After clicking confirm",
"and": "and",
"confirm": "Confirm",
"enter_crypto_wallet_select_payment_method": "you will enter the crypto wallet to select a payment method",
"invalid_amount": "Invalid amount",
"minimum_recharge_amount": "Minimum recharge amount",
"notes": "Notes",
"recharge": "Recharge",
"recharge_amount": "Recharge Amount",
"recharge_failed": "Recharge Failed",
"recharge_handling_fee": "Recharge requires a handling fee of",
"recharge_successful": "Recharge Successful",
"support": "Support",
"supported_networks": "Supported networks"
},
"user-[userId]-update-balance": {
"add_or_subtract_balance": "Add or subtract balance for the user",
"amount": "Amount",
"reduce_balance": "Reduce Balance",
"remark": "Remark",
"save": "Save",
"update_balance": "Update Balance"
},
"user-[userId]-withdrawal-balance": {
"amount": "Amount",
"current_earnings_balance": "Current Earnings Balance",
"deduct_handling_fee": "A handling fee will be deducted",
"minimum_withdrawal_amount": "Minimum withdrawal amount is",
"please_provide": "Please provide",
"receiving_address": "Receiving Address",
"request_withdrawal": "Request Withdrawal",
"request_withdrawal_to_specified_address": "Request withdrawal to the specified address",
"subject_to_actual_received_amount": "Subject to the actual received amount",
"withdrawal": "Withdrawal"
}
}

719
messages/zh.json Normal file
View File

@ -0,0 +1,719 @@
{
"admin-config": {},
"admin-config-[classify]": {},
"admin-config-code-input-dialog": {
"edit": "编辑",
"preview": "预览"
},
"admin-config-config-field": {
"save": "保存"
},
"admin-config-config-list": {},
"admin-config-cron-input": {
"after": "之后",
"any_value": "任何值",
"day": "日",
"hide": "隐藏",
"hour": "时",
"minute": "分",
"month": "月",
"more": "更多",
"next": "下次",
"possible_values": "可取的值",
"step": "步长",
"value_in_range": "范围内的值",
"value_separator": "取值分隔符",
"week": "周"
},
"admin-config-layout": {
"general": "通用",
"general_config_etc": "通用配置等",
"including_log_config": "包括日志配置",
"log_config": "日志配置",
"node_related_config": "节点相关配置",
"payment_records": "支付记录",
"recharge_code": "充值码",
"system_config": "系统配置",
"website_system_config": "网站系统配置",
"withdrawal_records": "提现记录"
},
"admin-config-payment-info": {},
"admin-config-payment": {},
"admin-config-payment-table": {
"info": "信息",
"received_amount": "到账金额",
"recharge_amount": "充值金额",
"reset": "重置",
"status": "状态",
"user": "用户"
},
"admin-config-recharge-code": {
"balance": "余额",
"batch_generate_export_recharge_code": "可以批量生成导出充值码",
"manage_recharge_code": "管理充值码",
"personal_center": "个人中心",
"recharge_code": "充值码",
"recharge_code_in": "充值码在",
"recharge_use": "充值使用"
},
"admin-config-recharge-code-table": {
"add": "添加",
"amount": "金额",
"cancel": "取消",
"confirm_delete_recharge_code": "你确认要删除这条充值码吗",
"continue": "继续",
"create_recharge_code": "创建充值码",
"export_after_creation": "创建后导出",
"pieces": "个",
"quantity": "数量",
"recharge_code": "充值码",
"reset": "重置",
"save": "保存",
"total": "共",
"usage_status": "使用状态",
"used": "已使用",
"used_by": "使用用户",
"user": "用户",
"yuan": "元"
},
"admin-config-traffic-price-config": {
"price": "价格",
"unit": "单位"
},
"admin-config-withdraw": {},
"admin-config-withdrawal-table": {
"address": "地址",
"operation_successful": "操作成功",
"reset": "重置",
"status": "状态",
"user": "用户",
"user_wallet_balance_updated": "已自动更新用户钱包收益余额",
"withdrawal_amount": "提现金额",
"withdrawal_status_updated": "提现状态已更新"
},
"admin-log": {
"logs": "日志"
},
"admin-log-log": {
"copied_to_clipboard": "已复制到剪贴板"
},
"admin-log-log-delete": {
"cancel": "取消",
"confirm_delete_all_logs": "你确认要删除所有日志吗",
"continue": "继续"
},
"admin-log-log-glance": {},
"admin-log-log-search-keyword": {
"advanced_search": "高级搜索",
"array_index_is": "数组下标为",
"array_index_with": "数组下标以",
"default_fuzzy_search": "默认模糊查询",
"field": "字段",
"for_example": "如",
"format": "格式",
"of": "的",
"query": "查询",
"search": "搜索",
"separated": "分割",
"support": "支持",
"syntax": "语法",
"with": "以",
"wrapped": "包裹"
},
"admin-log-log-toolbar": {
"add_log_display_field_config": "增加日志展示字段的配置",
"new_logs_available": "有新日志",
"reset": "重置"
},
"admin-log-logs": {},
"admin-users": {
"users": "用户"
},
"admin-users-user-role-setting": {
"modify_role": "修改角色",
"relogin_required_after_modification": "修改之后需重新登录"
},
"admin-users-user-status": {
"activate_user": "激活此用户",
"ban_user": "封禁此用户"
},
"admin-users-user-table": {
"email": "邮箱",
"filter_name": "过滤名称",
"info": "信息",
"operation": "操作",
"reset": "重置",
"role": "角色",
"status": "状态"
},
"agent": {},
"agent-[agentId]-config-base": {
"basic_info": "基础信息",
"server": "服务器"
},
"agent-[agentId]-config-other": {
"other_settings": "其它设置",
"server": "服务器"
},
"agent-[agentId]-forward": {
"forward": "转发",
"server": "服务器"
},
"agent-[agentId]-install": {
"install": "安装",
"server": "服务器"
},
"agent-[agentId]-layout": {
"server": "服务器"
},
"agent-[agentId]-loading": {},
"agent-[agentId]-log": {
"logs": "日志",
"server": "服务器"
},
"agent-[agentId]-status": {
"address": "地址",
"bandwidth": "带宽",
"info": "信息",
"last_response": "上次响应",
"memory": "内存",
"node_version": "节点版本",
"price": "价格",
"server": "服务器",
"status": "状态",
"system": "系统",
"traffic": "流量",
"unknown": "未知"
},
"agent-agent-command": {
"enter_command": "请输入命令",
"execute": "执行",
"execute_command": "执行命令",
"execution_result": "执行结果",
"failed": "失败",
"success": "成功",
"type": "类型"
},
"agent-agent-config": {
"server_basic_info_settings": "服务器基本信息设置"
},
"agent-agent-delete": {
"all_forwarding_stopped": "会停止所有的转发",
"all_related_data_deleted": "并且删除所有相关的数据",
"cancel": "取消",
"confirm_delete_server": "你确认要删除这台服务器吗",
"continue": "继续",
"operation_irreversible": "这个操作不可逆转",
"server_deleted_from_system": "将会从系统上将这台服务器删除"
},
"agent-agent-form": {
"description": "描述",
"name": "名称",
"save": "保存",
"server_description": "服务器描述",
"server_name": "服务器名称",
"share": "共享",
"share_with_other_users": "是否共享给其他用户",
"used_to_distinguish_servers": "用于区分不同服务器"
},
"agent-agent-install": {
"after_installation": "安装完成后",
"click": "可以点击",
"copy_command_below_to_install": "复制下方命令进行安装",
"copy_command_below_to_uninstall": "复制下方命令进行卸载",
"execute_in_installation_directory": "请在安装目录下执行",
"if_installation_command_leaked": "如果安装命令泄露",
"install": "安装",
"server_status_will_change": "服务器状态将会修改",
"successful_log_message": "成功将会看到一条",
"uninstall": "卸载",
"uninstall_deletes_all_configs_and_files": "卸载后会删除所有配置和安装目录下的文件",
"update": "更新",
"version": "版本",
"view_installation_progress_on_logs_page": "可以通过日志页面查看安装情况"
},
"agent-agent-list": {},
"agent-agent-list-aside": {
"add_server": "添加服务器",
"offline_servers": "掉线服务器",
"online_servers": "在线服务器",
"search_server": "搜索服务器",
"unknown_servers": "未知服务器",
"add_tips": "点击保存后查看侧边服务器栏。添加中转服务器,保存后会给你一个安装命令,复制到服务器上执行即可"
},
"agent-agent-menu": {
"basic_info": "基础信息",
"config": "配置",
"forward": "转发",
"install": "安装",
"log_config_etc": "日志等配置",
"logs": "日志",
"other_settings": "其它设置",
"port": "端口",
"price": "价格",
"remarks_etc": "备注等",
"server_name": "服务器名称",
"status": "状态"
},
"agent-agent-price": {},
"agent-agent-resizable-layout": {},
"agent-bandwidth-usage": {
"download": "下载",
"upload": "上传"
},
"agent-cpu-usage": {},
"agent-mem-usage": {},
"agent-traffic-usage": {
"download": "下载",
"upload": "上传"
},
"auth-error": {
"access_denied": "拒绝访问",
"an_error_occurred": "发生错误",
"back_to_signin": "返回登录",
"check_details_provided_are_correct": "检查您提供的详细信息是否正确",
"check_information_provided_is_correct": "请检查您提供的信息是否正确",
"check_server_logs_for_more_info": "检查服务器日志以获取更多信息",
"email_could_not_be_sent": "电子邮件无法发送",
"it_may_have_been_used_or_expired": "它可能已经被使用过或者可能已经过期",
"not_authorized_to_signin": "您没有登录权限",
"please_signin_to_access_this_page": "请登录才能访问此页面",
"server_error": "服务器错误",
"server_misconfigured": "服务器配置有问题",
"signin_link_no_longer_valid": "登录链接不再有效",
"oauth_account_not_linked": "要确认您的身份,请使用您最初使用的同一帐户登录",
"try_signing_in_with_different_account": "尝试使用其他帐户登录",
"unable_to_signin": "无法登录",
"user_disabled": "用户已禁用",
"your_account_has_been_disabled": "您的帐户已被禁用"
},
"auth-layout": {},
"auth-new": {
"create_password": "创建密码",
"signin_directly": "直接登录",
"skip_password_tips": "不设置密码,直接登录",
"create_password_tips": "为您的账户创建一个密码,以便您可以使用电子邮件地址和密码登录"
},
"auth-signin": {
"and": "和",
"by_continuing_you_agree_to_our": "继续即表示您同意我们的",
"continue": "继续",
"create_an_account": "创建一个账号",
"enter_email_signin_or_register": "输入你的邮箱来登录或者注册一个账号",
"or_use": "或者使用",
"password_signin": "密码登录",
"privacy_policy": "隐私政策",
"registration_closed": "已关闭注册",
"signin": "登录",
"terms_of_service": "服务条款",
"your_email_address": "你的邮箱地址"
},
"auth-signin-credential": {
"and": "和",
"back_to_signup": "返回注册",
"by_continuing_you_agree_to_our": "继续即表示您同意我们的",
"enter_valid_email_address": "请输入正确的邮箱地址",
"enter_your_password": "请输入你的密码",
"password_signin": "密码登录",
"privacy_policy": "隐私政策",
"signin": "登录",
"terms_of_service": "服务条款",
"your_email_address": "你的邮箱地址",
"your_password": "你的密码"
},
"auth-signout": {
"confirm": "确认",
"confirm_sign_out": "确认退出登录"
},
"auth-verify": {},
"dashboard": {
"announcement": "公告",
"balance": "余额",
"earnings": "收益",
"no_announcement": "暂无公告",
"recent_days_traffic_usage": "最近7天的流量使用情况",
"system_running_normally": "系统运行正常",
"system_status": "系统状态",
"traffic_usage": "流量使用",
"yesterday_consumption": "昨日消费",
"yesterday_earnings": "昨日收益"
},
"dashboard-system-status": {
"download": "下载",
"memory": "内存",
"network": "网络",
"upload": "上传"
},
"dashboard-traffic-usage": {
"used_traffic": "使用流量"
},
"forward": {
"forward": "Forward"
},
"forward-forward-delete": {
"all_related_data_deleted": "并且删除所有相关的数据",
"cancel": "取消",
"confirm_delete_forward_config": "你确认要删除这个转发配置吗",
"continue": "继续",
"delete_entire_network_on_networking_page": "你应该去组网页面删除整个组网",
"forwarding_stopped": "将会停止转发",
"if_forward_created_through_networking": "如果这个转发是通过组网创建的",
"operation_irreversible": "这个操作不可逆转"
},
"forward-forward-modify-remark": {
"cancel": "取消",
"enter_remark_here": "在这里输入你的备注",
"save": "保存",
"update_forward_remark": "更新转发备注"
},
"forward-forward-new": {
"can_be": "可以是",
"enter_forwarding_info": "请填写转发信息",
"forwarding_method": "转发方式",
"forwarding_target": "转发目标",
"limit_range": "限制范围",
"more_config": "更多配置",
"new_forward": "新增转发",
"no_available_servers": "暂无可用服务器",
"or_domain_name": "或者域名",
"relay_server": "中转服务器",
"remark": "备注",
"reset": "重置",
"save": "保存",
"select_forwarding_method": "请选择一种转发方式进行转发",
"select_relay_server": "请选择中转服务器",
"server": "服务器",
"server_port": "服务器端口",
"target_port": "目标端口"
},
"forward-forward-new-gost": {
"channel": "通道",
"enable_after_selection": "选择后开启",
"multiplexing": "多路复用",
"protocol": "协议",
"relay_data_channel": "中转数据通道",
"relay_data_protocol": "中转数据协议"
},
"forward-forward-reset-traffic": {
"cancel": "取消",
"confirm_reset_forward_traffic": "你确认要重置这个转发配置的流量吗",
"continue": "继续",
"operation_irreversible": "这个操作不可逆转",
"used_traffic_reset": "将会重置已使用的流量"
},
"forward-forward-table": {
"add": "添加",
"delete": "删除",
"modify_remark": "修改备注",
"remark": "备注",
"reset": "重置",
"reset_traffic": "重置流量",
"server": "服务器",
"status": "状态",
"target": "目标",
"used_traffic": "已用流量",
"user": "用户"
},
"index": {
"Dashboard": "控制台",
"Sign In": "登录",
"Welcome": "欢迎"
},
"global_theme-provider": {},
"global_monthly-traffic-usage": {
"january": "一月",
"february": "二月",
"march": "三月",
"april": "四月",
"may": "五月",
"june": "六月",
"july": "七月",
"august": "八月",
"september": "九月",
"october": "十月",
"november": "十一月",
"december": "十二月",
"upload": "上传",
"download": "下载"
},
"global_user-column": {},
"global_channel-selector": {
"select-a-channel": "选择一个通道",
"search": "搜索",
"no-data": "无数据"
},
"global_search-empty-state": {},
"global_update-password-dialog": {
"change-password": "更改密码",
"set-password": "设置密码",
"update-password": "更新密码"
},
"global_resizable-layout": {},
"global_traffic": {},
"global_code-input": {
"format": "格式化"
},
"global_update-password-form": {
"password-must-be-at-least": "密码必须至少为",
"characters-long": "个字符",
"and-contain-at-least": "并且至少包含",
"letters-and": "个字母和",
"numbers": "个数字",
"passwords-do-not-match": "密码不匹配",
"please-enter-your-old-password": "请输入原密码",
"old-password": "原密码",
"password": "密码",
"confirm-password": "确认密码",
"save": "保存"
},
"global_locale-switcher": {
"label": "选择语言",
"locale": "{locale, select, zh {🇨🇳 简体中文} en {🇺🇸 English} other {Unknown}}"
},
"global_faceted-filter": {},
"global_logo": {},
"global_id": {
"created-at": "创建于"
},
"global_menu": {
"personal-center": "个人中心",
"balance": "余额",
"logout": "退出",
"dashboard": "控制台",
"forward": "转发",
"agent": "服务器",
"network": "组网",
"ticket": "工单",
"manage": "管理",
"users": "用户",
"statistics": "统计",
"system": "系统",
"log": "日志",
"config": "配置"
},
"global_table-faceted-filter": {},
"global_loading": {},
"global_table": {
"no-data": "无数据"
},
"global_sidebar-nav": {},
"global_welcome": {},
"global_table-view-options": {},
"network": {
"networking": "组网"
},
"network-[networkId]": {
"networking": "组网"
},
"network-agent-edge": {
"random": "随机"
},
"network-agent-edge-forward-settings": {
"channel": "通道",
"default_random": "默认随机",
"enter_port_to_forward": "填写你需要转发的端口",
"forwarding_method": "转发方式",
"forwarding_method_required": "必须选择转发方式",
"forwarding_port": "转发端口",
"forwarding_port_required": "必须填写转发端口",
"listening_port": "监听端口",
"listening_port_greater_than": "监听端口必须大于",
"listening_port_less_than": "监听端口必须小于",
"port_range": "端口范围",
"relay_settings": "中转设置",
"target_port_greater_than": "目标端口必须大于",
"target_port_less_than": "目标端口必须小于"
},
"network-agent-edge-test": {
"avg_delay": "平均延迟",
"diagnose_relayed_network_connection": "诊断中转的网络连接",
"execution_result": "执行结果",
"failed": "失败",
"max_delay": "最大延迟",
"min_delay": "最小延迟",
"network_diagnostics": "网络诊断",
"packet_loss_rate": "丢包率",
"start": "开始",
"test": "测试",
"test_method": "测试方式"
},
"network-agent-edge-toolbar": {},
"network-agent-node": {},
"network-external-node": {},
"network-external-node-new": {
"address": "地址",
"address_or_domain_name": "地址或域名",
"create": "创建",
"create_external_node": "创建外部节点",
"enter_external_node": "请输入外部节点的",
"enter_external_node_name": "请输入外部节点的名称",
"enter_node_address": "请输入节点地址",
"enter_node_name": "请输入节点名称",
"enter_valid_address": "请输入正确的地址",
"name": "名称",
"support": "支持",
"used_to_identify_node": "用于标识该节点"
},
"network-network-command": {
"add_external_node": "添加外部节点",
"added": "已添加",
"operation": "操作",
"search_add_server": "搜索添加服务器"
},
"network-network-delete": {
"all_forwarding_stopped": "会停止所有的转发",
"all_related_data_deleted": "并且删除所有相关的数据",
"cancel": "取消",
"confirm_delete_network_config": "你确认要删除这条网络配置吗",
"continue": "继续",
"network_config_deleted_from_system": "将会从系统上将这条网络配置删除",
"operation_irreversible": "这个操作不可逆转"
},
"network-network-edit": {
"apply_to_network": "是否应用至网络",
"cancel": "取消",
"network_name": "组网名称",
"please_operate_with_caution": "请谨慎操作",
"save": "保存",
"save_as_new_network_config": "保存为新的组网配置",
"this_will_overwrite_current_network_config": "选择此选项将会覆盖当前网络配置",
"update_network_config": "更新组网配置"
},
"network-network-flow": {
"new_network": "新的组网"
},
"network-network-selector": {},
"network-network-table": {
"copy_entrance_address": "复制入口地址",
"create_new_network": "创建新的组网",
"creator": "创建者",
"filter_name": "过滤名称",
"name": "名称",
"node_info": "节点信息",
"nodes": "个节点",
"reset": "重置",
"traffic": "流量"
},
"ticket": {
"tickets": "工单"
},
"ticket-[ticketId]": {
"created_at": "创建时间",
"ticket": "工单"
},
"ticket-markdown-input": {
"edit": "编辑",
"preview": "预览"
},
"ticket-new": {
"create_ticket": "创建工单",
"ticket": "工单"
},
"ticket-new-ticket-form": {
"briefly_describe_problem": "请简要描述您的问题",
"characters": "字符",
"content": "内容",
"format": "格式",
"max_length": "最大长度",
"save": "保存",
"support": "支持",
"title": "标题"
},
"ticket-ticket-close": {
"cancel": "取消",
"close": "关闭",
"confirm_close_ticket": "你确认要关闭这个工单吗",
"continue": "继续"
},
"ticket-ticket-reply": {
"reply": "回复"
},
"ticket-ticket-status-badge": {},
"ticket-ticket-table": {
"create_new_ticket": "创建新的工单",
"creator": "创建者",
"reset": "重置",
"status": "状态",
"title": "标题"
},
"user-[userId]": {
"profile": "个人资料",
"relogin_required_to_take_effect": "需要重新登录后生效",
"set_name_avatar": "设置你的名称和头像"
},
"user-[userId]-account": {
"account": "账号",
"email": "邮箱",
"password": "密码",
"password_not_set": "未设置密码",
"view_update_account_info": "查看和更新你的账号信息"
},
"user-[userId]-balance": {
"available_balance": "可消费余额",
"earnings_amount": "收益金额"
},
"user-[userId]-balance-log": {
"balance": "余额",
"balance_history": "余额历史",
"change_amount": "变动金额",
"other_info": "其它信息",
"time": "时间"
},
"user-[userId]-layout": {
"account": "账户",
"balance": "余额",
"manage_account_settings_email_preferences": "管理您的帐户设置并设置电子邮件首选项",
"personal_center": "个人中心",
"profile": "个人资料",
"user_center": "用户中心"
},
"user-[userId]-profile-form": {
"avatar": "头像",
"avatar_link": "头像链接",
"name": "名称",
"name_displayed_in_profile": "显示在您的个人资料中的名称",
"save": "保存"
},
"user-[userId]-recharge-balance": {
"balance_recharge": "余额充值",
"enter_recharge_code": "请输入充值码",
"recharge": "充值",
"recharge_code": "充值码"
},
"user-[userId]-recharge-depay": {
"after_clicking_confirm": "点击确认后",
"and": "和",
"confirm": "确认",
"enter_crypto_wallet_select_payment_method": "将会进入加密钱包选择支付方式",
"invalid_amount": "无效的金额",
"minimum_recharge_amount": "充值金额最低",
"notes": "注意事项",
"recharge": "充值",
"recharge_amount": "充值金额",
"recharge_failed": "充值失败",
"recharge_handling_fee": "充值需要收取",
"recharge_successful": "充值成功",
"support": "支持",
"supported_networks": "支持的网络"
},
"user-[userId]-update-balance": {
"add_or_subtract_balance": "为用户添加或减少余额",
"amount": "金额",
"reduce_balance": "减少余额",
"remark": "备注",
"save": "保存",
"update_balance": "更新余额"
},
"user-[userId]-withdrawal-balance": {
"amount": "金额",
"current_earnings_balance": "当前收益余额",
"deduct_handling_fee": "需要扣除部分手续费",
"minimum_withdrawal_amount": "最低提现金额为",
"please_provide": "请提供",
"receiving_address": "收款地址",
"request_withdrawal": "申请提现",
"request_withdrawal_to_specified_address": "申请提现到指定的地址",
"subject_to_actual_received_amount": "以实际到账金额为准",
"withdrawal": "提现"
}
}

View File

@ -2,8 +2,12 @@
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
* for Docker builds.
*/
import createNextIntlPlugin from "next-intl/plugin";
await import("./src/env.js");
const withNextIntl = createNextIntlPlugin();
/** @type {import("next").NextConfig} */
const config = {
experimental: {
@ -30,4 +34,4 @@ const config = {
},
};
export default config;
export default withNextIntl(config);

155
package-lock.json generated
View File

@ -57,6 +57,7 @@
"lucide-react": "^0.316.0",
"next": "^14.1.0",
"next-auth": "^4.24.5",
"next-intl": "^3.9.5",
"next-themes": "^0.2.1",
"nodemailer": "^6.9.9",
"pino": "^8.17.2",
@ -3371,6 +3372,92 @@
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz",
"integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A=="
},
"node_modules/@formatjs/ecma402-abstract": {
"version": "1.18.2",
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.2.tgz",
"integrity": "sha512-+QoPW4csYALsQIl8GbN14igZzDbuwzcpWrku9nyMXlaqAlwRBgl5V+p0vWMGFqHOw37czNXaP/lEk4wbLgcmtA==",
"dependencies": {
"@formatjs/intl-localematcher": "0.5.4",
"tslib": "^2.4.0"
}
},
"node_modules/@formatjs/ecma402-abstract/node_modules/@formatjs/intl-localematcher": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz",
"integrity": "sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==",
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@formatjs/fast-memoize": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz",
"integrity": "sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/@formatjs/icu-messageformat-parser": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.0.tgz",
"integrity": "sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==",
"dependencies": {
"@formatjs/ecma402-abstract": "1.11.4",
"@formatjs/icu-skeleton-parser": "1.3.6",
"tslib": "^2.1.0"
}
},
"node_modules/@formatjs/icu-messageformat-parser/node_modules/@formatjs/ecma402-abstract": {
"version": "1.11.4",
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz",
"integrity": "sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==",
"dependencies": {
"@formatjs/intl-localematcher": "0.2.25",
"tslib": "^2.1.0"
}
},
"node_modules/@formatjs/icu-messageformat-parser/node_modules/@formatjs/intl-localematcher": {
"version": "0.2.25",
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz",
"integrity": "sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/@formatjs/icu-skeleton-parser": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.6.tgz",
"integrity": "sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==",
"dependencies": {
"@formatjs/ecma402-abstract": "1.11.4",
"tslib": "^2.1.0"
}
},
"node_modules/@formatjs/icu-skeleton-parser/node_modules/@formatjs/ecma402-abstract": {
"version": "1.11.4",
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz",
"integrity": "sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==",
"dependencies": {
"@formatjs/intl-localematcher": "0.2.25",
"tslib": "^2.1.0"
}
},
"node_modules/@formatjs/icu-skeleton-parser/node_modules/@formatjs/intl-localematcher": {
"version": "0.2.25",
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz",
"integrity": "sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/@formatjs/intl-localematcher": {
"version": "0.2.32",
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.32.tgz",
"integrity": "sha512-k/MEBstff4sttohyEpXxCmC3MqbUn9VvHGlZ8fauLzkbwXmVrEeyzS+4uhrvAk9DWU9/7otYWxyDox4nT/KVLQ==",
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@hookform/resolvers": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.4.tgz",
@ -11251,6 +11338,34 @@
"node": ">=12"
}
},
"node_modules/intl-messageformat": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.13.0.tgz",
"integrity": "sha512-7sGC7QnSQGa5LZP7bXLDhVDtQOeKGeBFGHF2Y8LVBwYZoQZCgWeKoPGTa5GMG8g/TzDgeXuYJQis7Ggiw2xTOw==",
"dependencies": {
"@formatjs/ecma402-abstract": "1.11.4",
"@formatjs/fast-memoize": "1.2.1",
"@formatjs/icu-messageformat-parser": "2.1.0",
"tslib": "^2.1.0"
}
},
"node_modules/intl-messageformat/node_modules/@formatjs/ecma402-abstract": {
"version": "1.11.4",
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz",
"integrity": "sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==",
"dependencies": {
"@formatjs/intl-localematcher": "0.2.25",
"tslib": "^2.1.0"
}
},
"node_modules/intl-messageformat/node_modules/@formatjs/intl-localematcher": {
"version": "0.2.25",
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz",
"integrity": "sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@ -14127,6 +14242,14 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/next": {
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/next/-/next-14.1.0.tgz",
@ -14199,6 +14322,26 @@
}
}
},
"node_modules/next-intl": {
"version": "3.9.5",
"resolved": "https://registry.npmjs.org/next-intl/-/next-intl-3.9.5.tgz",
"integrity": "sha512-tsp4N433WgTAbbyZdMlcsLGHFM88wv2a7ZpF/od8X9+qAlO1TrajZrNrGBpIg6nA9EGZyMbQPzZD7XZrqYIv7g==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/amannn"
}
],
"dependencies": {
"@formatjs/intl-localematcher": "^0.2.32",
"negotiator": "^0.6.3",
"use-intl": "^3.9.5"
},
"peerDependencies": {
"next": "^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/next-themes": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz",
@ -17643,6 +17786,18 @@
}
}
},
"node_modules/use-intl": {
"version": "3.9.5",
"resolved": "https://registry.npmjs.org/use-intl/-/use-intl-3.9.5.tgz",
"integrity": "sha512-1g+f/pKEeXqOXrd+QBvwnIN5kzM56PHsorbVWzNvlnGk2fo/eRwuuT/S0jTuzKLRW4uNybpHvRs6U06rP31iKw==",
"dependencies": {
"@formatjs/ecma402-abstract": "^1.11.4",
"intl-messageformat": "^9.3.18"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/use-sidecar": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz",

View File

@ -71,6 +71,7 @@
"lucide-react": "^0.316.0",
"next": "^14.1.0",
"next-auth": "^4.24.5",
"next-intl": "^3.9.5",
"next-themes": "^0.2.1",
"nodemailer": "^6.9.9",
"pino": "^8.17.2",

View File

@ -1,5 +0,0 @@
import PaymentTable from "~/app/(manage)/admin/config/_components/payment-table";
export default function PaymentPage() {
return <PaymentTable />;
}

View File

@ -1,5 +0,0 @@
import WithdrawalTable from "~/app/(manage)/admin/config/_components/withdrawal-table";
export default function WithdrawalPage() {
return <WithdrawalTable />;
}

View File

@ -1,14 +0,0 @@
import ForwardTable from "~/app/(manage)/forward/_components/forward-table";
export const metadata = {
title: "转发 - vortex",
};
export default function Forward() {
return (
<div className="p-4">
<h1 className="mb-4 text-3xl"></h1>
<ForwardTable />
</div>
);
}

View File

@ -1,21 +0,0 @@
import "reactflow/dist/style.css";
import NetworkTable from "~/app/(manage)/network/_components/network-table";
export const metadata = {
title: "组网 - vortex",
};
export default async function NetworksPage({
searchParams: { keyword },
}: {
searchParams: { keyword: string };
}) {
return (
<div className="h-full p-4">
<div className="flex gap-4">
<h1 className="mb-4 text-3xl">Network</h1>
</div>
<NetworkTable keyword={keyword} />
</div>
);
}

View File

@ -1,20 +0,0 @@
import TicketTable from "~/app/(manage)/ticket/_components/ticket-table";
export const metadata = {
title: "工单 - vortex",
};
export default function TicketsPage({
searchParams: { keyword },
}: {
searchParams: { keyword: string };
}) {
return (
<div className="h-full p-4">
<div className="flex gap-4">
<h1 className="mb-4 text-3xl"></h1>
</div>
<TicketTable keyword={keyword} />
</div>
);
}

View File

@ -1,5 +1,5 @@
import { api } from "~/trpc/server";
import ConfigList from "~/app/(manage)/admin/config/_components/config-list";
import ConfigList from "~/app/[local]/(manage)/admin/config/_components/config-list";
import { GLOBAL_CONFIG_SCHEMA_MAP } from "~/lib/constants/config";
import { type CONFIG_KEY } from "~/lib/types";

View File

@ -5,7 +5,7 @@ import {
DialogTitle,
DialogTrigger,
} from "~/lib/ui/dialog";
import CodeInput from "~/app/_components/code-input";
import CodeInput from "~/app/[local]/_components/code-input";
import { useState } from "react";
import { Tabs, TabsList, TabsTrigger } from "~/lib/ui/tabs";
import Markdown from "react-markdown";

View File

@ -18,7 +18,7 @@ import {
} from "~/lib/ui/select";
import { Switch } from "~/lib/ui/switch";
import { CONFIG_DEFAULT_VALUE_MAP } from "~/lib/constants/config";
import CodeInputDialog from "~/app/(manage)/admin/config/_components/code-input-dialog";
import CodeInputDialog from "~/app/[local]/(manage)/admin/config/_components/code-input-dialog";
import { isTrue } from "~/lib/utils";
import { useTrack } from "~/lib/hooks/use-track";

View File

@ -1,5 +1,5 @@
import { type Config } from "@prisma/client";
import ConfigField from "~/app/(manage)/admin/config/_components/config-field";
import ConfigField from "~/app/[local]/(manage)/admin/config/_components/config-field";
import { type CONFIG_KEY, type ConfigSchema } from "~/lib/types";
export default function ConfigList({

View File

@ -2,7 +2,7 @@ import Blockchains from "@depay/web3-blockchains";
import * as React from "react";
import { Label } from "~/lib/ui/label";
import Link from "next/link";
import ID from "~/app/_components/id";
import ID from "~/app/[local]/_components/id";
import Image from "next/image";
import { Badge } from "~/lib/ui/badge";
import { formatDate } from "~/lib/utils";

View File

@ -11,15 +11,15 @@ import {
} from "@tanstack/react-table";
import { api } from "~/trpc/react";
import { Input } from "~/lib/ui/input";
import Table from "~/app/_components/table";
import Table from "~/app/[local]/_components/table";
import { type PaymentGetAllOutput } from "~/lib/types/trpc";
import { Button } from "~/lib/ui/button";
import { MoreHorizontalIcon, XIcon } from "lucide-react";
import { DataTableViewOptions } from "~/app/_components/table-view-options";
import ID from "~/app/_components/id";
import UserColumn from "~/app/_components/user-column";
import { DataTableViewOptions } from "~/app/[local]/_components/table-view-options";
import ID from "~/app/[local]/_components/id";
import UserColumn from "~/app/[local]/_components/user-column";
import { MoneyInput } from "~/lib/ui/money-input";
import { TableFacetedFilter } from "~/app/_components/table-faceted-filter";
import { TableFacetedFilter } from "~/app/[local]/_components/table-faceted-filter";
import { PaymentStatusOptions } from "~/lib/constants";
import { type $Enums } from ".prisma/client";
import { cn, formatDate } from "~/lib/utils";
@ -37,7 +37,7 @@ import {
AccordionItem,
AccordionTrigger,
} from "~/lib/ui/accordion";
import PaymentInfo from "~/app/(manage)/admin/config/_components/payment-info";
import PaymentInfo from "~/app/[local]/(manage)/admin/config/_components/payment-info";
type PaymentStatus = $Enums.PaymentStatus;

View File

@ -9,13 +9,13 @@ import {
} from "@tanstack/react-table";
import { api } from "~/trpc/react";
import { Input } from "~/lib/ui/input";
import Table from "~/app/_components/table";
import Table from "~/app/[local]/_components/table";
import { type RechargeCodeGetAllOutput } from "~/lib/types/trpc";
import { Button } from "~/lib/ui/button";
import { TicketCheckIcon, TicketIcon, Trash2Icon, XIcon } from "lucide-react";
import { DataTableViewOptions } from "~/app/_components/table-view-options";
import ID from "~/app/_components/id";
import UserColumn from "~/app/_components/user-column";
import { DataTableViewOptions } from "~/app/[local]/_components/table-view-options";
import ID from "~/app/[local]/_components/id";
import UserColumn from "~/app/[local]/_components/user-column";
import {
AlertDialog,
AlertDialogAction,

View File

@ -11,15 +11,15 @@ import {
} from "@tanstack/react-table";
import { api } from "~/trpc/react";
import { Input } from "~/lib/ui/input";
import Table from "~/app/_components/table";
import Table from "~/app/[local]/_components/table";
import { type WithdrawalGetAllOutput } from "~/lib/types/trpc";
import { Button } from "~/lib/ui/button";
import { CheckSquareIcon, XIcon } from "lucide-react";
import { DataTableViewOptions } from "~/app/_components/table-view-options";
import ID from "~/app/_components/id";
import UserColumn from "~/app/_components/user-column";
import { DataTableViewOptions } from "~/app/[local]/_components/table-view-options";
import ID from "~/app/[local]/_components/id";
import UserColumn from "~/app/[local]/_components/user-column";
import { MoneyInput } from "~/lib/ui/money-input";
import { TableFacetedFilter } from "~/app/_components/table-faceted-filter";
import { TableFacetedFilter } from "~/app/[local]/_components/table-faceted-filter";
import { WithdrawalStatusOptions } from "~/lib/constants";
import { Badge } from "~/lib/ui/badge";
import { toast } from "~/lib/ui/use-toast";

View File

@ -1,6 +1,6 @@
import { Separator } from "~/lib/ui/separator";
import { type ReactNode } from "react";
import { SidebarNav } from "~/app/_components/sidebar-nav";
import { SidebarNav } from "~/app/[local]/_components/sidebar-nav";
import type { Metadata } from "next";
export const metadata: Metadata = {

View File

@ -1,5 +1,5 @@
import { api } from "~/trpc/server";
import ConfigList from "~/app/(manage)/admin/config/_components/config-list";
import ConfigList from "~/app/[local]/(manage)/admin/config/_components/config-list";
import { GLOBAL_CONFIG_SCHEMA_MAP } from "~/lib/constants/config";
export default async function Config() {

View File

@ -0,0 +1,5 @@
import PaymentTable from "~/app/[local]/(manage)/admin/config/_components/payment-table";
export default function PaymentPage() {
return <PaymentTable />;
}

View File

@ -1,4 +1,4 @@
import RechargeCodeTable from "~/app/(manage)/admin/config/_components/recharge-code-table";
import RechargeCodeTable from "~/app/[local]/(manage)/admin/config/_components/recharge-code-table";
import { Separator } from "~/lib/ui/separator";
import Link from "next/link";
import { MoveRightIcon } from "lucide-react";

View File

@ -0,0 +1,5 @@
import WithdrawalTable from "~/app/[local]/(manage)/admin/config/_components/withdrawal-table";
export default function WithdrawalPage() {
return <WithdrawalTable />;
}

View File

@ -14,7 +14,7 @@ import { Button } from "~/lib/ui/button";
import { Trash2Icon } from "lucide-react";
import React from "react";
import { toast } from "~/lib/ui/use-toast";
import { useLogStore } from "~/app/(manage)/admin/log/store/log-store";
import { useLogStore } from "~/app/[local]/(manage)/admin/log/store/log-store";
import { useTrack } from "~/lib/hooks/use-track";
export default function LogDelete() {

View File

@ -7,7 +7,7 @@ import {
import { BarChartHorizontalIcon } from "lucide-react";
import React from "react";
import { cn } from "~/lib/utils";
import { useLogStore } from "~/app/(manage)/admin/log/store/log-store";
import { useLogStore } from "~/app/[local]/(manage)/admin/log/store/log-store";
import { api } from "~/trpc/react";
export default function LogGlance() {

View File

@ -1,4 +1,4 @@
import { useLogStore } from "~/app/(manage)/admin/log/store/log-store";
import { useLogStore } from "~/app/[local]/(manage)/admin/log/store/log-store";
import { Popover, PopoverContent, PopoverTrigger } from "~/lib/ui/popover";
import { Input } from "~/lib/ui/input";
import React, { useEffect } from "react";

View File

@ -6,10 +6,10 @@ import { Popover, PopoverContent, PopoverTrigger } from "~/lib/ui/popover";
import { Label } from "~/lib/ui/label";
import React from "react";
import { LEVELS } from "~/lib/constants/log-level";
import { useLogStore } from "~/app/(manage)/admin/log/store/log-store";
import LogDelete from "~/app/(manage)/admin/log/_components/log-delete";
import { FacetedFilter } from "~/app/_components/faceted-filter";
import LogSearchKeyword from "~/app/(manage)/admin/log/_components/log-search-keyword";
import { useLogStore } from "~/app/[local]/(manage)/admin/log/store/log-store";
import LogDelete from "~/app/[local]/(manage)/admin/log/_components/log-delete";
import { FacetedFilter } from "~/app/[local]/_components/faceted-filter";
import LogSearchKeyword from "~/app/[local]/(manage)/admin/log/_components/log-search-keyword";
export default function LogToolbar() {
const { params, setParams, resetParams, isFiltering } = useLogStore();

View File

@ -3,12 +3,12 @@ import React, { useEffect } from "react";
import { ScrollArea } from "~/lib/ui/scroll-area";
import { Accordion } from "~/lib/ui/accordion";
import { api } from "~/trpc/react";
import { useLogStore } from "~/app/(manage)/admin/log/store/log-store";
import LogGlance from "~/app/(manage)/admin/log/_components/log-glance";
import Log from "~/app/(manage)/admin/log/_components/log";
import LogToolbar from "~/app/(manage)/admin/log/_components/log-toolbar";
import { useLogStore } from "~/app/[local]/(manage)/admin/log/store/log-store";
import LogGlance from "~/app/[local]/(manage)/admin/log/_components/log-glance";
import Log from "~/app/[local]/(manage)/admin/log/_components/log";
import LogToolbar from "~/app/[local]/(manage)/admin/log/_components/log-toolbar";
import type { LogsOutput } from "~/lib/types/trpc";
import SearchEmptyState from "~/app/_components/search-empty-state";
import SearchEmptyState from "~/app/[local]/_components/search-empty-state";
export function Logs({ agentId }: { agentId?: string }) {
const { convertParams, setParams, params } = useLogStore();

View File

@ -1,4 +1,4 @@
import { Logs } from "~/app/(manage)/admin/log/_components/logs";
import { Logs } from "~/app/[local]/(manage)/admin/log/_components/logs";
export const metadata = {
title: "日志 - vortex",

View File

@ -7,12 +7,12 @@ import {
} from "@tanstack/react-table";
import { Input } from "~/lib/ui/input";
import { type ChangeEvent, useMemo, useState } from "react";
import Table from "~/app/_components/table";
import Table from "~/app/[local]/_components/table";
import { api } from "~/trpc/react";
import { type UserGetAllOutput } from "~/lib/types/trpc";
import ID from "~/app/_components/id";
import UserColumn from "~/app/_components/user-column";
import UserStatusSwitch from "~/app/(manage)/admin/users/_components/user-status";
import ID from "~/app/[local]/_components/id";
import UserColumn from "~/app/[local]/_components/user-column";
import UserStatusSwitch from "~/app/[local]/(manage)/admin/users/_components/user-status";
import { TooltipProvider } from "~/lib/ui/tooltip";
import { Badge } from "~/lib/ui/badge";
import {
@ -22,8 +22,8 @@ import {
} from "~/lib/ui/dropdown-menu";
import { Button } from "~/lib/ui/button";
import { MoreHorizontalIcon, XIcon } from "lucide-react";
import UserRoleSettings from "~/app/(manage)/admin/users/_components/user-role-setting";
import { DataTableViewOptions } from "~/app/_components/table-view-options";
import UserRoleSettings from "~/app/[local]/(manage)/admin/users/_components/user-role-setting";
import { DataTableViewOptions } from "~/app/[local]/_components/table-view-options";
export default function UserTable() {
const [keyword, setKeyword] = useState("");

View File

@ -1,4 +1,4 @@
import UserTable from "~/app/(manage)/admin/users/_components/user-table";
import UserTable from "~/app/[local]/(manage)/admin/users/_components/user-table";
export const metadata = {
title: "用户 - vortex",

View File

@ -1,4 +1,4 @@
import { AgentForm } from "~/app/(manage)/agent/_components/agent-form";
import { AgentForm } from "~/app/[local]/(manage)/agent/_components/agent-form";
import { api } from "~/trpc/server";
export const metadata = {

View File

@ -1,4 +1,4 @@
import ConfigList from "~/app/(manage)/admin/config/_components/config-list";
import ConfigList from "~/app/[local]/(manage)/admin/config/_components/config-list";
import { AGENT_CONFIG_SCHEMA_MAP } from "~/lib/constants/config";
import { api } from "~/trpc/server";

View File

@ -1,4 +1,4 @@
import ForwardTable from "~/app/(manage)/forward/_components/forward-table";
import ForwardTable from "~/app/[local]/(manage)/forward/_components/forward-table";
export const metadata = {
title: "服务器 - 转发 - vortex",

View File

@ -1,4 +1,4 @@
import AgentInstall from "~/app/(manage)/agent/_components/agent-install";
import AgentInstall from "~/app/[local]/(manage)/agent/_components/agent-install";
export const metadata = {
title: "服务器 - 安装 - vortex",

View File

@ -1,7 +1,7 @@
import { api } from "~/trpc/server";
import AgentResizableLayout from "~/app/(manage)/agent/_components/agent-resizable-layout";
import AgentResizableLayout from "~/app/[local]/(manage)/agent/_components/agent-resizable-layout";
import { type ReactNode } from "react";
import AgentMenu from "~/app/(manage)/agent/_components/agent-menu";
import AgentMenu from "~/app/[local]/(manage)/agent/_components/agent-menu";
export const metadata = {
title: "服务器 - vortex",

View File

@ -1,4 +1,4 @@
import { Logs } from "~/app/(manage)/admin/log/_components/logs";
import { Logs } from "~/app/[local]/(manage)/admin/log/_components/logs";
export const metadata = {
title: "服务器 - 日志 - vortex",

View File

@ -1,22 +1,22 @@
import { getPlatformIcon } from "~/lib/icons";
import CpuUsage, {
type CpuStat,
} from "~/app/(manage)/agent/_components/cpu-usage";
} from "~/app/[local]/(manage)/agent/_components/cpu-usage";
import MemUsage, {
type MemStat,
} from "~/app/(manage)/agent/_components/mem-usage";
} from "~/app/[local]/(manage)/agent/_components/mem-usage";
import BandwidthUsage, {
type BandwidthStat,
} from "~/app/(manage)/agent/_components/bandwidth-usage";
} from "~/app/[local]/(manage)/agent/_components/bandwidth-usage";
import TrafficUsage, {
type TrafficStat,
} from "~/app/(manage)/agent/_components/traffic-usage";
} from "~/app/[local]/(manage)/agent/_components/traffic-usage";
import { convertBytes, convertBytesToBestUnit, formatDate } from "~/lib/utils";
import "/node_modules/flag-icons/css/flag-icons.min.css";
import ID from "~/app/_components/id";
import ID from "~/app/[local]/_components/id";
import { MoveDownIcon, MoveUpIcon } from "lucide-react";
import { api } from "~/trpc/server";
import AgentPrice from "~/app/(manage)/agent/_components/agent-price";
import AgentPrice from "~/app/[local]/(manage)/agent/_components/agent-price";
export const metadata = {
title: "服务器 - 状态 - vortex",

View File

@ -1,4 +1,4 @@
import ConfigList from "~/app/(manage)/admin/config/_components/config-list";
import ConfigList from "~/app/[local]/(manage)/admin/config/_components/config-list";
import { AGENT_CONFIG_SCHEMA_MAP } from "~/lib/constants/config";
import { api } from "~/trpc/server";

View File

@ -1,7 +1,7 @@
"use client";
import { ScrollArea } from "~/lib/ui/scroll-area";
import AgentList from "~/app/(manage)/agent/_components/agent-list";
import { AgentForm } from "~/app/(manage)/agent/_components/agent-form";
import AgentList from "~/app/[local]/(manage)/agent/_components/agent-list";
import { AgentForm } from "~/app/[local]/(manage)/agent/_components/agent-form";
import { Button } from "~/lib/ui/button";
import { PlusIcon } from "lucide-react";
import { type AgentGetAllOutput } from "~/lib/types/trpc";
@ -9,7 +9,7 @@ import { api } from "~/trpc/react";
import { cn } from "~/lib/utils";
import { hasPermission } from "~/lib/constants/permission";
import { useSession } from "next-auth/react";
import { CSSProperties, useMemo, useState } from "react";
import { type CSSProperties, useMemo, useState } from "react";
import {
Dialog,
DialogContent,
@ -19,6 +19,7 @@ import {
DialogTrigger,
} from "~/lib/ui/dialog";
import { Input } from "~/lib/ui/input";
import { useTranslations } from "use-intl";
export default function AgentListAside({
agentId,
@ -31,6 +32,7 @@ export default function AgentListAside({
className?: string;
style?: CSSProperties;
}) {
const t = useTranslations("agent-agent-list-aside");
const [keyword, setKeyword] = useState("");
agents =
api.agent.getAll.useQuery(undefined, {
@ -52,23 +54,23 @@ export default function AgentListAside({
<div className="fixed h-full" style={style}>
<Input
className="mx-auto mt-4 w-[90%]"
placeholder="搜索服务器"
placeholder={t("search_server")}
value={keyword}
onChange={(e) => setKeyword(e.target.value)}
/>
<ScrollArea className={cn("h-full w-full px-4 pb-12", className)}>
<AgentList
title="在线服务器"
title={t("online_servers")}
agents={agents.ONLINE}
agentId={agentId}
/>
<AgentList
title="掉线服务器"
title={t("offline_servers")}
agents={agents.OFFLINE}
agentId={agentId}
/>
<AgentList
title="未知服务器"
title={t("unknown_servers")}
agents={agents.UNKNOWN}
agentId={agentId}
/>
@ -79,15 +81,13 @@ export default function AgentListAside({
<DialogTrigger asChild>
<Button className="w-full">
<PlusIcon className="mr-2 h-4 w-4" />
{t("add_server")}
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription>
</DialogDescription>
<DialogTitle>{t("add_server")}</DialogTitle>
<DialogDescription>{t("add_tips")}</DialogDescription>
</DialogHeader>
<AgentForm />
</DialogContent>

View File

@ -12,8 +12,8 @@ import { usePathname } from "next/navigation";
import * as React from "react";
import { cn } from "~/lib/utils";
import { useSession } from "next-auth/react";
import AgentCommand from "~/app/(manage)/agent/_components/agent-command";
import AgentDelete from "~/app/(manage)/agent/_components/agent-delete";
import AgentCommand from "~/app/[local]/(manage)/agent/_components/agent-command";
import AgentDelete from "~/app/[local]/(manage)/agent/_components/agent-delete";
import { type Agent } from ".prisma/client";
import { Role } from "@prisma/client";

View File

@ -4,7 +4,7 @@ import {
ResizablePanel,
ResizablePanelGroup,
} from "~/lib/ui/resizable";
import AgentListAside from "~/app/(manage)/agent/_components/agent-list-aside";
import AgentListAside from "~/app/[local]/(manage)/agent/_components/agent-list-aside";
import { type AgentGetAllOutput } from "~/lib/types/trpc";
import { type ReactNode, useRef } from "react";
import { useResizeObserver } from "~/lib/hooks/use-resize-observer";

View File

@ -1,7 +1,20 @@
import AgentResizableLayout from "~/app/(manage)/agent/_components/agent-resizable-layout";
import AgentResizableLayout from "~/app/[local]/(manage)/agent/_components/agent-resizable-layout";
import { api } from "~/trpc/server";
import { redirect, RedirectType } from "next/navigation";
import { AgentStatus } from "@prisma/client";
import { getTranslations } from "next-intl/server";
export async function generateMetadata({
params: { locale },
}: {
params: { locale: string };
}) {
const t = await getTranslations({ locale, namespace: "global_menu" });
return {
title: `${t("agent")} - vortex`,
};
}
export default async function AgentPage() {
const agents = await api.agent.getAll.query(undefined);

View File

@ -7,8 +7,10 @@ import { Line, LineChart, ResponsiveContainer, Tooltip } from "recharts";
import { useEffect, useState } from "react";
import { MoveDownIcon, MoveUpIcon } from "lucide-react";
import type { TooltipProps } from "recharts/types/component/Tooltip";
import { useTranslations } from "use-intl";
export default function SystemStatus() {
const t = useTranslations("dashboard-system-status");
const [networks, setNetworks] = useState<
{
upload: number;
@ -57,8 +59,8 @@ export default function SystemStatus() {
<div className="rounded-md bg-white p-4 shadow-md dark:bg-accent">
<div className="grid grid-cols-2 gap-4">
<div className="flex flex-col space-y-2">
<span className="text-sm"></span>
<span className="text-sm"></span>
<span className="text-sm">{t("download")}</span>
<span className="text-sm">{t("upload")}</span>
</div>
<div className="flex flex-col space-y-2">
<span className="text-sm">{`${download} ${downloadUnit}`}</span>
@ -84,7 +86,7 @@ export default function SystemStatus() {
</div>
</div>
<div className="flex flex-col space-y-2">
<Label className="block"></Label>
<Label className="block">{t("memory")}</Label>
<div className="flex items-center space-x-2">
<Progress value={data?.mem} />
<span className="text-sm">{data?.mem.toFixed(2)}%</span>
@ -93,7 +95,7 @@ export default function SystemStatus() {
</div>
<div className="flex flex-1 flex-col items-center gap-1">
<div className="relative flex w-full items-center justify-center gap-1">
<Label className="absolute left-0"></Label>
<Label className="absolute left-0">{t("network")}</Label>
<div className="before:content flex items-center before:h-2 before:w-2 before:bg-[#fef08a]">
<MoveDownIcon className="h-3 w-3" />
<span className="text-sm">

View File

@ -5,8 +5,10 @@ import { convertBytesToBestUnit } from "~/lib/utils";
import { api } from "~/trpc/react";
import dayjs from "dayjs";
import { useMemo } from "react";
import { useTranslations } from "use-intl";
export default function UserTrafficUsage() {
const t = useTranslations("dashboard-traffic-usage");
const startDate = dayjs().subtract(7, "day").startOf("day").toDate();
const endDate = dayjs().endOf("day").toDate();
@ -36,7 +38,7 @@ export default function UserTrafficUsage() {
<p className="mb-2">{`${payload[0]?.payload.date}`}</p>
<div className="grid grid-cols-2 gap-4">
<div className="flex flex-col space-y-2">
<span className="text-sm">使</span>
<span className="text-sm">{t("used_traffic")}</span>
</div>
<div className="flex flex-col space-y-2">
<span className="text-sm">{`${traffic} ${trafficUnit}`}</span>

View File

@ -9,14 +9,16 @@ import {
CardTitle,
} from "~/lib/ui/card";
import Link from "next/link";
import UserTrafficUsage from "~/app/(manage)/dashboard/_components/traffic-usage";
import SystemStatus from "~/app/(manage)/dashboard/_components/system-status";
import UserTrafficUsage from "~/app/[local]/(manage)/dashboard/_components/traffic-usage";
import SystemStatus from "~/app/[local]/(manage)/dashboard/_components/system-status";
import { api } from "~/trpc/server";
import { MoneyInput } from "~/lib/ui/money-input";
import { MoreHorizontalIcon } from "lucide-react";
import Markdown from "react-markdown";
import { Dialog, DialogContent, DialogTrigger } from "~/lib/ui/dialog";
import { type RouterOutputs } from "~/trpc/shared";
import { getTranslations } from "next-intl/server";
import { type NamespaceKeys } from "use-intl/core";
export const metadata = {
title: "Dashboard - vortex",
@ -27,6 +29,7 @@ export default async function Dashboard() {
if (!session) {
return null;
}
const t = await getTranslations("dashboard");
const wallet = await api.user.getWallet.query({ id: session.user.id });
const yesterdayBalanceChange = await api.user.getYesterdayBalanceChange.query(
{ id: session.user.id },
@ -55,8 +58,10 @@ export default async function Dashboard() {
<div className="col-span-2 flex flex-col">
<Card className="h-[300px] lg:h-3/5">
<CardHeader>
<CardTitle>使</CardTitle>
<CardDescription>7使</CardDescription>
<CardTitle>{t("traffic_usage")}</CardTitle>
<CardDescription>
{t("recent_days_traffic_usage")}
</CardDescription>
</CardHeader>
<CardContent className="relative h-full w-full">
<UserTrafficUsage />
@ -71,8 +76,8 @@ export default async function Dashboard() {
</Card>
<Card className="mt-4 flex-grow">
<CardHeader>
<CardTitle></CardTitle>
<CardDescription></CardDescription>
<CardTitle>{t("system_status")}</CardTitle>
<CardDescription>{t("system_running_normally")}</CardDescription>
</CardHeader>
<CardContent className="flex">
<Image
@ -92,11 +97,12 @@ export default async function Dashboard() {
wallet={wallet}
yesterdayBalanceChange={yesterdayBalanceChange}
userId={session.user.id}
t={t}
/>
</Card>
<Card className="mt-4 flex-grow overflow-hidden">
<CardHeader className="flex flex-row items-center justify-between">
<CardTitle></CardTitle>
<CardTitle>{t("announcement")}</CardTitle>
{announcement && (
<AnnouncementDialog announcement={announcement} />
)}
@ -107,7 +113,7 @@ export default async function Dashboard() {
{announcement}
</Markdown>
) : (
<p></p>
<p>{t("no_announcement")}</p>
)}
</CardContent>
</Card>
@ -121,17 +127,21 @@ function UserBalance({
userId,
wallet,
yesterdayBalanceChange,
t,
}: {
userId: string;
wallet: RouterOutputs["user"]["getWallet"];
yesterdayBalanceChange: RouterOutputs["user"]["getYesterdayBalanceChange"];
t: Awaited<
ReturnType<typeof getTranslations<NamespaceKeys<IntlMessages, "dashboard">>>
>;
}) {
return (
<>
<div className="flex flex-col border-b px-6 py-3">
<div className="flex justify-between">
<h3 className="text-2xl font-semibold leading-none tracking-tight">
{t("balance")}
</h3>
<Link href={`/user/${userId}/balance`}>
<MoreHorizontalIcon className="h-6 w-6 cursor-pointer hover:bg-muted" />
@ -144,7 +154,9 @@ function UserBalance({
className="bg-gradient-to-r from-blue-500 to-green-500 bg-clip-text text-5xl text-transparent"
/>
<div className="flex items-center space-x-2">
<span className="text-muted-foreground"></span>
<span className="text-muted-foreground">
{t("yesterday_consumption")}
</span>
<span className="text-2xl">
{yesterdayBalanceChange?.CONSUMPTION?.toNumber() ?? 0}
</span>
@ -153,7 +165,7 @@ function UserBalance({
</div>
<div className="flex flex-col px-6 py-3">
<h3 className="text-2xl font-semibold leading-none tracking-tight">
{t("earnings")}
</h3>
<div className="flex h-full items-center space-x-6">
<MoneyInput
@ -162,7 +174,9 @@ function UserBalance({
className="bg-gradient-to-r from-blue-500 to-pink-500 bg-clip-text text-5xl text-transparent"
/>
<div className=" flex items-center space-x-2">
<span className="text-muted-foreground"></span>
<span className="text-muted-foreground">
{t("yesterday_earnings")}
</span>
<span className="text-2xl">
{yesterdayBalanceChange?.INCOME?.toNumber() ?? 0}
</span>

View File

@ -13,9 +13,9 @@ import {
SelectTrigger,
SelectValue,
} from "~/lib/ui/select";
import { type ForwardForm } from "~/app/(manage)/forward/_components/forward-new-form-schema";
import { type ForwardForm } from "~/app/[local]/(manage)/forward/_components/forward-new-form-schema";
import { GostChannelOptions, GostProtocolOptions } from "~/lib/constants";
import { WithDescSelector } from "~/app/_components/with-desc-selector";
import { WithDescSelector } from "~/app/[local]/_components/with-desc-selector";
export default function ForwardNewGost({ form }: { form: ForwardForm }) {
return (

View File

@ -29,7 +29,7 @@ import { cn } from "~/lib/utils";
import {
forwardFormSchema,
type ForwardFormValues,
} from "~/app/(manage)/forward/_components/forward-new-form-schema";
} from "~/app/[local]/(manage)/forward/_components/forward-new-form-schema";
import {
Dialog,
DialogContent,

View File

@ -10,8 +10,8 @@ import {
} from "@tanstack/react-table";
import { api } from "~/trpc/react";
import { Input } from "~/lib/ui/input";
import Table from "~/app/_components/table";
import { TableFacetedFilter } from "~/app/_components/table-faceted-filter";
import Table from "~/app/[local]/_components/table";
import { TableFacetedFilter } from "~/app/[local]/_components/table-faceted-filter";
import { ForwardStatusOptions } from "~/lib/constants";
import { type ForwardGetAllOutput } from "~/lib/types/trpc";
import { type AgentInfo } from "~/lib/types/agent";
@ -21,7 +21,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "~/lib/ui/tooltip";
import { $Enums, type Agent, ForwardTargetType } from ".prisma/client";
import { Button } from "~/lib/ui/button";
import { MoreHorizontalIcon, XIcon } from "lucide-react";
import { DataTableViewOptions } from "~/app/_components/table-view-options";
import { DataTableViewOptions } from "~/app/[local]/_components/table-view-options";
import {
DropdownMenu,
DropdownMenuContent,
@ -29,13 +29,13 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "~/lib/ui/dropdown-menu";
import ForwardDelete from "~/app/(manage)/forward/_components/forward-delete";
import ForwardModifyRemark from "~/app/(manage)/forward/_components/forward-modify-remark";
import ForwardResetTraffic from "~/app/(manage)/forward/_components/forward-reset-traffic";
import ForwardNew from "~/app/(manage)/forward/_components/forward-new";
import ID from "~/app/_components/id";
import UserColumn from "~/app/_components/user-column";
import Traffic from "~/app/_components/traffic";
import ForwardDelete from "~/app/[local]/(manage)/forward/_components/forward-delete";
import ForwardModifyRemark from "~/app/[local]/(manage)/forward/_components/forward-modify-remark";
import ForwardResetTraffic from "~/app/[local]/(manage)/forward/_components/forward-reset-traffic";
import ForwardNew from "~/app/[local]/(manage)/forward/_components/forward-new";
import ID from "~/app/[local]/_components/id";
import UserColumn from "~/app/[local]/_components/user-column";
import Traffic from "~/app/[local]/_components/traffic";
import { useSession } from "next-auth/react";
import { Role } from "@prisma/client";
import ForwardStatus = $Enums.ForwardStatus;

View File

@ -0,0 +1,24 @@
import ForwardTable from "~/app/[local]/(manage)/forward/_components/forward-table";
import { getTranslations } from "next-intl/server";
export async function generateMetadata({
params: { locale },
}: {
params: { locale: string };
}) {
const t = await getTranslations({ locale, namespace: "global_menu" });
return {
title: `${t("forward")} - vortex`,
};
}
export default async function Forward() {
const t = await getTranslations("global_menu");
return (
<div className="p-4">
<h1 className="mb-4 text-3xl">{t("forward")}</h1>
<ForwardTable />
</div>
);
}

View File

@ -1,5 +1,5 @@
import { type ReactNode } from "react";
import ResizableLayout from "~/app/_components/resizable-layout";
import ResizableLayout from "~/app/[local]/_components/resizable-layout";
import { cookies } from "next/headers";
import { getServerAuthSession } from "~/server/auth";
import { redirect } from "next/navigation";

View File

@ -1,5 +1,5 @@
import { api } from "~/trpc/server";
import NetworkFlow from "~/app/(manage)/network/_components/network-flow";
import NetworkFlow from "~/app/[local]/(manage)/network/_components/network-flow";
export const metadata = {
title: "组网 - vortex",

View File

@ -11,7 +11,7 @@ import {
import { ForwardMethod } from ".prisma/client";
import { useStore } from "zustand";
import { useContext, useMemo, useState } from "react";
import { NetworkContext } from "~/app/(manage)/network/store/network-store";
import { NetworkContext } from "~/app/[local]/(manage)/network/store/network-store";
import { type NetworkAgentEdge } from "~/lib/types/agent";
import { Input } from "~/lib/ui/input";
import { z } from "zod";
@ -27,7 +27,7 @@ import {
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { cn } from "~/lib/utils";
import { WithDescSelector } from "~/app/_components/with-desc-selector";
import { WithDescSelector } from "~/app/[local]/_components/with-desc-selector";
import { ForwardMethodOptions, GostChannelOptions } from "~/lib/constants";
import { api } from "~/trpc/react";

View File

@ -12,7 +12,7 @@ import {
import { useContext, useMemo, useState } from "react";
import { api } from "~/trpc/react";
import { useStore } from "zustand";
import { NetworkContext } from "~/app/(manage)/network/store/network-store";
import { NetworkContext } from "~/app/[local]/(manage)/network/store/network-store";
import { cn, isBase64, isJson } from "~/lib/utils";
import { type NetworkExternalNode } from "~/lib/types/agent";
import { useTrack } from "~/lib/hooks/use-track";

View File

@ -1,7 +1,7 @@
"use client";
import { type NetworkAgentEdge } from "~/lib/types/agent";
import AgentEdgeTest from "~/app/(manage)/network/_components/agent-edge-test";
import AgentEdgeForwardSettings from "~/app/(manage)/network/_components/agent-edge-forward-settings";
import AgentEdgeTest from "~/app/[local]/(manage)/network/_components/agent-edge-test";
import AgentEdgeForwardSettings from "~/app/[local]/(manage)/network/_components/agent-edge-forward-settings";
export default function AgentEdgeToolbar({
id,

View File

@ -4,12 +4,12 @@ import {
type EdgeProps,
getBezierPath,
} from "reactflow";
import AgentEdgeToolbar from "~/app/(manage)/network/_components/agent-edge-toolbar";
import AgentEdgeToolbar from "~/app/[local]/(manage)/network/_components/agent-edge-toolbar";
import { type NetworkAgentEdge } from "~/lib/types/agent";
import { MoveRightIcon, XIcon } from "lucide-react";
import { useStore } from "zustand";
import { useContext, useMemo } from "react";
import { NetworkContext } from "~/app/(manage)/network/store/network-store";
import { NetworkContext } from "~/app/[local]/(manage)/network/store/network-store";
export default function AgentEdge({
id,

View File

@ -12,7 +12,7 @@ import { ServerIcon } from "~/lib/icons";
import { type NetworkAgentNode } from "~/lib/types/agent";
import { useStore } from "zustand";
import { useContext } from "react";
import { NetworkContext } from "~/app/(manage)/network/store/network-store";
import { NetworkContext } from "~/app/[local]/(manage)/network/store/network-store";
export default function AgentNode(props: NodeProps<NetworkAgentNode>) {
const { data } = props;

View File

@ -22,7 +22,7 @@ import {
import { Input } from "~/lib/ui/input";
import React, { useContext } from "react";
import { useStore } from "zustand";
import { NetworkContext } from "~/app/(manage)/network/store/network-store";
import { NetworkContext } from "~/app/[local]/(manage)/network/store/network-store";
import { getNewNodePosition, isValidHost, uuid } from "~/lib/utils";
import { useStoreApi } from "reactflow";

View File

@ -16,7 +16,7 @@ import { useStore } from "zustand";
import {
type AgentProps,
NetworkContext,
} from "~/app/(manage)/network/store/network-store";
} from "~/app/[local]/(manage)/network/store/network-store";
import { AgentStatus } from "@prisma/client";
import { getNewNodePosition } from "~/lib/utils";
import { useStoreApi } from "reactflow";

View File

@ -12,7 +12,7 @@ import { useContext, useEffect, useState } from "react";
import { api } from "~/trpc/react";
import { Button } from "~/lib/ui/button";
import { Input } from "~/lib/ui/input";
import { NetworkContext } from "~/app/(manage)/network/store/network-store";
import { NetworkContext } from "~/app/[local]/(manage)/network/store/network-store";
import { useStore } from "zustand";
import { useRouter } from "next/navigation";
import { Switch } from "~/lib/ui/switch";

View File

@ -1,7 +1,7 @@
"use client";
import ReactFlow, { Background, Controls, Panel } from "reactflow";
import { useEffect, useRef } from "react";
import AgentNode from "~/app/(manage)/network/_components/agent-node";
import AgentNode from "~/app/[local]/(manage)/network/_components/agent-node";
import {
type AgentGetAllOutput,
type NetworkGetOneOutput,
@ -9,13 +9,13 @@ import {
import {
createNetworkStore,
NetworkContext,
} from "~/app/(manage)/network/store/network-store";
import AgentEdge from "~/app/(manage)/network/_components/agent-edge";
import ExternalNode from "~/app/(manage)/network/_components/external-node";
import { NetworkCommand } from "~/app/(manage)/network/_components/network-command";
import NetworkEdit from "~/app/(manage)/network/_components/network-edit";
} from "~/app/[local]/(manage)/network/store/network-store";
import AgentEdge from "~/app/[local]/(manage)/network/_components/agent-edge";
import ExternalNode from "~/app/[local]/(manage)/network/_components/external-node";
import { NetworkCommand } from "~/app/[local]/(manage)/network/_components/network-command";
import NetworkEdit from "~/app/[local]/(manage)/network/_components/network-edit";
import "reactflow/dist/style.css";
import ExternalNodeNew from "~/app/(manage)/network/_components/external-node-new";
import ExternalNodeNew from "~/app/[local]/(manage)/network/_components/external-node-new";
interface NetworkFlowProps {
agents: AgentGetAllOutput;

View File

@ -16,7 +16,7 @@ import {
import { Popover, PopoverContent, PopoverTrigger } from "~/lib/ui/popover";
import { CheckIcon, ChevronsUpDownIcon } from "lucide-react";
import { useStore } from "zustand";
import { NetworkContext } from "~/app/(manage)/network/store/network-store";
import { NetworkContext } from "~/app/[local]/(manage)/network/store/network-store";
import Link from "next/link";
import { type NetworkGetOneOutput } from "~/lib/types/trpc";

View File

@ -7,19 +7,19 @@ import {
} from "@tanstack/react-table";
import { Input } from "~/lib/ui/input";
import { type ChangeEvent, useMemo, useState } from "react";
import Table from "~/app/_components/table";
import Table from "~/app/[local]/_components/table";
import { api } from "~/trpc/react";
import { type NetworkGetAllOutput } from "~/lib/types/trpc";
import ID from "~/app/_components/id";
import UserColumn from "~/app/_components/user-column";
import NetworkDelete from "~/app/(manage)/network/_components/network-delete";
import ID from "~/app/[local]/_components/id";
import UserColumn from "~/app/[local]/_components/user-column";
import NetworkDelete from "~/app/[local]/(manage)/network/_components/network-delete";
import { Button } from "~/lib/ui/button";
import { ArrowRightIcon, CopyIcon, XIcon } from "lucide-react";
import Link from "next/link";
import { copyToClipboard } from "~/lib/utils";
import { type AgentInfo, type NetworkFlow } from "~/lib/types/agent";
import { Tooltip, TooltipContent, TooltipTrigger } from "~/lib/ui/tooltip";
import Traffic from "~/app/_components/traffic";
import Traffic from "~/app/[local]/_components/traffic";
import { ForwardTrafficDimensions } from "~/lib/constants";
export default function NetworkTable({ keyword: k }: { keyword: string }) {

View File

@ -0,0 +1,30 @@
import "reactflow/dist/style.css";
import NetworkTable from "~/app/[local]/(manage)/network/_components/network-table";
import { getTranslations } from "next-intl/server";
export async function generateMetadata({
params: { locale },
}: {
params: { locale: string };
}) {
const t = await getTranslations({ locale, namespace: "global_menu" });
return {
title: `${t("network")} - vortex`,
};
}
export default async function NetworksPage({
searchParams: { keyword },
}: {
searchParams: { keyword: string };
}) {
return (
<div className="h-full p-4">
<div className="flex gap-4">
<h1 className="mb-4 text-3xl">Network</h1>
</div>
<NetworkTable keyword={keyword} />
</div>
);
}

View File

@ -1,8 +1,8 @@
import { api } from "~/trpc/server";
import Markdown from "react-markdown";
import UserColumn from "~/app/_components/user-column";
import TicketReply from "~/app/(manage)/ticket/_components/ticket-reply";
import TicketStatusBadge from "~/app/(manage)/ticket/_components/ticket-status-badge";
import UserColumn from "~/app/[local]/_components/user-column";
import TicketReply from "~/app/[local]/(manage)/ticket/_components/ticket-reply";
import TicketStatusBadge from "~/app/[local]/(manage)/ticket/_components/ticket-status-badge";
import dayjs from "dayjs";
export const metadata = {

View File

@ -1,6 +1,6 @@
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/lib/ui/tabs";
import Markdown from "react-markdown";
import CodeInput from "~/app/_components/code-input";
import CodeInput from "~/app/[local]/_components/code-input";
interface MarkdownInputProps {
value: string;

View File

@ -9,7 +9,7 @@ import {
FormMessage,
} from "~/lib/ui/form";
import { Input } from "~/lib/ui/input";
import MarkdownInput from "~/app/(manage)/ticket/_components/markdown-input";
import MarkdownInput from "~/app/[local]/(manage)/ticket/_components/markdown-input";
import { Button } from "~/lib/ui/button";
import { useTrack } from "~/lib/hooks/use-track";
import { api } from "~/trpc/react";

View File

@ -1,5 +1,5 @@
"use client";
import MarkdownInput from "~/app/(manage)/ticket/_components/markdown-input";
import MarkdownInput from "~/app/[local]/(manage)/ticket/_components/markdown-input";
import { Button } from "~/lib/ui/button";
import { useState } from "react";
import { api } from "~/trpc/react";

View File

@ -8,16 +8,16 @@ import {
import { Input } from "~/lib/ui/input";
import * as React from "react";
import { type ChangeEvent, useMemo, useState } from "react";
import Table from "~/app/_components/table";
import Table from "~/app/[local]/_components/table";
import { api } from "~/trpc/react";
import { type TicketGetAllOutput } from "~/lib/types/trpc";
import ID from "~/app/_components/id";
import UserColumn from "~/app/_components/user-column";
import ID from "~/app/[local]/_components/id";
import UserColumn from "~/app/[local]/_components/user-column";
import { Button } from "~/lib/ui/button";
import { XIcon } from "lucide-react";
import Link from "next/link";
import TicketStatusBadge from "~/app/(manage)/ticket/_components/ticket-status-badge";
import TicketClose from "~/app/(manage)/ticket/_components/ticket-close";
import TicketStatusBadge from "~/app/[local]/(manage)/ticket/_components/ticket-status-badge";
import TicketClose from "~/app/[local]/(manage)/ticket/_components/ticket-close";
export default function TicketTable({ keyword: k }: { keyword: string }) {
const [keyword, setKeyword] = useState(k);

View File

@ -1,4 +1,4 @@
import NewTicketForm from "~/app/(manage)/ticket/_components/new-ticket-form";
import NewTicketForm from "~/app/[local]/(manage)/ticket/_components/new-ticket-form";
export const metadata = {
title: "工单 - vortex",

View File

@ -0,0 +1,30 @@
import TicketTable from "~/app/[local]/(manage)/ticket/_components/ticket-table";
import { getTranslations } from "next-intl/server";
export async function generateMetadata({
params: { locale },
}: {
params: { locale: string };
}) {
const t = await getTranslations({ locale, namespace: "global_menu" });
return {
title: `${t("ticket")} - vortex`,
};
}
export default async function TicketsPage({
searchParams: { keyword },
}: {
searchParams: { keyword: string };
}) {
const t = await getTranslations("global_menu");
return (
<div className="h-full p-4">
<div className="flex gap-4">
<h1 className="mb-4 text-3xl">{t("ticket")}</h1>
</div>
<TicketTable keyword={keyword} />
</div>
);
}

View File

@ -4,7 +4,7 @@ import { ScrollArea } from "~/lib/ui/scroll-area";
import { api } from "~/trpc/react";
import React from "react";
import { formatDate } from "~/lib/utils";
import SearchEmptyState from "~/app/_components/search-empty-state";
import SearchEmptyState from "~/app/[local]/_components/search-empty-state";
import { Tooltip, TooltipContent, TooltipTrigger } from "~/lib/ui/tooltip";
import type { RouterOutputs } from "~/trpc/shared";
import { MoneyInput } from "~/lib/ui/money-input";

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