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:
Radosław Gierwiało
2025-11-20 23:22:05 +01:00
parent c1b5ae2ad3
commit 1772fc522e
11 changed files with 704 additions and 0 deletions

View 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;