224 lines
6.8 KiB
JavaScript
224 lines
6.8 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { participantAPI } from '../services/api.service';
|
|
|
|
const EventComments = ({ eventId, onScoreUpdate }) => {
|
|
const [comments, setComments] = useState([]);
|
|
const [commentText, setCommentText] = useState('');
|
|
const [loading, setLoading] = useState(false);
|
|
const [showCongratsModal, setShowCongratsModal] = useState(false);
|
|
const [congratsData, setCongratsData] = useState(null);
|
|
|
|
useEffect(() => {
|
|
loadComments();
|
|
}, [eventId]);
|
|
|
|
const loadComments = async () => {
|
|
try {
|
|
const response = await participantAPI.getEventComments(eventId);
|
|
setComments(response.data.data);
|
|
} catch (err) {
|
|
console.error('Failed to load comments:', err);
|
|
}
|
|
};
|
|
|
|
const handleSubmit = async (e) => {
|
|
e.preventDefault();
|
|
if (!commentText.trim() || loading) return;
|
|
|
|
setLoading(true);
|
|
try {
|
|
const response = await participantAPI.addEventComment(eventId, commentText);
|
|
|
|
// Add comment to list
|
|
setComments([response.data.data.comment, ...comments]);
|
|
setCommentText('');
|
|
|
|
// Check if jackpot was discovered
|
|
if (response.data.data.jackpotDiscovered) {
|
|
setCongratsData({
|
|
message: response.data.data.congratsMessage,
|
|
bonusPoints: response.data.data.bonusPoints,
|
|
xssType: response.data.data.xssType // Track if this is XSS discovery
|
|
});
|
|
setShowCongratsModal(true);
|
|
}
|
|
|
|
// Notify parent of score update
|
|
if (onScoreUpdate && response.data.data.totalScore !== undefined) {
|
|
onScoreUpdate(response.data.data.totalScore);
|
|
}
|
|
} catch (err) {
|
|
console.error('Failed to add comment:', err);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const closeCongratsModal = () => {
|
|
setShowCongratsModal(false);
|
|
setCongratsData(null);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<div className="card" style={{ marginBottom: '2rem' }}>
|
|
<h3 style={{ marginBottom: '0.5rem' }}>Feedback</h3>
|
|
<p style={{ fontSize: '0.875rem', color: '#6b7280', marginBottom: '1rem' }}>
|
|
Share your thoughts on the event
|
|
</p>
|
|
|
|
<form onSubmit={handleSubmit} style={{ marginBottom: '1.5rem' }}>
|
|
<textarea
|
|
value={commentText}
|
|
onChange={(e) => setCommentText(e.target.value)}
|
|
placeholder="Your feedback on this event..."
|
|
rows={3}
|
|
style={{
|
|
width: '100%',
|
|
padding: '0.75rem',
|
|
border: '1px solid #d1d5db',
|
|
borderRadius: '0.375rem',
|
|
fontSize: '0.875rem',
|
|
fontFamily: 'inherit',
|
|
marginBottom: '0.5rem',
|
|
resize: 'vertical'
|
|
}}
|
|
/>
|
|
<button
|
|
type="submit"
|
|
disabled={!commentText.trim() || loading}
|
|
style={{
|
|
padding: '0.5rem 1rem',
|
|
background: loading || !commentText.trim() ? '#9ca3af' : '#2563eb',
|
|
color: 'white',
|
|
border: 'none',
|
|
borderRadius: '0.375rem',
|
|
cursor: loading || !commentText.trim() ? 'not-allowed' : 'pointer',
|
|
fontWeight: '500'
|
|
}}
|
|
>
|
|
{loading ? 'Submitting...' : 'Submit Feedback'}
|
|
</button>
|
|
</form>
|
|
|
|
{comments.length > 0 && (
|
|
<div>
|
|
<div style={{
|
|
fontSize: '0.875rem',
|
|
fontWeight: '600',
|
|
color: '#374151',
|
|
marginBottom: '0.75rem'
|
|
}}>
|
|
Your Feedback ({comments.length})
|
|
</div>
|
|
<div style={{ maxHeight: '300px', overflowY: 'auto' }}>
|
|
{comments.map((comment) => (
|
|
<div
|
|
key={comment.id}
|
|
style={{
|
|
marginBottom: '0.75rem',
|
|
paddingBottom: '0.75rem',
|
|
borderBottom: '1px solid #e5e7eb'
|
|
}}
|
|
>
|
|
<div style={{
|
|
fontSize: '0.75rem',
|
|
color: '#6b7280',
|
|
marginBottom: '0.25rem'
|
|
}}>
|
|
{new Date(comment.created_at).toLocaleString()}
|
|
</div>
|
|
<div style={{
|
|
fontSize: '0.875rem',
|
|
whiteSpace: 'pre-wrap',
|
|
wordBreak: 'break-word'
|
|
}}>
|
|
{comment.content}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{comments.length === 0 && (
|
|
<div style={{
|
|
fontSize: '0.875rem',
|
|
color: '#9ca3af',
|
|
textAlign: 'center',
|
|
padding: '1rem'
|
|
}}>
|
|
No feedback yet
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Congratulations Modal */}
|
|
{showCongratsModal && congratsData && (
|
|
<div
|
|
style={{
|
|
position: 'fixed',
|
|
top: 0,
|
|
left: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
background: 'rgba(0, 0, 0, 0.8)',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
zIndex: 9999
|
|
}}
|
|
onClick={closeCongratsModal}
|
|
>
|
|
<div
|
|
style={{
|
|
background: 'white',
|
|
padding: '2rem',
|
|
borderRadius: '0.5rem',
|
|
maxWidth: '500px',
|
|
textAlign: 'center',
|
|
boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.3)'
|
|
}}
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<div style={{ fontSize: '3rem', marginBottom: '1rem' }}>
|
|
{congratsData.xssType ? '🎯' : '🎰'}
|
|
</div>
|
|
<h2 style={{ color: '#10b981', marginBottom: '1rem', fontSize: '1.875rem' }}>
|
|
{congratsData.xssType ? 'XSS Discovered!' : 'Jackpot!'}
|
|
</h2>
|
|
<p style={{ marginBottom: '1rem', color: '#374151', lineHeight: '1.6' }}>
|
|
{congratsData.message}
|
|
</p>
|
|
<div style={{
|
|
fontSize: '2rem',
|
|
fontWeight: 'bold',
|
|
color: '#2563eb',
|
|
marginBottom: '1.5rem'
|
|
}}>
|
|
+{congratsData.bonusPoints} Points
|
|
</div>
|
|
<button
|
|
onClick={closeCongratsModal}
|
|
style={{
|
|
padding: '0.75rem 2rem',
|
|
background: '#2563eb',
|
|
color: 'white',
|
|
border: 'none',
|
|
borderRadius: '0.375rem',
|
|
cursor: 'pointer',
|
|
fontWeight: '600',
|
|
fontSize: '1rem'
|
|
}}
|
|
>
|
|
Awesome!
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default EventComments;
|