UI / frontend /components /MessageList.tsx
Chan-Y's picture
Initial commit for HF Space
a94ab76
import React from 'react';
import { Message } from '../types';
import { User, Bot, Sparkles } from 'lucide-react';
interface MessageListProps {
messages: Message[];
}
export const MessageList: React.FC<MessageListProps> = ({ messages }) => {
const formatMessage = (content: string) => {
// Split by solution tags for better formatting
const parts = content.split(/(<start_working_out>|<end_working_out>|<SOLUTION>|<\/SOLUTION>)/g);
return parts.map((part, idx) => {
if (part === '<start_working_out>') {
return (
<div key={idx} className="inline-flex items-center gap-2 text-primary-600 dark:text-primary-400 font-semibold mt-3 mb-2">
<Sparkles size={16} className="flex-shrink-0" />
<span className="leading-none">Düşünme Süreci</span>
</div>
);
} else if (part === '<end_working_out>') {
return null;
} else if (part === '<SOLUTION>') {
return (
<div key={idx} className="inline-flex items-center gap-2 text-green-600 dark:text-green-400 font-semibold mt-4 mb-2">
<svg className="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span className="leading-none">Çözüm</span>
</div>
);
} else if (part === '</SOLUTION>') {
return null;
} else if (part.trim()) {
return <div key={idx} className="whitespace-pre-wrap leading-relaxed">{part.trim()}</div>;
}
return null;
});
};
if (messages.length === 0) {
return (
<div className="flex-1 flex items-center justify-center text-gray-400 dark:text-gray-600 bg-gray-50 dark:bg-gray-900">
<div className="text-center max-w-md px-4">
<div className="w-20 h-20 bg-gradient-to-br from-primary-100 to-primary-200 dark:from-primary-900/30 dark:to-primary-800/30 rounded-2xl flex items-center justify-center mx-auto mb-4">
<Bot size={40} className="text-primary-600 dark:text-primary-400" />
</div>
<h3 className="text-xl font-semibold text-gray-700 dark:text-gray-300 mb-2">
Sohbete Başlayın
</h3>
<p className="text-sm text-gray-500 dark:text-gray-400">
Türkçe AI modeliyle muhakeme sorularınızı sorun ve detaylı açıklamalar alın
</p>
</div>
</div>
);
}
return (
<div className="flex-1 overflow-y-auto px-4 py-6 space-y-6 bg-white dark:bg-gray-950">
<div className="max-w-3xl mx-auto space-y-6">
{messages.map((message, idx) => {
if (message.role === 'system') return null;
return (
<div
key={idx}
className="flex gap-4 group"
>
{/* Avatar */}
<div className="flex-shrink-0">
{message.role === 'assistant' ? (
<div className="w-7 h-7 bg-primary-600 rounded-sm flex items-center justify-center">
<Bot size={16} className="text-white" />
</div>
) : (
<div className="w-7 h-7 bg-gray-700 dark:bg-gray-600 rounded-sm flex items-center justify-center">
<User size={16} className="text-white" />
</div>
)}
</div>
{/* Message Content */}
<div className="flex-1 min-w-0 pt-1">
{message.image && (
<img
src={message.image}
alt="User upload"
className="max-w-sm rounded-lg mb-3 border border-gray-200 dark:border-gray-700"
/>
)}
<div className="text-sm text-gray-800 dark:text-gray-200 leading-relaxed">
{message.role === 'assistant' ? (
formatMessage(message.content)
) : (
<div className="whitespace-pre-wrap">{message.content}</div>
)}
</div>
</div>
</div>
);
})}
</div>
</div>
);
};