Browse Source

Finish playlist page

features/playlist
Astri4-4 4 months ago
parent
commit
a9c8af837d
  1. 58
      backend/app/controllers/playlist.controller.js
  2. 30
      backend/app/utils/database.js
  3. 779
      backend/logs/access.log
  4. 1
      frontend/src/assets/svg/trash.svg
  5. 1
      frontend/src/components/Navbar.jsx
  6. 2
      frontend/src/components/PlaylistCard.jsx
  7. 4
      frontend/src/components/TrendingVideos.jsx
  8. 40
      frontend/src/components/VideoCard.jsx
  9. 27
      frontend/src/modals/VerificationModal.jsx
  10. 12
      frontend/src/pages/Account.jsx
  11. 97
      frontend/src/pages/Playlist.jsx
  12. 61
      frontend/src/pages/Video.jsx
  13. 9
      frontend/src/routes/routes.jsx
  14. 83
      frontend/src/services/playlist.service.js

58
backend/app/controllers/playlist.controller.js

@ -83,7 +83,63 @@ export async function getById(req, res) {
const logger = req.body.logger;
const client = await getClient();
const query = `SELECT * FROM playlists WHERE id = $1`;
const query = `
SELECT
playlists.id,
playlists.name,
COALESCE(
JSON_AGG(
JSON_BUILD_OBJECT(
'id', video_data.id,
'title', video_data.title,
'thumbnail', video_data.thumbnail,
'video_description', video_data.description,
'channel', video_data.channel,
'visibility', video_data.visibility,
'file', video_data.file,
'slug', video_data.slug,
'format', video_data.format,
'release_date', video_data.release_date,
'channel_id', video_data.channel,
'owner', channels.owner,
'views', CAST(video_data.views AS TEXT),
'creator', JSON_BUILD_OBJECT(
'name', channels.name,
'profilePicture', users.picture,
'description', channels.description
),
'type', 'video'
)
) FILTER (WHERE video_data.id IS NOT NULL),
'[]'::json
) AS videos
FROM
playlists
LEFT JOIN playlist_elements ON playlists.id = playlist_elements.playlist
LEFT JOIN (
SELECT
videos.id,
videos.title,
videos.description,
videos.thumbnail,
videos.release_date,
videos.visibility,
videos.file,
videos.slug,
videos.format,
videos.channel,
COUNT(history.id) AS views
FROM videos
LEFT JOIN history ON history.video = videos.id
GROUP BY videos.id, videos.title, videos.description, videos.thumbnail, videos.release_date, videos.visibility, videos.file, videos.slug, videos.format, videos.channel
) video_data ON playlist_elements.video = video_data.id
LEFT JOIN channels ON video_data.channel = channels.id
LEFT JOIN users ON channels.owner = users.id
WHERE
playlists.id = $1
GROUP BY
playlists.id;
`;
try {
const result = await client.query(query, [id]);

30
backend/app/utils/database.js

@ -31,7 +31,7 @@ export async function initDb() {
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT NOT NULL,
owner INTEGER NOT NULL REFERENCES users(id)
owner INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE
)`
await client.query(query);
@ -40,7 +40,7 @@ export async function initDb() {
title VARCHAR(255) NOT NULL,
thumbnail VARCHAR(255) NOT NULL,
description TEXT NOT NULL,
channel INTEGER NOT NULL REFERENCES channels(id),
channel INTEGER NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
visibility VARCHAR(50) NOT NULL DEFAULT 'public',
file VARCHAR(255) NOT NULL,
slug VARCHAR(255) NOT NULL,
@ -53,16 +53,16 @@ export async function initDb() {
(
id SERIAL PRIMARY KEY,
content TEXT NOT NULL,
author INTEGER NOT NULL REFERENCES users(id),
video INTEGER NOT NULL REFERENCES videos(id),
author INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
video INTEGER NOT NULL REFERENCES videos(id) ON DELETE CASCADE,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
)`;
await client.query(query);
query = `CREATE TABLE IF NOT EXISTS likes (
id SERIAL PRIMARY KEY,
owner INTEGER NOT NULL REFERENCES users(id),
video INTEGER NOT NULL REFERENCES videos(id),
owner INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
video INTEGER NOT NULL REFERENCES videos(id) ON DELETE CASCADE,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);`;
await client.query(query);
@ -70,21 +70,21 @@ export async function initDb() {
query = `CREATE TABLE IF NOT EXISTS playlists (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
owner INTEGER NOT NULL REFERENCES users(id)
owner INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE
)`;
await client.query(query);
query = `CREATE TABLE IF NOT EXISTS playlist_elements (
id SERIAL PRIMARY KEY,
video INTEGER NOT NULL REFERENCES videos(id),
playlist INTEGER NOT NULL REFERENCES playlists(id)
video INTEGER NOT NULL REFERENCES videos(id) ON DELETE CASCADE,
playlist INTEGER NOT NULL REFERENCES playlists(id) ON DELETE CASCADE
)`;
await client.query(query);
query = `CREATE TABLE IF NOT EXISTS subscriptions (
id SERIAL PRIMARY KEY,
channel INTEGER NOT NULL REFERENCES channels(id),
owner INTEGER NOT NULL REFERENCES users(id)
channel INTEGER NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
owner INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE
)`;
await client.query(query);
@ -96,15 +96,15 @@ export async function initDb() {
await client.query(query);
query = `CREATE TABLE IF NOT EXISTS video_tags (
video INTEGER NOT NULL REFERENCES videos(id),
tag INTEGER NOT NULL REFERENCES tags(id)
video INTEGER NOT NULL REFERENCES videos(id) ON DELETE CASCADE,
tag INTEGER NOT NULL REFERENCES tags(id) ON DELETE CASCADE
)`
await client.query(query);
query = `CREATE TABLE IF NOT EXISTS history (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id),
video INTEGER NOT NULL REFERENCES videos(id),
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
video INTEGER NOT NULL REFERENCES videos(id) ON DELETE CASCADE,
viewed_at TIMESTAMP NOT NULL DEFAULT NOW()
)`;
await client.query(query);

779
backend/logs/access.log

@ -5654,3 +5654,782 @@
[2025-08-14 20:41:50.539] [undefined] GET(/:id/history): failed to retrieve history of user 6 because it doesn't exist with status 404
[2025-08-14 20:41:50.550] [undefined] GET(/user/:id): Playlists retrieved for user with id 6 with status 200
[2025-08-14 20:41:53.692] [undefined] POST(/): Playlist created with id 7 with status 200
[2025-08-15 07:15:46.354] [undefined] POST(/login): try to login with username 'sacha2'
[2025-08-15 07:15:46.413] [undefined] POST(/login): Successfully logged in with status 200
[2025-08-15 07:16:04.703] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 07:16:04.706] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 07:16:04.709] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 07:16:04.714] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 07:16:04.722] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:16:25.767] [undefined] POST(/): Playlist created with id 8 with status 200
[2025-08-15 07:16:26.987] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 07:16:26.989] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 07:16:26.991] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 07:16:26.995] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 07:16:27.006] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:17:15.294] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 07:17:15.298] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 07:17:15.322] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 07:17:15.327] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 07:17:15.333] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:17:22.303] [undefined] POST(/): Playlist created with id 9 with status 200
[2025-08-15 07:17:22.321] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:17:41.905] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 07:17:41.908] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 07:17:41.916] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 07:17:41.921] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 07:17:41.927] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:17:43.230] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 07:17:43.233] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 07:17:43.258] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 07:17:43.261] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 07:17:43.269] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:17:44.606] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 07:17:44.609] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 07:17:44.612] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 07:17:44.616] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 07:17:44.623] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:17:45.539] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 07:17:45.543] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 07:17:45.545] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 07:17:45.549] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 07:17:45.556] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:18:53.759] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:18:53.769] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:18:53.782] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:18:53.794] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:18:53.821] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:18:53.832] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:19:35.214] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:19:35.225] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:19:35.238] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:19:35.251] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:19:35.273] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:19:35.284] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:19:46.027] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:19:46.037] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:19:46.050] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:19:46.068] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:19:46.093] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:19:46.101] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:21:30.310] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:21:30.320] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:21:30.333] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:21:30.348] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:21:30.386] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:21:30.395] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:21:32.380] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:21:32.390] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:21:32.403] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:21:32.418] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:21:32.441] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:21:32.449] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:21:43.838] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:21:43.848] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:21:43.860] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:21:43.876] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:21:43.916] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:21:43.925] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:22:08.679] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:22:08.689] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:22:08.701] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:22:08.716] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:22:08.747] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:22:08.757] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:22:21.736] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:22:21.747] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:22:21.762] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:22:21.777] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:22:21.802] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:22:21.811] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:22:43.624] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:22:43.634] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:22:43.647] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:22:43.662] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:22:43.692] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:22:43.703] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:23:56.553] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:23:56.564] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:23:56.577] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:23:56.591] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:23:56.613] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:23:56.622] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:26:28.747] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:26:28.757] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:26:28.770] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:26:28.798] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:26:28.834] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:26:28.843] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:26:36.036] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:26:36.047] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:26:36.063] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:26:36.075] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:26:36.122] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:26:36.132] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:27:02.346] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:27:02.357] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:27:02.360] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:27:02.374] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:27:02.385] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:27:02.417] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:27:02.428] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:28:53.335] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:28:53.346] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:28:53.351] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:28:53.366] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:28:53.382] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:28:53.407] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:28:53.415] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:29:06.301] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:29:06.311] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:29:06.315] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:29:06.327] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:29:06.341] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:29:06.370] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:29:06.380] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:29:14.077] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:29:14.088] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:29:14.092] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:29:14.109] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:29:14.124] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:29:14.156] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:29:14.165] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:29:23.599] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:29:23.610] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:29:23.614] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:29:23.630] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:29:23.643] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:29:23.669] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:29:23.677] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:29:34.032] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:29:34.042] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:29:34.047] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:29:34.061] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:29:34.075] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:29:34.117] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:29:34.127] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:29:46.216] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:29:46.227] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:29:46.232] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:29:46.251] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:29:46.265] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:29:46.287] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:29:46.297] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:30:08.411] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:30:08.421] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:30:08.425] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:30:08.438] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:30:08.451] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:30:08.495] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:30:08.504] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:30:17.869] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:30:17.880] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:30:17.899] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:30:17.911] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:30:17.926] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:30:17.956] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:30:17.966] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:30:49.412] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:30:49.422] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:30:49.427] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:30:49.438] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:30:49.453] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:30:49.477] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:30:49.493] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:31:32.628] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:31:32.640] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:31:32.645] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:31:32.659] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:31:32.674] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:31:32.704] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:31:32.713] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:32:10.030] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:32:10.041] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:32:10.045] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:32:10.057] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:32:10.070] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:32:10.105] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:32:10.115] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:32:30.091] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:32:30.102] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:32:30.927] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:32:39.410] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:32:39.424] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:32:39.432] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:32:39.447] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:32:39.465] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:32:39.492] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:32:39.502] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:33:07.385] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:33:07.396] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:33:07.401] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:33:07.417] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:33:07.431] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:33:07.470] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:33:07.480] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:33:20.298] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:33:20.309] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:33:20.315] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:33:20.332] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:33:20.350] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:33:20.373] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:33:20.383] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:33:27.995] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:33:28.007] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:33:28.012] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:33:28.026] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:33:28.042] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:33:28.076] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:33:28.086] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:33:33.605] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:33:33.615] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:33:33.620] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:33:33.631] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:33:33.646] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:33:33.677] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:33:33.689] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:33:47.482] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:33:47.493] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:33:47.497] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:33:47.511] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:33:47.527] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:33:47.551] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:33:47.559] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:33:53.695] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:33:53.707] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:33:53.724] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:33:53.737] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:33:53.751] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:33:53.780] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:33:53.791] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:33:57.653] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:33:57.665] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:33:57.670] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:33:57.683] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:33:57.700] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:33:57.725] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:33:57.733] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:34:08.528] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:34:08.538] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:34:08.543] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:34:08.556] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:34:08.569] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:34:08.616] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:34:08.625] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:35:58.474] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:35:58.485] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:35:58.490] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:35:58.504] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:35:58.522] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:35:58.544] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:35:58.553] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:36:12.736] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:36:12.747] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:36:12.752] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:36:12.764] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:36:12.778] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:36:12.799] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:36:12.809] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:36:23.117] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:36:23.128] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:36:23.133] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:36:23.145] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:36:23.160] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:36:23.192] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:36:23.202] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:36:35.456] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:36:35.467] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:36:35.472] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:36:35.486] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:36:35.501] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:36:35.545] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:36:35.554] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:38:52.975] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:38:52.987] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:38:52.993] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:38:53.007] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:38:53.022] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:38:53.053] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:38:53.066] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:39:16.059] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:39:16.071] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:39:16.077] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:39:16.091] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:39:16.105] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:39:16.149] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:39:16.160] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:39:34.058] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:39:34.069] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:39:34.073] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:39:34.088] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:39:34.105] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:39:34.130] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:39:34.141] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:40:05.198] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:40:05.209] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:40:05.213] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:40:05.227] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:40:05.244] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:40:05.279] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:40:05.289] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:40:22.330] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:40:22.342] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:40:22.347] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:40:22.361] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:40:22.376] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:40:22.400] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:40:22.409] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:43:58.684] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:43:58.695] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:43:58.699] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:43:58.713] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:43:58.728] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:43:58.771] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:43:58.781] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:44:11.725] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:44:11.737] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:44:11.742] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:44:11.762] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:44:11.775] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:44:11.810] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:44:11.819] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:44:33.503] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:44:33.515] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:44:33.520] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:44:33.542] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:44:33.557] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:44:33.628] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:44:33.640] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:45:01.108] [undefined] GET(/:id): try to get video 3
[2025-08-15 07:45:01.118] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:45:01.123] [undefined] GET(/:id): successfully get video 3 with status 200
[2025-08-15 07:45:01.140] [undefined] GET(/:id/similar): try to get similar videos for video 3
[2025-08-15 07:45:01.153] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-08-15 07:45:01.185] [undefined] GET(/:id/views): try to add views for video 3
[2025-08-15 07:45:01.194] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-08-15 07:45:03.398] [undefined] POST(/:id): Video added to playlist with id 2 with status 200
[2025-08-15 07:45:12.544] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 07:45:12.548] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 07:45:12.551] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 07:45:12.554] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 07:45:12.561] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:45:18.685] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 07:45:18.688] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 07:45:18.691] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 07:45:18.695] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 07:45:18.703] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:46:57.187] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 07:46:57.191] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 07:46:57.195] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 07:46:57.201] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 07:46:57.207] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:53:09.712] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 07:57:29.629] [undefined] GET(/:id): try to get video 10
[2025-08-15 07:57:29.640] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 07:57:29.645] [undefined] GET(/:id): successfully get video 10 with status 200
[2025-08-15 07:57:29.661] [undefined] GET(/:id/similar): try to get similar videos for video 10
[2025-08-15 07:57:29.673] [undefined] GET(/:id/similar): successfully get similar videos for video 10 with status 200
[2025-08-15 07:57:29.702] [undefined] GET(/:id/views): try to add views for video 10
[2025-08-15 07:57:29.714] [undefined] GET(/:id/views): successfully added views for video 10 with status 200
[2025-08-15 07:57:31.756] [undefined] POST(/:id): Video added to playlist with id 2 with status 200
[2025-08-15 08:01:04.884] [undefined] GET(/:id): try to get video 10
[2025-08-15 08:01:04.895] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 08:01:04.902] [undefined] GET(/:id): successfully get video 10 with status 200
[2025-08-15 08:01:04.924] [undefined] GET(/:id/similar): try to get similar videos for video 10
[2025-08-15 08:01:04.942] [undefined] GET(/:id/similar): successfully get similar videos for video 10 with status 200
[2025-08-15 08:01:04.989] [undefined] GET(/:id/views): try to add views for video 10
[2025-08-15 08:01:04.998] [undefined] GET(/:id/views): successfully added views for video 10 with status 200
[2025-08-15 08:01:08.034] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 08:01:08.037] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 08:01:08.041] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 08:01:08.046] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 08:01:08.053] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 08:01:09.580] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 08:09:51.858] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 08:10:08.586] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 08:10:21.732] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 08:10:21.736] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 08:10:21.739] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 08:10:21.746] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 08:10:21.753] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 08:11:01.489] [undefined] GET(/:id): Error retrieving playlist: missing FROM-clause entry for table "channel" with status 500
[2025-08-15 08:11:36.075] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:34:51.115] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:34:51.118] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:34:51.126] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:34:51.132] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:34:51.141] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:34:52.476] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:36:02.596] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:36:12.642] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:36:12.646] [undefined] GET(/:id): try to get video 7
[2025-08-15 11:36:12.657] [undefined] GET(/:id): successfully get video 7 with status 200
[2025-08-15 11:36:12.669] [undefined] GET(/:id/similar): try to get similar videos for video 7
[2025-08-15 11:36:12.685] [undefined] GET(/:id/similar): successfully get similar videos for video 7 with status 200
[2025-08-15 11:36:12.709] [undefined] GET(/:id/views): try to add views for video 7
[2025-08-15 11:36:12.721] [undefined] GET(/:id/views): successfully added views for video 7 with status 200
[2025-08-15 11:36:15.330] [undefined] POST(/:id): Video added to playlist with id 9 with status 200
[2025-08-15 11:36:16.992] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:36:16.996] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:36:16.999] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:36:17.004] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:36:17.010] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:36:19.673] [undefined] GET(/:id): Playlist retrieved with id 9 with status 200
[2025-08-15 11:36:21.015] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:36:21.017] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:36:21.020] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:36:21.024] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:36:21.031] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:37:36.685] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:37:36.688] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:37:36.691] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:37:36.697] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:37:36.704] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:37:37.540] [undefined] GET(/:id): Playlist retrieved with id 9 with status 200
[2025-08-15 11:37:46.171] [undefined] GET(/:id): try to get video 7
[2025-08-15 11:37:46.181] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:37:46.186] [undefined] GET(/:id): successfully get video 7 with status 200
[2025-08-15 11:37:46.197] [undefined] GET(/:id/similar): try to get similar videos for video 7
[2025-08-15 11:37:46.211] [undefined] GET(/:id/similar): successfully get similar videos for video 7 with status 200
[2025-08-15 11:37:46.241] [undefined] GET(/:id/views): try to add views for video 7
[2025-08-15 11:37:46.251] [undefined] GET(/:id/views): successfully added views for video 7 with status 200
[2025-08-15 11:37:46.753] [undefined] GET(/:id): Playlist retrieved with id 9 with status 200
[2025-08-15 11:37:48.179] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:37:48.182] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:37:48.184] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:37:48.189] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:37:48.197] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:38:45.205] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:38:45.208] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:38:45.217] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:38:45.221] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:38:45.228] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:39:25.429] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:39:25.432] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:39:25.436] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:39:25.441] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:39:25.447] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:39:33.775] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:39:33.780] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:39:33.783] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:39:33.788] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:39:33.796] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:39:42.483] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:39:42.487] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:39:42.492] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:39:42.499] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:39:42.506] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:39:54.583] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:39:54.587] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:39:54.590] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:39:54.597] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:39:54.604] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:40:01.578] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:40:02.989] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:40:02.992] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:40:02.996] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:40:03.001] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:40:03.006] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:40:03.583] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:40:04.040] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:40:04.044] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:40:04.047] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:40:04.050] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:40:04.058] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:40:04.695] [undefined] GET(/:id): Playlist retrieved with id 9 with status 200
[2025-08-15 11:40:05.139] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:40:05.142] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:40:05.145] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:40:05.149] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:40:05.156] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:40:05.674] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:40:06.063] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:40:06.067] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:40:06.070] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:40:06.074] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:40:06.082] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:40:06.616] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:40:32.573] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:40:33.203] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:40:33.945] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:40:45.160] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:40:45.922] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:40:51.863] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:41:01.257] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:41:01.260] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:41:01.264] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:41:01.269] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:41:01.277] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:42:23.314] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:42:23.319] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:42:23.344] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:42:23.351] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:42:23.358] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:42:24.351] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:42:27.415] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:42:27.419] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:42:27.427] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:42:27.432] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:42:27.439] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:42:28.016] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:42:28.584] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:42:28.587] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:42:28.591] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:42:28.595] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:42:28.600] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:42:29.091] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:42:30.125] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:42:30.129] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:42:30.131] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:42:30.136] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:42:30.144] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:42:55.444] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:42:55.447] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:42:55.450] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:42:55.454] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:42:55.462] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:42:55.946] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:43:04.667] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:43:25.896] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:44:01.336] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:44:08.744] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:44:40.681] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:44:51.683] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:45:09.918] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:45:17.445] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:45:23.115] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:46:00.470] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:46:03.102] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:46:03.105] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:46:03.107] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:46:03.113] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:46:03.121] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:46:06.450] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:46:07.270] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:51:55.980] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:52:34.410] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:52:49.764] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:52:59.942] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:53:14.793] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:53:23.643] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:53:42.731] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:54:00.339] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:54:35.499] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:54:53.925] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:55:09.339] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:55:22.887] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 11:56:17.396] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:56:17.401] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:56:17.407] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:56:17.411] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:56:17.418] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:56:18.071] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:56:43.895] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:57:03.654] [undefined] GET(/:id): Playlist retrieved with id 8 with status 200
[2025-08-15 11:57:05.682] [undefined] DELETE(/:id): Playlist deleted with status 200
[2025-08-15 11:57:07.595] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:57:07.598] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:57:07.601] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:57:07.606] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:57:07.614] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:57:27.626] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:57:27.630] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:57:27.634] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:57:27.641] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:57:27.650] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:57:31.598] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:57:31.602] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:57:31.605] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:57:31.611] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:57:31.616] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:57:45.169] [undefined] GET(/:id): Playlist retrieved with id 9 with status 200
[2025-08-15 11:57:49.098] [undefined] DELETE(/:id): Error deleting playlist: update or delete on table "playlists" violates foreign key constraint "playlist_elements_playlist_fkey" on table "playlist_elements" with status 500
[2025-08-15 11:57:49.135] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:57:49.139] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:57:49.141] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:57:49.147] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:57:49.156] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:57:50.662] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:57:50.665] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:57:50.668] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:57:50.674] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:57:50.680] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:57:51.421] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:57:51.424] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:57:51.427] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:57:51.431] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:57:51.439] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:57:52.853] [undefined] GET(/:id): Playlist retrieved with id 9 with status 200
[2025-08-15 11:57:53.587] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:57:53.591] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:57:53.595] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:57:53.599] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:57:53.605] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 11:57:54.570] [undefined] GET(/:id): Playlist retrieved with id 9 with status 200
[2025-08-15 11:57:59.003] [undefined] DELETE(/:id): Error deleting playlist: update or delete on table "playlists" violates foreign key constraint "playlist_elements_playlist_fkey" on table "playlist_elements" with status 500
[2025-08-15 11:57:59.062] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-08-15 11:57:59.065] [undefined] GET(/:id/channel): successfully retrieved channel of user 2 with status 200
[2025-08-15 11:57:59.069] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-08-15 11:57:59.074] [undefined] GET(/:id/history): successfully retrieved history of user 2 with status 200
[2025-08-15 11:57:59.082] [undefined] GET(/user/:id): Playlists retrieved for user with id 2 with status 200
[2025-08-15 12:02:47.596] [undefined] POST(/): try to register a user with username: astria and email: sachaguerin.sg@gmail.com
[2025-08-15 12:02:47.647] [undefined] POST(/): successfully registered with status 200
[2025-08-15 12:02:47.659] [undefined] POST(/login): try to login with username 'astria'
[2025-08-15 12:02:47.710] [undefined] POST(/login): Successfully logged in with status 200
[2025-08-15 12:02:49.622] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-08-15 12:02:49.625] [undefined] GET(/:id/channel): failed to retrieve channel of user 1 because it doesn't exist with status 404
[2025-08-15 12:02:49.630] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-08-15 12:02:49.634] [undefined] GET(/:id/history): failed to retrieve history of user 1 because it doesn't exist with status 404
[2025-08-15 12:02:49.642] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:02:56.061] [undefined] POST(/): try to create new channel with owner 1 and name astria
[2025-08-15 12:02:56.063] [undefined] POST(/): Successfully created new channel with name astria with status 200
[2025-08-15 12:02:56.078] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-08-15 12:02:56.082] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-08-15 12:02:57.508] [undefined] GET(/:id): try to get channel with id 1
[2025-08-15 12:02:57.519] [undefined] GET(/:id/stats): try to get stats
[2025-08-15 12:02:57.522] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-08-15 12:02:57.531] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-08-15 12:02:58.751] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-08-15 12:02:58.754] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-08-15 12:03:17.807] [undefined] POST(/): try to upload video with status undefined
[2025-08-15 12:03:17.812] [undefined] POST(/): successfully uploaded video with status 200
[2025-08-15 12:03:17.878] [undefined] POST(/thumbnail): try to add thumbnail to video 1
[2025-08-15 12:03:17.881] [undefined] POST(/thumbnail): successfully uploaded thumbnail with status 200
[2025-08-15 12:03:17.900] [undefined] PUT(/:id/tags): try to add tags to video 1
[2025-08-15 12:03:17.910] [undefined] PUT(/:id/tags): successfully added tags to video 1 with status 200
[2025-08-15 12:03:21.191] [undefined] GET(/:id): try to get video 1
[2025-08-15 12:03:21.201] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:03:21.206] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-08-15 12:03:21.218] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-08-15 12:03:21.229] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200
[2025-08-15 12:03:21.250] [undefined] GET(/:id/views): try to add views for video 1
[2025-08-15 12:03:21.265] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-08-15 12:03:25.914] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-08-15 12:03:25.917] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-08-15 12:03:25.919] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-08-15 12:03:25.925] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-08-15 12:03:25.934] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:03:30.209] [undefined] POST(/): Playlist created with id 2 with status 200
[2025-08-15 12:03:30.227] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:03:34.208] [undefined] GET(/:id): try to get video 1
[2025-08-15 12:03:34.219] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:03:34.223] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-08-15 12:03:34.236] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-08-15 12:03:34.248] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200
[2025-08-15 12:03:34.273] [undefined] GET(/:id/views): try to add views for video 1
[2025-08-15 12:03:34.281] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-08-15 12:03:36.394] [undefined] POST(/:id): Video added to playlist with id 2 with status 200
[2025-08-15 12:03:38.143] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-08-15 12:03:38.145] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-08-15 12:03:38.148] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-08-15 12:03:38.151] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-08-15 12:03:38.161] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:03:38.653] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200
[2025-08-15 12:03:40.880] [undefined] DELETE(/:id): Playlist deleted with status 200
[2025-08-15 12:03:40.925] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-08-15 12:03:40.928] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-08-15 12:03:40.931] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-08-15 12:03:40.933] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-08-15 12:03:40.942] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:03:52.229] [undefined] POST(/): Playlist created with id 3 with status 200
[2025-08-15 12:03:52.247] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:03:53.608] [undefined] GET(/:id): try to get video 1
[2025-08-15 12:03:53.619] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:03:53.624] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-08-15 12:03:53.635] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-08-15 12:03:53.648] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200
[2025-08-15 12:03:53.675] [undefined] GET(/:id/views): try to add views for video 1
[2025-08-15 12:03:53.685] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-08-15 12:03:55.180] [undefined] POST(/:id): Video added to playlist with id 3 with status 200
[2025-08-15 12:03:56.494] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-08-15 12:03:56.497] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-08-15 12:03:56.500] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-08-15 12:03:56.504] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-08-15 12:03:56.511] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:03:57.117] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:06:09.157] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:06:13.801] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-08-15 12:06:13.805] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-08-15 12:06:13.808] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-08-15 12:06:13.812] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-08-15 12:06:13.820] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:06:15.043] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:07:33.375] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:07:46.081] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:07:54.278] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:08:25.981] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:08:48.330] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:09:05.838] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:09:20.029] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:09:31.979] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:10:11.328] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:10:17.318] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:11:07.347] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:11:08.287] [undefined] GET(/:id): try to get video 1
[2025-08-15 12:11:08.297] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:11:08.302] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-08-15 12:11:08.314] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-08-15 12:11:08.327] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200
[2025-08-15 12:11:08.348] [undefined] GET(/:id/views): try to add views for video 1
[2025-08-15 12:11:08.359] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-08-15 12:11:09.147] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:11:43.722] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:12:10.236] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:12:22.230] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:12:36.945] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:12:38.251] [undefined] GET(/:id): try to get video 1
[2025-08-15 12:12:38.262] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:12:38.266] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-08-15 12:12:38.278] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-08-15 12:12:38.291] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200
[2025-08-15 12:12:38.315] [undefined] GET(/:id/views): try to add views for video 1
[2025-08-15 12:12:38.327] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-08-15 12:12:39.300] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:13:16.106] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:13:17.470] [undefined] GET(/:id): try to get video 1
[2025-08-15 12:13:17.481] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:13:17.487] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-08-15 12:13:17.499] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-08-15 12:13:17.513] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200
[2025-08-15 12:13:17.565] [undefined] GET(/:id/views): try to add views for video 1
[2025-08-15 12:13:17.574] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-08-15 12:13:18.292] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:13:19.374] [undefined] GET(/:id): try to get video 1
[2025-08-15 12:13:19.384] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:13:19.389] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-08-15 12:13:19.402] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-08-15 12:13:19.414] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200
[2025-08-15 12:13:19.438] [undefined] GET(/:id/views): try to add views for video 1
[2025-08-15 12:13:19.446] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-08-15 12:13:19.797] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:13:50.493] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:13:52.628] [undefined] GET(/:id): try to get video 1
[2025-08-15 12:13:52.639] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:13:52.644] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-08-15 12:13:52.657] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-08-15 12:13:52.670] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200
[2025-08-15 12:13:52.693] [undefined] GET(/:id/views): try to add views for video 1
[2025-08-15 12:13:52.705] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-08-15 12:13:53.217] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:16:32.830] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:16:33.842] [undefined] GET(/:id): try to get video 1
[2025-08-15 12:16:33.853] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-08-15 12:16:33.859] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-08-15 12:16:33.871] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-08-15 12:16:33.884] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200
[2025-08-15 12:16:33.909] [undefined] GET(/:id/views): try to add views for video 1
[2025-08-15 12:16:33.917] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-08-15 12:16:34.233] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:18:40.492] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:18:51.040] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:19:00.143] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:19:03.469] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:19:55.046] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:19:57.124] [undefined] DELETE(/:id/video/:videoId): Video deleted from playlist with id 3 with status 200
[2025-08-15 12:19:57.149] [undefined] GET(/:id): Playlist retrieved with id 3 with status 200
[2025-08-15 12:20:03.498] [undefined] DELETE(/:id): Playlist deleted with status 200
[2025-08-15 12:20:03.611] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-08-15 12:20:03.614] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-08-15 12:20:03.617] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-08-15 12:20:03.621] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-08-15 12:20:03.630] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200

