From f97d04ec81103c02d0df8487e31a2d159e947139 Mon Sep 17 00:00:00 2001 From: Pakize Bozkurt Date: Thu, 7 Sep 2023 21:12:08 +0100 Subject: [PATCH 1/9] 22-youtube-video ticket --- langjo-frontend/package-lock.json | 36 ------------------------------- langjo-frontend/src/Home.js | 1 - 2 files changed, 37 deletions(-) diff --git a/langjo-frontend/package-lock.json b/langjo-frontend/package-lock.json index c70a4a1..a596918 100644 --- a/langjo-frontend/package-lock.json +++ b/langjo-frontend/package-lock.json @@ -14,7 +14,6 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "axios": "^1.4.0", - "axios": "^1.4.0", "bootstrap": "^5.3.0", "bootstrap-icons": "^1.10.5", "react": "^18.2.0", @@ -24,7 +23,6 @@ "react-router-dom": "^6.14.1", "react-scripts": "^5.0.1", "react-toastify": "^9.1.3", - "react-toastify": "^9.1.3", "web-vitals": "^2.1.4" } }, @@ -14219,40 +14217,6 @@ } } }, - "node_modules/react-dev-utils": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", - "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", - "dependencies": { - "@babel/code-frame": "^7.16.0", - "address": "^1.1.2", - "browserslist": "^4.18.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "detect-port-alt": "^1.1.6", - "escape-string-regexp": "^4.0.0", - "filesize": "^8.0.6", - "find-up": "^5.0.0", - "fork-ts-checker-webpack-plugin": "^6.5.0", - "global-modules": "^2.0.0", - "globby": "^11.0.4", - "gzip-size": "^6.0.0", - "immer": "^9.0.7", - "is-root": "^2.1.0", - "loader-utils": "^3.2.0", - "open": "^8.4.0", - "pkg-up": "^3.1.0", - "prompts": "^2.4.2", - "react-error-overlay": "^6.0.11", - "recursive-readdir": "^2.2.2", - "shell-quote": "^1.7.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/react-dev-utils/node_modules/loader-utils": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", diff --git a/langjo-frontend/src/Home.js b/langjo-frontend/src/Home.js index 009a743..6c6f5d0 100644 --- a/langjo-frontend/src/Home.js +++ b/langjo-frontend/src/Home.js @@ -1,7 +1,6 @@ import React from "react"; import LevelTest from "./components/LevelTest/LevelTest"; import BeginnerLevel from "./components/BeginnerLevel/BeginnerLevel"; -import BeginnerLevel from "./components/BeginnerLevel/BeginnerLevel"; import BlocksCards from "./components/BlockCards/BlocksCards"; import Hero from "./components/Hero/Hero"; From bc72b7db5c8b595d50b80e55b7a31f7c724ea858 Mon Sep 17 00:00:00 2001 From: Pakize Bozkurt Date: Thu, 7 Sep 2023 21:36:22 +0100 Subject: [PATCH 2/9] deleted unnecessary component --- langjo-frontend/src/Pages.js | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 langjo-frontend/src/Pages.js diff --git a/langjo-frontend/src/Pages.js b/langjo-frontend/src/Pages.js deleted file mode 100644 index 6d6161e..0000000 --- a/langjo-frontend/src/Pages.js +++ /dev/null @@ -1,19 +0,0 @@ -import React from "react"; -import { Routes, Route } from "react-router-dom"; -import EnglishLevel from "./components/EnglishLevel/EnglishLevel"; - -import Home from "./Home.js"; -// import LevelTest from "./components/LevelTest/LevelTest"; - -function Pages() { - return ( -
- - } /> - } /> - -
- ); -} - -export default Pages; From cdb562b04c75b77ba8ff491cce94c91b7712661a Mon Sep 17 00:00:00 2001 From: Pakize Bozkurt Date: Tue, 12 Sep 2023 23:23:07 +0100 Subject: [PATCH 3/9] api endpoints for videopage --- langjo-frontend/package.json | 2 +- langjo-frontend/src/Home.js | 4 ++ .../components/BeginnerLevel/BeginnerLevel.js | 11 ++++ .../src/components/VideoPage/VideoPage.js | 60 +++++++++++++++++++ langjo-frontend/src/pages/Pages.js | 3 + 5 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 langjo-frontend/src/components/VideoPage/VideoPage.js diff --git a/langjo-frontend/package.json b/langjo-frontend/package.json index 84a1085..d6146b6 100644 --- a/langjo-frontend/package.json +++ b/langjo-frontend/package.json @@ -1,4 +1,4 @@ -{ +{ "proxy": "http://localhost:5000", "name": "langjo-frontend", "version": "0.1.0", "private": true, diff --git a/langjo-frontend/src/Home.js b/langjo-frontend/src/Home.js index 6c6f5d0..2bdac93 100644 --- a/langjo-frontend/src/Home.js +++ b/langjo-frontend/src/Home.js @@ -4,6 +4,8 @@ import BeginnerLevel from "./components/BeginnerLevel/BeginnerLevel"; import BlocksCards from "./components/BlockCards/BlocksCards"; import Hero from "./components/Hero/Hero"; + + function Home() { return (
@@ -11,6 +13,8 @@ function Home() { + +
); } diff --git a/langjo-frontend/src/components/BeginnerLevel/BeginnerLevel.js b/langjo-frontend/src/components/BeginnerLevel/BeginnerLevel.js index 7e1b706..2075cbb 100644 --- a/langjo-frontend/src/components/BeginnerLevel/BeginnerLevel.js +++ b/langjo-frontend/src/components/BeginnerLevel/BeginnerLevel.js @@ -54,6 +54,17 @@ function BeginnerLevel() { ); })} +
+ + See More + +
); diff --git a/langjo-frontend/src/components/VideoPage/VideoPage.js b/langjo-frontend/src/components/VideoPage/VideoPage.js new file mode 100644 index 0000000..eef82ee --- /dev/null +++ b/langjo-frontend/src/components/VideoPage/VideoPage.js @@ -0,0 +1,60 @@ +import React, { useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; + +const VideoPage = () => { + const { videoId } = useParams(); + const [videoData, setVideoData] = useState(null); + + useEffect(() => { + const fetchVideoData = async () => { + try { + + const res = await fetch(`api/videos/`); + + if (!res.ok) throw new Error(`HTTP error! Status: ${res.status}`); + const data = await res.json(); + + setVideoData(data.data); + } catch (error) { + console.error("Error fetching video data:", error); + } + }; + + if (videoId) { + + fetchVideoData(); + } + }, [videoId]); + console.log(videoData); + + if (!videoData) { + return ( +
+
+ Loading... +
+
+ ); + } + + return ( +
+
+
+

{videoData.title}

+ {videoData && videoData.map((videoData) => ( +

{videoData.title}

+ ))} + {/*
+ +
*/} +
+
+
+ ); +}; + +export default VideoPage; diff --git a/langjo-frontend/src/pages/Pages.js b/langjo-frontend/src/pages/Pages.js index 82dd8db..33129e8 100644 --- a/langjo-frontend/src/pages/Pages.js +++ b/langjo-frontend/src/pages/Pages.js @@ -6,6 +6,8 @@ import LogIn from "../components/LogIn/LogIn"; import BeginnerLevel from "../components/BeginnerLevel/BeginnerLevel"; import EnglishLevel from "../components/EnglishLevel/EnglishLevel"; import BlockCards from "../components/BlockCards/BlocksCards"; +import VideoPage from "../components/VideoPage/VideoPage"; + function Pages() { return ( @@ -17,6 +19,7 @@ function Pages() { } /> } /> } /> + } /> ); From 79e4349dbff784667b57ad096267012b4a2c5ef6 Mon Sep 17 00:00:00 2001 From: Pakize Bozkurt Date: Wed, 13 Sep 2023 10:08:01 +0100 Subject: [PATCH 4/9] videopage --- server/controllers/video.js | 22 ++++++++++++++++++++ server/index.js | 35 ++++++++++---------------------- server/routes/beginners-level.js | 6 +++++- server/routes/videos.js | 19 +++++++++++++++++ 4 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 server/routes/videos.js diff --git a/server/controllers/video.js b/server/controllers/video.js index 87c98a9..b673aa3 100644 --- a/server/controllers/video.js +++ b/server/controllers/video.js @@ -17,3 +17,25 @@ export const displayVideo = async (req, res, next) => { next(error); } }; +export const getVideo = async (req, res, next) => { + try { + const video = await Video.findById(req.params.id); + res.status(200).json({ success: true, data: video }); + } catch (error) { + next(error); + } +}; + +export const getVideoByTitle = async (req, res, next) => { + try { + const video = await Video.findOne({ title: req.params.title }); + if (!video) { + return res + .status(404) + .json({ success: false, message: "Video not found" }); + } + res.status(200).json({ success: true, data: video }); + } catch (error) { + next(error); + } +}; \ No newline at end of file diff --git a/server/index.js b/server/index.js index c431e5d..73e4197 100644 --- a/server/index.js +++ b/server/index.js @@ -2,18 +2,14 @@ import express from "express"; import mongoose from "mongoose"; import cors from "cors"; import * as dotenv from "dotenv"; -import { userRouter } from "./routes/users.js" -import { videoRouter } from "./routes/beginners-level.js" +import { userRouter } from "./routes/users.js"; +import { videoRouter } from "./routes/beginners-level.js"; import { authRouter } from "./routes/auth.js"; import { commentRouter } from "./routes/comment.js"; import cookieParser from "cookie-parser"; - dotenv.config(); - const PORT = process.env.PORT || 5000; const app = express(); - -// Enable CORS for all routes app.use( cors({ origin: "http://localhost:3000", @@ -21,33 +17,24 @@ app.use( allowedHeaders: "Content-Type, Authorization, X-Requested-With, Accept", }) ); - const connect = () => { mongoose.connect( "mongodb+srv://chioma:chioma@cluster0.cfdz7fx.mongodb.net/?retryWrites=true&w=majority" ); }; - -app.get('/', (req, res) => { - res.json({ message: "This is LangJo App 🏴󠁧󠁢󠁥󠁮󠁧󠁿!" }); -}) -app.use(cookieParser()) +app.get("/", (req, res) => { + res.json({ message: "This is LangJo App :flag-england:!" }); +}); +app.use(cookieParser()); app.use(express.json()); -app.use("/api/auth", authRouter) -app.use("/api/users", userRouter) -app.use("/api/videos", videoRouter) -app.use("/api/comments", commentRouter) - -// API routes +app.use("/api/auth", authRouter); app.use("/api/users", userRouter); -app.use("/api/videos", videoRouter); - -// Error-handling middleware +app.use("/api/videos", videoRouter); // This route will handle both "/api/videos/" and "/api/videos/:id" +app.use("/api/comments", commentRouter); app.use((error, req, res, next) => { - // Error handling code + res.status(500).json({ message: error.message }); }); - +connect(); app.listen(PORT, () => { - connect(); console.log(`Listening on port ${PORT}`); }); diff --git a/server/routes/beginners-level.js b/server/routes/beginners-level.js index 40ab754..0ac2aba 100644 --- a/server/routes/beginners-level.js +++ b/server/routes/beginners-level.js @@ -1,6 +1,7 @@ import express from "express"; import cors from "cors"; -import { displayVideo, createVideo } from "../controllers/video.js"; +import { getVideo, getVideoByTitle, displayVideo, createVideo } from "../controllers/video.js"; +import { verifyToken } from "../verifyToken.js"; const app = express(); app.use( @@ -17,5 +18,8 @@ app.use(express.json()); const videoRouter = express.Router(); videoRouter.get("/beginners-level", displayVideo); videoRouter.post("/beginners-level", createVideo); +videoRouter.get("/beginners-level/:videoId", getVideo); +videoRouter.put("/beginners-level/:videoId", verifyToken); +videoRouter.get("/title/:title", getVideoByTitle); export { videoRouter }; diff --git a/server/routes/videos.js b/server/routes/videos.js new file mode 100644 index 0000000..7c538e9 --- /dev/null +++ b/server/routes/videos.js @@ -0,0 +1,19 @@ +import express from "express"; +import { getVideo, createVideo } from "../controllers/video.js"; +import { verifyToken } from "../verifyToken.js"; + +const videoRouter = express.Router(); + +// get all videos +videoRouter.get("/videos", getVideo); + +// create a new video +videoRouter.post("/videos", createVideo); + +// get a video +videoRouter.get("/videos/:videoId", getVideo); + +// put a video +videoRouter.put("/videos/:videoId", verifyToken); + +export { videoRouter }; From 85e88a8bb4da1ade01c54d4be4da0d13d4ef5087 Mon Sep 17 00:00:00 2001 From: JanefrancessC Date: Mon, 18 Sep 2023 10:46:32 +0100 Subject: [PATCH 5/9] Display one video added --- server/controllers/video.js | 15 +++++++++++++++ server/package-lock.json | 12 ++++++++++++ server/routes/beginners-level.js | 5 +++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/server/controllers/video.js b/server/controllers/video.js index 87c98a9..3974070 100644 --- a/server/controllers/video.js +++ b/server/controllers/video.js @@ -10,6 +10,21 @@ export const createVideo = async (req, res, next) => { }; export const displayVideo = async (req, res, next) => { + try { + const videoId = req.params.id; + const video = await Video.findById(videoId); + if (!video) { + return res + .status(404) + .json({ success: false, message: "Video not found" }); + } + res.status(200).json({ success: true, data: video }); + } catch (error) { + next(error); + } +}; + +export const displayVideos = async (req, res, next) => { try { const video = await Video.find(); res.status(200).json({ success: true, data: video }); diff --git a/server/package-lock.json b/server/package-lock.json index 1f4244d..44fcf4c 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -11,9 +11,11 @@ "dependencies": { "bcryptjs": "^2.4.3", "cookie-parser": "^1.4.6", + "cors": "^2.8.5", "dotenv": "^16.1.3", "express": "^4.18.2", "jsonwebtoken": "^9.0.0", + "mongodb": "^5.6.0", "mongoose": "^7.3.4", "nodemon": "^2.0.22" } @@ -140,6 +142,11 @@ "node": ">=14.20.1" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -1310,6 +1317,11 @@ "engines": { "node": ">=12" } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } } diff --git a/server/routes/beginners-level.js b/server/routes/beginners-level.js index 40ab754..25c4267 100644 --- a/server/routes/beginners-level.js +++ b/server/routes/beginners-level.js @@ -1,6 +1,6 @@ import express from "express"; import cors from "cors"; -import { displayVideo, createVideo } from "../controllers/video.js"; +import { displayVideo, displayVideos, createVideo } from "../controllers/video.js"; const app = express(); app.use( @@ -15,7 +15,8 @@ app.use( app.use(express.json()); const videoRouter = express.Router(); -videoRouter.get("/beginners-level", displayVideo); +videoRouter.get("/beginners-level/:id", displayVideo); +videoRouter.get("/beginners-level", displayVideos); videoRouter.post("/beginners-level", createVideo); export { videoRouter }; From 622e737cd969fe5182dc3d58d031775f5fbc813f Mon Sep 17 00:00:00 2001 From: JanefrancessC Date: Mon, 18 Sep 2023 15:44:28 +0100 Subject: [PATCH 6/9] added a search query option --- server/controllers/video.js | 14 +++++++++++++- server/routes/beginners-level.js | 5 +++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/server/controllers/video.js b/server/controllers/video.js index 3b274f4..fc3c851 100644 --- a/server/controllers/video.js +++ b/server/controllers/video.js @@ -53,4 +53,16 @@ export const getVideoByTitle = async (req, res, next) => { } catch (error) { next(error); } -}; \ No newline at end of file +}; + +export const searchVideo = async (req, res, next) => { + const query = req.query.q; + try { + const videos = await Video.find({ + title: { $regex: query, $options: "i" }, + }).limit(10); + res.status(200).json({ success: true, data: videos }); + } catch (error) { + next(error); + } +}; diff --git a/server/routes/beginners-level.js b/server/routes/beginners-level.js index 3734985..ed51b5c 100644 --- a/server/routes/beginners-level.js +++ b/server/routes/beginners-level.js @@ -1,6 +1,6 @@ import express from "express"; import cors from "cors"; -import { getVideo, getVideoByTitle, displayVideo, createVideo, displayVideos} from "../controllers/video.js"; +import { getVideo, getVideoByTitle, displayVideo, createVideo, displayVideos, searchVideo } from "../controllers/video.js"; import { verifyToken } from "../verifyToken.js"; const app = express(); @@ -17,8 +17,9 @@ app.use( app.use(express.json()); const videoRouter = express.Router(); -videoRouter.get("/beginners-level/:id", displayVideo); +videoRouter.get("/beginners-level/search", searchVideo); videoRouter.get("/beginners-level", displayVideos); +videoRouter.get("/beginners-level/:id", displayVideo); videoRouter.post("/beginners-level", createVideo); videoRouter.get("/beginners-level/:videoId", getVideo); videoRouter.put("/beginners-level/:videoId", verifyToken); From 4408596967aee638582a45e4e541cb86dcbd1b19 Mon Sep 17 00:00:00 2001 From: Pakize Bozkurt Date: Wed, 20 Sep 2023 19:28:53 +0100 Subject: [PATCH 7/9] added one video on video page --- .../components/BeginnerLevel/BeginnerLevel.js | 23 +++++---- .../src/components/NavBar/NavBar.js | 2 +- .../src/components/VideoPage/VideoPage.js | 50 ++++++++----------- langjo-frontend/src/pages/Pages.js | 2 +- 4 files changed, 36 insertions(+), 41 deletions(-) diff --git a/langjo-frontend/src/components/BeginnerLevel/BeginnerLevel.js b/langjo-frontend/src/components/BeginnerLevel/BeginnerLevel.js index 2075cbb..e641300 100644 --- a/langjo-frontend/src/components/BeginnerLevel/BeginnerLevel.js +++ b/langjo-frontend/src/components/BeginnerLevel/BeginnerLevel.js @@ -50,21 +50,22 @@ function BeginnerLevel() { > + ); })} - + ); diff --git a/langjo-frontend/src/components/NavBar/NavBar.js b/langjo-frontend/src/components/NavBar/NavBar.js index 809d03f..4c06f8f 100644 --- a/langjo-frontend/src/components/NavBar/NavBar.js +++ b/langjo-frontend/src/components/NavBar/NavBar.js @@ -35,7 +35,7 @@ function NavBar() { Beginner - Intermadite + Intermediate Advance Quiz diff --git a/langjo-frontend/src/components/VideoPage/VideoPage.js b/langjo-frontend/src/components/VideoPage/VideoPage.js index eef82ee..9b4316d 100644 --- a/langjo-frontend/src/components/VideoPage/VideoPage.js +++ b/langjo-frontend/src/components/VideoPage/VideoPage.js @@ -1,32 +1,25 @@ import React, { useEffect, useState } from "react"; import { useParams } from "react-router-dom"; + const VideoPage = () => { - const { videoId } = useParams(); + const videoId = useParams(); const [videoData, setVideoData] = useState(null); - useEffect(() => { const fetchVideoData = async () => { try { - - const res = await fetch(`api/videos/`); - - if (!res.ok) throw new Error(`HTTP error! Status: ${res.status}`); - const data = await res.json(); - - setVideoData(data.data); + const res = await fetch( + `http://localhost:5000/api/videos/beginners-level/${videoId.id}` + ); + if (!res.ok) throw new Error(`HTTP error! Status: ${res.status}`); + const data = await res.json(); + setVideoData(data.data); } catch (error) { - console.error("Error fetching video data:", error); + console.error("Failed to fetch video data:", error); } }; - - if (videoId) { - - fetchVideoData(); - } + fetchVideoData(); }, [videoId]); - console.log(videoData); - if (!videoData) { return (
@@ -36,25 +29,26 @@ const VideoPage = () => {
); } - + const videoGet = + (videoData.videoUrl && videoData.videoUrl.split("/").pop()) || ""; return (

{videoData.title}

- {videoData && videoData.map((videoData) => ( -

{videoData.title}

- ))} - {/*
- -
*/} +

{videoData.desc}

+
+
- ); })}
-
); diff --git a/langjo-frontend/src/components/VideoPage/VideoPage.js b/langjo-frontend/src/components/VideoPage/VideoPage.js index 9b4316d..c62fa39 100644 --- a/langjo-frontend/src/components/VideoPage/VideoPage.js +++ b/langjo-frontend/src/components/VideoPage/VideoPage.js @@ -22,7 +22,7 @@ const VideoPage = () => { }, [videoId]); if (!videoData) { return ( -
+
Loading...
@@ -32,15 +32,17 @@ const VideoPage = () => { const videoGet = (videoData.videoUrl && videoData.videoUrl.split("/").pop()) || ""; return ( -
-
-
-

{videoData.title}

-

{videoData.desc}

+
+
+
+

{videoData.title}

+

{videoData.desc}