Browse Source

Merge pull request #8 from Astri4-4/channel-page

Channel page
features/create-channel
Sacha GUERIN 5 months ago
committed by GitHub
parent
commit
45e7a98e9f
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 53
      backend/app/controllers/channel.controller.js
  2. 6
      backend/app/routes/channel.route.js
  3. BIN
      backend/app/uploads/profiles/sacha.jpg
  4. 455
      backend/logs/access.log
  5. 19
      frontend/src/components/VideoStatListElement.jsx
  6. 4
      frontend/src/index.css
  7. 2
      frontend/src/pages/Account.jsx
  8. 208
      frontend/src/pages/ManageChannel.jsx
  9. 9
      frontend/src/routes/routes.jsx

53
backend/app/controllers/channel.controller.js

@ -27,10 +27,30 @@ export async function getById(req, res) {
const logger = req.body.logger; const logger = req.body.logger;
logger.action("try to get channel with id " + id); logger.action("try to get channel with id " + id);
const client = await getClient(); const client = await getClient();
const query = `SELECT * FROM channels WHERE id = $1`;
const query = `
SELECT *
FROM channels
WHERE channels.id = $1
`;
const result = await client.query(query, [id]); const result = await client.query(query, [id]);
const videoQuery = `
SELECT v.*, COUNT(h.video) as views, COUNT(l.id) as likes, COUNT(c.id) as comments
FROM videos v
LEFT JOIN history h ON v.id = h.video
LEFT JOIN likes l ON v.id = l.video
LEFT JOIN comments c ON v.id = c.video
WHERE v.channel = $1
GROUP BY v.id, title, thumbnail, description, channel, visibility, file, slug, format, release_date
`;
const videoResult = await client.query(videoQuery, [id]);
result.rows[0].videos = videoResult.rows;
logger.write("Successfully get channel with id " + id, 200); logger.write("Successfully get channel with id " + id, 200);
res.status(200).json(result); res.status(200).json(result.rows[0]);
} }
@ -146,4 +166,33 @@ export async function toggleSubscription(req, res) {
logger.write("Successfully subscribed to channel", 200); logger.write("Successfully subscribed to channel", 200);
res.status(200).json({message: 'Subscribed successfully', subscriptions: totalSubscriptions}); res.status(200).json({message: 'Subscribed successfully', subscriptions: totalSubscriptions});
} }
}
export async function getStats(req, res) {
try {
const id = req.params.id;
const logger = req.body.logger;
logger.action("try to get stats");
const request = `
SELECT
(SELECT COUNT(*) FROM subscriptions WHERE channel = $1) as subscribers,
(SELECT COUNT(*) FROM history h JOIN videos v ON h.video = v.id WHERE v.channel = $1) as views
FROM channels
LEFT JOIN public.subscriptions s on channels.id = s.channel
LEFT JOIN public.videos v on channels.id = v.channel
LEFT JOIN public.history h on v.id = h.video
WHERE channels.id = $1
`;
const client = await getClient();
const result = await client.query(request, [id]);
logger.write("Successfully get stats", 200);
res.status(200).json(result.rows[0]);
} catch (error) {
console.log(error);
res.status(500).json({error: error.message});
}
} }

6
backend/app/routes/channel.route.js

