@@ -19,6 +19,7 @@ import {
1919import { parseDate } from "@internationalized/date" ;
2020import { addToast } from "@heroui/toast" ;
2121import Editor from "@monaco-editor/react" ;
22+ import { useTranslation } from "react-i18next" ;
2223
2324interface InstanceTagModalProps {
2425 isOpen : boolean ;
@@ -70,6 +71,8 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
7071 currentTags = { } ,
7172 onSaved,
7273} ) => {
74+ const { t } = useTranslation ( "tunnels" ) ;
75+
7376 // 标准字段状态
7477 const [ startDate , setStartDate ] = useState < string > ( "" ) ;
7578 const [ endDate , setEndDate ] = useState < string > ( "" ) ;
@@ -184,7 +187,8 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
184187 }
185188
186189 // 检查是否为免费
187- if ( amount . toLowerCase ( ) . includes ( "免费" ) || amount . toLowerCase ( ) . includes ( "free" ) ) {
190+ const freeText = t ( "instanceTagModal.amountType.free" ) . toLowerCase ( ) ;
191+ if ( amount . toLowerCase ( ) . includes ( freeText ) || amount . toLowerCase ( ) . includes ( "free" ) ) {
188192 setAmountType ( "free" ) ;
189193 setAmountValue ( "" ) ;
190194 return ;
@@ -441,12 +445,12 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
441445 } ) ;
442446
443447 if ( ! response . ok ) {
444- throw new Error ( "保存标签失败" ) ;
448+ throw new Error ( t ( "instanceTagModal.toast.saveFailedMessage" ) ) ;
445449 }
446450
447451 addToast ( {
448- title : "保存成功" ,
449- description : "实例标签已更新" ,
452+ title : t ( "instanceTagModal.toast.saveSuccess" ) ,
453+ description : t ( "instanceTagModal.toast.saveSuccessDesc" ) ,
450454 color : "success" ,
451455 } ) ;
452456
@@ -455,8 +459,8 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
455459 } catch ( error ) {
456460 console . error ( "保存标签失败:" , error ) ;
457461 addToast ( {
458- title : "保存失败" ,
459- description : error instanceof Error ? error . message : "未知错误" ,
462+ title : t ( "instanceTagModal.toast.saveFailed" ) ,
463+ description : error instanceof Error ? error . message : t ( "instanceTagModal.toast.unknownError" ) ,
460464 color : "danger" ,
461465 } ) ;
462466 } finally {
@@ -476,16 +480,16 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
476480 { ( onClose ) => (
477481 < >
478482 < ModalHeader className = "flex flex-col gap-1 pb-0" >
479- < h2 className = "text-xl font-semibold" > 设置标签 </ h2 >
483+ < h2 className = "text-xl font-semibold" > { t ( "instanceTagModal.title" ) } </ h2 >
480484 </ ModalHeader >
481485 < ModalBody >
482486 < Tabs
483487 fullWidth
484488 selectedKey = { activeTab }
485489 onSelectionChange = { handleTabChange }
486- aria-label = "编辑模式"
490+ aria-label = { t ( "instanceTagModal.tabs.ariaLabel" ) }
487491 >
488- < Tab key = "json" title = "JSON 编辑" >
492+ < Tab key = "json" title = { t ( "instanceTagModal.tabs.json" ) } >
489493 < div className = { `border rounded-lg overflow-hidden ${ isJsonError ? 'border-danger' : 'border-default-200' } ` } >
490494 < Editor
491495 defaultLanguage = "json"
@@ -508,13 +512,13 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
508512 />
509513 </ div >
510514 </ Tab >
511- < Tab key = "template" title = "模板编辑" >
515+ < Tab key = "template" title = { t ( "instanceTagModal.tabs.template" ) } >
512516 < div className = "space-y-4 " >
513517 { /* 日期字段 */ }
514518 < div className = "grid grid-cols-2 gap-4" >
515519 { /* 开始日期 */ }
516520 < div className = "flex flex-col gap-2" >
517- < label className = "text-sm font-medium text-default-700" > 开始日期 </ label >
521+ < label className = "text-sm font-medium text-default-700" > { t ( "instanceTagModal.fields.startDate" ) } </ label >
518522 < DatePicker
519523 value = { startDate ? ( parseDate ( startDate . split ( 'T' ) [ 0 ] ) as any ) : undefined }
520524 onChange = { ( date ) => {
@@ -536,7 +540,7 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
536540 { /* 结束日期 */ }
537541 < div className = "flex flex-col gap-1.5" >
538542 < div className = "flex items-center justify-between" >
539- < label className = "text-sm font-medium text-default-700" > 结束日期 </ label >
543+ < label className = "text-sm font-medium text-default-700" > { t ( "instanceTagModal.fields.endDate" ) } </ label >
540544 < Checkbox
541545 isSelected = { isUnlimited }
542546 onValueChange = { ( checked ) => {
@@ -547,7 +551,7 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
547551 } }
548552 size = "sm"
549553 >
550- 无限期
554+ { t ( "instanceTagModal.fields.unlimited" ) }
551555 </ Checkbox >
552556 </ div >
553557 < DatePicker
@@ -574,25 +578,25 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
574578 { /* 金额字段 */ }
575579 < div className = "flex flex-col gap-1.5" >
576580 < div className = "flex items-center justify-between" >
577- < label className = "text-sm font-medium text-default-700" > 金额 </ label >
581+ < label className = "text-sm font-medium text-default-700" > { t ( "instanceTagModal.fields.amount" ) } </ label >
578582 < RadioGroup
579583 value = { amountType }
580584 onValueChange = { setAmountType }
581585 orientation = "horizontal"
582586 className = "gap-2"
583587 size = "sm"
584588 >
585- < Radio value = "none" > 无格式 </ Radio >
586- < Radio value = "prefix" > 前缀 </ Radio >
587- < Radio value = "suffix" > 后缀 </ Radio >
588- < Radio value = "free" > 免费 </ Radio >
589+ < Radio value = "none" > { t ( "instanceTagModal.amountType.none" ) } </ Radio >
590+ < Radio value = "prefix" > { t ( "instanceTagModal.amountType.prefix" ) } </ Radio >
591+ < Radio value = "suffix" > { t ( "instanceTagModal.amountType.suffix" ) } </ Radio >
592+ < Radio value = "free" > { t ( "instanceTagModal.amountType.free" ) } </ Radio >
589593 </ RadioGroup >
590594 </ div >
591595
592596 { /* 金额输入区域 */ }
593597 { amountType === "none" && (
594598 < Input
595- placeholder = "输入金额"
599+ placeholder = { t ( "instanceTagModal.fields.amountPlaceholder" ) }
596600 value = { amountValue }
597601 onValueChange = { setAmountValue }
598602 variant = "bordered"
@@ -609,7 +613,7 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
609613 } }
610614 className = "w-32"
611615 variant = "bordered"
612- aria-label = "货币符号"
616+ aria-label = { t ( "instanceTagModal.ariaLabels.currencySymbol" ) }
613617 >
614618 { CURRENCY_OPTIONS . map ( ( currency ) => (
615619 < SelectItem key = { currency . key } >
@@ -618,7 +622,7 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
618622 ) ) }
619623 </ Select >
620624 < Input
621- placeholder = "输入金额"
625+ placeholder = { t ( "instanceTagModal.fields.amountPlaceholder" ) }
622626 value = { amountValue }
623627 onValueChange = { setAmountValue }
624628 variant = "bordered"
@@ -635,7 +639,7 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
635639 { amountType === "suffix" && (
636640 < div className = "flex gap-2" >
637641 < Input
638- placeholder = "输入金额"
642+ placeholder = { t ( "instanceTagModal.fields.amountPlaceholder" ) }
639643 value = { amountValue }
640644 onValueChange = { setAmountValue }
641645 variant = "bordered"
@@ -654,7 +658,7 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
654658 } }
655659 className = "w-32"
656660 variant = "bordered"
657- aria-label = "货币代码"
661+ aria-label = { t ( "instanceTagModal.ariaLabels.currencyCode" ) }
658662 >
659663 { CURRENCY_CODES . map ( ( currency ) => (
660664 < SelectItem key = { currency . key } >
@@ -679,9 +683,9 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
679683 < div className = "grid grid-cols-2 gap-4" >
680684 { /* 带宽 */ }
681685 < div className = "flex flex-col gap-1.5" >
682- < label className = "text-sm font-medium text-default-700" > 带宽 </ label >
686+ < label className = "text-sm font-medium text-default-700" > { t ( "instanceTagModal.fields.bandwidth" ) } </ label >
683687 < Input
684- placeholder = "输入带宽数值"
688+ placeholder = { t ( "instanceTagModal.fields.bandwidthPlaceholder" ) }
685689 value = { bandwidthValue }
686690 onValueChange = { setBandwidthValue }
687691 variant = "bordered"
@@ -703,9 +707,9 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
703707
704708 { /* 流量 */ }
705709 < div className = "flex flex-col gap-1.5" >
706- < label className = "text-sm font-medium text-default-700" > 流量 </ label >
710+ < label className = "text-sm font-medium text-default-700" > { t ( "instanceTagModal.fields.traffic" ) } </ label >
707711 < Input
708- placeholder = "输入流量数值"
712+ placeholder = { t ( "instanceTagModal.fields.trafficPlaceholder" ) }
709713 value = { trafficValue }
710714 onValueChange = { setTrafficValue }
711715 variant = "bordered"
@@ -730,9 +734,9 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
730734 < div className = "grid grid-cols-2 gap-4" >
731735 { /* 网络路由 */ }
732736 < div className = "flex flex-col gap-1.5" >
733- < label className = "text-sm font-medium text-default-700" > 网络路由 </ label >
737+ < label className = "text-sm font-medium text-default-700" > { t ( "instanceTagModal.fields.networkRoute" ) } </ label >
734738 < Input
735- placeholder = "例如:4837、9929、联通 等"
739+ placeholder = { t ( "instanceTagModal.fields.networkRoutePlaceholder" ) }
736740 value = { networkRoute }
737741 onValueChange = { setNetworkRoute }
738742 variant = "bordered"
@@ -741,9 +745,9 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
741745
742746 { /* 额外信息 */ }
743747 < div className = "flex flex-col gap-1.5" >
744- < label className = "text-sm font-medium text-default-700" > 额外信息 </ label >
748+ < label className = "text-sm font-medium text-default-700" > { t ( "instanceTagModal.fields.extra" ) } </ label >
745749 < Input
746- placeholder = "使用逗号分隔多个信息"
750+ placeholder = { t ( "instanceTagModal.fields.extraPlaceholder" ) }
747751 value = { extra }
748752 onValueChange = { setExtra }
749753 variant = "bordered"
@@ -756,15 +760,15 @@ const InstanceTagModal: React.FC<InstanceTagModalProps> = ({
756760 </ ModalBody >
757761 < ModalFooter className = "pt-0" >
758762 < Button color = "danger" variant = "light" onPress = { onClose } >
759- 取消
763+ { t ( "instanceTagModal.buttons.cancel" ) }
760764 </ Button >
761765 < Button
762766 color = "primary"
763767 onPress = { handleSave }
764768 isLoading = { isSaving }
765769 isDisabled = { isJsonError }
766770 >
767- 保存
771+ { t ( "instanceTagModal.buttons.save" ) }
768772 </ Button >
769773 </ ModalFooter >
770774 </ >
0 commit comments