From 975a523ff6817f342807d99a0ad031cd0d3bcaa7 Mon Sep 17 00:00:00 2001 From: Astri4-4 Date: Wed, 13 Aug 2025 09:15:49 +0000 Subject: [PATCH] FINISH alert system --- backend/app/controllers/search.controller.js | 127 +++--- backend/app/middlewares/channel.middleware.js | 4 +- backend/logs/access.log | 373 ++++++++++++++++++ checklist.md | 145 +++---- frontend/src/assets/svg/check.svg | 1 + frontend/src/assets/svg/plus.svg | 1 + frontend/src/components/Alert.jsx | 33 ++ frontend/src/components/AlertList.jsx | 17 + frontend/src/components/Navbar.jsx | 23 +- frontend/src/index.css | 14 + frontend/src/pages/Account.jsx | 24 +- frontend/src/pages/AddVideo.jsx | 32 +- frontend/src/pages/Home.jsx | 12 +- frontend/src/pages/Login.jsx | 25 +- frontend/src/pages/ManageChannel.jsx | 16 +- frontend/src/pages/ManageVideo.jsx | 29 +- frontend/src/pages/Register.jsx | 25 +- frontend/src/pages/Search.jsx | 16 +- frontend/src/pages/Video.jsx | 28 +- frontend/src/services/search.service.js | 5 +- nginx/default.conf | 18 + 21 files changed, 770 insertions(+), 198 deletions(-) create mode 100644 frontend/src/assets/svg/check.svg create mode 100644 frontend/src/assets/svg/plus.svg create mode 100644 frontend/src/components/Alert.jsx create mode 100644 frontend/src/components/AlertList.jsx diff --git a/backend/app/controllers/search.controller.js b/backend/app/controllers/search.controller.js index 55e4d77..1f94b80 100644 --- a/backend/app/controllers/search.controller.js +++ b/backend/app/controllers/search.controller.js @@ -5,8 +5,8 @@ export async function search(req, res) { console.log(req.query); const query = req.query.q; const type = req.query.type || 'all'; - const offset = req.query.offset || 0; - const limit = req.query.limit || 20; + const offset = parseInt(req.query.offset) || 0; + const limit = parseInt(req.query.limit) || 20; const client = await getClient(); @@ -15,71 +15,80 @@ export async function search(req, res) { } if (type === 'videos') { - // Search video in database based on the query, video title, tags and author - const videoNameQuery = `SELECT id FROM videos WHERE title ILIKE $1 OFFSET $3 LIMIT $2`; - const videoNameResult = await client.query(videoNameQuery, [`%${query}%`, limit, offset]); - - // Search video from tags - const tagQuery = `SELECT id FROM tags WHERE name ILIKE $1 OFFSET $3 LIMIT $2`; - const tagResult = await client.query(tagQuery, [`%${query}%`, limit, offset]); - const tags = tagResult.rows.map(tag => tag.name); - - for (const tag of tags) { - const videoTagQuery = `SELECT id FROM videos WHERE id IN (SELECT video FROM video_tags WHERE tag = (SELECT id FROM tags WHERE name = $1)) OFFSET $3 LIMIT $2`; - const videoTagResult = await client.query(videoTagQuery, [tag, limit, offset]); - videoNameResult.rows.push(...videoTagResult.rows); + let videoResults = []; + + // Search video in database based on the video title + const videoNameQuery = ` + SELECT + v.id, v.title, v.thumbnail, v.description as video_description, v.channel, v.visibility, v.file, v.slug, v.format, v.release_date, + c.id as channel_id, c.owner, c.description as channel_description, c.name, + u.picture as profilePicture, + COUNT(h.id) as views + FROM videos as v + JOIN public.channels c on v.channel = c.id + JOIN public.users u on c.owner = u.id + LEFT JOIN public.history h on h.video = v.id + WHERE v.title ILIKE $1 + GROUP BY v.id, v.title, v.thumbnail, v.description, v.channel, v.visibility, v.file, v.slug, v.format, v.release_date, + c.id, c.owner, c.description, c.name, u.picture + OFFSET $2 + LIMIT $3; + `; + + const videoNameResult = await client.query(videoNameQuery, [`%${query}%`, offset, limit]); + const videoNames = videoNameResult.rows; + + for (const video of videoNames) { + // Put all the creator's information in the creator sub-object + video.creator = { + name: video.name, + profilePicture: video.profilepicture, + description: video.channel_description + }; + // Remove the creator's information from the video object + delete video.name; + delete video.profilepicture; + delete video.channel_description; + + video.type = "video"; + videoResults.push(video); } - // Search video from author - const authorQuery = `SELECT videos.id FROM videos JOIN channels c ON videos.channel = c.id WHERE c.name ILIKE $1`; - const authorResult = await client.query(authorQuery, [`%${query}%`]); - - for (const author of authorResult.rows) { - if (!videoNameResult.rows.some(video => video.id === author.id)) { - videoNameResult.rows.push(author); - } - } - - const videos = []; - - for (let video of videoNameResult.rows) { - video = video.id; // Extracting the video ID - let videoDetails = {}; - - // Fetching video details - const videoDetailsQuery = `SELECT id, title, description, thumbnail, channel, release_date FROM videos WHERE id = $1`; - const videoDetailsResult = await client.query(videoDetailsQuery, [video]); - if (videoDetailsResult.rows.length === 0) { - continue; // Skip if no video details found - } - - videoDetails = videoDetailsResult.rows[0]; - // Setting the type - videoDetails.type = 'video'; - - // Fetching views and likes - const viewsQuery = `SELECT COUNT(*) AS view_count FROM history WHERE video = $1`; - const viewsResult = await client.query(viewsQuery, [video]); - videoDetails.views = viewsResult.rows[0].view_count; - - // GET CREATOR - const creatorQuery = `SELECT c.id, c.name, c.owner FROM channels c JOIN videos v ON c.id = v.channel WHERE v.id = $1`; - const creatorResult = await client.query(creatorQuery, [video]); - videoDetails.creator = creatorResult.rows[0]; - - // GET CREATOR PROFILE PICTURE - const profilePictureQuery = `SELECT picture FROM users WHERE id = $1`; - const profilePictureResult = await client.query(profilePictureQuery, [videoDetails.creator.owner]); - videoDetails.creator.profile_picture = profilePictureResult.rows[0].picture; - - videos.push(videoDetails); + client.end() + return res.status(200).json(videoResults); + + } else if (type === 'channel') { + let channelResults = []; + + // Search channel in database based on the channel name + const channelNameQuery = ` + SELECT c.id as channel_id, c.name, c.description as channel_description, c.owner, u.picture as profilePicture, COUNT(s.id) as subscribers + FROM public.channels c + JOIN public.users u on c.owner = u.id + LEFT JOIN public.subscriptions s ON s.channel = c.id + WHERE c.name ILIKE $1 + group by c.name, c.id, c.description, c.owner, u.picture + OFFSET $2 + LIMIT $3; + `; + + const channelNameResult = await client.query(channelNameQuery, [`%${query}%`, offset, limit]); + const channelNames = channelNameResult.rows; + + for (const channel of channelNames) { + channel.type = "channel"; + channel.profilePicture = channel.profilepicture; // Rename for consistency + delete channel.profilepicture; + channelResults.push(channel); } client.end() - return res.status(200).json(videos); + return res.status(200).json(channelResults); + } else { + return res.status(400).json({ message: "Invalid type parameter. Use 'videos' or 'channel'." }); } diff --git a/backend/app/middlewares/channel.middleware.js b/backend/app/middlewares/channel.middleware.js index 7336681..2293cdf 100644 --- a/backend/app/middlewares/channel.middleware.js +++ b/backend/app/middlewares/channel.middleware.js @@ -7,7 +7,7 @@ export const Channel = { name: body("name").notEmpty().isAlphanumeric("fr-FR", { ignore: " _-" }).trim(), - description: body("description").optional({values: "falsy"}).isAlphanumeric().trim(), + description: body("description").optional({values: "falsy"}).isLength({ max: 500 }).trim(), owner: body("owner").notEmpty().isNumeric().trim().withMessage("bad owner"), } @@ -15,7 +15,7 @@ export const ChannelCreate = { name: body("name").notEmpty().isAlphanumeric("fr-FR", { ignore: " _-" }).trim(), - description: body("description").optional({values: "falsy"}).isAlphanumeric().trim(), + description: body("description").optional({values: "falsy"}).isLength({ max: 500 }).trim(), owner: body("owner").notEmpty().isNumeric().trim(), } diff --git a/backend/logs/access.log b/backend/logs/access.log index cd06a78..c2a14a4 100644 --- a/backend/logs/access.log +++ b/backend/logs/access.log @@ -3823,3 +3823,376 @@ [2025-07-26 09:05:11.448] [undefined] GET(/:id/similar): No tags found for video 8 with status 404 [2025-07-26 09:05:11.474] [undefined] GET(/:id/views): try to add views for video 8 [2025-07-26 09:05:11.481] [undefined] GET(/:id/views): successfully added views for video 8 with status 200 +[2025-08-11 11:11:21.571] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-11 11:11:21.575] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-11 11:11:21.577] [undefined] GET(/:id/history): failed to retrieve history of user 2 because it doesn't exist with status 404 +[2025-08-11 11:11:21.580] [undefined] GET(/:id/channel): failed to retrieve channel of user 2 because it doesn't exist with status 404 +[2025-08-11 11:11:21.589] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-11 11:11:37.891] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-11 11:11:37.893] [undefined] GET(/:id/channel): failed to retrieve channel of user 2 because it doesn't exist with status 404 +[2025-08-11 11:11:37.896] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-11 11:11:37.898] [undefined] GET(/:id/history): failed to retrieve history of user 2 because it doesn't exist with status 404 +[2025-08-11 11:11:37.904] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-11 11:11:47.642] [undefined] POST(/): try to create new channel with owner 2 and name astria +[2025-08-11 11:11:47.644] [undefined] POST(/): Successfully created new channel with name astria with status 200 +[2025-08-11 11:11:51.909] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-11 11:11:51.912] [undefined] GET(/:id/history): failed to retrieve history of user 2 because it doesn't exist with status 404 +[2025-08-11 11:11:51.914] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-11 11:11:51.916] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-11 11:11:51.922] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-11 11:11:53.197] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-11 11:11:53.206] [undefined] GET(/:id/stats): try to get stats +[2025-08-11 11:11:53.209] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-11 11:11:53.216] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-11 11:12:01.877] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-11 11:12:01.880] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-11 11:12:45.598] [undefined] POST(/): failed due to invalid values with status 400 +[2025-08-11 11:12:56.047] [undefined] POST(/): failed due to invalid values with status 400 +[2025-08-11 11:13:02.078] [undefined] POST(/): failed due to invalid values with status 400 +[2025-08-11 11:14:01.356] [undefined] POST(/): try to upload video with status undefined +[2025-08-11 11:14:01.359] [undefined] POST(/): successfully uploaded video with status 200 +[2025-08-11 11:14:01.426] [undefined] POST(/thumbnail): try to add thumbnail to video 1 +[2025-08-11 11:14:01.428] [undefined] POST(/thumbnail): successfully uploaded thumbnail with status 200 +[2025-08-11 11:14:01.449] [undefined] PUT(/:id/tags): try to add tags to video 1 +[2025-08-11 11:14:01.464] [undefined] PUT(/:id/tags): successfully added tags to video 1 with status 200 +[2025-08-11 11:14:08.592] [undefined] GET(/:id): try to get video 1 +[2025-08-11 11:14:08.601] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-11 11:14:08.612] [undefined] GET(/:id/similar): try to get similar videos for video 1 +[2025-08-11 11:14:08.623] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200 +[2025-08-11 11:14:08.687] [undefined] GET(/:id/views): try to add views for video 1 +[2025-08-11 11:14:08.695] [undefined] GET(/:id/views): successfully added views for video 1 with status 200 +[2025-08-11 13:18:23.053] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-11 13:18:23.055] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-11 13:18:23.065] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-11 13:18:23.069] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-11 13:18:23.076] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-11 13:18:25.052] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-11 13:18:25.061] [undefined] GET(/:id/stats): try to get stats +[2025-08-11 13:18:25.063] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-11 13:18:25.072] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-11 13:18:25.688] [undefined] GET(/:id): try to get video 1 +[2025-08-11 13:18:25.690] [undefined] GET(/:id/likes/day): try to get likes per day +[2025-08-11 13:18:25.699] [undefined] GET(/:id/likes/day): successfully retrieved likes per day with status 200 +[2025-08-11 13:18:25.703] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-11 13:18:31.902] [undefined] PUT(/:id): try to update video 1 +[2025-08-11 13:18:31.927] [undefined] PUT(/:id): successfully updated video with status 200 +[2025-08-11 13:41:12.278] [undefined] GET(/:id): failed due to invalid values with status 400 +[2025-08-11 13:41:12.282] [undefined] GET(/:id/stats): failed due to invalid values with status 400 +[2025-08-11 13:41:16.105] [undefined] GET(/:id): try to get video 1 +[2025-08-11 13:41:16.115] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-11 13:41:16.126] [undefined] GET(/:id/similar): try to get similar videos for video 1 +[2025-08-11 13:41:16.139] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200 +[2025-08-11 13:41:16.175] [undefined] GET(/:id/views): try to add views for video 1 +[2025-08-11 13:41:16.183] [undefined] GET(/:id/views): successfully added views for video 1 with status 200 +[2025-08-11 13:41:17.093] [undefined] POST(/:id/subscribe): try to toggle subscription for channel with id 1 +[2025-08-11 13:41:17.101] [undefined] POST(/:id/subscribe): Successfully subscribed to channel with status 200 +[2025-08-11 13:41:21.195] [undefined] GET(/:id): try to get video 1 +[2025-08-11 13:41:21.206] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-11 13:41:21.221] [undefined] GET(/:id/similar): try to get similar videos for video 1 +[2025-08-11 13:41:21.233] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200 +[2025-08-11 13:41:21.271] [undefined] GET(/:id/views): try to add views for video 1 +[2025-08-11 13:41:21.279] [undefined] GET(/:id/views): successfully added views for video 1 with status 200 +[2025-08-11 13:41:21.710] [undefined] GET(/:id): failed due to invalid values with status 400 +[2025-08-11 13:41:21.714] [undefined] GET(/:id/stats): failed due to invalid values with status 400 +[2025-08-11 13:45:04.724] [undefined] GET(/:id): failed due to invalid values with status 400 +[2025-08-11 13:45:04.730] [undefined] GET(/:id/similar): failed due to invalid values with status 400 +[2025-08-11 13:45:04.735] [undefined] GET(/:id/views): failed due to invalid values with status 400 +[2025-08-11 13:46:05.149] [undefined] GET(/:id): try to get video 1 +[2025-08-11 13:46:05.160] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-11 13:46:05.174] [undefined] GET(/:id/similar): try to get similar videos for video 1 +[2025-08-11 13:46:05.183] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200 +[2025-08-11 13:46:05.247] [undefined] GET(/:id/views): try to add views for video 1 +[2025-08-11 13:46:05.254] [undefined] GET(/:id/views): successfully added views for video 1 with status 200 +[2025-08-11 13:47:58.621] [undefined] GET(/:id): try to get video 1 +[2025-08-11 13:47:58.630] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-11 13:47:58.642] [undefined] GET(/:id/similar): try to get similar videos for video 1 +[2025-08-11 13:47:58.651] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200 +[2025-08-11 13:47:58.670] [undefined] GET(/:id/views): try to add views for video 1 +[2025-08-11 13:47:58.679] [undefined] GET(/:id/views): successfully added views for video 1 with status 200 +[2025-08-11 13:48:04.381] [undefined] GET(/:id/like): try to toggle like on video 1 +[2025-08-11 13:48:04.389] [undefined] GET(/:id/like): no likes found adding likes for video 1 with status 200 +[2025-08-11 13:48:05.683] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-11 13:48:05.685] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-11 13:48:05.687] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-11 13:48:05.691] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-11 13:48:05.697] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-11 13:48:07.023] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-11 13:48:07.032] [undefined] GET(/:id/stats): try to get stats +[2025-08-11 13:48:07.034] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-11 13:48:07.042] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-11 13:48:08.705] [undefined] GET(/:id/likes/day): try to get likes per day +[2025-08-11 13:48:08.707] [undefined] GET(/:id): try to get video 1 +[2025-08-11 13:48:08.716] [undefined] GET(/:id/likes/day): successfully retrieved likes per day with status 200 +[2025-08-11 13:48:08.720] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-11 13:48:15.706] [undefined] PUT(/:id/tags): try to add tags to video 1 +[2025-08-11 13:48:15.715] [undefined] PUT(/:id/tags): Tag minecraft already exists for video 1 with status 200 +[2025-08-11 13:48:15.718] [undefined] PUT(/:id/tags): Tag survie already exists for video 1 with status 200 +[2025-08-11 13:48:15.721] [undefined] PUT(/:id/tags): Tag moddée already exists for video 1 with status 200 +[2025-08-11 13:48:15.724] [undefined] PUT(/:id/tags): Tag create mod already exists for video 1 with status 200 +[2025-08-11 13:48:15.729] [undefined] PUT(/:id/tags): successfully added tags to video 1 with status 200 +[2025-08-11 13:48:18.023] [undefined] PUT(/:id/tags): try to add tags to video 1 +[2025-08-11 13:48:18.032] [undefined] PUT(/:id/tags): Tag minecraft already exists for video 1 with status 200 +[2025-08-11 13:48:18.035] [undefined] PUT(/:id/tags): Tag survie already exists for video 1 with status 200 +[2025-08-11 13:48:18.038] [undefined] PUT(/:id/tags): Tag moddée already exists for video 1 with status 200 +[2025-08-11 13:48:18.041] [undefined] PUT(/:id/tags): Tag create mod already exists for video 1 with status 200 +[2025-08-11 13:48:18.044] [undefined] PUT(/:id/tags): successfully added tags to video 1 with status 200 +[2025-08-11 13:48:27.781] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-11 13:48:27.783] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-11 13:48:27.786] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-11 13:48:27.789] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-11 13:48:27.796] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-11 13:53:54.947] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-11 13:53:54.949] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-11 13:53:54.951] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-11 13:53:54.953] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-11 13:53:54.961] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-11 13:56:27.148] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-11 13:56:27.151] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-11 13:56:27.153] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-11 13:56:27.156] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-11 13:56:27.162] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-12 08:01:10.302] [undefined] GET(/:id): try to get video 1 +[2025-08-12 08:01:10.312] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-12 08:01:10.324] [undefined] GET(/:id/similar): try to get similar videos for video 1 +[2025-08-12 08:01:10.334] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200 +[2025-08-12 08:01:10.356] [undefined] GET(/:id/views): try to add views for video 1 +[2025-08-12 08:01:10.366] [undefined] GET(/:id/views): successfully added views for video 1 with status 200 +[2025-08-12 08:02:05.673] [undefined] GET(/:id/stats): failed due to invalid values with status 400 +[2025-08-12 08:02:05.677] [undefined] GET(/:id): failed due to invalid values with status 400 +[2025-08-12 09:58:17.398] [undefined] GET(/:id): try to get video 1 +[2025-08-12 09:58:17.407] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-12 09:58:17.420] [undefined] GET(/:id/similar): try to get similar videos for video 1 +[2025-08-12 09:58:17.431] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200 +[2025-08-12 09:58:17.492] [undefined] GET(/:id/views): try to add views for video 1 +[2025-08-12 09:58:17.499] [undefined] GET(/:id/views): successfully added views for video 1 with status 200 +[2025-08-12 15:37:24.916] [undefined] POST(/login): try to login with username 'astria' +[2025-08-12 15:37:24.969] [undefined] POST(/login): Successfully logged in with status 200 +[2025-08-12 16:06:07.030] [undefined] POST(/login): failed due to invalid values with status 400 +[2025-08-12 16:06:20.090] [undefined] POST(/login): try to login with username 'astria' +[2025-08-12 16:06:20.140] [undefined] POST(/login): Successfully logged in with status 200 +[2025-08-13 07:54:19.889] [undefined] GET(/:id/channel): try to retrieve channel of user 1 +[2025-08-13 07:54:19.892] [undefined] GET(/:id/channel): failed to retrieve channel of user 1 because it doesn't exist with status 404 +[2025-08-13 07:54:19.896] [undefined] GET(/:id/history): try to retrieve history of user 1 +[2025-08-13 07:54:19.899] [undefined] GET(/:id/history): failed to retrieve history of user 1 because it doesn't exist with status 404 +[2025-08-13 07:54:19.907] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200 +[2025-08-13 07:55:50.168] [undefined] GET(/:id/channel): try to retrieve channel of user 1 +[2025-08-13 07:55:50.171] [undefined] GET(/:id/channel): failed to retrieve channel of user 1 because it doesn't exist with status 404 +[2025-08-13 07:55:50.173] [undefined] GET(/:id/history): try to retrieve history of user 1 +[2025-08-13 07:55:50.176] [undefined] GET(/:id/history): failed to retrieve history of user 1 because it doesn't exist with status 404 +[2025-08-13 07:55:50.183] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200 +[2025-08-13 07:58:02.863] [undefined] GET(/:id): try to get video 1 +[2025-08-13 07:58:02.874] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-13 07:58:02.886] [undefined] GET(/:id/similar): try to get similar videos for video 1 +[2025-08-13 07:58:02.895] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200 +[2025-08-13 07:58:02.914] [undefined] GET(/:id/views): try to add views for video 1 +[2025-08-13 07:58:02.926] [undefined] GET(/:id/views): successfully added views for video 1 with status 200 +[2025-08-13 07:58:07.598] [undefined] GET(/:id/channel): try to retrieve channel of user 1 +[2025-08-13 07:58:07.600] [undefined] GET(/:id/channel): failed to retrieve channel of user 1 because it doesn't exist with status 404 +[2025-08-13 07:58:07.609] [undefined] GET(/:id/history): try to retrieve history of user 1 +[2025-08-13 07:58:07.613] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200 +[2025-08-13 07:58:07.620] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200 +[2025-08-13 07:58:19.231] [undefined] GET(/:id/channel): try to retrieve channel of user 1 +[2025-08-13 07:58:19.234] [undefined] GET(/:id/history): try to retrieve history of user 1 +[2025-08-13 07:58:19.236] [undefined] GET(/:id/channel): failed to retrieve channel of user 1 because it doesn't exist with status 404 +[2025-08-13 07:58:19.238] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200 +[2025-08-13 07:58:19.247] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200 +[2025-08-13 07:58:26.874] [undefined] POST(/login): try to login with username 'sacha' +[2025-08-13 07:58:26.925] [undefined] POST(/login): Successfully logged in with status 200 +[2025-08-13 07:58:33.080] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 07:58:33.082] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-13 07:58:33.084] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 07:58:33.087] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-13 07:58:33.093] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-13 07:58:34.762] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 07:58:34.771] [undefined] GET(/:id/stats): try to get stats +[2025-08-13 07:58:34.773] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 07:58:34.781] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-13 08:01:18.744] [undefined] PUT(/:id): failed due to invalid values with status 400 +[2025-08-13 08:01:40.135] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 08:01:40.144] [undefined] GET(/:id/stats): try to get stats +[2025-08-13 08:01:40.147] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 08:01:40.154] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-13 08:01:45.190] [undefined] PUT(/:id): failed due to invalid values with status 400 +[2025-08-13 08:02:08.907] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 08:02:08.916] [undefined] GET(/:id/stats): try to get stats +[2025-08-13 08:02:08.919] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 08:02:08.927] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-13 08:02:14.295] [undefined] PUT(/:id): failed due to invalid values with status 400 +[2025-08-13 08:02:32.447] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 08:02:32.456] [undefined] GET(/:id/stats): try to get stats +[2025-08-13 08:02:32.459] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 08:02:32.467] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-13 08:02:37.213] [undefined] PUT(/:id): try to update channel with id 1 +[2025-08-13 08:02:37.223] [undefined] PUT(/:id): Successfully updated channel with status 200 +[2025-08-13 08:02:37.235] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 08:02:37.242] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 08:04:41.723] [undefined] GET(/:id): try to get video 1 +[2025-08-13 08:04:41.733] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-13 08:04:41.744] [undefined] GET(/:id/similar): try to get similar videos for video 1 +[2025-08-13 08:04:41.756] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200 +[2025-08-13 08:04:41.780] [undefined] GET(/:id/views): try to add views for video 1 +[2025-08-13 08:04:41.790] [undefined] GET(/:id/views): successfully added views for video 1 with status 200 +[2025-08-13 08:04:50.802] [undefined] POST(/): try to post comment +[2025-08-13 08:04:50.812] [undefined] POST(/): successfully post comment with status 200 +[2025-08-13 08:04:54.530] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:04:54.532] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:04:54.534] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-13 08:04:54.537] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-13 08:04:54.543] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-13 08:04:56.638] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 08:04:56.648] [undefined] GET(/:id/stats): try to get stats +[2025-08-13 08:04:56.650] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 08:04:56.659] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-13 08:04:58.247] [undefined] GET(/:id): try to get video 1 +[2025-08-13 08:04:58.250] [undefined] GET(/:id/likes/day): try to get likes per day +[2025-08-13 08:04:58.260] [undefined] GET(/:id/likes/day): successfully retrieved likes per day with status 200 +[2025-08-13 08:04:58.264] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-13 08:05:21.729] [undefined] GET(/:id): try to get video 1 +[2025-08-13 08:05:21.738] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-13 08:05:21.750] [undefined] GET(/:id/similar): try to get similar videos for video 1 +[2025-08-13 08:05:21.760] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200 +[2025-08-13 08:05:21.779] [undefined] GET(/:id/views): try to add views for video 1 +[2025-08-13 08:05:21.791] [undefined] GET(/:id/views): successfully added views for video 1 with status 200 +[2025-08-13 08:05:23.178] [undefined] DELETE(/:id): try to delete comment 1 +[2025-08-13 08:05:23.185] [undefined] DELETE(/:id): successfully deleted comment with status 200 +[2025-08-13 08:05:23.450] [undefined] GET(/:id): try to get video 1 +[2025-08-13 08:05:23.459] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-13 08:05:23.479] [undefined] GET(/:id/similar): try to get similar videos for video 1 +[2025-08-13 08:05:23.506] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200 +[2025-08-13 08:05:23.521] [undefined] GET(/:id/views): try to add views for video 1 +[2025-08-13 08:05:23.529] [undefined] GET(/:id/views): successfully added views for video 1 with status 200 +[2025-08-13 08:07:08.206] [undefined] GET(/:id): try to get video 1 +[2025-08-13 08:07:08.215] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-13 08:07:08.241] [undefined] GET(/:id/similar): try to get similar videos for video 1 +[2025-08-13 08:07:08.253] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200 +[2025-08-13 08:07:08.281] [undefined] GET(/:id/views): try to add views for video 1 +[2025-08-13 08:07:08.287] [undefined] GET(/:id/views): successfully added views for video 1 with status 200 +[2025-08-13 08:07:09.259] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:07:09.261] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:07:09.263] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-13 08:07:09.267] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-13 08:07:09.273] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-13 08:07:11.274] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 08:07:11.283] [undefined] GET(/:id/stats): try to get stats +[2025-08-13 08:07:11.287] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 08:07:11.294] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-13 08:07:14.428] [undefined] PUT(/:id): try to update channel with id 1 +[2025-08-13 08:07:14.438] [undefined] PUT(/:id): Successfully updated channel with status 200 +[2025-08-13 08:07:14.449] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 08:07:14.457] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 08:09:19.413] [undefined] PUT(/:id): try to update channel with id 1 +[2025-08-13 08:09:19.418] [undefined] PUT(/:id): Successfully updated channel with status 200 +[2025-08-13 08:09:19.432] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 08:09:19.441] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 08:13:02.276] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 08:13:02.284] [undefined] GET(/:id/stats): try to get stats +[2025-08-13 08:13:02.288] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 08:13:02.294] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-13 08:13:05.983] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:13:05.985] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-13 08:13:05.988] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:13:05.991] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-13 08:13:05.997] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-13 08:13:32.065] [undefined] PUT(/:id): try to update user 2 +[2025-08-13 08:13:32.067] [undefined] PUT(/:id): failed to update because username is already used with status 400 +[2025-08-13 08:13:43.652] [undefined] PUT(/:id): try to update user 2 +[2025-08-13 08:13:43.654] [undefined] PUT(/:id): failed to update because username is already used with status 400 +[2025-08-13 08:13:43.702] [undefined] PUT(/:id): failed to update profile picture with status 500 +[2025-08-13 08:15:55.326] [undefined] PUT(/:id): try to update user 2 +[2025-08-13 08:15:55.329] [undefined] PUT(/:id): failed to update because username is already used with status 400 +[2025-08-13 08:15:55.377] [undefined] PUT(/:id): failed to update profile picture with status 500 +[2025-08-13 08:16:22.726] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:16:22.729] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-13 08:16:22.733] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:16:22.739] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-13 08:16:22.750] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-13 08:17:26.321] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:17:26.324] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-13 08:17:26.327] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:17:26.330] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-13 08:17:26.341] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-13 08:17:53.837] [undefined] PUT(/:id): try to update user 2 +[2025-08-13 08:17:53.882] [undefined] PUT(/:id): successfully updated user 2 with status 200 +[2025-08-13 08:18:53.327] [undefined] POST(/login): try to login with username 'chien' +[2025-08-13 08:18:53.377] [undefined] POST(/login): Successfully logged in with status 200 +[2025-08-13 08:18:58.149] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:18:58.151] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:18:58.155] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-13 08:18:58.158] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-13 08:18:58.166] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-13 08:19:31.958] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:19:31.960] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:19:31.970] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-13 08:19:31.974] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-13 08:19:31.979] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-13 08:19:50.162] [undefined] PUT(/:id): try to update user 2 +[2025-08-13 08:19:50.205] [undefined] PUT(/:id): successfully updated user 2 with status 200 +[2025-08-13 08:20:21.321] [undefined] POST(/login): try to login with username 'chienne' +[2025-08-13 08:20:21.374] [undefined] POST(/login): Successfully logged in with status 200 +[2025-08-13 08:20:30.730] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:20:30.733] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:20:30.735] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-13 08:20:30.739] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-13 08:20:30.745] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-13 08:20:47.202] [undefined] PUT(/:id): try to update user 2 +[2025-08-13 08:20:47.247] [undefined] PUT(/:id): successfully updated user 2 with status 200 +[2025-08-13 08:20:57.402] [undefined] PUT(/:id): try to update user 2 +[2025-08-13 08:20:57.444] [undefined] PUT(/:id): successfully updated user 2 with status 200 +[2025-08-13 08:24:14.507] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 08:24:14.517] [undefined] GET(/:id/stats): try to get stats +[2025-08-13 08:24:14.519] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 08:24:14.527] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-13 08:24:18.228] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:24:18.230] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:26:51.461] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:26:51.464] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:27:19.201] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:27:19.204] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:27:19.206] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-13 08:27:19.209] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-13 08:27:19.217] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-13 08:32:59.197] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:32:59.199] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-13 08:32:59.201] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:32:59.203] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-13 08:32:59.209] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-13 08:33:01.805] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 08:33:01.826] [undefined] GET(/:id/stats): try to get stats +[2025-08-13 08:33:01.838] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 08:33:01.850] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-13 08:33:25.114] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:33:25.116] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-13 08:33:25.118] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:33:25.121] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-13 08:33:25.127] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-13 08:33:25.756] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 08:33:25.765] [undefined] GET(/:id/stats): try to get stats +[2025-08-13 08:33:25.767] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 08:33:25.776] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-13 08:34:28.854] [undefined] GET(/:id/likes/day): try to get likes per day +[2025-08-13 08:34:28.856] [undefined] GET(/:id): try to get video 1 +[2025-08-13 08:34:28.888] [undefined] GET(/:id/likes/day): successfully retrieved likes per day with status 200 +[2025-08-13 08:34:28.893] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-13 08:34:33.937] [undefined] GET(/:id/likes/day): try to get likes per day +[2025-08-13 08:34:33.939] [undefined] GET(/:id): try to get video 1 +[2025-08-13 08:34:33.950] [undefined] GET(/:id/likes/day): successfully retrieved likes per day with status 200 +[2025-08-13 08:34:33.954] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-13 08:34:42.356] [undefined] PUT(/:id): try to update video 1 +[2025-08-13 08:34:42.364] [undefined] PUT(/:id): successfully updated video with status 200 +[2025-08-13 08:35:02.613] [undefined] GET(/:id): try to get video 1 +[2025-08-13 08:35:02.616] [undefined] GET(/:id/likes/day): try to get likes per day +[2025-08-13 08:35:02.626] [undefined] GET(/:id/likes/day): successfully retrieved likes per day with status 200 +[2025-08-13 08:35:02.630] [undefined] GET(/:id): successfully get video 1 with status 200 +[2025-08-13 08:35:20.147] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:35:20.150] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 08:35:20.154] [undefined] GET(/:id/history): try to retrieve history of user 2 +[2025-08-13 08:35:20.158] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200 +[2025-08-13 08:35:20.164] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200 +[2025-08-13 08:35:20.898] [undefined] GET(/:id): try to get channel with id 1 +[2025-08-13 08:35:20.908] [undefined] GET(/:id/stats): try to get stats +[2025-08-13 08:35:20.912] [undefined] GET(/:id): Successfully get channel with id 1 with status 200 +[2025-08-13 08:35:20.917] [undefined] GET(/:id/stats): Successfully get stats with status 200 +[2025-08-13 08:35:26.515] [undefined] GET(/:id/channel): try to retrieve channel of user 2 +[2025-08-13 08:35:26.517] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200 +[2025-08-13 09:11:32.832] [undefined] POST(/login): try to login with username 'sacha' +[2025-08-13 09:11:32.881] [undefined] POST(/login): Successfully logged in with status 200 diff --git a/checklist.md b/checklist.md index 895dbd2..4c6f68a 100644 --- a/checklist.md +++ b/checklist.md @@ -22,122 +22,125 @@ ## **ADMINISTRATION CHAÎNE FREETUBE** (55 points) -### Mettre en ligne une vidéo (30 points) +### Mettre en ligne une vidéo (30 points) - 27/30 points ✅ - [x] Upload média vidéo (10 points) - [x] Upload miniature vidéo (2 points) - [x] Titre (2 points) - [x] Description (2 points) - [x] Date de mise en ligne automatique (2 points) - [ ] Mots-clefs/hashtags jusqu'à 10 (2 points) -- [ ] Visibilité publique/privée (5 points) -- [ ] Génération lien partageable (5 points) +- [x] Visibilité publique/privée (5 points) +- [x] Génération lien partageable (5 points) - via slug système -### Gestion vidéos existantes -- [ ] Éditer une vidéo existante (5 points) -- [ ] Changer la visibilité (5 points) +### Gestion vidéos existantes (15 points) - 10/15 points +- [x] Éditer une vidéo existante (5 points) +- [x] Changer la visibilité (5 points) - [x] Supprimer une vidéo (5 points) -### Statistiques -- [ ] Statistiques par vidéo (vues, likes, commentaires) (5 points) +### Statistiques (10 points) - 5/10 points +- [x] Statistiques par vidéo (vues, likes, commentaires) (5 points) - [ ] Statistiques globales de la chaîne (5 points) -## **PAGE ACCUEIL** (30 points) +## **RECHERCHE ET NAVIGATION** (20 points) ✅ -### Utilisateur authentifié (15 points) +### Système de recherche (20 points) - 20/20 points ✅ +- [x] Recherche par titre de vidéo (8 points) +- [x] Recherche par chaîne (8 points) +- [x] Interface de recherche fonctionnelle (4 points) + +## **PAGE ACCUEIL** (30 points) - 10/30 points + +### Utilisateur authentifié (15 points) - 5/15 points +- [x] Section Tendances (contenu avec plus d'interactions récentes) (5 points) - [ ] Section Recommendations (contenu similaire non vu) (5 points) - [ ] Section "À consulter plus tard" (5 points) -- [ ] Section Tendances (contenu avec plus d'interactions récentes) (5 points) -### Utilisateur non-authentifié (15 points) +### Utilisateur non-authentifié (15 points) - 5/15 points +- [x] Section Tendances (5 points) - [ ] Section Recommendations (3 mots-clefs les plus utilisés) (5 points) -- [ ] Section Tendances (5 points) - [ ] Section Top créateurs (plus d'abonnés) (5 points) ## **PAGE ABONNEMENTS** (10 points) - [ ] Fil d'actualité des abonnements (8 points) - [ ] Redirection pour non-authentifiés (2 points) -## **PAGE UTILISATEUR** (15 points) +## **PAGE UTILISATEUR** (15 points) - 5/15 points - [ ] Historique des vidéos regardées (10 points) -- [ ] Gestion et liste des playlists (5 points) +- [x] Gestion et liste des playlists (5 points) -## **PAGE PLAYLIST** (10 points) -- [ ] Affichage nom playlist et vidéos -- [ ] Tri par date d'ajout -- [ ] Navigation depuis page utilisateur +## **PAGE PLAYLIST** (10 points) - 8/10 points ✅ +- [x] Affichage nom playlist et vidéos (4 points) +- [x] Tri par date d'ajout (2 points) +- [x] Navigation depuis page utilisateur (2 points) +- [ ] Interface utilisateur complète (2 points) -## **PAGE VIDÉO** (50 points) +## **PAGE VIDÉO** (50 points) - 27/50 points -### Lecteur vidéo (20 points) +### Lecteur vidéo (20 points) - 10/20 points - [x] Média visualisable (10 points) - [ ] Bouton Pause (2 points) - [ ] Bouton Play (2 points) - [ ] Saut XX secondes en avant (3 points) - [ ] Saut XX secondes en arrière (3 points) -### Informations vidéo (20 points) +### Informations vidéo (20 points) - 12/20 points - [x] Titre de la vidéo (2 points) - [x] Description (2 points) - [x] Nom de la chaîne (2 points) +- [x] Compteur "J'aime" (2 points) +- [x] Compteur vues (2 points) +- [x] Bouton "J'aime" (2 points) - [ ] Compteur abonnés (2 points) -- [ ] Compteur "J'aime" (2 points) -- [ ] Bouton "J'aime" (5 points) -- [ ] Bouton "S'abonner" (5 points) +- [ ] Bouton "S'abonner" (6 points) ### Commentaires (10 points) ✅ - [x] Créer un commentaire (5 points) - [x] Voir les commentaires (5 points) ### Recommendations (5 points) -- [ ] Section recommendations/tendances selon authentification +- [ ] Section recommendations/tendances selon authentification (5 points) ## **FONCTIONNALITÉS SYSTÈME** +### Système de playlists (15 points) ✅ +- [x] Routes créer/gérer playlists (8 points) +- [x] Ajouter/retirer vidéos des playlists (4 points) +- [x] Playlist "À regarder plus tard" automatique (3 points) + +### Système "J'aime" (10 points) ✅ +- [x] Routes like/unlike vidéo (5 points) +- [x] Compteur de likes par vidéo (3 points) +- [x] Interface utilisateur (2 points) + ### Système d'abonnements (18 points estimés) -- [ ] Routes s'abonner/désabonner à une chaîne -- [ ] Modèle de données abonnements -- [ ] Compteur d'abonnés par chaîne - -### Système "J'aime" (10 points estimés) -- [ ] Routes aimer/ne plus aimer vidéo -- [ ] Modèle de données likes -- [ ] Mise à jour compteur likes - -### Gestion playlists (25 points estimés) -- [ ] Routes créer/supprimer playlists -- [ ] Ajout/suppression vidéos dans playlists -- [ ] Playlist "À consulter plus tard" par défaut -- [ ] Affichage contenu playlist - -### Historique utilisateur (10 points estimés) -- [ ] Enregistrement automatique vidéos regardées -- [ ] Routes consultation historique - -### Système recommandations (15 points estimés) -- [ ] Algorithme pour utilisateurs authentifiés -- [ ] Recommendations mots-clés pour non-authentifiés -- [ ] Calcul tendances (interactions récentes) - -### Compteurs et statistiques -- [ ] Compteur de vues par vidéo -- [ ] Mise à jour automatique lors du visionnage -- [ ] Statistiques complètes par vidéo et chaîne - -## **POINTS CRITIQUES POUR ÉVITER L'AJOURNEMENT** -- **Fonctionnalités : 120/200 points minimum** -- **Qualité code : 60/100 points minimum** -- **Documentation : 30/50 points minimum** -- **Déploiement : 30/50 points minimum** - -## **AMÉLIORATIONS TECHNIQUES** -- [ ] Validation robuste données d'entrée -- [ ] Gestion d'erreurs appropriée -- [ ] Middleware de sécurité complet -- [ ] Tests unitaires (fichiers présents à compléter) -- [ ] Architecture REST propre -- [ ] Optimisation performances base de données +- [ ] Routes s'abonner/désabonner à une chaîne (8 points) +- [ ] Modèle de données abonnements (5 points) +- [ ] Compteur d'abonnés par chaîne (5 points) + +### Système de tags/mots-clefs (8 points estimés) +- [ ] Modèle de données tags (3 points) +- [ ] Association vidéos-tags (3 points) +- [ ] Interface gestion tags (2 points) + +## **SÉCURITÉ ET MIDDLEWARE** ✅ +- [x] Middleware d'authentification JWT +- [x] Validation des données d'entrée +- [x] Gestion des erreurs +- [x] Upload sécurisé de fichiers +- [x] Logging des actions + +## **INFRASTRUCTURE** ✅ +- [x] Configuration Docker +- [x] Base de données PostgreSQL +- [x] Serveur de fichiers médias +- [x] Tests unitaires --- - -**Status actuel estimé : ~102/200 points fonctionnalités** -**Objectif prioritaire : Atteindre 120 points minimum** \ No newline at end of file +## **SCORE ESTIMÉ** +**Backend: ~127/183 points (69%)** +**Points prioritaires manquants:** +- OAuth2 (10 points) +- Système d'abonnements (18 points) +- Tags/mots-clefs (8 points) +- Statistiques globales chaîne (5 points) +- Contrôles lecteur vidéo (10 points) diff --git a/frontend/src/assets/svg/check.svg b/frontend/src/assets/svg/check.svg new file mode 100644 index 0000000..1a8e9b3 --- /dev/null +++ b/frontend/src/assets/svg/check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/assets/svg/plus.svg b/frontend/src/assets/svg/plus.svg new file mode 100644 index 0000000..e9def70 --- /dev/null +++ b/frontend/src/assets/svg/plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/components/Alert.jsx b/frontend/src/components/Alert.jsx new file mode 100644 index 0000000..255cdf0 --- /dev/null +++ b/frontend/src/components/Alert.jsx @@ -0,0 +1,33 @@ +import { useEffect } from 'react'; + +export default function Alert({ type, message, onClose }) { + const alertClass = `cursor-pointer flex items-center gap-4 p-4 rounded-md text-white transition-opacity duration-300 ${ type === "error" ? "glassmorphism-red" : "glassmorphism-green" } `; + + useEffect(() => { + const timer = setTimeout(() => { + onClose(); + }, 15000); // 15 seconds + + return () => clearTimeout(timer); + }, [onClose]); + + return ( +
+ + { + type === 'success' ? ( + + ) : ( + + ) + } + + {message} +
+ ); + +} \ No newline at end of file diff --git a/frontend/src/components/AlertList.jsx b/frontend/src/components/AlertList.jsx new file mode 100644 index 0000000..649ea90 --- /dev/null +++ b/frontend/src/components/AlertList.jsx @@ -0,0 +1,17 @@ +import Alert from "./Alert.jsx"; + + +export default function AlertList({ alerts, onCloseAlert }) { + return ( +
+ {alerts.map((alert, index) => ( + onCloseAlert(alert)} + /> + ))} +
+ ); +} \ No newline at end of file diff --git a/frontend/src/components/Navbar.jsx b/frontend/src/components/Navbar.jsx index e229da1..15aa707 100644 --- a/frontend/src/components/Navbar.jsx +++ b/frontend/src/components/Navbar.jsx @@ -1,10 +1,12 @@ import { useAuth } from '../contexts/AuthContext'; import React, { useState } from 'react'; import {useNavigate} from "react-router-dom"; +import AlertList from "./AlertList.jsx"; -export default function Navbar({ isSearchPage = false }) { +export default function Navbar({ isSearchPage = false, alerts = [], onCloseAlert = () => {} }) { const { user, logout, isAuthenticated } = useAuth(); const [searchQuery, setSearchQuery] = useState(''); + const [internalAlerts, setInternalAlerts] = useState([]); const navigate = useNavigate(); const handleLogout = () => { @@ -20,8 +22,24 @@ export default function Navbar({ isSearchPage = false }) { } } + const onCloseInternalAlert = (alertToRemove) => { + setInternalAlerts(internalAlerts.filter(alert => alert !== alertToRemove)); + } + + // Combine internal alerts with external alerts + const allAlerts = [...internalAlerts, ...alerts]; + + const handleCloseAlert = (alertToRemove) => { + // Check if it's an internal alert or external alert + if (internalAlerts.includes(alertToRemove)) { + onCloseInternalAlert(alertToRemove); + } else { + onCloseAlert(alertToRemove); + } + }; + return ( -