@ -1,5 +1,5 @@
import {Router} from "express"; import {Router} from "express";
import {create, del, getAll, getById, toggleSubscription, update} from "../controllers/channel.controller.js"; import {create, del, getAll, getById, getStats, toggleSubscription, update} from "../controllers/channel.controller.js";
import {isTokenValid} from "../middlewares/jwt.middleware.js"; import {isTokenValid} from "../middlewares/jwt.middleware.js";
import { import {
Channel, Channel,
@ -32,4 +32,8 @@ router.delete("/:id", [addLogger, isTokenValid, Channel.id, validator, doChannel
// TOGGLE SUBSCRIPTION // TOGGLE SUBSCRIPTION
router.post("/:id/subscribe", [addLogger, isTokenValid, Channel.id, validator, doChannelExists], toggleSubscription); router.post("/:id/subscribe", [addLogger, isTokenValid, Channel.id, validator, doChannelExists], toggleSubscription);
// GET TOTAL VIEWS AND SUBSCRIBERS OF THE CHANNEL
router.get("/:id/stats", [addLogger, isTokenValid, Channel.id, validator, doChannelExists, isOwner], getStats);
export default router; export default router;

BIN
backend/app/uploads/profiles/sacha.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

455
backend/logs/access.log

@ -1463,3 +1463,458 @@
[2025-07-21 19:03:11.316] [undefined] GET(/:id/history): try to retrieve history of user 1 [2025-07-21 19:03:11.316] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-21 19:03:11.318] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200 [2025-07-21 19:03:11.318] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-21 19:03:11.323] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200 [2025-07-21 19:03:11.323] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-21 19:19:15.258] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-21 19:19:15.261] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-21 19:19:15.263] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-21 19:19:15.268] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-21 19:19:15.272] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-21 19:19:19.428] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-21 19:19:19.429] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-21 19:19:19.431] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-21 19:19:19.434] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-21 19:19:19.440] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-21 19:19:24.221] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-21 19:19:24.223] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-21 19:19:24.225] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-21 19:19:24.228] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-21 19:19:24.234] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-21 19:20:39.780] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-21 19:20:39.781] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-21 19:20:39.785] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-21 19:20:39.786] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-21 19:20:39.800] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-21 19:25:44.379] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-21 19:25:44.380] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-21 19:25:44.381] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-21 19:25:44.382] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-21 19:25:44.389] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-21 19:31:53.819] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 19:31:53.825] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 19:32:30.436] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 19:32:30.444] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 19:59:26.602] [undefined] GET(/:id): try to get video 1
[2025-07-21 19:59:26.612] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-07-21 19:59:26.623] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-07-21 19:59:26.634] [undefined] GET(/:id/similar): No tags found for video 1 with status 404
[2025-07-21 19:59:26.647] [undefined] GET(/:id/views): try to add views for video 1
[2025-07-21 19:59:26.655] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-07-21 19:59:41.085] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-21 19:59:41.086] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-21 19:59:41.087] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-21 19:59:41.090] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-21 19:59:41.098] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-21 19:59:51.789] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 19:59:51.795] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:14:14.201] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:14:14.206] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:14:18.696] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:14:18.702] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:15:10.246] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:15:10.252] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:15:43.827] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:15:43.833] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:18:01.362] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:18:01.368] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:18:03.002] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:18:03.010] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:18:03.626] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:18:03.633] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:18:04.284] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:18:04.290] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:18:12.698] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:18:12.704] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:19:31.307] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:19:31.313] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:20:04.286] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:20:04.293] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:21:09.351] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:21:09.357] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:21:58.235] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:21:58.243] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:22:29.658] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:22:29.665] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:22:35.734] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:22:35.740] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:23:03.808] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:23:03.815] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:23:55.396] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:23:55.402] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:24:23.905] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:24:23.911] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:24:46.937] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:24:46.943] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:25:45.198] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:25:45.206] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:27:28.321] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:27:28.327] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:27:41.458] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:27:41.464] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:28:10.249] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:28:10.255] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:29:14.356] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:29:14.364] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:29:21.986] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:29:21.993] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:29:27.635] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:29:27.641] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:29:28.745] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:29:28.752] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:30:05.524] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:30:05.530] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:30:17.367] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:30:17.373] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:30:28.264] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:30:28.270] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:30:48.458] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-21 20:30:48.459] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-21 20:30:48.460] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-21 20:30:48.462] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-21 20:30:48.468] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-21 20:30:51.208] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:30:51.214] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:31:03.767] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:31:03.775] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:32:20.977] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:32:20.984] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:32:35.582] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:32:35.588] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:32:47.976] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:32:47.982] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:32:55.140] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:32:55.146] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:33:16.205] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:33:16.211] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:33:30.951] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:33:30.957] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:33:42.394] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:34:09.793] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:34:09.800] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:37:17.708] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:37:17.714] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:37:29.461] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:37:29.467] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:37:35.661] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:37:35.667] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:37:44.011] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:37:44.018] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:37:52.702] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:37:52.709] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:46:17.200] [undefined] GET(/:id): try to get video 1
[2025-07-21 20:46:17.208] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-07-21 20:46:17.218] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-07-21 20:46:17.229] [undefined] GET(/:id/similar): No tags found for video 1 with status 404
[2025-07-21 20:46:17.241] [undefined] GET(/:id/views): try to add views for video 1
[2025-07-21 20:46:17.249] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-07-21 20:46:18.397] [undefined] POST(/:id/subscribe): try to toggle subscription for channel with id 1
[2025-07-21 20:46:18.410] [undefined] POST(/:id/subscribe): Successfully subscribed to channel with status 200
[2025-07-21 20:47:07.908] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-21 20:47:07.910] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-21 20:47:07.911] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-21 20:47:07.913] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-21 20:47:07.921] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-21 20:47:08.769] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:47:08.776] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:52:55.243] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:52:55.252] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:52:55.255] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:53:31.341] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:53:31.349] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:53:31.352] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:53:31.359] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 20:53:54.157] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:53:54.166] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:53:54.167] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:53:54.176] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 20:54:27.105] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:54:27.115] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:54:27.117] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:54:27.124] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 20:55:10.279] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:55:10.287] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:55:10.288] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:55:10.294] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 20:55:18.042] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:55:18.050] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:55:18.051] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:55:18.058] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 20:55:56.629] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:55:56.638] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:55:56.639] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:55:56.646] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 20:56:14.738] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:56:14.747] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:56:14.749] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:56:14.756] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 20:56:24.537] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:56:24.546] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:56:24.547] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:56:24.553] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 20:56:47.291] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:56:47.300] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:56:47.301] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:56:47.308] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 20:57:00.345] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:57:00.353] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:57:00.355] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:57:00.362] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 20:57:10.945] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:57:10.954] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:57:10.955] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:57:10.962] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 20:58:04.767] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:58:04.775] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:58:04.776] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:58:04.783] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 20:58:10.452] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:58:10.461] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:58:10.463] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:58:10.471] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 20:58:21.280] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 20:58:21.290] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 20:58:21.291] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 20:58:21.297] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:01:19.881] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:01:19.891] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:01:19.893] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:01:19.902] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:02:30.037] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:02:30.048] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:02:30.050] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:02:30.059] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:04:09.412] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:04:09.420] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:04:09.422] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:04:09.429] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:04:22.514] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:04:22.523] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:04:22.524] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:04:22.530] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:04:45.081] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:04:45.089] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:04:45.090] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:04:45.100] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:05:18.620] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:05:18.627] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:05:18.629] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:05:18.638] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:09:03.213] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:09:03.222] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:09:03.224] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:09:03.230] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:09:12.057] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:09:12.066] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:09:12.070] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:09:12.076] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:09:15.276] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:09:15.285] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:09:15.287] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:09:15.293] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:09:38.508] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:09:38.515] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:09:38.518] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:09:38.524] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:10:05.727] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:10:05.736] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:10:05.737] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:10:05.742] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:10:11.175] [undefined] GET(/:id): try to get video 1
[2025-07-21 21:10:11.183] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-07-21 21:10:11.193] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-07-21 21:10:11.204] [undefined] GET(/:id/similar): No tags found for video 1 with status 404
[2025-07-21 21:10:11.217] [undefined] GET(/:id/views): try to add views for video 1
[2025-07-21 21:10:11.224] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-07-21 21:10:19.413] [undefined] POST(/): try to post comment
[2025-07-21 21:10:19.420] [undefined] POST(/): successfully post comment with status 200
[2025-07-21 21:10:21.844] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-21 21:10:21.845] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-21 21:10:21.848] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-21 21:10:21.850] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-21 21:10:21.858] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-21 21:10:23.870] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:10:23.878] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:10:23.881] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:10:23.886] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:11:01.966] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-21 21:11:01.968] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-21 21:11:01.975] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-21 21:11:01.978] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-21 21:11:01.986] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-21 21:11:06.061] [undefined] PUT(/:id): try to update user 1
[2025-07-21 21:11:06.070] [undefined] PUT(/:id): successfully updated user 1 with status 200
[2025-07-21 21:11:42.403] [undefined] POST(/login): try to login with username 'astria'
[2025-07-21 21:11:42.454] [undefined] POST(/login): Successfully logged in with status 200
[2025-07-21 21:11:48.848] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-21 21:11:48.850] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-21 21:11:48.851] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-21 21:11:48.854] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-21 21:11:48.863] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-21 21:11:50.371] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:11:50.380] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:11:50.381] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:11:50.388] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:12:18.324] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:12:18.333] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:12:18.334] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:12:18.341] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:12:44.758] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:12:44.766] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:12:44.768] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:12:44.775] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:12:58.746] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:12:58.754] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:12:58.757] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:12:58.761] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:13:06.729] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:13:06.737] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:13:06.739] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:13:06.746] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:13:18.575] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:13:18.584] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:13:18.587] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:13:18.594] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:13:24.618] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:13:24.627] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:13:24.628] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:13:24.636] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:14:03.638] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:14:03.646] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:14:03.647] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:14:03.656] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:14:29.560] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:14:29.568] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:14:29.570] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:14:29.577] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:15:16.154] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:15:16.164] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:15:16.168] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:15:16.175] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:15:23.551] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:15:23.561] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:15:23.562] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:15:23.571] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:16:20.926] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:16:20.934] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:16:20.936] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:16:20.942] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:17:22.302] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:17:22.310] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:17:22.311] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:17:22.318] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:17:31.534] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:17:31.543] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:17:31.545] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:17:31.551] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:17:43.018] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:17:43.026] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:17:43.028] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:17:43.035] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:17:54.055] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:17:54.063] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:17:54.065] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:17:54.072] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:18:00.691] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:18:00.701] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:18:00.705] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:18:00.711] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:18:10.209] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:18:10.218] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:18:10.221] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:18:10.228] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:20:55.081] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:20:55.091] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:20:55.092] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:20:55.101] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:21:11.321] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:21:11.330] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:21:11.332] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:21:11.338] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:21:13.706] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:21:13.714] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:21:13.716] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:21:13.722] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:21:14.695] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:21:14.704] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:21:14.705] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:21:14.713] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:21:23.256] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:21:23.264] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:21:23.267] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:21:23.273] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:21:36.663] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:21:36.674] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:21:36.677] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:21:36.686] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:23:18.012] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:23:18.020] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:23:18.023] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:23:18.029] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:23:39.046] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:23:39.055] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:23:39.056] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:23:39.063] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 21:24:01.549] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 21:24:01.557] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 21:24:01.559] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 21:24:01.566] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 22:09:05.554] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 22:09:05.562] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 22:09:05.568] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 22:09:05.574] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 22:09:22.406] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 22:09:22.416] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 22:09:22.417] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 22:09:22.425] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 22:09:26.086] [undefined] PUT(/:id): failed due to invalid values with status 400
[2025-07-21 22:09:34.169] [undefined] PUT(/:id): failed due to invalid values with status 400
[2025-07-21 22:09:39.872] [undefined] PUT(/:id): failed due to invalid values with status 400
[2025-07-21 22:10:27.086] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 22:10:27.095] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 22:10:27.096] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 22:10:27.104] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 22:10:32.179] [undefined] PUT(/:id): try to update channel with id 1
[2025-07-21 22:10:32.181] [undefined] PUT(/:id): Successfully updated channel with status 200
[2025-07-21 22:10:32.192] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 22:10:32.199] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 22:10:33.864] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 22:10:33.873] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 22:10:33.875] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 22:10:33.882] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 22:10:34.455] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 22:10:34.464] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 22:10:34.466] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 22:10:34.472] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 22:10:34.943] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 22:10:34.951] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 22:10:34.954] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 22:10:34.960] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 22:10:41.192] [undefined] PUT(/:id): try to update channel with id 1
[2025-07-21 22:10:41.201] [undefined] PUT(/:id): Successfully updated channel with status 200
[2025-07-21 22:10:41.210] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 22:10:41.217] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 22:10:42.177] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 22:10:42.186] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 22:10:42.187] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 22:10:42.195] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 22:10:45.345] [undefined] GET(/:id): try to get video 1
[2025-07-21 22:10:45.354] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-07-21 22:10:45.363] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-07-21 22:10:45.372] [undefined] GET(/:id/similar): No tags found for video 1 with status 404
[2025-07-21 22:10:45.387] [undefined] GET(/:id/views): try to add views for video 1
[2025-07-21 22:10:45.394] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-07-21 22:10:50.080] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-21 22:10:50.081] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-21 22:10:50.082] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-21 22:10:50.085] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-21 22:10:50.090] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-21 22:10:53.388] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 22:10:53.396] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 22:10:53.399] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 22:10:53.404] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-21 22:11:01.752] [undefined] PUT(/:id): try to update channel with id 1
[2025-07-21 22:11:01.776] [undefined] PUT(/:id): Successfully updated channel with status 200
[2025-07-21 22:11:01.787] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 22:11:01.794] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 22:11:05.090] [undefined] GET(/:id): try to get channel with id 1
[2025-07-21 22:11:05.099] [undefined] GET(/:id/stats): try to get stats
[2025-07-21 22:11:05.102] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-21 22:11:05.107] [undefined] GET(/:id/stats): Successfully get stats with status 200

