diff --git a/frontend/src/pages/EventChatPage.jsx b/frontend/src/pages/EventChatPage.jsx
index 384134b..6bad930 100644
--- a/frontend/src/pages/EventChatPage.jsx
+++ b/frontend/src/pages/EventChatPage.jsx
@@ -7,6 +7,10 @@ import { connectSocket, disconnectSocket, getSocket } from '../services/socket';
import { eventsAPI, heatsAPI, matchesAPI } from '../services/api';
import HeatsBanner from '../components/heats/HeatsBanner';
import Avatar from '../components/common/Avatar';
+import ChatMessageList from '../components/chat/ChatMessageList';
+import ChatInput from '../components/chat/ChatInput';
+import ConfirmationModal from '../components/modals/ConfirmationModal';
+import Modal from '../components/modals/Modal';
const EventChatPage = () => {
const { slug } = useParams();
@@ -590,79 +594,24 @@ const EventChatPage = () => {
{/* Chat Area */}
- {/* Messages */}
-
- {/* Loading older messages indicator */}
- {loadingOlder && (
-
-
-
- )}
-
- {messages.length === 0 && (
-
- No messages yet. Start the conversation!
-
- )}
- {messages.map((message) => {
- const isOwnMessage = (message.userId ?? message.user_id) === user.id;
- return (
-
-
-
-
-
-
- {message.username}
-
-
- {new Date(message.createdAt).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })}
-
-
-
- {message.content}
-
-
-
-
- );
- })}
-
-
+
{/* Message Input */}
-
+ setNewMessage(e.target.value)}
+ onSubmit={handleSendMessage}
+ disabled={!isConnected}
+ placeholder="Write a message..."
+ />
@@ -679,79 +628,31 @@ const EventChatPage = () => {
- {/* Leave Confirmation Modal */}
- {showLeaveModal && (
-
-
-
-
-
-
Leave Event?
-
This action cannot be undone
-
-
+
setShowLeaveModal(false)}
+ onConfirm={handleLeaveEvent}
+ title="Leave Event?"
+ description="This action cannot be undone"
+ message={`Are you sure you want to leave ${event?.name || 'this event'}? You will need to scan the QR code again to rejoin.`}
+ confirmText="Leave Event"
+ isLoading={isLeaving}
+ loadingText="Leaving..."
+ icon={AlertTriangle}
+ />
-
- Are you sure you want to leave {event.name} ?
- You will need to scan the QR code again to rejoin.
-
-
-
- setShowLeaveModal(false)}
- disabled={isLeaving}
- className="flex-1 px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors font-medium disabled:opacity-50"
- >
- Cancel
-
-
- {isLeaving ? (
- <>
-
- Leaving...
- >
- ) : (
- <>
-
- Leave Event
- >
- )}
-
-
-
-
- )}
-
- {/* Edit Heats Modal */}
- {showHeatsModal && (
-
-
-
-
Edit Your Competition Heats
- setShowHeatsModal(false)}
- className="text-gray-400 hover:text-gray-600"
- >
-
-
-
-
- setShowHeatsModal(false)}
- existingHeats={myHeats}
- />
-
-
-
- )}
+ setShowHeatsModal(false)}
+ title="Edit Your Competition Heats"
+ >
+ setShowHeatsModal(false)}
+ existingHeats={myHeats}
+ />
+
);
diff --git a/frontend/src/pages/LoginPage.jsx b/frontend/src/pages/LoginPage.jsx
index 620e153..3b935da 100644
--- a/frontend/src/pages/LoginPage.jsx
+++ b/frontend/src/pages/LoginPage.jsx
@@ -2,6 +2,8 @@ import { useState } from 'react';
import { useNavigate, Link } from 'react-router-dom';
import { useAuth } from '../contexts/AuthContext';
import { Video, Mail, Lock } from 'lucide-react';
+import FormInput from '../components/common/FormInput';
+import LoadingButton from '../components/common/LoadingButton';
const LoginPage = () => {
const [email, setEmail] = useState('');
@@ -33,24 +35,16 @@ const LoginPage = () => {
diff --git a/frontend/src/pages/MatchChatPage.jsx b/frontend/src/pages/MatchChatPage.jsx
index 279fb4c..63b9983 100644
--- a/frontend/src/pages/MatchChatPage.jsx
+++ b/frontend/src/pages/MatchChatPage.jsx
@@ -9,6 +9,8 @@ import { useWebRTC } from '../hooks/useWebRTC';
import { detectWebRTCSupport } from '../utils/webrtcDetection';
import WebRTCWarning from '../components/WebRTCWarning';
import Avatar from '../components/common/Avatar';
+import ChatMessageList from '../components/chat/ChatMessageList';
+import ChatInput from '../components/chat/ChatInput';
const MatchChatPage = () => {
const { slug } = useParams();
@@ -350,52 +352,11 @@ const MatchChatPage = () => {
)}
- {/* Messages */}
-
- {messages.length === 0 && (
-
- No messages yet. Start the conversation!
-
- )}
- {messages.map((message) => {
- const isOwnMessage = (message.userId ?? message.user_id) === user.id;
- return (
-
-
-
-
-
-
- {message.username}
-
-
- {new Date(message.createdAt).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })}
-
-
-
- {message.content}
-
-
-
-
- );
- })}
-
-
+
{/* Video Transfer Section */}
{(selectedFile || isTransferring) && (
@@ -529,23 +490,13 @@ const MatchChatPage = () => {
-
+ setNewMessage(e.target.value)}
+ onSubmit={handleSendMessage}
+ disabled={!isConnected}
+ placeholder="Write a message..."
+ />
diff --git a/frontend/src/pages/ProfilePage.jsx b/frontend/src/pages/ProfilePage.jsx
index aeacda9..23c20c1 100644
--- a/frontend/src/pages/ProfilePage.jsx
+++ b/frontend/src/pages/ProfilePage.jsx
@@ -2,9 +2,13 @@ import { useState, useEffect } from 'react';
import { useAuth } from '../contexts/AuthContext';
import { authAPI } from '../services/api';
import Layout from '../components/layout/Layout';
-import { User, Mail, Lock, Save, AlertCircle, CheckCircle, Loader2, Hash, Youtube, Instagram, Facebook, MapPin, Globe } from 'lucide-react';
-import { COUNTRIES } from '../data/countries';
+import Alert from '../components/common/Alert';
+import FormInput from '../components/common/FormInput';
+import FormSelect from '../components/common/FormSelect';
+import LoadingButton from '../components/common/LoadingButton';
import Avatar from '../components/common/Avatar';
+import { User, Mail, Lock, Save, Hash, Youtube, Instagram, Facebook, MapPin, Globe } from 'lucide-react';
+import { COUNTRIES } from '../data/countries';
const ProfilePage = () => {
const { user, updateUser } = useAuth();
@@ -41,6 +45,7 @@ const ProfilePage = () => {
});
}
}, [user]);
+
const [profileLoading, setProfileLoading] = useState(false);
const [profileMessage, setProfileMessage] = useState('');
const [profileError, setProfileError] = useState('');
@@ -196,254 +201,135 @@ const ProfilePage = () => {
)}
@@ -452,98 +338,49 @@ const ProfilePage = () => {
)}
diff --git a/frontend/src/pages/RegisterPage.jsx b/frontend/src/pages/RegisterPage.jsx
index 5193cab..d551a3f 100644
--- a/frontend/src/pages/RegisterPage.jsx
+++ b/frontend/src/pages/RegisterPage.jsx
@@ -4,6 +4,9 @@ import { useAuth } from '../contexts/AuthContext';
import { wsdcAPI } from '../services/api';
import { Video, Mail, Lock, User, Hash, ArrowRight, ArrowLeft, Loader2, CheckCircle, XCircle, AlertCircle } from 'lucide-react';
import PasswordStrengthIndicator from '../components/common/PasswordStrengthIndicator';
+import FormInput from '../components/common/FormInput';
+import LoadingButton from '../components/common/LoadingButton';
+import Alert from '../components/common/Alert';
const RegisterPage = () => {
// Step management
@@ -183,23 +186,19 @@ const RegisterPage = () => {
) : (
-
- Enter your WSDC ID
-
-
-
-
-
setWsdcId(e.target.value.replace(/\D/g, ''))}
- className="pl-10 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:ring-primary-500 focus:border-primary-500"
+ icon={Hash}
placeholder="12345"
maxLength={10}
/>
{wsdcLoading && (
-
+
)}
@@ -307,145 +306,85 @@ const RegisterPage = () => {
)}
- {error && (
-
- )}
+