diff --git a/frontend/src/App.js b/frontend/src/App.js index eeb16b7..4c7c75a 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -38,8 +38,14 @@ import Policy from './pages//PaymentPolicy' import Signup from './pages/Signup'; import AddPromotionCourse from './pages/AddPromotionCourse'; -import CourseView from './pages/CourseView'; -import CourseViewPage from './pages/CourseViewPage'; +import CourseViewGuest from './pages/CourseViewGuest'; + +//test +import TestCard from './pages/TestCard'; +import CourseViewCTR from './pages/CourseViewCTR'; +import CourseViewITE from './pages/CourseViewITE'; +import CourseViewInstructor from './pages/CourseViewInstructor'; + function App() { return (
@@ -69,8 +75,23 @@ function App() { element ={} /> } /> + exact path="/api/courses/getCourse/:courseid/guest" + element={} /> + {/* test Route */} + {/* }/> */} + }/> + }/> + + }/> + {/* Nada */} diff --git a/frontend/src/components/Card.js b/frontend/src/components/SubtitleCard.js similarity index 89% rename from frontend/src/components/Card.js rename to frontend/src/components/SubtitleCard.js index 44e2b34..bc21539 100644 --- a/frontend/src/components/Card.js +++ b/frontend/src/components/SubtitleCard.js @@ -1,7 +1,7 @@ import {StyleCard} from './styles/Card.style' -export default function Card({subtitle:{_id,title ,totalHours, tasks}}){ - +export default function SubtitleCard({subtitle:{_id,title ,totalHours, tasks}}){ + return ( diff --git a/frontend/src/components/styles/Card.style.js b/frontend/src/components/styles/Card.style.js index 887ddf1..fd2330a 100644 --- a/frontend/src/components/styles/Card.style.js +++ b/frontend/src/components/styles/Card.style.js @@ -12,6 +12,8 @@ box-shadow :0 0 5px rgba (0,0,0,0.15); margin:5px 5px 5px; padding :0px; position :relative; +width: 900px; + h6{ margin :5px 5px 10px; diff --git a/frontend/src/pages/AddPromotionCourse.js b/frontend/src/pages/AddPromotionCourse.js index 6981e40..6c8f046 100644 --- a/frontend/src/pages/AddPromotionCourse.js +++ b/frontend/src/pages/AddPromotionCourse.js @@ -1,6 +1,6 @@ import axios from "axios"; import { useState } from "react" -import {useParams} from "react-router-dom"; +import {useNavigate, useParams} from "react-router-dom"; import "../index.css" @@ -16,6 +16,9 @@ const AddPromotionCourse=()=>{ //getting courseid from react route const courseid=useParams().courseid; + //useNavigate + const navigate=useNavigate(); + //handling Submitting const handleSubmit=async(e)=>{ @@ -35,6 +38,8 @@ const AddPromotionCourse=()=>{ //Redirecting //Navigating to Instructor course view Page + navigate(`/api/courses/getCourse/${courseid}/Instructor`); + navigate(0); } diff --git a/frontend/src/pages/CourseViewCTR.js b/frontend/src/pages/CourseViewCTR.js new file mode 100644 index 0000000..1af0b45 --- /dev/null +++ b/frontend/src/pages/CourseViewCTR.js @@ -0,0 +1,182 @@ +import axios from 'axios'; +import {useEffect, useState} from 'react'; +import { useParams } from 'react-router-dom'; +import { makeStyles } from '@mui/styles'; +import {Typography} from '@mui/material'; +import { blue } from '@mui/material/colors'; +import {StyledCourseHeader} from '../components/styles/CourseHeader.style' +import SubtitleCard from '../components/SubtitleCard' +// import Card from '@mui/material/Card'; +// import CardActions from '@mui/material/CardActions'; +// import CardContent from '@mui/material/CardContent'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import { spacing } from '@mui/system'; +import { positions } from '@mui/system'; + + + +//stylings custom css + + + +const CourseViewCTR=()=>{ + // const useStyles=makeStyles({ + // courseTitle:{ + // fontSize:60, + // color:blue, + + + + // } + // }) + + //styles + // const classes=useStyles(); + + const [course,setCourse]=useState(null); + const [coursePriceAfterDiscount,setPrice]=useState(''); + const [courseSubtitles,setCourseSubtitles]=useState([]); + + ///api/courses + const {courseid}=useParams(); + + + + //Using useEffect to run only on 1st render to display the course's data + useEffect( ()=>{ + const getCourseanditsSubtitle=async()=>{ + + + try{ + //Sending a get request to the server to get course + const response= await axios.get('http://localhost:5000/api/courses/',{params :{id:courseid}}); + const coursedata=response.data; + setCourse(coursedata); + + //handling setting course price according to discount and its expiry date + //checking if expiry date has passed + //getting today's date (day 1) + let currentdate =new Date(); + let year=currentdate.getFullYear(); + let month=currentdate.getMonth()+1; //because it outputs a number from 0-11 ex:3-->April + let day =currentdate.getDate(); + let dateCformat=`${year}-${month}-${day}` //current date in appropriate format. + let dateC=new Date(dateCformat); + //console.log(dateCformat); + + //getting expiry date from DB "through server response" + const expirydate=coursedata.discountExpireAt; + const dateEformat=expirydate.substring(0,10); //Put it in appropriate format + const dateE=new Date(dateEformat); + //console.log(dateEformat); + + //Comparing current date with expiry date + console.log(dateC.getTime()<=dateE.getTime()); + if(dateC.getTime()<=dateE.getTime()){ + + const newPrice=course.discount*course.price; + setPrice(newPrice); + } + + else{ + setPrice(coursedata.price); + } + + + + //Sending a get request to server to get this course's Subtitles + const response2=await axios.get(`http://localhost:5000/api/courses/getSubtitlesforCourse/${courseid}`); + const subtitlesArray=response2.data; + setCourseSubtitles(subtitlesArray); + + + + + + } + //catching any request error + catch (error){ + + } + + } + + getCourseanditsSubtitle(); } + ,[courseid] ); + + + + + + return ( + +
+
+ + < StyledCourseHeader> +

{course&&course.title}

+
Total Hours :{course&&course.totalhours}
+
Price: {course&&coursePriceAfterDiscount}
+ + + + +
+ + + + + + + + + + + + + +
+ {/* subtitles */} + + {courseSubtitles.map((subtitle)=>( + + ))} + + + + + + + + + + + + + + +
+ + + +
+ ) +} + +export default CourseViewCTR; \ No newline at end of file diff --git a/frontend/src/pages/CourseView.js b/frontend/src/pages/CourseViewGuest.js similarity index 93% rename from frontend/src/pages/CourseView.js rename to frontend/src/pages/CourseViewGuest.js index 22dc51a..b152f7e 100644 --- a/frontend/src/pages/CourseView.js +++ b/frontend/src/pages/CourseViewGuest.js @@ -5,7 +5,7 @@ import { makeStyles } from '@mui/styles'; import {Typography} from '@mui/material'; import { blue } from '@mui/material/colors'; import {StyledCourseHeader} from '../components/styles/CourseHeader.style' -import Card from '../components/Card' +import SubtitleCard from '../components/SubtitleCard' // import Card from '@mui/material/Card'; // import CardActions from '@mui/material/CardActions'; // import CardContent from '@mui/material/CardContent'; @@ -15,7 +15,7 @@ import Card from '../components/Card' -const CourseView=()=>{ +const CourseViewGuest=()=>{ // const useStyles=makeStyles({ // courseTitle:{ // fontSize:60, @@ -126,6 +126,8 @@ const CourseView=()=>{ */} < StyledCourseHeader>

{course&&course.title}

+
Total Hours :{course&&course.totalhours}
+
Price: {course&&coursePriceAfterDiscount}
@@ -154,7 +156,7 @@ const CourseView=()=>{ {courseSubtitles.map((subtitle)=>( - + ))} @@ -178,4 +180,4 @@ const CourseView=()=>{ ) } -export default CourseView; \ No newline at end of file +export default CourseViewGuest; \ No newline at end of file diff --git a/frontend/src/pages/CourseViewITE.js b/frontend/src/pages/CourseViewITE.js new file mode 100644 index 0000000..eb369c7 --- /dev/null +++ b/frontend/src/pages/CourseViewITE.js @@ -0,0 +1,182 @@ +import axios from 'axios'; +import {useEffect, useState} from 'react'; +import { useParams } from 'react-router-dom'; +import { makeStyles } from '@mui/styles'; +import {Typography} from '@mui/material'; +import { blue } from '@mui/material/colors'; +import {StyledCourseHeader} from '../components/styles/CourseHeader.style' +import SubtitleCard from '../components/SubtitleCard' +// import Card from '@mui/material/Card'; +// import CardActions from '@mui/material/CardActions'; +// import CardContent from '@mui/material/CardContent'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import { spacing } from '@mui/system'; +import { positions } from '@mui/system'; + + + +//stylings custom css + + + +const CourseViewITE=()=>{ + // const useStyles=makeStyles({ + // courseTitle:{ + // fontSize:60, + // color:blue, + + + + // } + // }) + + //styles + // const classes=useStyles(); + + const [course,setCourse]=useState(null); + const [coursePriceAfterDiscount,setPrice]=useState(''); + const [courseSubtitles,setCourseSubtitles]=useState([]); + + ///api/courses + const {courseid}=useParams(); + + + + //Using useEffect to run only on 1st render to display the course's data + useEffect( ()=>{ + const getCourseanditsSubtitle=async()=>{ + + + try{ + //Sending a get request to the server to get course + const response= await axios.get('http://localhost:5000/api/courses/',{params :{id:courseid}}); + const coursedata=response.data; + setCourse(coursedata); + + //handling setting course price according to discount and its expiry date + //checking if expiry date has passed + //getting today's date (day 1) + let currentdate =new Date(); + let year=currentdate.getFullYear(); + let month=currentdate.getMonth()+1; //because it outputs a number from 0-11 ex:3-->April + let day =currentdate.getDate(); + let dateCformat=`${year}-${month}-${day}` //current date in appropriate format. + let dateC=new Date(dateCformat); + //console.log(dateCformat); + + //getting expiry date from DB "through server response" + const expirydate=coursedata.discountExpireAt; + const dateEformat=expirydate.substring(0,10); //Put it in appropriate format + const dateE=new Date(dateEformat); + //console.log(dateEformat); + + //Comparing current date with expiry date + console.log(dateC.getTime()<=dateE.getTime()); + if(dateC.getTime()<=dateE.getTime()){ + + const newPrice=course.discount*course.price; + setPrice(newPrice); + } + + else{ + setPrice(coursedata.price); + } + + + + //Sending a get request to server to get this course's Subtitles + const response2=await axios.get(`http://localhost:5000/api/courses/getSubtitlesforCourse/${courseid}`); + const subtitlesArray=response2.data; + setCourseSubtitles(subtitlesArray); + + + + + + } + //catching any request error + catch (error){ + + } + + } + + getCourseanditsSubtitle(); } + ,[courseid] ); + + + + + + return ( + +
+
+ + < StyledCourseHeader> +

{course&&course.title}

+
Total Hours :{course&&course.totalhours}
+
Price: {course&&coursePriceAfterDiscount}
+ + + + +
+ + + + + + + + + + + + + +
+ {/* subtitles */} + + {courseSubtitles.map((subtitle)=>( + + ))} + + + + + + + + + + + + + + +
+ + + +
+ ) +} + +export default CourseViewITE; \ No newline at end of file diff --git a/frontend/src/pages/CourseViewInstructor.js b/frontend/src/pages/CourseViewInstructor.js new file mode 100644 index 0000000..82fea6b --- /dev/null +++ b/frontend/src/pages/CourseViewInstructor.js @@ -0,0 +1,192 @@ +import axios from 'axios'; +import {useEffect, useState} from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; +import { makeStyles } from '@mui/styles'; +import {Typography} from '@mui/material'; +import { blue } from '@mui/material/colors'; +import {StyledCourseHeader} from '../components/styles/CourseHeader.style' +import SubtitleCard from '../components/SubtitleCard' +// import Card from '@mui/material/Card'; +// import CardActions from '@mui/material/CardActions'; +// import CardContent from '@mui/material/CardContent'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import { spacing } from '@mui/system'; +import { positions } from '@mui/system'; + + + +//stylings custom css + + + +const CourseViewInstructor=()=>{ + // const useStyles=makeStyles({ + // courseTitle:{ + // fontSize:60, + // color:blue, + + + + // } + // }) + + //styles + // const classes=useStyles(); + + const [course,setCourse]=useState(null); + const [coursePriceAfterDiscount,setPrice]=useState(''); + const [courseSubtitles,setCourseSubtitles]=useState([]); + + ///api/courses + const {courseid}=useParams(); + + //useNavigate + const navigate=useNavigate(); + + + //Button Clicking + const handleAddPromotion=()=>{ + navigate(`/api/courses/addPromotion/${courseid}`); + navigate(0); + } + + + + //Using useEffect to run only on 1st render to display the course's data + useEffect( ()=>{ + const getCourseanditsSubtitle=async()=>{ + + + try{ + //Sending a get request to the server to get course + const response= await axios.get('http://localhost:5000/api/courses/',{params :{id:courseid}}); + const coursedata=response.data; + setCourse(coursedata); + + //handling setting course price according to discount and its expiry date + //checking if expiry date has passed + //getting today's date (day 1) + let currentdate =new Date(); + let year=currentdate.getFullYear(); + let month=currentdate.getMonth()+1; //because it outputs a number from 0-11 ex:3-->April + let day =currentdate.getDate(); + let dateCformat=`${year}-${month}-${day}` //current date in appropriate format. + let dateC=new Date(dateCformat); + //console.log(dateCformat); + + //getting expiry date from DB "through server response" + const expirydate=coursedata.discountExpireAt; + const dateEformat=expirydate.substring(0,10); //Put it in appropriate format + const dateE=new Date(dateEformat); + //console.log(dateEformat); + + //Comparing current date with expiry date + console.log(dateC.getTime()<=dateE.getTime()); + if(dateC.getTime()<=dateE.getTime()){ + + const newPrice=course.discount*course.price; + setPrice(newPrice); + } + + else{ + setPrice(coursedata.price); + } + + + + //Sending a get request to server to get this course's Subtitles + const response2=await axios.get(`http://localhost:5000/api/courses/getSubtitlesforCourse/${courseid}`); + const subtitlesArray=response2.data; + setCourseSubtitles(subtitlesArray); + + + + + + } + //catching any request error + catch (error){ + + } + + } + + getCourseanditsSubtitle(); } + ,[courseid] ); + + + + + + return ( + +
+
+ + < StyledCourseHeader> +

{course&&course.title}

+
Total Hours :{course&&course.totalhours}
+
Price: {course&&coursePriceAfterDiscount}
+ + + + +
+ + + + + + + + + + + + + +
+ {/* subtitles */} + + {course && courseSubtitles.map((subtitle)=>( + + ))} + + + + + + + + + + + + + + +
+ + + +
+ ) +} + +export default CourseViewInstructor; \ No newline at end of file diff --git a/frontend/src/pages/CourseViewPage.js b/frontend/src/pages/CourseViewPage.js deleted file mode 100644 index 7f1d771..0000000 --- a/frontend/src/pages/CourseViewPage.js +++ /dev/null @@ -1,116 +0,0 @@ -import React from 'react' - -import axios from 'axios'; -import {useEffect, useState} from 'react'; -import { useParams } from 'react-router-dom'; -import HomeNavBar from '../components/HomeNavBar'; - -export default function CourseViewPage() { - - const [course,setCourse]=useState(null); - const [coursePriceAfterDiscount,setPrice]=useState(''); - const [courseSubtitles,setCourseSubtitles]=useState([]); - - ///api/courses - const {courseid}=useParams(); - - - - //Using useEffect to run only on 1st render to display the course's data - useEffect( ()=>{ - const getCourseanditsSubtitle=async()=>{ - - - try{ - //Sending a get request to the server to get course - const response= await axios.get('http://localhost:5000/api/courses/',{params :{id:courseid}}); - const coursedata=response.data; - setCourse(coursedata); - - //handling setting course price according to discount and its expiry date - //checking if expiry date has passed - //getting today's date (day 1) - let currentdate =new Date(); - let year=currentdate.getFullYear(); - let month=currentdate.getMonth()+1; //because it outputs a number from 0-11 ex:3-->April - let day =currentdate.getDate(); - let dateCformat=`${year}-${month}-${day}` //current date in appropriate format. - let dateC=new Date(dateCformat); - //console.log(dateCformat); - - //getting expiry date from DB "through server response" - const expirydate=coursedata.discountExpireAt; - const dateEformat=expirydate.substring(0,10); //Put it in appropriate format - const dateE=new Date(dateEformat); - //console.log(dateEformat); - - //Comparing current date with expiry date - console.log(dateC.getTime()<=dateE.getTime()); - if(dateC.getTime()<=dateE.getTime()){ - - const newPrice=course.discount*course.price; - setPrice(newPrice); - } - - else{ - setPrice(coursedata.price); - } - - - - //Sending a get request to server to get this course's Subtitles - const response2=await axios.get(`http://localhost:5000/api/courses/getSubtitlesforCourse/${courseid}`); - const subtitlesArray=response2.data; - setCourseSubtitles(subtitlesArray); - - - - - - } - //catching any request error - catch (error){ - - } - - } - - getCourseanditsSubtitle(); } - ,[courseid] ); - - - return ( -
- {/* */} -
-
- -
- - - -
-
-
- {/* */} - - {/* */} -
-
-
-
- -
-
-
-
- - - - -
- -); - - -} diff --git a/frontend/src/pages/TestCard.js b/frontend/src/pages/TestCard.js new file mode 100644 index 0000000..48d4bc7 --- /dev/null +++ b/frontend/src/pages/TestCard.js @@ -0,0 +1,48 @@ +import Card from '@mui/material/Card'; +import CardActions from '@mui/material/CardActions'; +import CardContent from '@mui/material/CardContent'; +//import CardMedia from '@mui/material/CardMedia'; +import Button from '@mui/material/Button'; +import Typography from '@mui/material/Typography'; +import { shadows } from '@mui/system'; +import { Box } from '@mui/system'; +import { useNavigate } from 'react-router-dom'; +import {Link} from 'react-router-dom'; + +export default function ImgMediaCard() { + const navigate=useNavigate(); + const handleClick=()=>{ + navigate('/api/courses/addPromotion/:courseid'); + navigate(0); + } + + return ( + + + + {/* + Lizard + */} + {/* */} + + Lizard + + {/* */} +
    +
  • Reem
  • +
+ + Lizards are a widespread group of squamate reptiles, with over 6,000 + species, ranging across all continents except Antarctica + +
+ + + + + +
+ + + ); +} \ No newline at end of file diff --git a/package.json b/package.json index b90cc31..e1e52bf 100644 --- a/package.json +++ b/package.json @@ -39,9 +39,12 @@ "react-icons": "^4.7.1", "sass": "^1.56.2", "styled": "^1.0.0" + }, "devDependencies": { "concurrently": "^7.5.0", - "nodemon": "^2.0.20" + "nodemon": "^2.0.20" + + } }