ChatHeader.tsx 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. "use client";
  2. import { formatConversationTime } from "@/utils/format";
  3. import { Button } from "@/components/ui/button";
  4. import { Separator } from "@/components/ui/separator";
  5. interface ChatHeaderProps {
  6. conversationId: number;
  7. lastSeenAt?: string | null;
  8. unreadCount: number;
  9. onMarkAllRead: () => void;
  10. onRefresh: () => void;
  11. includeAIMessages?: boolean; // 是否包含 AI 消息
  12. onToggleAIMessages?: () => void; // 切换 AI 消息显示/隐藏
  13. }
  14. export function ChatHeader({
  15. conversationId,
  16. lastSeenAt,
  17. unreadCount,
  18. onMarkAllRead,
  19. onRefresh,
  20. includeAIMessages = false,
  21. onToggleAIMessages,
  22. }: ChatHeaderProps) {
  23. return (
  24. <div className="h-16 flex items-center justify-between px-4 bg-background flex-shrink-0 relative">
  25. <div className="z-10">
  26. <div className="font-semibold text-foreground">对话 #{conversationId}</div>
  27. <div className="text-xs text-muted-foreground mt-0.5">
  28. {lastSeenAt
  29. ? `last seen ${formatConversationTime(lastSeenAt)}`
  30. : "last seen 未知"}
  31. </div>
  32. </div>
  33. <div className="flex items-center gap-2">
  34. {/* 显示/隐藏 AI 消息切换按钮 */}
  35. {onToggleAIMessages && (
  36. <Button
  37. variant={includeAIMessages ? "default" : "outline"}
  38. size="sm"
  39. onClick={onToggleAIMessages}
  40. title={includeAIMessages ? "隐藏 AI 消息" : "显示 AI 消息"}
  41. className="text-xs"
  42. >
  43. {includeAIMessages ? "隐藏 AI 消息" : "显示 AI 消息"}
  44. </Button>
  45. )}
  46. <Button
  47. variant="ghost"
  48. size="icon"
  49. title="标记全部已读"
  50. onClick={onMarkAllRead}
  51. disabled={unreadCount === 0}
  52. >
  53. <svg
  54. className="w-5 h-5"
  55. fill="none"
  56. stroke="currentColor"
  57. viewBox="0 0 24 24"
  58. >
  59. <path
  60. strokeLinecap="round"
  61. strokeLinejoin="round"
  62. strokeWidth={2}
  63. d="M5 13l4 4L19 7"
  64. />
  65. </svg>
  66. </Button>
  67. <Button
  68. variant="ghost"
  69. size="icon"
  70. title="刷新"
  71. onClick={onRefresh}
  72. >
  73. <svg
  74. className="w-5 h-5 text-muted-foreground"
  75. fill="none"
  76. stroke="currentColor"
  77. viewBox="0 0 24 24"
  78. >
  79. <path
  80. strokeLinecap="round"
  81. strokeLinejoin="round"
  82. strokeWidth={2}
  83. d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
  84. />
  85. </svg>
  86. </Button>
  87. </div>
  88. <Separator className="absolute bottom-0 left-0 right-0" />
  89. </div>
  90. );
  91. }