diff --git a/package.json b/package.json
index f131a85..945ea25 100644
--- a/package.json
+++ b/package.json
@@ -8,12 +8,15 @@
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@trendyol-js/react-carousel": "^2.0.0",
+ "axios": "^0.24.0",
+ "jol-player": "^2.5.0",
"lodash": "^4.17.21",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"react-router-dom": "^6.0.2",
"react-scripts": "4.0.3",
+ "react-toastify": "^8.1.0",
"redux": "^4.1.2",
"redux-devtools-extension": "^2.13.9",
"redux-thunk": "^2.4.0",
diff --git a/src/App.js b/src/App.js
index 0898b1f..178e80b 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,12 +1,13 @@
import './App.scss';
import { Provider } from 'react-redux';
+import store from './redux/store';
import Router from './router';
function App() {
return (
-
{
+ return (
+
+ 1000 ? window.innerHeight - 300 : 250,
+ theme: "#4dd35b",
+ language: "en",
+ isShowMultiple: window.innerWidth > 700,
+ hideMouseTime: 10000,
+ isShowPicture: true,
+ isShowFullScreen: false,
+ isShowSet: false,
+ isShowScreenshot: window.innerWidth > 700,
+ // isShowSet : false,
+ isShowPauseButton: false,
+ poster: `https://dnvn.ir/api/v1/file/${posterId}`,
+ quality: [
+ {
+ name: "SD",
+ url: `https://dnvn.ir/api/v1/file/${fileIds}`,
+ },
+ ],
+ isShowWebFullScreen: false,
+ }}
+ />
+
+ );
+};
+
+export default Video;
diff --git a/src/constants/defaultValues.js b/src/constants/defaultValues.js
new file mode 100644
index 0000000..2591544
--- /dev/null
+++ b/src/constants/defaultValues.js
@@ -0,0 +1,9 @@
+export const ApiConfig = {
+ apiKey: 'AIzaSyBBksq-Asxq2M4Ot-75X19IyrEYJqNBPcg',
+ authDomain: 'dnvn.ir',
+ baseUrl: 'https://dnvn.ir/api/v1',
+ //baseUrl: 'http://localhost:3030/api/v1',
+ loginURL: 'user/login',
+ otploginURL: 'user/otp/login',
+ logoutURL: 'user/logout',
+};
\ No newline at end of file
diff --git a/src/redux/actions/blog.js b/src/redux/actions/blog.js
new file mode 100644
index 0000000..d873065
--- /dev/null
+++ b/src/redux/actions/blog.js
@@ -0,0 +1,27 @@
+import proxy from "../proxy";
+const blog = {
+ list:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/blogList", data, { dispatch }),
+ // update:
+ // (data = {}, data2 = {}) =>
+ // async (dispatch : Dispatch) => {
+ // await proxy.put("blog/update", data);
+ // await proxy.get("blog/list", data2, { dispatch });
+ // },
+ // add:
+ // (data = {}, data2 = {}) =>
+ // async (dispatch : Dispatch) => {
+ // await proxy.post("blog/add", data);
+ // await proxy.get("blog/list", data2, { dispatch });
+ // },
+ // del:
+ // (data = {}, data2 = {}) =>
+ // async (dispatch : Dispatch) => {
+ // await proxy.delete("blog/delete", data);
+ // await proxy.get("blog/list", data2, { dispatch });
+ // },
+};
+
+export default blog;
diff --git a/src/redux/actions/book.js b/src/redux/actions/book.js
new file mode 100644
index 0000000..baa730c
--- /dev/null
+++ b/src/redux/actions/book.js
@@ -0,0 +1,39 @@
+import proxy from "../proxy";
+const book = {
+ list:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("book/list", data, { dispatch }),
+ setLessonActive: (data) => async (dispatch) =>
+ await dispatch({ type: "book/lesson/active", data: data }),
+ gradeFilter: (data) => async (dispatch) =>
+ await dispatch({ type: "book/gradeFilter", data: data }),
+ sortFilter: (data) => async (dispatch) =>
+ await dispatch({ type: "book/sortFilter", data: data }),
+ // update:
+ // (data = {}, data2 = {}) =>
+ // async (dispatch : Dispatch) => {
+ // await proxy.put("book/update", data);
+ // await proxy.get("book/list", data2, { dispatch });
+ // },
+ // add:
+ // (data = {}, data2 = {}) =>
+ // async (dispatch) => {
+ // await proxy.post("book/add", data);
+ // await proxy.get("book/list", data2, { dispatch });
+ // },
+ // del:
+ // (data = {}, data2 = {}) =>
+ // async (dispatch) => {
+ // await proxy.delete("book/delete", data);
+ // await proxy.get("book/list", data2, { dispatch });
+ // },
+ // searchBook: (data) => async (dispatch) => {
+ // dispatch({ type: "book/search", data: data });
+ // },
+ // filterBook: (data) => async (dispatch) => {
+ // dispatch({ type: "book/filter", data: data });
+ // },
+};
+
+export default book;
diff --git a/src/redux/actions/content.js b/src/redux/actions/content.js
new file mode 100644
index 0000000..e09c8c8
--- /dev/null
+++ b/src/redux/actions/content.js
@@ -0,0 +1,14 @@
+import proxy from "../proxy";
+import { Dispatch } from "redux";
+const content = {
+ listVOD:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("content/listVOD", data, { dispatch }),
+ infoVOD:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("content/infoVOD", data, { dispatch }),
+};
+
+export default content;
diff --git a/src/redux/actions/faq.js b/src/redux/actions/faq.js
new file mode 100644
index 0000000..aaf031b
--- /dev/null
+++ b/src/redux/actions/faq.js
@@ -0,0 +1,20 @@
+import proxy from "../proxy";
+import { Dispatch } from "redux";
+const faq = {
+ list:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("faq/list", data, { dispatch }),
+ add:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.post("faq/add", data, { dispatch }),
+ selectFaq:
+ (data = {}) =>
+ async (dispatch) =>
+ await dispatch({ type: "faq/selectFaq", data: data }),
+ searchFaq: (data) => async (dispatch) =>
+ await dispatch({ type: "faq/search", data: data }),
+};
+
+export default faq;
diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js
new file mode 100644
index 0000000..02090a1
--- /dev/null
+++ b/src/redux/actions/file.js
@@ -0,0 +1,22 @@
+import proxy from "../proxy";
+const file = {
+ upload:
+ (data = {}) =>
+ async (dispatch) => {
+ var formData = new FormData();
+ for (let key in data) formData.append(key, data[key]);
+ return await proxy.post(
+ "file/upload",
+ formData,
+ {
+ dispatch,
+ headers: {
+ "Content-Type": "multipart/form-data",
+ },
+ },
+ data
+ );
+ },
+};
+
+export default file;
diff --git a/src/redux/actions/index.js b/src/redux/actions/index.js
new file mode 100644
index 0000000..9fd9385
--- /dev/null
+++ b/src/redux/actions/index.js
@@ -0,0 +1,16 @@
+// @create-index
+export { default as publicApi } from "./public";
+export { default as user } from "./user";
+export { default as book } from "./book";
+export { default as blog } from "./blog";
+export { default as product } from "./product";
+export { default as userFactor } from "./userFactor";
+export { default as userProduct } from "./userProduct";
+export { default as content } from "./content";
+export { default as faq } from "./faq";
+export { default as file } from "./file";
+
+
+
+
+
diff --git a/src/redux/actions/product.js b/src/redux/actions/product.js
new file mode 100644
index 0000000..7a770ad
--- /dev/null
+++ b/src/redux/actions/product.js
@@ -0,0 +1,26 @@
+import proxy from "../proxy";
+const product = {
+ listVOD:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("product/listVOD", data, { dispatch }),
+ addVOD:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.post("product/addVOD", data);
+ await proxy.get("product/listVOD", data2, { dispatch });
+ },
+ deleteVOD:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.delete("product/deleteVOD", data);
+ await proxy.get("product/listVOD", data2, { dispatch });
+ },
+ selectVOD:
+ (data = {}) =>
+ async (dispatch) => {
+ await dispatch({ type: "product/selectVOD", data });
+ },
+};
+
+export default product;
diff --git a/src/redux/actions/public.js b/src/redux/actions/public.js
new file mode 100644
index 0000000..94344e3
--- /dev/null
+++ b/src/redux/actions/public.js
@@ -0,0 +1,50 @@
+import proxy from "../proxy";
+const publicApi = {
+ setTheme: (data) => async (dispatch) =>
+ await dispatch({ type: "public/setTheme", data: data }),
+ getHomeData: (data) => async (dispatch) =>
+ await proxy.get("public/homePage", data, { dispatch }),
+
+ setFaqActive: (data) => async (dispatch) =>
+ await dispatch({ type: "public/faq/activate", data: data }),
+ bookInfo:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/vod/bookCourse", data, { dispatch }),
+ bookSection:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/vod/bookSection", data, { dispatch }),
+ getContactData:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/contact", data, { dispatch }),
+
+ getBlogList: (data) => async (dispatch) =>
+ await proxy.get("public/blogList", data, { dispatch }),
+
+ getBlogInfo: (data) => async (dispatch) =>
+ await proxy.get("public/blogInfo", data, { dispatch }),
+ setSubscribe: (data) => async (dispatch) =>
+ await dispatch({ type: "public/setSubscribe", data: data }),
+ getProvince:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/province", data, { dispatch }),
+ getCity:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/city", data, { dispatch }),
+ selectMenu: (data) => async (dispatch) =>
+ await dispatch({ type: "public/selectMenu", data: data }),
+ getHeader:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("public/VOD/homePage", data, { dispatch }),
+ activeCategory: (data) => async (dispatch) =>
+ await dispatch({ type: "active/category", data: data }),
+ setVideoActive: (data) => async (dispatch) =>
+ await dispatch({ type: "active/video", data: data }),
+};
+
+export default publicApi;
diff --git a/src/redux/actions/user.js b/src/redux/actions/user.js
new file mode 100644
index 0000000..31fe949
--- /dev/null
+++ b/src/redux/actions/user.js
@@ -0,0 +1,63 @@
+import proxy from "../proxy";
+
+const user = {
+ otp: (data) => async (dispatch) =>
+ await proxy.post("public/sendOTP", data, { dispatch }),
+
+ otp_login: (data) => async (dispatch) =>
+ await proxy.login("user/otp/login", data, { dispatch }),
+
+ login: (data) => async (dispatch) =>
+ await proxy.login("user/login", data, { dispatch }),
+
+ // register: (data : undefined) => async (dispatch : Dispatch) =>
+ // await proxy.login("user/register", data, { dispatch }),
+
+ // switchRole: (data : String) => async (dispatch : Dispatch) =>
+ // await proxy.login("user/switchRole", data, { dispatch }),
+
+ logout: (data) => async (dispatch) =>
+ await proxy.logout("user/logout", data, { dispatch }),
+
+ getUserRole: (data) => async (dispatch) =>
+ await proxy.get("user/getUserRole", data, { dispatch }),
+
+ // list:
+ // (data = {}) =>
+ // async (dispatch : Dispatch) =>
+ // await proxy.get("user/list", data, { dispatch }),
+ // domains:
+ // (data = {}) =>
+ // async (dispatch : Dispatch) =>
+ // await proxy.get("user/domains", data, { dispatch }),
+ // getmothers:
+ // (data = {}) =>
+ // async (dispatch : Dispatch) =>
+ // await proxy.get("mothers/list", data, {
+ // dispatch,
+ // }),
+ getProfile:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("user/getProfile", data, { dispatch }),
+ setProfile:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.put("user/setProfile", data, { dispatch });
+ await proxy.get("user/getProfile", data2, { dispatch });
+ },
+ add:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.post("user/add", data);
+ await proxy.get("user/list", data2, { dispatch });
+ },
+ del:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.delete("user/delete", data);
+ await proxy.get("user/list", data2, { dispatch });
+ },
+};
+
+export default user;
diff --git a/src/redux/actions/userFactor.js b/src/redux/actions/userFactor.js
new file mode 100644
index 0000000..16424e9
--- /dev/null
+++ b/src/redux/actions/userFactor.js
@@ -0,0 +1,31 @@
+import proxy from "../proxy";
+const userFactor = {
+ payment:
+ (data1 = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.post("userProduct/addVOD", data1, { dispatch });
+ await proxy.post("userFactor/paymentVOD", data2, { dispatch });
+ },
+ verify:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.post("userFactor/verifyVOD", data, { dispatch }),
+ info:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.get("userFactor/info", data, { dispatch }),
+ update:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.put("userFactor/update", data, { dispatch });
+ await proxy.get("userFactor/info", data2, { dispatch });
+ },
+ deleteUserOffCode:
+ (data = {}, data2 = {}) =>
+ async (dispatch) => {
+ await proxy.delete("userFactor/deleteUserOffCode", data, { dispatch });
+ await proxy.get("userFactor/info", data2, { dispatch });
+ },
+};
+
+export default userFactor;
diff --git a/src/redux/actions/userProduct.js b/src/redux/actions/userProduct.js
new file mode 100644
index 0000000..677c191
--- /dev/null
+++ b/src/redux/actions/userProduct.js
@@ -0,0 +1,9 @@
+import proxy from "../proxy";
+const userProduct = {
+ addVOD:
+ (data = {}) =>
+ async (dispatch) =>
+ await proxy.post("userProduct/addVOD", data, { dispatch }),
+};
+
+export default userProduct;
\ No newline at end of file
diff --git a/src/redux/index.js b/src/redux/index.js
new file mode 100644
index 0000000..94cfa95
--- /dev/null
+++ b/src/redux/index.js
@@ -0,0 +1,7 @@
+// @create-index
+
+export { default as actions } from './actions';
+export { default as proxy } from './proxy.js';
+export { default as reducers } from './reducers';
+export { default as store } from './store.js';
+
diff --git a/src/redux/proxy.js b/src/redux/proxy.js
new file mode 100644
index 0000000..23bc497
--- /dev/null
+++ b/src/redux/proxy.js
@@ -0,0 +1,120 @@
+import { ApiConfig } from "../constants/defaultValues";
+import axios from "axios";
+
+let { baseUrl } = ApiConfig;
+let access = window.localStorage.getItem("access");
+baseUrl = baseUrl + "/";
+
+const Axios = axios.create({
+ withCredentials: true,
+ validateStatus: null,
+ baseURL: baseUrl,
+ //headers: access ? { Authorization: `Bearer ${access}` } : {},
+});
+class Proxy {
+ get = async (url, params, opt, data) =>
+ await this.check(
+ url,
+ opt,
+ async () => await Axios.get(url, { params, ...opt }),
+ data || params
+ );
+ post = async (url, params, opt, data ) =>
+ await this.check(
+ url,
+ opt,
+ async () => await Axios.post(url, params, opt),
+ data || params
+ );
+ put = async (url , params , opt , data ) =>
+ await this.check(
+ url,
+ opt,
+ async () => await Axios.put(url, params, opt),
+ data || params
+ );
+ delete = async (url , params , opt , data ) => {
+ await this.check(
+ url,
+ opt,
+ async () => await Axios.delete(url, { ...opt, data: params }),
+ data || params
+ );
+ };
+
+ check = async (url , { dispatch } , fetch , params ) => {
+ dispatch = dispatch || (() => {});
+ dispatch({ type: url.split("/")[0] + "/" + "loading" });
+ let response = await fetch();
+ switch (response.status) {
+ case 200:
+ dispatch({ type: url, data: response.data.data, params });
+ return response.data.data;
+ case 401:
+ if (await this.refresh()) {
+ let response = await fetch();
+ dispatch({ type: url, data: response.data.data, params });
+ return response.data.data;
+ }
+ break;
+ default:
+ dispatch({
+ type: url.split("/")[0] + "/" + "error",
+ data: response.data,
+ params,
+ });
+ }
+ return false;
+ };
+
+ refresh = async () => {
+ let refresh = localStorage.getItem("refresh");
+ if (!refresh) window.location.href = "/";
+ let login = await this.login(
+ "user/login",
+ {},
+ { headers: { Authorization: `Bearer ${refresh}` } }
+ );
+ return login ? true : false;
+ };
+ login = async (url , params , { dispatch } ) =>
+ this.post(url, params, {
+ dispatch: (obj ) => {
+ let login = obj.data;
+ if (!login || !login.refreshToken) return false;
+ localStorage.setItem("refresh", login.refreshToken);
+ localStorage.setItem("access", login.accessToken);
+ delete login.refreshToken;
+ delete login.accessToken;
+ localStorage.setItem("userData", JSON.stringify(login.profile));
+ dispatch(obj);
+ },
+ });
+
+ logout = async (url , params , { dispatch } ) => {
+ this.post(url, params, {
+ dispatch: (obj ) => {
+ localStorage.removeItem("refresh");
+ localStorage.removeItem("access");
+ localStorage.removeItem("userData");
+ dispatch(obj);
+ },
+ });
+ };
+ status = () => {
+ let refresh = localStorage.getItem("refresh");
+ let userData = localStorage.getItem("userData");
+ if (!refresh) return false;
+ if (refresh == "undefined") {
+ localStorage.removeItem("refresh");
+ localStorage.removeItem("access");
+ localStorage.removeItem("userData");
+ return false;
+ }
+
+ return JSON.parse(userData || '');
+ };
+}
+const _proxy = new Proxy();
+
+export default _proxy;
diff --git a/src/redux/reducers/blog.js b/src/redux/reducers/blog.js
new file mode 100644
index 0000000..f7fafc3
--- /dev/null
+++ b/src/redux/reducers/blog.js
@@ -0,0 +1,28 @@
+import { toast } from "react-toastify";
+
+const initialState = {
+ loading: false,
+ error: null,
+ list: [],
+};
+export default function blog(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ case "public/blogList":
+ return { ...state, loading: false, list: data, error: null };
+ // case "blog/update":
+ // return { ...state, loading: false, error: null };
+ // case "blog/add":
+ // return { ...state, loading: false, error: null };
+ // case "blog/delete":
+ // return { ...state, loading: false, error: null };
+ /////////////
+ case "blog/loading":
+ return { ...state, loading: true };
+ case "blog/error":
+ toast.error(data.message);
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/book.js b/src/redux/reducers/book.js
new file mode 100644
index 0000000..df57c87
--- /dev/null
+++ b/src/redux/reducers/book.js
@@ -0,0 +1,166 @@
+import { toast } from "react-toastify";
+
+const initialState = {
+ loading: false,
+ error: null,
+ list: [],
+ info: null,
+ searchResult: [],
+ filterResult: [],
+ subjects: [],
+ levels: [],
+ sortFilters: ["مرتب سازی", "محبوب ترین", "جدیدترین"],
+ selectedVideo: null,
+ gradeFilterBooks: null,
+ sortFilterCourse: null,
+ selectedGrade: null,
+ selectedSort: "پربازدید ترین ها",
+};
+
+const grades = [
+ "پیش دبستان",
+ "اول",
+ "دوم",
+ "سوم",
+ "چهارم",
+ "پنجم",
+ "ششم",
+ "هفتم",
+ "هشتم",
+ "نهم",
+ "دهم",
+ "یازدهم",
+ "دوازدهم",
+];
+
+export default function book(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ case "book/list":
+ let itemsSubject = (Array.isArray(data) ? data : []).map(
+ (item, index) => item.name
+ );
+ if (window.innerWidth < 1000) {
+ itemsSubject.unshift("نام کتاب");
+ }
+ let itemsLevel = (Array.isArray(data) ? data : [])
+ .map((item) => item.gradeId * 1)
+ .sort((a, b) => a - b)
+ .map((e) => grades[e]);
+ if (window.innerWidth < 1000) {
+ itemsLevel.unshift("پایه تحصیلی");
+ }
+ return {
+ ...state,
+ loading: false,
+ list: data,
+ subjects: Array.from(new Set(itemsSubject)),
+ levels: Array.from(new Set(itemsLevel)),
+ filterResult: data,
+ error: null,
+ };
+ case "book/lesson/active":
+ return {
+ ...state,
+ loading: false,
+ error: null,
+ };
+ case "book/gradeFilter":
+ if (data === state.selectedGrade) {
+ return { ...state, gradeFilterBooks: null, selectedGrade: null };
+ } else {
+ return {
+ ...state,
+ gradeFilterBooks: state.list.filter(
+ (item, i) => item.gradeId === data
+ ),
+ selectedGrade: data,
+ };
+ }
+ case "book/sortFilter":
+ const search = state.list.filter(
+ (item) => item.name.indexOf(data.search) !== -1
+ );
+ if (data.sort === "تمامی دورهها") {
+ return { ...state, sortFilterCourse: search, selectedSort: data.sort };
+ } else if (data.sort === "جدیدترینها") {
+ return {
+ ...state,
+ sortFilterCourse: search.sort((item1, item2) => {
+ return item1.publishYear - item2.publishYear;
+ }),
+ selectedSort: data.sort,
+ };
+ }
+ return { ...state, sortFilterCourse: search, selectedSort: data.sort };
+
+ // case "book/update":
+ // return { ...state, loading: false, error: null };
+ // case "book/add":
+ // return { ...state, loading: false, error: null };
+ // case "book/delete":
+ // return { ...state, loading: false, error: null };
+ // case "book/search":
+ // return { ...state };
+ // case "book/filter":
+ // const realList = state.list;
+ // const level = data.level;
+ // const subject = data.subject;
+ // const sort = data.sort;
+ // const search = data.search;
+ // if (level.length > 0 || subject.length > 0 || sort || search) {
+ // localStorage.setItem("filter", "ON");
+ // }
+ // let finalSort;
+ // let byLevelFilter = [];
+ // if (level.length > 0) {
+ // level.map((item1) => {
+ // for (let i = 0; i < realList.length; i++) {
+ // if (grades[realList[i].gradeId] === item1) {
+ // byLevelFilter.push(realList[i]);
+ // }
+ // }
+ // });
+ // } else {
+ // byLevelFilter = realList;
+ // }
+
+ // let bySubjectFilter = [];
+ // if (subject.length > 0) {
+ // subject.map((item1) => {
+ // for (let i = 0; i < byLevelFilter.length; i++) {
+ // if (byLevelFilter[i].name === item1) {
+ // bySubjectFilter.push(byLevelFilter[i]);
+ // }
+ // }
+ // });
+ // } else {
+ // bySubjectFilter = byLevelFilter;
+ // }
+
+ // const bySearchFilter = search
+ // ? bySubjectFilter.filter((item1) => item1.name.indexOf(search) !== -1)
+ // : bySubjectFilter;
+
+ // if (sort === "گران ترین") {
+ // finalSort = bySearchFilter.sort((item1, item2) => {
+ // return item1.product[0].price - item2.product[0].price;
+ // });
+ // } else {
+ // finalSort = bySearchFilter;
+ // }
+ // return {
+ // ...state,
+ // loading: false,
+ // error: null,
+ // filterResult: finalSort,
+ // };
+ case "book/loading":
+ return { ...state, loading: true };
+ case "book/error":
+ toast.error(data.message);
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/faq.js b/src/redux/reducers/faq.js
new file mode 100644
index 0000000..c89b078
--- /dev/null
+++ b/src/redux/reducers/faq.js
@@ -0,0 +1,57 @@
+import { toast } from "react-toastify";
+
+const initialState = {
+ loading: false,
+ error: null,
+ list: [],
+ searchResult: [],
+ search: null,
+};
+export default function faq(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ case "faq/list":
+ return { ...state, loading: false, list: data, error: null };
+ case "faq/add":
+ return { ...state, loading: false, error: null };
+ case "faq/selectFaq":
+ return {
+ ...state,
+ loading: false,
+ error: null,
+ list: !state.search
+ ? state.list.map((item) =>
+ item.id === data
+ ? { ...item, active: !item.active }
+ : { ...item, active: false }
+ )
+ : state.list,
+ searchResult: state.search
+ ? state.searchResult.map((item) =>
+ item.id === data
+ ? { ...item, active: !item.active }
+ : { ...item, active: false }
+ )
+ : state.searchResult,
+ };
+ case "faq/search":
+ return {
+ ...state,
+ loading: false,
+ error: null,
+ search: data,
+ searchResult: state.list.filter(
+ (item) =>
+ item.title.indexOf(data) !== -1 ||
+ item.description.indexOf(data) !== -1
+ ),
+ };
+ case "faq/loading":
+ return { ...state, loading: true };
+ case "faq/error":
+ toast.error(data.message);
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/file.js b/src/redux/reducers/file.js
new file mode 100644
index 0000000..164494c
--- /dev/null
+++ b/src/redux/reducers/file.js
@@ -0,0 +1,26 @@
+const initialState = {
+ loading: false,
+ error: null,
+ uploads: {},
+ lastUpload: null,
+};
+
+export default function file(state = initialState, action) {
+ let { type, data, params } = action;
+ switch (type) {
+ case "file/upload":
+ return {
+ ...state,
+ loading: false,
+ error: null,
+ uploads: { ...state.uploads, [params?.target || "last"]: data.id },
+ lastUpload: data.id,
+ };
+ case "file/loading":
+ return { ...state, loading: true };
+ case "file/error":
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/index.js b/src/redux/reducers/index.js
new file mode 100644
index 0000000..e5ec6b1
--- /dev/null
+++ b/src/redux/reducers/index.js
@@ -0,0 +1,13 @@
+// @create-index
+export { default as publicApi } from "./public";
+export { default as user } from "./user";
+export { default as book } from "./book";
+export { default as blog } from "./blog";
+export { default as product } from "./product";
+export { default as faq } from "./faq";
+export { default as file } from "./file";
+export { default as userFactor } from "./userFactor";
+export { default as userProduct } from "./userProduct";
+
+
+
diff --git a/src/redux/reducers/product.js b/src/redux/reducers/product.js
new file mode 100644
index 0000000..411a256
--- /dev/null
+++ b/src/redux/reducers/product.js
@@ -0,0 +1,28 @@
+import { toast } from "react-toastify";
+
+const initialState = {
+ loading: false,
+ error: null,
+ listVOD: [],
+ selectedVOD: null,
+};
+export default function product(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ case "product/listVOD":
+ return { ...state, loading: false, listVOD: data, error: null };
+ case "product/addVOD":
+ return { ...state, loading: false, error: null };
+ case "product/deleteVOD":
+ return { ...state, loading: false, error: null };
+ case "product/selectVOD":
+ return {...state, selectedVOD : data};
+ case "product/loading":
+ return { ...state, loading: true };
+ case "product/error":
+ toast.error(data.message);
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/public.js b/src/redux/reducers/public.js
new file mode 100644
index 0000000..c896aeb
--- /dev/null
+++ b/src/redux/reducers/public.js
@@ -0,0 +1,243 @@
+import location from '../../utils/location';
+
+const initialState = {
+ theme : localStorage.getItem('theme') || 'light',
+ homeData: [],
+ newProducts: [],
+ levels: [],
+ loading: false,
+ error: null,
+ searchResult: [],
+ arList: [],
+ blogList: [],
+ blog: null,
+ province: null,
+ city: null,
+ departmans: [
+ {
+ id: 0,
+ name: "محتوا",
+ },
+ {
+ id: 0,
+ name: "دیزاین",
+ },
+ {
+ id: 0,
+ name: "برنامه نویسی",
+ },
+ ],
+ header: [],
+ selectedMenu: null,
+ contactData: null,
+ selectedVideo: null,
+ bookInfo: null,
+ activeCategory: null,
+ categories: null,
+ bookSection: null,
+};
+
+const grades = [
+ "پیش دبستان",
+ "اول",
+ "دوم",
+ "سوم",
+ "چهارم",
+ "پنجم",
+ "ششم",
+ "هفتم",
+ "هشتم",
+ "نهم",
+ "دهم",
+ "یازدهم",
+ "دوازدهم",
+];
+export default function publicApi(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ case "public/setTheme":
+ localStorage.setItem("theme", data);
+ return { ...state, location: false, error : null, theme: data };
+ 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":
+ const videoId = location.getId();
+ return {
+ ...state,
+ loading: false,
+ bookSection: data,
+ error: null,
+ selectedVideo: data.vods?.filter((item) => item.id !== videoId)[0]
+ };
+
+ case "public/vod/bookCourse":
+ let allCats;
+ allCats = Array.from(
+ new Set(
+ data.vods.map((item) => item.categoryId && item.categoryId)
+ )
+ );
+ return {
+ ...state,
+ loading: false,
+ bookInfo: {
+ ...data,
+ vods: data.vods.map((item) => {
+ return { ...item, active: false };
+ }),
+ },
+ error: null,
+ categories: allCats.map((item) =>
+ data.vods.filter((item1) => item1.categoryId === item)
+ ),
+ selectedVideo: data.vods.filter((item ) => item.id !== location.getId())[0],
+ };
+ case "public/homePage":
+ let itemsLevel;
+ if (window.innerWidth > 1000) {
+ const jadidTarin = data.filter(
+ (item) => item.title === "جدیدترین کتابهای دانوین"
+ );
+ itemsLevel = jadidTarin[0].data
+ .map((item) => item.book.gradeId * 1)
+ .sort((a, b) => a - b)
+ .map((e) => grades[e]);
+ itemsLevel.unshift("همه");
+ }
+
+ return {
+ ...state,
+ loading: false,
+ levels: window.innerWidth > 1000 ? Array.from(new Set(itemsLevel)) : [],
+ error: null,
+ homeData: data,
+ };
+ // case "public/filter":
+ // const realList =
+ // state.newProducts.length === 0
+ // ? state.homeData.filter(
+ // (item) => item.title === "جدیدترین کتابهای دانوین"
+ // )[0].data
+ // : state.newProducts;
+ // if (state.newProducts.length === 0) {
+ // state = {
+ // ...state,
+ // newProducts: realList,
+ // };
+ // console.log("here1");
+ // }
+ // const level = data.levels;
+ // const search = data.search;
+ // if (level.length > 0 || search) {
+ // localStorage.setItem("filter", "ON");
+ // } else {
+ // return {
+ // ...state,
+ // loading: false,
+ // error: null,
+ // homeData: state.homeData.map((item) =>
+ // item.title === "جدیدترین کتابهای دانوین"
+ // ? { ...item, data: state.newProducts }
+ // : { ...item }
+ // ),
+ // newProducts: [],
+ // };
+ // }
+ // let byLevelFilter = [];
+ // if (level.length > 0) {
+ // level.map((item1) => {
+ // for (let i = 0; i < realList.length; i++) {
+ // if (grades[realList[i].book.gradeId] === item1) {
+ // byLevelFilter.push(realList[i]);
+ // }
+ // }
+ // });
+ // } else {
+ // byLevelFilter = realList;
+ // }
+
+ // // let bySubjectFilter = [];
+ // // if (subject.length > 0) {
+ // // subject.map((item1) => {
+ // // for (let i = 0; i < byLevelFilter.length; i++) {
+ // // if (byLevelFilter[i].name === item1) {
+ // // bySubjectFilter.push(byLevelFilter[i]);
+ // // }
+ // // }
+ // // });
+ // // } else {
+ // // bySubjectFilter = byLevelFilter;
+ // // }
+
+ // const bySearchFilter = search
+ // ? byLevelFilter.filter((item1) => item1.name.indexOf(search) !== -1)
+ // : byLevelFilter;
+ // // if (sort === "گران ترین") {
+ // // finalSort = bySearchFilter.sort((item1, item2) => {
+ // // return item1.product[0].price - item2.product[0].price;
+ // // });
+ // // } else {
+ // // finalSort = bySearchFilter;
+ // // }
+
+ // return {
+ // ...state,
+ // loading: false,
+ // error: null,
+ // homeData: state.homeData.map((item) =>
+ // item.title === "جدیدترین کتابهای دانوین"
+ // ? { ...item, data: bySearchFilter }
+ // : { ...item }
+ // ),
+ // };
+ // case "faq/list":
+ // return { ...state, loading: false, error: null, faqList: data };
+ // case "public/faq/search":
+ // return {
+ // ...state,
+ // loading: false,
+ // error: null,
+ // searchResult: state.faqList.filter(
+ // (item) =>
+ // item.title.indexOf(data) !== -1 ||
+ // item.description.indexOf(data) !== -1
+ // ),
+ // };
+ case "public/contact":
+ return { ...state, loading: false, error: null, contactData: data };
+ // case "public/ar":
+ // return { ...state, loading: false, error: null, arList: data };
+ case "public/blogList":
+ return { ...state, loading: false, error: null, blogList: data };
+ case "public/blogInfo":
+ return { ...state, loading: false, error: null, blog: data };
+ case "public/setSubscribe":
+ 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 };
+ case "public/VOD/homePage":
+ return { ...state, loading: false, error: null, header: data };
+ case "loading":
+ return { ...state, loading: true };
+ case "error":
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/user.js b/src/redux/reducers/user.js
new file mode 100644
index 0000000..d856d84
--- /dev/null
+++ b/src/redux/reducers/user.js
@@ -0,0 +1,48 @@
+import proxy from "../proxy";
+import { toast } from "react-toastify";
+const initialState = {
+ status: proxy.status(),
+ loading: false,
+ error: null,
+ list: null,
+ domains: [],
+ mothers: [],
+ profileStatus: false,
+ setDone: false,
+ setLogin : false,
+};
+export default function user(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ // case "user/login":
+ // case "user/register":
+ // case "user/switchRole":
+ case "public/sendOTP":
+ return { ...state, loading: false, status: data.profile, error: null };
+ case "user/login":
+ case "user/otp/login":
+ return {
+ ...state,
+ loading: false,
+ status: data.profile,
+ error: null,
+ setLogin: !state.setLogin,
+ };
+ case "user/getProfile":
+ localStorage.setItem("userData", JSON.stringify(data));
+ return { ...state, loading: false, status: data, error: null, setDone : false, };
+ case "user/logout":
+ return { ...state, loading: false, status: proxy.status(), error: null };
+ case "user/getUserRole":
+ return { ...state, loading: false, userRoles: data, error: null };
+ case "user/setProfile":
+ toast.success("تغییرات اعمال شد.");
+ return { ...state, loading: false, error: null, setDone : true };
+ case "loading":
+ return { ...state, loading: true };
+ case "error":
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/userFactor.js b/src/redux/reducers/userFactor.js
new file mode 100644
index 0000000..88db2ef
--- /dev/null
+++ b/src/redux/reducers/userFactor.js
@@ -0,0 +1,39 @@
+import { toast } from "react-toastify";
+const initialState = {
+ loading: false,
+ error: null,
+ list: null,
+ info: null,
+ sum: null,
+ checkEmpty: false,
+ isVerified: null,
+};
+export default function userFactor(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ case "userFactor/myList":
+ return { ...state, loading: false, list: data, error: null };
+ case "userFactor/info":
+ return { ...state, loading: false, info: data, error: null };
+ case "userFactor/update":
+ toast.success("درخواست شما با موفقیت انجام شد.");
+ return { ...state, loading: false, error: null };
+ // case "userFactor/add":
+ // toast.success("درخواست شما با موفقیت انجام شد.");
+ // return { ...state, loading: false, error: null, sum: data.payPrice };
+ case "userFactor/deleteUserOffCode":
+ return { ...state, loading: false, error: null };
+ case "userFactor/paymentVOD":
+ window.location.replace(data);
+ return { ...state, loading: false, error: null, isVerified: false };
+ case "userFactor/verifyVOD":
+ return { ...state, loading: false, error: null, isVerified: true };
+ case "userFactor/loading":
+ return { ...state, loading: true };
+ case "userFactor/error":
+ toast.error(data.message);
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/reducers/userProduct.js b/src/redux/reducers/userProduct.js
new file mode 100644
index 0000000..23cfd01
--- /dev/null
+++ b/src/redux/reducers/userProduct.js
@@ -0,0 +1,19 @@
+import { toast } from "react-toastify";
+const initialState = {
+ loading: false,
+ error: null,
+};
+export default function userFactor(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ case "userProduct/addVOD":
+ return { ...state, loading: false, error: null };
+ case "userProduct/loading":
+ return { ...state, loading: true };
+ case "userProduct/error":
+ toast.error(data.message);
+ return { ...state, loading: false, error: data.message };
+ default:
+ return state;
+ }
+}
diff --git a/src/redux/store.js b/src/redux/store.js
new file mode 100644
index 0000000..ecaf6db
--- /dev/null
+++ b/src/redux/store.js
@@ -0,0 +1,14 @@
+import { createStore, applyMiddleware } from 'redux';
+import { composeWithDevTools } from 'redux-devtools-extension';
+import { combineReducers } from 'redux';
+import * as reducers from './reducers';
+import thunk from 'redux-thunk';
+const initialState = {};
+const middleware = [thunk];
+const store = createStore(
+ combineReducers(reducers),
+ initialState,
+ composeWithDevTools(applyMiddleware(...middleware))
+);
+export default store;
+
diff --git a/src/utils/location.js b/src/utils/location.js
new file mode 100644
index 0000000..aa083ce
--- /dev/null
+++ b/src/utils/location.js
@@ -0,0 +1,11 @@
+
+class location {
+ getId = () => {
+ const pathname = window.location.pathname;
+ return pathname.slice(pathname.lastIndexOf('/') + 1, pathname.length);
+ }
+}
+
+const _location = new location();
+
+export default _location;
\ No newline at end of file
diff --git a/src/utils/scroll.js b/src/utils/scroll.js
index 4ebf1f5..481d921 100644
--- a/src/utils/scroll.js
+++ b/src/utils/scroll.js
@@ -94,10 +94,8 @@ class scroll {
};
doubleLinearFormula = (currentScroll) => {
- const rect = document.getElementsById("video").getClientRects();
- console.log(rect);
-
- return 1;
+ const rect = document.getElementById("video").getBoundingClientRect();
+ console.log(rect.x / window.innerWidth * 100);
};
}
diff --git a/src/views/Home/Page2/Mobile/index.js b/src/views/Home/Page2/Mobile/index.js
index f36bd78..eeda611 100644
--- a/src/views/Home/Page2/Mobile/index.js
+++ b/src/views/Home/Page2/Mobile/index.js
@@ -12,7 +12,9 @@ export default function Mobile({ mobilePosition }) {
setChecked(false);
}
}, [mobilePosition]);
-
+ useEffect(async () => {
+ console.log(document.getElementById("video"));
+ },[]);
return (
diff --git a/src/views/Home/Page2/index.js b/src/views/Home/Page2/index.js
index c9ed948..7bf6af4 100644
--- a/src/views/Home/Page2/index.js
+++ b/src/views/Home/Page2/index.js
@@ -7,6 +7,7 @@ import qrImage from "../../../assets/images/qrImage.png";
export default function Page2({ list, page }) {
const height = window.innerHeight;
const [top, setTop] = useState(window.innerHeight);
+ const [videoPosition, setVideoPosition] = useState(null);
const [boxPosition, setBoxPosition] = useState({
translateY: null,
translateX: null,
@@ -78,6 +79,7 @@ export default function Page2({ list, page }) {
setTop(scroll.homeScrollHandler(page));
boxPositionHandler(window.scrollY);
mobilePositionHandler(window.scrollY);
+ videoPositionHandler(window.scrollY);
});
}, []);
@@ -138,6 +140,15 @@ export default function Page2({ list, page }) {
}
};
+ const videoPositionHandler = (scrollY) => {
+ if(scrollY <= 3 * height){
+ setVideoPosition(() => null);
+ }else if(scrollY > 3 * height && scrollY < 4 * height){
+ scroll.doubleLinearFormula(scrollY);
+ }else{
+
+ }
+ }
return (
+ {/*
*/}
+
+ >
+ );
+}
diff --git a/src/views/Home/VideoTube/Attachments/index.js b/src/views/Home/VideoTube/Attachments/index.js
new file mode 100644
index 0000000..366d9ae
--- /dev/null
+++ b/src/views/Home/VideoTube/Attachments/index.js
@@ -0,0 +1,13 @@
+import React from 'react';
+
+export default function Attachments({file,num}) {
+ return (
+
+
+ {num}
+
{file.name}
+
+
دریافت
+
+ )
+}
diff --git a/src/views/Home/VideoTube/Attachments/index.scss b/src/views/Home/VideoTube/Attachments/index.scss
new file mode 100644
index 0000000..60a2bb3
--- /dev/null
+++ b/src/views/Home/VideoTube/Attachments/index.scss
@@ -0,0 +1,70 @@
+.download-attachments{
+ color: white;
+ margin: 0px auto;
+ border-bottom: 1px solid $gray8;
+ span{
+
+ }
+ h4{
+ margin: 0px;
+ }
+ a{
+ padding: 5px 15px;
+ border: 1px solid $gray7;
+ color: white;
+ text-decoration: none;
+ border-radius: 8px;
+ }
+}
+
+@media screen and (min-width: 1441px) {
+ .download-attachments{
+ width: calc(100% - 20px);
+ padding: 20px 0px;
+ a{
+ font-size: 13px;
+ }
+ h4{
+ font-size: 15px;
+ }
+ }
+}
+
+@media screen and (min-width: 1008px) and (max-width: 1440px) {
+ .download-attachments{
+ width: calc(100% - 20px);
+ padding: 10px 0px;
+ a{
+ font-size: calc(100vw / 100);
+ }
+ h4{
+ font-size: calc(100vw / 100);
+ }
+ }
+}
+
+@media screen and (min-width: 641px) and (max-width: 1007px) {
+ .download-attachments{
+ width: calc(100% - 20px);
+ padding: 10px 0px;
+ a{
+ font-size: calc(100vw / 50);
+ }
+ h4{
+ font-size: calc(100vw / 50);
+ }
+ }
+}
+
+@media screen and (max-width: 640px) {
+ .download-attachments{
+ width: calc(100% - 20px);
+ padding: 10px 0px;
+ a{
+ font-size: calc(100vw / 40);
+ }
+ h4{
+ font-size: calc(100vw / 40);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/views/Home/VideoTube/Book/index.js b/src/views/Home/VideoTube/Book/index.js
new file mode 100644
index 0000000..e3a18a1
--- /dev/null
+++ b/src/views/Home/VideoTube/Book/index.js
@@ -0,0 +1,20 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+
+export default function Book({ data }) {
+ const desc = {
+ "ریاضی": 'ریاضی از ریاضت میاد ولی دانوین آسون و لذت بخشش کرده',
+ 'علوم': "علوم تجربی تو دانوین واقعا تجربی و محسوس میشه",
+ 'زیست شناسی': "زیست را در دانوین باید زیست",
+ 'شیمی': 'شیمی اینجا می فهمه کیمیا یعنی چی',
+ 'فیزیک': "با دانوین فیزیکو با یه لنز جدید ببنید"
+ }
+ return (
+
+
+
{data.name}
+
{desc[data.name] || ""}
+
+ )
+}
+
diff --git a/src/views/Home/VideoTube/Book/index.scss b/src/views/Home/VideoTube/Book/index.scss
new file mode 100644
index 0000000..e83d357
--- /dev/null
+++ b/src/views/Home/VideoTube/Book/index.scss
@@ -0,0 +1,82 @@
+.video-tube-suggest{
+ color: white;
+ img{
+ border-top-right-radius: 10px;
+ border-top-left-radius: 10px;
+ border-bottom-right-radius: 10px;
+ border-bottom-left-radius: 24px;
+ margin-bottom: 10px;
+ transition: all 0.5s;
+ }
+ &:hover{
+ color: white;
+ img{
+ transform: translateY(-10px);
+ }
+ }
+}
+
+@media screen and (min-width: 1441px) {
+ .video-tube-suggest{
+ width: 30%;
+ img{
+ width: 130px;
+ height: 180px;
+ }
+ h4{
+ font-size: 15px;
+ }
+ p{
+ font-size: 11px;
+ }
+ }
+}
+
+
+@media screen and (min-width: 1008px) and (max-width: 1440px) {
+ .video-tube-suggest{
+ width: 30%;
+ img{
+ width: 100%;
+ // height: 180px;
+ }
+ h4{
+ font-size: calc(100vw / 90);
+ }
+ p{
+ font-size: calc(100vw / 110);
+ }
+ }
+}
+
+@media screen and (min-width: 641px) and (max-width: 1007px) {
+ .video-tube-suggest{
+ width: 30%;
+ img{
+ width: 200px;
+ // height: 180px;
+ }
+ h4{
+ font-size: calc(100vw / 43);
+ }
+ p{
+ font-size: calc(100vw / 52);
+ }
+ }
+}
+
+@media screen and (max-width: 640px) {
+ .video-tube-suggest{
+ width: 30%;
+ img{
+ width: 100px;
+ // height: 180px;
+ }
+ h4{
+ font-size: calc(100vw / 36);
+ }
+ p{
+ font-size: calc(100vw / 43);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/views/Home/VideoTube/Comment/index.js b/src/views/Home/VideoTube/Comment/index.js
new file mode 100644
index 0000000..7ed5dd8
--- /dev/null
+++ b/src/views/Home/VideoTube/Comment/index.js
@@ -0,0 +1,20 @@
+import React from "react";
+// import Avatar from "@mui/material/Avatar";
+
+
+export default function Comment({ comment }) {
+ return (
+
+ {/*
*/}
+
+
+ {comment.name} {comment.text}
+
+
+
+ {comment.date}
+
+
+
+ );
+}
diff --git a/src/views/Home/VideoTube/Comment/index.scss b/src/views/Home/VideoTube/Comment/index.scss
new file mode 100644
index 0000000..93cb60e
--- /dev/null
+++ b/src/views/Home/VideoTube/Comment/index.scss
@@ -0,0 +1,92 @@
+.video-tube-comment{
+ padding: 10px 0px;
+ color: white;
+ div{
+ }
+ button{
+ background-color: inherit;
+ color: $green;
+ border: none;
+ margin-left: 20px;
+ }
+ p{
+ line-height: 1.5;
+ margin-bottom: 15px;
+ }
+}
+
+@media screen and (min-width: 1441px){
+ .video-tube-comment{
+ width: 90%;
+ p{
+ font-size: 13px;
+ strong{
+ font-size: 15px;
+ margin-left: 5px;
+ }
+ }
+ button{
+ font-size: 13px;
+ }
+ span{
+ font-size: 15px;
+ }
+ }
+}
+
+@media screen and (min-width: 1008px) and (max-width: 1440px) {
+ .video-tube-comment{
+ width: 90%;
+ p{
+ font-size: calc(100vw / 105);
+ strong{
+ font-size: calc(100vw / 90);
+ margin-left: 5px;
+ }
+ }
+ button{
+ font-size: calc(100vw / 100) !important;
+ }
+ span{
+ font-size: calc(100vw / 90);
+ }
+ }
+}
+
+@media screen and (min-width: 641px) and (max-width: 1007px) {
+ .video-tube-comment{
+ width: 95%;
+ p{
+ font-size: calc(100vw / 50);
+ strong{
+ font-size: calc(100vw / 45);
+ margin-left: 5px;
+ }
+ }
+ button{
+ font-size: calc(100vw / 50) !important;
+ }
+ span{
+ font-size: calc(100vw / 45);
+ }
+ }
+}
+
+@media screen and (max-width: 640px) {
+ .video-tube-comment{
+ width: 95%;
+ p{
+ font-size: calc(100vw / 38);
+ strong{
+ font-size: calc(100vw / 35);
+ margin-left: 5px;
+ }
+ }
+ button{
+ font-size: calc(100vw / 40) !important;
+ }
+ span{
+ font-size: calc(100vw / 35);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/views/Home/VideoTube/LessonPlayList/index.js b/src/views/Home/VideoTube/LessonPlayList/index.js
new file mode 100644
index 0000000..fe6526c
--- /dev/null
+++ b/src/views/Home/VideoTube/LessonPlayList/index.js
@@ -0,0 +1,145 @@
+import React, { useEffect } from "react";
+import { connect } from "react-redux";
+// import { publicApi } from "../../../redux/actions";
+import { Link } from "react-router-dom";
+import _ from 'lodash';
+
+function LessonPlayList({
+ category,
+ selectedVideo,
+ setVideoActive,
+ catergories,
+ realCategories,
+ vods,
+ theme,
+}) {
+ const bookId = localStorage.getItem("bookId");
+ useEffect(() => {
+ if (localStorage.getItem("scroll-list") && vods) {
+ const list = document.getElementById("list");
+ const listItem = document.getElementById(
+ "listItem" + selectedVideo?.id
+ );
+ const elementHeight = (listItem)?.offsetHeight;
+ const listHeight = (list).offsetHeight;
+ const index = vods?.findIndex(
+ (item) => item?.name === selectedVideo?.name
+ );
+ console.log(index);
+ console.log(listHeight, elementHeight * (Number(index) + 1));
+
+ if (elementHeight * (Number(index) + 1) > listHeight) {
+ list.scrollTo(0, elementHeight * (Number(index) + 1) + elementHeight);
+ }
+ localStorage.removeItem("scroll-list");
+ }
+ }, [vods]);
+
+ const light = theme === "light";
+ return (
+ <>
+ {
+
+ {bookId && (
+
+
+ {
+ realCategories.filter(
+ (item) => item.id === category[0].categoryId
+ )[0].name
+ }
+
+
+
+ )}
+
+ {bookId ? (
+ category.map((video, i) => (
+
setVideoActive(video)}
+ >
+
+ {Number(i) + 1}
+
+
+ {/*
*/}
+
+
22:05
+
+
+
{video.name}
+ {/*
{file.text}
*/}
+
+
+ ))
+ ) : (
+
setVideoActive(category)}
+ id={"listItem" + category.id}
+ >
+
+
+ {/*
*/}
+
+
22:05
+
+
+
{category.name}
+ {/*
{file.text}
*/}
+
+
+ )}
+
+ }
+ >
+ );
+}
+
+export default connect(
+ (state) => ({
+ selectedVideo: state.publicApi.selectedVideo,
+ realCategories: state.publicApi.bookInfo?.categories,
+ vods: state.publicApi.bookSection?.vods,
+ }),
+ {
+ // setVideoActive: publicApi.setVideoActive,
+ }
+)(LessonPlayList);
diff --git a/src/views/Home/VideoTube/LessonPlayList/index.scss b/src/views/Home/VideoTube/LessonPlayList/index.scss
new file mode 100644
index 0000000..f20be7f
--- /dev/null
+++ b/src/views/Home/VideoTube/LessonPlayList/index.scss
@@ -0,0 +1,265 @@
+.lesson-playlist {
+ width: 100%;
+ padding-bottom: 10px;
+ &-light {
+ header {
+ background-color: inherit !important;
+ h3 {
+ background-color: $gray12;
+ }
+ }
+ .lesson-playlist {
+ &__item {
+ * {
+ color: black !important;
+ }
+ &--active{
+ background-color: $gray13;
+ }
+ }
+ }
+ }
+ &-dark {
+ header {
+ background-color: inherit !important;
+ h3 {
+ background-color: $gray7;
+ }
+ span {
+ background-color: $gray7;
+ }
+ }
+ .lesson-playlist {
+
+ &__item {
+ &--count {
+ color: white;
+ }
+ &--active {
+ background: rgba($gray12, 0.21);
+ }
+ &--text {
+ h4 {
+ color: white;
+ }
+ p {
+ color: $gray7;
+ }
+ }
+ &--video {
+ span {
+ background-color: #0000006d;
+ color: white;
+ }
+ }
+ }
+ }
+ }
+ header {
+ margin-bottom: 5px;
+ h3 {
+ padding: 5px 10px;
+ margin: 0px;
+ }
+ span {
+ display: flex;
+ flex: 1;
+ height: 1px;
+ }
+ }
+ &__item {
+ &--text {
+ padding: 15px 10px;
+ h4 {
+ margin: 0px;
+ }
+ p {
+ margin: 0px;
+ }
+ }
+ &--video {
+ span {
+ padding: 0px 5px;
+ position: absolute;
+ left: 5px;
+ bottom: 10px;
+ }
+ }
+ }
+}
+
+@media screen and (min-width: 1441px) {
+ .lesson-playlist {
+ width: 100%;
+ header {
+ padding: 10px 40px 0px 0px !important;
+ h3 {
+ font-size: 16px;
+ }
+ span {
+ }
+ }
+ &__item {
+ padding: 10px 0px 5px 0px;
+ cursor: pointer;
+ &--count {
+ font-size: 18px;
+ width: 40px;
+ text-align: center;
+ }
+ &--text {
+ max-width: 55%;
+ h4 {
+ font-size: 17px;
+ }
+ p {
+ font-size: 14px;
+ }
+ }
+ &--video {
+ width: 142px;
+ height: 90px;
+ position: relative;
+ img {
+ width: 100%;
+ height: 100%;
+ }
+ span {
+ font-size: 18px;
+ }
+ }
+ }
+ }
+}
+
+@media screen and (min-width: 1008px) and (max-width: 1440px) {
+ .lesson-playlist {
+ width: 100%;
+ header {
+ padding: 10px 40px 0px 0px !important;
+ h3 {
+ font-size: calc(100vw / 95);
+ }
+ span {
+ }
+ }
+ &__item {
+ padding: 10px 0px 5px 0px;
+ cursor: pointer;
+ &--count {
+ font-size: calc(100vw / 72);
+ width: 40px;
+ text-align: center;
+ }
+ &--text {
+ max-width: 55%;
+ h4 {
+ font-size: calc(100vw / 90);
+ }
+ p {
+ font-size: calc(100vw / 100);
+ }
+ }
+ &--video {
+ width: 132px;
+ height: 90px;
+ position: relative;
+ img {
+ width: 100%;
+ height: 100%;
+ }
+ span {
+ font-size: calc(100vw / 100);
+ }
+ }
+ }
+ }
+}
+
+@media screen and (min-width: 641px) and (max-width: 1007px) {
+ .lesson-playlist {
+ width: 100%;
+ header {
+ padding: 10px 50px 0px 0px !important;
+ h3 {
+ font-size: calc(100vw / 45);
+ }
+ span {
+ }
+ }
+ &__item {
+ padding: 10px 0px 5px 0px;
+ cursor: pointer;
+ &--count {
+ font-size: calc(100vw / 35);
+ width: 50px;
+ text-align: center;
+ }
+ &--text {
+ max-width: 55%;
+ h4 {
+ font-size: calc(100vw / 45);
+ }
+ p {
+ font-size: calc(100vw / 50);
+ }
+ }
+ &--video {
+ width: 182px;
+ // height: 90px;
+ position: relative;
+ img {
+ width: 100%;
+ height: 100%;
+ }
+ span {
+ font-size: calc(100vw / 45);
+ }
+ }
+ }
+ }
+}
+
+@media screen and (max-width: 640px) {
+ .lesson-playlist {
+ width: 100%;
+ header {
+ padding: 10px 40px 0px 0px !important;
+ h3 {
+ font-size: calc(100vw / 38);
+ }
+ span {
+ }
+ }
+ &__item {
+ padding: 10px 0px 5px 0px;
+ cursor: pointer;
+ &--count {
+ font-size: calc(100vw / 25);
+ width: 40px;
+ text-align: center;
+ }
+ &--text {
+ max-width: 55%;
+ h4 {
+ font-size: calc(100vw / 35);
+ }
+ p {
+ font-size: calc(100vw / 40);
+ }
+ }
+ &--video {
+ width: 132px;
+ height: 90px;
+ position: relative;
+ img {
+ width: 100%;
+ height: 100%;
+ }
+ span {
+ font-size: calc(100vw / 40);
+ }
+ }
+ }
+ }
+}
diff --git a/src/views/Home/VideoTube/index.js b/src/views/Home/VideoTube/index.js
new file mode 100644
index 0000000..8757fac
--- /dev/null
+++ b/src/views/Home/VideoTube/index.js
@@ -0,0 +1,184 @@
+import React, { useState, useEffect, useRef } from "react";
+import LessonPlayList from "./LessonPlayList";
+import Attachments from "./Attachments";
+import Book from "./Book";
+import Comment from "./Comment";
+import AddComment from "./AddComment";
+import Video from "../../../components/JolPlayer";
+
+import listIcon from "../../assets/icons/list.png";
+import { connect } from "react-redux";
+import _ from "lodash";
+import scroll from "../../../utils/scroll.js";
+import location from "../../../utils/location.js";
+import { book, publicApi } from "../../redux/actions";
+import Loader from "../../components/Loader";
+
+function VodTube({
+ selectedVideo,
+ info,
+ bookSection,
+ loading,
+ getInfo,
+ categories,
+ setVideoActive,
+ allBooks,
+ theme,
+}) {
+ const videoListTag = useRef(null);
+ useEffect(() => {
+ localStorage.setItem("scroll-list", "on");
+ scroll.goToTop();
+ getInfo({
+ bookId: localStorage.getItem("bookId")
+ ? localStorage.getItem("bookId")
+ : localStorage.getItem("category")?.split(",")[0],
+ });
+ }, []);
+
+ useEffect(() => {
+ if (allBooks && localStorage.getItem("category")) {
+ const cat = localStorage.getItem("category")?.split(",");
+ bookSection({ bookId: cat[0], categoryId: cat[1] });
+ }
+ }, [allBooks]);
+
+ const light = theme === "light";
+ return (
+ <>
+
+
+
+
+ {/* */}
+
+ {/* درس دوم / بیست و یکم */}
+ {selectedVideo?.name}
+ {/* {selectedVideo.text}
*/}
+
+
+
+
+ {info?.comments?.map((comment, i) => (
+
+ ))}
+
+
+
+
+
+
+
+
+ {localStorage.getItem("bookId")
+ ? categories?.map((video, i) => (
+
+ ))
+ : info?.vods.map((video, i) => (
+
+ ))}
+
+
+ {info?.attachments.length > 0 && (
+
+
+
+ {info?.attachments?.map((file, i) => (
+
+ ))}
+
+
+ )}
+ {info?.related && (
+
+
+ پیشنهاد دانوین برای شما
+ تا 50% تخفیف
+
+
+ {info?.related.slice(0, 3).map((item, i) => (
+
+ ))}
+
+
+ )}
+
+
+
+
+ {info?.comments?.map((comment, i) => (
+
+ ))}
+
+
+
+
+
+
+ {loading && (
+
+
+
+ )}
+ >
+ );
+}
+
+export default connect(
+ (state) => ({
+ selectedVideo: state.publicApi.selectedVideo,
+ info: state.publicApi.bookSection,
+ loading: state.publicApi.loading,
+ categories: state.publicApi.categories,
+ allBooks: state.publicApi.bookInfo?.vods,
+ theme: state.publicApi.theme,
+ }),
+ {
+ getInfo: publicApi.bookInfo,
+ getBookList: book.list,
+ bookSection: publicApi.bookSection,
+ setVideoActive: publicApi.setVideoActive,
+ }
+)(VodTube);
diff --git a/src/views/Home/VideoTube/index.scss b/src/views/Home/VideoTube/index.scss
new file mode 100644
index 0000000..812da7c
--- /dev/null
+++ b/src/views/Home/VideoTube/index.scss
@@ -0,0 +1,672 @@
+@import "./Attachments/index.scss";
+@import "./Book/index.scss";
+@import "./Comment/index.scss";
+@import "./LessonPlayList/index.scss";
+
+.video-tube {
+ &-light {
+ background-color: white;
+ h1,
+ p {
+ color: black !important;
+ }
+ .video-tube {
+ &__content {
+ &--comments {
+ color: black !important;
+ header{
+ background-color: inherit !important;
+ h2{
+ color: $green !important;
+ }
+ }
+ button{
+ color: $green !important;
+ background-color: inherit;
+ }
+ }
+ &--addComment {
+ textarea {
+ background-color: $gray13;
+ color: black !important;
+ border: none;
+ }
+ }
+ }
+ &__sidebar {
+ header {
+ background-color: $gray12;
+ * {
+ color: black !important;
+ }
+ }
+ &--playlist{
+ border: 1px solid $gray7;
+ border-top: none;
+ }
+ &--suggests{
+ border : none;
+ &__list{
+ background-color: inherit;
+ }
+ }
+ &--attachments{
+ border: none;
+ }
+ }
+ }
+ }
+ &-dark {
+ .video-tube{
+ &__content {
+ &--display {
+ border-bottom: 1px solid $gray8;
+ video {
+ border: 1px solid $gray8;
+ }
+ span {
+ color: $green4;
+ }
+ h1 {
+ color: white;
+ }
+ p {
+ color: white;
+ }
+ }
+ &--comments {
+ color: white;
+ border-bottom: 1px solid $gray8;
+ header {
+ h2 {
+ color: white;
+ }
+ }
+ button {
+ background-color: inherit;
+ color: $green;
+ }
+ }
+ &--addComment {
+ textarea {
+ background-color: $gray8;
+ color: white;
+ &::placeholder {
+ color: $gray4;
+ }
+ }
+ }
+ }
+ &__sidebar {
+ &--playlist {
+ border: 1px solid $gray8;
+ header {
+ color: white;
+ }
+ &___list {
+ /* Track */
+ &::-webkit-scrollbar-track {
+ box-shadow: inset 0 0 5px inherit;
+ }
+
+ /* Handle */
+ &::-webkit-scrollbar-thumb {
+ background: $gray;
+ }
+
+ /* Handle on hover */
+ &::-webkit-scrollbar-thumb:hover {
+ background: white;
+ }
+ }
+ }
+ &--attachments {
+ border: 1px solid $gray8;
+ header {
+ color: white;
+ }
+ &___list {
+ /* Track */
+ &::-webkit-scrollbar-track {
+ box-shadow: inset 0 0 5px inherit;
+ }
+ /* Handle */
+ &::-webkit-scrollbar-thumb {
+ background: $gray10;
+ }
+ /* Handle on hover */
+ &::-webkit-scrollbar-thumb:hover {
+ background: white;
+ }
+ }
+ }
+ &--suggests {
+ border: 1px solid $gray8;
+ header {
+ color: white;
+ span {
+ background-color: #00fff74f;
+ color: $blue2;
+ }
+ }
+ }
+ }
+ }
+ }
+ &__content {
+ margin-left: 15px;
+
+ &--display {
+ padding-bottom: 30px;
+ video {
+ }
+ span {
+ padding: 15px 0px;
+ }
+ h1 {
+ margin-bottom: 20px;
+ }
+ p {
+ }
+ }
+ &--comments {
+ padding-bottom: 30px;
+ header {
+ padding: 20px 0px;
+ h2 {
+ margin: 0px;
+ }
+ }
+ button {
+ border: none;
+ }
+ }
+ &--addComment {
+ padding: 15px 0px;
+
+ textarea {
+ width: 100%;
+ border-radius: 12px;
+ padding: 10px;
+ &:focus {
+ outline: none;
+ }
+ }
+ }
+ }
+ &__sidebar {
+ &--playlist {
+ margin-bottom: 30px;
+ header {
+ width: 100%;
+ h2,
+ p {
+ margin: 0px;
+ }
+ p {
+ margin-top: 5px;
+ }
+ }
+ &___list {
+ padding-top: 10px;
+ overflow-y: scroll;
+ &::-webkit-scrollbar {
+ width: 8px;
+ }
+
+ /* Track */
+ &::-webkit-scrollbar-track {
+ border-radius: 10px;
+ }
+
+ /* Handle */
+ &::-webkit-scrollbar-thumb {
+ border-radius: 10px;
+ }
+
+ /* Handle on hover */
+ &::-webkit-scrollbar-thumb:hover {
+ }
+ }
+ }
+ &--attachments {
+ margin-bottom: 30px;
+ header {
+ width: 100%;
+ h2,
+ p {
+ margin: 0px;
+ }
+ p {
+ margin-top: 5px;
+ }
+ }
+ &___list {
+ overflow-y: scroll;
+ &::-webkit-scrollbar {
+ width: 8px;
+ }
+
+ /* Track */
+ &::-webkit-scrollbar-track {
+ border-radius: 10px;
+ }
+
+ /* Handle */
+ &::-webkit-scrollbar-thumb {
+ border-radius: 10px;
+ }
+
+ /* Handle on hover */
+ &::-webkit-scrollbar-thumb:hover {
+ }
+ }
+ }
+ &--suggests {
+ background-color: inherit;
+ header {
+ width: 100%;
+ h2 {
+ margin: 0px;
+ }
+ span {
+ padding: 5px 8px;
+ }
+ }
+ }
+ }
+}
+
+@media screen and (min-width: 1441px) {
+ .video-tube {
+ main {
+ max-width: $maxWidth;
+ margin-top: 10px;
+ }
+ &__content {
+ flex: 8;
+ &--display {
+ span {
+ font-size: 16px;
+ }
+ h1 {
+ font-size: 24px;
+ }
+ p {
+ font-size: 16px;
+ }
+ }
+ &--comments {
+ header {
+ h2 {
+ font-size: 20px;
+ }
+ }
+ button {
+ font-size: 14px;
+ }
+ }
+ &--addComment {
+ width: 60%;
+ textarea {
+ font-size: 14px;
+ &::placeholder {
+ font-size: 14px;
+ }
+ }
+ }
+ }
+ &__sidebar {
+ flex: 4;
+ &--playlist {
+ max-height: calc(100vh - 140px);
+ header {
+ padding: 12px;
+ background-color: #2c2c2c;
+ img {
+ transform: translateY(-5px);
+ }
+ h2 {
+ font-size: 16px;
+ }
+ p {
+ font-size: 10px;
+ }
+ }
+ }
+ &--attachments {
+ max-height: 320px;
+ header {
+ padding: 14px 12px;
+ background-color: rgba(#ebebeb, 0.21);
+ h2 {
+ font-size: 16px;
+ }
+ p {
+ font-size: 10px;
+ }
+ }
+ }
+ &--suggests {
+ header {
+ padding: 20px 12px;
+ // background-color: #8bd09746;
+ h2 {
+ font-size: 16px;
+ }
+ span {
+ font-size: 11px;
+ }
+ }
+ &___list {
+ padding: 15px 12px;
+ // background-color: #08793d58;
+ }
+ }
+ }
+ }
+}
+
+@media screen and (min-width: 1008px) and (max-width: 1440px) {
+ .video-tube {
+ main {
+ max-width: 1250px;
+ margin-top: 10px;
+ padding: 0px 10px;
+ }
+ &__content {
+ flex: 8;
+ &--display {
+ video {
+ width: 100%;
+ }
+ span {
+ font-size: calc(100vw / 100);
+ }
+ h1 {
+ font-size: calc(100vw / 60);
+ }
+ p {
+ font-size: calc(100vw / 100);
+ }
+ }
+ &--comments {
+ header {
+ h2 {
+ font-size: calc(100vw / 80);
+ }
+ }
+ button {
+ font-size: calc(100vw / 90);
+ }
+ }
+ &--addComment {
+ width: 60%;
+ button {
+ font-size: calc(100vw / 110);
+ }
+ textarea {
+ font-size: calc(100vw / 90);
+ &::placeholder {
+ font-size: calc(100vw / 90);
+ }
+ }
+ }
+ }
+ &__sidebar {
+ flex: 4;
+ &--playlist {
+ max-height: calc(100vh - 140px);
+ header {
+ padding: 14px 12px;
+ background-color: #2c2c2c;
+ img {
+ transform: translateY(-5px);
+ }
+ h2 {
+ font-size: calc(100vw / 85);
+ }
+ p {
+ font-size: calc(100vw / 120);
+ }
+ }
+ }
+ &--attachments {
+ max-height: 250px;
+ header {
+ padding: 14px 12px;
+ background-color: rgba(#ebebeb, 0.21);
+ h2 {
+ font-size: calc(100vw / 85);
+ }
+ p {
+ font-size: calc(100vw / 120);
+ }
+ }
+ }
+ &--suggests {
+ background-color: #001702;
+ header {
+ padding: 26px 12px;
+ background-color: rgba(#ebebeb, 0.21);
+ h2 {
+ font-size: calc(100vw / 85);
+ }
+ span {
+ font-size: calc(100vw / 120);
+ }
+ }
+ &___list {
+ padding: 15px 12px;
+ background-color: #ffffff00;
+ }
+ }
+ }
+ }
+}
+
+@media screen and (min-width: 641px) and (max-width: 1007px) {
+ .video-tube {
+ background: black;
+ main {
+ max-width: 900px;
+ margin-top: 10px;
+ padding: 0px 10px;
+ flex-direction: column;
+ }
+ &__content {
+ flex: 8;
+ margin: 0px;
+ &--display {
+ padding: 0px;
+ video {
+ width: 100%;
+ margin-bottom: 10px;
+ }
+ span {
+ font-size: calc(100vw / 40);
+ }
+ h1 {
+ font-size: calc(100vw / 30);
+ }
+ p {
+ font-size: calc(100vw / 40);
+ }
+ }
+ &--comments {
+ header {
+ h2 {
+ font-size: calc(100vw / 40);
+ }
+ }
+ button {
+ font-size: calc(100vw / 50);
+ }
+ }
+ &--addComment {
+ width: 100%;
+ button {
+ font-size: calc(100vw / 45);
+ }
+ textarea {
+ font-size: calc(100vw / 45);
+ &::placeholder {
+ font-size: calc(100vw / 45);
+ }
+ }
+ }
+ }
+ &__sidebar {
+ flex: 4;
+ &--playlist {
+ max-height: 450px;
+ header {
+ padding: 12px 12px;
+ background-color: #2c2c2c;
+ img {
+ transform: translateY(-5px);
+ width: 40px;
+ }
+ h2 {
+ font-size: calc(100vw / 40);
+ }
+ p {
+ font-size: calc(100vw / 55);
+ }
+ }
+ }
+ &--attachments {
+ max-height: 250px;
+ header {
+ padding: 14px 12px;
+ background-color: #2c2c2c;
+ h2 {
+ font-size: calc(100vw / 40);
+ }
+ p {
+ font-size: calc(100vw / 55);
+ }
+ }
+ }
+ &--suggests {
+ header {
+ padding: 14px 12px;
+ background-color: #8bd09746;
+ h2 {
+ font-size: calc(100vw / 40);
+ }
+ span {
+ font-size: calc(100vw / 55);
+ }
+ }
+ &___list {
+ padding: 15px 12px;
+ background-color: #ffffff00;
+ }
+ }
+ }
+ }
+}
+
+@media screen and (max-width: 640px) {
+ .video-tube {
+ background: black;
+ margin-top: 20px;
+ main {
+ max-width: 500px;
+ margin-top: 0px;
+ padding: 0px 10px;
+ flex-direction: column;
+ }
+ &__content {
+ flex: 8;
+ margin: 0px;
+ &--display {
+ padding: 0px;
+ video {
+ width: 100%;
+ margin-bottom: 10px;
+ }
+ span {
+ font-size: calc(100vw / 40);
+ }
+ h1 {
+ font-size: calc(100vw / 30);
+ }
+ p {
+ font-size: calc(100vw / 40);
+ }
+ }
+ &--comments {
+ header {
+ h2 {
+ font-size: calc(100vw / 30);
+ }
+ }
+ button {
+ font-size: calc(100vw / 37);
+ }
+ }
+ &--addComment {
+ width: 100%;
+ button {
+ font-size: calc(100vw / 40);
+ }
+ textarea {
+ font-size: calc(100vw / 35);
+ &::placeholder {
+ font-size: calc(100vw / 35);
+ }
+ }
+ }
+ }
+ &__sidebar {
+ flex: 4;
+ &--playlist {
+ max-height: calc(60vh);
+ header {
+ padding: 8px 12px;
+ background-color: #2c2c2c;
+ img {
+ transform: translateY(-5px);
+ width: 30px;
+ }
+ h2 {
+ font-size: calc(100vw / 30);
+ }
+ p {
+ font-size: calc(100vw / 45);
+ }
+ }
+ }
+ &--attachments {
+ max-height: 200px;
+ header {
+ padding: 14px 12px;
+ background-color: #2c2c2c;
+ h2 {
+ font-size: calc(100vw / 30);
+ }
+ p {
+ font-size: calc(100vw / 45);
+ }
+ }
+ }
+ &--suggests {
+ header {
+ padding: 10px 12px;
+ background-color: #8bd09746;
+ h2 {
+ font-size: calc(100vw / 30);
+ }
+ span {
+ font-size: calc(100vw / 45);
+ }
+ }
+ &___list {
+ padding: 15px 12px;
+ }
+ }
+ }
+ }
+}
diff --git a/src/views/Home/index.js b/src/views/Home/index.js
index f28dbe4..e448af4 100644
--- a/src/views/Home/index.js
+++ b/src/views/Home/index.js
@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from "react";
+import React from "react";
import Navbar from "../../components/Navbar";
import Page1 from "./Page1";
@@ -9,7 +9,6 @@ import Page5 from "./Page5";
import Page6 from "./Page6";
import Page7 from "./Page7";
import Dots from "../../components/Dots";
-import { set } from "lodash";
export default function Home() {
return (
diff --git a/yarn.lock b/yarn.lock
index 075ace6..0d7ea31 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2613,6 +2613,13 @@ axe-core@^4.0.2:
resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.1.2.tgz"
integrity sha512-V+Nq70NxKhYt89ArVcaNL9FDryB3vQOd+BFXZIfO3RP6rwtj+2yqqqdHEkacutglPaZLkJeuXKCjCJDMGPtPqg==
+axios@^0.24.0:
+ version "0.24.0"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6"
+ integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==
+ dependencies:
+ follow-redirects "^1.14.4"
+
axobject-query@^2.2.0:
version "2.2.0"
resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz"
@@ -3376,6 +3383,11 @@ cliui@^6.0.0:
strip-ansi "^6.0.0"
wrap-ansi "^6.2.0"
+clsx@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
+ integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
+
co@^4.6.0:
version "4.6.0"
resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz"
@@ -3624,7 +3636,7 @@ core-js-pure@^3.0.0:
resolved "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.9.0.tgz"
integrity sha512-3pEcmMZC9Cq0D4ZBh3pe2HLtqxpGNJBLXF/kZ2YzK17RbKp94w0HFbdbSx8H8kAlZG5k76hvLrkPm57Uyef+kg==
-core-js@^2.4.0:
+core-js@^2.4.0, core-js@^2.6.10:
version "2.6.12"
resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz"
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
@@ -5202,6 +5214,11 @@ follow-redirects@^1.0.0:
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz"
integrity sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==
+follow-redirects@^1.14.4:
+ version "1.14.5"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381"
+ integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==
+
for-in@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz"
@@ -5621,6 +5638,11 @@ history@^5.1.0:
dependencies:
"@babel/runtime" "^7.7.6"
+hls.js@^1.0.11:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-1.1.1.tgz#d8ff641f764741f13259a2740aa33336810a10a5"
+ integrity sha512-2VEVzO/gr5LOD6K/DEmBkKEary6hr4YZ/SLb0PV81jOAM/Tl9DviL0sFMoUHDq05/j4OZxIj691Zo0p40u3Gtw==
+
hmac-drbg@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz"
@@ -6844,6 +6866,17 @@ jest@26.6.0:
import-local "^3.0.2"
jest-cli "^26.6.0"
+jol-player@^2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/jol-player/-/jol-player-2.5.0.tgz#a1cc95746066e759d036a7a64a5690ca36f48430"
+ integrity sha512-zAGERLbo9i3e+gLv+CC7Viv0HU851PhE94F3c8umqT1rUXUty6Gx+z8GDUFt3VtjGsHWx4BbBTnLogSmQt97vQ==
+ dependencies:
+ core-js "^2.6.10"
+ hls.js "^1.0.11"
+ react "^17.0.2"
+ react-dom "^17.0.2"
+ screenfull "^5.0.0"
+
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
@@ -9477,6 +9510,13 @@ react-scripts@4.0.3:
optionalDependencies:
fsevents "^2.1.3"
+react-toastify@^8.1.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-8.1.0.tgz#acaca4e8c4415c8474562dd84a14e6f390ed7f17"
+ integrity sha512-M+Q3rTmEw/53Csr7NsV/YnldJe4c7uERcY7Tma9mvLU98QT2VhIkKwjBzzxZkJRk/oBKyUAtkyMjMgO00hx6gQ==
+ dependencies:
+ clsx "^1.1.1"
+
react@^17.0.2:
version "17.0.2"
resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz"
@@ -10065,6 +10105,11 @@ schema-utils@^3.0.0:
ajv "^6.12.5"
ajv-keywords "^3.5.2"
+screenfull@^5.0.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.2.0.tgz#6533d524d30621fc1283b9692146f3f13a93d1ba"
+ integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==
+
select-hose@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz"