Browse Source

FINISH features/create-video

features/create-channel
Astri4-4 5 months ago
parent
commit
4af948fcd7
  1. 9
      .gitignore
  2. 7
      backend/app/controllers/video.controller.js
  3. 132
      backend/logs/access.log
  4. 274
      frontend/src/pages/AddVideo.jsx
  5. 9
      frontend/src/routes/routes.jsx

9
.gitignore

@ -0,0 +1,9 @@
/backend/app/uploads/
# Ignore all files in the uploads directory
/frontend/node_modules
/backend/node_modules
# Ignore node_modules directories in both frontend and backend
/frontend/dist
# Ignore the build output directory for the frontend

7
backend/app/controllers/video.controller.js

@ -49,11 +49,12 @@ export async function upload(req, res) {
logger.write("try to upload video");
const releaseDate = new Date(Date.now()).toISOString();
const query = `INSERT INTO videos (title, thumbnail, description, channel, visibility, file, slug, format, release_date) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`;
await client.query(query, [video.title, 'null', video.description, video.channel, video.visibility, video.file, video.slug, video.format, releaseDate]);
const query = `INSERT INTO videos (title, thumbnail, description, channel, visibility, file, slug, format, release_date) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id`;
const idResult = await client.query(query, [video.title, 'null', video.description, video.channel, video.visibility, video.file, video.slug, video.format, releaseDate]);
const id = idResult.rows[0].id;
logger.write("successfully uploaded video", 200);
await client.end()
res.status(200).json({"message": "Successfully uploaded video"});
res.status(200).json({"message": "Successfully uploaded video", "id":id});
}

132
backend/logs/access.log