1
frontend/src/assets/svg/trash.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M5 20a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8h2V6h-4V4a2 2 0 0 0-2-2H9a2 2 0 0 0-2 2v2H3v2h2zM9 4h6v2H9zM8 8h9v12H7V8z"></path><path d="M9 10h2v8H9zm4 0h2v8h-2z"></path></svg>

After

Width:  |  Height:  |  Size: 260 B

1
frontend/src/components/Navbar.jsx

@ -48,6 +48,7 @@ export default function Navbar({ isSearchPage = false, alerts = [], onCloseAlert
</div>
<div>
<ul className="flex items-center space-x-[44px] font-montserrat text-2xl font-black">
<li><a href="/">Accueil</a></li>
{isAuthenticated ? (
<>
<li><a href="/">Abonnements</a></li>

2
frontend/src/components/PlaylistCard.jsx

@ -4,7 +4,7 @@ export default function PlaylistCard(props){
const {playlist, onClick} = props;
return (
<div className="glassmorphism w-1/3 p-4 cursor-pointer" onClick={() => {onClick(playlist.id)}}>
<div className="glassmorphism p-4 cursor-pointer" onClick={() => {onClick(playlist.id)}}>
<img src={playlist.thumbnail ? playlist.thumbnail : Default} alt={playlist.name} className="rounded-sm" />
<div className="playlist-info">
<h3 className="font-montserrat font-semibold text-xl text-white mt-3">{playlist.name}</h3>

4
frontend/src/components/TrendingVideos.jsx

@ -6,11 +6,9 @@ export default function TrendingVideos({ videos }) {
return (
<div className="mt-10">
<h2 className="text-3xl font-bold mb-4 text-white">Tendances</h2>
<div className="flex flex-wrap gap-11">
<div className="grid grid-cols-5 gap-8 mt-8">
{videos && videos.map((video, index) => (
<div className="w-445/1920" key={index}>
<VideoCard video={video} key={index} />
</div>
))}
</div>
</div>

40
frontend/src/components/VideoCard.jsx

@ -25,7 +25,7 @@ import { useNavigate } from 'react-router-dom';
// }
// ]
export default function VideoCard({ video }) {
export default function VideoCard({ video, showControls = false, onDelete = () => {} }) {
const navigation = useNavigate();
const handleClick = () => {
navigation(`/video/${video.id}`, {
@ -33,20 +33,32 @@ export default function VideoCard({ video }) {
})
}
return (
<div className="flex flex-col glassmorphism w-full p-6 cursor-pointer" onClick={handleClick} >
<div className="aspect-video rounded-sm overflow-hidden">
<img
src={video.thumbnail}
alt={video.title}
className="w-full h-full object-cover"
/>
</div>
<h2 className="text-2xl font-medium font-inter mt-3 text-white">{video.title}</h2>
<div className="text-sm text-gray-400 mt-1 flex items-center">
<img src={video.creator.profilePicture} alt={video.title} className="w-12 aspect-square rounded-full object-cover" />
<span className="ml-2">{video.creator.name}</span>
<span className="ml-3.5">{video.views} vues</span>
<div className="flex flex-col glassmorphism w-full p-6 cursor-pointer relative">
<div onClick={handleClick} >
<div className="aspect-video rounded-sm overflow-hidden">
<img
src={video.thumbnail}
alt={video.title}
className="w-full h-full object-cover"
/>
</div>
<h2 className="text-2xl font-medium font-inter mt-3 text-white">{video.title}</h2>
<div className="text-sm text-gray-400 mt-1 flex items-center">
<img src={video.creator.profilePicture} alt={video.title} className="w-12 aspect-square rounded-full object-cover" />
<span className="ml-2">{video.creator.name}</span>
<span className="ml-3.5">{video.views} vues</span>
</div>
</div>
{showControls && (
<div className="mt-4">
<button
className="absolute -bottom-5 -right-5 bg-red-500 ml-4 px-3 py-2 rounded-full aspect-square text-white font-montserrat text-lg font-semibold cursor-pointer"
onClick={() => onDelete(video.id)}
>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className='fill-white' ><path d="M5 20a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8h2V6h-4V4a2 2 0 0 0-2-2H9a2 2 0 0 0-2 2v2H3v2h2zM9 4h6v2H9zM8 8h9v12H7V8z"></path><path d="M9 10h2v8H9zm4 0h2v8h-2z"></path></svg>
</button>
</div>
)}
</div>
);
}

27
frontend/src/modals/VerificationModal.jsx

@ -0,0 +1,27 @@
export default function VerificationModal({title, onConfirm, onCancel, isOpen}) {
if (!isOpen) return null;
return (
<div className="fixed inset-0 flex items-center justify-center">
<div className="glassmorphism p-6">
<h2 className="text-lg text-white font-semibold mb-4">{title}</h2>
<div className="flex justify-end">
<button
className="bg-primary px-3 py-2 rounded-sm text-white font-montserrat text-lg font-semibold cursor-pointer"
onClick={() => onConfirm()}
>
Confirmer
</button>
<button
className="bg-red-500 ml-4 px-3 py-2 rounded-sm text-white font-montserrat text-lg font-semibold cursor-pointer"
onClick={() => onCancel()}
>
Annuler
</button>
</div>
</div>
</div>
);
}

12
frontend/src/pages/Account.jsx

@ -86,6 +86,10 @@ export default function Account() {
setIsModalOpen(false);
fetchUserChannel();
}
const closePlaylistModal = () => {
setIsCreatePlaylistModalOpen(false);
fetchUserPlaylists();
}
return (
<div className="min-w-screen min-h-screen bg-linear-to-br from-left-gradient to-right-gradient">
@ -231,7 +235,7 @@ export default function Account() {
Créer une playlist
</button>
</div>
<div className="w-full mt-5 flex flex-wrap" >
<div className="grid grid-cols-3 gap-8 mt-8" >
{
userPlaylists && userPlaylists.map((playlist, index) => (
<PlaylistCard playlist={playlist} key={index} onClick={handlePlaylistClick} />
@ -240,12 +244,10 @@ export default function Account() {
</div>
{/* History */}
<h2 className="font-montserrat font-bold text-3xl text-white mt-10" >Historique</h2>
<div className="w-full mt-5 flex flex-wrap gap-2" >
<div className="grid grid-cols-3 gap-8 mt-8" >
{
userHistory && userHistory.map((video, index) => (
<div className="w-1/3" key={index}>
<VideoCard video={video} />
</div>
))
}
</div>
@ -253,7 +255,7 @@ export default function Account() {
</main>
<CreateChannelModal isOpen={isModalOpen} onClose={() => closeModal()} addAlert={addAlert} />
<CreatePlaylistModal isOpen={isCreatePlaylistModalOpen} onClose={() => setIsCreatePlaylistModalOpen(false)} addAlert={addAlert} />
<CreatePlaylistModal isOpen={isCreatePlaylistModalOpen} onClose={() => closePlaylistModal()} addAlert={addAlert} />
</div>
)

97
frontend/src/pages/Playlist.jsx

@ -0,0 +1,97 @@
import { useParams } from "react-router-dom";
import Navbar from "../components/Navbar";
import { useEffect, useState } from "react";
import { getPlaylistById, deletePlaylist, deleteVideo } from "../services/playlist.service.js";
import VideoCard from "../components/VideoCard.jsx";
import VerificationModal from "../modals/VerificationModal.jsx";
import { useNavigate } from "react-router-dom";
export default function Playlist() {
const { id } = useParams();
const navigate = useNavigate();
const [alerts, setAlerts] = useState([]);
const [playlist, setPlaylist] = useState(null);
const [isDeletePlaylistModalOpen, setIsDeletePlaylistModalOpen] = useState(false);
const fetchPlaylistDetails = async () => {
const token = localStorage.getItem("token");
const data = await getPlaylistById(id, token, addAlert);
setPlaylist(data);
}
useEffect(() => {
fetchPlaylistDetails();
}, [id]);
const addAlert = (type, message) => {
const newAlert = { type, message, id: Date.now() }; // Add unique ID
setAlerts([...alerts, newAlert]);
};
const onCloseAlert = (alertToRemove) => {
setAlerts(alerts.filter(alert => alert !== alertToRemove));
};
const onDeletePlaylist = async () => {
const token = localStorage.getItem("token");
await deletePlaylist(id, token, addAlert);
setIsDeletePlaylistModalOpen(false);
navigate("/profile");
}
const onDeleteVideo = async (videoId) => {
const token = localStorage.getItem("token");
await deleteVideo(id, videoId, token, addAlert);
fetchPlaylistDetails();
}
return (
<div className="min-w-screen min-h-screen bg-linear-to-br from-left-gradient to-right-gradient">
<Navbar isSearchPage={false} alerts={alerts} onCloseAlert={onCloseAlert} />
<main className="px-36 w-full pt-[118px]">
<h1 className="font-bold font-montserrat text-3xl text-white" >{playlist && playlist.name}</h1>
{/* CONTROLS */}
<div className="mt-4">
<button
className="bg-primary px-3 py-2 rounded-sm text-white font-montserrat text-lg font-semibold cursor-pointer"
onClick={() => console.log("Modifier playlist")}
>
modifier
</button>
<button
className="bg-red-500 ml-4 px-3 py-2 rounded-sm text-white font-montserrat text-lg font-semibold cursor-pointer"
onClick={() => setIsDeletePlaylistModalOpen(true)}
>
supprimer
</button>
</div>
<div className="grid grid-cols-4 gap-8 mt-12">
{
playlist && playlist.videos && playlist.videos.length > 0 ? playlist.videos.map(video => (
<VideoCard
key={video.id}
video={video}
showControls={true}
onDelete={onDeleteVideo}
/>
)) : (
<p className="text-white">Aucun vidéo trouvée dans cette playlist.</p>
)
}
</div>
</main>
<VerificationModal
title="Confirmer la suppression"
onConfirm={() => onDeletePlaylist()}
onCancel={() => setIsDeletePlaylistModalOpen(false)}
isOpen={isDeletePlaylistModalOpen}
/>
</div>
);
}

61
frontend/src/pages/Video.jsx

@ -8,6 +8,8 @@ import Tag from "../components/Tag.jsx";
import {addView, getSimilarVideos, getVideoById, toggleLike} from "../services/video.service.js";
import {subscribe} from "../services/channel.service.js";
import {addComment} from "../services/comment.service.js";
import { getPlaylists } from "../services/user.service.js";
import { addToPlaylist } from "../services/playlist.service.js";
export default function Video() {
@ -25,6 +27,8 @@ export default function Video() {
const [showControls, setShowControls] = useState(false);
const [comment, setComment] = useState("");
const [alerts, setAlerts] = useState([]);
const [playlists, setPlaylists] = useState([]);
const [isAddToPlaylistOpen, setIsAddToPlaylistOpen] = useState(false);
const fetchVideo = useCallback(async () => {
// Fetch video data and similar videos based on the video ID from the URL
@ -47,8 +51,20 @@ export default function Video() {
await addView(id, addAlert);
}, [id, navigation]);
const fetchPlaylists = async () => {
const token = localStorage.getItem('token');
if (!token) return;
const user = JSON.parse(localStorage.getItem('user'));
const data = await getPlaylists(user.id, token, addAlert);
if (data) {
setPlaylists(data);
}
}
useEffect(() => {
fetchVideo();
fetchPlaylists();
}, [fetchVideo]);
const handlePlayPause = () => {
@ -212,6 +228,22 @@ export default function Video() {
setAlerts(alerts.filter(alert => alert !== alertToRemove));
};
const handleAddToPlaylist = async (id) => {
if (!isAuthenticated) {
navigation('/login');
return;
}
const body = {
video: video.id
}
const token = localStorage.getItem('token');
await addToPlaylist(id, body, token, addAlert);
setIsAddToPlaylistOpen(!isAddToPlaylistOpen);
}
return (
<div className="min-w-screen min-h-screen bg-linear-to-br from-left-gradient to-right-gradient">
<Navbar isSearchPage={false} alerts={alerts} onCloseAlert={onCloseAlert} />
@ -292,6 +324,35 @@ export default function Video() {
</svg>
</button>
<p className="font-montserrat text-white ml-2" >{video.likes}</p>
<button className="relative ml-14">
<div className="bg-primary cursor-pointer px-4 py-2 rounded-md flex items-center gap-4" onClick={() => setIsAddToPlaylistOpen(!isAddToPlaylistOpen)} >
<p className="text-white font-montserrat font-bold" >playlist</p>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="fill-white"><path d="M19 11h-6V5h-2v6H5v2h6v6h2v-6h6z"></path></svg>
</div>
{
playlists.length > 0 && isAddToPlaylistOpen && (
<div className="absolute inset-0 w-max h-max z-40 glassmorphism top-1/1 mt-2 left-0 rounded-2xl px-4 py-2 cursor-default">
<ul className="flex flex-col gap-2">
{playlists.map((playlist) => (
<li
key={playlist.id}
className="text-white font-montserrat font-medium text-sm cursor-pointer hover:underline flex items-center justify-between gap-4"
onClick={() => handleAddToPlaylist(playlist.id)}
>
<p className="text-start">{playlist.name}</p>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="fill-white"><path d="M19 11h-6V5h-2v6H5v2h6v6h2v-6h6z"></path></svg>
</li>
))}
</ul>
</div>
)
}
</button>
</div>
{/* Video details */}

9
frontend/src/routes/routes.jsx

@ -9,6 +9,7 @@ import ManageVideo from "../pages/ManageVideo.jsx";
import AddVideo from "../pages/AddVideo.jsx";
import Search from "../pages/Search.jsx";
import Channel from "../pages/Channel.jsx";
import Playlist from "../pages/Playlist.jsx";
const routes = [
{ path: "/", element: <Home/> },
@ -79,6 +80,14 @@ const routes = [
element: (
<Channel/>
)
},
{
path: "playlist/:id",
element: (
<ProtectedRoute requireAuth={true}>
<Playlist/>
</ProtectedRoute>
)
}
]

83
frontend/src/services/playlist.service.js

@ -20,4 +20,85 @@ export async function createPlaylist(body, token, addAlert) {
} catch (error) {
addAlert('error', error.message);
}
}
}
export async function addToPlaylist(id, body, token, addAlert) {
try {
const response = await fetch(`https://localhost/api/playlists/${id}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify(body)
});
if (!response.ok) {
throw new Error('Failed to add video to playlist');
}
const data = await response.json();
addAlert('success', 'Vidéo ajoutée à la playlist avec succès');
return data;
} catch (error) {
addAlert('error', "Erreur lors de l'ajout à la playlist");
}
}
export async function getPlaylistById(id, token, addAlert) {
try {
const response = await fetch(`https://localhost/api/playlists/${id}`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
throw new Error('Failed to fetch playlist');
}
const data = await response.json();
return data;
} catch (error) {
addAlert('error', error.message);
}
}
export async function deletePlaylist(id, token, addAlert) {
try {
const response = await fetch(`https://localhost/api/playlists/${id}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
throw new Error('Failed to delete playlist');
}
addAlert('success', 'Playlist deleted successfully');
} catch (error) {
addAlert('error', error.message);
}
}
export async function deleteVideo(playlistId, videoId, token, addAlert) {
try {
const response = await fetch(`https://localhost/api/playlists/${playlistId}/video/${videoId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
throw new Error('Failed to delete video');
}
addAlert('success', 'Video deleted successfully');
} catch (error) {
addAlert('error', error.message);
}
}

Loading…
Cancel
Save