@@ -16,6 +16,12 @@ import {
DropdownMenuTrigger ,
} from "@workspace/ui/components/dropdown-menu" ;
import { Input } from "@workspace/ui/components/input" ;
import {
Popover ,
PopoverClose ,
PopoverContent ,
PopoverTrigger ,
} from "@workspace/ui/components/popover" ;
import { ScrollArea } from "@workspace/ui/components/scroll-area" ;
import {
Select ,
@@ -31,13 +37,6 @@ import {
SheetTitle ,
SheetTrigger ,
} from "@workspace/ui/components/sheet" ;
import { FilePenLine } from 'lucide-react' ;
import {
Popover ,
PopoverClose ,
PopoverContent ,
PopoverTrigger ,
} from '@workspace/ui/components/popover' ;
import { Switch } from "@workspace/ui/components/switch" ;
import {
Tabs ,
@@ -63,7 +62,9 @@ import {
updateUserBasicInfo ,
} from "@workspace/ui/services/admin/user" ;
import { parseDeviceType } from "@workspace/ui/utils/device" ;
import React , { useRef , useState , useCallback } from ' react' ;
import { FilePenLine } from "lucide- react" ;
import type React from "react" ;
import { useCallback , useRef , useState } from "react" ;
import { useTranslation } from "react-i18next" ;
import { toast } from "sonner" ;
import { Display } from "@/components/display" ;
@@ -77,18 +78,25 @@ import { AuthMethodsForm } from "./user-profile/auth-methods-form";
import { BasicInfoForm } from "./user-profile/basic-info-form" ;
import { NotifySettingsForm } from "./user-profile/notify-settings-form" ;
import UserSubscription from "./user-subscription" ;
// import EditUserGroupDialog from "./edit-user-group-dialog";
// import EditUserGroupDialog from "./edit-user-group-dialog";
// 为 RemarkForm 组件定义 props 类型
interface RemarkFormProps {
initialRemark? : string | null ;
onSave : ( remark : string ) = > void ;
CloseComponent : React.ComponentType < { asChild? : boolean ; children : React.ReactNode } > ;
CloseComponent : React.ComponentType < {
asChild? : boolean ;
children : React.ReactNode ;
} > ;
}
// 新的子组件,在管理它自己的备注状态
const RemarkForm : React.FC < RemarkFormProps > = ( { onSave , initialRemark , CloseComponent } ) = > {
const [ remark , setRemark ] = useState < string > ( initialRemark ? ? '' ) ;
const RemarkForm : React.FC < RemarkFormProps > = ( {
onSave ,
initialRemark ,
CloseComponent ,
} ) = > {
const [ remark , setRemark ] = useState < string > ( initialRemark ? ? "" ) ;
const handleInputChange = ( event : React.ChangeEvent < HTMLInputElement > ) = > {
setRemark ( event . target . value ) ;
@@ -99,21 +107,26 @@ const RemarkForm: React.FC<RemarkFormProps> = ({ onSave, initialRemark, CloseCom
} ;
return (
< >
< div className = ' mb-2 text-sm font-semibold' > 备 注 < / div >
< Input
type = 'text'
value = { remark }
onChange = { handleInputChange }
placeholder = '在此输入备注...'
className = 'w-full'
/ >
< CloseComponent asChild >
< Button onClick = { handleSaveClick } variant = 'default' size = { 'sm' } className = { 'mt-2' } >
保 存
< / Button >
< / CloseComponent >
< / >
< >
< div className = " mb-2 font-semibold text-sm" > 备 注 < / div >
< Input
className = "w-full"
onChange = { handleInputChange }
placeholder = "在此输入备注..."
type = "text"
value = { remark }
/ >
< CloseComponent asChild >
< Button
className = { "mt-2" }
onClick = { handleSaveClick }
size = { "sm" }
variant = "default"
>
保 存
< / Button >
< / CloseComponent >
< / >
) ;
} ;
@@ -184,7 +197,7 @@ export default function User() {
userId = { row . id }
/ > ,
< PreviewNodesDialog key = "preview-nodes" userId = { row . id } / > ,
/* <ConfirmButton
/* <ConfirmButton
cancelText={t("cancel", "Cancel")}
confirmText={t("confirm", "Confirm")}
description={t(
@@ -293,7 +306,7 @@ export default function User() {
{
id : "auth_methods" ,
accessorKey : "auth_methods" ,
header : ' 设备码/邮箱' ,
header : " 设备码/邮箱" ,
cell : ( { row } ) = > {
const method = row . original . auth_methods ? . [ 0 ] ;
const identifier = method ? . auth_identifier || "" ;
@@ -304,50 +317,44 @@ export default function User() {
const display = isDevice ? deviceNo || identifier : identifier ;
return (
< div className = "flex items-center" >
{ /* <Badge
{ /* <Badge
className="mr-1 uppercase"
title={method?.verified ? t("verified", "Verified") : ""}
>
{method?.auth_type}
</Badge>*/ }
{ deviceType && (
< Badge className = "mr-1" variant = "secondary" >
{ deviceType }
< / Badge >
< Badge className = "mr-1" variant = "secondary" >
{ deviceType }
< / Badge >
) }
< span title = { isDevice ? display : undefined } > { display } < / span >
< Popover >
< PopoverTrigger >
< div className = { ' flex items-center' } >
{ row . original ? . remark ? ` ( ${ row . original . remark } ) ` : '' }
< FilePenLine size = { 14 } className = { 'text-primary ml-2' } / >
< div className = { " flex items-center" } >
{ row . original ? . remark ? ` ( ${ row . original . remark } ) ` : "" }
< FilePenLine className = { "ml-2 text-primary" } size = { 14 } / >
< / div >
< / PopoverTrigger >
< PopoverContent className = { ' w-64' } >
< PopoverContent className = { " w-64" } >
< RemarkForm
initialRemark = { row . original . remark }
CloseComponent = { PopoverClose }
onSave = { async ( remark ) = > {
const {
auth_methods : _auth_methods ,
user_devices : _user_devices ,
enable_balance_notify : _enable_balance_notify ,
enable_login_notify : _enable_login_notify ,
enable_subscribe_notify : _enable_subscribe_notify ,
enable_trade_notify : _enable_trade_notify ,
updated_at : _updated_at ,
created_at : _created_at ,
id ,
. . . rest
} = row . original ;
await updateUserBasicInfo ( {
user_id : id ,
. . . rest ,
remark ,
} as unknown as API . UpdateUserBasiceInfoRequest ) ;
toast . success ( t ( 'updateSuccess' ) ) ;
ref . current ? . refresh ( ) ;
} }
CloseComponent = { PopoverClose }
initialRemark = { row . original . remark }
onSave = { async ( remark ) = > {
const {
updated_at : _updated_at ,
created_at : _created_at ,
id ,
. . . rest
} = row . original ;
await updateUserBasicInfo ( {
user_id : id ,
. . . rest ,
remark ,
} as unknown as API . UpdateUserBasiceInfoRequest ) ;
toast . success ( t ( "updateSuccess" ) ) ;
ref . current ? . refresh ( ) ;
} }
/ >
< / PopoverContent >
< / Popover >
@@ -355,7 +362,7 @@ export default function User() {
) ;
} ,
} ,
/* {
/* {
id: "balance",
accessorKey: "balance",
header: t("balance", "Balance"),