296 lines
8.6 KiB
TypeScript
296 lines
8.6 KiB
TypeScript
import React from 'react';
|
|
import {
|
|
Box,
|
|
List,
|
|
ListItem,
|
|
ListItemText,
|
|
Avatar,
|
|
Typography,
|
|
Button,
|
|
Divider,
|
|
useTheme,
|
|
Paper
|
|
} from '@mui/material';
|
|
import { Add, Settings } from '@mui/icons-material';
|
|
|
|
interface Conversation {
|
|
id: string;
|
|
name: string;
|
|
lastMessage?: string;
|
|
timestamp?: Date;
|
|
isActive?: boolean;
|
|
avatar?: string;
|
|
unreadCount?: number;
|
|
}
|
|
|
|
export const Sidebar: React.FC = () => {
|
|
const theme = useTheme();
|
|
|
|
// 模拟对话历史数据
|
|
const conversations: Conversation[] = [
|
|
{
|
|
id: '1',
|
|
name: '开始',
|
|
lastMessage: '守正出奇,让你的内容脱颖而出',
|
|
timestamp: new Date(),
|
|
isActive: true,
|
|
avatar: '🤖',
|
|
unreadCount: 0
|
|
},
|
|
{
|
|
id: '2',
|
|
name: '营销文案',
|
|
lastMessage: '爆款标题的3个关键要素...',
|
|
timestamp: new Date(Date.now() - 3600000),
|
|
isActive: false,
|
|
avatar: '📝',
|
|
unreadCount: 1
|
|
},
|
|
{
|
|
id: '3',
|
|
name: '社交媒体策略',
|
|
lastMessage: '如何提高社交媒体互动率?',
|
|
timestamp: new Date(Date.now() - 86400000),
|
|
isActive: false,
|
|
avatar: '📱',
|
|
unreadCount: 0
|
|
}
|
|
];
|
|
|
|
// 处理新建对话
|
|
const handleNewConversation = () => {
|
|
console.log('创建新对话');
|
|
};
|
|
|
|
// 处理选择对话
|
|
const handleSelectConversation = (conversationId: string) => {
|
|
console.log('选择对话:', conversationId);
|
|
};
|
|
|
|
// 格式化时间
|
|
const formatTime = (date: Date) => {
|
|
const now = new Date();
|
|
const diff = now.getTime() - date.getTime();
|
|
|
|
if (diff < 86400000) { // 24小时内
|
|
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
} else if (diff < 172800000) { // 48小时内
|
|
return '昨天';
|
|
} else {
|
|
return date.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' });
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Paper
|
|
elevation={2}
|
|
sx={{
|
|
width: { xs: '100%', sm: 300 },
|
|
height: '100vh',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
backgroundColor: theme.palette.background.paper,
|
|
borderRight: `1px solid ${theme.palette.divider}`,
|
|
position: 'relative',
|
|
overflow: 'hidden',
|
|
}}
|
|
>
|
|
{/* 用户信息区域 */}
|
|
<Box sx={{ p: 2, borderBottom: `1px solid ${theme.palette.divider}` }}>
|
|
<Box sx={{ mb: 2 }}>
|
|
<Typography
|
|
variant="h6"
|
|
component="h1"
|
|
sx={{
|
|
fontWeight: 600,
|
|
color: theme.palette.primary.main,
|
|
mb: 0.5,
|
|
fontSize: '1.1rem',
|
|
}}
|
|
>
|
|
爆款文案助手
|
|
</Typography>
|
|
<Typography
|
|
variant="body2"
|
|
color="text.secondary"
|
|
sx={{ fontSize: '0.85rem' }}
|
|
>
|
|
亲爱的安先生
|
|
</Typography>
|
|
</Box>
|
|
|
|
{/* 新建对话按钮 */}
|
|
<Button
|
|
fullWidth
|
|
variant="contained"
|
|
startIcon={<Add fontSize="small" />}
|
|
onClick={handleNewConversation}
|
|
sx={{
|
|
backgroundColor: theme.palette.primary.main,
|
|
'&:hover': {
|
|
backgroundColor: theme.palette.primary.dark,
|
|
},
|
|
py: 1.2,
|
|
borderRadius: 2,
|
|
textTransform: 'none',
|
|
fontWeight: 500,
|
|
fontSize: '0.9rem',
|
|
boxShadow: theme.shadows[1],
|
|
}}
|
|
>
|
|
新建对话
|
|
</Button>
|
|
</Box>
|
|
|
|
{/* 对话历史列表 */}
|
|
<List
|
|
component="nav"
|
|
sx={{
|
|
flex: 1,
|
|
overflow: 'auto',
|
|
'&::-webkit-scrollbar': {
|
|
width: 6,
|
|
},
|
|
'&::-webkit-scrollbar-track': {
|
|
backgroundColor: theme.palette.background.default,
|
|
},
|
|
'&::-webkit-scrollbar-thumb': {
|
|
backgroundColor: theme.palette.divider,
|
|
borderRadius: 3,
|
|
},
|
|
}}
|
|
>
|
|
<Typography
|
|
variant="caption"
|
|
sx={{
|
|
px: 2,
|
|
pt: 2,
|
|
pb: 1,
|
|
display: 'block',
|
|
color: theme.palette.text.secondary,
|
|
fontWeight: 500,
|
|
textTransform: 'uppercase',
|
|
letterSpacing: 0.5,
|
|
}}
|
|
>
|
|
最近对话
|
|
</Typography>
|
|
|
|
{conversations.map((conversation) => (
|
|
<React.Fragment key={conversation.id}>
|
|
<ListItem
|
|
onClick={() => handleSelectConversation(conversation.id)}
|
|
sx={{
|
|
borderRadius: 1,
|
|
mx: 1,
|
|
'&:hover': {
|
|
backgroundColor: theme.palette.action.hover,
|
|
},
|
|
backgroundColor: conversation.isActive ? theme.palette.action.selected : 'transparent',
|
|
transition: 'all 0.2s ease',
|
|
paddingX: 2,
|
|
paddingY: 1.5,
|
|
}}
|
|
>
|
|
<Avatar
|
|
sx={{
|
|
width: 44,
|
|
height: 44,
|
|
bgcolor: conversation.isActive ? theme.palette.primary.main : theme.palette.background.default,
|
|
color: conversation.isActive ? 'white' : theme.palette.text.primary,
|
|
fontSize: '1.2rem',
|
|
boxShadow: conversation.isActive ? theme.shadows[2] : 'none',
|
|
}}
|
|
>
|
|
{conversation.avatar}
|
|
</Avatar>
|
|
|
|
<ListItemText
|
|
primary={
|
|
<Box display="flex" justifyContent="space-between" alignItems="center" gap={1}>
|
|
<Typography
|
|
variant="subtitle1"
|
|
sx={{
|
|
fontWeight: conversation.isActive ? 600 : 500,
|
|
fontSize: '0.9rem',
|
|
flex: 1,
|
|
}}
|
|
>
|
|
{conversation.name}
|
|
</Typography>
|
|
<Typography
|
|
variant="caption"
|
|
color="text.secondary"
|
|
sx={{ fontSize: '0.75rem' }}
|
|
>
|
|
{conversation.timestamp && formatTime(conversation.timestamp)}
|
|
</Typography>
|
|
</Box>
|
|
}
|
|
secondary={
|
|
<Box display="flex" alignItems="center" gap={1}>
|
|
<Typography
|
|
variant="body2"
|
|
color="text.secondary"
|
|
sx={{
|
|
flex: 1,
|
|
overflow: 'hidden',
|
|
textOverflow: 'ellipsis',
|
|
whiteSpace: 'nowrap',
|
|
fontSize: '0.8rem',
|
|
}}
|
|
>
|
|
{conversation.lastMessage}
|
|
</Typography>
|
|
{conversation.unreadCount && conversation.unreadCount > 0 && (
|
|
<Box
|
|
sx={{
|
|
minWidth: '18px',
|
|
height: '18px',
|
|
borderRadius: '9px',
|
|
backgroundColor: theme.palette.primary.main,
|
|
color: 'white',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
px: 0.5,
|
|
}}
|
|
>
|
|
<Typography variant="caption" sx={{ fontSize: '0.7rem', fontWeight: 600 }}>
|
|
{conversation.unreadCount}
|
|
</Typography>
|
|
</Box>
|
|
)}
|
|
</Box>
|
|
}
|
|
primaryTypographyProps={{ component: 'div' }}
|
|
secondaryTypographyProps={{ component: 'div' }}
|
|
/>
|
|
</ListItem>
|
|
<Divider light />
|
|
</React.Fragment>
|
|
))}
|
|
</List>
|
|
|
|
{/* 底部设置区域 */}
|
|
<Box sx={{ p: 2, borderTop: `1px solid ${theme.palette.divider}` }}>
|
|
<Button
|
|
fullWidth
|
|
startIcon={<Settings fontSize="small" />}
|
|
sx={{
|
|
justifyContent: 'flex-start',
|
|
color: theme.palette.text.primary,
|
|
'&:hover': {
|
|
backgroundColor: theme.palette.action.hover,
|
|
},
|
|
textTransform: 'none',
|
|
fontWeight: 500,
|
|
fontSize: '0.9rem',
|
|
}}
|
|
>
|
|
设置
|
|
</Button>
|
|
</Box>
|
|
</Paper>
|
|
);
|
|
}; |