reza added course and video api

master
RezaAshrafi77 3 years ago
parent 7d72b50b1d
commit c0bb31ac48
  1. 7
      src/components/JolPlayer/index.js
  2. 14
      src/components/Navbar/index.scss
  3. 7
      src/custom.scss
  4. 2
      src/redux/actions-type/book.tsx
  5. 2
      src/redux/actions/book.tsx
  6. 31
      src/redux/reducers/book.tsx
  7. 6
      src/views/Course/Lesson/index.scss
  8. 11
      src/views/Course/index.scss
  9. 51
      src/views/Course/index.tsx
  10. 3
      src/views/VideoTube/Comment/index.scss
  11. 2
      src/views/VideoTube/LessonPlayList/index.scss
  12. 76
      src/views/VideoTube/LessonPlayList/index.tsx
  13. 4
      src/views/VideoTube/index.scss
  14. 34
      src/views/VideoTube/index.tsx

@ -1,12 +1,12 @@
import JoLPlayer from "jol-player"; import JoLPlayer from "jol-player";
import file from "../../assets/videos/sea.mp4"; import file from "../../assets/videos/sea.mp4";
const Video = () => { const Video = ({fileIds}) => {
return ( return (
<div style={{direction: 'ltr', textAlign: 'left'}}> <div style={{direction: 'ltr', textAlign: 'left'}}>
<JoLPlayer <JoLPlayer
option={{ option={{
videoSrc: `https://dnvn.ir/api/v1/file/0`, videoSrc: `https://dnvn.ir/api/v1/file/${fileIds}`,
width: '100%', width: '100%',
height: 400, height: 400,
theme : '#4dd35b', theme : '#4dd35b',
@ -15,8 +15,9 @@ const Video = () => {
hideMouseTime : 10000, hideMouseTime : 10000,
isShowPicture : true, isShowPicture : true,
isShowScreenshot : true, isShowScreenshot : true,
isShowPauseButton : false,
quality: [{ quality: [{
name: "SD", url : `https://dnvn.ir/api/v1/file/0`, name: "SD", url : `https://dnvn.ir/api/v1/file/${fileIds}`,
}] }]
}} }}
/> />

@ -21,7 +21,8 @@
min-width : 130px; min-width : 130px;
font-family: numeralLight; font-family: numeralLight;
a{ a{
margin: 0px auto; width : 100%;
height : 100%;
} }
} }
} }
@ -53,7 +54,10 @@
} }
&--buttons{ &--buttons{
li{ li{
font-size: 18px; a{
font-size: 14px;
padding: 5px 0px;
}
} }
} }
} }
@ -62,6 +66,7 @@
} }
&___share{ &___share{
margin-left: 20px; margin-left: 20px;
font-size: 14px;
} }
} }
@ -74,7 +79,7 @@
&--links{ &--links{
li{ li{
padding: 0px 20px; padding: 0px 20px;
font-size: calc(100vw / 120); font-size: calc(100vw / 115);
span{ span{
width: 2px; width: 2px;
height: 15px; height: 15px;
@ -87,7 +92,8 @@
&--buttons{ &--buttons{
li{ li{
a{ a{
font-size: calc(100vw / 120); font-size: calc(100vw / 115);
padding: 5px 0px;
} }
min-width: 100px; min-width: 100px;
} }

@ -217,6 +217,13 @@
display: none !important; display: none !important;
} }
//JOL PLayer
.tooltip{
opacity: 1 !important;
transform : translateY(-2px) !important;
}
@media screen and (min-width: 1441px) { @media screen and (min-width: 1441px) {
.submit { .submit {
font-size: 20px; font-size: 20px;

@ -4,7 +4,7 @@ interface list {
} }
interface info { interface info {
type: "book/info"; type: "public/bookVOD";
data: any; data: any;
} }

@ -8,7 +8,7 @@ const book = {
info: info:
(data = {}) => (data = {}) =>
async (dispatch: Dispatch) => async (dispatch: Dispatch) =>
await proxy.get("book/info", data, { dispatch }), await proxy.get("public/bookVOD", data, { dispatch }),
setLessonActive: (data: undefined) => async (dispatch: Dispatch) => setLessonActive: (data: undefined) => async (dispatch: Dispatch) =>
await dispatch({ type: "book/lesson/active", data: data }), await dispatch({ type: "book/lesson/active", data: data }),
setVideoActive: (data: undefined) => async (dispatch: Dispatch) => setVideoActive: (data: undefined) => async (dispatch: Dispatch) =>

@ -269,11 +269,7 @@ const initialState = {
}, },
], ],
}, },
selectedVideo: { selectedVideo: null,
name: "ماهی های پرورشی و فواید آن ی",
src: sea,
text: "لورم اپیوسرم یک متن آزمایشی است که برای",
},
comments: [ comments: [
{ {
id: 0, id: 0,
@ -295,7 +291,7 @@ const initialState = {
gradeFilterBooks: null, gradeFilterBooks: null,
sortFilterCourse: null, sortFilterCourse: null,
selectedGrade: null, selectedGrade: null,
selectedSort: 'تمامی دورهها', selectedSort: "تمامی دورهها",
}; };
const grades = [ const grades = [
@ -340,8 +336,14 @@ export default function book(state = initialState, action: BookAction) {
filterResult: data, filterResult: data,
error: null, error: null,
}; };
case "book/info": case "public/bookVOD":
return { ...state, loading: false, info: data, error: null }; return {
...state,
loading: false,
info: data,
selectedVideo: data.vods[0],
error: null,
};
case "book/lesson/active": case "book/lesson/active":
return { return {
...state, ...state,
@ -378,11 +380,14 @@ export default function book(state = initialState, action: BookAction) {
); );
if (data.sort === "تمامی دورهها") { if (data.sort === "تمامی دورهها") {
return { ...state, sortFilterCourse: search, selectedSort: data.sort }; return { ...state, sortFilterCourse: search, selectedSort: data.sort };
} } else if (data.sort === "جدیدترینها") {
else if(data.sort === 'جدیدترینها'){ return {
return { ...state, sortFilterCourse: search.sort((item1 : any, item2 : any) => { ...state,
return item1.publishYear - item2.publishYear; sortFilterCourse: search.sort((item1: any, item2: any) => {
}), selectedSort: data.sort }; return item1.publishYear - item2.publishYear;
}),
selectedSort: data.sort,
};
} }
return { ...state, sortFilterCourse: search, selectedSort: data.sort }; return { ...state, sortFilterCourse: search, selectedSort: data.sort };

@ -50,6 +50,9 @@
@media screen and (min-width: 1441px) { @media screen and (min-width: 1441px) {
.lesson { .lesson {
header { header {
img{
margin-right: 5px;
}
h4 { h4 {
font-size: 21px; font-size: 21px;
margin-right: 30px; margin-right: 30px;
@ -79,6 +82,9 @@
@media screen and (min-width: 1008px) and (max-width: 1440px) { @media screen and (min-width: 1008px) and (max-width: 1440px) {
.lesson { .lesson {
header { header {
img{
margin-right: 5px;
}
h4 { h4 {
font-size: calc(100vw / 75); font-size: calc(100vw / 75);
margin-right: 30px; margin-right: 30px;

@ -1,7 +1,7 @@
.course{ .course{
main{ main{
header{ header{
padding: 70px 0px 45px; padding: 30px 0px 45px;
border-bottom:2px solid #4a4a4a; border-bottom:2px solid #4a4a4a;
} }
} }
@ -88,7 +88,7 @@
flex: 4; flex: 4;
&--image{ &--image{
img{ img{
width: 320px; // width: 320px;
height: 420px; height: 420px;
} }
} }
@ -182,7 +182,7 @@
flex: 3; flex: 3;
&--image{ &--image{
img{ img{
width: 250px; // width: 250px;
height: 380px; height: 380px;
} }
} }
@ -224,6 +224,7 @@
height: 160px; height: 160px;
margin-bottom: 30px; margin-bottom: 30px;
&__number{ &__number{
margin-bottom: 15px;
i{ i{
font-size: calc(100vw / 100); font-size: calc(100vw / 100);
} }
@ -246,7 +247,7 @@
width: 70%; width: 70%;
height: 59px; height: 59px;
padding: 0px 30px; padding: 0px 30px;
font-size: calc(100vw / 75); font-size: calc(100vw / 100);
border-radius: 40px; border-radius: 40px;
} }
} }
@ -284,7 +285,7 @@
flex: 3; flex: 3;
&--image{ &--image{
img{ img{
width: 200px; // width: 200px;
height: 280px; height: 280px;
} }
} }

@ -10,12 +10,13 @@ import slide from "../../assets/icons/slide.png";
import play from "../../assets/icons/play.png"; import play from "../../assets/icons/play.png";
import bookmark from "../../assets/icons/bookmark.png"; import bookmark from "../../assets/icons/bookmark.png";
import StyledRating from "../../components/StyledRating/index"; import StyledRating from "../../components/StyledRating/index";
import { connect, useSelector } from "react-redux"; import { connect } from "react-redux";
import scroll from '../../util/scroll'; import { book } from "../../redux/actions";
import scroll from "../../util/scroll";
import "./index.scss"; import "./index.scss";
function Course({ lessons }: any) { function Course({ lessons, getInfo, info }: any) {
const [links, setLinks] = useState([ const [links, setLinks] = useState([
{ link: "/", name: "صفحه اصلی" }, { link: "/", name: "صفحه اصلی" },
{ link: "/courses", name: "دورهها" }, { link: "/courses", name: "دورهها" },
@ -23,15 +24,14 @@ function Course({ lessons }: any) {
]); ]);
const [course, setCourse] = useState<any>(undefined); const [course, setCourse] = useState<any>(undefined);
useEffect(() => { useEffect(() => {
axios
.get("https://jsonplaceholder.typicode.com/photos/1")
.then((res: any) => {
setCourse(res.data);
})
.catch((err) => {
console.log(err);
});
scroll.goToTop(); scroll.goToTop();
getInfo({
bookId: 18
// window.location.pathname.slice(
// window.location.pathname.lastIndexOf("/") + 1,
// window.location.pathname.length
// ),
});
}, []); }, []);
return ( return (
@ -41,12 +41,12 @@ function Course({ lessons }: any) {
<header className="desktop align-items-end"> <header className="desktop align-items-end">
<div className="course__info d-flex"> <div className="course__info d-flex">
<div className="course__info--image d-flex align-items-end"> <div className="course__info--image d-flex align-items-end">
<img src={course?.thumbnailUrl} alt="" /> <img src={`https://dnvn.ir/api/v1/file/${info?.fileIds}`} alt="" />
</div> </div>
<div className="course__info--description d-flex flex-column justify-content-between"> <div className="course__info--description d-flex flex-column justify-content-between">
<div> <div>
<BreadCrumbs links={links} /> <BreadCrumbs links={links} />
<h1>{course?.title?.slice(0, 25)}</h1> <h1>{info?.name}</h1>
</div> </div>
<div className="d-flex justify-content-between"> <div className="d-flex justify-content-between">
<div className="course-info-items d-flex align-items-center justify-content-around"> <div className="course-info-items d-flex align-items-center justify-content-around">
@ -97,18 +97,18 @@ function Course({ lessons }: any) {
<img src={course?.thumbnailUrl} alt="" /> <img src={course?.thumbnailUrl} alt="" />
</div> </div>
<div className="course__info--description d-flex flex-column justify-content-between"> <div className="course__info--description d-flex flex-column justify-content-between">
<BreadCrumbs links={links} /> <BreadCrumbs links={links} />
<h1>{course?.title?.slice(0, 25)}</h1> <h1>{info?.name}</h1>
<i>240 ساعت</i> <i>240 ساعت</i>
<div className="course__options--rate d-flex align-items-center justify-content-between"> <div className="course__options--rate d-flex align-items-center justify-content-between">
<div className="course__options--rate__number d-flex flex-column align-items-center"> <div className="course__options--rate__number d-flex flex-column align-items-center">
<h2>میانگین رای کاربران</h2> <h2>میانگین رای کاربران</h2>
<div> <div>
<b>10</b> <b>10</b>
<i>/2</i> <i>/2</i>
</div>
</div> </div>
<StyledRating /> </div>
<StyledRating />
</div> </div>
</div> </div>
</div> </div>
@ -153,6 +153,7 @@ function Course({ lessons }: any) {
export default connect( export default connect(
(state: any) => ({ (state: any) => ({
lessons: state.book.mockLessons, lessons: state.book.mockLessons,
info : state.book.info,
}), }),
{} { getInfo: book.info }
)(Course); )(Course);

@ -9,6 +9,9 @@
border: none; border: none;
margin-left: 20px; margin-left: 20px;
} }
p{
line-height: 1.5;
}
} }
@media screen and (min-width: 1441px){ @media screen and (min-width: 1441px){

@ -1,7 +1,9 @@
.lesson-playlist{ .lesson-playlist{
width: 100%; width: 100%;
padding-bottom : 10px;
header{ header{
background-color: inherit !important; background-color: inherit !important;
margin-bottom: 5px;
h3{ h3{
background-color : #707070; background-color : #707070;
padding: 5px 10px; padding: 5px 10px;

@ -1,44 +1,52 @@
import React from "react"; import React from "react";
import "./index.scss"; import "./index.scss";
import { connect } from "react-redux"; import { connect } from "react-redux";
import {book} from '../../../redux/actions'; import { book } from "../../../redux/actions";
function LessonPlayList({ lesson, selectedVideo,setVideoActive }: any) { function LessonPlayList({ video, selectedVideo, setVideoActive, num }: any) {
return ( return (
<div className="lesson-playlist d-flex flex-column"> <>
<header className="d-flex align-items-center"> {1 && (
<h3>{lesson.name}</h3> <div className="lesson-playlist d-flex flex-column">
<span></span> <header className="d-flex align-items-center">
</header> <h3>{'بخش 1'}</h3>
{lesson.files.map((file: any, i: any) => ( <span></span>
<div </header>
className={ {/* {lesson.files.map((file: any, i: any) => ( */}
"lesson-playlist__item d-flex align-items-center" + ' ' + <div
(file.name === selectedVideo.name && className={
"lesson-playlist__item--active") "lesson-playlist__item d-flex align-items-center" +
} " " +
key={i} (video.id === selectedVideo.id &&
onClick={() => setVideoActive(file)} "lesson-playlist__item--active")
> }
<span className="lesson-playlist__item--count">{i + 1}</span> // key={i}
<div className="lesson-playlist__item--video"> onClick={() => setVideoActive(video)}
<video> >
<source src={file.src} /> <span className="lesson-playlist__item--count">{num}</span>
</video> <div className="lesson-playlist__item--video">
<span>22:05</span> <video>
</div> <source src={`https://dnvn.ir/api/v1/file/${video.fileIds}`} />
<div className="lesson-playlist__item--text d-flex flex-column"> </video>
<h4>{file.name}</h4> <span>22:05</span>
<p>{file.text}</p> </div>
<div className="lesson-playlist__item--text d-flex flex-column">
<h4>{video.name}</h4>
{/* <p>{file.text}</p> */}
</div>
</div> </div>
{/* ))} */}
</div> </div>
))} )}
</div> </>
); );
} }
export default connect((state: any) => ({ export default connect(
selectedVideo: state.book.selectedVideo, (state: any) => ({
}), { selectedVideo: state.book.selectedVideo,
setVideoActive : book.setVideoActive, }),
})(LessonPlayList); {
setVideoActive: book.setVideoActive,
}
)(LessonPlayList);

@ -159,7 +159,7 @@
.video-tube { .video-tube {
main { main {
max-width: 1350px; max-width: 1350px;
margin-top: 30px; margin-top: 10px;
} }
&__content { &__content {
flex: 8; flex: 8;
@ -253,7 +253,7 @@
.video-tube { .video-tube {
main { main {
max-width: 1250px; max-width: 1250px;
margin-top: 30px; margin-top: 10px;
padding: 0px 10px; padding: 0px 10px;
} }
&__content { &__content {

@ -6,7 +6,7 @@ import Attachments from "./Attachments/index";
import Book from "./Book/index"; import Book from "./Book/index";
import Comment from "./Comment/index"; import Comment from "./Comment/index";
import AddComment from "./AddComment/index"; import AddComment from "./AddComment/index";
import Video from '../../components/JolPlayer'; import Video from "../../components/JolPlayer";
import "./index.scss"; import "./index.scss";
import listIcon from "../../assets/icons/list.png"; import listIcon from "../../assets/icons/list.png";
@ -14,9 +14,24 @@ import { connect } from "react-redux";
import scroll from "../../util/scroll.js"; import scroll from "../../util/scroll.js";
import { book } from "../../redux/actions"; import { book } from "../../redux/actions";
function VodTube({ videoList, getList, list, selectedVideo, comments }: any) { function VodTube({
videoList,
getBookList,
list,
selectedVideo,
comments,
info,
getInfo,
}: any) {
useEffect(() => { useEffect(() => {
getList(); getBookList();
getInfo({
bookId: 18,
// window.location.pathname.slice(
// window.location.pathname.lastIndexOf("/") + 1,
// window.location.pathname.length
// ),
});
scroll.goToTop(); scroll.goToTop();
}, []); }, []);
return ( return (
@ -28,10 +43,10 @@ function VodTube({ videoList, getList, list, selectedVideo, comments }: any) {
{/* <video controls> {/* <video controls>
<source src={selectedVideo.src} /> <source src={selectedVideo.src} />
</video> */} </video> */}
<Video /> <Video fileIds={selectedVideo?.fileIds} />
<span className="desktop">درس دوم / بیست و یکم</span> <span className="desktop">درس دوم / بیست و یکم</span>
<h1 className="desktop">{selectedVideo.name}</h1> <h1 className="desktop">{selectedVideo?.name}</h1>
<p className="desktop">{selectedVideo.text}</p> {/* <p className="desktop">{selectedVideo.text}</p> */}
</section> </section>
<section className="desktop video-tube__content--comments flex-column"> <section className="desktop video-tube__content--comments flex-column">
<header className="d-flex justify-content-between align-items-center"> <header className="d-flex justify-content-between align-items-center">
@ -58,8 +73,8 @@ function VodTube({ videoList, getList, list, selectedVideo, comments }: any) {
<img src={listIcon} alt="" /> <img src={listIcon} alt="" />
</header> </header>
<div className="video-tube__sidebar--playlist___list d-flex flex-column"> <div className="video-tube__sidebar--playlist___list d-flex flex-column">
{videoList.lessons?.map((lesson: any, i: any) => ( {info?.vods.map((video: any, i: any) => (
<LessonPlayList lesson={lesson} key={i} num={i + 1} /> <LessonPlayList video={video} key={i} num={i + 1} />
))} ))}
</div> </div>
</section> </section>
@ -114,6 +129,7 @@ export default connect(
selectedVideo: state.book.selectedVideo, selectedVideo: state.book.selectedVideo,
list: state.book.list, list: state.book.list,
comments: state.book.comments, comments: state.book.comments,
info: state.book.info,
}), }),
{ getList: book.list } { getInfo: book.info, getBookList : book.list }
)(VodTube); )(VodTube);

Loading…
Cancel
Save