- Add Alert component with 4 variants (success/error/warning/info) - Add LoadingSpinner and LoadingButton components - Add FormInput and FormSelect components with icon support - Add Modal and ConfirmationModal components - Add ChatMessage, ChatMessageList, and ChatInput components - Add EventCard component These components will eliminate ~450 lines of duplicated code across pages. Part of Phase 1 (Quick Wins) frontend refactoring.
58 lines
1.7 KiB
JavaScript
58 lines
1.7 KiB
JavaScript
import Avatar from '../common/Avatar';
|
|
|
|
/**
|
|
* Individual Chat Message component
|
|
*
|
|
* @param {object} message - Message object with { id, content, username, avatar, createdAt, userId/user_id }
|
|
* @param {boolean} isOwn - Whether this message belongs to the current user
|
|
* @param {function} formatTime - Optional custom time formatter (default: toLocaleTimeString)
|
|
*/
|
|
const ChatMessage = ({ message, isOwn, formatTime }) => {
|
|
const defaultFormatTime = (timestamp) => {
|
|
return new Date(timestamp).toLocaleTimeString('en-US', {
|
|
hour: '2-digit',
|
|
minute: '2-digit'
|
|
});
|
|
};
|
|
|
|
const timeFormatter = formatTime || defaultFormatTime;
|
|
|
|
return (
|
|
<div className={`flex ${isOwn ? 'justify-end' : 'justify-start'}`}>
|
|
<div
|
|
className={`flex items-start space-x-2 max-w-md ${
|
|
isOwn ? 'flex-row-reverse space-x-reverse' : ''
|
|
}`}
|
|
>
|
|
<Avatar
|
|
src={message.avatar}
|
|
username={message.username}
|
|
size={32}
|
|
title={message.username}
|
|
/>
|
|
<div>
|
|
<div className="flex items-baseline space-x-2 mb-1">
|
|
<span className="text-sm font-medium text-gray-900">
|
|
{message.username}
|
|
</span>
|
|
<span className="text-xs text-gray-500">
|
|
{timeFormatter(message.createdAt)}
|
|
</span>
|
|
</div>
|
|
<div
|
|
className={`rounded-lg px-4 py-2 ${
|
|
isOwn
|
|
? 'bg-primary-600 text-white'
|
|
: 'bg-gray-100 text-gray-900'
|
|
}`}
|
|
>
|
|
{message.content}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ChatMessage;
|