@ -3691,3 +3691,135 @@
[2025-07-24 21:50:12.955] [undefined] GET(/:id/similar): successfully get similar videos for video 3 with status 200
[2025-07-24 21:50:12.973] [undefined] GET(/:id/views): try to add views for video 3
[2025-07-24 21:50:12.980] [undefined] GET(/:id/views): successfully added views for video 3 with status 200
[2025-07-25 19:54:37.439] [undefined] GET(/:id): try to get channel with id 1
[2025-07-25 19:54:37.449] [undefined] GET(/:id/stats): try to get stats
[2025-07-25 19:54:37.452] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-25 19:54:37.458] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-26 08:12:37.895] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 08:12:37.896] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-26 08:12:37.898] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 08:12:37.901] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-26 08:12:37.908] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-26 08:12:38.691] [undefined] GET(/:id): try to get channel with id 1
[2025-07-26 08:12:38.701] [undefined] GET(/:id/stats): try to get stats
[2025-07-26 08:12:38.702] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-26 08:12:38.711] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-26 08:45:16.047] [undefined] POST(/): failed due to invalid values with status 400
[2025-07-26 08:48:28.235] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 08:48:28.237] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 08:48:31.269] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 08:48:31.272] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 08:49:37.594] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 08:49:37.596] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 08:49:56.943] [undefined] POST(/): failed due to invalid values with status 400
[2025-07-26 08:50:18.564] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 08:50:18.567] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 08:50:32.509] [undefined] POST(/): failed due to invalid values with status 400
[2025-07-26 08:53:06.249] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 08:53:06.251] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 08:53:22.601] [undefined] POST(/): failed due to invalid values with status 400
[2025-07-26 08:55:33.886] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 08:55:33.888] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 08:55:42.316] [undefined] POST(/): try to upload video with status undefined
[2025-07-26 08:55:42.320] [undefined] POST(/): successfully uploaded video with status 200
[2025-07-26 08:55:52.499] [undefined] GET(/:id): try to get video 4
[2025-07-26 08:55:52.508] [undefined] GET(/:id): successfully get video 4 with status 200
[2025-07-26 08:55:52.520] [undefined] GET(/:id/similar): try to get similar videos for video 4
[2025-07-26 08:55:52.527] [undefined] GET(/:id/similar): No tags found for video 4 with status 404
[2025-07-26 08:55:52.562] [undefined] GET(/:id/views): try to add views for video 4
[2025-07-26 08:55:52.576] [undefined] GET(/:id/views): successfully added views for video 4 with status 200
[2025-07-26 08:56:02.055] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 08:56:02.057] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 08:56:02.060] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-26 08:56:02.063] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-26 08:56:02.069] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-26 08:56:02.787] [undefined] GET(/:id): try to get channel with id 1
[2025-07-26 08:56:02.796] [undefined] GET(/:id/stats): try to get stats
[2025-07-26 08:56:02.799] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-26 08:56:02.805] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-26 08:56:03.535] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 08:56:03.537] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 08:57:44.716] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 08:57:44.719] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 08:57:54.363] [undefined] POST(/): try to upload video with status undefined
[2025-07-26 08:57:54.366] [undefined] POST(/): successfully uploaded video with status 200
[2025-07-26 08:58:08.735] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 08:58:08.739] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 08:58:18.190] [undefined] POST(/): try to upload video with status undefined
[2025-07-26 08:58:18.194] [undefined] POST(/): successfully uploaded video with status 200
[2025-07-26 09:00:32.892] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 09:00:32.894] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 09:00:45.499] [undefined] POST(/): try to upload video with status undefined
[2025-07-26 09:00:45.503] [undefined] POST(/): successfully uploaded video with status 200
[2025-07-26 09:00:45.551] [undefined] POST(/thumbnail): failed due to invalid values with status 400
[2025-07-26 09:01:41.512] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 09:01:41.514] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 09:01:56.701] [undefined] POST(/): try to upload video with status undefined
[2025-07-26 09:01:56.704] [undefined] POST(/): successfully uploaded video with status 200
[2025-07-26 09:01:56.793] [undefined] POST(/thumbnail): try to add thumbnail to video 8
[2025-07-26 09:01:56.798] [undefined] POST(/thumbnail): successfully uploaded thumbnail with status 200
[2025-07-26 09:02:29.458] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 09:02:29.460] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 09:02:45.369] [undefined] POST(/): try to upload video with status undefined
[2025-07-26 09:02:45.372] [undefined] POST(/): successfully uploaded video with status 200
[2025-07-26 09:02:45.443] [undefined] POST(/thumbnail): try to add thumbnail to video 9
[2025-07-26 09:02:45.446] [undefined] POST(/thumbnail): successfully uploaded thumbnail with status 200
[2025-07-26 09:03:38.478] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 09:03:38.479] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 09:03:54.208] [undefined] POST(/): failed due to invalid values with status 400
[2025-07-26 09:04:01.982] [undefined] POST(/): try to upload video with status undefined
[2025-07-26 09:04:01.985] [undefined] POST(/): successfully uploaded video with status 200
[2025-07-26 09:04:02.052] [undefined] POST(/thumbnail): try to add thumbnail to video 10
[2025-07-26 09:04:02.055] [undefined] POST(/thumbnail): successfully uploaded thumbnail with status 200
[2025-07-26 09:04:02.074] [undefined] PUT(/:id/tags): try to add tags to video 10
[2025-07-26 09:04:02.084] [undefined] PUT(/:id/tags): successfully added tags to video 10 with status 200
[2025-07-26 09:04:08.248] [undefined] GET(/:id): try to get video 10
[2025-07-26 09:04:08.257] [undefined] GET(/:id): successfully get video 10 with status 200
[2025-07-26 09:04:08.270] [undefined] GET(/:id/similar): try to get similar videos for video 10
[2025-07-26 09:04:08.279] [undefined] GET(/:id/similar): successfully get similar videos for video 10 with status 200
[2025-07-26 09:04:08.339] [undefined] GET(/:id/views): try to add views for video 10
[2025-07-26 09:04:08.347] [undefined] GET(/:id/views): successfully added views for video 10 with status 200
[2025-07-26 09:04:12.622] [undefined] GET(/:id): try to get video 10
[2025-07-26 09:04:12.632] [undefined] GET(/:id): successfully get video 10 with status 200
[2025-07-26 09:04:12.648] [undefined] GET(/:id/similar): try to get similar videos for video 10
[2025-07-26 09:04:12.657] [undefined] GET(/:id/similar): successfully get similar videos for video 10 with status 200
[2025-07-26 09:04:12.701] [undefined] GET(/:id/views): try to add views for video 10
[2025-07-26 09:04:12.709] [undefined] GET(/:id/views): successfully added views for video 10 with status 200
[2025-07-26 09:04:23.159] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 09:04:23.161] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-26 09:04:23.163] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 09:04:23.166] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-26 09:04:23.172] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-26 09:04:25.131] [undefined] GET(/:id/channel): try to retrieve channel of user 1
[2025-07-26 09:04:25.133] [undefined] GET(/:id/history): try to retrieve history of user 1
[2025-07-26 09:04:25.134] [undefined] GET(/:id/channel): successfully retrieved channel of user 1 with status 200
[2025-07-26 09:04:25.137] [undefined] GET(/:id/history): successfully retrieved history of user 1 with status 200
[2025-07-26 09:04:25.144] [undefined] GET(/user/:id): Playlists retrieved for user with id 1 with status 200
[2025-07-26 09:04:26.249] [undefined] GET(/:id): try to get channel with id 1
[2025-07-26 09:04:26.258] [undefined] GET(/:id/stats): try to get stats
[2025-07-26 09:04:26.260] [undefined] GET(/:id): Successfully get channel with id 1 with status 200
[2025-07-26 09:04:26.268] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-07-26 09:04:34.109] [undefined] GET(/:id): try to get video 4
[2025-07-26 09:04:34.112] [undefined] GET(/:id/likes/day): try to get likes per day
[2025-07-26 09:04:34.122] [undefined] GET(/:id/likes/day): successfully retrieved likes per day with status 200
[2025-07-26 09:04:34.126] [undefined] GET(/:id): successfully get video 4 with status 200
[2025-07-26 09:04:41.682] [undefined] GET(/:id): try to get video 4
[2025-07-26 09:04:41.684] [undefined] GET(/:id/likes/day): try to get likes per day
[2025-07-26 09:04:41.705] [undefined] GET(/:id/likes/day): successfully retrieved likes per day with status 200
[2025-07-26 09:04:41.709] [undefined] GET(/:id): successfully get video 4 with status 200
[2025-07-26 09:04:51.790] [undefined] POST(/thumbnail): try to add thumbnail to video 4
[2025-07-26 09:04:51.795] [undefined] POST(/thumbnail): successfully uploaded thumbnail with status 200
[2025-07-26 09:05:01.430] [undefined] PUT(/:id/tags): try to add tags to video 4
[2025-07-26 09:05:01.440] [undefined] PUT(/:id/tags): successfully added tags to video 4 with status 200
[2025-07-26 09:05:09.306] [undefined] GET(/:id): try to get video 8
[2025-07-26 09:05:09.314] [undefined] GET(/:id): successfully get video 8 with status 200
[2025-07-26 09:05:09.339] [undefined] GET(/:id/similar): try to get similar videos for video 8
[2025-07-26 09:05:09.348] [undefined] GET(/:id/similar): No tags found for video 8 with status 404
[2025-07-26 09:05:09.363] [undefined] GET(/:id/views): try to add views for video 8
[2025-07-26 09:05:09.374] [undefined] GET(/:id/views): successfully added views for video 8 with status 200
[2025-07-26 09:05:11.418] [undefined] GET(/:id): try to get video 8
[2025-07-26 09:05:11.428] [undefined] GET(/:id): successfully get video 8 with status 200
[2025-07-26 09:05:11.439] [undefined] GET(/:id/similar): try to get similar videos for video 8
[2025-07-26 09:05:11.448] [undefined] GET(/:id/similar): No tags found for video 8 with status 404
[2025-07-26 09:05:11.474] [undefined] GET(/:id/views): try to add views for video 8
[2025-07-26 09:05:11.481] [undefined] GET(/:id/views): successfully added views for video 8 with status 200

