diff --git a/frontend/src/components/events/MatchingConfigSection.jsx b/frontend/src/components/events/MatchingConfigSection.jsx index 7742570..58abd51 100644 --- a/frontend/src/components/events/MatchingConfigSection.jsx +++ b/frontend/src/components/events/MatchingConfigSection.jsx @@ -1,4 +1,5 @@ import { useState } from 'react'; +import toast from 'react-hot-toast'; import { Video, Clock, Save, RefreshCw } from 'lucide-react'; import { matchingAPI } from '../../services/api'; @@ -21,10 +22,11 @@ const MatchingConfigSection = ({ slug, event, onRefresh }) => { setSavingDeadline(true); const deadline = deadlineInput ? new Date(deadlineInput).toISOString() : null; await matchingAPI.setRegistrationDeadline(slug, deadline); + toast.success('Deadline saved successfully'); onRefresh?.(); } catch (err) { console.error('Failed to save deadline:', err); - alert('Nie udalo sie zapisac deadline'); + toast.error('Failed to save deadline'); } finally { setSavingDeadline(false); } diff --git a/frontend/src/components/events/ScheduleConfigSection.jsx b/frontend/src/components/events/ScheduleConfigSection.jsx index c661793..76f310e 100644 --- a/frontend/src/components/events/ScheduleConfigSection.jsx +++ b/frontend/src/components/events/ScheduleConfigSection.jsx @@ -1,4 +1,5 @@ import { useState, useEffect } from 'react'; +import toast from 'react-hot-toast'; import { Layers, Plus, Trash2, Save, RefreshCw } from 'lucide-react'; import { matchingAPI, divisionsAPI } from '../../services/api'; @@ -72,10 +73,11 @@ const ScheduleConfigSection = ({ slug, event, onRefresh }) => { ? { slots: scheduleSlots.filter(s => s.divisionIds.length > 0) } : null; await matchingAPI.setScheduleConfig(slug, scheduleConfig); + toast.success('Schedule saved successfully'); onRefresh?.(); } catch (err) { console.error('Failed to save schedule:', err); - alert('Nie udalo sie zapisac harmonogramu'); + toast.error('Failed to save schedule'); } finally { setSavingSchedule(false); } diff --git a/frontend/src/pages/EventChatPage.jsx b/frontend/src/pages/EventChatPage.jsx index eb91545..5ede7d5 100644 --- a/frontend/src/pages/EventChatPage.jsx +++ b/frontend/src/pages/EventChatPage.jsx @@ -1,5 +1,6 @@ import { useState, useRef, useEffect } from 'react'; import { useParams, useNavigate, useSearchParams, Link } from 'react-router-dom'; +import toast from 'react-hot-toast'; import Layout from '../components/layout/Layout'; import { useAuth } from '../contexts/AuthContext'; import { Send, UserPlus, Loader2, LogOut, AlertTriangle, QrCode, Edit2, Filter, X, MessageSquare, Users, Video } from 'lucide-react'; @@ -201,7 +202,7 @@ const EventChatPage = () => { const result = await matchesAPI.createMatch(userId, slug); // Show success message - alert(`Match request sent successfully! The user will be notified.`); + toast.success('Match request sent successfully! The user will be notified.'); // Optional: Navigate to matches page or refresh matches list // For now, we just show a success message @@ -210,13 +211,13 @@ const EventChatPage = () => { // Show appropriate error message if (error.status === 400 && error.message.includes('already exists')) { - alert('You already have a match request with this user.'); + toast.error('You already have a match request with this user.'); } else if (error.status === 403) { - alert('You must be a participant of this event to send match requests.'); + toast.error('You must be a participant of this event to send match requests.'); } else if (error.status === 404) { - alert('Event not found.'); + toast.error('Event not found.'); } else { - alert('Failed to send match request. Please try again.'); + toast.error('Failed to send match request. Please try again.'); } } }; @@ -298,7 +299,7 @@ const EventChatPage = () => { navigate('/events'); } catch (error) { console.error('Failed to leave event:', error); - alert('Failed to leave event. Please try again.'); + toast.error('Failed to leave event. Please try again.'); } finally { setIsLeaving(false); setShowLeaveModal(false); diff --git a/frontend/src/pages/MatchChatPage.jsx b/frontend/src/pages/MatchChatPage.jsx index 4f11c89..41d5142 100644 --- a/frontend/src/pages/MatchChatPage.jsx +++ b/frontend/src/pages/MatchChatPage.jsx @@ -1,5 +1,6 @@ import { useState, useRef, useEffect } from 'react'; import { useParams, useNavigate, Link } from 'react-router-dom'; +import toast from 'react-hot-toast'; import Layout from '../components/layout/Layout'; import { useAuth } from '../contexts/AuthContext'; import { matchesAPI } from '../services/api'; @@ -73,7 +74,7 @@ const MatchChatPage = () => { setMatch(result.data); } catch (error) { console.error('Failed to load match:', error); - alert('Failed to load match. Redirecting to matches page.'); + toast.error('Failed to load match. Redirecting to matches page.'); navigate('/matches'); } finally { setLoading(false); @@ -97,7 +98,7 @@ const MatchChatPage = () => { if (file && file.type.startsWith('video/')) { setSelectedFile(file); } else { - alert('Please select a video file'); + toast.error('Please select a video file'); } }; @@ -128,7 +129,7 @@ const MatchChatPage = () => { try { await waitForConnection; } catch (error) { - alert('Failed to establish connection: ' + error.message); + toast.error('Failed to establish connection: ' + error.message); return; } } diff --git a/frontend/src/pages/MatchesPage.jsx b/frontend/src/pages/MatchesPage.jsx index 50de404..25d1033 100644 --- a/frontend/src/pages/MatchesPage.jsx +++ b/frontend/src/pages/MatchesPage.jsx @@ -1,5 +1,6 @@ import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; +import toast from 'react-hot-toast'; import Layout from '../components/layout/Layout'; import { useAuth } from '../contexts/AuthContext'; import { matchesAPI } from '../services/api'; @@ -80,10 +81,10 @@ const MatchesPage = () => { await loadMatches(); // Show success message - alert('Match accepted! You can now chat with your partner.'); + toast.success('Match accepted! You can now chat with your partner.'); } catch (error) { console.error('Failed to accept match:', error); - alert('Failed to accept match. Please try again.'); + toast.error('Failed to accept match. Please try again.'); } finally { setProcessingMatchId(null); } @@ -102,7 +103,7 @@ const MatchesPage = () => { setMatches(prev => prev.filter(m => m.slug !== matchSlug)); } catch (error) { console.error('Failed to reject match:', error); - alert('Failed to reject match. Please try again.'); + toast.error('Failed to reject match. Please try again.'); } finally { setProcessingMatchId(null); } diff --git a/frontend/src/pages/RatePartnerPage.jsx b/frontend/src/pages/RatePartnerPage.jsx index 73a5136..b818cfd 100644 --- a/frontend/src/pages/RatePartnerPage.jsx +++ b/frontend/src/pages/RatePartnerPage.jsx @@ -1,5 +1,6 @@ import { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; +import toast from 'react-hot-toast'; import Layout from '../components/layout/Layout'; import { matchesAPI } from '../services/api'; import { Star, Loader2 } from 'lucide-react'; @@ -26,20 +27,20 @@ const RatePartnerPage = () => { // Check if this match can be rated if (result.data.status !== MATCH_STATUS.ACCEPTED && result.data.status !== MATCH_STATUS.COMPLETED) { - alert('This match must be accepted before rating.'); + toast.error('This match must be accepted before rating.'); navigate('/matches'); return; } // Check if user has already rated this match if (result.data.hasRated) { - alert('You have already rated this match.'); + toast.info('You have already rated this match.'); navigate('/matches'); return; } } catch (error) { console.error('Failed to load match:', error); - alert('Failed to load match. Redirecting to matches page.'); + toast.error('Failed to load match. Redirecting to matches page.'); navigate('/matches'); } finally { setLoading(false); @@ -53,7 +54,7 @@ const RatePartnerPage = () => { const handleSubmit = async (e) => { e.preventDefault(); if (rating === 0) { - alert('Please select a rating (1-5 stars)'); + toast.warning('Please select a rating (1-5 stars)'); return; } @@ -66,14 +67,14 @@ const RatePartnerPage = () => { wouldCollaborateAgain, }); - alert('Rating submitted successfully!'); + toast.success('Rating submitted successfully!'); navigate('/matches'); } catch (error) { console.error('Failed to submit rating:', error); if (error.message?.includes('already rated')) { - alert('You have already rated this match.'); + toast.error('You have already rated this match.'); } else { - alert('Failed to submit rating. Please try again.'); + toast.error('Failed to submit rating. Please try again.'); } } finally { setSubmitting(false); diff --git a/frontend/src/pages/VerifyEmailPage.jsx b/frontend/src/pages/VerifyEmailPage.jsx index 567247b..1b10e5a 100644 --- a/frontend/src/pages/VerifyEmailPage.jsx +++ b/frontend/src/pages/VerifyEmailPage.jsx @@ -1,5 +1,6 @@ import { useState, useEffect } from 'react'; import { useNavigate, useSearchParams, Link } from 'react-router-dom'; +import toast from 'react-hot-toast'; import { authAPI } from '../services/api'; import { useAuth } from '../contexts/AuthContext'; import { Video, Mail, CheckCircle, XCircle, Loader2, ArrowRight } from 'lucide-react'; @@ -91,7 +92,7 @@ const VerifyEmailPage = () => { try { await authAPI.resendVerification(email); - alert('Verification email sent! Please check your inbox.'); + toast.success('Verification email sent! Please check your inbox.'); } catch (err) { setError(err.data?.error || 'Failed to resend verification email'); } finally {