diff --git a/backend/app/controllers/comment.controller.js b/backend/app/controllers/comment.controller.js index 45b30c3..8ff3064 100644 --- a/backend/app/controllers/comment.controller.js +++ b/backend/app/controllers/comment.controller.js @@ -17,10 +17,30 @@ export async function upload(req, res) { logger.action("try to post comment"); const client = await getClient(); - const query = `INSERT INTO comments (content, author, video, created_at) VALUES ($1, $2, $3, $4)`; - await client.query(query, [comment.content, comment.author, comment.video, comment.createdAt]); + const query = `INSERT INTO comments (content, author, video, created_at) VALUES ($1, $2, $3, $4) RETURNING id, created_at`; + const result = await client.query(query, [comment.content, comment.author, comment.video, comment.createdAt]); logger.write("successfully post comment", 200); - res.status(200).send("successfully post comment"); + + const createdAt = result.rows[0].created_at; + comment.id = result.rows[0].id; + + // Send back the comment + // Get the author's name and profile picture + const authorQuery = `SELECT username, picture FROM users WHERE id = $1`; + const authorResult = await client.query(authorQuery, [comment.author]); + const author = authorResult.rows[0]; + + const responseComment = { + id: comment.id, + content: comment.content, + video: comment.video, + username: author.username, + picture: author.picture, + createdAt: createdAt + } + + + res.status(200).json(responseComment); } diff --git a/backend/logs/access.log b/backend/logs/access.log index c7d1053..0863867 100644 --- a/backend/logs/access.log +++ b/backend/logs/access.log @@ -831,49 +831,4 @@ [2025-07-19 23:05:34.319] [undefined] GET(/:id/similar): successfully retrieved similar videos for video 3 with status 200 [2025-07-19 23:05:34.328] [undefined] GET(/:id/views): try to add views for video 3 [2025-07-19 23:05:34.333] [undefined] GET(/:id/views): successfully added views for video 3 with status 200 -[2025-07-20 08:47:03.500] [undefined] GET(/:id): try to get video 3 -[2025-07-20 08:47:03.511] [undefined] GET(/:id): successfully get video 3 with status 200 -[2025-07-20 08:47:03.524] [undefined] GET(/:id/similar): try to get similar videos for video 3 -[2025-07-20 08:47:03.535] [undefined] GET(/:id/similar): successfully retrieved similar videos for video 3 with status 200 -[2025-07-20 08:47:03.553] [undefined] GET(/:id/views): try to add views for video 3 -[2025-07-20 08:47:03.561] [undefined] GET(/:id/views): successfully added views for video 3 with status 200 -[2025-07-20 08:47:07.593] [undefined] GET(/:id): try to get video 3 -[2025-07-20 08:47:07.601] [undefined] GET(/:id): successfully get video 3 with status 200 -[2025-07-20 08:47:07.616] [undefined] GET(/:id/similar): try to get similar videos for video 3 -[2025-07-20 08:47:07.626] [undefined] GET(/:id/similar): successfully retrieved similar videos for video 3 with status 200 -[2025-07-20 08:47:07.670] [undefined] GET(/:id/views): try to add views for video 3 -[2025-07-20 08:47:07.679] [undefined] GET(/:id/views): successfully added views for video 3 with status 200 -[2025-07-20 08:47:09.941] [undefined] POST(/:id/subscribe): try to toggle subscription for channel with id 2 -[2025-07-20 08:47:09.947] [undefined] POST(/:id/subscribe): Successfully unsubscribed from channel with status 200 -[2025-07-20 08:51:41.655] [undefined] GET(/:id): try to get video 3 -[2025-07-20 08:51:41.668] [undefined] GET(/:id): successfully get video 3 with status 200 -[2025-07-20 08:51:41.681] [undefined] GET(/:id/similar): try to get similar videos for video 3 -[2025-07-20 08:51:41.695] [undefined] GET(/:id/similar): successfully retrieved similar videos for video 3 with status 200 -[2025-07-20 08:51:41.737] [undefined] GET(/:id/views): try to add views for video 3 -[2025-07-20 08:51:41.747] [undefined] GET(/:id/views): successfully added views for video 3 with status 200 -[2025-07-20 08:51:45.125] [undefined] POST(/:id/subscribe): try to toggle subscription for channel with id 2 -[2025-07-20 08:51:45.132] [undefined] POST(/:id/subscribe): Successfully subscribed to channel with status 200 -[2025-07-20 08:51:46.253] [undefined] POST(/:id/subscribe): try to toggle subscription for channel with id 2 -[2025-07-20 08:51:46.260] [undefined] POST(/:id/subscribe): Successfully unsubscribed from channel with status 200 -[2025-07-20 08:51:47.141] [undefined] POST(/:id/subscribe): try to toggle subscription for channel with id 2 -[2025-07-20 08:51:47.147] [undefined] POST(/:id/subscribe): Successfully subscribed to channel with status 200 -[2025-07-20 08:54:06.806] [undefined] GET(/:id): try to get video 3 -[2025-07-20 08:54:06.817] [undefined] GET(/:id): successfully get video 3 with status 200 -[2025-07-20 08:54:06.833] [undefined] GET(/:id/similar): try to get similar videos for video 3 -[2025-07-20 08:54:06.845] [undefined] GET(/:id/similar): successfully retrieved similar videos for video 3 with status 200 -[2025-07-20 08:54:06.897] [undefined] GET(/:id/views): try to add views for video 3 -[2025-07-20 08:54:06.906] [undefined] GET(/:id/views): successfully added views for video 3 with status 200 -[2025-07-20 08:54:09.393] [undefined] GET(/:id/like): try to toggle like on video 3 -[2025-07-20 08:54:09.399] [undefined] GET(/:id/like): likes found, removing like for video 3 with status 200 -[2025-07-20 08:54:59.934] [undefined] GET(/:id): try to get video 3 -[2025-07-20 08:54:59.942] [undefined] GET(/:id): successfully get video 3 with status 200 -[2025-07-20 08:54:59.953] [undefined] GET(/:id/similar): try to get similar videos for video 3 -[2025-07-20 08:54:59.964] [undefined] GET(/:id/similar): successfully retrieved similar videos for video 3 with status 200 -[2025-07-20 08:54:59.995] [undefined] GET(/:id/views): try to add views for video 3 -[2025-07-20 08:55:00.002] [undefined] GET(/:id/views): successfully added views for video 3 with status 200 -[2025-07-20 08:55:01.907] [undefined] GET(/:id/like): try to toggle like on video 3 -[2025-07-20 08:55:01.915] [undefined] GET(/:id/like): no likes found adding likes for video 3 with status 200 -[2025-07-20 08:55:02.619] [undefined] GET(/:id/like): try to toggle like on video 3 -[2025-07-20 08:55:02.625] [undefined] GET(/:id/like): likes found, removing like for video 3 with status 200 -[2025-07-20 08:55:03.148] [undefined] GET(/:id/like): try to toggle like on video 3 -[2025-07-20 08:55:03.155] [undefined] GET(/:id/like): no likes found adding likes for video 3 with status 200 + diff --git a/frontend/src/components/Comment.jsx b/frontend/src/components/Comment.jsx index 1c398f7..de6dc96 100644 --- a/frontend/src/components/Comment.jsx +++ b/frontend/src/components/Comment.jsx @@ -2,7 +2,7 @@ import {useAuth} from "../contexts/AuthContext.jsx"; import {useRef, useState} from "react"; -export default function Comment({ comment, index, videoId }) { +export default function Comment({ comment, index, videoId, refetchVideo }) { let {user, isAuthenticated} = useAuth(); let commentRef = useRef(); @@ -15,15 +15,25 @@ export default function Comment({ comment, index, videoId }) { const commentElement = commentRef.current; commentElement.contentEditable = true; } + const handleDelete = async (id) => { - const token = localStorage.getItem('token'); - await fetch(`/api/comments/${id}`, { - method: 'DELETE', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${token}` + try { + const token = localStorage.getItem('token'); + const response = await fetch(`/api/comments/${id}`, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + } + }); + + if (response.ok) { + // Refresh the video data to update the comments list + refetchVideo(); } - }) + } catch (error) { + console.error('Error deleting comment:', error); + } } const handleEditSubmit = async (id, content) => { diff --git a/frontend/src/pages/Video.jsx b/frontend/src/pages/Video.jsx index 264f138..6f8e2d0 100644 --- a/frontend/src/pages/Video.jsx +++ b/frontend/src/pages/Video.jsx @@ -1,5 +1,5 @@ import {useNavigate, useParams} from "react-router-dom"; -import {useEffect, useState, useRef} from "react"; +import {useEffect, useState, useRef, useCallback} from "react"; import Navbar from "../components/Navbar.jsx"; import { useAuth } from "../contexts/AuthContext.jsx"; import Comment from "../components/Comment.jsx"; @@ -22,51 +22,69 @@ export default function Video() { const [showControls, setShowControls] = useState(false); const [comment, setComment] = useState(""); - useEffect(() => { - const fetchVideo = async () => { - // Fetch video data and similar videos based on the video ID from the URL - try { - const response = await fetch(`/api/videos/${id}`); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - const videoData = await response.json(); - setVideo(videoData); - } catch (error) { - console.error('Error fetching video:', error); + const fetchVideo = useCallback(async () => { + // Fetch video data and similar videos based on the video ID from the URL + try { + const response = await fetch(`/api/videos/${id}`); + if (!response.ok) { + throw new Error('Network response was not ok'); } - try { - const response = await fetch(`/api/videos/${id}/similar`); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - const similarVideosData = await response.json(); - setSimilarVideos(similarVideosData); - } catch (error) { - console.error('Error fetching similar videos:', error); + const videoData = await response.json(); + setVideo(videoData); + } catch (error) { + console.error('Error fetching video:', error); + } + try { + const response = await fetch(`/api/videos/${id}/similar`); + if (!response.ok) { + throw new Error('Network response was not ok'); } + const similarVideosData = await response.json(); + setSimilarVideos(similarVideosData); + } catch (error) { + console.error('Error fetching similar videos:', error); + } - // Add views to the video - try { - const token = localStorage.getItem('token'); - if (!token) { - navigation('/login'); - return; + // Add views to the video + try { + const token = localStorage.getItem('token'); + if (!token) { + navigation('/login'); + return; + } + await fetch(`/api/videos/${id}/views`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` } - await fetch(`/api/videos/${id}/views`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${token}` - } - }); - } catch (error) { - console.error('Error adding views:', error); + }); + } catch (error) { + console.error('Error adding views:', error); + } + }, [id, navigation]); + + const fetchComments = useCallback(async () => { + // Fetch comments for the video + try { + const response = await fetch(`/api/comments/video/${id}`); + if (!response.ok) { + throw new Error('Network response was not ok'); } + const commentsData = await response.json(); + setVideo((prevVideo) => ({ + ...prevVideo, + comments: commentsData + })); + } catch (error) { + console.error('Error fetching comments:', error); } - fetchVideo(); }, [id]); + useEffect(() => { + fetchVideo(); + }, [fetchVideo]); + const handlePlayPause = () => { if (videoRef.current) { if (videoRef.current.paused) { @@ -278,6 +296,12 @@ export default function Video() { console.log('Comment posted successfully:', data); setComment(""); // Clear the comment input + setVideo((prevVideo) => ({ + ...prevVideo, + comments: [...(prevVideo.comments || []), data] // Add the new comment to the existing comments + })); + + } catch (error) { console.error('Error posting comment:', error); } @@ -405,7 +429,7 @@ export default function Video() {
Aucun commentaire pour le moment. Soyez le premier à en publier !