274
frontend/src/pages/AddVideo.jsx

@ -0,0 +1,274 @@
import Navbar from "../components/Navbar.jsx";
import {useEffect, useState} from "react";
import Tag from "../components/Tag.jsx";
export default function AddVideo() {
const user = JSON.parse(localStorage.getItem("user"));
const token = localStorage.getItem("token");
const [videoTitle, setVideoTitle] = useState("");
const [videoDescription, setVideoDescription] = useState("");
const [videoTags, setVideoTags] = useState([]);
const [visibility, setVisibility] = useState("public"); // Default visibility
const [videoThumbnail, setVideoThumbnail] = useState(null);
const [videoFile, setVideoFile] = useState(null);
const [channel, setChannel] = useState(null); // Assuming user.channel is the channel ID
useEffect(() => {
fetchChannel();
}, [])
const fetchChannel = async () => {
try {
const response = await fetch(`/api/users/${user.id}/channel`, {
headers: {
"Authorization": `Bearer ${token}` // Assuming you have a token for authentication
},
});
if (!response.ok) {
throw new Error("Erreur lors de la récupération de la chaîne");
}
const data = await response.json();
setChannel(data.channel);
} catch (error) {
console.error("Erreur lors de la récupération de la chaîne :", error);
}
}
const handleTagKeyDown = (e) => {
if (e.key === 'Enter' && videoTags.length < 10) {
e.preventDefault();
const newTag = e.target.value.trim();
if (newTag && !videoTags.includes(newTag)) {
setVideoTags([...videoTags, newTag]);
e.target.value = '';
}
}
}
const handleTagRemove = (tagToRemove) => {
setVideoTags(videoTags.filter(tag => tag !== tagToRemove));
};
// This function handles the submission of the video form
const handleSubmit = async (e) => {
e.preventDefault();
if (!videoTitle || !videoDescription || !videoThumbnail || !videoFile) {
alert("Veuillez remplir tous les champs requis.");
return;
}
if (!channel || !channel.id) {
alert("Erreur: aucune chaîne trouvée. Veuillez actualiser la page.");
return;
}
if (videoTags.length > 10) {
alert("Vous ne pouvez pas ajouter plus de 10 tags.");
return;
}
const formData = new FormData();
formData.append("title", videoTitle);
formData.append("description", videoDescription);
formData.append("channel", channel.id.toString()); // Ensure it's a string
formData.append("visibility", visibility);
formData.append("file", videoFile);
const request = await fetch("/api/videos", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}` // Assuming you have a token for authentication
},
body: formData
});
if (!request.ok) {
const errorData = await request.json();
console.error("Backend validation errors:", errorData);
// Display specific validation errors if available
if (errorData.errors && errorData.errors.length > 0) {
const errorMessages = errorData.errors.map(error =>
`${error.path}: ${error.msg}`
).join('\n');
alert(`Erreurs de validation:\n${errorMessages}`);
} else {
alert(`Erreur lors de l'ajout de la vidéo : ${errorData.message || 'Erreur inconnue'}`);
}
return;
}
// If the video was successfully created, we can now upload the thumbnail
const response = await request.json();
const videoId = response.id;
const thumbnailFormData = new FormData();
thumbnailFormData.append("video", videoId);
thumbnailFormData.append("file", videoThumbnail);
thumbnailFormData.append("channel", channel.id.toString());
const thumbnailRequest = await fetch("/api/videos/thumbnail", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}` // Assuming you have a token for authentication
},
body: thumbnailFormData
});
if (!thumbnailRequest.ok) {
const errorData = await thumbnailRequest.json();
console.error("Backend validation errors:", errorData);
alert(`Erreur lors de l'ajout de la miniature : ${errorData.message || 'Erreur inconnue'}`);
return;
}
// if the thumbnail was successfully uploaded, we can send the tags
const tagsRequest = await fetch(`/api/videos/${videoId}/tags`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}` // Assuming you have a token for authentication
},
body: JSON.stringify({ tags: videoTags, channel: channel.id.toString() }) // Ensure channel ID is a string
});
if (!tagsRequest.ok) {
const errorData = await tagsRequest.json();
console.error("Backend validation errors:", errorData);
alert(`Erreur lors de l'ajout des tags : ${errorData.message || 'Erreur inconnue'}`);
return;
}
// If everything is successful, redirect to the video management page
alert("Vidéo ajoutée avec succès !");
};
return (
<div className="min-w-screen min-h-screen bg-linear-to-br from-left-gradient to-right-gradient">
<Navbar isSearchPage={false} />
<main className="px-36 pt-[118px]">
<h1 className="font-montserrat text-2xl font-black text-white">
Ajouter une vidéo
</h1>
<div className="flex gap-8 mt-8">
{/* Left side: Form for adding video details */}
<form className="flex-1">
<label className="block text-white text-xl font-montserrat font-semibold mb-2" htmlFor="videoTitle">Titre de la vidéo</label>
<input
type="text"
id="videoTitle"
name="videoTitle"
className="w-full p-2 mb-4 glassmorphism focus:outline-none font-inter text-xl text-white"
placeholder="Entrez le titre de la vidéo"
value={videoTitle}
onChange={(e) => setVideoTitle(e.target.value)}
required
/>
<label className="block text-white text-xl font-montserrat font-semibold mb-2" htmlFor="videoDescription">Description de la vidéo</label>
<textarea
id="videoDescription"
name="videoDescription"
className="w-full p-2 mb-4 glassmorphism focus:outline-none font-inter text-xl text-white"
placeholder="Entrez la description de la vidéo"
rows="4"
value={videoDescription}
onChange={(e) => setVideoDescription(e.target.value)}
required
></textarea>
<label className="block text-white text-xl font-montserrat font-semibold mb-1" htmlFor="videoDescription">Tags</label>
<input
type="text"
id="videoTags"
name="videoTags"
className="w-full p-2 mb-4 glassmorphism focus:outline-none font-inter text-xl text-white"
placeholder="Entrez les tags de la vidéo (entré pour valider) 10 maximums"
onKeyDown={handleTagKeyDown}
required
/>
<div className="flex flex-wrap gap-2 mb-2">
{videoTags.map((tag, index) => (
<Tag tag={tag} doShowControls={true} key={index} onSuppress={() => handleTagRemove(tag)} />
))}
</div>
<label className="block text-white text-xl font-montserrat font-semibold mb-2" htmlFor="visibility">Visibilité</label>
<select
name="visibility"
id="visibility"
className="w-full p-2 mb-4 glassmorphism focus:outline-none font-inter text-xl text-white"
value={visibility}
onChange={(e) => setVisibility(e.target.value)}
>
<option value="public">Public</option>
<option value="private">Privé</option>
</select>
<label className="block text-white text-xl font-montserrat font-semibold mb-2" htmlFor="videoThumbnail">Miniature</label>
<input
type="file"
id="videoThumbnail"
name="videoThumbnail"
className="w-full p-2 mb-4 glassmorphism focus:outline-none font-inter text-xl text-white"
accept="image/*"
onChange={(e) => setVideoThumbnail(e.target.files[0])}
required
/>
<label className="block text-white text-xl font-montserrat font-semibold mb-2" htmlFor="videoFile">Fichier vidéo</label>
<input
type="file"
id="videoFile"
name="videoFile"
className="w-full p-2 mb-4 glassmorphism focus:outline-none font-inter text-xl text-white"
accept="video/*"
onChange={(e) => setVideoFile(e.target.files[0])}
required
/>
<button
type="submit"
className="bg-primary text-white font-montserrat p-3 rounded-lg text-2xl font-bold w-full cursor-pointer"
onClick={(e) => { handleSubmit(e) }}
>
Ajouter la vidéo
</button>
</form>
{/* Right side: Preview of the video being added */}
<div className="flex-1 flex justify-center">
<div className="glassmorphism p-4 rounded-lg">
<img
src={videoThumbnail ? URL.createObjectURL(videoThumbnail) : "https://placehold.co/1280x720"} alt={videoTitle}
className="w-[480] h-auto mb-4 rounded-lg"
/>
<h2 className="text-white text-xl font-montserrat font-semibold mb-2">{videoTitle || "Titre de la vidéo"}</h2>
<div className="glassmorphism p-4 rounded-sm">
<p className="text-white font-inter mb-2">
{videoDescription || "Description de la vidéo"}
</p>
<div className="flex flex-wrap gap-2">
{videoTags.length > 0 ? (
videoTags.map((tag, index) => (
<Tag tag={tag} doShowControls={false} key={index} />
))
) : (
<span className="text-gray-400">Aucun tag ajouté</span>
)}
</div>
</div>
</div>
</div>
</div>
</main>
</div>
);
}

9
frontend/src/routes/routes.jsx

@ -6,6 +6,7 @@ import ProtectedRoute from '../components/ProtectedRoute.jsx'
import Account from "../pages/Account.jsx";
import ManageChannel from "../pages/ManageChannel.jsx";
import ManageVideo from "../pages/ManageVideo.jsx";
import AddVideo from "../pages/AddVideo.jsx";
const routes = [
{ path: "/", element: <Home/> },
@ -52,6 +53,14 @@ const routes = [
<ManageVideo/>
</ProtectedRoute>
)
},
{
path: "/add-video",
element: (
<ProtectedRoute requireAuth={true}>
<AddVideo/>
</ProtectedRoute>
)
}
]

Loading…
Cancel
Save