parent
eaef7ac8b8
commit
5ee952357e
47 changed files with 2833 additions and 16 deletions
@ -0,0 +1,35 @@ |
||||
import JoLPlayer from "jol-player"; |
||||
|
||||
const Video = ({ fileIds, posterId }) => { |
||||
return ( |
||||
<div style={{ direction: "ltr", textAlign: "left", marginBottom: 10 }}> |
||||
<JoLPlayer |
||||
option={{ |
||||
videoSrc: `https://dnvn.ir/api/v1/file/${fileIds}`, |
||||
width: "100%", |
||||
height: window.innerWidth > 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, |
||||
}} |
||||
/> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default Video; |
@ -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', |
||||
}; |
@ -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; |
@ -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; |
@ -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; |
@ -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; |
@ -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; |
@ -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"; |
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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; |
@ -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; |
@ -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; |
@ -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; |
@ -0,0 +1,9 @@ |
||||
import proxy from "../proxy"; |
||||
const userProduct = { |
||||
addVOD: |
||||
(data = {}) => |
||||
async (dispatch) => |
||||
await proxy.post("userProduct/addVOD", data, { dispatch }), |
||||
}; |
||||
|
||||
export default userProduct; |
@ -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'; |
||||
|
@ -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; |
@ -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; |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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"; |
||||
|
||||
|
||||
|
@ -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; |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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; |
||||
|
@ -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; |
@ -0,0 +1,18 @@ |
||||
import React from "react"; |
||||
// import Avatar from "@mui/material/Avatar";
|
||||
import user3 from "../../../assets/images/user3.png"; |
||||
|
||||
export default function AddComment(props) { |
||||
const { theme } = props; |
||||
return ( |
||||
<> |
||||
{/* <Avatar style={{ width: 60, height: 60, marginLeft: 10 }} /> */} |
||||
<div className="d-flex flex-column" style={{width : '100%'}}> |
||||
<textarea rows={5} placeholder="نظر خود را در این قسمت بنویسید " /> |
||||
<div className="d-flex justify-content-end"> |
||||
<button className="submit submit-small mt-2">ارسال نظر</button> |
||||
</div> |
||||
</div> |
||||
</> |
||||
); |
||||
} |
@ -0,0 +1,13 @@ |
||||
import React from 'react'; |
||||
|
||||
export default function Attachments({file,num}) { |
||||
return ( |
||||
<div className="download-attachments d-flex justify-content-between align-items-center"> |
||||
<div className="d-flex"> |
||||
<span>{num}</span> |
||||
<h4>{file.name}</h4> |
||||
</div> |
||||
<a href={file.file} download>دریافت</a> |
||||
</div> |
||||
) |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,20 @@ |
||||
import React from 'react'; |
||||
import { Link } from 'react-router-dom'; |
||||
|
||||
export default function Book({ data }) { |
||||
const desc = { |
||||
"ریاضی": 'ریاضی از ریاضت میاد ولی دانوین آسون و لذت بخشش کرده', |
||||
'علوم': "علوم تجربی تو دانوین واقعا تجربی و محسوس میشه", |
||||
'زیست شناسی': "زیست را در دانوین باید زیست", |
||||
'شیمی': 'شیمی اینجا می فهمه کیمیا یعنی چی', |
||||
'فیزیک': "با دانوین فیزیکو با یه لنز جدید ببنید" |
||||
} |
||||
return ( |
||||
<Link to={'/courses/' + data.id} className="video-tube-suggest d-flex flex-column"> |
||||
<img src={`https://dnvn.ir/api/v1/file/${data.fileIds}`} alt="" /> |
||||
<h4>{data.name}</h4> |
||||
<p>{desc[data.name] || ""}</p> |
||||
</Link> |
||||
) |
||||
} |
||||
|
@ -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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,20 @@ |
||||
import React from "react"; |
||||
// import Avatar from "@mui/material/Avatar";
|
||||
|
||||
|
||||
export default function Comment({ comment }) { |
||||
return ( |
||||
<div className="video-tube-comment d-flex"> |
||||
{/* <Avatar src={comment.imageUrl} style={{ width: 65, height: 65, marginLeft: 10 }} /> */} |
||||
<div className="d-flex flex-column"> |
||||
<p> |
||||
<strong>{comment.name}</strong> {comment.text} |
||||
</p> |
||||
<div className="d-flex justify-content-end align-items-center"> |
||||
<button>پاسخ</button> |
||||
<span>{comment.date}</span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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 ( |
||||
<> |
||||
{ |
||||
<div |
||||
className={_.join( |
||||
[ |
||||
"lesson-playlist d-flex flex-column", |
||||
light ? "lesson-playlist-light" : "lesson-playlist-dark", |
||||
], |
||||
" " |
||||
)} |
||||
> |
||||
{bookId && ( |
||||
<header> |
||||
<h3> |
||||
{ |
||||
realCategories.filter( |
||||
(item) => item.id === category[0].categoryId |
||||
)[0].name |
||||
} |
||||
</h3> |
||||
<span></span> |
||||
</header> |
||||
)} |
||||
|
||||
{bookId ? ( |
||||
category.map((video, i) => ( |
||||
<Link |
||||
to={"/video/" + video.id} |
||||
className={ |
||||
"lesson-playlist__item d-flex align-items-center" + |
||||
" " + |
||||
(video?.id === selectedVideo?.id && |
||||
"lesson-playlist__item--active") |
||||
} |
||||
key={i} |
||||
id={"listItem" + video.id} |
||||
onClick={() => setVideoActive(video)} |
||||
> |
||||
<span className="lesson-playlist__item--count"> |
||||
{Number(i) + 1} |
||||
</span> |
||||
<div className="lesson-playlist__item--video"> |
||||
{/* <video> |
||||
<source |
||||
src={`https://dnvn.ir/api/v1/file/${video.fileIds}`} |
||||
/> |
||||
</video> */} |
||||
<img |
||||
src={`https://dnvn.ir/api/v1/file/${video.posterId}`} |
||||
alt="" |
||||
/> |
||||
<span>22:05</span> |
||||
</div> |
||||
<div className="lesson-playlist__item--text d-flex flex-column"> |
||||
<h4>{video.name}</h4> |
||||
{/* <p>{file.text}</p> */} |
||||
</div> |
||||
</Link> |
||||
)) |
||||
) : ( |
||||
<Link |
||||
to={"/video/" + category.id} |
||||
className={ |
||||
"lesson-playlist__item d-flex align-items-center" + |
||||
" " + |
||||
(category?.id === selectedVideo?.id && |
||||
"lesson-playlist__item--active") |
||||
} |
||||
onClick={() => setVideoActive(category)} |
||||
id={"listItem" + category.id} |
||||
> |
||||
<span className="lesson-playlist__item--count"></span> |
||||
<div className="lesson-playlist__item--video"> |
||||
{/* <video> |
||||
<source |
||||
src={`https://dnvn.ir/api/v1/file/${video.fileIds}`} |
||||
/> |
||||
</video> */} |
||||
<img |
||||
src={`https://dnvn.ir/api/v1/file/${category.posterId}`} |
||||
alt="" |
||||
/> |
||||
<span>22:05</span> |
||||
</div> |
||||
<div className="lesson-playlist__item--text d-flex flex-column"> |
||||
<h4>{category.name}</h4> |
||||
{/* <p>{file.text}</p> */} |
||||
</div> |
||||
</Link> |
||||
)} |
||||
</div> |
||||
} |
||||
</> |
||||
); |
||||
} |
||||
|
||||
export default connect( |
||||
(state) => ({ |
||||
selectedVideo: state.publicApi.selectedVideo, |
||||
realCategories: state.publicApi.bookInfo?.categories, |
||||
vods: state.publicApi.bookSection?.vods, |
||||
}), |
||||
{ |
||||
// setVideoActive: publicApi.setVideoActive,
|
||||
} |
||||
)(LessonPlayList); |
@ -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); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue