@@ -0,0 +1,186 @@
import { useState } from 'react'
import { Badge , Input , Tooltip } from 'antd'
import { SearchOutlined , UserOutlined , StarFilled } from '@ant-design/icons'
interface Session {
id : string
name : string
avatar? : string
lastMessage : string
time : string
priority : 'urgent' | 'waiting' | 'active'
unread : number
}
const mockSessions : Session [ ] = [
{ id : '1' , name : '张三' , lastMessage : '我的订单什么时候发货?' , time : '10:32' , priority : 'urgent' , unread : 3 } ,
{ id : '2' , name : '李四' , lastMessage : '怎么退货啊' , time : '10:28' , priority : 'active' , unread : 0 } ,
{ id : '3' , name : '王五' , lastMessage : '你们这个产品好用吗' , time : '10:15' , priority : 'active' , unread : 1 } ,
{ id : '4' , name : '赵六科技' , lastMessage : '企业版价格能否优惠' , time : '09:58' , priority : 'waiting' , unread : 0 } ,
{ id : '5' , name : '钱七' , lastMessage : '谢谢,问题已解决' , time : '09:45' , priority : 'active' , unread : 0 } ,
]
const priorityColors = { urgent : '#dc2626' , waiting : '#d97706' , active : '#2563eb' }
const priorityLabels = { urgent : '紧急' , waiting : '等待中' , active : '进行中' }
const Dashboard = ( ) = > {
const [ selectedId , setSelectedId ] = useState < string > ( '1' )
const [ message , setMessage ] = useState ( '' )
const selectedSession = mockSessions . find ( s = > s . id === selectedId )
return (
< div className = "h-full flex" >
{ /* 左侧:会话列表 */ }
< div className = "w-[300px] flex-shrink-0 border-r border-neutral-200 bg-white flex flex-col" >
< div className = "p-3 border-b border-neutral-100" >
< Input prefix = { < SearchOutlined / > } placeholder = "搜索会话..." variant = "borderless" / >
< / div >
< div className = "flex px-3 py-2 gap-2 border-b border-neutral-100" >
{ ( [ 'urgent' , 'waiting' , 'active' ] as const ) . map ( p = > (
< span key = { p } className = "text-xs px-2 py-0.5 rounded-full cursor-pointer hover:bg-neutral-100" style = { { color : priorityColors [ p ] } } >
{ priorityLabels [ p ] }
< / span >
) ) }
< / div >
< div className = "flex-1 overflow-auto" >
{ mockSessions . map ( session = > (
< div
key = { session . id }
className = { ` px-3 py-2.5 cursor-pointer border-b border-neutral-50 hover:bg-neutral-50 transition-colors ${ selectedId === session . id ? 'bg-blue-50' : '' } ` }
onClick = { ( ) = > setSelectedId ( session . id ) }
>
< div className = "flex items-center justify-between" >
< div className = "flex items-center gap-2" >
< span className = "inline-block w-2 h-2 rounded-full" style = { { backgroundColor : priorityColors [ session . priority ] } } / >
< span className = "text-sm font-medium text-neutral-800" > { session . name } < / span >
< / div >
< div className = "flex items-center gap-1" >
{ session . unread > 0 && < Badge count = { session . unread } size = "small" / > }
< span className = "text-xs text-neutral-400" > { session . time } < / span >
< / div >
< / div >
< p className = "text-xs text-neutral-400 mt-1 truncate pl-4" > { session . lastMessage } < / p >
< / div >
) ) }
< / div >
< / div >
{ /* 中间:聊天区 */ }
< div className = "flex-1 flex flex-col min-w-0 bg-white" >
{ selectedSession ? (
< >
< div className = "h-12 px-4 flex items-center justify-between border-b border-neutral-100 flex-shrink-0" >
< span className = "text-sm font-medium text-neutral-800" > { selectedSession . name } < / span >
< div className = "flex gap-2" >
< Tooltip title = "转接" > < span className = "text-neutral-400 cursor-pointer hover:text-neutral-600 text-sm" > 转 接 < / span > < / Tooltip >
< Tooltip title = "结束会话" > < span className = "text-neutral-400 cursor-pointer hover:text-red-500 text-sm" > 结 束 < / span > < / Tooltip >
< / div >
< / div >
< div className = "flex-1 overflow-auto p-4 flex flex-col gap-3" >
< div className = "flex flex-col items-start" >
< div className = "bg-neutral-100 rounded-lg px-3 py-2 text-sm text-neutral-700 max-w-[70%]" >
你 好 , 我 想 咨 询 一 下 订 单 物 流 问 题
< / div >
< span className = "text-xs text-neutral-400 mt-0.5" > 10 :30 < / span >
< / div >
< div className = "flex flex-col items-end" >
< div className = "bg-blue-500 rounded-lg px-3 py-2 text-sm text-white max-w-[70%]" >
您 好 , 请 提 供 您 的 订 单 号 , 我 帮 您 查 询
< / div >
< span className = "text-xs text-neutral-400 mt-0.5" > 10 :31 < / span >
< / div >
< div className = "flex flex-col items-start" >
< div className = "bg-neutral-100 rounded-lg px-3 py-2 text-sm text-neutral-700 max-w-[70%]" >
订 单 号 是 : AB20260714001
< / div >
< span className = "text-xs text-neutral-400 mt-0.5" > 10 :31 < / span >
< / div >
< div className = "flex flex-col items-end" >
< div className = "bg-blue-500 rounded-lg px-3 py-2 text-sm text-white max-w-[70%]" >
好 的 , 正 在 为 您 查 询 , 请 稍 候 . . .
< / div >
< span className = "text-xs text-neutral-400 mt-0.5" > 10 :32 < / span >
< / div >
< / div >
< div className = "p-3 border-t border-neutral-100 flex-shrink-0" >
< div className = "flex items-center gap-2 bg-neutral-50 rounded-lg px-3 py-2" >
< input
className = "flex-1 bg-transparent outline-none text-sm text-neutral-700 placeholder:text-neutral-400"
placeholder = "输入消息... (Enter 发送)"
value = { message }
onChange = { e = > setMessage ( e . target . value ) }
onKeyDown = { e = > {
if ( e . key === 'Enter' && message . trim ( ) ) {
setMessage ( '' )
}
} }
/ >
< span className = "text-neutral-300 cursor-pointer hover:text-neutral-500" > 😊 < / span >
< span className = "text-neutral-300 cursor-pointer hover:text-neutral-500" > 📎 < / span >
< / div >
< / div >
< / >
) : (
< div className = "flex-1 flex items-center justify-center text-neutral-400" >
选 择 一 个 会 话 开 始 接 待
< / div >
) }
< / div >
{ /* 右侧:客户信息面板 */ }
< div className = "w-[300px] flex-shrink-0 border-l border-neutral-200 bg-white overflow-auto" >
< div className = "p-4 border-b border-neutral-100" >
< div className = "flex items-center gap-3" >
< div className = "w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center" >
< UserOutlined className = "text-blue-500" / >
< / div >
< div >
< div className = "text-sm font-medium text-neutral-800" > { selectedSession ? . name || '访客' } < / div >
< div className = "text-xs text-neutral-400 mt-0.5" > 网 页 渠 道 < / div >
< / div >
< / div >
< / div >
< div className = "p-4 space-y-4" >
< div >
< div className = "text-xs text-neutral-400 mb-1.5" > 标 签 < / div >
< div className = "flex flex-wrap gap-1" >
< span className = "text-xs px-2 py-0.5 rounded bg-orange-50 text-orange-600" > VIP客户 < / span >
< span className = "text-xs px-2 py-0.5 rounded bg-blue-50 text-blue-600" > 新 客 户 < / span >
< / div >
< / div >
< div >
< div className = "text-xs text-neutral-400 mb-1.5" > 联 系 信 息 < / div >
< div className = "text-sm text-neutral-700 space-y-1" >
< div > 📱 138 * * * * 8888 < / div >
< div > 📧 zhang * * * @example . com < / div >
< / div >
< / div >
< div >
< div className = "text-xs text-neutral-400 mb-1.5" > 统 计 数 据 < / div >
< div className = "grid grid-cols-2 gap-2" >
< div className = "bg-neutral-50 rounded p-2 text-center" >
< div className = "text-lg font-semibold text-neutral-800" > 12 < / div >
< div className = "text-xs text-neutral-400" > 对 话 次 数 < / div >
< / div >
< div className = "bg-neutral-50 rounded p-2 text-center" >
< div className = "text-lg font-semibold text-green-600 flex items-center justify-center gap-0.5" >
4.8 < StarFilled className = "text-xs" / >
< / div >
< div className = "text-xs text-neutral-400" > 满 意 度 < / div >
< / div >
< / div >
< / div >
< div >
< div className = "text-xs text-neutral-400 mb-1.5" > 内 部 备 注 < / div >
< div className = "text-sm text-neutral-500 bg-neutral-50 rounded p-2" >
之 前 咨 询 过 售 后 问 题 . . .
< / div >
< / div >
< / div >
< / div >
< / div >
)
}
export default Dashboard