|
|
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) => { |
|
|
|
|
|
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> |
|
|
); |
|
|
}; |
|
|
|