From 8c8be6e2e6dde9722dfaa41ef4790ceba2581c39 Mon Sep 17 00:00:00 2001 From: RezaAshrafi77 Date: Fri, 15 Oct 2021 15:59:08 +0330 Subject: [PATCH] reza completed available api --- src/redux/actions-type/book.tsx | 6 - src/redux/actions-type/public.tsx | 24 ++- src/redux/actions/book.tsx | 2 - src/redux/actions/public.tsx | 8 + src/redux/reducers/book.tsx | 7 - src/redux/reducers/public.tsx | 61 +++++- src/views/Course/Lesson/index.tsx | 46 +++-- src/views/Course/index.tsx | 37 ++-- src/views/Courses/Course/index.scss | 31 ++- src/views/Courses/Course/index.tsx | 15 +- src/views/Courses/index.scss | 1 + src/views/Courses/index.tsx | 11 +- src/views/VideoTube/Book/index.scss | 7 + src/views/VideoTube/Book/index.tsx | 5 +- src/views/VideoTube/LessonPlayList/index.tsx | 20 +- src/views/VideoTube/index.scss | 1 + src/views/VideoTube/index.tsx | 206 ++++++++++--------- 17 files changed, 303 insertions(+), 185 deletions(-) diff --git a/src/redux/actions-type/book.tsx b/src/redux/actions-type/book.tsx index 8b66b67..a3afab2 100644 --- a/src/redux/actions-type/book.tsx +++ b/src/redux/actions-type/book.tsx @@ -8,11 +8,6 @@ interface setLessonActive { data: any; } -interface setVideoActive { - type: "book/video/active"; - data: any; -} - interface gradeFilter { type: "book/gradeFilter"; data: any; @@ -35,7 +30,6 @@ interface loading { type BookAction = | list - | setVideoActive | setLessonActive | gradeFilter | sortFilter diff --git a/src/redux/actions-type/public.tsx b/src/redux/actions-type/public.tsx index 2a51ab6..a3a99bf 100644 --- a/src/redux/actions-type/public.tsx +++ b/src/redux/actions-type/public.tsx @@ -8,9 +8,24 @@ interface getBlogList { data: any; } +interface setVideoActive { + type: "active/video"; + data: any; +} + +interface activeCategory { + type: "active/category"; + data: any; +} + interface bookInfo { - type: "public/vod/bookCourse" - data: any + type: "public/vod/bookCourse"; + data: any; +} + +interface bookSection { + type: "public/vod/bookSection"; + data: any; } interface getBlogInfo { @@ -48,7 +63,7 @@ interface selectMenu { data: any; } -interface getHeader{ +interface getHeader { type: "public/VOD/homePage"; data: any; } @@ -68,9 +83,12 @@ interface loading { // } type PublicAction = + | activeCategory + | setVideoActive | getBlogList | getBlogInfo | bookInfo + | bookSection | setSubscribe | getHomeData | setFaqActive diff --git a/src/redux/actions/book.tsx b/src/redux/actions/book.tsx index ce43ee0..24577db 100644 --- a/src/redux/actions/book.tsx +++ b/src/redux/actions/book.tsx @@ -7,8 +7,6 @@ const book = { await proxy.get("book/list", data, { dispatch }), setLessonActive: (data: undefined) => async (dispatch: Dispatch) => await dispatch({ type: "book/lesson/active", data: data }), - setVideoActive: (data: undefined) => async (dispatch: Dispatch) => - await dispatch({ type: "book/video/active", data: data }), gradeFilter: (data: undefined) => async (dispatch: Dispatch) => await dispatch({ type: "book/gradeFilter", data: data }), sortFilter: (data: undefined) => async (dispatch: Dispatch) => diff --git a/src/redux/actions/public.tsx b/src/redux/actions/public.tsx index 051bca6..4ec545a 100644 --- a/src/redux/actions/public.tsx +++ b/src/redux/actions/public.tsx @@ -10,6 +10,10 @@ const publicApi = { (data = {}) => async (dispatch: Dispatch) => await proxy.get("public/vod/bookCourse", data, { dispatch }), + bookSection: + (data = {}) => + async (dispatch: Dispatch) => + await proxy.get("public/vod/bookSection", data, { dispatch }), getContactData: (data = {}) => async (dispatch: Dispatch) => @@ -36,6 +40,10 @@ const publicApi = { (data = {}) => async (dispatch: Dispatch) => await proxy.get("public/VOD/homePage", data, { dispatch }), + activeCategory: (data: Object) => async (dispatch: Dispatch) => + await dispatch({ type: "active/category", data: data }), + setVideoActive: (data: undefined) => async (dispatch: Dispatch) => + await dispatch({ type: "active/video", data: data }), }; export default publicApi; diff --git a/src/redux/reducers/book.tsx b/src/redux/reducers/book.tsx index b5ef59a..d3d82c1 100644 --- a/src/redux/reducers/book.tsx +++ b/src/redux/reducers/book.tsx @@ -347,13 +347,6 @@ export default function book(state = initialState, action: BookAction) { : { ...item, active: false } ), }; - case "book/video/active": - return { - ...state, - loading: false, - error: null, - selectedVideo: data, - }; case "book/gradeFilter": if (data === state.selectedGrade) { return { ...state, gradeFilterBooks: null, selectedGrade: null }; diff --git a/src/redux/reducers/public.tsx b/src/redux/reducers/public.tsx index 1f3c84a..c6b677b 100644 --- a/src/redux/reducers/public.tsx +++ b/src/redux/reducers/public.tsx @@ -1,5 +1,5 @@ import { PublicAction } from "../actions-type"; -import proxy from '../proxy'; +import proxy from "../proxy"; const initialState = { homeData: [], newProducts: [], @@ -10,8 +10,8 @@ const initialState = { arList: [], blogList: [], blog: null, - province : null, - city : null, + province: null, + city: null, departmans: [ { id: 0, @@ -26,11 +26,14 @@ const initialState = { name: "برنامه نویسی", }, ], - header : [], - selectedMenu : null, + header: [], + selectedMenu: null, contactData: null, selectedVideo: null, - bookInfo : null, + bookInfo: null, + activeCategory: null, + categories: null, + bookSection : null, }; const grades = [ @@ -51,13 +54,49 @@ const grades = [ export default function publicApi(state = initialState, action: PublicAction) { let { type, data } = action; switch (type) { + case "active/video": + return { + ...state, + loading: false, + error: null, + selectedVideo: data, + }; + case "active/category": + return { + ...state, + loading: false, + activeCategory: state.activeCategory === data ? null : data, + error: null, + }; + case "public/vod/bookSection": + return { + ...state, + loading: false, + bookSection: data, + error: null, + selectedVideo : data?.vods[0] + }; + case "public/vod/bookCourse": + let allCats; + allCats = Array.from( + new Set( + data.vods.map((item: any) => item.categoryId && item.categoryId) + ) + ); return { ...state, loading: false, - bookInfo: data, - selectedVideo: data.vods[0], + bookInfo: { + ...data, + vods: data.vods.map((item: any) => { + return { ...item, active: false }; + }), + }, error: null, + categories: allCats.map((item: any) => + data.vods.filter((item1: any) => item1.categoryId === item) + ), }; case "public/homePage": let itemsLevel; @@ -179,15 +218,15 @@ export default function publicApi(state = initialState, action: PublicAction) { case "public/blogInfo": return { ...state, loading: false, error: null, blog: data }; case "public/setSubscribe": - return { ...state, loading: false, error: null, selectedSubscribe : data }; + return { ...state, loading: false, error: null, selectedSubscribe: data }; case "public/province": return { ...state, loading: false, error: null, province: data }; case "public/city": return { ...state, loading: false, error: null, city: data }; case "public/selectMenu": - return { ...state, loading: false, error: null, selectedMenu : data }; + return { ...state, loading: false, error: null, selectedMenu: data }; case "public/VOD/homePage": - return { ...state, loading: false, error: null, header : data }; + return { ...state, loading: false, error: null, header: data }; case "loading": return { ...state, loading: true }; case "error": diff --git a/src/views/Course/Lesson/index.tsx b/src/views/Course/Lesson/index.tsx index eba3d26..9cd354a 100644 --- a/src/views/Course/Lesson/index.tsx +++ b/src/views/Course/Lesson/index.tsx @@ -2,23 +2,25 @@ import React from "react"; import whiteDropdown from "../../../assets/icons/white-dropdown.png"; import whitePlay from "../../../assets/icons/white-play.png"; import document from "../../../assets/icons/document.png"; -import lock from "../../../assets/icons/lock.png"; import "./index.scss"; import { connect } from "react-redux"; -import { book } from "../../../redux/actions"; -import LessonPlayList from "../../VideoTube/LessonPlayList"; +import { book, publicApi } from "../../../redux/actions"; -function Lesson(props: any) { - const { lesson } = props; +function Lesson({toggle, lesson, activeCategory} : any) { + const duration = (value : number) => { + const minute = value % 60; + const hour = Math.round(value / 60); + return (hour > 0 ? (hour + ' ' + 'ساعت') : '') + ' ' + minute + ' ' + 'دقیقه'; + } return (
props.toggle(lesson.id)} + onClick={() => toggle(lesson[0].categoryId)} >
-

{lesson.title}

+

{lesson[0].categoryId}

مدت زمان درس {lesson.duration} @@ -30,10 +32,10 @@ function Lesson(props: any) { " " + (!lesson.active && "lesson__active") } - onClick={() => props.toggle(lesson.id)} + onClick={() => toggle(lesson[0].categoryId)} >
-

{lesson.title}

+

{lesson[0].categoryId}

مدت زمان درس {lesson.duration}
@@ -44,32 +46,32 @@ function Lesson(props: any) { className={ "lesson__files d-flex flex-column justify-content-around" + " " + - (lesson.active && "lesson__files--active") + ((lesson[0].categoryId === activeCategory) && "lesson__files--active") } style={{ - height: lesson.active - ? lesson.files.length * + height: lesson[0].categoryId === activeCategory + ? lesson.length * (window.innerWidth > 1007 - ? window.innerWidth / 33 + 20 + ? window.innerWidth / 33 + 20 : window.innerWidth / 33 + 45) : "0px", }} > - {lesson.map((data: any, i: any) => ( + {lesson?.map((data: any, i: any) => (
  • {data.type === "video" && } - {data.type === "document" && } + {data.type === "pdf" && }
    {data.name}
      -
    • {data.type !== "document" && data.duration}
    • -
    • {data.view && "مشاهده"}
    • +
    • {data.type !== "pdf" && duration(data.duration)}
    • +
    • {data.isFree && "مشاهده"}
    • {/*
    • {data.download ? "دانلود" : }
    • */}
  • @@ -79,6 +81,8 @@ function Lesson(props: any) { ); } -export default connect((state: any) => ({}), { toggle: book.setLessonActive })( - Lesson -); +export default connect((state: any) => ({ + activeCategory : state.publicApi.activeCategory +}), { + toggle : publicApi.activeCategory, +})(Lesson); diff --git a/src/views/Course/index.tsx b/src/views/Course/index.tsx index 385d133..cf5add3 100644 --- a/src/views/Course/index.tsx +++ b/src/views/Course/index.tsx @@ -13,8 +13,9 @@ import StyledRating from "../../components/StyledRating"; import { connect } from "react-redux"; import { publicApi } from "../../redux/actions"; import scroll from "../../util/scroll"; +import Loader from "../../components/Loader"; -function Course({ lessons, getInfo, info }: any) { +function Course({ getInfo, info, categories, loading }: any) { const [links, setLinks] = useState([ { link: "/", name: "صفحه اصلی" }, { link: "/courses", name: "دوره‌ها" }, @@ -31,18 +32,17 @@ function Course({ lessons, getInfo, info }: any) { // ), }); }, []); - let allCats; - let cats = []; - if (info?.vods) { - allCats = Array.from( - new Set(info?.vods.map((item: any) => item.categoryId && item.categoryId)) - ); - cats = allCats.map((item: any) => - info?.vods.filter((item1: any) => item1.categoryId === item) - ); - } + + const checkFreeCat = () => { + const freeCat = info?.vods.filter((item: any) => item?.isFreeVOD)[0]; + localStorage.setItem("free", 1 + "," + freeCat?.categoryId); + }; + return ( -
    +
    @@ -58,12 +58,13 @@ function Course({ lessons, getInfo, info }: any) {

    {info?.name}

    {info?.text}

    + {info?.vodTeacher}
    - {240} ساعت درس + {info?.vodDuration} ساعت درس

    در این قسمت توضیحی

    @@ -96,6 +97,7 @@ function Course({ lessons, getInfo, info }: any) { checkFreeCat()} > مشاهده پیشنمایش دوره @@ -154,12 +156,17 @@ function Course({ lessons, getInfo, info }: any) {

    سر فصل دوره

    در این قسمت شاید یک متن جهت زیباسازی قرار بگیرد

    - {cats?.map((lesson: any, i: any) => ( + {categories?.map((lesson: any, i: any) => ( ))}
    + {loading && ( +
    + +
    + )}
    ); } @@ -168,6 +175,8 @@ export default connect( (state: any) => ({ lessons: state.book.mockLessons, info: state.publicApi.bookInfo, + categories: state.publicApi.categories, + loading: state.publicApi.loading, }), { getInfo: publicApi.bookInfo } )(Course); diff --git a/src/views/Courses/Course/index.scss b/src/views/Courses/Course/index.scss index 934e1c2..fd4621e 100644 --- a/src/views/Courses/Course/index.scss +++ b/src/views/Courses/Course/index.scss @@ -3,6 +3,7 @@ padding: 10px; border-bottom: 1px solid #212121; transition: all 0.5s; + position: relative; * { transition: all 0.5s; color: #aaa; @@ -16,6 +17,11 @@ } p { } + span { + position: absolute; + left: 10px; + top: 10px; + } } @media screen and (min-width: 1441px) { @@ -44,6 +50,9 @@ font-size: 13px; width: 80%; } + span { + font-size: 13px; + } } } @@ -69,14 +78,20 @@ h1 { font-size: calc(100vw / 70); } + h2{ + font-size: calc(100vw / 90); + } p { - font-size: calc(100vw / 100); + font-size: calc(100vw / 110); width: 80%; } + span { + font-size: calc(100vw / 120); + } } } -@media screen and (min-width : 641px) and (max-width: 1007px) { +@media screen and (min-width: 641px) and (max-width: 1007px) { .courses-course { margin-top: 20px; background-color: #aaaaaa21; @@ -89,10 +104,16 @@ font-size: calc(100vw / 45); color: #84de56; } + h2{ + font-size: calc(100vw / 52); + } p { font-size: calc(100vw / 65); width: 80%; } + span { + font-size: calc(100vw / 70); + } } } @@ -109,9 +130,15 @@ font-size: calc(100vw / 24); color: #84de56; } + h2{ + font-size: calc(100vw / 28); + } p { font-size: calc(100vw / 40); width: 80%; } + span { + font-size: calc(100vw / 45); + } } } diff --git a/src/views/Courses/Course/index.tsx b/src/views/Courses/Course/index.tsx index a153f65..af29052 100644 --- a/src/views/Courses/Course/index.tsx +++ b/src/views/Courses/Course/index.tsx @@ -4,17 +4,26 @@ import { Link } from "react-router-dom"; import location from "../../../util/location"; export default function Course({ data }: any) { + const duration = () => { + const minute = data.vodDuration % 60; + const hour = Math.round(data.vodDuration / 60); + return (hour > 0 ? (hour + ' ' + 'ساعت') : '') + ' ' + minute + ' ' + 'دقیقه'; + } return ( -
    -

    {data.name}

    +
    +
    +

    {data.name}

    +

    نام نویسنده

    +
    +

    لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است چاپگرها و متون بلکه روزنامه و مجله در ستون و

    -
    + {duration()} ); } diff --git a/src/views/Courses/index.scss b/src/views/Courses/index.scss index b6342b6..05747c2 100644 --- a/src/views/Courses/index.scss +++ b/src/views/Courses/index.scss @@ -1,4 +1,5 @@ .courses { + position: relative; main { margin-top: 30px; header { diff --git a/src/views/Courses/index.tsx b/src/views/Courses/index.tsx index 007ea78..ee5a804 100644 --- a/src/views/Courses/index.tsx +++ b/src/views/Courses/index.tsx @@ -7,8 +7,9 @@ import { connect } from "react-redux"; import location from "../../util/location"; import Course from "./Course"; import BreadCrumbs from "../../components/BreadCrumbs"; +import Loader from "../../components/Loader"; -function Courses({ getList, list, selectedMenu }: any) { +function Courses({ getList, list, selectedMenu, loading }: any) { const [links, setLinks] = useState([ { link: "/", name: "صفحه اصلی" }, { link: "/courses", name: "دوره‌ها" }, @@ -19,7 +20,7 @@ function Courses({ getList, list, selectedMenu }: any) { }, []); return ( -
    +
    @@ -36,6 +37,11 @@ function Courses({ getList, list, selectedMenu }: any) { ))}
    + { + loading &&
    + +
    + }
    ); } @@ -44,6 +50,7 @@ export default connect( (state: any) => ({ list: state.book.list, selectedMenu: state.publicApi.selectedMenu, + loading : state.book.loading }), { getList: book.list } )(Courses); diff --git a/src/views/VideoTube/Book/index.scss b/src/views/VideoTube/Book/index.scss index 2912f02..e83d357 100644 --- a/src/views/VideoTube/Book/index.scss +++ b/src/views/VideoTube/Book/index.scss @@ -6,6 +6,13 @@ border-bottom-right-radius: 10px; border-bottom-left-radius: 24px; margin-bottom: 10px; + transition: all 0.5s; + } + &:hover{ + color: white; + img{ + transform: translateY(-10px); + } } } diff --git a/src/views/VideoTube/Book/index.tsx b/src/views/VideoTube/Book/index.tsx index 03199de..f74d7b8 100644 --- a/src/views/VideoTube/Book/index.tsx +++ b/src/views/VideoTube/Book/index.tsx @@ -1,13 +1,14 @@ import React from 'react'; +import {Link} from 'react-router-dom'; import './index.scss'; export default function Book({data} : any) { return ( -
    +

    {data.name}

    {'لورم ایپسوم و اینجور چیزا'}

    -
    + ) } diff --git a/src/views/VideoTube/LessonPlayList/index.tsx b/src/views/VideoTube/LessonPlayList/index.tsx index 015f2f4..88a0725 100644 --- a/src/views/VideoTube/LessonPlayList/index.tsx +++ b/src/views/VideoTube/LessonPlayList/index.tsx @@ -1,24 +1,19 @@ import React from "react"; import "./index.scss"; import { connect } from "react-redux"; -import { book } from "../../../redux/actions"; +import { publicApi } from "../../../redux/actions"; function LessonPlayList({ video, selectedVideo, setVideoActive, num }: any) { return ( <> - {1 && ( + { + video.isFreeVOD &&
    -
    -

    {'بخش 1'}

    - -
    - {/* {lesson.files.map((file: any, i: any) => ( */}
    setVideoActive(video)} @@ -35,18 +30,17 @@ function LessonPlayList({ video, selectedVideo, setVideoActive, num }: any) { {/*

    {file.text}

    */}
    - {/* ))} */}
    - )} + } ); } export default connect( (state: any) => ({ - selectedVideo: state.book.selectedVideo, + selectedVideo: state.publicApi.selectedVideo, }), { - setVideoActive: book.setVideoActive, + setVideoActive: publicApi.setVideoActive, } )(LessonPlayList); diff --git a/src/views/VideoTube/index.scss b/src/views/VideoTube/index.scss index 029c902..227a7a6 100644 --- a/src/views/VideoTube/index.scss +++ b/src/views/VideoTube/index.scss @@ -70,6 +70,7 @@ } } &___list { + padding-top: 10px; overflow-y: scroll; &::-webkit-scrollbar { width: 8px; diff --git a/src/views/VideoTube/index.tsx b/src/views/VideoTube/index.tsx index 554e2e0..699a76c 100644 --- a/src/views/VideoTube/index.tsx +++ b/src/views/VideoTube/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useState, useEffect } from "react"; import Navbar from "../../components/Navbar"; import Footer from "../Home/Footer"; import LessonPlayList from "./LessonPlayList"; @@ -13,18 +13,12 @@ import listIcon from "../../assets/icons/list.png"; import { connect } from "react-redux"; import scroll from "../../util/scroll.js"; import { book, publicApi } from "../../redux/actions"; +import Loader from "../../components/Loader"; -function VodTube({ - videoList, - getBookList, - list, - selectedVideo, - comments, - info, - getInfo, -}: any) { +function VodTube({ selectedVideo, info, bookSection, loading }: any) { useEffect(() => { - getBookList(); + const free: any = localStorage.getItem("free")?.split(","); + scroll.goToTop(); // getInfo({ // bookId: 1, // // window.location.pathname.slice( @@ -32,105 +26,119 @@ function VodTube({ // // window.location.pathname.length // // ), // }); - scroll.goToTop(); + bookSection({ bookId: free[0], categoryId: free[1] }); }, []); - + return ( -
    - -
    -
    -
    - {/*
    -
    -
    + +
    +
    + {loading && ( +
    + +
    + )} + ); } export default connect( (state: any) => ({ - videoList: state.book.mockVideoList, - selectedVideo: state.book.selectedVideo, - list: state.book.list, - comments: state.book.comments, - info: state.book.info, + selectedVideo: state.publicApi.selectedVideo, + info: state.publicApi.bookSection, + loading: state.publicApi.loading, }), - { getInfo: publicApi.bookInfo, getBookList : book.list } + { + getInfo: publicApi.bookInfo, + getBookList: book.list, + bookSection: publicApi.bookSection, + } )(VodTube);