19
frontend/src/components/VideoStatListElement.jsx

@ -0,0 +1,19 @@
export default function VideoStatListElement ({ video, onClick }) {
return (
<div className="flex p-4 gap-4 glassmorphism cursor-pointer" onClick={onClick} >
<img
src={video.thumbnail}
alt=""
className="w-1/4 aspect-video rounded-sm"
/>
<div>
<h3 className="text-white text-2xl font-montserrat font-bold" >{video.title}</h3>
<p className="text-white text-lg font-montserrat font-normal">Vues: {video.views}</p>
<p className="text-white text-lg font-montserrat font-normal">Likes: {video.likes}</p>
<p className="text-white text-lg font-montserrat font-normal">Commentaires: {video.comments}</p>
</div>
</div>
);
}

4
frontend/src/index.css

@ -31,6 +31,10 @@
backdrop-filter: blur(27.5px); backdrop-filter: blur(27.5px);
} }
.resizable-none {
resize: none;
}
@theme { @theme {
/* Fonts */ /* Fonts */
--font-inter: 'Inter', sans-serif; --font-inter: 'Inter', sans-serif;

2
frontend/src/pages/Account.jsx

@ -255,7 +255,7 @@ export default function Account() {
<div className="glassmorphism p-10 w-full flex justify-between"> <div className="glassmorphism p-10 w-full flex justify-between">
<p className="text-3xl text-white mb-2 font-montserrat font-bold">{userChannel.channel.name}</p> <p className="text-3xl text-white mb-2 font-montserrat font-bold">{userChannel.channel.name}</p>
<button> <button>
<span onClick={() => navigation("/manage-channel")} className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-semibold cursor-pointer"> <span onClick={() => navigation(`/manage-channel/${userChannel.channel.id}`)} className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-semibold cursor-pointer">
Gérer la chaîne Gérer la chaîne
</span> </span>
</button> </button>

208
frontend/src/pages/ManageChannel.jsx

@ -0,0 +1,208 @@
import Navbar from "../components/Navbar.jsx";
import {useEffect, useState} from "react";
import {useNavigate, useParams} from "react-router-dom";
import {useAuth} from "../contexts/AuthContext.jsx";
import VideoStatListElement from "../components/VideoStatListElement.jsx";
export default function ManageChannel() {
const {id} = useParams();
const {user} = useAuth();
const navigate = useNavigate();
const [channel, setChannel] = useState();
const [channelStats, setChannelStats] = useState();
const [channelName, setChannelName] = useState(null);
const [description, setDescription] = useState(null);
const [editMode, setEditMode] = useState(false);
const token = localStorage.getItem("token");
const nonEditModeClasses = "text-2xl font-bold text-white p-2 focus:text-white focus:outline-none w-full font-montserrat resizable-none text-center";
const editModeClasses = nonEditModeClasses + " glassmorphism";
const nonEditModeClassesTextArea = "text-md font-normal text-white p-2 focus:text-white focus:outline-none w-full font-montserrat resizable-none w-full"
const editModeClassesTextArea = nonEditModeClassesTextArea + " glassmorphism h-48";
useEffect(() => {
fetchChannelData()
fetchChannelStats()
}, []);
const fetchChannelData = async () => {
try {
const request = await fetch(`/api/channels/${id}`, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
}
})
const result = await request.json();
setChannel(result);
} catch (error) {
console.error("Error fetching channel data:", error);
}
}
const fetchChannelStats = async () => {
try {
const request = await fetch(`/api/channels/${id}/stats`, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
}
})
const result = await request.json();
setChannelStats(result);
} catch (error) {
console.error("Error fetching channel stats", error);
}
}
const handleUpdateChannel = async () => {
if (!editMode) return;
try {
const response = await fetch(`/api/channels/${id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
},
body: JSON.stringify({
name: channelName || channel.name,
description: description || channel.description,
})
});
if (response.ok) {
setEditMode(false);
fetchChannelData(); // Refresh channel data after update
} else {
console.error("Failed to update channel");
}
} catch (error) {
console.error("Error updating channel:", error);
}
}
return (
<div className="min-w-screen min-h-screen bg-linear-to-br from-left-gradient to-right-gradient">
<Navbar isSearchPage={false} />
<main className="pt-[118px] px-36 flex">
{/* LEFT SIDE */}
<form className="glassmorphism w-1/3 h-screen py-10 px-4">
<img src={user.picture} className="w-1/3 aspect-square object-cover rounded-full mx-auto" alt=""/>
<label htmlFor="name" className={`text-2xl text-white mb-1 block font-montserrat ${editMode ? "block" : "hidden"} `}>
Nom de chaine
</label>
<input
type="text"
id="name"
value={channelName || channelName === "" ? channelName : channel ? channel.name : "Chargement"}
className={(editMode ? editModeClasses : nonEditModeClasses)}
onChange={(e) => setChannelName(e.target.value)}
placeholder="Nom d'utilisateur"
disabled={!editMode}
/>
<label htmlFor="name" className={`text-2xl text-white mb-1 block font-montserrat`}>
Description
</label>
<textarea
name="description"
id=""
className={(editMode ? editModeClassesTextArea : nonEditModeClassesTextArea)}
value={description || description === "" ? description : channel ? channel.description : "Chargement"}
onChange={(e) => setDescription(e.target.value)}
placeholder="Description de votre chaine"
disabled={!editMode}
></textarea>
{
editMode ? (
<div className="mt-4">
<button
type="button"
className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-black cursor-pointer"
onClick={handleUpdateChannel}
>
Enregistrer
</button>
<button
type="button"
className="bg-red-500 p-3 rounded-sm text-white font-montserrat text-2xl font-black cursor-pointer ml-3"
onClick={() => setEditMode(!editMode)}
>
Annuler
</button>
</div>
) : (
<button
type="button"
className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-black cursor-pointer mt-4"
onClick={() => setEditMode(!editMode)}
>
Modifier
</button>
)
}
</form>
{/* RIGHT SIDE */}
<div className="w-2/3 h-screen pl-10" >
{/* VIEW / SUBSCRIBERS STATS */}
<div className="flex gap-4" >
<div className="glassmorphism flex-1 h-32 flex flex-col justify-center items-center" >
{/* TOTAL VIEWS */}
<p className="text-white text-xl font-montserrat font-semibold" >Vues totales</p>
<p className="text-white text-2xl font-montserrat font-bold" >{channelStats ? channelStats.views : "0"}</p>
</div>
<div className="glassmorphism flex-1 h-32 flex flex-col justify-center items-center" >
{/* TOTAL SUBSCRIBERS */}
<p className="text-white text-xl font-montserrat font-semibold" >Abonnés</p>
<p className="text-white text-2xl font-montserrat font-bold" >{channelStats ? channelStats.subscribers : "0"}</p>
</div>
</div>
{/* VIDEOS */}
<div className="flex justify-between">
<h2 className="text-white text-3xl font-montserrat font-bold mt-10" >Vidéos</h2>
<button
className="bg-primary px-2 py-1 rounded-sm text-white font-montserrat text-md font-semibold cursor-pointer mt-4"
onClick={() => navigate("/add-video")}
>
Ajouter une vidéo
</button>
</div>
{ channel?.videos?.length > 0 ? (
<div className="flex flex-col gap-4 mt-5">
{channel.videos.map((video) => (
<VideoStatListElement
video={video}
onClick={() => navigate("/manage-video/" + video.id)}
key={video.id}
/>
))}
</div>
) : (
<p className="text-white text-xl font-montserrat mt-4">Aucune vidéo trouvée pour cette chaîne.</p>
)}
</div>
</main>
</div>
)
}

9
frontend/src/routes/routes.jsx

@ -4,6 +4,7 @@ import Register from '../pages/Register.jsx'
import Video from '../pages/Video.jsx' import Video from '../pages/Video.jsx'
import ProtectedRoute from '../components/ProtectedRoute.jsx' import ProtectedRoute from '../components/ProtectedRoute.jsx'
import Account from "../pages/Account.jsx"; import Account from "../pages/Account.jsx";
import ManageChannel from "../pages/ManageChannel.jsx";
const routes = [ const routes = [
{ path: "/", element: <Home/> }, { path: "/", element: <Home/> },
@ -34,6 +35,14 @@ const routes = [
<Account/> <Account/>
</ProtectedRoute> </ProtectedRoute>
) )
},
{
path: "/manage-channel/:id",
element: (
<ProtectedRoute requireAuth={true}>
<ManageChannel/>
</ProtectedRoute>
)
} }
] ]

Loading…
Cancel
Save