feat(frontend): create reusable components for Phase 1 refactoring
- 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.
This commit is contained in:
57
frontend/src/components/chat/ChatMessage.jsx
Normal file
57
frontend/src/components/chat/ChatMessage.jsx
Normal file
@@ -0,0 +1,57 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user