commit 569ac7ccaddf217cbf1dcdf1eed40ac5de292f45 Author: HOANGLAOTA Date: Fri Jul 12 16:24:27 2024 +0700 fist commit diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..5c445b1 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,5 @@ +build +registerServiceWorker.js +reportWebVitals.js +src/utils/timeline.js +src \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..982c1cb --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +.eslintcache + +/src/_constants/configs.js +/src/_constants/config.js +/package-lock.json +/docker-compose.yml +/yarn.lock \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..36f8df5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM node:14 + +# Set working directory +WORKDIR /var/www + +# get latest nodejs +RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - +RUN apt-get install -y nodejs + +# Install Yarn +#RUN npm install --global yarn + +#npm install +#RUN bash -c "cd /var/www/src; npm install" diff --git a/README.md b/README.md new file mode 100644 index 0000000..7fae147 --- /dev/null +++ b/README.md @@ -0,0 +1,82 @@ +# Build code +## required +`nodejs version 16.x` + +## Build + +- Step 0: run `npm install -g npm@latest` +- Step 1: run `npm install` +- Step 2: create config.js file `cp src/_constants/configs.example.js src/_constants/configs.js` +- Step 3: run `npm run build` to build code +- Step 4: copy `build` directory to server + +# Getting Started with Create React App + +This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). + +## Available Scripts + +In the project directory, you can run: + +### `yarn start` + +Runs the app in the development mode.\ +Open [http://localhost:1480](http://localhost:1480) to view it in the browser. + +The page will reload if you make edits.\ +You will also see any lint errors in the console. + +### `yarn test` + +Launches the test runner in the interactive watch mode.\ +See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. + +### `yarn build` + +Builds the app for production to the `build` folder.\ +It correctly bundles React in production mode and optimizes the build for the best performance. + +The build is minified and the filenames include the hashes.\ +Your app is ready to be deployed! + +See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. + +### `yarn eject` + +**Note: this is a one-way operation. Once you `eject`, you can’t go back!** + +If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. + +Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. + +You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. + +## Learn More + +You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). + +To learn React, check out the [React documentation](https://reactjs.org/). + +### Code Splitting + +This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) + +### Analyzing the Bundle Size + +This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) + +### Making a Progressive Web App + +This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) + +### Advanced Configuration + +This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) + +### Deployment + +This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) + +### `yarn build` fails to minify + +This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) diff --git a/nginx/conf.d/vhost.conf b/nginx/conf.d/vhost.conf new file mode 100644 index 0000000..06cedb1 --- /dev/null +++ b/nginx/conf.d/vhost.conf @@ -0,0 +1,15 @@ +server { + listen 80; + server_name se_dev.sundayenglish.com; + index index.html; + error_log /var/log/nginx/error.log; + access_log /var/log/nginx/access.log; + root /var/www/build; + + location / { + try_files $uri $uri/ /index.html$is_args$args; + gzip_static on; + } + + client_max_body_size 128m; +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..306cc7a --- /dev/null +++ b/package.json @@ -0,0 +1,75 @@ +{ + "name": "sunday-english", + "version": "0.1.0", + "private": true, + "dependencies": { + "@material-ui/core": "3.9.2", + "@material-ui/icons": "3.0.2", + "@testing-library/jest-dom": "^5.11.4", + "@testing-library/react": "^11.1.0", + "@testing-library/user-event": "^12.1.10", + "axios": "^0.21.1", + "chart.js": "^2.9.4", + "chartjs-plugin-datalabels": "1.0.0", + "classnames": "^2.3.1", + "date-fns": "^2.22.1", + "dayjs": "^1.10.4", + "history": "^4.10.1", + "html-react-parser": "^1.2.4", + "jquery": "^3.6.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "moment-duration-format": "2.2.2", + "node-sass": "9.0.0", + "qs": "^6.9.6", + "query-string": "^7.1.1", + "react": "^17.0.1", + "react-apple-login": "^1.1.3", + "react-chartjs-2": "^2.11.1", + "react-datepicker": "^4.1.1", + "react-dom": "^17.0.1", + "react-facebook-login": "^4.1.1", + "react-google-login": "^5.2.2", + "react-js-pagination": "^3.0.3", + "react-lazyload": "^3.2.0", + "react-markdown": "^8.0.5", + "react-redux": "^7.2.2", + "react-router-dom": "^5.2.0", + "react-router-hash-link": "^2.4.3", + "react-scripts": "4.0.3", + "react-slick": "^0.28.1", + "react-social-login": "^3.4.12", + "react-uikit3": "^0.14.0", + "redux": "^4.0.5", + "redux-persist": "^6.0.0", + "redux-thunk": "^2.3.0", + "sass": "^1.32.8", + "styled-components": "^5.3.3", + "text-selection-react": "^1.1.8", + "web-vitals": "^1.0.1" + }, + "scripts": { + "start": "react-scripts --max_old_space_size=4096 start", + "build": "react-scripts --max_old_space_size=4096 build", + "test": "react-scripts test", + "eject": "react-scripts eject", + "lint": "eslint src" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "devDependencies": { + "css-loader": "^5.1.1", + "prettier": "^2.2.1", + "style-loader": "^2.0.0" + } +} diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..8d23de1 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,6 @@ +RewriteEngine On +RewriteBase / +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME} !-l +RewriteRule ^.*$ / [L,QSA] \ No newline at end of file diff --git a/public/assets/css/all.css b/public/assets/css/all.css new file mode 100644 index 0000000..203eed6 --- /dev/null +++ b/public/assets/css/all.css @@ -0,0 +1,11221 @@ +/*IMPORT FONT*/ + +@font-face { + font-family: "iCiel-Alina"; + src: url(../fonts/iCiel-Alina.otf); +} + +@font-face { + font-family: "Myriadpro-Regular"; + src: url(../fonts/MYRIADPRO-REGULAR.woff); +} + +@font-face { + font-family: "Myriadpro-Bold"; + src: url(../fonts/MYRIADPRO-BOLD.woff); +} + +@font-face { + font-family: "Myriadpro-SemiBold"; + src: url(../fonts/MYRIADPRO-SEMIBOLD.woff); +} + +@font-face { + font-family: "Myriadpro-Light"; + src: url(../fonts/MYRIADPRO-LIGHT_0.OTF); +} + +@font-face { + font-family: "Myriadpro-Italic"; + src: url(../fonts/MyriadProCondensedItalic.ttf); +} + +@font-face { + font-family: "MyriadPro-Bold"; + src: url(../fonts/myriad-pro/MYRIADPRO-BOLD.OTF); +} + +@font-face { + font-family: "MyriadPro-SemiBold"; + src: url(../fonts/myriad-pro/MYRIADPRO-SEMIBOLD.OTF); +} + +@font-face { + font-family: "MyriadPro"; + src: url(../fonts/myriad-pro/MYRIADPRO-REGULAR.OTF); +} + +/* AvertaStd */ +@font-face { + font-family: "AvertaStdCY-Black"; + src: url(../fonts/AvertaStdCY-Black_1.otf); +} +@font-face { + font-family: "AvertaStdCY-ExtraBold"; + src: url(../fonts/AvertaStdCY-Extrabold_1.otf); +} +@font-face { + font-family: "AvertaStdCY-ExtraBoldItalic"; + src: url(../fonts/AvertaStdCY-ExtraboldItalic_1.otf); +} +@font-face { + font-family: "AvertaStdCY-Bold"; + src: url(../fonts/AvertaStdCY-Bold_1.otf); +} + +@font-face { + font-family: "AvertaStdCY-SemiBold"; + src: url(../fonts/AvertaStdCY-Semibold_1.otf); +} + +@font-face { + font-family: "AvertaStdCY"; + src: url(../fonts/AvertaStdCY-Regular_3.otf); +} +@font-face { + font-family: "AvertaStdCY-Italic"; + src: url(../fonts/AvertaStdCY-RegularItalic_1.otf); +} + + +@font-face { + font-family: 'Barlow-Bold'; + src: url(../fonts//Barlow-Bold.ttf); +} + +/*END IMPORT FONT*/ +/*RESET CSS*/ +html, +body, +div, +span, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +abbr, +address, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +samp, +small, +strong, +sub, +sup, +var, +b, +i, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; + vertical-align: baseline; + background: transparent; + font-family: "Myriadpro-Regular"; + font-size: 16px; + color: #404041; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; +} +html, +body { + /* height: 100%; */ + width: 100%; +} + +html { + scroll-behavior: smooth; +} + +html:has(.modal_filter_mocktest), +html:has(.modal_not_scroll), +body:has(.modal_filter_mocktest), +body:has(.modal_not_scroll) { + overflow: hidden !important; + height: 100%; +} + +article, +aside, +details, +figcaption, +figure, +footer, +headLr, +hgroup, +menu, +nav, +section { + display: block; +} + +nav ul { + list-style: none; + -webkit-padding-start: 0; + -moz-padding-start: 0; + padding-inline-start: 0; +} + +blockquote, +q { + quotes: none; +} + +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ""; + content: none; +} + +ul { + list-style: none; +} + +input { + font-family: "Myriadpro-Regular"; +} + +a { + margin: 0; + padding: 0; + font-size: 100%; + vertical-align: baseline; + background: transparent; + text-decoration: none; + cursor: pointer; + color: #4e4e4e; +} + +ins { + background-color: #ff9; + color: #000; + text-decoration: none; +} + +mark { + background-color: #ff9; + color: #000; + font-style: italic; + font-weight: bold; +} + +del { + text-decoration: line-through; +} + +abbr[title], +dfn[title] { + border-bottom: 1px dotted; + cursor: help; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +/* Change CSS UI modal select as div option */ + +.home_curriculum .select-styled { + z-index: 1002 !important; +} + +.home_curriculum .select-options { + top: 14px !important; +} + +input, +select { + vertical-align: middle; +} + +button { + outline: none; + cursor: pointer; +} + +a:hover { + text-decoration: none; +} + +.__bg_layout_parent_and_student { + height: 100%; + width: 100%; + object-fit: contain; + background: #fff; +} + +body > iframe[style*="2147483647"] { + display: none; +} + +/*END RESET CSS*/ +/*GENERAL CSS*/ +.flex, +.flex-m { + display: flex; + justify-content: space-between; + flex-direction: row; +} + +.width-100-percent { + width: 100% !important; +} + +.__icon_close_filter { + height: 18px; +} + +.btn-custom-width { + width: 100% !important; + margin: 0px 10px; + padding: 0px 25px !important; +} + +.btn-add-class-custom { + padding: 0px 70px !important; +} + +.select-avatar-class-custom { + height: 68px; + display: flex; + align-items: center; + padding: 0px 10px !important; +} + +.select-avatar-class-custom img { + height: 53px; +} + +.select-avatar-class-custom p { + margin-left: 10px !important; +} + +.flex-1 { + flex: 1; +} + +.clear { + clear: both; +} + +.text-center { + text-align: center; +} + +.text-right { + text-align: right !important; +} + +.text-trans { + text-transform: uppercase; +} + +.disable-mobile { + display: block; +} + +.enable-mobile { + display: none; +} + +.rel { + position: relative; +} + +.sunE-container { + width: 100%; + height: auto; + max-width: 1200px; + margin: 0 auto; + padding: 0; +} + +.form-sunE-button .btn-check-custom { + padding: 0px 50px; + /* margin-top: 60px; */ +} + +.bg-main { + background: #f3ffff; +} + +.min-hei-100 { + min-height: 100vh; +} + +.bold { + font-family: "Myriadpro-Bold"; +} + +a:hover { + color: #00b9b7; +} + +/*END GENERAL CSS*/ +/*SIDEBAR MENU*/ +.sunE-logo { + cursor: pointer; +} + +.sunE-sidebar { + display: flex; + height: 100vh; + -webkit-box-flex: 0; + background-color: rgba(172, 241, 228, 0.66); + flex: 0 0 auto; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + flex-direction: column; + -webkit-transition: margin-left 250ms ease-out, + -webkit-transform 250ms ease-out; + transition: margin-left 250ms ease-out, -webkit-transform 250ms ease-out; + transition: margin-left 250ms ease-out, transform 250ms ease-out; + transition: margin-left 250ms ease-out, transform 250ms ease-out, + -webkit-transform 250ms ease-out; + width: 292px; +} + +.calendar .day-calendar-custom { + height: 40px; + padding: 0px 12px; + margin-bottom: 5px; + margin-top: 12px; +} + +.day-container .day-box { + flex-grow: 0; + flex-shrink: 0; + flex-basis: calc(100% / 7 - 0px); + display: flex; + justify-content: center; + align-items: center; + /* width: 100%; */ +} + +.day-container .day-box .day-cell { + min-width: 40px; + min-height: 40px; + margin: 5px 0px; +} + +.sunE-sidebar-header svg { + margin: 12px 8px 0 0; + cursor: pointer; +} + +.list-menu-i { + margin-top: 20px; + padding: 0 20px; +} + +.list-menu-i-logout { + padding-bottom: 3vh; +} + +.list-menu-i .menu-img { + width: 68px; + max-height: 36px; +} + +.list-menu-i-logout .menu-img img { + width: 37px; +} + +.list-menu-i .menu-img.active .ico_default { + display: none; +} + +.list-menu-i .menu-img .ico_active { + display: none; +} + +.list-menu-i .menu-img.active .ico_active { + display: block; +} + +.list-menu-i a.menu-item { + font-size: 16px; + color: #404041; + line-height: 34px; + align-items: center; + padding: 12px 0 12px 40px; + text-decoration: none; + margin: 8px 0; +} + +.list-menu-i a.menu-item.active { + background: #fff; + border-radius: 30px; +} + +.list-menu-i a.menu-item span { + font-size: 16px; + color: #404041; +} + +.list-menu-i a.menu-item:hover { + text-decoration: none; + background: #fff; + border-radius: 30px; +} + +.badge-student span { + text-transform: uppercase; + line-height: 30px !important; + color: #fc9d24 !important; +} + +.list-menu-i .active span { + font-weight: bolder; + font-size: 17px !important; +} + +.empty-plan-custom { + display: flex; + flex-direction: column; + align-items: center; + margin-top: 30px; +} + +.hide-date-custom { + display: none !important; +} + +.empty-plan-custom img { + width: 316px; + object-fit: cover; +} + +.empty-plan-custom span { + color: #00a79d; + font-size: 24px; + font-weight: bold; + width: 316px; + text-align: center; + text-transform: uppercase; +} + +.sunE-right-container { + width: 100%; + height: 100vh; + overflow: auto; + padding: 30px 20px 20px; + position: relative; +} + +.sunE-main-title { + margin: 0 0 20px; +} + +.sunE-main-title .line-h { + display: block; + width: 4px; + height: 40px; + background: #00bbb5; + border-radius: 2px; + border: none; +} + +.sunE-main-title h1 { + font-size: 32px; + font-family: "Myriadpro-SemiBold"; + color: #00bbb5; + line-height: 40px; + padding-left: 8px; +} + +.list-menu-custom { + width: 300px; +} + +.btn-gr { + margin: 0 0 10px; + background: #b7f3e5; + border-radius: 15px; + height: 60px; + cursor: pointer; + overflow: hidden; +} + +.btn-gr.active { + background-image: linear-gradient(to right, #00e1a0, #00b9b7); +} + +.btn-gr .ico_active { + display: none; +} + +.btn-gr.active .ico_active { + display: block; + margin: 0 auto; +} + +.btn-gr.active .ico_default { + display: none; +} + +.btn-gr-img { + width: 100px; + text-align: center; + padding: 13px 0; +} + +.btn-gr-text p { + font-size: 18px; + font-family: "Myriadpro-Bold"; + color: #00a79d; + line-height: 60px; +} + +.btn-gr.active .btn-gr-text p { + color: #fff; +} + +.sunE-content-box { + padding: 0 0 0 30px; +} + +.sunE-content-box.pad-0 { + padding: 0; +} + +.box-shadow { + box-shadow: 1px 2px 4px 0 rgba(21, 27, 38, 0.4); +} + +.box-shadow-2 { + box-shadow: 1px 2px 6px 0 rgb(21 27 38 / 35%); +} + +.box-white-content { + background: #fff; + border-radius: 15px; + border: none; + margin: 0 0 15px; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; +} + +.title-no-bg { + color: #8f9a96; + text-align: center; + padding: 15px 0; + border-top-left-radius: 15px; + border-top-right-radius: 15px; + border: none; + font-size: 22px; + font-family: "Myriadpro-Bold"; + margin: 0 0 15px; +} + +.title-bg { + color: #fff; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); + text-align: center; + padding: 15px 0; + border-top-left-radius: 15px; + border-top-right-radius: 15px; + border: none; + font-size: 22px; + font-family: "Myriadpro-Bold"; + margin: 0 0 15px; +} + +.text-light { + font-family: "Myriadpro-Light"; +} + +.box-white-content p { + font-size: 16px; + text-align: center; + margin: 0; + padding: 0 0 15px; +} + +.het-han { + color: #8f9a96; + text-align: center; + padding: 5px 15px; + border: 1px solid #8f9a96; + font-size: 22px; + font-family: "Myriadpro-Bold"; + margin: 0 0 15px; +} + +.box-white-content { + padding: 0 0 15px; +} + +.text-title-blue { + color: #00a69c; + font-family: "Myriadpro-Bold"; + font-size: 18px; +} + +.btn-send { + margin-top: 40px; +} + +.input-nm { + background: #eee; + color: #000; + height: 40px; + line-height: 40px; + outline: none; + border: none; + border-radius: 20px; + padding-left: 20px; + width: 100%; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + margin: 0 0 15px; + font-size: 16px; + color: #000; +} + +.input-nm::placeholder { + /* Chrome, Firefox, Opera, Safari 10.1+ */ + color: #000; + opacity: 1; + /* Firefox */ +} + +.input-nm:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + color: #000; +} + +.input-nm::-ms-input-placeholder { + /* Microsoft Edge */ + color: #000; +} + +.pad-box { + padding: 30px 20px 0; +} + +.box-buy-history .title-bg { + padding: 5px 0; +} + +.box-buy-history .price { + background: #e6e7e8; + color: #1b75bb; + font-size: 32px; + height: 60px; + line-height: 60px; + border: none; + border-radius: 16px; + padding: 0; + text-align: center; +} + +.box-buy-history p { + padding: 0 0 8px; + text-align: left; +} + +.box-buy-history-price { + padding: 0 20px; +} + +.box-buy-history-time { + padding-left: 20px; +} + +.small { + font-size: 18px; +} + +.list-buy-history { + max-height: calc(100vh - 120px); + overflow: auto; + padding: 0 15px 10px 30px; +} + +.list-buy-history::-webkit-scrollbar { + width: 8px; +} + +/* Track */ +.list-buy-history::-webkit-scrollbar-track { + background: #bbcbc3; + border-radius: 4px; +} + +/* Handle */ +.list-buy-history::-webkit-scrollbar-thumb { + background: #00bbb6; + border-radius: 4px; +} + +.bg-main-site { + background: #effff7; +} + +.slider-custom { + max-width: 440px; + margin: 0 auto; +} + +.slider-custom .uk-position-small { + margin: 0; +} + +.slider-custom .uk-slidenav-next svg, +.slider-custom .uk-slidenav-previous svg { + display: none !important; +} + +.slider-custom .uk-slidenav { + padding: 86px 5px; + border-radius: 8px; + background: #f5fefa; + box-shadow: 0 1px 3px 0 rgba(21, 27, 38, 0.15); +} + +.slider-item-content { + margin: 10px 30px; + padding: 5px 0 0; +} + +.slider-custom .uk-position-small[class*="uk-position-center-left"], +.slider-custom .uk-position-small[class*="uk-position-center-right"] { + transform: translateY(-50%) translateY(0px); +} + +.slider-custom .uk-dotnav > * > * { + width: 14px; + height: 14px; + border: 1px solid #00bbb6; +} + +.slider-custom .uk-dotnav > .uk-active > * { + background-color: #00bbb6; + border-color: transparent; +} + +.slider-custom .uk-dotnav > * > :focus, +.slider-custom .uk-dotnav > * > :hover { + background-color: #00bbb6; +} + +.slider-custom .slick-next:before, +.slider-custom [dir="rtl"] .slick-prev:before, +.slider-custom .slick-prev:before { + display: none; +} + +.slider-custom .slick-arrow { + background: #fff; + padding: 86px 5px; + position: absolute; + border-radius: 10px; + border: none; + z-index: 9; + text-align: center; +} + +.slider-custom .slick-next, +.slider-custom .slick-prev { + width: 31px; + height: auto; +} + +.slider-custom .slick-arrow.slick-next { + left: calc(100% - 17px); +} + +.slider-custom .slick-arrow.slick-prev { + left: -16px; +} + +.slider-custom .slick-next:before, +.slider-custom .slick-prev:before { + font-size: 20px; + line-height: 1; + opacity: 0.75; + color: #fff; +} + +.slider-custom .slick-dots li button:before { + font-size: 16px; + color: #00a79d; +} + +.item-top-title { + margin: 5px 10px; + background: #d9ecf2; + padding: 5px 0; + border-radius: 10px; +} + +.item-top-title p { + text-align: center; + font-size: 20px; + padding: 0; + color: #262261; +} + +.item-price { + margin: 5px 0; + background: #f5f5f5; +} + +.item-price p { + text-align: center; + font-size: 28px; + padding: 0; + color: #d34e42; +} + +.item-time { + padding: 0 30px; + margin: 20px 0 20px; +} + +.item-time p, +.item-time span { + font-size: 16px; + padding: 0; + color: #000; + text-align: left; +} + +.item-time .text-red { + color: #d34e42; +} + +.btn-show-hide { + width: 100%; + padding-top: 30px; + height: 1px; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + overflow: hidden; +} + +.btn-desc { + background: #bbf7e4; + width: 60px; + height: 60px; + border-radius: 30px; + text-align: center; + display: block; + position: absolute; + left: 50%; + transform: translate(-50%, -50%); + cursor: pointer; +} + +.box-white-content .btn-desc img { + margin-top: 8px; +} + +.info .btn-desc img { + transform: rotate(180deg); +} + +.hide { + display: none !important; +} + +.list-info { + padding: 0 20px; + margin: 20px 0; +} + +.item-list { + margin: 0 0 10px; +} + +.info-list-title { + color: #000; + font-family: "Myriadpro-Bold"; + font-size: 18px; + margin: 0; + padding: 0 0 20px; +} + +.item-list-img { + margin-right: 15px; +} + +.item-list p { + color: #404041; + text-align: left; +} + +.bg-yellow { + background: #f1f3b9; +} + +.chosen-class { + margin: 0 auto; + text-align: center; +} + +.chosen-class select { + width: 380px; + height: 40px; + border-radius: 20px; + border: none; + outline: none; + text-align-last: center; + box-shadow: 0 1px 8px 0 rgba(21, 27, 38, 0.15); + font-size: 16px; + font-family: "Myriadpro-Bold"; + padding-right: 40px; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + /* Remove default arrow */ + background: url("./../images/icon/ico_dropdown.png") 96% / 20px no-repeat #fff; + /* Add custom arrow */ +} + +.chosen-class select::-ms-expand { + display: none; + /* remove default arrow on ie10 and ie11 */ +} + +.chosen-class.err select { + border: 2px solid #e22028; +} + +.chosen-class select option { + text-align: center; +} + +.__status_excercise_home_std { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; + align-items: center; + justify-content: center; + background: #ffffff6b; +} + +/*END SIDEBAR MENU*/ +/*GIAO VIEN*/ + +.bg-main-img { + background-image: url("./../images/bg_gv.png"); + background-repeat: no-repeat; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; + margin-top: -36px !important; + padding-top: 36px; +} + +.bg-main-img-teacher { + background-image: url("./../images/bg_gv.png"); + background-repeat: no-repeat; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; +} + +.bg-main-img-add-student { + background-image: url("./../images/bg_add_student.png"); + background-repeat: no-repeat; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; +} + +.bg-main-img-link-parent { + background-image: url("./../images/img-bg-parent.png"); + background-repeat: no-repeat; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; +} + +.bg-main-img-detail-unit { + background-image: url("./../images/bg-detail-unit.jpg"); + background-repeat: no-repeat; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; +} + +.bg-header-entrance-score { + background-image: url('./../images/entrance_header.png'); + background-repeat: no-repeat; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; + background-position: bottom; +} + +.bg-body-entrance-score { + background-image: url('./../images/entrance_body.png'); + background-repeat: no-repeat; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; + background-position: bottom; +} + +.bg-main-color { + background-image: linear-gradient(to top, #fafffd, #e1fef0); +} + +.sunE-container-box { + padding: 50px 20px 20px; +} + +.sunE-calendar { + padding-right: 10px; +} + +.calendar { + width: 100%; + background: #fff; + border-radius: 20px; +} + +.sunE-plan { + padding-left: 10px; +} + +.no-plan h2 { + font-family: "Myriadpro-SemiBold"; + font-size: 24px; + padding: 0; + margin: 0; + color: #00a79d; +} + +.no-plan .form-sunE-button { + margin: 10px 0 0; +} + +.sunE-box-slider { + margin: 20px 0; +} + +.slider-custom-2 { + max-width: 860px; + margin: 0 auto; +} + +.slider-custom-2 .uk-position-small { + margin: 0; +} + +.slider-custom-2 .uk-slidenav-next svg, +.slider-custom-2 .uk-slidenav-previous svg { + display: none !important; +} + +.slider-custom-2 .uk-slidenav { + padding: 14px 16px; + border-radius: 12px; + background-image: linear-gradient(to bottom, #00e1a0, #00b9b7); + box-shadow: 0 1px 3px 0 rgba(21, 27, 38, 0.15); +} + +.slider-item-content { + margin: 10px 30px; + padding: 5px 0 0; +} + +.slider-item-content img { + margin: auto; +} + +.slider-custom-2 .uk-position-center-left-out { + right: calc(100% - 30px); +} + +.slider-custom-2 .uk-position-center-right-out { + left: calc(100% - 30px); +} + +.slider-custom-2 .uk-dotnav > * > * { + width: 14px; + height: 14px; + border: 1px solid #00bbb6; +} + +.slider-custom-2 .uk-dotnav > .uk-active > * { + background-color: #00bbb6; + border-color: transparent; +} + +.slider-custom-2 .uk-dotnav > * > :focus, +.slider-custom-2 .uk-dotnav > * > :hover { + background-color: #00bbb6; +} + +.slider-custom-2 .slick-next:before, +.slider-custom-2 [dir="rtl"] .slick-prev:before, +.slider-custom-2 .slick-prev:before { + display: none; +} + +.slider-custom-2 .slick-arrow { + background: #00bbb6; + padding: 14px 16px; + position: absolute; + border-radius: 10px; + border: none; + z-index: 9; + text-align: center; +} + +.slider-custom-2 .slick-next, +.slider-custom-2 .slick-prev { + width: 48px; + height: auto; +} + +.slider-custom-2 .slick-arrow.slick-next { + left: calc(100% - 35px); +} + +/* Slider for student homepage */ +.slider-custom-student .slick-arrow.slick-next { + left: calc(100% - 75px); +} + +.slider-custom-2 .slick-arrow.slick-prev { + left: -16px; +} + +/* Slider for student homepage */ +.slider-custom-student .slick-arrow.slick-prev { + left: 28px; +} + +.slider-custom-2 .slick-next:before, +.slider-custom-2 .slick-prev:before { + font-size: 20px; + line-height: 1; + opacity: 0.75; + color: #fff; +} + +.slick-dots { + bottom: -45px !important; +} + +.slider-custom-student .slick-dots { + position: relative !important; + bottom: 0 !important; + margin: 0.25rem 0 0.65rem; +} + +.slider-custom-2 .slick-dots li button:before { + font-size: 16px; + color: #00a79d; + background-color: #00a79d; + content: ""; + border-radius: 50%; + width: 14px; + height: 14px; +} + +.img-thumb { + margin: 10px; + width: 270px; + height: 240px; + border-radius: 10px; + overflow: hidden; +} + +.img-thumb img { + width: 100%; + height: 100%; + border-radius: 10px; +} + +.slider-item-desc { + padding: 0 10px; + box-sizing: border-box; +} + +.item-top-title-main { + margin: 10px 0; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); + padding: 10px 0; + border-radius: 25px; +} + +.item-top-title-main p { + text-align: center; + font-size: 20px; + padding: 0; + color: #fff; + font-family: "Myriadpro-SemiBold"; +} + +.chart-content { + width: 100%; + padding: 0 10px; +} + +.chart-content canvas { + margin-left: -35px; + margin-top: 35px; +} + +.calendar-text-tb { + font-size: 18px; + font-family: "Myriadpro-Bold"; + color: #00a79d; +} + +.slider-custom-2 .slider-item-content { + margin: 10px; + padding: 0 15px; +} + +.align-item-center { + align-items: center; +} + +.box-no-class .center-horizontal { + padding-top: 80px; +} + +.btn-img { + display: inline-block; +} + +.btn-img img { + position: absolute; + top: 8px; + left: 15px; + width: 24px; +} + +.btn-img .btn-line-blue { + padding-left: 50px; +} + +.plan-item { + background: #fff; + border-radius: 10px; + border: none; + margin: 0 0 10px; + /* border-left: 20px solid #fbb040; */ + overflow: hidden; + height: 80px; +} +.personal.plan-item { + border-left: 20px solid #8dc63f; +} + +.test_evaluation.plan-item { + border-left: 20px solid #c367f4; +} + +.teaching_work.plan-item { + border-left: 20px solid #00aeef; +} + +.professional_activities.plan-item { + border-left: 20px solid #fbb040; +} + +.other.plan-item { + border-left: 20px solid #be1e2d; +} + +.plan-item:last-child { + margin: 0 0 2px; +} + +.plan-item-content { + width: 100%; + padding: 10px 40px 10px 10px; +} + +.check-work { + color: #000; + font-family: "Myriadpro-SemiBold"; + font-size: 18px; + padding: 0 0 0 10px; + margin: 0 !important; + line-height: 20px; + width: 99%; +} + +.width_70_percent { + width: 70% !important; +} + +.plan-item-content p { + font-size: 18px; + padding-left: 10px; +} + +.his { + margin-top: -5px; + width: 111px; +} + +.orange span, +.red span, +.success-text span { + color: #fbb040; + font-size: 14px; + font-family: "Myriadpro-Bold"; + line-height: 30px; + padding-left: 5px; +} + +.red span { + color: #be1e2d; +} + +.success-text span { + color: #84c241; +} + +.btn-plan-item { + position: absolute; + top: 50%; + transform: translateY(-50%); + right: 0; + cursor: pointer; +} + +.sunE-plan-list { + max-height: 356px; + overflow: auto; + padding-right: 12px; +} + +.homepage-teacher .sunE-plan-list-home { + max-height: 24.8rem; +} + +.sunE-plan-list::-webkit-scrollbar { + width: 8px; +} + +/* Track */ +.sunE-plan-list::-webkit-scrollbar-track { + background: #bbcbc3; + border-radius: 4px; +} + +/* Handle */ +.sunE-plan-list::-webkit-scrollbar-thumb { + background: #00bbb6; + border-radius: 4px; +} + +.edit-plan-box { + width: 166px; + background: #b7f2e4; + display: flex; + justify-content: center; + align-items: center; + margin-right: -166px; + transition: margin 0.6s ease; + padding-top: 5px; +} + +.edit-plan-box .flex-m { + width: 166px; +} + +.edit-plan-box .btn p { + font-size: 18px; + line-height: 18px; +} + +.btn { + cursor: pointer; +} + +.plan-item-content .show-edit-box { + display: none; +} + +.edit-show .plan-item-content .hide-edit-box { + display: none; +} + +.edit-show .plan-item-content .show-edit-box { + display: block; +} + +.edit-show .edit-plan-box { + margin-right: 0; + transition: margin 0.6s ease; +} + +.edit-show .plan-item-content { + margin-left: -166px; + transition: margin 0.6s ease; + border-top-right-radius: 10px; + border-bottom-right-radius: 10px; +} + +.btn-sign-out { + position: absolute; + right: 20px; + bottom: 50px; +} + +.setting-content { + text-align: center; +} + +.setting-list { + display: inline-block; + max-width: 480px; + margin: 80px 0 0; +} + +.setting-box { + padding: 20px 20px 0; + display: inline-block; + width: 125px; + height: 125px; + background: #fff; + margin: 30px 30px 0 0; + border-radius: 10px; + border: none; + cursor: pointer; + box-sizing: border-box; + overflow: hidden; +} + +.setting-box img { + margin: auto; +} + +.setting-box p { + line-height: 14px; +} + +.top-8 { + margin-top: 8px; +} + +.top-16 { + margin-top: 16px; +} + +.sunE-no-class p { + font-size: 18px; + padding: 0; + margin: 0; + color: #000; +} + +.sunE-no-class p .bold { + color: #000; + font-size: 18px; +} + +.sunE-class-list { + box-sizing: border-box; +} + +.class-box { + box-sizing: border-box; + padding: 15px; + border-radius: 20px; + background: #fff; + display: inline-block; +} + +.class-box a { + display: block; + text-decoration: none; +} + +.class-box a:hover { + text-decoration: none; +} + +.class-box .class-box-img { + width: 145px; + height: 120px; + overflow: hidden; +} + +.class-box .class-box-img img { + width: 100%; + height: 100%; + border-radius: 10px; +} + +.title-line-blue { + font-size: 20px; + line-height: 24px; + padding: 8px; + text-align: center; + border-radius: 20px; + color: #fff; + font-family: "Myriadpro-SemiBold"; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); +} + +.class-box-desc { + padding: 0 0 0 15px; +} + +.class-box-desc .title-line-blue { + margin: 0 0 15px; +} + +.class-box-desc p, +.class-box-desc span { + font-size: 18px; + margin: 0; + padding: 0; + font-family: "Myriadpro-Regular"; +} + +.class-offline { + color: #be1e2d; + text-transform: uppercase; +} + +.class-online { + color: #00a69c; + text-transform: uppercase; +} + +.sunE-class-content { + padding-top: 40px; +} + +.sunE-class-content .uk-grid > * { + padding-left: 20px; + padding-bottom: 20px; +} + +.sunE-class-content .class-box { + width: 100%; + height: 100%; +} + +.sunE-class-list { + padding-right: 20px; + max-height: calc(100vh - 225px); + padding-bottom: 30px; + overflow: auto; +} + +.sunE-class-list::-webkit-scrollbar { + width: 8px; +} + +/* Track */ +.sunE-class-list::-webkit-scrollbar-track { + background: #bbcbc3; + border-radius: 4px; +} + +/* Handle */ +.sunE-class-list::-webkit-scrollbar-thumb { + background: #00bbb6; + border-radius: 4px; +} + +.img-upload { + width: 100%; + height: 500px; + background: #fff; + border-radius: 20px; + border: none; +} + +.sunE-create-class-img .height-330 { + height: 330px; +} + +.avt-img { + width: 100%; + height: 100%; + border-radius: 20px; + overflow: hidden; +} + +.avt-img img { + width: 100%; + height: 100%; +} + +.avt-img #preview-avatar { + object-fit: cover; +} + +.img-gray { + background: #ccc; +} + +.upload-img { + width: 88px; + height: 55px; + border-radius: 10px; + border: none; +} + +.upload-gr { + background: #b2f1e6; + width: 260px; + padding: 10px; + border-radius: 20px; + border: none; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + cursor: pointer; +} + +.upload-gr p { + font-size: 18px; + margin: 0; + padding: 0; + text-align: center; + line-height: 55px; + font-family: "Myriadpro-Light"; +} + +.bg-line-blue select { + background: linear-gradient(to right, #00e1a0, #00b9b7); + color: #fff; +} + +.sunE-class-info { + padding-left: 30px; +} + +.sunE-class-info select { + width: 100%; +} + +.class-on-off { + margin: 10px 0 40px; +} + +.class-on-off input { + margin: -3px 8px 0 0; + width: 20px; + height: 20px; + outline: none; + /*box-shadow: 0 1px 6px 0 rgba(21, 27, 38, .15);*/ +} + +.class-on-off .err label { + color: #e22028; +} + +.class-on-off label { + font-size: 16px; + font-family: "Myriadpro-Semibold"; + color: #000; +} + +.red { + color: #ff0000; +} + +.sunE-input-group { + margin: 0 0 15px; +} + +.sunE-input-group label { + display: block; + margin: 0; + padding: 0 0 10px; + font-family: "Myriadpro-Semibold"; + font-size: 18px; + color: #000; +} + +.sunE-input-group input { + width: 100%; + height: 44px; + border: 1px solid #fff; + border-radius: 18px; + box-shadow: 0 1px 6px 0 rgba(21, 27, 38, 0.15); + padding: 0 20px; + box-sizing: border-box; + outline: none; + /* font-family: ; */ +} + +.sunE-input-group.err input { + border-color: #e22028; +} + +.class-slect-time { + margin: 30px 0 0; +} + +.class_slect_time_margin { + margin: 20px 0 0 !important; +} + +.select-gr { + display: flex; +} + +.select-gr select { + width: 40px; + height: 50px; + border-radius: 10px; + background: #00a69c; + color: #fff; + outline: none; + border: none; + box-shadow: 0 1px 6px 0 rgba(21, 27, 38, 0.15); + margin: 0 8px 0 0; + text-align-last: center; + font-size: 16px; + font-family: "Myriadpro-Semibold"; +} + +.select-gr select option { + padding: 8px; + text-align: center; + text-align-last: center; + background: #fff; + color: #000; + font-family: "Myriadpro-Regular"; +} + +.select-gr select { + /* for Firefox */ + -moz-appearance: none; + /* for Chrome */ + -webkit-appearance: none; +} + +/* For IE10 */ +.select-gr select::-ms-expand { + display: none; +} + +/* Select time Center */ +.select-time-center input { + text-align: center; +} + +.class-index-box { + box-sizing: border-box; + padding: 15px; + border-radius: 20px; + background: #fff; + display: inline-block; + width: 100%; +} + +.class-index-box .class-index-box-img { + width: 280px; + height: 237px; +} + +.class-index-box .class-index-box-img img { + width: 100%; + height: 100%; +} + +.class-index-box .class-box-desc .class-on { + margin: 0 0 20px; + display: block; +} + +.info-gr { + margin: 0 0 10px; +} + +.info-gr .info-img { + width: 30px; +} + +.info-gr .info-img img { + margin-top: 2px; +} + +.info-gr .info-con { + padding: 0 0 0 15px; +} + +.info-gr .info-con p { + font-size: 16px; + font-family: "Myriadpro-Light"; + line-height: 30px; +} + +.info-gr img { + height: 22px; + cursor: pointer; +} + +.class-select-content { + width: 100%; + margin: auto; + text-align: center; +} + +.class-select-list { + display: inline-block; + max-width: 700px; + margin: 80px 0 0; +} + +.class-select-box { + padding: 20px 0px 0; + display: inline-block; + width: 160px; + height: 160px; + background: #fff; + margin: 0 5px; + border-radius: 10px; + border: none; + cursor: pointer; + box-sizing: border-box; + overflow: hidden; +} + +.class-select-box img { + margin: auto; +} + +.class-select-box .select-img { + height: 90px; +} + +.class-select-box p { + font-size: 16px; + padding: 10px 0 0; + margin: 0; +} + +.bcht-calendar { + text-align: center; + margin: 0 0 40px; +} + +.bcht-calendar input { + width: 500px; + height: 44px; + border: none; + border-radius: 18px; + box-shadow: 0 1px 6px 0 rgba(21, 27, 38, 0.15); + padding: 0 0 0 20px; + box-sizing: border-box; +} + +.student-list-container { + width: 380px; +} + +.custom-list-student { + padding: 20px; + border-radius: 20px; + background: #fff; +} + +.custom-list-student-2 { + padding: 3px; + box-shadow: 1px 2px 4px 0 rgb(21 27 38 / 40%); + border-radius: 20px; + background: #fff; +} + +.list-student { + max-height: calc(100vh - 270px); + overflow: auto; +} + +.list-student::-webkit-scrollbar { + width: 8px; +} + +/* Track */ +.list-student::-webkit-scrollbar-track { + background: #bbcbc3; + border-radius: 4px; +} + +/* Handle */ +.list-student::-webkit-scrollbar-thumb { + background: #00cfab; + border-radius: 4px; +} + +.sunE-title-medium { + font-size: 22px; + margin: 0; + padding: 0 0 20px; +} + +.d-flex { + display: flex; +} + +.align-items-center { + align-items: center; +} + +.item-student { + margin: 0 0 15px; + display: flex; + justify-content: space-between; + align-items: center; + border-radius: 10px; + padding: 10px; +} + +.item-student .stt { + line-height: 70px; + font-size: 16px; + font-family: "Myriadpro-Bold"; + width: 30px; +} + +.item-student .item-student-img { + width: 70px; + height: 70px; + border-radius: 35px; + background: #ccc; + overflow: hidden; +} + +.item-student .item-student-img.bd-orange { + box-sizing: border-box; + border: 2px solid #e7c71d; +} + +.item-student .item-student-img img { + width: 100%; + height: 100%; + object-fit: cover; +} +.item-student-name-container { + max-width: 65%; +} +.item-student-name { + padding: 0 0 0 20px; +} + +.ranks .item-student-name { + max-width: 70%; +} + +.item-student-name p { + line-height: 24px; + font-size: 16px; +} + +.add_student_container { + padding-bottom: 0; + overflow: hidden !important; +} + +.justify-content-end { + justify-content: end; +} + +.justify-content-center { + justify-content: center; +} + +.__btn-cancel, +.__btn-register { + height: 35px !important; + width: 120px !important; +} + +.background-add-student { + height: calc(100vh - 90px); + width: 100%; + object-fit: contain; + background: #fff; +} + +.show_img { + width: 8px; +} + +.calendar .fix-nowap-row-calendar { + min-width: 280px; + /* max-width: 300px; */ + flex-wrap: nowrap; +} + +.min-width-custom-200 { + min-width: 200px; +} + +.add_student { + background-repeat: no-repeat; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; + height: calc(100vh - 100px); + width: 100%; + position: relative; +} + +.add_code_student_custom { + width: 470px; + position: absolute; + left: 50%; + bottom: 0px; + transform: translate(-50%, 0%); +} + +.add_code_student_custom { + width: 470px; + position: absolute; + left: 50%; + top: 548px; + transform: translate(-50%, -50%); +} + +.add_code_student_custom.err input { + border-color: #e22028; +} + +.add_code_student_custom .ico_err { + display: none; + position: absolute; + top: 5px; + right: 15px; +} + +.add_code_student_custom .sunE-input-border-blue-gr.err .ico_err { + display: block; + width: 25px; +} + +.add_code_student_custom .form-sunE-button { + margin: 20px 0 0; +} + +.add_code_student_custom .sunE-title-medium { + padding: 0 0 10px; + margin-bottom: 20px; +} + +.add_code_student_custom p.red { + font-size: 16px; + display: none; +} + +.noti-message-custom { + position: relative; +} + +/* .noti-message-custom .icon-noti-mess{ + height: 35px; +} */ + +.noti-message-custom .count-noti-custom { + position: absolute; + top: 0; + right: 0; + width: 30px; + height: 30px; + border-radius: 50%; + background: #be1e2d; + display: flex; + align-items: center; + justify-content: center; + color: #fff; + padding: 3px; +} + +.add_code_student_custom.err p.red { + display: block; +} + +.empty-err-custom { + height: 3vh; +} + +.add_code_student_custom .error-help { + margin: 0px; + width: 100%; +} + +.bottom-10 { + margin-bottom: 10px; +} + +.bottom-60 { + margin-bottom: 60px; +} + +.bottom-30 { + margin-bottom: 30px; +} + +.upload-gr .upload-img { + height: 53px; +} + +.add_code_student-bottom-60 { + transform: translate(-50%, 0%); + bottom: 30px; + top: auto; +} + +.sunE-input-border-blue-gr { + max-width: 420px; + margin: 0 auto 10px; +} + +.horizontal-center { + display: flex; + align-items: center; +} + +.horizontal-center .ico_input { + top: auto !important; + left: auto !important; + margin-left: 5px; +} + +.input-hide-arrow::-webkit-outer-spin-button, +.input-hide-arrow::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +/* Firefox */ +.input-hide-arrow[type="number"] { + -moz-appearance: textfield; +} + +.sunE-input-border-blue-gr input { + width: 100%; + height: 44px; + border: 2px solid #399098; + border-radius: 22px; + /* text-align: center; */ + padding: 0 50px; + box-sizing: border-box; + outline: none; +} + +.__posistion_custom { + top: 0px !important; + left: 0px !important; + right: 0px !important; + bottom: 0px !important; + margin: auto !important; + transform: none !important; + display: flex; + flex-direction: column; + justify-content: end; + padding-bottom: 30px; +} + +.__posistion_custom .sunE-title-medium { + display: flex; + flex-direction: column; + justify-content: end; +} + +.add_code_student-gr.err input { + border-color: #e22028; +} + +.add_code_student-gr .ico_err { + display: none; + position: absolute; + top: 5px; + right: 15px; +} + +.add_code_student-gr .sunE-input-border-blue-gr.err .ico_err { + display: block; +} + +.add_code_student-gr .form-sunE-button { + margin: 20px 0 0; +} + +.add_code_student-gr .sunE-title-medium { + padding: 0 0 10px; +} + +.add_code_student-gr p.red { + font-size: 16px; + display: none; +} + +.add_code_student-gr.err p.red { + display: block; +} + +.sunE-input-border-blue-gr .ico_input { + position: absolute; + /* top: 5px; */ + left: 7px; +} + +.sunE-no-student .add_code_student-gr { + top: 510px; +} + +.class_student_list .sunE-title-medium { + font-size: 18px; +} + +.class_student_list_box { + padding: 20px; + border-radius: 20px; + border: none; + background: #fff; + height: calc(100vh - 220px); + overflow: auto; +} + +.h-160.class_student_list_box { + height: calc(100vh - 160px); +} + +.btn-remove-student { + padding-top: 20px; + cursor: pointer; +} + +.btn-user-add, +.btn-user-share { + margin-right: 8px; +} + +.btn-user-add img, +.btn-user-share img { + width: 40px; +} + +.sh-num { + width: 20px; + height: 20px; + text-align: center; + line-height: 20px; + font-size: 12px; + color: #fff; + background: #f70000; + position: absolute; + top: -4px; + right: -4px; + border-radius: 10px; + font-family: "Myriadpro-SemiBold"; +} + +.dk_class .select-all { + padding: 10px; + /* margin-right: 30px; */ + padding-right: 39px; +} + +.change_point_checkbox_add_exercise { + padding-right: 45px !important; +} + +.dk_class .select-all label { + font-size: 16px; + font-family: "Myriadpro-SemiBold"; + color: #000; +} + +.dk_class .select-all input { + margin: -3px 0 0 10px; + width: 16px; + height: 16px; +} + +.btn-check-gr { + padding-top: 20px; +} + +.btn-check-gr input { + margin: -3px 10px 0 0; + width: 16px; + height: 16px; +} + +.btn-check-gr .btn-accept { + background: #eb8923; + color: #fff; + width: 115px; + height: 30px; + border-radius: 15px; + outline: none; + border: none; + text-align: center; + margin-right: 5px; +} + +.btn-check-gr .btn-reject { + background: #bcbdbf; + color: #fff; + width: 115px; + height: 30px; + border-radius: 15px; + outline: none; + border: none; + text-align: center; +} + +.btn-accept-reject-select-gr { + margin: 20px 0; +} + +.btn-accept-reject-select-gr .btn-select-custom { + background-image: linear-gradient(to top, #00b9b7, #00e1a0); + color: #fff; + width: 120px; + height: 40px; + border-radius: 20px; + outline: none; + border: none; + text-align: center; + font-size: 16px; + font-family: "Myriadpro-SemiBold"; +} + +.btn-select-custom.btn-reject { + margin-right: 10px; +} + +.btn-accept-reject-select-gr .btn-select-custom.no-accept { + background: #bcbdbf; +} + +.lichngay .list-menu-custom .btn-gr { + height: 50px; +} + +.lichngay .list-menu-custom .btn-gr-text p { + line-height: 50px; + font-size: 18px; +} + +.sunE-main-title .form-sunE-button.btn-create-kh { + margin-right: 10px; +} + +.box-calender { + width: 100%; + margin: 0 0 30px; +} + +.lichngay .list-menu-custom { + width: 340px; +} + +.list-kh-content { + padding: 20px; +} + +.no-kh { + text-align: center; + margin: 60px auto 0; +} + +.no-kh h2 { + font-family: "Myriadpro-Bold"; + font-size: 18px; + color: #00a79d; + text-align: center; +} + +.plan-item-content { + width: 100%; +} + +.lichngay .sunE-plan-list { + max-height: 420px; + padding: 0 20px; +} + +.sunE-box-tkh, +.sunE-box-xkh { + width: 100%; + padding: 30px 30px 0; +} + +.input-gr { + width: 100%; + margin: 0 0 20px; +} + +.laplai { + width: 100%; + margin: 0 0 20px; + padding-left: 15px; +} + +.input-gr label, +.laplai label, +.ct-hs label.ht { + font-family: "Myriadpro-SemiBold"; + font-size: 18px; + color: #000000; + display: block; + padding: 0 0 10px 15px; +} + +.input-gr input, +.input-gr select { + width: 100%; + height: 40px; + outline: none; + border: none; + border-radius: 20px; + padding: 5px 20px; + box-shadow: 0 1px 6px 0 rgba(21, 27, 38, 0.15); + box-sizing: border-box; + font-family: "Myriadpro-Regular"; + font-size: 16px; + background: #fff; +} + +.input-gr textarea { + width: 100%; + height: 100px; + outline: none; + border: none; + border-radius: 20px; + padding: 10px 20px; + box-shadow: 0 1px 6px 0 rgba(21, 27, 38, 0.15); + box-sizing: border-box; + font-family: "Myriadpro-Regular"; + background: #fff; + font-size: 16px; +} + +.input-gr textarea::placeholder, +.input-gr input::placeholder, +.input-gr select::placeholder { + color: #414042 !important; +} + +.input-gr textarea::-ms-input-placeholder, +.input-gr input::-ms-input-placeholder, +.input-gr select::-ms-input-placeholder { + color: #414042 !important; +} + +.input-gr textarea::-webkit-input-placeholder, +.input-gr input::-webkit-input-placeholder, +.input-gr select::-webkit-input-placeholder { + color: #414042 !important; +} + +.message textarea { + resize: none; +} + +.datlichnhac-input-gr { + /* text-align: center; */ +} + +.custom-input::placeholder { + opacity: 0.5; +} + +.datlichnhac-input-gr input.dln-mins { + width: 100px; + height: 40px; + outline: none; + border: none; + border-radius: 20px; + padding: 5px 20px; + box-shadow: 0 1px 6px 0 rgba(21, 27, 38, 0.15); + box-sizing: border-box; + text-align: center; + font-size: 16px; +} + +.datlichnhac-input-gr input.dln-check { + width: 20px; + height: 20px; + border-radius: 0; + padding: 0; + box-shadow: none; + margin: 0 10px 0 0; +} + +.datlichnhac-input-gr .left { + padding-right: 10px; + font-size: 16px; +} + +.datlichnhac-input-gr .right { + padding-left: 10px; + font-size: 16px; +} + +.datlichnhac.err .datlichnhac-input-gr input.dln-mins { + border: 2px solid #e22028; +} + +.input-gr.err input, +.input-gr.err select, +.input-gr.err textarea { + border: 2px solid #e22028; +} + +.input-gr input::placeholder, +.input-gr textarea::placeholder { + /* Chrome, Firefox, Opera, Safari 10.1+ */ + color: #000; + opacity: 1; + /* Firefox */ +} + +.input-gr input:-ms-input-placeholder, +.input-gr textarea::placeholder { + /* Internet Explorer 10-11 */ + color: #000; +} + +.input-gr input::-ms-input-placeholder, +.input-gr textarea::placeholder { + /* Microsoft Edge */ + color: #000; +} + +.sunE-time-lcv .time { + padding-right: 10px; +} + +.sunE-time-lcv .time input { + background: #a2eddf; +} + +.sunE-time-lcv .lcv { + padding-left: 10px; +} + +.sunE-time-lcv .lcv select { + padding-left: 10px; +} + +.laplai p { + line-height: 24px; + padding-left: 0; +} + +.laplai p span { + line-height: 24px; + font-family: "Myriadpro-Light"; + font-size: 16px; +} + +.laplai input { + margin: -2px 10px 0 0; +} + +.laplai p > input[type="radio"]:checked + *::before { + background: radial-gradient( + #84c241 0%, + #84c241 40%, + transparent 50%, + transparent + ); +} + +.apdung label { + display: block; + margin: 15px 0; + font-family: "Myriadpro-SemiBold"; + font-size: 18px; + color: #000000; + padding: 0 0 10px 15px; +} + +.text-blue-main { + color: #00a79d; + font-family: "Myriadpro-SemiBold"; + font-size: 18px; + padding-left: 40px; +} + +.apdung .flex-1 img { + margin: 20px 0 0 10px; + cursor: pointer; +} + +.sunE-box-xkh p { + text-align: center; + font-size: 18px; + font-family: "Myriadpro-Light"; + margin: 0 0 15px; +} + +.title-list-lichnam h2 { + font-size: 24px; + padding: 10px 0; + text-align: center; + color: #fff; + font-family: "Myriadpro-Bold"; + background: #00a79d; + border-radius: 15px; + border: none; +} + +.w-120 { + width: 120px; +} + +.title-list-lichnam { + margin: 0 0 15px; +} + +.title-list-lichnam .flex-1 { + margin-left: 10px; +} + +.list-lichnam-item .w-120 { + background: #fff; + border-radius: 15px; + box-shadow: 0 1px 6px 0 rgba(21, 27, 38, 0.15); + display: flex; + justify-content: center; + align-items: center; +} + +.list-lichnam-item { + margin: 0 0 10px; +} + +.list-lichnam-item .w-120 p { + font-size: 22px; + text-align: center; + font-family: "Myriadpro-Bold"; + margin: 0; + padding: 0; + min-height: 100px; + line-height: 100px; +} + +.list-lichnam-item .flex-1 { + margin-left: 10px; + background: #fff; + border-radius: 15px; + box-shadow: 0 1px 6px 0 rgba(21, 27, 38, 0.15); + padding: 10px 10px 35px 20px; +} + +.list-lichnam-item .flex-1 p { + font-size: 16px; + font-family: "Myriadpro-Light"; + margin: 0; + padding: 0; +} + +.btn-capnhat { + color: #00a79d; + text-decoration: underline; + font-size: 16px; + font-family: "Myriadpro-SemiBold"; + position: absolute; + bottom: 0.3rem; + right: 3rem; + cursor: pointer; +} + +.__top { + bottom: 30px; + top: auto !important; +} + +.flex-center-custom { + display: flex; + align-items: center; + flex-direction: column; + justify-content: center; + padding: 0px !important; +} + +.flex-center-custom input { + width: 46px !important; +} + +.list-lichnam-box { + max-height: calc(100vh - 210px); + overflow: auto; + padding-right: 10px; +} + +.custom-area::-webkit-input-placeholder { + opacity: 0.5; +} +.scrollbar-custom::-webkit-scrollbar { + width: 6px; +} + +.style_scroll_overflowing_curriculum_favorite { + max-height: calc(100vh - 280px) !important; +} + +/* Track */ +.scrollbar-custom::-webkit-scrollbar-track { + background: #bbcbc3; + border-radius: 4px; +} + +/* Handle */ +.scrollbar-custom::-webkit-scrollbar-thumb { + background: #00bbb6; + border-radius: 4px; +} + +.scrollbar-custom-2::-webkit-scrollbar { + width: 7px; +} + +/* Track */ +.scrollbar-custom-2::-webkit-scrollbar-track { + background: #bbcbc3; + border-radius: 4px; + margin: 15px; +} + +/* Handle */ +.scrollbar-custom-2::-webkit-scrollbar-thumb { + background: #00bbb6; + border-radius: 4px; +} + +/* Scroll Custom Transparent bg */ +.scrollbar-custom-3::-webkit-scrollbar { + width: 8px; +} + +/* Track */ +.scrollbar-custom-3::-webkit-scrollbar-track { + /* background: #bbcbc3; */ + border-radius: 4px; + margin: 10px 0; +} + +/* Handle */ +.scrollbar-custom-3::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.2); + border-radius: 4px; +} + +/* SCROLL 4 */ +/* Scroll Custom Transparent bg */ +.scrollbar-custom-4::-webkit-scrollbar { + width: 8px; +} + +/* SCROLL PURPLE */ +.scrollbar-custom-purple::-webkit-scrollbar { + width: 7px; +} + +/* Track */ +.scrollbar-custom-purple::-webkit-scrollbar-track { + background: #bbcbc3; + border-radius: 4px; +} + +/* Handle */ +.scrollbar-custom-purple::-webkit-scrollbar-thumb { + background: #2e3192; + border-radius: 4px; +} + +/* Track */ +.scrollbar-custom-4::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.1); + border-radius: 4px; + margin: 10px 0; +} + +/* Handle */ +.scrollbar-custom-4::-webkit-scrollbar-thumb { + background: #ececec; + border-radius: 4px; +} + +/* Scroll5 */ +/* Scroll Custom Transparent bg */ +.scrollbar-custom-5::-webkit-scrollbar { + width: 13px; +} + +/* Track */ +.scrollbar-custom-5::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.1); + border-radius: 6px; + /* margin: 10px 0; */ +} + +/* Handle */ +.scrollbar-custom-5::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.2); + border-radius: 6px; +} + +/* Scroll Orange */ +/* Scroll Custom Transparent bg */ +.scrollbar-custom-orange::-webkit-scrollbar { + width: 6px; +} + +/* Track */ +.scrollbar-custom-orange::-webkit-scrollbar-track { + background: transparent; + border-radius: 8px; + margin: 14px 0; +} + +/* Handle */ +.scrollbar-custom-orange::-webkit-scrollbar-thumb { + background: #dfb937; + border-radius: 6px; +} + +.btn-create-taomoi img { + position: absolute; + left: 15px; + top: 9px; +} + +.sunE-main-title .btn-create-taomoi.form-sunE-button, +.sunE-main-title .btn-create-datlai.form-sunE-button { + margin-right: 10px; +} + +.btn-create-taomoi button, +.btn-create-datlai button { + padding: 0 35px 0 60px; +} + +.btn-create-datlai img { + position: absolute; + left: 15px; + top: 7px; +} + +.w60 { + width: 66px; +} + +.tkb-day { + display: flex; +} + +.tkb-day p { + text-align: center; + font-size: 16px; + color: #2ecdc0; + font-family: "Myriadpro-Regular"; + padding-right: 20px; +} + +.sunE-tkb-hour { + display: flex; +} + +.sunE-tkb-hour .w60 { + border: 1px solid #a7a9ac; + border-right: none; + border-top: none; + height: 88px; +} + +.tkb-table .sunE-tkb-hour:first-child .w60 { + border-top: 1px solid #a7a9ac; +} + +.tkb-table .sunE-tkb-hour .w60.tkb-time { + border: none; + display: flex; + align-items: flex-end; + position: relative; +} + +.tkb-table .borderTop50 { + position: absolute; + border-top: 1px solid #a7a9ac; + top: 0; + left: 50%; + width: 100%; +} + +.tkb-table .borderBottom50 { + position: absolute; + border-bottom: 1px solid #a7a9ac; + bottom: 0; + left: 50%; + width: 100%; +} + +.tkb-time p { + font-size: 16px; + color: #414042; + font-family: "Myriadpro-SemiBold"; + text-align: right; + padding-right: 10px; + display: block; + width: 100%; +} + +.tkb-item { + width: 66px; + position: absolute; + border-radius: 10px; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; +} + +.tkb-item h2 { + color: #fff; + font-size: 14px; + font-family: "Myriadpro-Bold"; + text-align: center; + padding: 0; + margin: 0; + line-height: 18px; + width: 60px; + max-height: 38px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + margin: 0 0 5px; +} + +.tkb-item p { + color: #fff; + font-size: 14px; + font-family: "Myriadpro-Light"; + text-align: center; + padding: 0; + margin: 0; + line-height: 16px; +} + +.tkb-table { + max-height: calc(100vh - 200px); + overflow: auto; + padding-right: 5px; +} + +.flex-column { + display: flex; + justify-content: space-between; + flex-direction: column; +} + +.select-time input { + width: 180px; + margin: 13px 0 0 15px; + background: #a2eddf; +} + +.select-time .react-datepicker-wrapper .react-datepicker__input-container { + z-index: 10; +} + +/*END GIAO VIEN*/ +/*GIAO TRINH*/ +.pr-15 { + padding-right: 15px; +} + +.pl-15 { + padding-left: 15px; +} + +.pr-25 { + padding-right: 25px; +} + +.pl-25 { + padding-left: 25px; +} + +.sunE-select-gt { + margin-top: 83px; +} + +.box-select-gr { + background: #fff; + border-radius: 20px; + padding: 30px 0 30px 32px; + margin: 0 0 15px 20px; + cursor: pointer; + box-sizing: border-box; +} + +.box-select-gr .thumb { + position: absolute; + top: -2px; + left: -30px; + display: flex; + justify-content: center; + align-items: center; + background: #ccedeb; + border: 5px solid #fff; + border-radius: 50%; + width: 104px; + height: 104px; + box-shadow: 0 1px 8px 0 rgba(21, 27, 38, 0.24); +} + +.box-select-info p { + color: #221f1f; + font-size: 18px; + text-align: center; + padding: 0; + margin: 0; + line-height: 20px; +} + +.box-select-info h2 { + color: #00a69c; + font-size: 18px; + font-family: "Myriadpro-Bold"; + text-align: center; + padding: 0; + margin: 0; + line-height: 20px; + text-transform: uppercase; +} + +.box-select-file-full { + flex: 1; +} +.box-select-file-full p { + flex: 1; + text-align: left; +} + +.box-giaotrinh-gr { + background: #fff; + border-radius: 20px; + height: 64px; + display: flex; + justify-content: center; + align-items: center; + margin: 0 0 30px 20px; + cursor: pointer; + box-sizing: border-box; + padding: 0 15px 0 60px; + width: 100%; +} + +.giaobai-support.uk-container .box-giaotrinh-gr { + margin: 0 0 0 20px; +} + +.__input_score_exercise { + /* color: rgb(183, 178, 178); */ + width: 80%; + border: none; + text-align: center; +} + +.__input_score_exercise::placeholder { + opacity: 0.5; +} + +.__input_score_exercise:focus { + outline: none; +} + +.box-giaotrinh-gr .thumb { + position: absolute; + top: -5px; + left: -30px; + display: flex; + justify-content: center; + align-items: center; + background: #ffffff; + border: 3px solid #fff; + border-radius: 50%; + width: 75px; + height: 75px; + box-shadow: 0 1px 8px 0 rgba(21, 27, 38, 0.24); +} + +.box-giaotrinh-gr .thumb3 { + position: absolute; + top: -5px; + left: -30px; + display: flex; + justify-content: center; + align-items: center; + background: #ccedeb; + border: 3px solid #fff; + border-radius: 50%; + width: 75px; + height: 75px; + box-shadow: 0 1px 8px 0 rgba(21, 27, 38, 0.24); +} + +.box-giaotrinh-gr .thumb img { + width: 65px; + height: 65px; + object-fit: contain; +} + +.box-giaotrinh-gr .thumb3 img { + width: 50px; + height: 50px; + object-fit: contain; +} + +.box-giaotrinh-gr .thumb2 { + position: absolute; + top: 5px; + left: -30px; + display: flex; + justify-content: center; + align-items: center; + border-radius: 50%; + width: 90px; + height: 90px; +} + +.gtcn-menu-gr { + margin: 0 0 20px; +} + +.gtcn-menu-gr span { + color: #373737; + font-size: 24px; + font-family: "Myriadpro-SemiBold"; + margin-right: 30px; + cursor: pointer; +} + +.gtcn-menu-gr span.active { + color: #00bbb6; + border-bottom: 2px solid #00bbb6; +} + +.box-select-info span { + display: block; + font-family: "Myriadpro-Light"; + font-size: 16px; +} + +.box-giaotrinh-gr.hei-custom { + height: 102px; + justify-content: flex-start; +} + +.box-giaotrinh-gr.hei-custom .thumb { + top: 13px; +} + +.box-giaotrinh-gr.hei-custom .thumb3 { + top: 13px; +} + +.box-giaotrinh-gr.hei-custom .box-select-info p { + margin: 0 0 5px; +} + +.btn-disable { + cursor: not-allowed; + background: #70707070 !important; + pointer-events: none; +} + +.box-giaotrinh-gr.hei-custom.active { + background: #c3fdf3; +} + +.flex-2 { + flex: 2; +} + +.flex-3 { + flex: 3; +} + +.box-giaotrinh-gr.hei-custom.edit .box-select-info p { + text-align: left; +} + +.box-giaotrinh-gr.hei-custom.edit { + height: 150px; + padding: 0 15px 0 30px; + margin: 0 0 20px 0; +} + +.sunE-main-title .form-sunE-button.btn-filter { + margin-right: 10px; +} + +.btn-filter-custom { + justify-content: center; + display: flex; + align-items: center; + margin-right: 10px; +} + +.btn-filter-custom img { + margin-right: 6px; +} + +.btn-filter img { + position: absolute; + top: 12px; + left: 15px; +} + +.btn-filter button { + padding: 0 35px 0 45px; +} + +.sunE-container-box.filter { + padding: 20px 20px 0 20px; +} + +.sunE-container-box.filter.pad-t-0 { + padding: 0 20px 0 20px; +} + +.sunE-giaotrinh-resuft-filter { + background: #fff; + padding: 20px 30px; + border-radius: 20px; + max-height: calc(100vh - 230px); + margin: 0 0 15px; + overflow: auto; +} + +.span-title { + color: #000; + font-size: 16px; + font-family: "Myriadpro-SemiBold"; + margin: 0 0 10px; + display: block; +} + +.sunE-giaotrinh-item { + margin: 0 0 10px; +} + +.sunE-giaotrinh-item .img { + width: 120px; + height: 108px; +} + +.sunE-giaotrinh-item .img img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.sunE-giaotrinh-item .content { + padding-left: 20px; + padding-top: 10px; +} + +.sunE-giaotrinh-item .content h2.title { + color: #00a69c; + font-family: "Myriadpro-Bold"; + font-size: 18px; + line-height: 22px; + margin: 0 0 5px; +} + +.sunE-giaotrinh-item .content .easy { + background: #6ebf49; + color: #fff; + padding: 3px 10px; + border: none; + border-radius: 5px; +} + +.sunE-giaotrinh-item .content .medium, +.sunE-giaotrinh-item .content .normal { + background: #fbb040; + color: #fff; + padding: 3px 10px; + border: none; + border-radius: 5px; +} + +.sunE-giaotrinh-item .content .hard { + background: #be1e2d; + color: #fff; + padding: 3px 10px; + border: none; + border-radius: 5px; +} + +.sunE-giaotrinh-item .content h3.desc { + color: #00a69c; + font-family: "Myriadpro-Light"; + font-size: 18px; + line-height: 22px; + margin: 0 0 10px; +} + +.sunE-giaotrinh-item .content p, +.sunE-giaotrinh-item .content span { + font-family: "Myriadpro-Light"; + font-size: 18px; + line-height: 22px; + margin: 0 0 10px; +} + +.sunE-giaotrinh-item .chk-gr { + position: absolute; + display: flex; + bottom: 0; + right: 0; +} + +.sunE-giaotrinh-item .chk-gr input { + width: 25px; + height: 25px; + margin: 0 0 0 10px; +} + +.btn-bar { + margin-right: 10px; + cursor: pointer; + width: 64px; +} + +.btn-bar img { + height: 40px; +} + +.bar-select { + margin: 0 20px 0 20px; +} + +.bar-select select { + width: 100%; + height: 40px; + padding-left: 40px; + border-radius: 20px; + border: none; + outline: none; + box-shadow: 0 1px 8px 0 rgba(21, 27, 38, 0.15); + font-size: 16px; + font-family: "Myriadpro-SemiBold"; + padding-right: 40px; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + /* Remove default arrow */ + background: url("./../images/icon/ico_dropdown.png") 97% / 20px no-repeat #fff; + /* Add custom arrow */ +} + +.sunE-content-unit { + max-width: 100%; + overflow: auto; +} + +.sunE-content-unit::-webkit-scrollbar { + display: none; +} + +.sunE-unit-list { + display: inline-flex; +} + +.sunE-unit-item { + width: 187px; +} + +.sunE-unit-item .h-287 { + height: 287px; +} + +.sunE-unit-item h2 { + font-size: 22px; + margin: 0; + padding: 0; + text-align: center; + font-family: "Myriadpro-Regular"; +} + +.sunE-unit-item p { + font-size: 16px; + margin: 0; + padding: 0; + text-align: center; + font-family: "Myriadpro-Light"; +} + +.cs-point { + cursor: pointer; +} + +.giaotrinh.unit .box-giaotrinh-gr { + padding: 0 15px 0 50px; + margin: 0 0 20px 20px; +} + +.giaotrinh.unit .sunE-giaotrinh-list, +.giaotrinh.unit .unit-list { + max-height: calc(100vh - 210px); + overflow: auto; + padding: 0 25px 0 20px; + + @media screen and (max-height: 800px){ + max-height: calc(100vh - 130px); + + } +} + +.giaotrinh.unit .unit-list { + padding: 0 80px 0 100px; +} + +.giaotrinh.unit .unit-list .box-giaotrinh-gr { + border-radius: 32px; + height: 50px; +} + +.giaotrinh.unit .box-giaotrinh-gr-first { + background: #fff; + padding: 15px 0; + text-align: center; + border-radius: 20px; + margin: 0 0 20px -10px; + width: calc(100% + 30px); +} + +.padding_box_giaotrinh_gr_frist { + padding: 15px 0 15px 50px !important; +} + +.giaotrinh.unit .box-giaotrinh-gr-first h2 { + font-size: 24px; + margin: 0; + padding: 15px 0; + text-align: center; + font-family: "Myriadpro-Bold"; +} + +.giaotrinh.unit .box-giaotrinh-gr-first img { + width: 70px; + height: 70px; + object-fit: contain; +} + +.giaotrinh.unit .unit-list .box-giaotrinh-gr { + padding: 0 45px 0 25px; + margin: 0 0 10px 0; + justify-content: flex-start; +} + +.box-unit-info p, +.box-unit-info p span { + font-size: 16px; +} + +.unit-list .unit-giaotrinh-content.active { + background: rgba(106, 248, 239, 0.3); + border-top-right-radius: 30px; + border-top-left-radius: 30px; + border-bottom-right-radius: 20px; + border-bottom-left-radius: 20px; + padding-bottom: 10px; +} + +.btn-more-info { + width: 40px; + height: 40px; + text-align: center; + border-radius: 20px; + background: #d3d2d1; + position: absolute; + right: 10px; + top: 5px; + cursor: pointer; +} + +.btn-more-info img { + margin: 0; +} + +.unit-list .unit-giaotrinh-content.active { + margin-bottom: 10px; +} + +.unit-list .unit-giaotrinh-content .unit-more-info { + display: none; +} + +.unit-list .unit-giaotrinh-content.active .unit-more-info { + display: block; + border-bottom: 1px solid #000; +} + +.unit-list .unit-giaotrinh-content.active a:last-child .unit-more-info { + border-bottom: none; +} + +.unit-more-info-item { + padding: 10px 0; + border-bottom: 1px solid #fff; +} + +.unit-more-info-item:last-child { + border-bottom: none; +} + +.unit-more-info-item .score { + width: 60px; + margin: auto; + display: flex; + justify-content: center; + align-items: center; +} + +.unit-more-info-item .score .score-box { + width: 40px; + height: 40px; + text-align: center; + background: #fff; + border-radius: 50%; +} + +.info-item-desc h2 { + font-size: 16px; + line-height: 20px; + margin: 0; + padding: 0; + font-family: "Myriadpro-SemiBold"; + color: #000; + margin-right: 5px; +} + +.info-item-desc p { + font-size: 16px; + line-height: 20px; + margin: 0; + padding: 0; + color: #fff; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + margin-right: 5px; + max-width: 290px; + max-height: 20px; +} + +.score-box { + padding: 2px 0 0; +} + +.score-box h2 { + font-size: 20px; + line-height: 20px; + margin: 0; + padding: 0; + font-family: "Myriadpro-Bold"; + color: #e3001b; +} + +.score-box span { + font-size: 12px; + line-height: 12px; + margin: 0; + padding: 0; + font-family: "Myriadpro-Light"; + display: block; +} + +.percent { + width: 42px; + height: 42px; +} + +.line-h-44 { + padding: 0; + line-height: 44px; +} + +.check-box-gr { + margin: 10px 0; +} + +.check-box-gr input { + margin: -3px 8px 0 0; + width: 20px; + height: 20px; + outline: none; + /*box-shadow: 0 1px 6px 0 rgba(21, 27, 38, .15);*/ +} + +.check-box-gr .err label { + color: #e22028; +} + +.check-box-gr label { + font-size: 16px; + font-family: "Myriadpro-Semibold"; + color: #000; +} + +/*END GIAO TRINH*/ +/*TEACHER GIAO BAI*/ +.btn-giaobai-gr { + margin: 20px 0 0; +} + +.btn-giaobai-gr .btn-line-blue { + padding: 0 50px; +} + +.sunE-giaobai-list { + background: #fff; + padding: 20px 30px; + border-radius: 20px; + max-height: calc(100vh - 230px); + margin: 0 0 15px; + overflow: auto; +} + +.sunE-giaobai-list .sunE-giaotrinh-item { + padding-bottom: 10px; + border-bottom: 1px solid #777777; +} + +.sunE-giaobai-list .sunE-giaotrinh-item:last-child { + border-bottom: none; +} + +.giaotrinh.pad-t-0 .sunE-giaotrinh-resuft-filter .sunE-giaotrinh-item { + padding-bottom: 10px; + border-bottom: 1px solid #777777; +} + +.giaotrinh.pad-t-0 + .sunE-giaotrinh-resuft-filter + .sunE-giaotrinh-item:last-child { + border-bottom: none; +} + +.pl-20 { + padding-left: 20px; +} + +.semibold { + font-family: "Myriadpro-Semibold"; +} + +.nhacnho-content textarea { + width: 100%; + height: 80px; + outline: none; + border: none; + border-radius: 20px; + padding: 10px 20px; + box-shadow: 0 1px 6px 0 rgb(21 27 38 / 15%); + box-sizing: border-box; + font-family: "Myriadpro-Regular"; + font-size: 16px; + resize: none; + margin: 0 0 10px; +} + +.nhacnho-content .datlichnhac-input-gr input.dln-mins { + width: 80px; +} + +.err-nhacnho { + margin: 10px 0; + display: none; +} + +.err-nhacnho p { + color: #e22028; + font-family: "Myriadpro-Light"; +} + +.err-nhacnho img { + margin: 15px 0 0; +} + +.err.err-nhacnho { + display: flex; +} + +.box-giaotrinh-gr.active { + background: #c3fdf3; +} + +.teacher-giaobai .unit-list .box-giaotrinh-gr { + padding: 0 25px; + margin: 0 0 10px 0; + justify-content: flex-start; +} + +.unit-list .unit-giaotrinh-content.active a:last-child .unit-more-info { + border-bottom: none; +} + +.ythich.sunE-giaotrinh-resuft-filter { + max-height: calc(100vh - 235px); +} + +.sunE-container-box.teacher-giaotrinh-yt { + padding: 10px 20px 0 20px; +} + +.sunE-main-title .form-sunE-button.btn-setting { + margin-right: 10px; +} + +.btn-setting img { + position: absolute; + top: 6px; + left: 15px; +} + +.btn-setting button { + padding: 0 35px 0 50px; +} + +.box-info-giaobai { + background: #fff; + padding: 28px 20px; + border-radius: 20px; +} + +.box-info-giaobai h2.title { + color: #00a69c; + font-family: "Myriadpro-Bold"; + font-size: 18px; + line-height: 22px; + margin: 0 0 5px; +} + +.box-info-giaobai h3.desc { + color: #00a69c; + font-family: "Myriadpro-Light"; + font-size: 18px; + line-height: 22px; + margin: 0 0 30px; +} + +.box-info-giaobai p { + font-family: "Myriadpro-Light"; + font-size: 18px; + line-height: 22px; + margin: 0 0 10px; +} + +.semibold.box-info-giaobai p { + font-family: "Myriadpro-Semibold"; +} + +.box-info-giaobai.semibold p { + font-family: "Myriadpro-Semibold"; +} + +.pr-10 { + padding-right: 10px; +} + +.pl-10 { + padding-left: 10px; +} + +.menu-gr { + margin: 0 0 15px; +} + +.menu-gr button.btn-line-blue { + background-image: linear-gradient(to right, #b7f3e4, #b7f3e4); + border-radius: 5px; + width: 100%; + color: #00bbb5; +} + +.menu-gr button.btn-line-blue.active { + background-image: linear-gradient(to right, #00e1a0, #00b9b7); + color: #fff; +} + +.list-giaobai .item-student { + background: #fff; + border-radius: 20px; + padding: 10px; + /* margin-right: 15px; */ +} + +.item-student-name h2 { + font-family: "Myriadpro-Semibold"; + font-size: 18px; + line-height: 22px; + margin: 10px 0 10px; +} + +.item-student-name span { + font-size: 18px; + line-height: 26px; + padding-left: 10px; + font-family: "Myriadpro-Light"; +} + +.item-student .score { + background: #be1e2d; + width: 55px; + height: 55px; + display: flex; + justify-content: center; + align-items: center; + border-radius: 50%; + border: none; + box-sizing: border-box; + margin: 9px 0 0; +} + +.item-student .score span { + color: #fff; + font-family: "Myriadpro-Semibold"; + font-size: 18px; +} + +.list-giaobai { + overflow: auto; + max-height: calc(100vh - 260px); + padding-right: 10px; +} + +.list-giaobai.chualam { + max-height: calc(100vh - 320px); +} + +.chk-flex { + display: flex; + align-items: center; +} + +.chk-flex input, +.chk-ab input { + width: 20px; + height: 20px; + margin: 0; +} + +.chk-ab { + position: absolute; + top: calc(50% - 10px); + right: 15px; +} + +.check-box-padding-custom label::before { + padding: 10px 10px 10px 10px !important; +} + +.padding_checkbox_filter label::before { + margin-right: 8px !important; +} + +.giaobai-ganday .select-all { + padding: 15px 0 0; +} + +.giaobai-ganday .select-all input { + margin: -3px 10px 0 0; + width: 16px; + height: 16px; +} + +.giaobai-ganday .select-all label { + font-family: "Myriadpro-Semibold"; +} + +.gr-all-nn { + margin: 30px 0 0; +} + +.sunE-container-box.giaobai-ganday { + padding: 32px 20px 20px; +} + +.sunE-container-box.giaobai-support { + padding: 20px 0 15px; +} + +.mb-10 { + margin-bottom: 10px; +} + +.giaobai-ganday .p0 { + padding: 0; +} + +.btn-thembai { + margin-right: 10px; +} + +.file-support span { + font-size: 14px; + color: #f16522; + padding-left: 10px; + line-height: 30px; +} + +.file-support-is-active span { + color: #0b9300 !important; +} + +.file-support.black span { + font-size: 18px; + color: #404041; + font-family: "Myriadpro-Light"; + padding: 0 15px; + display: block; +} + +.bg-dc .sunE-giaotrinh-item { + padding-bottom: 10px; + border-bottom: 1px solid #000; +} + +.bg-dc .sunE-giaotrinh-item:last-child { + border-bottom: none; +} + +.blue-main { + color: #00a79d; +} + +.giaobai-support .box-giaotrinh-gr { + padding: 0 40px 0 60px; +} + +.mr-10 { + margin-right: 10px !important; +} + +.title-semi { + margin: 20px 0 10px; + font-family: "Myriadpro-Semibold"; + font-size: 18px; +} + +.sunE-input-group.re label { + font-family: "Myriadpro-Regular"; +} + +.mg0 { + margin: 0; +} + +.mb-10 { + margin-bottom: 10px; +} + +.w-remove img { + cursor: pointer; +} + +/*END TEACHER GIAO BAI*/ +/*CHAM BAI*/ +.flex-5 { + flex: 5; +} + +.sunE-right-container:has(.__text_empty) { + overflow: initial; +} +.chambai.writing { + margin: 0 0 15px; +} + +.btn-setting-cb { + margin-right: 10px; +} + +.topic { + background: #fff; + padding: 25px 20px; + border-radius: 20px; + margin: 0 0 15px; +} + +.bg-line-blue { + background-image: linear-gradient(to right, #00e1a0, #00b9b7); +} + +.bg-blue { + background: #00a69c; +} + +.box-criteria { + padding: 10px; + border-radius: 20px; + height: 274px; + overflow: auto; +} + +.box-criteria-full { + max-height: fit-content; +} + +.box-criteria-scroll { + max-height: 310px; +} + +.box-title-bg { + border-radius: 25px; + height: 40px; + box-sizing: border-box; + border: none; +} + +.box-title-bg p { + font-family: "Myriadpro-Bold"; + font-size: 22px; + color: #fff; + /* line-height: 48px; */ +} + +.bg-white { + background: #fff; +} + +.box-criteria-list, +.box-criteria-score { + border-radius: 20px; + border: none; + padding: 10px 0; +} + +.bd-bot { + border-bottom: 1px solid #787878; +} + +.bd-bot:last-child { + border-bottom: none; +} + +.box-criteria-item { + height: 59px; +} + +.max-w { + max-width: 150px; +} + +.center-flex { + display: flex; + justify-content: center; + align-items: center; +} + +.center-h-flex { + display: flex; + align-items: center; +} + +.box-criteria-content { + margin: 0 0 15px; +} + +.box-bd-20 { + border-radius: 20px; + padding: 10px 0; +} + +.box-criteria-score-title p { + color: #231f20; + font-family: "Myriadpro-Bold"; + font-size: 18px; + padding-left: 15px; +} + +.box-criteria-comment { + padding: 10px; + border-radius: 20px; +} + +.ml-10 { + margin-left: 10px; +} + +.box-criteria-comment h2 { + color: #231f20; + font-family: "Myriadpro-Bold"; + font-size: 24px; + padding-left: 35px; + margin: 0 0 5px; +} + +.box-criteria-comment textarea { + padding: 15px 15px 10px 35px; + border-radius: 20px; + resize: none; + width: 100%; + height: 200px; + background: #ececec; + border: none; + outline: none; + box-sizing: border-box; + font-family: "Myriadpro-Regular"; + font-size: 16px; +} + +.box-criteria-comment textarea::placeholder { + font-family: "Myriadpro-Regular"; + font-size: 16px; +} + +.post-content { + background: #fff; + padding: 30px 20px; + border-radius: 20px; + margin: 0 0 15px; +} + +.btn-mark { + height: 42px; + line-height: 42px; + background: #ed8a22; + padding: 0 0 0 25px; + box-sizing: border-box; + border-radius: 21px; + border: none; + cursor: pointer; + margin: 0 10px 0 0; +} + +.btn-help { + height: 42px; + line-height: 42px; + background: #00a69c; + box-sizing: border-box; + border-radius: 21px; + border: none; + cursor: pointer; + padding: 0 30px; +} + +.btn-mark img { + position: absolute; + top: 2px; + left: 3px; +} + +.btn-mark p { + font-family: "Myriadpro-Regular"; + font-size: 18px; + padding: 0 35px; + color: #fff; +} + +.title-post-box { + font-family: "Myriadpro-Bold"; + font-size: 24px; + line-height: 42px; +} + +.post-content .content-box-edit { + padding: 15px 15px 10px 35px; + border-radius: 20px; + resize: none; + width: 100%; + background: #ececec; + border: none; + outline: none; + box-sizing: border-box; + font-family: "Myriadpro-Regular"; + font-size: 16px; + max-height: 210px; + overflow-y: auto; +} + +.content-box-edit .error { + color: #ff0606; + font-family: "Myriadpro-Bold"; +} + +.content-box-edit .delete { + color: #ff0606; + font-family: "Myriadpro-Bold"; + text-decoration: line-through; +} + +.content-box-edit .fix { + color: #00e254; + font-family: "Myriadpro-Bold"; + text-decoration: underline; +} + +.box-video-project { + margin: 0 0 15px; +} + +.box-project-score-gr { + border-radius: 20px; +} + +.project-score-gr { + padding: 20px; +} + +.project-score-gr h2 { + color: #231f20; + font-family: "Myriadpro-Bold"; + font-size: 24px; + margin: 0 0 5px; +} + +.project-score-gr textarea { + padding: 15px 15px 10px 20px; + border-radius: 20px; + resize: none; + width: 100%; + height: 132px; + background: #ececec; + border: none; + outline: none; + box-sizing: border-box; + font-family: "Myriadpro-Regular"; + font-size: 16px; +} + +.project-score-gr textarea::placeholder { + font-family: "Myriadpro-Regular"; + font-size: 16px; +} + +.project-score-gr input { + border-radius: 20px; + resize: none; + width: 152px; + height: 132px; + background: #ececec; + border: none; + outline: none; + box-sizing: border-box; + font-family: "Myriadpro-Bold"; + font-size: 50px; + color: #ff0000; + text-align: center; +} + +.project-score-gr input::-webkit-outer-spin-button, +.project-score-gr input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +/* Firefox */ +.project-score-gr input[type="number"] { + -moz-appearance: textfield; +} + +.black { + color: #4d4d4d !important; +} + +.lb-dc-gr span { + color: #fff; + font-size: 14px; + padding: 3px 15px; + border-radius: 11px; + line-height: 21px; +} + +.lb-dc-gr .lb { + background: #faaf40; + margin-right: 10px; +} + +.lb-dc-gr .dc { + background: #00a69c; +} + +.sunE-container-box.chambai { + padding: 10px 20px; +} + +.sunE-chambai-content { + background: #fff; + padding: 20px 30px; + border-radius: 20px; + max-height: calc(100vh - 150px); + margin: 0 0 15px; + overflow: auto; +} + +.sunE-chambai-content .sunE-giaotrinh-item { + padding-bottom: 10px; + border-bottom: 1px solid #707070; +} + +.sunE-chambai-content .sunE-giaotrinh-item:last-child { + border-bottom: none; +} + +.list-detail { + overflow: auto; + max-height: calc(100vh - 260px); + padding-right: 10px; +} + +.list-detail .item-student { + background: #fff; + border-radius: 20px; + padding: 10px 10px 10px 35px; + margin: 0 0 10px 50px; + min-height: 104px; +} + +.list-detail .item-student .item-student-name span { + font-size: 18px; + line-height: 37px; +} + +.list-detail .item-student-img { + position: absolute; + top: 9px; + left: -45px; + width: 85px; + height: 85px; + border-radius: 43px; + overflow: hidden; +} + +.list-detail .score { + background-image: linear-gradient(to top, #00b9b7, #00e1a0); + border-radius: 15px; + width: 82px; + height: 34px; + position: absolute; + top: 3px; + right: 5px; + margin: 0; +} + +.list-detail .score span { + font-size: 14px; + color: #fff; + line-height: 34px; + font-family: "Myriadpro-Italic"; +} + +.list-detail .score span.f24.bold { + font-family: "Myriadpro-Regular"; +} + +.f24 { + font-size: 24px !important; +} + +.gtcn-menu-gr.cb { + margin: 10px 0 10px 0; +} + +.cb-score-gr { + width: 100%; +} + +.cb-score-gr p { + font-size: 18px; + margin: 0 0 10px; + font-family: "Myriadpro-Light"; +} + +.cb-score-gr span { + font-size: 32px; + font-family: "Myriadpro-Bold"; + color: #00a69c; +} + +.bd-r-blue { + border-right: 2px solid #00a69c; +} + +/*END CHAM BAI*/ + +/*HO SO*/ +.avatar-edit { + margin: 30px 0 0; +} + +.avatar-edit-box { + background: #fff; + width: 210px; + height: 210px; + border-radius: 115px; + border: none; + cursor: pointer; + margin: 7px auto 25px; + padding: 3px; + overflow: hidden; +} + +.avatar-edit-box img { + width: 100%; + height: 100%; + border-radius: 50%; + z-index: 9; + object-fit: cover; +} + +.avatar-edit-box .img-edit-avt { + position: absolute; + bottom: 0; + background: #fff; + height: 53px; + width: 100%; + text-align: center; +} + +.avatar-edit-box .img-edit-avt img { + width: 39px; + height: 30px; + border-radius: 0; + margin-top: 10px; + object-fit: cover; +} + +.sunE-input-gr { + margin: 0 0 20px; +} + +.capitalize { + text-transform: capitalize; +} + +.sunE-input-gr label { + padding: 0 0 0 20px; + margin: 0 0 5px; + display: block; + font-family: "Myriadpro-Semibold"; + font-size: 18px; +} + +.sunE-input-gr input { + height: 44px; + width: 100%; + line-height: 44px; + font-size: 14px; + box-sizing: border-box; + padding: 0 20px; + border-radius: 22px; + outline: none; + border: 1px solid #fff; + box-shadow: 0 1px 8px 0 rgba(21, 27, 38, 0.15); +} + +.select-date-profile .input_date_base_container .field_birthday { + background-color: #fff; + display: block; + border: none; + padding: 0; + height: 44px; +} + +.sunE-input-gr input { + height: 44px; + width: 100%; + line-height: 44px; + font-size: 14px; + box-sizing: border-box; + padding-left: 20px; + border-radius: 22px; + outline: none; + border: 1px solid #fff; + box-shadow: 0 1px 8px 0 rgba(21, 27, 38, 0.15); +} + +.sunE-input-gr input::-webkit-outer-spin-button, +.sunE-input-gr input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +/* Firefox */ +.project-score-gr input[type="number"] { + -moz-appearance: textfield; +} + +.ml-10 { + margin-left: 10px; +} + +.hoso .sunE-male-female { + width: 44px; + height: 44px; + text-align: center; + background: #fff; + border-radius: 33px; + border: none; + box-shadow: 0 1px 15px 0 rgba(21, 27, 38, 0.15); + margin: 0 8px 0 0; + line-height: 60px; + cursor: pointer; + display: flex; +} + +.hoso .sunE-male-female span { + font-size: 18px; + line-height: 44px; + padding: 0 0 0 10px; +} + +.hoso .ico_male, +.hoso .ico_male_active { + width: 26px; + margin: 10px; +} + +.hoso .ico_female, +.hoso .ico_female_active { + width: 20px; + margin: 5px 13px; +} + +.hoso .sunE-male-female.male .ico_male_active { + display: none; +} + +.hoso .sunE-male-female.male .ico_male { + display: flex; +} + +.hoso .sunE-male-female.male.active .ico_male_active { + display: flex; +} + +.hoso .sunE-male-female.male.active .ico_male { + display: none; +} + +.hoso .sunE-male-female.female .ico_female_active { + display: none; +} + +.hoso .sunE-male-female.female .ico_female { + display: flex; +} + +.hoso .sunE-male-female.female.active .ico_female_active { + display: flex; +} + +.hoso .sunE-male-female.female.active .ico_female { + display: none; +} + +.sunE-container-box.hoso { + padding: 0; + min-height: 760px; +} + +.box-detail-ab { + position: absolute; + top: 190px; + width: 100%; + padding: 0 80px; +} + +.bg-hoso-top { + background-image: linear-gradient(to right, #00e2a0, #00b9b7); + width: 100%; + height: 344px; + position: absolute; + top: 0; + left: 0; + opacity: 0.1; +} + +.box-detail-ab .box-detail-hs { + background: #fff; + border-radius: 20px; + padding: 100px 20px 20px; + width: 420px; + margin: 0 auto; +} + +.text-error-input { + color: #e22028; +} + +.input-error { + border-color: #e22028 !important; +} + +.box-detail-hs .avt-ab { + width: 217px; + height: 217px; + border-radius: 50%; + overflow: hidden; + border: 5px solid #fff; +} + +.box-detail-hs.student .avt-ab { + width: 150px; + height: 150px; + top: -75px; + left: calc(50% - 75px); +} + +.box-detail-hs .avt-ab img { + width: 100%; + height: 100%; +} + +.box-detail-hs h2.name { + padding: 0; + margin: 10px 0px; + display: block; + font-family: "Myriadpro-Bold"; + font-size: 32px; + color: #231f20; + text-align: center; + margin-top: 20px; +} + +.box-detail-hs .avt-ab { + position: absolute; + top: -109px; + left: calc(50% - 108px); +} + +.detail-info { + padding: 0 60px 20px; +} + +.ltk { + line-height: 28px; + margin: 20px 0 10px; +} + +.btn-nc { + padding: 0 5px; + height: 28px; + line-height: 28px; + border-radius: 14px; + border: none; + font-size: 16px; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); + color: #fff; + display: block; + text-align: center; + cursor: pointer; +} + +#c-result-exam { + background-image: url("/assets/images/bg-result-exam.png"); +} + +.btn-nc:hover { + background-image: linear-gradient(to left, #00e1a0, #00b9b7); +} + +.btn-nc a { + color: #fff; +} + +.info-sum { + margin: 20px 0 0; +} + +.info-sum h3 { + font-size: 55px; +} + +.mr-20 { + margin-right: 20px; +} + +.ml-20 { + margin-left: 20px; +} + +.flex-in { + display: inline-flex; +} + +.male-box { + margin-right: 60px; +} + +/*END HO SO*/ +/*QUAN LY LOP OFFLINE*/ +.sunE-container-box.diemdanh { + padding: 30px 0 10px; + margin-bottom: 10px; +} + +.diemdanh-list { + padding-right: 20px; + max-height: calc(100vh - 230px); + padding-bottom: 10px; + overflow: auto; +} + +.diemdanh-item { + background: #fff; + border-radius: 20px; + padding: 10px 25px; + margin: 0 0 10px 15px; +} + +.diemdanh-add { + cursor: pointer; + padding: 15px 0; +} + +.diemdanh-add img { + width: 30px; + height: 30px; +} + +.medium-title { + padding: 0; + margin: 0 0 10px; + display: block; + font-family: "Myriadpro-Semibold"; + font-size: 18px; +} + +.diemdanh-item img { + margin-right: 10px; +} + +.diemdanh-item p { + font-size: 18px; + font-family: "Myriadpro-Semibold"; + color: #000; + line-height: 24px; +} + +.mb-5 { + margin-bottom: 5px; +} + +.ico_user_class { + margin-top: 12px; +} + +.diemdanh-item span { + font-size: 32px; + font-family: "Myriadpro-Semibold"; + color: #faaf40; + line-height: 42px; +} + +.diemdanh-list-hs { + padding: 0 15px 0 15px; + height: calc(100vh - 240px); + max-height: calc(100vh - 240px); +} + +.diemdanh-list-hs .chk-flex.ab-top { + position: absolute; + top: 8px; + right: 8px; +} + +.diemdanh-list-hs .item-student-name h2 { + font-family: "Myriadpro-Regular"; +} + +.item-student-name .btn-send-now { + height: 32px; + display: block; + line-height: 32px; + text-align: center; + padding: 0; + width: 120px; + min-width: 120px; + font-size: 16px; + font-family: "Myriadpro-Regular"; + cursor: pointer; +} + +.item-student-name .btn-op { + height: 32px; + border: 1px solid green; + color: green; + outline: none; + box-sizing: border-box; + border-radius: 16px; + width: 100%; + text-align: center; + padding-left: 20px; + font-size: 16px; + font-family: "Myriadpro-Regular"; +} + +.diemdanh-no-item { + margin: 40px auto 0; +} + +.diemdanh-no-item p { + color: #231f20; + font-size: 24px; + font-family: "Myriadpro-Bold"; + margin: 10px 0 0; +} + +.btn-create-diemdanh button { + padding: 0 20px 0 50px; + background-image: linear-gradient(to left, #00e1a0, #00b9b7); +} + +.btn-create-diemdanh img { + position: absolute; + top: 8px; + left: 13px; +} + +.diemdanh-ss { + display: flex; + justify-content: flex-end; + align-items: center; + margin-right: 3rem; +} + +.diemdanh-container .medium-title { + color: #707070; +} + +.w280 { + width: 280px; +} + +.f-right { + float: right; +} + +.nx-right-gr { + position: absolute; + bottom: 5px; + right: 10px; +} + +.diemdanh-list-hs .item-student-name h3 { + max-width: 450px; +} + +.send-success { + display: flex; +} + +.send-success img { + margin: -3px 3px 0 0; +} + +.send-success span.text-green { + font-size: 14px; + line-height: 20px; +} + +/*END QUAN LY LOP OFFLINE*/ +/*BANG VANG*/ +.score-tb-student span { + display: block; + width: 80px; + height: 46px; + line-height: 46px; + color: #fff; + text-align: center; + font-size: 24px; + font-family: "Myriadpro-Bold"; + background: #dc4630; + border-radius: 5px; + border: none; +} + +.lv-up div { + margin-left: 5px; + color: #0b9300; +} + +.lv-down span { + margin-left: 5px; + color: #dc4630; +} + +.bangvang-content { + padding: 20px 0 0; +} + +.top { + width: 285px; + background: #fff; + border-radius: 20px; + padding: 30px 0; + height: calc(100vh - 140px); + overflow: auto; +} + +.bangvang-content .class_student_list_box { + padding: 20px 10px 20px 20px; + border-radius: 20px; + border: none; + background: #fff; + height: calc(100vh - 140px); + overflow: auto; +} + +.bangvang-content .class_student_list_box .list-student { + max-height: 100%; + padding-right: 10px; +} + +.top-box { + margin: 0 0 20px; +} + +.__top_number { + position: absolute; + bottom: -5px; + left: 40%; + font-weight: bold; + border-radius: 50%; + background: #fff; + width: 30px; + height: 30px; + font-family: "Myriadpro-Bold" !important; + display: flex; + align-items: center; +} + +.__top_1 { + border: 1px solid #eeab50; +} + +.__top_2 { + border: 1px solid #a5a5a5; +} + +.__top_3 { + border: 1px solid #7da6d7; +} + +.top1 span { + display: block; + width: 80px; + height: 30px; + line-height: 30px; + color: #fff; + font-size: 18px; + font-family: "Myriadpro-Bold"; + background-image: linear-gradient( + 45deg, + #b0853a, + #f8efa5, + #9d7033, + #e7bf55, + #faf4ac, + #9d7033 + ); + text-align: center; + border-radius: 15px; + margin: 0 auto 5px; +} + +.top2 span { + display: block; + width: 80px; + height: 30px; + line-height: 30px; + color: #fff; + font-size: 18px; + font-family: "Myriadpro-Bold"; + background-image: linear-gradient( + 45deg, + #c0c0c0, + #ebeaea, + #b8b8b8, + #6f6f6f, + #ebeaea + ); + text-align: center; + border-radius: 15px; + margin: 0 auto 5px; +} + +.top3 span { + display: block; + width: 80px; + height: 30px; + line-height: 30px; + color: #fff; + font-size: 18px; + font-family: "Myriadpro-Bold"; + background-image: linear-gradient( + 40deg, + #a3bee3, + #7da6d7, + #dde5f4, + #b5c9e7, + #174d6b + ); + text-align: center; + border-radius: 15px; + margin: 0 auto 5px; +} + +.top-hs { + width: 166px; + height: 147px; + margin: 0 auto 10px; +} + +.top2 .top-hs { + width: 145px; + height: 129px; + margin: 0 auto 10px; +} + +.top3 .top-hs { + width: 139px; + height: 123px; + margin: 0 auto 10px; +} + +.top1 .top-hs .avt { + position: absolute; + top: 34px; + left: 45px; + width: 78px; + height: 78px; + border-radius: 39px; + border: 2px solid #f7eda1; + box-sizing: border-box; + object-fit: cover; +} + +.top2 .top-hs .avt { + position: absolute; + top: 19px; + left: 34px; + width: 78px; + height: 78px; + border-radius: 39px; + border: none; + border: 2px solid #d3d2d2; + box-sizing: border-box; + object-fit: cover; +} + +.top3 .top-hs .avt { + position: absolute; + top: 18px; + left: 31px; + width: 78px; + height: 78px; + border-radius: 39px; + border: none; + border: 2px solid #8da8ce; + box-sizing: border-box; + object-fit: cover; +} + +.top-hs .gold { + position: absolute; + top: 11px; + left: 61px; +} + +.top p { + font-size: 18px; + font-family: "Myriadpro-Regular"; + text-align: center; + padding: 0 10px; +} + +.top-hs .__top_number { + font-size: 18px; + font-family: "Myriadpro-Regular"; + /* text-align: center; */ + display: flex; + align-items: center; + justify-content: center; + line-height: 18px; +} + +/*END BANG VANG*/ +/*VINH DANH*/ +.vinhdanh-content { + padding: 30px 0 10px; +} + +.vinhdanh-content .uk-width-1-2 { + margin-bottom: 20px; +} + +.vinhdanh-content .uk-grid > * { + padding-left: 20px !important; +} + +.vinhdanh-content .uk-grid { + margin-left: -20px !important; +} + +.vinhdanh-item { + background: #fff; + border-radius: 20px; +} + +.avt-vd { + width: 100px; + height: 100px; + border-radius: 50px; + border: 3px solid #e9af38; + overflow: hidden; + margin: 20px auto 0; +} + +.avt-vd img { + width: 100px; + height: 100px; + object-fit: cover; +} + +.name-vd { + padding: 0 20px; + line-height: 37px; + white-space: nowrap; + text-align: center; + font-family: "Myriadpro-SemiBold"; + font-size: 18px; + color: #fff; + border-radius: 19px; + position: absolute; + top: 100px; + left: 50%; + transform: translate(-50%, 0); +} + +.vd-info { + position: absolute; + bottom: 15px; + left: 50%; + transform: translate(-50%, 0); + font-family: "Myriadpro-Bold"; + font-size: 18px; + white-space: nowrap; +} + +.bg-red { + background: #dc4630; +} + +.text-red { + color: #dc4630; +} + +.bg-blue { + background: #1b75bb; +} + +.text-blue { + color: #1b75bb; +} + +.bg-green { + background: #4b7805; +} + +.text-green { + color: #4b7805; +} + +.bg-green-hi { + background: #095b4f; +} + +.text-green-hi { + color: #095b4f; +} + +.bg-black { + background: #000000; +} + +.text-black { + color: #000000; +} + +/*END VINH DANH*/ +/*TIN NHAN*/ +.tinnhan { + padding: 20px 0 0; +} + +.tb-mes { + position: absolute; + bottom: 10px; + right: 10px; +} + +.box-btn { + width: 33px; + height: 33px; + border-radius: 50%; + border: none; + box-sizing: border-box; + display: flex; + justify-content: center; + align-items: center; + background: #00b9b7; + cursor: pointer; +} + +.reng { + width: 10px; + height: 10px; + border-radius: 5px; + background: #be1e2d; + position: absolute; + bottom: 0; + right: 0; +} + +.tn-menu-gr { + margin: 0 0 20px; +} + +.tn-menu-item { + cursor: pointer; + text-align: center; + box-sizing: border-box; + padding-bottom: 10px; + border-bottom: 2px solid #afafaf; +} + +.tn-menu-item.active { + padding-bottom: 11px; + border-bottom: 4px solid #f4ba42; +} + +.tn-menu-item .box-btn { + width: 45px; + height: 45px; + border-radius: 50%; + border: none; + box-sizing: border-box; + display: flex; + justify-content: center; + align-items: center; + background: #00b9b7; + cursor: pointer; + margin: 0 auto 8px; +} + +.tn-menu-item .reng { + width: 25px; + height: 25px; + border-radius: 50%; + background: #be1e2d; + position: absolute; + top: -4px; + right: -11px; + color: #fff; + text-align: center; + line-height: 25px; + font-size: 14px; + font-family: "Myriadpro-Light"; +} + +.tn-menu-item p { + color: #58595b; + font-size: 18px; + font-family: "Myriadpro-Light"; + text-transform: uppercase; +} + +.tn-menu-item.active p { + font-family: "Myriadpro-Bold"; +} + +.list-tinnhan { + padding: 0 20px 0 30px; + height: calc(100vh - 260px); + overflow: auto; +} + +.tinnhan-item { + background: #fff; + border-radius: 20px; + padding: 12px 20px 20px 45px; + margin: 0 0 10px; +} + +.tinnhan-item .avt { + width: 46px; + height: 46px; + border-radius: 23px; + border: 2px solid #e7c71d; + overflow: hidden; + box-sizing: border-box; + position: absolute; + top: 0; + left: -23px; + background: #fff; +} + +.tinnhan-item .avt.bd-ht { + border: 1px solid #00b9b7; +} + +.tinnhan-item .avt img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.add_code_student-gr { + width: 368px; + position: absolute; + left: 50%; + top: 510px; + transform: translate(-50%, -50%); +} + +.border-dash-map-up { + width: 250px; + border: 3px dashed #00b9b7; + top: 325px; + left: 68px; + transform: rotate(-60deg); + position: absolute; + z-index: 1; +} + +.border-dash-map-down { + width: 250px; + border: 3px dashed #00b9b7; + top: 333px; + left: 50px; + transform: rotate(60deg); + position: absolute; + z-index: 1; +} + +.hethong .tinnhan-item .avt { + text-align: center; +} + +.hethong .tinnhan-item .avt img { + width: 29px; + height: 24px; + margin-top: 9px; + object-fit: cover; +} + +.tinnhan-item h2 { + font-size: 18px; + line-height: 20px; + font-family: "Myriadpro-SemiBold"; + margin: 0 0 10px; + color: #000; +} + +.tinnhan-item span { + font-size: 12px; + font-family: "Myriadpro-Bold"; + color: #000; +} + +.hethong .tinnhan-item span { + color: #939598; +} + +.tinnhan-item p.mes-info { + font-size: 18px; + line-height: 24px; + max-height: 72px; + font-family: "Myriadpro-Regular"; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + color: #000; +} + +.msg-seen.tinnhan-item p.mes-info { + color: #525252; +} + +.no-mes-bg { + display: none; +} + +.no-mes .no-mes-bg { + display: block; +} + +.mes-content { + display: flex; + justify-content: center; + align-items: flex-start; + max-width: 444px; +} + +.mes-content.no-mes { + align-items: center; +} + +.mes-content { + padding: 0 0 0 20px; +} + +.mex-box { + width: 100%; + background: rgb(0 185 183 / 10%); + border-radius: 20px; + box-sizing: border-box; +} + +.mex-box.cus-hei { + height: calc(100vh - 140px); +} + +.mex-box.cus-hei-2 { + height: calc(100vh - 220px); +} + +.mex-info { + padding: 30px; +} + +.mex-box h2 { + font-size: 22px; + margin: 0 0 20px; +} + +.mex-box p { + font-size: 18px; + margin: 0 0 10px; +} + +.mex-box .btn-view-detail { + margin: 40px auto 0; + text-align: center; +} + +.bg_update { + width: calc(100% - 10px); + margin: 30px 5px 0; + box-sizing: border-box; +} + +.select-message.select { + cursor: pointer; + display: inline-block; + position: relative; + font-size: 18px; + font-family: "Myriadpro-SemiBold"; + color: #3f3f3f; + width: 200px; + height: 48px; + line-height: 48px; + border-radius: 24px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border: none; + background: #fff; + box-shadow: 2px 2px 4px 0 rgb(21 27 38 / 35%); +} + +.select-message .select-styled { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: #fff; + width: 200px; + height: 48px; + line-height: 48px; + border: none; + transition: all 0.2s ease-in; + border-radius: 24px; + color: #3f3f3f; + font-size: 18px; + text-align: center; + font-family: "Myriadpro-SemiBold"; + z-index: 10; + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.select-message .select-styled:after { + content: ""; + width: 17px; + height: 10px; + background: url(./../images/tinnhan/ico_dropdown.png) 98% / 17px no-repeat + transparent; + position: absolute; + top: 18px; + right: 30px; +} + +.select-message .select-options { + z-index: 9; + top: 50px; + border-top-right-radius: 20px; + border-top-left-radius: 20px; + padding: 0 20px 0; + margin-top: 0 !important; +} + +.select-message .select-options li { + margin: 0; + text-indent: 0; + transition: all 0.15s ease-in; + border-bottom: 1px solid #d2d2d2; + text-align: center; + font-size: 18px; + font-family: "Myriadpro-SemiBold"; +} + +.search-custom { + width: 400px; + height: 48px; + line-height: 48px; + padding: 0 45px 0 20px; + font-size: 18px; + font-family: "Myriadpro-Regular"; + box-sizing: border-box; + border: none; + text-align: center; + border-top-right-radius: 24px; + border-bottom-right-radius: 24px; + outline: none; +} + +._line_box { + background: #fff; + padding: 6px 0; + height: 48px; + position: relative; + width: 1px; +} + +._line { + width: 1px; + display: block; + height: 36px; + border-right: 1px solid #d2d2d2; + position: absolute; + top: 6px; + left: 0; +} + +.icon_search { + position: absolute; + right: 13px; + top: 14px; + width: 22px; +} + +/*END TIN NHAN*/ +/*BAO CAO HOC TAP*/ +.bcht { + padding: 30px 0 10px; +} + +.bcht .list-student { + max-height: calc(100vh - 320px); +} + +.student-info { + width: 350px; + margin-right: 20px; +} + +.student-info input { + width: 100%; + height: 44px; + border: none; + border-radius: 18px; + box-shadow: 0 1px 6px 0 rgb(21 27 38 / 15%); + padding: 0 10px; + box-sizing: border-box; + outline: none; + text-align: center; +} + +.student-info .avt-i { + width: 180px; + height: 180px; + border-radius: 90px; + box-sizing: border-box; + border: 3px solid #e7ae38; + overflow: hidden; + margin: 0 auto 20px; +} + +.student-info .avt-i img { + width: 100%; + height: 100%; +} + +.student-info .name { + text-align: center; + font-size: 24px; + margin: 0 0 10px; +} + +.email-gr { + margin: 0 0 20px; +} + +.email-gr img { + margin: 0 10px 0 0; +} + +.email-gr p { + font-size: 18px; + line-height: 24px; + font-family: "Myriadpro-Light"; + word-break: break-all; +} + +.box-bcht { + background: #fff; + border-radius: 20px; + padding: 20px; +} + +.box-bcht-top { + margin: 0 0 20px; +} + +.box-bcht-top h2 { + color: #414042; + font-size: 18px; + line-height: 40px; + font-family: "Myriadpro-Bold"; +} + +.btn-history-bcht { + color: #00b9b7; + background: #fff; + border: 2px solid #00b9b7; + display: block; + line-height: 40px; + height: 40px; + border-radius: 20px; + padding: 0 35px; + text-align: center; + cursor: pointer; + font-family: "Myriadpro-Semibold"; + font-size: 18px; +} + +.title-info { + background: #e6e7e8; + border-radius: 20px; + border: none; + height: 40px; + padding-left: 20px; + margin: 0 5px 0 0; + box-sizing: border-box; +} + +.title-info.dtb-title { + padding-left: 0; +} + +.title-info p { + font-family: "Myriadpro-Light"; + color: #000000; + line-height: 40px; + font-size: 18px; +} + +.title-info.dtb-title p { + font-family: "Myriadpro-Light"; + color: #000000; + line-height: 20px; + font-size: 18px; +} + +.score-info { + background: rgba(172, 241, 228, 0.86); + border-radius: 20px; + border: none; + height: 40px; + width: 84px; +} + +.score-info p { + font-family: "Myriadpro-Bold"; + color: #000000; + line-height: 40px; + font-size: 18px; + text-align: center; +} + +.title-info.dtb-title { + width: 120px; + height: auto; +} + +.h356 { + height: 356px; + width: 100%; + background: #ccc; + margin: 0 0 25px; +} + +.bcht .sunE-plan { + padding-left: 0; +} + +.time-h { + width: 80px; +} + +.time-h p { + font-family: "Myriadpro-Bold"; + font-size: 18px; + color: #000; + padding-left: 10px; +} + +.schedule-item { + margin: 0 0 10px; + padding: 0 0 10px; + border-bottom: 1px solid #b5b5b5; +} + +.schedule-item:last-child { + border-bottom: none; +} + +.score-d { + width: 80px; +} + +.schedule-i p { + font-family: "Myriadpro-Light"; + font-size: 18px; + color: #000; +} + +.score-d p { + font-family: "Myriadpro-Light"; + font-size: 18px; + color: #000; +} + +.width_chart_report_student { + width: 55%; +} + +.width_report_detail_student { + width: 45% !important; + margin-left: 25px; +} + +.flex_center_chart_report_student { + display: flex; + flex-direction: column; + align-items: center; +} + +.flex_self_chart_report_student { + align-self: flex-start; +} + +/*END BAO CAO HOC TAP*/ +/*PHIEU DIEM*/ +.phieudiem-box { + width: 286px; + height: 100px; + border-radius: 20px; + background: rgb(0 203 173 / 30%); + padding: 14px 30px; +} + +.phieudiem .diemdanh-item { + padding: 0; +} + +.phieudiem .diemdanh-item .phieudiem-info { + display: flex; + align-items: center; + justify-content: space-between; + padding-left: 3rem; +} +.phieudiem .diemdanh-item .phieudiem-info p { + font-family: "Myriadpro-Bold"; + font-size: 18px; + text-align: center; + line-height: 80px; +} + +.score-bg-blue { + width: 56px; + height: 56px; + border-radius: 28px; + background: rgb(0 203 173 / 30%); + padding: 10px; +} + +.score-bg-blue p { + font-family: "Myriadpro-Light"; + font-size: 14px; + line-height: 14px; + text-align: center; + color: #00a69c; +} + +.score-bg-blue span { + font-family: "Myriadpro-Bold"; + font-size: 24px; + text-align: center; + color: #00a69c; + line-height: 24px; + display: block; + text-align: center; +} + +.box-bg-gr { + width: 300px; + margin-right: 20px; +} + +.box-bg-content { + width: 100%; + background: #fff; + padding: 30px 20px; + border-radius: 20px; +} + +.box-bg-content.th { + margin-top: 34px; +} + +.menu-gr-right span.btn { + width: 100%; + display: block; + height: 56px; + border-radius: 28px; + text-align: center; + background: rgb(0 203 173 / 30%); + color: #231f20; + font-size: 18px; + line-height: 56px; + margin: 0 0 10px; + cursor: pointer; +} + +.menu-gr-right input[type="text"].btn::placeholder { + opacity: 0.3; +} + +.send-success.title span { + font-size: 24px; + font-family: "Myriadpro-SemiBold"; + color: #84c241; + line-height: 29px; +} + +.box-bg-content h2 { + font-size: 24px; + font-family: "Myriadpro-Bold"; + color: #48d0c8; + margin: 0 0 30px; +} + +.box-bg-content p { + font-size: 18px; + line-height: 18px; + font-family: "Myriadpro-SemiBold"; + color: #262626; + margin: 0 0 10px; +} + +.mt-10 { + margin-top: 10px; +} + +/*END PHIEU DIEM*/ +/*HDHT*/ +.huong-dan-hoc-tap.giaobai-support .box-giaotrinh-gr { + padding: 0 20px 0 60px; +} + +.box-select-info .text-left { + text-align: left; +} + +.btn-remove-item { + width: 50px; + height: 50px; + background-image: linear-gradient(to right, #00b97f, #00b9b7); + border-radius: 10px; + cursor: pointer; +} + +/*END HDHT*/ +/*CUSTOM ON OFF BUTTON*/ +.toggle-button-cover { + position: relative; + width: 52px; +} + +.knobs, +.layer { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +.button { + position: relative; + top: calc(50% - 15px); + width: 52px; + height: 20px; + margin: 0 auto 0 auto; +} + +.button.r, +.button.r .layer { + border-radius: 100px; +} + +.checkbox { + position: relative; + width: 100%; + height: 100%; + padding: 0; + margin: 0; + opacity: 0; + cursor: pointer; + z-index: 3; +} + +.knobs { + z-index: 2; +} + +.layer { + width: 100%; + background-color: #dddddd; + transition: 0.3s ease all; + z-index: 1; +} + +/* Button 1 */ +.btn-on-off .knobs:before { + content: ""; + position: absolute; + top: -5px; + left: -4px; + width: 30px; + height: 30px; + color: #fff; + font-size: 10px; + font-weight: bold; + text-align: center; + line-height: 1; + background-image: linear-gradient(to right, #c9c9c9, #989898, #6e6f6f); + border-radius: 50%; + transition: 0.3s cubic-bezier(0.18, 0.89, 0.35, 1.15) all; + border: 2px solid #fff; + box-sizing: border-box; +} + +.btn-on-off.active .checkbox:checked + .knobs:before { + left: 24px; + background-image: linear-gradient(to right, #fadb3a, #f5d030, #ebb318); +} + +.btn-on-off .knobs, +#button-1 .knobs:before, +.btn-on-off .layer { + transition: 0.3s ease all; +} + +/*END CUSTOM ON OFF BUTTON*/ +/*STUDENT*/ +.bg-main-img-student { + background-image: url("./../images/student/bg_student_index.png"); + background-repeat: no-repeat; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; + margin-top: -36px !important; + background-position: 0px -18px; + background-color: #f3ffff; +} + +/* .bg-main-student { + padding-bottom: 0 !important; +} */ + +.student-index { + padding: 7vh 20px 10px; +} + +.empty-leaderboard-custom { + display: flex; + align-items: center; + flex-direction: column; +} + +.empty-leaderboard-custom .title-empty { + font-weight: bold; + font-size: 18px; +} + +.list-teacher-sunE { + max-height: calc(100vh - 220px); + height: calc(100vh - 220px); + min-height: 33.5rem; + overflow: auto; + padding-right: 20px; + width: 210px; + overflow-x: hidden; + box-shadow: 1px 2px 4px 0 rgb(21 27 38 / 40%); +} + +.empty-payment-custom { + display: flex; + align-items: center; + flex-direction: column; +} + +.empty-payment-custom img { + margin-bottom: 10px; +} + +.empty-payment-custom span { + font-weight: bold; +} + +.box-item-wh { + width: 185px; + height: 170px; + box-sizing: border-box; + cursor: pointer; + overflow: hidden; + border-radius: 20px; + background: #fff; + padding: 10px 0px; + border: 3px solid #fff; + margin: 0 0 10px; + margin-left: 10px; + position: relative; +} + +.box-item-wh .img-thumb { + width: 100%; + height: 120px; + box-sizing: border-box; + overflow: hidden; + margin: 0 0 10px; + border-radius: 20px; +} + +.box-item-wh .img-thumb img { + width: 100%; + height: 100%; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + object-fit: cover; +} + +.box-item-wh.active { + border: 3px solid #00e0a1; +} + +.box-item-wh h2 { + color: #404041; + font-size: 18px; + line-height: 18px; + height: 18px; + font-family: "Myriadpro-Bold"; + text-align: center; + width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + padding: 0 10px; +} + +.box-item-wh .name-box { + color: #404041; + font-size: 18px; + font-family: "Myriadpro-Bold"; + text-align: center; + width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + position: absolute; + background: #fff; + padding: 10px; + height: 33px; + bottom: 0; +} + +/* Shedu Item */ +/* .shedu-item-container { + width: 33rem; +} */ + +.shedu-mo-item { + width: 100%; + height: 100%; + box-sizing: border-box; + border-radius: 20px; + background: #fff; +} + +.shedu-first-item { + padding: 25px 25px 45px; + box-sizing: border-box; + border-radius: 20px; + background: #fff; + margin: 0 0 20px; +} + +.shedu-mo-item p { + text-align: center; + font-size: 24px; + line-height: 24px; + font-family: "Myriadpro-SemiBold"; + color: #606060; + margin: 10px 0; +} + +.shedu-first-item .img-shedu { + width: 148px; + height: 148px; + border-radius: 50%; + background: #ccedeb; + margin: 0 auto 20px; + overflow: hidden; +} + +.shedu-first-item h2 { + color: #00bd9d; + text-align: center; + font-size: 30px; + line-height: 32px; + font-family: "Myriadpro-SemiBold"; + padding: 0; + margin: 0 0 5px; +} + +.shedu-first-item h3 { + color: #404041; + text-align: center; + font-size: 18px; + line-height: 18px; + font-family: "Myriadpro-SemiBold"; + padding: 0; + margin: 0 0 5px; +} + +.shedu-first-item p { + color: #404041; + text-align: center; + font-size: 18px; + line-height: 18px; + font-family: "Myriadpro-Light"; + padding: 0; + margin: 0 0 5px; +} + +.shedu-list-more-gr { + padding: 25px; + box-sizing: border-box; + border-radius: 20px; + background: #fff; +} + +.shedu-more-item .img { + width: 68px; + height: 68px; + border-radius: 50%; + background: #ccedeb; + margin: 0 auto 10px; + overflow: hidden; +} + +.shedu-more-item p { + color: #6d6e70; + text-align: center; + font-size: 16px; + line-height: 18px; + font-family: "Myriadpro-SemiBold"; + padding: 0 10px; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.bg-ab { + position: absolute; + top: 0; + left: 0; + background: rgb(0 0 0 / 0.3); + width: 68px; + height: 68px; +} + +.lb-qh-nn span { + font-size: 14px; + padding: 3px 15px; + border-radius: 11px; + line-height: 21px; +} + +.lb-qh-nn .qh { + color: #e53535; + border: 1px solid #e53535; + margin-right: 10px; +} + +.btn-default:hover { + background: #00c0b4; + color: #ffffff; + border-color: #00c0b4; +} + +.btn-line-blue:hover { + background: #00c0b4; + color: #ffffff; +} + +.lb-qh-nn .nn { + color: #fff; + background: #e53535; + border: 1px solid #e53535; + margin-right: 10px; + cursor: pointer; +} + +.lb-qh-nn .over { + color: #bc4f4a; + border: 1px solid #bc4f4a; + margin-right: 10px; + font-weight: 700; +} + +.lb-qh-nn .hn { + color: #faaf40; + border: 1px solid #faaf40; + margin-right: 10px; +} + +.lb-qh-nn .sc { + color: #fff; + background: #84c241; + border: 1px solid #84c241; + margin-right: 10px; + margin-left: 1rem !important; +} + +.lb-qh-nn .sc_waiting { + color: #fff; + background: #f7b32b; + border: 1px solid #f7b32b; + margin-right: 10px; +} + +.student-baitap-content { + background: #fff; + padding: 20px 30px; + border-radius: 20px; + max-height: calc(100vh - 200px); + margin: 0 0 15px; + overflow: auto; +} + +.no-item p { + text-align: center; + font-size: 24px; + line-height: 24px; + font-family: "Myriadpro-SemiBold"; + color: #606060; + margin: 10px 0; +} + +.student-baitap-content .sunE-giaotrinh-item { + padding-bottom: 10px; + border-bottom: 1px solid #707070; +} + +.star { + margin-right: 10px; +} + +.star img { + width: 40px; +} + +.map-skill span { + width: 200px; + height: 44px; + line-height: 44px; + color: #040505; + font-size: 18px; + font-family: "Myriadpro-Regular"; + background: #fff; + display: block; + border-radius: 20px; + text-align: center; + margin-left: 10px; +} + +.disable-link { + pointer-events: none; +} + +.chart-circle-report-class { + transform: rotate(-90deg); + position: absolute; + /* inset: 0px; */ + height: 180px; + width: 170px; + margin-left: 145px; +} + +.shadow-chart-circle { + -webkit-filter: drop-shadow(0px 1px 1px #70707070); + filter: drop-shadow(0px 1px 1px #70707070); + /* Similar syntax to box-shadow */ +} + +.map-skill img { + position: absolute; + top: -25px; + left: -10px; + width: 60px; +} + +.pink-ab { + position: absolute; + bottom: 20px; + right: 15px; +} + +.pink-ab .__percent_unit { + background: rgb(216, 20, 96); + padding: 5px; + border-radius: 50%; + color: rgb(255, 255, 255); + height: 45px; + width: 45px; + border: 6px solid #fff; + display: flex; + justify-content: center; + align-items: center; +} + +.pink-ab img { + height: 45px; + width: 45px; +} + +.student_exercise_item { + background: #fff; + border-radius: 20px; + padding: 15px 30px 20px 15px; + box-sizing: border-box; + margin: 0 0 20px; + width: 95%; +} + +.student_exercise_item .level { + margin: 0 0 30px; +} + +.student_exercise_item .level span { + padding: 8px 35px; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); + font-size: 24px; + line-height: 24px; + font-family: "Myriadpro-Bold"; + color: #fff; + border-radius: 20px; + margin: 0 0 0 -10px; +} + +.student_exercise_item_info { + padding-bottom: 10px; + border-bottom: 1px solid #656565; +} + +.student_exercise_item_info h2 { + font-size: 18px; + line-height: 25px; + font-family: "Myriadpro-Bold"; + color: #040505; +} + +.student_exercise_item_info p { + font-size: 18px; + line-height: 25px; + font-family: "Myriadpro-Regular"; + color: #040505; +} + +.thumb-im { + position: absolute; + right: -53px; + top: 0; +} + +.student_exercise { + padding: 0 80px 0 30px; + max-height: calc(100vh - 120px); + overflow: auto; +} + +.history { + margin: 10px 10px 0; +} + +.history p { + color: #ad0a22; + font-size: 18px; + line-height: 22px; + font-family: "Myriadpro-Bold"; +} + +.scre { + margin-right: 20px; +} + +.kh-title { + margin: 0 0 20px; +} + +.kh-title h2 { + color: #000; + font-size: 24px; + font-family: "Myriadpro-Bold"; +} + +.student-khht .sunE-calendar { +} + +.sunE-plan.khht-tkb, +.sunE-plan.khht-cn { + padding-left: 0; +} + +.khht-cn .plan-item { + border-left: 20px solid #8dc63f; +} + +.khht-tkb .check-work { + color: #414042; + font-family: "Myriadpro-Bold"; + line-height: 24px; +} + +.khht-tkb .tiem { + color: #939598; + font-family: "Myriadpro-Bold"; + line-height: 24px; +} + +.student-khht .sunE-calendar { + margin: 0 0 40px; +} + +.success span.flex-1 { + color: #84c241; + font-size: 12px; + font-family: "Myriadpro-Bold"; + line-height: 30px; + padding-left: 5px; + background: none; +} + +.sunE-container-box.student-khht { + padding: 20px 20px 10px; +} + +.student .w60 { + width: 96px; +} + +.student .tkb-item { + width: 96px; +} + +/*END STUDENT*/ +/*CAI DAT*/ +.box-setting-custom { + background: #fff; + border-radius: 20px; + padding: 20px; + margin: 0 0 10px; +} + +.setting-title-blue { + color: #00bbb5; + font-size: 24px; + font-family: "Myriadpro-SemiBold"; + line-height: 32px; + margin: 0 0 15px; +} + +.setting-on-off-box { + margin: 0 0 1.2rem; +} + +.setting-on-off-box p { + color: #000; + font-size: 18px; + font-family: "Myriadpro-Semibold"; + line-height: 24px; + margin: 0; +} + +.setting-on-off-box span.btn { + color: #00bbb5; + font-size: 18px; + font-family: "Myriadpro-Semibold"; + line-height: 24px; + margin: 0; + cursor: pointer; +} + +.select-language { + color: #00bbb5; + font-size: 18px; + font-family: "Myriadpro-Semibold"; + line-height: 24px; + margin: 0; + text-decoration: underline; + cursor: pointer; + border: none; + outline: none; + background: #fff; + -webkit-appearance: none; + -moz-appearance: none; + text-overflow: ""; +} + +.select-language::-ms-expand { + display: none; +} + +.setting-on-off-box input[type="number"] { + width: 55px; + height: 28px; + border-radius: 10px; + outline: none; + box-sizing: border-box; + text-align: center; + color: #c2c2c2; + border: 1px solid #c2c2c2; +} + +.setting-on-off-box input[type="number"].active { + color: #f7991f; + border: 1px solid #00a69c; +} + +.setting-on-off-box input[type="number"]::-webkit-inner-spin-button, +.setting-on-off-box input[type="number"]::-webkit-outer-spin-button { + opacity: 1; +} + +.w80 { + width: 80px; +} + +.ph10 { + padding: 0 10px; +} + +.mt-17 { + margin-top: 17px; +} + +/*END CAI DAT*/ + +/*STUDENT MORE*/ +.mt-3 { + margin-top: 3px; +} + +.mt-9 { + margin-top: 9px; +} + +.student_class.class-index-box .class-index-box-img { + width: 182px; +} + +.student_class.class-index-box { + width: calc(100% - 280px); +} + +.student-class-no-item p { + color: #0d0e0e; + font-size: 24px; + line-height: 26px; + font-family: "Myriadpro-Semibold"; + padding-top: 20px; +} + +.sunE-student-class-homework { + padding: 20px 30px 20px 0; + max-height: calc(100vh - 150px); + overflow: auto; +} + +.sunE-student-class-homework .sunE-giaotrinh-item { + padding: 10px 20px; + border-radius: 20px; + background: #fff; + margin: 0 0 15px; +} + +.ico-checked { + position: absolute; + top: 5px; + left: 0; +} + +.progress { + position: absolute; + right: 20px; + top: -10px; +} + +.progress span { + display: block; + width: 74px; + height: 22px; + line-height: 22px; + color: #fff; + border-radius: 5px; + text-align: center; + font-size: 13px; + font-family: "Myriadpro-Bold"; + box-sizing: border-box; +} + +.danger span { + background: #dc4630; +} + +.warning span { + background: #ed8a22; +} + +.success span { + background: #36ae4a; +} + +.w380 { + width: 380px; + margin: 0 auto 30px; +} + +.show-hide-password { + position: absolute; + right: 15px; + top: 12px; + cursor: pointer; +} + +.thanhtich-container { + padding: 30px 0 10px; +} + +.list-menu-custom.student { + width: 35%; +} + +.list-menu-custom.student .btn-gr { + height: 70px; +} + +.list-menu-custom.student .btn-gr.active { + background-image: linear-gradient(to left, #00e1a0, #00b9b7); +} + +.list-menu-custom.student .btn-gr-text p { + line-height: 70px; +} + +.thanhtich-online-box { + width: 100%; + box-sizing: border-box; + height: calc(100vh - 17vh); + overflow: auto; + padding: 0 10px 0; +} + +.bg-line-op { + background-image: linear-gradient(to bottom, #258c96, #a6ffd9); + border-radius: 20px; + padding-bottom: 10px; +} + +.thanhtich-box-content { + padding: 0 10px 0 20px; +} + +.width-height-thanhtich-box-content { + width: 65%; +} + +.box-skill-process { + padding: 60px 10px 20px; +} + +.mte-gr { + background: #fff; + height: 54px; + width: 125px; + border-radius: 27px; + text-align: center; + padding-left: 30px; +} + +.mte-gr .mte-thumb { + position: absolute; + width: 65px; + height: 65px; + display: flex; + justify-content: center; + align-items: center; + background: #d1d3d4; + border: 5px solid #fff; + border-radius: 50%; + box-sizing: border-box; + top: -5px; + left: -15px; +} + +.mte-gr h2 { + line-height: 28px; + color: #2b3990; + font-size: 29px; + font-family: "Myriadpro-Bold"; + margin: 0; + padding: 0; +} + +.mte-gr p { + line-height: 11px; + color: #2b3990; + font-size: 10px; + font-family: "Myriadpro-Light"; + margin: 0; + padding: 0; +} + +.ml-15 { + margin-left: 15px; +} + +.skill-process-list { + margin: 30px 0 0; + padding: 20px 30px 10px 50px; + background: rgba(0, 0, 0, 0.2); + border-radius: 20px; +} + +.skill-process-item p.title { + color: #fff; + line-height: 24px; + font-size: 18px; + font-family: "Myriadpro-Regular"; + text-align: center; +} + +.skill-process-item { + margin: 0 0 20px; +} + +.process-100 { + width: 100%; + height: 30px; + border-radius: 15px; + box-sizing: border-box; + background: #fff; + padding: 5px 5px 5px 42px; +} + +.process-due { + background-image: linear-gradient(to bottom, #febe3f, #ed228c); + height: 20px; + box-sizing: border-box; + border-top-right-radius: 10px; + border-bottom-right-radius: 10px; +} + +.process-thumb { + position: absolute; + top: -24px; + left: -20px; +} + +.sco { + width: 96px; + height: 30px; + border-radius: 15px; + box-sizing: border-box; + background: #fff; + padding: 0 5px 0 12px; + margin: 24px 0 0 10px; +} + +.sco .slp { + color: #2b3990; + line-height: 30px; + font-size: 24px; + font-family: "Myriadpro-Bold"; +} + +.sco .slp-top { + line-height: 10px; + font-size: 12px; + font-family: "Myriadpro-Bold"; + top: -10px; + left: 3px; +} + +.sco .slp-top.down { + color: #be1e2d; +} + +.sco .slp-top.up { + color: #8dc63f; +} + +.thanhtich-offline-box { + background: #fff; + border-radius: 20px; + padding: 20px; +} + +.no-item-2 p { + text-align: center; + font-size: 24px; + line-height: 24px; + font-family: "Myriadpro-Light"; + color: #231f20; + margin: 10px 0; +} + +.title-k { + font-size: 24px; + line-height: 24px; + font-family: "Myriadpro-SemiBold"; + color: #00a79d; + margin: 0 0 20px; + text-transform: uppercase; +} + +.thanhtich-offline-content { + padding: 20px 15px; +} + +.gr-k p { + text-align: left; + font-size: 18px; + line-height: 65px; + font-family: "Myriadpro-Light"; + color: #231f20; + margin: 0; + padding: 0; +} + +.gr-k span { + display: block; + font-size: 24px; + line-height: 65px; + font-family: "Myriadpro-Bold"; + color: #00a79d; + margin: 0; + padding: 0; +} + +.gr-r { + margin: 0 0 10px; +} + +.gr-r p { + text-align: left; + font-size: 18px; + line-height: 24px; + font-family: "Myriadpro-Regular"; + color: #231f20; + margin: 0; + padding: 0; +} + +.gr-r span { + display: block; + font-size: 24px; + line-height: 28px; + font-family: "Myriadpro-SemiBold"; + color: #00a79d; + margin: 0; + padding: 0; +} + +.mb-30 { + margin: 0 0 30px; +} + +.gr-k span.btn { + cursor: pointer; + text-decoration: underline; +} + +.sub-title-18 { + display: block; + font-size: 18px; + line-height: 24px; + font-family: "Myriadpro-SemiBold"; + color: #231f20; + margin: 0 0 10px; + padding: 0; +} + +.bxh-info-student-box { + background: rgba(172, 241, 228, 0.76); + border-radius: 20px; + padding: 20px; + margin: 0 0 15px; +} + +.img-avatar-k { + width: 100px; + height: 100px; + border-radius: 50px; + border: 3px solid #fff; + overflow: hidden; + margin-right: 20px; +} + +.img-avatar-k img { + width: 100%; + height: 100%; +} + +.bxh-info-student-box h3 { + font-size: 24px; + line-height: 28px; + font-family: "Myriadpro-Regular"; + color: #231f20; + margin: 0 0 10px; + padding: 0; +} + +.f-18 { + font-size: 18px; + line-height: 24px; + color: #231f20; +} + +p.text-center.f-18 { + margin: 20px 0; +} + +.box-top-k { + background: #fff; + border-radius: 20px; + padding: 10px 20px; +} + +.avt-top-k { + margin: 0 auto; +} + +.avt-top-k .ico_avt { + position: absolute; +} + +.avt-top-k img { + z-index: 9; +} + +.top-k-score { + display: block; + width: 80px; + height: 28px; + text-align: center; + font-size: 16px; + line-height: 28px; + font-family: "Myriadpro-Bold"; + border-radius: 14px; + margin: 0 auto 15px; +} + +.top-k-item.s .avt-top-k .ico_avt, +.top-k-item.b .avt-top-k .ico_avt { + top: 18px; + left: 28px; + width: 62px; + height: 62px; + border-radius: 31px; + z-index: 8; +} + +.top-k-item.s, +.top-k-item.b { + width: 120px; +} + +.top-k-item.v { + width: 170px; + margin: 0 15px; +} + +.top-k-item.v .avt-top-k .ico_avt { + top: 38px; + left: 46px; + width: 78px; + height: 78px; + border-radius: 39px; + z-index: 8; +} + +.top-k-item.s .top-k-score { + background: #84b0ff; +} + +.top-k-item.v .top-k-score { + background-image: linear-gradient(45deg, #f7d200, #f7d200, #f7ba00, #f7a100); +} + +.top-k-item.b .top-k-score { + background-image: linear-gradient( + to right, + #b8b8b8, + #cfcfcf, + #ebeaea, + #c0c0c0, + #ebeaea + ); +} + +.top-k-item p { + text-align: center; +} + +.student_bxh_list { + max-height: calc(100vh - 400px); + overflow: auto; + padding-right: 10px; +} + +.student_bxh_list .item-student .stt { + line-height: 54px; + font-size: 16px; + font-family: "Myriadpro-Bold"; + width: 30px; +} + +.student_bxh_list .item-student { + background: #fff; + padding: 10px 20px; + border-radius: 20px; + margin: 0 0 10px; +} + +.student_bxh_list .item-student .item-student-img { + width: 54px; + height: 54px; + border-radius: 27px; + background: #ccc; + overflow: hidden; + border: 2px solid #e9af38; +} + +.student_bxh_list .item-student-name p { + line-height: 54px; + font-size: 16px; +} + +.thanhtich-bxh-box { + margin: 0 0 20px; +} + +.student_bxh_list::-webkit-scrollbar { + width: 8px; +} + +/* Track */ +.student_bxh_list::-webkit-scrollbar-track { + background: #bbcbc3; + border-radius: 4px; +} + +/* Handle */ +.student_bxh_list::-webkit-scrollbar-thumb { + background: #e8e803; + border-radius: 4px; +} + +.box-shadow-3 { + box-shadow: 2px 3px 4px 0 rgb(21 27 38 / 15%); +} + +.his-hd { + width: 100%; + background: #fff; + border-radius: 20px; + height: calc(100vh - 160px); + padding: 20px 10px 20px 30px; + /* overflow: auto; */ +} + +.his-hd .scrollbar-custom { + height: calc(100vh - 200px); + overflow: auto; + padding-right: 10px; +} + +.view_height_scroll_assessment_log_learning .scrollbar-custom { + height: calc(100vh - 180px); +} + +.b-26-black { + line-height: 32px; + font-size: 26px; + font-family: "Myriadpro-Bold"; + margin: 15px 0 10px; +} + +.his-item { + margin: 0 0 10px; + border-bottom: 1px solid #b5b5b5; +} + +.his-item p { + line-height: 31px; + font-size: 18px; + font-family: "Myriadpro-Light"; + padding: 0px 5px; + white-space: normal; + word-break: break-word; +} + +.his-item p.hours { + font-family: "Myriadpro-Bold"; + width: 100px; +} + +.tv-thumb { + width: 81px; + height: 81px; + border-radius: 20px; + border: 5px solid #fff; + overflow: hidden; + position: absolute; + left: -15px; + top: -10px; +} + +.tv-thumb img { + width: 100%; + height: 100%; +} + +.tv-item { + background: #fff; + border-radius: 20px; + width: 100%; + height: 62px; + padding: 0 0 0 100px; + margin: 0 0 30px !important; +} + +.tv-item h2 { + line-height: 62px; + font-size: 18px; + font-family: "Myriadpro-Bold"; + color: #221f1f; +} + +.voice { + width: 60px; +} + +.tv-score span { + width: 36px; + height: 36px; + border-radius: 18px; + font-size: 25px; + font-family: "Myriadpro-Bold"; + background-image: linear-gradient(to right, #58be92, #00b7b5); + text-align: center; + margin: 0 10px 0 0; + color: #fff; +} + +.tuvung-container { + padding: 30px 0 0; +} + +.tuvung_list { + max-height: calc(100vh - 200px); + padding-top: 10px; + overflow: auto; +} + +.box-tv-info h2 { + color: #221f1f; + font-size: 18px; + margin: 0 0 15px; + font-family: "Myriadpro-Regular"; +} + +.box-tv-info p, +.box-tv-info span { + color: #00a69c; + font-size: 16px; + font-family: "Myriadpro-Regular"; +} + +.tuvung .box-giaotrinh-gr { + background: #fff; + border-radius: 20px; + height: 100px; + display: flex; + justify-content: center; + align-items: center; + margin: 0 0 20px 20px; + cursor: pointer; + box-sizing: border-box; + padding: 0 15px 0 80px; + width: 100%; +} + +.tuvung .box-giaotrinh-gr.active { + background: #c3fdf3; +} + +.tuvung .box-giaotrinh-gr .thumb { + position: absolute; + top: 14px; + left: -20px; + display: flex; + justify-content: center; + align-items: center; + background: #ccedeb; + border: 3px solid #fff; + border-radius: 50%; + width: 70px; + height: 70px; + box-shadow: 0 1px 8px 0 rgb(21 27 38 / 24%); +} + +.bold { + font-family: "Myriadpro-Bold" !important; +} + +.sunE-giaotrinh-list { + max-height: calc(100vh - 360px); + overflow: auto; +} + +.ov-auto { + overflow: auto; + scroll-behavior: thin; + margin: 0 0 30px; + padding-bottom: 10px; +} + +.tv-giaotrinh-item { + height: 150px; + width: 100%; + /* width: 310px; */ + border-radius: 20px; + padding: 0 10px; + margin: 0 20px 10px 0; + cursor: pointer; +} + +.tv-giaotrinh-item .img { + height: 94px; + border-radius: 20px; + overflow: hidden; + opacity: 0.5; +} + +.tv-giaotrinh-item.active { + background: #fff; + width: 100%; +} + +.tv-giaotrinh-item.active .img { + width: 100%; + height: 94px; + opacity: 1; +} + +.tv-giaotrinh-item .img img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.sunE-container-box.tuvung { + padding: 20px; +} + +.tv-giaotrinh-item .flex-1 { + padding: 0 20px; +} + +.tv-giaotrinh-item p { + color: #00bbb6; + font-size: 17px; + font-family: "Myriadpro-Bold"; +} + +.bangdiem-menu-gr span { + color: #000000; + font-size: 24px; + font-family: "Myriadpro-Bold"; + padding: 0 0 5px; + margin: 0 20px; + cursor: pointer; +} + +.bangdiem-menu-gr { + margin: 0 0 30px; +} + +.bangdiem-menu-gr span.active { + border-bottom: 2px solid #f9b038; +} + +.table-box-content table { + width: 100%; + border-collapse: collapse; + border-radius: 20px !important; + border-style: hidden; + /* hide standard table (collapsed) border */ + box-shadow: 0 0 0 1px #58595b; + /* this draws the table border */ +} + +.table-box-content th, +.table-box-content td { + padding: 15px; + text-align: center; + font-size: 18px; + font-family: "Myriadpro-Regular"; + color: #58595b; + border: 1px solid #58595b; +} + +.box-danhhieu-process { + background: #fff; + padding: 10px; + border-radius: 20px; + margin: 0 10px 30px 10px; +} + +.top-t { + background-image: linear-gradient(to right, #00e2a0, #00b9b7); + height: 46px; + border-radius: 23px; + padding: 0 30px; + margin: 0 0 20px; + box-sizing: border-box; +} + +.top-t p { + font-size: 18px; + font-family: "Myriadpro-Regular"; + color: #fff; + line-height: 46px; +} + +.process-k, +.process-info-k { + display: flex; +} + +.circle-k { + width: 28px; + height: 28px; + background: #d1d3d4; + border-radius: 14px; + margin-left: -2px; + z-index: 9; + overflow: hidden; +} + +.process-line { + background: #00e2a0; + width: 100%; + height: 100%; +} + +.process-h .circle-k { + width: 12px; + height: 12px; + background: #d1d3d4; + border-radius: 6px; + margin-top: -1px; + z-index: 9; + overflow: hidden; +} + +.circle-k.active { + background: #00e2a0; +} + +.line-k { + width: 51px; + height: 14px; + margin-top: 7px; + background: #d1d3d4; + margin-left: -2px; + z-index: 8; +} + +.line-k.active { + background: #00e2a0; +} + +.process-h .line-k { + width: 4px; + height: 51px; + background: #d1d3d4; + margin-top: -1px; + z-index: 8; + margin-left: 2px; +} + +.process-h .line-k.active { + background: #00e2a0; +} + +.process-info-k { + margin-top: 10px; +} + +.process-info-k .space { + width: 79px; + text-align: center; +} + +.process-info-k .space p { + font-size: 18px; + font-family: "Myriadpro-Light"; + line-height: 18px; +} + +.process-info-h .space { + height: 59px; + opacity: 0.5; +} + +.process-info-h .space.active { + opacity: 1; +} + +.process-info-h .space p { + font-size: 18px; + font-family: "Myriadpro-Light"; + line-height: 24px; + margin-right: 10px; +} + +.top-h { + margin: 30px 0 10px; +} + +.top-h p { + font-size: 18px; + font-family: "Myriadpro-Light"; + line-height: 24px; +} + +.process-info-h .space .scoe { + padding-right: 8px; +} + +.process-hz { + padding: 0 30px; +} + +.box-nhatkyhoctap-graph, +.box-nhatkyhoatdong { + background: #fff; + border-radius: 20px; + padding: 10px; + margin: 0 10px 30px 10px; +} + +.box-nhatkyhoctap-graph, +.box-nhatkyhoatdong:last-child { + margin: 30px 10px 0 10px; +} + +.filter-box-nhatkyhoctap-graph { + width: 150px !important; +} + +.fix_text_cut_chart::after { + background: none !important; +} +.box-s { + padding: 0 5px 0 30px; +} + +.box-s span { + display: block; + height: 36px; + margin-top: 5px; + border-radius: 18px; + background: #fff; + color: #00cbad; + font-size: 18px; + font-family: "Myriadpro-Light"; + line-height: 36px; + padding: 0 5px 0 40px; +} + +.box-s img { + position: absolute; + top: 5px; + left: 5px; +} + +.box-nhatkyhoctap-graph .bangdiem-menu-gr span { + font-size: 18px; + text-align: center; + margin: 0; + font-family: "Myriadpro-Regular"; +} + +.line-active { + width: 80px; + height: 2px; + background: #f9b038; + margin: 0 auto; + display: none; +} + +.btn-gr-menu { + cursor: pointer; +} + +.btn-gr-menu.active .line-active { + display: block; +} + +.box-nhatkyhoctap-graph .bangdiem-menu-gr .btn-gr-menu.active span { + font-family: "Myriadpro-Bold"; +} + +.box-nhatkyhoctap-graph .bangdiem-menu-gr span.active { + border-bottom: none; +} + +.box-diem .top-o { + background-image: linear-gradient(to right, #00e2a0, #00b9b7); + border-radius: 28px; + height: 56px; + margin: 0 0 20px; +} + +.box-diem .top-o p { + font-size: 18px; + line-height: 20px; + text-align: center; + margin: 0; + font-family: "Myriadpro-Light"; + color: #fff; +} + +.box-diem h2 { + font-size: 45px; + text-align: center; + margin: 0; + font-family: "Myriadpro-Bold"; + color: #00c0b2; +} + +.box-diem { + background: #fff; + border-radius: 20px; + padding: 10px; + margin: 0 20px; +} + +.box-diem-gr { + margin: 0 10px 30px 10px; +} + +.box-nhatkyhoatdong .box-s span { + padding: 0 20px; + cursor: pointer; + box-sizing: border-box; +} + +.his-item-gr p.time-hs { + line-height: 31px; + font-size: 24px; + font-family: "Myriadpro-Light"; +} + +.box-nhatkyhoatdong .his-item .hours { + width: 80px; + margin: 10px; +} + +.box-nhatkyhoatdong .his-hd { + height: auto; + min-height: 400px; +} + +/*END STUDENT MORE*/ +/*MORE CSS*/ +.loading { + position: fixed; + display: flex; + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; + background: rgba(0, 0, 0, 0.48); + z-index: 9999; + align-items: center; + justify-content: center; +} + +/* Loading Side */ +/* .loading-side { + position: fixed; + display: flex; + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; + background: rgba(0, 0, 0, 0.48); + z-index: 9999; + align-items: center; + justify-content: center; +} */ + +.loader { + border: 4px solid #f1f1f1; + border-radius: 50%; + border-top: 4px solid #00b9b7; + width: 40px; + height: 40px; + -webkit-animation: spin 2s linear infinite; + /* Safari */ + animation: spin 2s linear infinite; +} + +/* Safari */ +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + } + + 100% { + -webkit-transform: rotate(360deg); + } +} + +@keyframes spin { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} + +.ico_dropdown { + position: absolute; + right: 5px; + top: 5px; +} + +.hide { + display: none; +} + +.err .select-styled { + border: 2px solid #e22028; +} + +.custom-select-content::after { + content: "\f107"; + font-family: FontAwesome; + position: absolute; + top: 0; + right: 0; + width: 44px; + height: 44px; + text-align: center; + font-size: 28px; + line-height: 44px; + color: #636363; + background-color: #fff; + pointer-events: none; + border-radius: 22px; +} + +.custom-select-content.err { + border: 2px solid #e22028; + border-radius: 22px; +} + +.custom-select { + height: 44px; + width: 100%; + line-height: 44px; + font-size: 16px; + box-sizing: border-box; + padding-left: 60px; + border-radius: 22px; + outline: none; + flex: 1; + cursor: pointer; + display: flex; + border: 1px solid #fff; + box-shadow: 0 1px 15px 0 rgb(21 27 38 / 15%); +} + +.custom-select option { + color: #dedede; +} + +.custom-select::after { + content: ""; + position: absolute; + top: 0; + right: 0; + padding: 0 1em; + background: #34495e; + cursor: pointer; + pointer-events: none; + -webkit-transition: 0.25s all ease; + -o-transition: 0.25s all ease; + transition: 0.25s all ease; +} + +.custom-select option[rel="hide"] { + display: none; +} + +.react-datepicker-wrapper { + width: 100%; +} + +.gr-gender.err .sunE-male-female { + border: 2px solid #e22028; +} + +.btn-back { + font-family: "Myriadpro-Bold"; +} + +.btn_click_link { + font-family: "Myriadpro-Bold"; + color: #3e3e3d; + text-decoration: underline; + cursor: pointer; + font-size: 16px; +} + +.menu-item .ico_active { + display: none; +} + +.menu-item.active img.ico_default { + display: none; +} + +.menu-item.active img.ico_active { + display: block; +} + +.form-sunE-button.btn-mr-custom { + margin: 0; +} + +.content-flex-end { + align-items: flex-end; + display: flex; +} + +.sunE-create-class-content { + padding-top: 40px; +} + +.apdung-custom { + background: #fff; + border-radius: 29px; + padding: 0 10px; +} + +.apdung.apdung-custom label { + margin: 15px 0 15px 15px; + padding: 0 0 0 15px; +} + +.apdung.apdung-custom .text-blue-main { + padding-left: 20px; + padding-right: 20px; +} + +.apdung.apdung-custom .flex-1 img { + margin: 18px 0 0 10px; + width: 12px; +} + +.select-custom-bg select { + width: 100%; + height: 40px; + border-radius: 20px; + border: none; + outline: none; + text-align-last: center; + box-shadow: 0 1px 8px 0 rgba(21, 27, 38, 0.15); + font-size: 16px; + font-family: "Myriadpro-SemiBold"; + padding-right: 40px; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + /* Remove default arrow */ + color: #fff; + background: url("./../images/icon/ico_dropdown_border_white.png") 98% / 30px + no-repeat #00ceab; + /* Add custom arrow */ +} + +.select-custom-bg select::-ms-expand { + display: none; + /* remove default arrow on ie10 and ie11 */ +} + +.select-custom-bg.err select { + border: 2px solid #e22028; +} + +.select-custom-bg select option { + text-align: center; +} + +.text-left select { + text-align-last: left; + padding-left: 40px; +} + +.sunE-calendar .react-datepicker__day--selected { + background: #fff !important; + border: 2px solid #00a79d !important; + border-radius: 50% !important; + color: #404041 !important; + padding-top: 3px !important; + background-image: linear-gradient(to right, #fff, #fff); +} + +.sunE-calendar .react-datepicker__day--today { + border-radius: 25px !important; + background-image: linear-gradient(to right, #00e1a0, #00b9b7) !important; + color: #fff !important; + border: none !important; +} + +.sunE-calendar .react-datepicker__day--keyboard-selected, +.sunE-calendar .react-datepicker__month-text--keyboard-selected, +.sunE-calendar .react-datepicker__quarter-text--keyboard-selected, +.sunE-calendar .react-datepicker__year-text--keyboard-selected { + background: #fff !important; + color: black !important; +} + +.buy-now { + margin: 20px 0; +} + +.sunE-main-title .form-sunE-button.btn-select-year { + margin-right: 10px; +} + +.btn-select-year button { + padding: 0 65px; +} + +.btn-select-year .ico_left { + position: absolute; + top: 8px; + left: 10px; + cursor: pointer; +} + +.btn-select-year .ico_right { + position: absolute; + top: 8px; + right: 10px; + cursor: pointer; +} + +.react-datepicker-popper { + z-index: 12 !important; +} + +.gt_list_hei { + max-height: calc(100vh - 360px); + padding: 0 15px; + overflow: auto; +} + +.no-gt p { + font-size: 18px; + margin: 20px 0 0; +} + +.mg-20 { + margin: 20px 0 !important; +} + +.custom-select-no-bg .arrow { + position: relative; + z-index: 1000; + width: 15px; + height: auto; + left: 94.8%; + top: 1px; +} + +.custom-select-no-bg .arrow.rotate180 { + transform: rotate(180deg); +} + +.custom-select-no-bg .select-styled { + width: 100%; + height: 44px; + border-radius: 22px; + border: none; + outline: none; + text-align-last: left; + box-shadow: 0 1px 8px 0 rgb(21 27 38 / 15%); + font-size: 16px; + font-family: "Myriadpro-Regular"; + padding-right: 40px; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: url(./../images/icon/ico_dropdown_s.png) 96% / 20px no-repeat #fff; + color: #424242; +} + +.custom-select-no-bg .select-styled.active { + background: url(./../images/icon/ico_dropup.png) 96% / 20px no-repeat #fff; +} + +.custom-select-no-bg.err .select-styled { + border: 2px solid #e22028; +} + +.custom-select-no-bg .select-styled { + z-index: 10; + text-align: left; + padding-left: 60px; +} + +.custom-select-no-bg .select-styled:after { + display: none; +} + +.custom-select-no-bg .select { + cursor: pointer; + display: inline-block; + position: relative; + font-size: 16px; + color: #424242; + width: 100%; + height: 44px; + line-height: 44px; + border-radius: 22px; + border: none; + background: #fff; +} + +.select-custom-bg .select-options { + padding: 20px 40px 0; + top: 20px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} + +.ico_icon_select { + position: absolute; + top: 12px; + left: 16px; + z-index: 10; +} + +.select-custom-bg .select { + width: 100%; + height: 40px; + line-height: 40px; + border-radius: 20px; +} + +.select-custom-bg.err .select-styled { + border: 2px solid #e22028; +} + +.select-custom-bg .select-styled { + width: 100%; + height: 40px; + border-radius: 20px; + font-size: 16px; + line-height: 40px; +} + +.select-custom-bg .select-styled:after { + top: 5px; + right: 6px; +} + +.select-custom-bg .select-options { + border-radius: 20px; +} + +.select-custom-bg .select-styled { + z-index: 10; + text-align: left; + padding-left: 20px; +} + +.select-custom-bg.text-center .select-styled { + text-align: center; + padding-left: 0; +} + +.select-custom-bg .select-options { + display: none; + position: absolute; + padding: 20px 40px 0; + top: 20px; + right: 0; + left: 0; + z-index: 9; + margin: 0; + list-style: none; + background-color: #fff; + border-radius: 20px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} + +.lcv.select-custom-bg .select-options li { + text-align: left; + text-indent: 0; + font-size: 16px; +} + +.lcv.select-custom-bg .select-options li .circle { + width: 10px; + height: 10px; + border-radius: 5px; + border: none; + background: #8dc63f; + margin: -2px 8px 0 0; + display: inline-block; +} + +.lcv.select-custom-bg .select-options li:nth-child(2) .circle { + background: #fbb040; +} + +.lcv.select-custom-bg .select-options li:nth-child(3) .circle { + background: #c367f4; +} + +.lcv.select-custom-bg .select-options li:nth-child(4) .circle { + background: #C41C2C; +} + +.lcv.select-custom-bg .select-options li:nth-child(5) .circle { + background: #be1e2d; +} + +.valid_to_input { + margin: 11px 0 0 10px; +} + +.valid_to_input input { + border: none; + outline: none; + color: #00a79d; + font-family: "Myriadpro-SemiBold"; + font-size: 18px; + width: 94px; + margin-right: 40px; + background: none; + height: 22px; +} + +.custom-select-w { + width: 380px; +} + +.custom-select-w .select-styled { + text-align-last: center; + padding: 0; +} + +.gt-sunE-hei { + max-height: calc(100vh - 200px); + overflow: auto; + padding-left: 20px; + padding-top: 10px; +} + +.unit-list .uk-grid > * { + padding-left: 25px; +} + +.btn-more-info .show_ { + /*margin: 18px 0 0 1px;*/ +} + +.text-trans { + text-transform: uppercase; +} + +.chk-custom-gr { + margin-left: 0; +} + +.chk-gr .chk-custom-gr { + margin-left: 5px; +} + +.chk-custom-gr input { + padding: 0; + height: initial; + width: initial; + margin-bottom: 0; + display: none; + cursor: pointer; +} + +.chk-custom-gr label { + position: relative; + cursor: pointer; +} + +.chk-custom-gr label:before { + content: ""; + -webkit-appearance: none; + background-color: transparent; + border: 1px solid #ed8a22; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), + inset 0px -15px 10px -12px rgba(0, 0, 0, 0.05); + padding: 12px; + display: inline-block; + position: relative; + vertical-align: middle; + cursor: pointer; + margin-right: 10px; + border-radius: 3px; + margin-top: -1px; +} + +.chk-custom-gr input:checked + label:after { + content: ""; + display: block; + position: absolute; + top: -8px; + left: 10px; + width: 8px; + height: 22px; + border: solid #84c241; + border-width: 0 4px 4px 0; + transform: rotate(37deg); +} + +.wh20.chk-custom-gr label:before { + padding: 9px; +} + +.wh20.chk-custom-gr input:checked + label:after { + top: -3px; + left: 6px; + width: 6px; + height: 18px; + border: solid #84c241; + border-width: 0 3px 3px 0; + transform: rotate(36deg); +} + +.wh20.chk-custom-gr-selected input:checked + label:after { + top: -6px; + left: 8px; +} + +.mt-20 { + margin-top: 20px !important; +} + +.sunE-class-list a { + width: 100%; +} + +.pad-center-large { + padding: 0 160px !important; +} + +.text-err-ai { + color: red; + text-decoration: line-through; +} + +.text-fix-ai { + color: green; +} + +.have-explain { + background-color: #ffe699; +} + +.wh27 { + width: 27px; + height: 27px; +} + +.react-datepicker__day-name, +.react-datepicker__day, +.react-datepicker__time-name { + height: 1.7rem; + line-height: 1.7rem !important; + border: 1px solid rgb(255 255 255 / 0%); +} + +.react-datepicker__day--selected { + background-image: linear-gradient(to right, #fff, #fff) !important; + color: #00b9b7 !important; + border: 1px solid #00b9b7 !important; +} + +.react-datepicker__week .react-datepicker__day--today { + background-image: linear-gradient(to right, #00e1a0, #00b9b7) !important; +} + +.react-datepicker__day--selected, +.react-datepicker__day--in-selecting-range, +.react-datepicker__day--in-range, +.react-datepicker__month-text--selected, +.react-datepicker__month-text--in-selecting-range, +.react-datepicker__month-text--in-range, +.react-datepicker__quarter-text--selected, +.react-datepicker__quarter-text--in-selecting-range, +.react-datepicker__quarter-text--in-range, +.react-datepicker__year-text--selected, +.react-datepicker__year-text--in-selecting-range, +.react-datepicker__year-text--in-range { + border-radius: 50% !important; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); +} + +.react-datepicker__day--selected:hover, +.react-datepicker__day--in-selecting-range:hover, +.react-datepicker__day--in-range:hover, +.react-datepicker__month-text--selected:hover, +.react-datepicker__month-text--in-selecting-range:hover, +.react-datepicker__month-text--in-range:hover, +.react-datepicker__quarter-text--selected:hover, +.react-datepicker__quarter-text--in-selecting-range:hover, +.react-datepicker__quarter-text--in-range:hover, +.react-datepicker__year-text--selected:hover, +.react-datepicker__year-text--in-selecting-range:hover, +.react-datepicker__year-text--in-range:hover { + background-image: linear-gradient(to right, #00e1a0, #00b9b7); +} + +.react-datepicker__day:hover, +.react-datepicker__month-text:hover, +.react-datepicker__quarter-text:hover, +.react-datepicker__year-text:hover { + border: 1px solid #00b9b7; + border-radius: 50% !important; +} + +.react-datepicker__time-container + .react-datepicker__time + .react-datepicker__time-box + ul.react-datepicker__time-list + li.react-datepicker__time-list-item--selected { + background-image: linear-gradient(to right, #00e1a0, #00b9b7); + color: white; + font-weight: bold; +} + +.react-datepicker__time-container + .react-datepicker__time + .react-datepicker__time-box + ul.react-datepicker__time-list + li.react-datepicker__time-list-item:hover { + background-image: linear-gradient(to right, #00e1a0, #00b9b7); +} + +.react-datepicker__day--today, +.react-datepicker__month-text--today, +.react-datepicker__quarter-text--today, +.react-datepicker__year-text--today { + font-weight: bold; + color: #fff !important; + border-radius: 50%; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); +} + +.react-datepicker__day--selected.react-datepicker__day--today { + color: #fff !important; +} + +/*.react-datepicker__day.react-datepicker__day--today:hover,.react-datepicker__day--selected.react-datepicker__day:hover,.react-datepicker__day--selected.react-datepicker__day{ + border: none!important; +}*/ +.react-datepicker__month-text--keyboard-selected, +.react-datepicker__quarter-text--keyboard-selected, +.react-datepicker__year-text--keyboard-selected { + border-radius: 50% !important; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); + border: none; + color: #fff !important; +} + +.react-datepicker__day--keyboard-selected { + border-radius: 0; + background-color: #fff !important; + color: #000 !important; +} + +.class-slect-time.mgh { + margin: 8px 0 0; +} + +.mb0 { + margin-bottom: 0 !important; +} + +.f20 { + font-size: 20px !important; +} + +.pad-t-80 { + padding-top: 80px; +} + +.mx-h { + max-height: calc(100vh - 190px); +} + +.sunE-container-box.giaotrinh.canhan.pad { + padding: 20px 20px 10px; +} + +ul.pagination { + list-style: none; + display: inline-block; +} + +ul.pagination li { + list-style: none; + display: inline-block; +} + +ul.pagination li a { + display: block; + width: 24px; + height: 24px; + margin-left: 10px; + text-align: center; + line-height: 24px; + border: none; + font-family: "Myriadpro-Regular"; + font-size: 16px; +} + +ul.pagination li.active a, +ul.pagination li:hover a { + background: #00b9b7; + color: #fff; + border: none; + border-radius: 5px; +} + +.sunE-container-box.giaotrinh.teacher-giaobai { + padding: 20px 20px 10px; +} + +.giaotrinh.teacher-giaobai .giaotrinh.filter .sunE-giaotrinh-resuft-filter { + height: calc(100vh - 270px); +} + +.giaotrinh.unit .sunE-giaotrinh-list.curriculum { + max-height: calc(100vh - 220px); + overflow: auto; + padding-top: 10px; + padding-left: 15px; +} + +.giaotrinh.unit .sunE-giaotrinh-list-teacher.curriculum { + max-height: calc(100vh - 200px); + overflow: auto; + padding-top: 10px; + padding-left: 15px; +} + +.giaotrinh.unit.teacher-giaobai .unit-list { + padding: 0 15px 0 30px; +} + +.bd-l-blue { + border-left: 3px solid #00bbb6; +} + +.sunE-giaotrinh-list .uk-width-1-2 { + margin-bottom: 15px; +} + +.giaobai-support .uk-container { + padding-left: 0; + padding-right: 0; +} + +.giaobai-detail .select-gr select { + border-radius: 3px; +} + +.giaobai-detail .underline { + text-decoration: underline; + font-family: "Myriadpro-Semibold"; +} + +.giaotrinh.unit .sunE-giaotrinh-list.curriculum { + padding: 10px 32px 0 20px; +} + +.giaotrinh.unit.teacher-giaobai .unit-list.uk-container { + padding-top: 10px; +} + +.diemdanh-cutom-select .select { + cursor: pointer; + display: inline-block; + position: relative; + font-size: 18px; + font-family: "Myriadpro-Light"; + color: #84c241; + width: 145px; + height: 32px; + line-height: 32px; + border-radius: 17px; + border: none; + background: #fff; + box-sizing: border-box; + box-shadow: none; +} + +.diemdanh-cutom-select .select-styled { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: #fff; + width: 145px; + height: 32px; + line-height: 32px; + /* transition: all 0.2s ease-in; */ + border-radius: 17px; + font-size: 18px; + text-align: left; + padding-left: 20px; + font-family: "Myriadpro-Light"; + z-index: 10; + box-sizing: border-box; +} + +.diemdanh-cutom-select .select-styled .line { + position: absolute; + right: 36px; + top: 2px; +} + +.diemdanh-cutom-select #intime.select-styled { + border: 1px solid #84c241; + color: #84c241; +} + +.diemdanh-cutom-select #intime.select-styled .line { + color: #84c241; +} + +.diemdanh-cutom-select #late.select-styled { + border: 1px solid #ed8a22; + color: #ed8a22; +} + +.diemdanh-cutom-select #late.select-styled .line { + color: #ed8a22; +} + +.diemdanh-cutom-select #absence_not_allowed.select-styled { + border: 1px solid #be1e2d; + color: #be1e2d; +} + +.diemdanh-cutom-select #absence_not_allowed.select-styled .line { + color: #be1e2d; +} + +.diemdanh-cutom-select #absence_allowed.select-styled { + border: 1px solid #be1e2d; + color: #be1e2d; +} + +.diemdanh-cutom-select #absence_allowed.select-styled .line { + color: #be1e2d; +} + +.diemdanh-cutom-select .select-styled:after { + content: ""; + width: 18px; + height: 9px; + background: url(./../images/teacher/diemdanh/ico_dropdown_green.png) 96% / + 18px no-repeat transparent; + position: absolute; + top: 12px; + right: 10px; +} + +.diemdanh-cutom-select #late.select-styled:after { + content: ""; + width: 18px; + height: 9px; + background: url(./../images/teacher/diemdanh/ico_dropdown_orange.png) 96% / + 18px no-repeat transparent; + position: absolute; + top: 12px; + right: 10px; +} + +.diemdanh-cutom-select #absence_not_allowed.select-styled:after, +.diemdanh-cutom-select #absence_allowed.select-styled:after { + content: ""; + width: 18px; + height: 9px; + background: url(./../images/teacher/diemdanh/ico_dropdown_red.png) 96% / 18px + no-repeat transparent; + position: absolute; + top: 12px; + right: 10px; +} + +.diemdanh-cutom-select .select-options { + display: none; + position: absolute; + padding: 10px; + top: calc(100% + 3px); + right: 0; + left: 0; + z-index: 11; + margin: 0; + list-style: none; + background-color: #fff; + border-radius: 20px; + border: none; + box-shadow: 0 1px 15px 0 rgb(21 27 38 / 15%); + max-height: calc(100vh - 100px); + overflow: auto; +} + +.diemdanh-cutom-select .select-options li { + margin: 0; + text-indent: 0; + transition: all 0.15s ease-in; + border-bottom: none; + text-align: center; + padding: 5px 0; + font-size: 18px; + font-family: "Myriadpro-Regular"; +} + +.diemdanh-cutom-select .select-options li:nth-child(1) { + color: #84c241; +} + +.diemdanh-cutom-select .select-options li:nth-child(2) { + color: #ed8a22; +} + +.diemdanh-cutom-select .select-options li:nth-child(3) { + color: #be1e2d; +} + +.diemdanh-cutom-select .select-options li:nth-child(4) { + color: #be1e2d; +} + +.f-24 { + font-size: 24px; +} + +.score-bg-blue input { + font-family: "Myriadpro-Bold"; + font-size: 24px; + width: 38px; + color: #00a69c; + line-height: 24px; + display: block; + text-align: center; + background: rgb(0 0 0 / 0%); + border: none; + outline: none; + margin: 0; + padding: 0; + box-sizing: border-box; +} + +.score-bg-blue input::-webkit-input-placeholder { + /* Edge */ + color: rgb(0 166 156 / 30%); + font-family: "Myriadpro-Bold"; +} + +.score-bg-blue input:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + color: rgb(0 166 156 / 30%); + font-family: "Myriadpro-Bold"; +} + +.score-bg-blue input::placeholder { + color: rgb(0 166 156 / 30%); + font-family: "Myriadpro-Bold"; +} + +/* Chrome, Safari, Edge, Opera */ +.score-bg-blue input::-webkit-outer-spin-button, +.score-bg-blue input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +/* Firefox */ +.score-bg-blue input[type="number"] { + -moz-appearance: textfield; +} + +.menu-gr-right input[type="text"].btn { + width: 100%; + display: block; + height: 48px; + border-radius: 24px; + background: rgb(0 203 173 / 30%); + color: #231f20; + font-size: 18px; + line-height: 48px; + margin: 0 0 10px; + cursor: pointer; + border: none; + outline: none; + box-sizing: border-box; + padding: 0 30px; + font-family: "Myriadpro-Regular"; +} + +.menu-gr-right input[type="text"].btn.name_kt { + font-family: "Myriadpro-Italic"; +} + +.menu-gr-right input[type="text"].btn::-webkit-input-placeholder { + /* Edge */ + color: #231f20; +} + +.menu-gr-right input[type="text"].btn:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + color: #231f20; +} + +.menu-gr-right input[type="text"].btn::placeholder { + color: #231f20; +} + +.menu-gr-right .react-datepicker-wrapper input[type="text"] { + width: 100%; + display: block; + height: 48px; + border-radius: 24px; + background: #b2ece8; + color: #231f20; + font-size: 18px; + line-height: 48px; + margin: 0 0 10px; + cursor: pointer; + border: none; + outline: none; + box-sizing: border-box; + padding: 0 30px; + font-family: "Myriadpro-Regular"; +} + +.btn-ob.select { + cursor: pointer; + display: inline-block; + position: relative; + font-size: 16px; + color: #fff; + width: 100%; + height: 48px; + line-height: 48px; + border-radius: 24px; + border: none; + background: #b2ece8; +} + +.btn-ob .select-styled { + background: #b2ece8; + border-radius: 24px; + color: #231f20; + font-family: "Myriadpro-Regular"; + font-size: 18px; + line-height: 48px; + text-align: left; + box-sizing: border-box; + padding: 0 30px; +} + +.btn-ob .select-styled:after { + content: ""; + width: 24px; + height: 14px; + background: url(./../images/teacher/diemdanh/ico_dropdown_blue.png) 90% / 24px + no-repeat transparent; + position: absolute; + top: 19px; + right: 8px; +} + +.btn-ob .select-styled.active:after { + background: url(./../images/teacher/diemdanh/ico_dropup_blue.png) 90% / 24px + no-repeat transparent; +} + +.hoc-ky.btn-ob { + z-index: 10; +} + +.hoc-ky.btn-ob .select-options { + z-index: 9; +} + +.kiem-tra-mieng.btn-ob { + z-index: 8; +} + +.kiem-tra-mieng.btn-ob .select-options { + z-index: 7; +} + +.he-so.btn-ob { + z-index: 6; +} + +.he-so.btn-ob .select-options { + z-index: 5; +} +.uk-modal { + z-index: 99999; +} + +.uk-modal .uk-modal-body { + padding: 20px; +} + +.medium-title.f-24 { + margin: 0 0 25px; +} + +.box-chart { + margin: 0 0 20px; +} + +.box-chart p { + color: #000000; + font-family: "Myriadpro-Regular"; + font-size: 18px; +} + +.box-chart .w254 { + width: 254px; +} + +.box-bcht .calendar { + margin: 0 auto 20px; +} + +.list-schedule { + max-height: calc(100vh - 160px); + overflow: auto; + padding-right: 10px; +} + +.medium-title .chk-custom-gr label:before { + margin-top: -4px; +} + +.medium-title .wh20.chk-custom-gr input:checked + label:after { + top: -10px; +} + +.mex-box-height { + height: calc(100vh - 340px); + overflow: auto; + padding-right: 10px; +} + +.mex-info-box { + background: #8ee4db; + padding: 20px; + margin: 0 0 30px 20px; + border-radius: 20px; +} + +.mex-info-box .send-name { + position: absolute; + top: 5px; + left: 15px; +} + +.mex-info-box.isMe { + background: #fff; + margin: 0 20px 30px 50px; + padding: 30px 20px 20px; +} + +.mex-info-box p { + color: #221f1f; + font-family: "Myriadpro-Light"; + font-size: 18px; +} + +.mex-info-box span.time-send { + position: absolute; + bottom: -20px; + right: 0; + color: #58595b; + font-family: "Myriadpro-Light"; + font-size: 12px; +} + +.mex-info-box.isMe span.time-send { + position: absolute; + bottom: -20px; + right: auto; + left: 0; + color: #58595b; + font-family: "Myriadpro-Light"; + font-size: 12px; +} + +.__checked_send_exam { + font-size: 22px; + font-weight: bold; + margin: 10px; + color: #84c241; + align-items: center; +} + +.__checked_send_exam img { + margin: 0px 10px; + height: 24px; +} + +.__checked_send_exam_children img { + margin: 0px 5px; + height: 20px; +} + +.__checked_send_exam_children { + font-size: 16px; + font-weight: bold; + margin: 5px 10px; + color: #84c241; + align-items: center; +} + +.pad20 { + padding: 20px; +} + +.react-datepicker-popper { + z-index: 12; +} + +.item-student-name .nx { + max-width: 460px; + display: block; + font-family: "Myriadpro-Light" !important; + /* padding-bottom: 30px; */ +} + +.btn-ob .select-options li { + text-indent: 25px; + border-bottom: 1px solid #d9d8d8; + text-align: left; +} + +.btn-ob .select-options { + padding: 24px 25px 0; +} + +.mex-box-height-2 { + height: calc(100vh - 433px); + overflow: auto; + padding-right: 10px; +} + +.send-mes { + background: #fff !important; + border: none; +} + +.send-mes img { + width: 24px; +} + +.diemdanh-list-hs.pr-0 { + padding-right: 0; +} + +.checbox-right .chk-custom-gr label:before { + margin-left: 15px; + margin-right: 0; +} + +.checbox-right .wh20.chk-custom-gr input:checked + label:after { + left: auto; + right: 5px; + top: -6px; +} + +/* Check box assigned */ +.wh20.check-assigned input:checked + label:after { + /* top: -5px; */ + top: -8px; + left: 8px; + height: 18px; + border: solid #84c241; + border-width: 0 3.7px 3.7px 0; +} + +/* Check box student */ +.wh20.check-select-student input:checked + label:after { + /* top: -5px; */ + top: -6px; + left: 8px; + height: 18px; + border: solid #84c241; + border-width: 0 3.7px 3.7px 0; +} + +/* Check box select all */ +.checbox-right .wh20.check-select-student input:checked + label:after { + left: auto; + right: 2px; + top: -8px; +} + +.mes-avt { + width: 42px; + height: 42px; + border-radius: 21px; + overflow: hidden; + border: 2px solid #e7c71d; + position: absolute; + left: -50px; + top: 0; +} + +.mes-avt img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.pr45 { + padding-right: 45px; +} + +.react-datepicker__day--outside-month { + color: #7d7d7d !important; +} + +.sunE-container-box.giaotrinh.unit { + padding: 20px 20px 0; +} + +.giaotrinh.unit.student .unit-list { + padding: 0 25px 0 20px; +} + +.giaotrinh.unit.student .info-item-desc h2 { + color: #fff; + text-align: left; +} + +.giaotrinh.unit.student .unit-list .unit-giaotrinh-content.active { + background: rgb(4 5 5 / 32%); + border-top-right-radius: 35px; + border-top-left-radius: 35px; +} + +.giaotrinh.unit.student + .unit-list + .unit-giaotrinh-content.active + .unit-more-info { + border-bottom: none; +} + +.msg-active { + background: #c3fdf3; +} + +.msg-seen.tinnhan-item h2 { + font-family: "Myriadpro-Regular"; + color: #525252; +} + +.msg-seen.tinnhan-item span { + color: #525252; +} + +.select-language.select { + cursor: pointer; + display: inline-block; + position: relative; + font-size: 18px; + color: #00bbb5; + width: 100%; + height: 24px; + line-height: 24px; + border-radius: 0; + border: none; + background: none; + font-family: "Myriadpro-SemiBold"; +} + +.select-language .select-styled { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: none; + width: 100%; + height: 24px; + line-height: 24px; + border: none; + transition: all 0.2s ease-in; + border-radius: 0; + color: #00bbb5; + font-size: 16px; + text-align: center; + font-family: "Myriadpro-SemiBold"; + z-index: 10; + text-decoration: underline; +} + +.select-language .select-styled:after { + content: ""; + width: 0; + height: 0; + background: none; + position: absolute; + top: 0; + right: 0; +} + +.select-language .select-options { + width: 130px; + display: none; + position: absolute; + padding: 10px 5px; + top: 100%; + right: 0; + left: 0; + z-index: 9; + margin: 0; + list-style: none; + background-color: #fff; + border-radius: 10px; + border: none; + box-shadow: 0 1px 15px 0 rgb(21 27 38 / 15%); + max-height: auto; + overflow: auto; +} + +.select-language .select-options li { + margin: 0; + text-indent: 0; + transition: all 0.15s ease-in; + border-bottom: none; + text-align: center; + padding: 3px 0; +} + +.student-search .search-custom { + border-top-left-radius: 24px; + border-bottom-left-radius: 24px; +} + +.edit-profile-student button { + padding: 0 20px 0 45px; +} + +.edit-profile-student .ico_edit_profile { + position: absolute; + left: 15px; + top: 8px; +} + +.w25 { + width: 25px; +} + +.info-parent { + margin: 20px 0 0; +} + +.ph-add-gr h2 { + color: #404041; + font-size: 24px; + line-height: 31px; + font-family: "Myriadpro-Bold"; +} + +.btn-add-ph { + cursor: pointer; + margin: 0 0 0 40px; +} + +.btn-add-ph span { + color: #00b9b6; + font-size: 18px; + line-height: 25px; + font-family: "Myriadpro-Regular"; + margin: 5px 0 0 10px; +} + +.parent-info .avatar { + width: 76px; + height: 76px; + border-radius: 38px; + overflow: hidden; + margin-right: 20px; + border: 3px solid #fff; + box-shadow: 0 1px 6px 0 rgba(21, 27, 38, 0.15); +} + +.parent-info p { + color: #231f20; + font-size: 18px; + line-height: 18px; + font-family: "Myriadpro-Regular"; + margin: 20px 0 5px; +} + +.parent-info span { + color: #231f20; + font-size: 18px; + line-height: 25px; + font-family: "Myriadpro-Light"; + margin: 0; +} + +.avatar-edit-box.student { + width: 186px; + height: 186px; +} + +.avatar-edit.student { + padding-top: 20px; +} + +.bg_edit_student_profile { + position: absolute; + top: 0; + left: 0; +} + +.radio-item { + position: relative; + padding: 0 6px; + margin: 10px 0 0; +} + +.radio-item input[type="radio"] { + display: none; +} + +.radio-item label { + color: #666; + font-weight: normal; +} + +.radio-item label:before { + content: " "; + display: inline-block; + position: relative; + top: 5px; + margin: 0 8px 0 0; + width: 20px; + height: 20px; + border-radius: 11px; + border: 1px solid #404041; + background-color: transparent; + box-sizing: border-box; +} + +.laplai label { + font-family: "Myriadpro-Regular"; + font-size: 16px; + color: #404041; + display: unset; + padding: 0; + cursor: pointer; +} + +.laplai p > input[type="radio"]:checked + *::before { + border-color: #84c241; +} + +.time-to.select-time input { + background: no-repeat; + box-shadow: none; + color: #00a69c; + font-size: 18px; + font-family: "Myriadpro-SemiBold"; + margin: 11px 0 0 15px; + cursor: pointer; +} + +.apdung .time-to.select-time .ico_edit_time_to { + cursor: pointer; + position: absolute; + left: 136px; + top: 18px; + margin: 0; +} + +.sunE-container-box-UI { + padding: 10px 0; +} + +.sunE-container-box-UI.setting { + padding: 0; + border-top-right-radius: 20px; + border-top-left-radius: 20px; +} + +.bg-main-color-m { + background-image: linear-gradient(to bottom, #e1fef0, #ffffff); +} + +.w100 { + width: 100%; + box-sizing: border-box; + display: block; +} + +.img-cover { + object-fit: cover; +} + +.w100 img { + width: 100%; + height: 100%; + display: block; +} + +.gioithieu-info { + padding: 0 25px 2rem; +} + +.gioithieu-info p { + line-height: 20px; + color: #404041; + font-size: 20px; + font-family: "Myriadpro-Regular"; + padding-bottom: 20px; +} + +.term-info { + background: #fff; + padding: 30px; + border-radius: 20px; + margin: 30px 0 0; +} + +.term-info p { + line-height: 24px; + color: #404041; + font-size: 18px; + font-family: "Myriadpro-Regular"; + padding: 0 0 20px; +} + +.btn-create-khk span { + display: block; + width: 110px; + height: 38px; + text-align: right; + min-width: 110px; + padding: 0 20px; + line-height: 36px; + box-sizing: border-box; +} + +.btn-create-khk .ico_add_kh { + position: absolute; + top: 9px; + left: 15px; +} + +.btn-create-khk .ico_line_kh { + position: absolute; + top: 4px; + left: 45px; +} + +.line38 { + line-height: 38px; +} + +.time-to-khht-cn .ico_edit_time_to_khht { + position: absolute; + top: 2px; + right: 0; +} + +.bg-w-h-50 { + height: 50px; + background: #fff; + border-radius: 25px; + padding: 0 35px; + margin-top: 20px; +} + +.apdung .bg-w-h-50 label { + margin: 0; + line-height: 50px; +} + +.mt-3 { + margin-top: 3px; +} + +.tong-hs { + line-height: 24px; + font-size: 18px; + font-family: "Myriadpro-SemiBold"; + margin: 0 0 20px; +} + +.custom-select-no-bg.one-line .select-styled { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.percent span { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 16px; + line-height: 16px; + font-family: "Myriadpro-Bold"; +} + +.collapse { + position: relative; +} + +.collapse .calendar { + height: 110px; + overflow: hidden; +} + +.fullHeight.collapse .calendar { + height: auto; + overflow: initial; +} + +.btn-collapse { + position: absolute; + bottom: -25px; + left: calc(50% - 25px); + width: 50px; + height: 25px; + border-bottom-left-radius: 25px; + border-bottom-right-radius: 25px; + background: #fff; + display: flex; + justify-content: center; + align-items: center; + box-shadow: 0 2px 1px 0 rgba(21, 27, 38, 0.15); + cursor: pointer; +} + +.btn-collapse img { + margin-top: -3px; +} + +.box-bcht-date-custom-hei.box-bcht { + padding: 0; + width: 498px; +} + +.box-bcht-date-custom-hei .calendar { + width: 100%; + border-bottom-left-radius: 20px; + border-bottom-right-radius: 20px; +} + +.box-bcht-date-custom-hei .calendar .week-cell, +.box-bcht-date-custom-hei .calendar .day-cell { + flex-grow: 0; + flex-shrink: 0; + flex-basis: calc(100% / 7 - 30px); + display: flex; + justify-content: center; + align-items: center; + height: 40px; + width: 40px; + cursor: pointer; + margin: 5px 15px; +} + +.two-line { + max-height: 58px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +.thoikhoabieu.tb .valid_to_input { + margin: 17px 0 0 10px; +} + +.thoikhoabieu.tb .apdung .valid_to_input .react-datepicker-wrapper { + width: 120px; +} + +.thoikhoabieu.tb .apdung.apdung-custom .flex-1 img { + margin: 2px 0 0 10px; + width: 12px; +} + +.sunE-plan.sunE-plan-list { + padding-left: 0; +} + +.lichngay-teacher .calendar { + width: 100%; +} + +.add_code_student-gr.w-custom { + width: 500px; +} + +.sunE-input-border-blue-gr .ico_class_po { + top: 8px; + left: 13px; +} + +.slider-item-desc .item-top-title-main .text-light.two-line { + padding: 0 20px; +} + +.datlichnhac-input-gr .chk-custom-gr label:before { + margin-right: 15px; +} + +.tp-k .time-to.select-time input { + margin: 6px 0 0 15px; +} + +.apdung.tp-k .time-to.select-time .ico_edit_time_to { + top: 14px; +} + +.box-gr-sp, +.box-sp { + background: #fff; + padding: 30px 60px; + border-radius: 20px; +} + +.box-gr-sp-i { + margin: 0 0 20px; +} + +.box-gr-sp-i .mi { + width: 60px; + box-sizing: border-box; +} + +.box-gr-sp-i .mi img { + display: block; +} + +.box-gr-sp-i p, +.box-sp p { + font-size: 18px; + line-height: 25px; + font-family: "Myriadpro-Regular"; + color: #404041; +} + +.hotline-sp { + padding: 30px 0; + border: 1px solid #404041; + border-radius: 20px; + margin-top: 30px; +} + +.hotline-sp img { + margin: 0 auto; +} + +.hotline-sp span { + font-size: 18px; + line-height: 54px; + font-family: "Myriadpro-Bold"; + color: #00a69c; + text-transform: uppercase; + display: block; + text-align: center; +} + +.support.sunE-container-box { + padding: 50px; +} + +.top-12-custom { + margin-top: 12px; +} + +.collapse .calendar { + border-radius: 20px; +} + +.one-line { + overflow: hidden; + /* display: -webkit-box; + -webkit-line-clamp: 1 !important; + -webkit-box-orient: vertical; */ + text-overflow: ellipsis; + white-space: nowrap; + /* width: 300px; */ +} + +.one-line-break-word { + white-space: normal; + word-wrap: break-word; +} + +.sunE-title-medium-p { + font-size: 18px; + line-height: 18px; + margin: 0 0 15px; + font-family: "Myriadpro-SemiBold"; +} + +.box-chart .dtb-sum { + width: 100%; + position: absolute; + bottom: 10px; + left: 0; +} + +.box-chart .bdg-sum { + width: 100%; + position: absolute; + bottom: 10px; + left: 0; +} + +.dtb-sum-slider { + width: 100%; + position: absolute; + bottom: 0; + left: 0; +} + +.bdg-sum .w { + width: 297px; +} + +.dtb-sum .w { + width: 307px; +} + +.student-ab .box-detail-ab { + top: 170px; +} + +.dtb-sum-slider p { + text-align: left; +} + +.dtb-sum-slider .w { + width: 234px; +} + +.btn-zoom-img { + cursor: pointer; +} + +.box-video-project { + height: 250px; +} + +.box-video-project video { + max-height: 250px; +} + +.custom-4.slider-custom { + max-width: 420px; +} + +.custom-4.slider-custom .slick-arrow.slick-prev { + left: -40px; +} + +.custom-4.slider-custom .slick-arrow.slick-next { + left: calc(100% + 9px); +} + +.select-all-k { + padding-bottom: 10px; +} + +.box-graph-content canvas { + width: 100% !important; + min-height: 25rem !important; +} + +.top-title-name { + padding: 8px 20px; + background: rgba(183, 243, 229, 0.6); + border-radius: 5px; + max-height: 59px; +} + +.item-skill-top { + display: flex; + align-items: center; + justify-content: center; +} + +.top-title-name p { + font-size: 22px; + line-height: 24px; + font-family: "Myriadpro-SemiBold"; + color: #00a79d; + text-align: center; +} + +.student-khht .calendar { + border-radius: 20px; +} + +.taokehoach .input-gr textarea::placeholder, +.input-gr input::placeholder, +.input-gr select::placeholder { + color: #8a8a8a !important; +} + +.taokehoach .input-gr textarea::-ms-input-placeholder, +.input-gr input::-ms-input-placeholder, +.input-gr select::-ms-input-placeholder { + color: #8a8a8a !important; +} + +.taokehoach .input-gr textarea::-webkit-input-placeholder, +.input-gr input::-webkit-input-placeholder, +.input-gr select::-webkit-input-placeholder { + color: #8a8a8a !important; +} + +.mr-c { + margin-right: 26px; +} + +.giaotrinh.unit .sunE-giaotrinh-list.pr-25.pt-8 { + padding: 8px 25px 0 20px; +} + +.giaotrinh.unit.student .unit-list.pt-8 { + padding: 8px 25px 0 20px; +} + +.item-student-name span.pl-0 { + padding-left: 0; +} + +.flex-1 { + flex: 1 !important; +} + +.box-shadow-la { + box-shadow: 0 2px 8px 0 rgb(21 27 38 / 40%) !important; +} + +.collapse.showMonth .calendar { + height: 165px; +} + +.fullHeight.showMonth .calendar { + height: auto; +} + +.mes-box-send { + resize: none; + height: 54px; + width: 100% !important; + line-height: 32px; + font-size: 16px; + box-sizing: border-box; + padding: 10px 20px 10px 20px; + border-top-left-radius: 27px; + border-bottom-left-radius: 27px; + outline: none; + border: 1px solid #fff; + box-shadow: 0 1px 8px 0 rgb(21 27 38 / 15%); + background: #fff; + font-family: "Myriadpro-Regular"; +} + +.mes-box-send::-webkit-input-placeholder { + /* Edge */ + font-family: "Myriadpro-Regular"; +} + +.mes-box-send:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + font-family: "Myriadpro-Regular"; +} + +.mes-box-send::placeholder { + font-family: "Myriadpro-Regular"; +} + +.search-gr-p { + height: 44px; + box-sizing: border-box; + margin: 30px 0 10px; +} + +.box-btn-send { + height: 54px; + width: 54px; + border-top-right-radius: 27px; + border-bottom-right-radius: 27px; + background: #fff; +} + +.setting-on-off-box .box-shadow-2 { + box-shadow: none; +} + +.hcs { + font-size: 18px; + line-height: 18px; + font-family: "Myriadpro-Bold"; + margin: 0 15px 0 5px; +} + +.gr-r span.mr-5 { + margin-right: 5px; +} + +.box-s span { + display: block; + height: 36px; + margin-top: 5px; + border-radius: 18px; + background: #fff; + color: #00cbad; + font-size: 18px; + font-family: "Myriadpro-Light"; + line-height: 36px; + padding: 0 5px 0 40px; +} + +.box-s img { + position: absolute; + top: 5px; + left: 5px; +} + +.box-s .select { + cursor: pointer; + display: inline-block; + position: relative; + font-size: 16px; + color: #00cbad; + width: 150px; + height: 36px; + line-height: 36px; + border-radius: 18px; + border: none; + background: #fff; + margin-top: 5px; +} + +.box-s .select-styled { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: #fff; + width: 150px; + height: 36px; + line-height: 36px; + border: none; + /* transition: all 0.2s ease-in; */ + border-radius: 18px; + color: #00cbad; + font-size: 16px; + text-align: left; + padding: 0 5px 0 40px; + font-family: "Myriadpro-Light"; + z-index: 10; +} + +.select-chart .select-styled { + padding: 0 5px; + text-align: center; + width: 100%; +} + +.box-s .select-options { + display: none; + position: absolute; + padding: 24px 10px 0; + top: 22px; + right: 0; + left: 0; + z-index: 9; + margin: 0; + list-style: none; + background-color: #fff; + border-radius: 24px; + border-top-right-radius: 0; + border-top-left-radius: 0; + border: none; + box-shadow: 0 1px 15px 0 rgb(21 27 38 / 15%); + max-height: calc(100vh - 100px); + overflow: auto; +} + +.select-chart .select-options { + top: 6px; +} + +.box-s .select img { + position: absolute; + top: 5px; + left: 5px; + z-index: 101; +} + +.box-s .select-options li { + margin: 0; + text-indent: 0; + transition: all 0.15s ease-in; + border-bottom: none; + text-align: center; + color: #00cbad; +} + +.gr-k .hs-dh { + font-size: 29px; + line-height: 65px; + color: #fc9d24; + font-family: "Myriadpro-Regular"; +} + +.tinnhan-item .avt.auto img { + width: 29px; + height: 24px; + object-fit: cover; +} + +.check-date-time-week { + width: 400px; + height: 44px; + background: #fff; + border-radius: 22px; + box-sizing: border-box; + padding: 0 15px; + box-shadow: 1px 2px 4px 0 rgb(21 27 38 / 35%); + margin: auto; +} + +.check-date-time-week p { + font-size: 20px; + line-height: 44px; + color: #414042; + font-family: "Myriadpro-Regular"; +} + +.check-date-time-week img { + width: 14px; + cursor: pointer; +} + +.search-gr-custom .box-shadow-2, +.search-custom, +._line_box { + box-shadow: 2px 2px 4px 0 rgb(21 27 38 / 35%); +} + +.img-bg-x { + width: 216px; + height: 287px; + background-image: url("./../images/giaotrinh/bg_unit.png"); + background-repeat: no-repeat; + background-position: center; + object-fit: cover; + display: flex; + justify-content: center; +} + +.__way_map { + position: absolute; + transform: translate(75%, 150%); +} + +.__way_map_down { + position: absolute; + transform: translate(65%, 210%); +} + +.img-bg-x .__avt_unit { + border-radius: 50%; + /* margin: 20px; */ + /* width: 120px; */ + /* height: 120px; */ + margin-top: 30px; + width: 76%; + height: 50%; + object-fit: cover; + margin-left: -8px; +} + +.info-gr-popup.info-gr img { + width: 30px; + height: auto; + margin: 0; +} + +.info-gr-popup.info-gr .info-con p { + font-size: 18px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 295px; +} + +.info-gr-popup.info-gr .avta { + width: 30px; + height: 30px; + border: 2px solid #e9af38; + border-radius: 50%; + overflow: hidden; +} + +.info-gr-popup.info-gr .avta img { + width: 100%; + height: 100%; +} + +.box-topic { + background: #fff; + padding: 15px; + border-radius: 20px; + margin: 0 0 30px; +} + +.box-topic h2 { + font-size: 18px; + line-height: 135%; + font-family: "Myriadpro-SemiBold"; +} + +.box-topic p { + font-size: 18px; + line-height: 135%; + font-family: "Myriadpro-Regular"; +} + +._tb .title { + background-color: rgb(172 241 228); + border-radius: 10px; +} + +._tb .title p { + text-align: center; + font-size: 18px; + line-height: 135%; + font-family: "Myriadpro-SemiBold"; + vertical-align: middle; +} + +._class { + width: 120px; + margin-right: 10px; + padding: 10px 0; +} + +._date { + width: 180px; + margin-right: 10px; + padding: 10px 0; +} + +._score { + margin-right: 10px; +} + +._number { + width: 140px; + padding: 10px 0; +} + +.pad100 { + padding: 10px 0; +} + +.mb-5 { + margin-bottom: 5px; +} + +.ml-2-5 { + margin-left: 2.5px; +} + +.mg-2-5-2 { + margin: 0 2.5px; +} + +.mr-2-5 { + margin-right: 2.5px; +} + +._detail { + background: #fff; + padding: 5px 10px; +} + +._detail p { + text-align: center; + font-size: 18px; + line-height: 26px; + font-family: "Myriadpro-Regular"; + vertical-align: middle; + max-height: 52px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +.list-details .item:first-child ._detail { + border-top-right-radius: 10px; + border-top-left-radius: 10px; +} + +.list-details .item:last-child ._detail { + border-bottom-right-radius: 10px; + border-bottom-left-radius: 10px; +} + +.homepage-teacher.sunE-container-box { + padding: 30px 20px 20px; +} + +.slider-class-see-report { + display: flex; + align-items: flex-end; + justify-content: flex-end; + width: 100%; + height: 100%; +} + +.txt-desc { + position: absolute; + top: -5px; + left: 25px; + color: #d1d3d4; +} + +.active .txt-desc { + color: #000000; +} + +.chk-gr .like, +.like-img .like { + display: none; +} + +.chk-gr .no_like, +.like-img .no_like { + display: block; +} + +.is_in_wishlist .like { + display: block; +} + +.is_in_wishlist .no_like { + display: none; +} + +.h-giaobai-support-list { + overflow-y: auto; + overflow-x: hidden; + max-height: calc(100vh - 220px); + padding: 10px 35px 10px 20px; +} + +.content_study_guide_container { + max-height: calc(100vh - 130px); +} + +.class-box-desc span.class-online, +.class-box-desc span.class-offline { + font-size: 18px; + font-family: "Myriadpro-SemiBold"; +} + +.input-gr .box-shadow-2 { + box-shadow: 1px 2px 6px 0 rgb(21 27 38 / 35%); +} + +.set-max-w { + max-width: 414px; +} + +.select-all-k.mg-top-0.flex-m { + margin-right: 10px; +} + +.sunE-container-box-UI.setting { + background: #fff; +} + +.tpm-r { + margin-right: 33px; +} + +.sunE-right-container.p0 { + padding: 30px 20px 0; +} + +.text-center.box-video-project.img-bg { + max-height: 260px; +} + +.text-center.box-video-project.img-bg img { + max-width: 100%; + height: 100%; +} + +.mg-10-0 { + margin: 10px 0 !important; +} + +.ql-bt-dg .sunE-giaotrinh-item { + margin: 10px 0; + padding-bottom: 10px; + border-bottom: 1px solid #c5c5c5; +} + +.ql-bt-dg .sunE-giaotrinh-item:first-child { + margin: 0 0 10px; +} + +.ql-bt-dg .sunE-giaotrinh-item:last-child { + padding-bottom: 0; + border-bottom: none; +} + +.sunE-giaotrinh-resuft-filter.ql-bt-dg { + max-height: calc(100vh - 160px); +} + +.file-support-list { + overflow: auto; + max-height: 240px; + padding-right: 10px; +} + +.pasd.sunE-container-box { + padding: 30px 20px 0; +} + +.ldjas + .giaotrinh.teacher-giaobai + .giaotrinh.filter + .sunE-giaotrinh-resuft-filter { + height: calc(100vh - 290px); +} + +.laplai label.title-b { + font-family: "Myriadpro-SemiBold"; + color: #000; +} + +.center-flex-hz { + display: flex; + align-items: center; +} + +.item-student-name.max-w-1 p { + word-break: break-all; +} + +.sunE-container-box.setting { + padding: 10px 20px 10px; +} + +.error-img { + height: 26px; +} + +.pad-t-30 { + padding-top: 30px; +} + +.sunE-calendar.student .calendar { + width: 420px; +} + +.sunE-calendar.student .calendar .week-cell, +.sunE-calendar.student .calendar .day-cell { + flex-grow: 0; + flex-shrink: 0; + flex-basis: calc(100% / 7 - 19px); + display: flex; + justify-content: center; + align-items: center; + height: 40px; + width: 40px; + cursor: pointer; + margin: 5px 9px; +} + +/*END MORE CSS*/ + +@media screen and (max-width: 768px) { + .flex { + display: block; + } + + .sunE-container { + width: 100%; + } + + .disable-mobile { + display: none; + } + + .enable-mobile { + display: block; + } +} + +.flex-m .class-slect-time .err label { + color: #e22028; +} + +.tinnhan-item .dot-active { + width: 12px; + height: 12px; + background-color: #3578e5; + border-radius: 50%; + position: relative; + top: 12px; + left: 12px; +} + +.msg-seen.tinnhan-item .dot-active { + display: none; +} + +video::-webkit-media-controls-volume-slider { + display: none; +} + +video::-webkit-media-controls-mute-button { + display: none; +} + +.popup-tag-edit { + position: fixed; + display: none; + color: #000; + background-color: #fff; + padding: 3px 30px; + border-radius: 17px; + font-size: 16px; + font-family: "Myriadpro-Regular"; + cursor: pointer; + box-shadow: 1px 2px 4px 0 rgba(21, 27, 38, 0.4); +} + +.ico_right_p5 { + margin: 0 5px; +} + +.no_select { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +input[type="text"]::-ms-reveal, +input[type="password"]::-ms-reveal, +input[type="text"]::-ms-clear, +input[type="password"]::-ms-clear { + display: none; +} + +.bg_auth { + max-width: 100%; +} + +.__overview_report { + background: #fff; + margin-top: 22px; + border-radius: 18px; + box-shadow: 1px 2px 4px 0 rgb(21 27 38 / 40%); + padding: 30px 0px; + display: flex; + align-items: center; + flex-direction: column; + position: relative; +} + +.__overview_info { + margin-top: 30px; + width: 240px; +} + +.__count_std_completed { + display: flex; + align-items: center; + font-size: 15px; + color: #58595b; + font-weight: bold; +} + +.__count_std_completed h5 { + font-size: 28px; + color: #58595b; + margin-left: 4px; + font-weight: bold; + margin-bottom: 5px; +} + +.__item_note_chart { + display: flex; + align-items: center; +} + +.__item_note_chart .__color_chart { + height: 20px; + width: 32px; +} + +.__item_note_chart .__text_note { + font-size: 16px; + font-weight: bold; + margin-left: 35px; +} + +.__overview_chart { + padding: 8px; + border-radius: 50%; + box-shadow: 1px 2px 4px 0 rgb(21 27 38 / 40%); + height: 162px; + width: 172px; +} + +.__overview_chart .__chart { + position: absolute; + left: 0; + right: 0px; +} + +.btn-edit-class { + display: flex; + align-items: center; +} + +.btn-edit-class img { + margin-right: 10px; +} + +.img-upload .__change_avatar { + display: flex; + align-items: center; + justify-content: center; + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: #000000; + opacity: 0.6; + border-radius: 0px 0px 24px 24px; + height: 63px; + cursor: pointer; +} + +.img-upload .__change_avatar img { + height: 33px; + margin-right: 24px; +} + +.img-upload .__change_avatar p { + font-size: 20px; + line-height: 24px; + color: #ffffff; +} + +.form-sunE-button .btn-update-class { + margin-top: 100px; + padding: 0px 75px; +} + +.__vertical-center { + display: flex; + flex-direction: column; + align-items: center; +} + +.__vertical-center .__action_delete_class { + font-weight: 600; + font-size: 18px; + line-height: 22px; + text-decoration-line: underline; + color: #ef4444; + margin-top: 32px; +} + +.__body_confirm_delete_class { + text-align: center; +} + +.__body_confirm_delete_class .__title_confirm { + font-weight: 600; + font-size: 20px; + line-height: 29px; + color: #000000; +} + +.__body_confirm_delete_class .__message_confirm { + font-weight: 300; + font-size: 18px; + line-height: 22px; + color: #000000; + margin-top: 12px; + margin-bottom: 18px; +} + +.horizontal-item-between { + display: flex; + justify-content: center; + align-items: center; + max-width: 100%; +} + +.__input_note_rollup { + border: none; + width: 60%; + border-radius: 8px; + padding: 5px 10px; + height: 22px; + resize: none; + margin: 0px -10px; +} + +.__input_note_rollup:focus { + outline: none; + background: #f5f5f5; + margin: 0px 0px; +} + +.__input_note_exam_card { + border: none; + width: 90%; + border-radius: 8px; + padding: 5px 10px; + height: 22px; + resize: none; + margin: 0px -10px; +} + +.__input_note_exam_card:focus { + outline: none; + background: #f5f5f5; + margin: 0px 0px; +} + +.diemdanh-list-hs .chk-flex.ab-top-custom { + position: absolute; + top: 8px; + right: 0px; +} + +.diemdanh-list-hs .chk-flex.ab-top-custom .left-10 { + margin-right: 10px; +} + +.__text_remind_max { + margin-top: 8px; + font-style: italic; +} + +.__max_add_schedule { + font-style: italic; + margin: 5px 15px; +} + +.__calendar_log { + margin-right: 16px; +} + +.btn-disable-status { + padding: 0 45px; + height: 40px; + line-height: 37px; + border-radius: 20px; + border: 2px solid #00a69c; + font-size: 16px; + color: #00a69c; + background: #fff; + font-family: "Myriadpro-SemiBold"; + box-sizing: content-box; +} + +.btn-line-blue-status-all { + padding: 0 47px; + height: 44px; + line-height: 37px; + border-radius: 20px; + border: none; + font-size: 16px; + background-image: linear-gradient(to right, #00b9b7, #00e1a0); + color: #fff; + font-family: "Myriadpro-SemiBold"; + min-width: 100px; +} + +.uk-modal-dialog.__modal_confirm_delete_class { + width: 390px; +} + +.__body_class { + display: flex; + justify-content: center; + align-items: center; + height: 50%; +} + +.__body_class .__text_empty_data_home_page { + width: 330px; + font-size: 20px; + font-family: "MyriadPro"; +} + +.__text_empty_curiclum_personal { + font-size: 22px; + font-family: "MyriadPro"; + text-align: center; +} + +.__text_empty_curiclum_personal strong { + color: #404041; +} + +.__semibold { + font-family: "MyriadPro-SemiBold" !important; + color: #404041; + font-size: 22px !important; +} + +.__text_bold_lisence { + font-family: "MyriadPro-SemiBold" !important; + color: #404041; + font-size: 18px !important; +} + +.__fontnormal { + font-family: "MyriadPro" !important; +} + +.__text_empty_tutorial_guide { + color: #707070; + font-size: 20px; + text-align: center; + font-family: "MyriadPro"; +} + +.__horizontal_center { + margin-top: 108px; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + width: 68%; + position: absolute; +} + +.__horizontal_center_over { + width: 100%; +} + +.__horizontal_center .__text_empty, +strong { + font-size: 20px; + color: #707070; + font-family: "MyriadPro-SemiBold"; + margin-top: 20px; + text-align: center; +} + +.tuvung-slider-custom { + padding-bottom: 40px; +} + +.align-items-baseline { + align-items: baseline; +} + +.position-relative { + position: relative; +} + +.__diamond_total { + margin-left: 30px; +} + +.__ico_diamond { + position: absolute; + left: -25px; +} + +.__diamond_number { + padding: 9.5px 15px 9.5px 30px; + background-color: #e0e0e0; + border-top-right-radius: 40px; + border-bottom-right-radius: 40px; +} + +.white-space-nowrap { + white-space: nowrap; +} + +.__custom_percent { + width: 60px; + height: 60px; +} + +.__custom_size_img { + width: 60px; + height: 60px; +} + +.mr-5 { + margin-left: 5px; +} + +.font-family-bold { + font-family: "MyriadPro-Bold" !important; +} + +.justify-content-center { + justify-content: center; +} + +.__top_assess_rank { + bottom: 0; + width: 25px; + height: 25px; +} + +.font-weight-bold { + font-weight: bold; +} + +.horizontal-space-between { + display: flex; + justify-content: space-between; + align-items: center; +} + +.origin-vertical { + display: flex; + flex-direction: column; +} + +.history-curriculum-student-page { + max-height: calc(100vh - 130px); + overflow: auto; + margin-top: 30px; +} + +.listview-history { + background-color: #fff; + box-shadow: 0px 0px 10px #ccc; + border-radius: 10px; + margin-left: 10%; + margin-right: 10%; + min-width: 360px; + margin-top: 20px; +} + +.listview_history_homepage { + min-height: 216px; + border-radius: 30px; +} + +.listview-history .item-history-student { + margin: 10px; + border-bottom: 1px solid #ccc; + padding: 10px; + margin-top: 0px; +} + +.listview-history .item-history-student .view-score { + font-size: 22px; + background-color: #00a69c; + border-radius: 6px; + padding: 0px 15px; + color: #fff; + font-weight: 600; +} + +.color-confirm-success { + color: #00b7b5; +} + +.color-confirm-success-2 { + color: #0b9300; +} + +.color-confirm-danger { + color: #fc9d24; +} + +.view-lession-detail { + padding: 5px 20px; + background-color: #fff; + box-shadow: 0px 0px 10px #ccc; + border-radius: 10px; + margin-left: 10%; + margin-right: 10%; + min-width: 360px; +} + +.mg-top-10 { + margin-top: 10px; +} + +.mr-top-1 { + margin-top: 1rem; +} + +.link-to-url { + color: #00b7b5; + text-decoration: underline; +} + +.master-unit .group-tab-content { + display: flex; + background: #cfcfcf; + border-radius: 30px; + align-items: center; +} + +.master-unit .group-tab-content .tab-item { + padding: 0px 10px; + display: flex; + justify-content: center; + align-items: center; + color: #fff; + font-size: 20px; + font-weight: 700; + height: 50px; + cursor: pointer; +} + +.master-unit .group-tab-content .active { + background: linear-gradient(90deg, #00b9b6 0%, #00e0a1 96.16%); + border-radius: 30px; +} + +.master-unit .group-tab-content .tab-item img { + margin-right: 10px; +} + +.master-unit .listview-unit .item-data { + padding: 10px; + margin: 10px; + background: #ffffff; + box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.25); + border-radius: 20px; +} + +.master-unit .listview-unit .item-data .item-body { + border-bottom: 1px solid #787878; + padding-bottom: 10px; + margin-bottom: 16px; +} + +.master-unit .listview-unit .item-data .item-body .type-lesstion { + height: 40px; + border-radius: 20px; + font-weight: 700; + font-size: 20px; + line-height: 24px; + padding: 8px 24px; + color: #ffffff; +} + +.master-unit .listview-unit .item-data .item-body .improvement { + background: #f084ad; +} + +.master-unit .listview-unit .item-data .item-body .user_looking_back { + background: #978bf4; +} + +.master-unit .listview-unit .item-data .item-body .status-lesstion { + border: 1px dashed #bc202e; + transform: rotate(2.98deg); + font-weight: 700; + font-size: 24px; + line-height: 29px; + color: #bc202e; + padding: 6px 24px; + text-transform: uppercase; +} + +.master-unit .listview-unit .item-data .item-body .fail { + border: 1px dashed #bc202e; + color: #bc202e; +} + +.master-unit .listview-unit .item-data .item-body .pass { + border: 1px dashed #37b34a; + color: #37b34a; +} + +.mg-left-10 { + margin-left: 10px; +} + +.master-unit .listview-unit .item-data .score { + color: #ad0a22; + font-size: 18px; + line-height: 22px; + font-family: "Myriadpro-Bold"; +} + +.master-unit .listview-unit { + margin-top: 20px; + height: calc(100vh - 180px); + overflow: auto; +} + +.master-unit .listview-unit .item-data .item-footer { + padding: 0px 10px; +} + +.listview-unit .text-empty { + font-weight: 700; + font-size: 32px; + line-height: 38px; + text-align: center; + margin-top: 30px; + color: #414042; +} + +.btn-size-sm { + min-width: 125px; +} + +.space-around-content { + justify-content: space-around; +} + +.popup-filter-select-date input { + text-align: center; +} + +.box-content-writing-study-guide { + background: #fff; + border-radius: 20px; + margin: 0 0 30px 20px; + cursor: pointer; + box-sizing: border-box; + padding: 15px; + width: 100%; +} + +.box-content-study-guide { + border-radius: 20px; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + box-sizing: border-box; + padding: 15px; + width: 100%; +} + +.content-study-guide { + max-height: calc(100vh - 410px); + max-width: 100%; +} + +.quantity_from_teacher_choose { + display: flex; + justify-content: center; + align-items: center; + top: -14px; + text-align: center; + right: 0; + color: #ffffff; + background: red; + border-radius: 50%; + min-width: 30px; + height: 30px; + font-family: "MyriadPro"; + padding-top: 5px; +} + +/* Home Page Student */ +.homepage-teacher .sunE-box-slider .slick-dots li button:before { + /* content: "\22C5" !important; + font-size: 115px !important; */ + top: -10px !important; +} + +.version-app { + font-size: 14px; + color: #565656 +} + +.manage-linking-container { + margin-top: 50px; + width: 100%; + display: flex; + justify-content: center; +} + +.manage-linking-btn { + height: 40px; + width: 200px; + border-radius: 20px; + padding: 0; +} + +.manage-linking-btn a { + font-size: 16px; + font-weight: 600; + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; +} + +.content-text-has-link a { + color: #00CC83 !important; + /* text-decoration: underline; */ +} + +.title-dot::before { + content: "•"; + color: red; + padding-right: .5em; + font-size: 1.7rem; +} + +.content-dot::before { + content: "•"; + color: #000; + padding-right: .5em; + font-size: 1.2rem; +} + +.profile-input-select { + width: 33%; +} + +.profile-input-select input { + width: 100% !important; + font-size: 16px !important; + text-overflow: ellipsis; +} + +.profile-input-select .icon_label { + width: 20px !important; + margin-right: 12px !important; +} + +.text-view-detail-entrance { + text-decoration: underline; + font-size: 16px; + color: #F29500; + padding-top: 10px; + margin-right: 16px; + cursor: pointer; +} + +.text-view-detail-entrance:hover { + opacity: 0.4; +} + +#keepReviewPersonal[type="checkbox"] { + accent-color: #00a69c !important; + } \ No newline at end of file diff --git a/public/assets/css/button.css b/public/assets/css/button.css new file mode 100644 index 0000000..430059e --- /dev/null +++ b/public/assets/css/button.css @@ -0,0 +1,49 @@ +.btn-line-blue{ + padding: 0 25px; + height: 40px; + border-radius: 20px; + border: none; + background-image: linear-gradient(to right, #00b9b7 , #00e1a0); + font-size: 16px; + line-height: 40px; + color: #fff; + /* transition: 0.8s; */ + font-family: 'Myriadpro-SemiBold'; + /* min-width: 100px; */ +} + +.btn-line-blue.border-transparent{ + border: 2px solid transparent; +} +.btn-line-blue:hover{ + /* background-image: linear-gradient(to top, #00b9b7 , #00e1a0); */ + transition: 0s; + background: #00C0B4; + color: #ffffff; +} +.btn-custom-hei{ + height: 36px; + line-height: 36px; + border-radius: 18px; +} +.btn-line-blue.btn-p35{ + padding: 0 35px; +} +@media screen and (max-height: 700px) { + .btn-line-blue { + padding: 0 15px; + height: 32px; + line-height: 32px; + border-radius: 16px; + border: none; + font-size: 14px; + background-image: linear-gradient(to right, #00e1a0 , #00b9b7); + color: #fff; + /* transition: 0.8s; */ + font-family: 'Myriadpro-SemiBold'; + /* min-width: 80px; */ + } + .btn-line-blue.btn-p35{ + padding: 0 25px; + } +} \ No newline at end of file diff --git a/public/assets/css/change_password.css b/public/assets/css/change_password.css new file mode 100644 index 0000000..cd90d3b --- /dev/null +++ b/public/assets/css/change_password.css @@ -0,0 +1,114 @@ +.header-change-password { + height: 20vh; + background-image: linear-gradient(to right, #03c6b8, #009393); + display: flex; + align-items: center; + min-height: 175px; +} + +.header-change-password .logo { + width: 220px; + margin-left: 50px; +} + +.header-change-password .logo img { + width: 100%; + object-fit: cover; +} + +.change-password-container { + background: #e6e7e9; + display: flex; + flex-wrap: wrap; + justify-content: center; + padding: 50px 20px; + height: 80vh; + min-height: 500px; +} + +.form-change-password { + box-shadow: 0 1px 15px 0 rgba(21, 27, 38, .15); + background: #ffffff; + border: 0; + border-radius: 20px; + text-align: center; + width: 100%; + max-width: 750px; + max-height: 400px; +} + +.form-change-password h2.title { + font-size: 18px; + color: #000000; + margin-top: 20px; + font-weight: 700; +} + +.form-change-password form { + margin: 20px; + display: flex; + flex-wrap: wrap; + flex-direction: row; + justify-content: center; +} + +.form-change-password-input { + margin: 0 10px 15px 10px; + width: 100%; + max-width: 350px; +} + +.form-change-password-input input { + height: 60px; + width: 100%; + line-height: 60px; + font-size: 18px; + box-sizing: border-box; + padding-left: 30px; + border-radius: 20px; + background: #e6e7e9; + border: 0; + outline: none; +} + +.form-change-password-input.err input { + border: solid 1px #e22028; +} + +.form-change-password-input button { + height: 60px; + width: 100%; + line-height: 60px; + font-size: 18px; + color: #ffffff; + font-weight: 700; + text-align: center; + border: 0; + border-radius: 20px; + outline: none; + background: #00b8b6; +} + +.form-change-password-input .ico_input_right { + position: absolute; + top: 18px; + right: 20px; +} + +.form-change-password-input .error-help { + margin-top: 10px; +} + +.form-change-password-input.err .error-help img { + position: absolute; + top: 0; + left: 0; +} + +.form-change-password-input.err .error-help p { + font-size: 18px; + color: #e22028; + line-height: 31px; + margin: 0; + padding: 0 0 0 40px; +} \ No newline at end of file diff --git a/public/assets/css/input.css b/public/assets/css/input.css new file mode 100644 index 0000000..520836d --- /dev/null +++ b/public/assets/css/input.css @@ -0,0 +1,194 @@ +.form-sunE-input { + margin: 20px 0 0; +} + +.form-sunE-input input { + height: 44px; + width: 100%; + line-height: 44px; + font-size: 16px; + box-sizing: border-box; + padding-left: 60px; + border-radius: 22px; + outline: none; + border: 2px solid #fff; + box-shadow: 0 1px 8px 0 rgba(21, 27, 38, 0.15); +} +.form-sunE-input .ico_input { + position: absolute; + top: 7px; + left: 15px; + z-index: 1; +} +.width-22 { + width: 22px; +} + +.form-sunE-input .ico_phone { + left: 18px; +} +.form-sunE-input .ico_top_3 { + top: 3px; +} + +.form-sunE-input.ico_left_custom input { + padding-left: 60px; +} + +.checkbox-gr input { + margin: -3px 5px 0 0; + width: 16px; + height: 16px; + border: 1px solid #00b9b7; + font-size: 16px; +} + +.err input { + border-color: #e22028; +} + +.select-hidden { + display: none; + visibility: hidden; + padding-right: 10px; +} + +.select { + cursor: pointer; + display: inline-block; + position: relative; + font-size: 16px; + color: #fff; + width: 100%; + height: 48px; + line-height: 48px; + border-radius: 24px; + border: none; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); +} + +.select-styled { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); + width: 100%; + height: 48px; + line-height: 48px; + border: none; + /* transition: all 0.2s ease-in; */ + border-radius: 24px; + color: #fff; + font-size: 16px; + text-align: center; + font-family: "Myriadpro-Bold"; + z-index: 10; + display: flex; +} + +.select-styled:after { + content: ""; + width: 32px; + height: 32px; + background: url("./../images/icon/ico_dropdown_border_white.png") 98% / 32px + no-repeat transparent; + position: absolute; + top: 8px; + right: 10px; +} +.select-styled.active:after { + border-color: transparent transparent #fff transparent; +} +.select-options { + display: none; + position: absolute; + padding: 24px 40px 0; + top: 24px; + right: 0; + left: 0; + z-index: 9; + margin: 0; + list-style: none; + background-color: #fff; + border-radius: 24px; + border-top-right-radius: 0; + border-top-left-radius: 0; + border: none; + box-shadow: 0 1px 15px 0 rgba(21, 27, 38, 0.15); + max-height: calc(100vh - 100px); + overflow: auto; +} +.select-options li { + margin: 0; + text-indent: 15px; + transition: all 0.15s ease-in; + border-bottom: 1px solid #000; + text-align: center; + display: flex; +} +.select-options li:last-child { + border-bottom: none; +} +.select-options li[rel="hide"] { + display: none; +} + +.select-options.left li { + text-align: left; +} +.select .image-selected { + margin-right: 1rem; +} +.select .image-option { + width: 30px; + height: 30px; + border-radius: 100%; + align-self: center; + display: flex; + border: 1px solid var(--primary-green); +} + +.select .image-option.image-option-logo { + border: 1px solid var(--light-yellow); +} + +.select .image-option img { + width: 26px; + height: 18px; + object-fit: contain; + margin: auto; +} + +@media screen and (max-height: 700px) { + .select { + font-size: 13px; + height: 32px; + line-height: 32px; + border-radius: 16px; + } + + .select-styled { + height: 32px; + line-height: 32px; + border-radius: 16px; + font-size: 14px; + } + + .select-styled:after { + content: ""; + width: 26px; + height: 26px; + top: 4px; + right: 5px; + background: url(./../images/icon/ico_dropdown_border_white.png) 96% / 26px + no-repeat transparent; + } + .select-options { + padding: 32px 32px 0; + top: 0; + border-radius: 18px; + max-height: calc(100vh - 90px); + } +} diff --git a/public/assets/css/login.css b/public/assets/css/login.css new file mode 100644 index 0000000..ceb9287 --- /dev/null +++ b/public/assets/css/login.css @@ -0,0 +1,189 @@ +.max430 { + max-width: 400px; + margin: 0 auto; +} +.top-image img { + width: 100%; + height: auto; + display: block; +} +h2.title { + font-family: "Myriadpro-Bold"; + font-size: 18px; +} +.login-form-container { + padding: 0; +} +.res-form-container { + padding: 40px 0 40px; +} +.help-block { + margin: 20px 0 0; + padding: 0 15px; +} +.form-sunE-button { + margin: 20px 0; + text-align: center; +} +.sunE-main-title .form-sunE-button { + margin: 0; +} +.sunE-custom-form a:hover { + color: #00b9b7; + text-decoration: none; +} +.sunE-line-or { + margin: 40px 0 0; +} +.sunE-line-or span { + width: 80px; + background: #f3ffff; + position: absolute; + display: block; + top: -9px; + left: calc(50% - 40px); + text-align: center; +} +.more-login { + margin: 30px 0 0; +} +.more-login img { + cursor: pointer; +} +.mr-5 { + margin-right: 5px; +} +.ml-5 { + margin-left: 5px; +} +.sunE-bottom-form { + margin: 20px 0 0; +} +.sunE-bottom-form p { + text-align: center; +} +.sunE-bottom-form p a { + font-family: "Myriadpro-Bold"; +} + +.sendMail-title { + color: #00b9b7; + margin: 100px 0 0px; +} +.profile-title { + color: #00b9b7; + margin: 30px 0; +} +.sunE-male-female { + width: 44px; + height: 44px; + text-align: center; + background: #fff; + border-radius: 33px; + border: none; + box-shadow: 0 1px 15px 0 rgba(21, 27, 38, 0.15); + margin: 20px 0 0 10px; + line-height: 60px; + display: inline-block; + cursor: pointer; +} + +.ico_male, +.ico_male_active { + width: 26px; + margin: 10px auto; +} +.ico_female, +.ico_female_active { + width: 20px; + margin: 5px auto; +} +.sunE-male-female.male .ico_male_active { + display: none; +} +.sunE-male-female.male .ico_male { + display: block; +} +.sunE-male-female.male.active .ico_male_active { + display: block; +} +.sunE-male-female.male.active .ico_male { + display: none; +} +.sunE-male-female.female .ico_female_active { + display: none; +} +.sunE-male-female.female .ico_female { + display: block; +} +.sunE-male-female.female.active .ico_female_active { + display: block; +} +.sunE-male-female.female.active .ico_female { + display: none; +} +.error-help { + margin: 20px 0 20px 15px; +} +.customErrorHelpClassName { + margin: 20px 0 0 0; +} +.error-help p { + font-size: 18px; + color: #e22028 !important; + line-height: 21px; + margin: 0; + padding: 0 0 0 0px; +} +.bg-login { + background-image: url("./../images/bg_auth_full_1.png"); + background-repeat: no-repeat; + background-size: cover; + min-height: 100vh; +} +.bg-login .version-app { + position: absolute; + bottom: 10px; + right: 10px; +} +.bg-register { + background-image: url("./../images/bg_auth_full_1.png"); + background-repeat: no-repeat; + background-size: cover; + min-height: 100vh; +} + +.bg-login .logo img, +.bg-register .logo img { + margin-top: 7px; +} + +.btn-re { + text-decoration: underline; +} +.more-login img { + width: 56px; +} +.form-sunE-button.mar-b-0 { + margin-bottom: 0 !important; +} +@media screen and (max-height: 800px) { + .error-help p { + font-size: 14px; + line-height: 20px; + } +} +@media screen and (max-width: 768px) { + .sunE-form-container { + padding: 0 10px; + } + .login-form-container { + padding: 100px 16px 40px; + } + .res-form-container { + padding: 100px 10px 40px; + } + .register_account_type .account_detail_placeholder { + height: 100px; + } +} diff --git a/public/assets/css/responsive.css b/public/assets/css/responsive.css new file mode 100644 index 0000000..9589815 --- /dev/null +++ b/public/assets/css/responsive.css @@ -0,0 +1,5630 @@ +@media screen and (max-height: 800px) { + /*RESET CSS*/ + html, + body, + div, + span, + object, + iframe, + h1, + h2, + h3, + h4, + h5, + h6, + p, + blockquote, + pre, + abbr, + address, + cite, + code, + del, + dfn, + em, + img, + ins, + kbd, + q, + samp, + small, + strong, + sub, + sup, + var, + b, + i, + dl, + dt, + dd, + ol, + ul, + li, + fieldset, + form, + label, + legend, + table, + caption, + tbody, + tfoot, + thead, + tr, + th, + td, + article, + aside, + canvas, + details, + figcaption, + figure, + footer, + header, + hgroup, + menu, + nav, + section, + summary, + time, + mark, + audio, + video { + /* font-size: 16px; */ + } + + .sunE-container { + width: 100%; + height: auto; + max-width: 1200px; + margin: 0 auto; + /* padding: 0; */ + } + + .homepage-teacher.sunE-container-box { + padding: 10px 20px 0px; + } + + .list-menu-i a.menu-item { + font-size: 14px; + color: #404041; + line-height: 34px; + align-items: center; + padding: 10px 0 10px 32px; + text-decoration: none; + margin: 8px 0; + } + + .list-menu-i .menu-img { + width: 60px; + max-height: 32px; + } + + .list-menu-i .menu-img img { + width: 30px; + } + + .list-menu-i a.menu-item span { + font-size: 14px; + color: #404041; + } + + .sunE-sidebar { + width: 255px; + } + + .plan-item-content p { + font-size: 14px; + } + + .btn-plan-item { + width: 21px; + } + + .his img { + width: 27px; + } + + .plan-item-content p.text-light { + padding: 0 0 0 10px; + } + + .slider-custom-2 .slick-arrow.slick-prev { + left: -10px; + } + + /* Slider for student homepage */ + + .slider_homepage_student .slider-custom-student { + /* margin-bottom: 1.1rem !important; */ + } + + .slider-custom-student .slick-arrow.slick-prev { + left: 33px; + } + + .slider-custom-2 .slick-next, + .slider-custom-2 .slick-prev { + width: 42px; + height: auto; + } + + .slider-custom-2 .slick-arrow { + background: #00bbb6; + padding: 12px 14px; + position: absolute; + border-radius: 12px; + border: none; + z-index: 9; + text-align: center; + } + + .item-top-title-main p { + text-align: center; + font-size: 17px; + padding: 0; + color: #fff; + font-family: "Myriadpro-SemiBold"; + } + + .slick-dots li button:before { + font-size: 7px; + line-height: 17px; + position: absolute; + top: 0; + left: 0; + width: 14px; + height: 14px; + content: "•"; + text-align: center; + opacity: 0.25; + color: #000; + } + + .slider-custom-2 .slick-dots li button:before { + font-size: 14px; + color: #00a79d; + } + + .slider-item-content .img-thumb { + margin: 12px; + width: 237px; + height: 210px; + border-radius: 12px; + overflow: hidden; + } + + .slider-custom-2 .slider-item-content { + margin: 12px; + padding: 6px 13px; + } + + /* For Student */ + .slider-custom-student .slider-item-content { + margin: 12px; + padding: 6px 9px; + } + + .slider-custom-student .slider_student_wrapper .slider-item-content { + margin-top: 0.75rem !important; + margin-bottom: 0.6rem !important; + } + + .slider-item-desc .item-top-title-main { + margin: 12px 0; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); + padding: 12px 24px; + border-radius: 30px; + max-height: 66px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + margin-bottom: 25px; + } + + .edit-plan-box .btn p { + font-size: 14px; + line-height: 14px; + } + + .edit-plan-box .btn img { + width: 24px; + } + + .sunE-right-container { + width: 100%; + height: 100vh; + overflow: auto; + padding: 36px 16px 10px 16px; + } + + .sunE-container-box.diemdanh { + padding: 20px 0 10px; + } + + .sunE-container-box { + padding: 24px 12px 12px; + } + + .orange span, + .red span, + .success-text span { + line-height: 27px; + } + + .chart-content canvas { + margin-left: 0; + } + + .sunE-plan-list { + max-height: 330px; + overflow: auto; + padding-right: 9px; + } + + .no-plan img { + width: 243px; + } + + .no-plan h2 { + font-family: "Myriadpro-SemiBold"; + font-size: 21px; + padding: 0; + margin: 0; + color: #00a79d; + } + + .dtb-sum-slider { + bottom: -45px; + } + + .dtb-sum-slider .w { + width: 168px; + } + + .slider-custom-2 .dtb-sum-slider .w { + width: 194px; + } + + .img-check-calendar { + top: -1px; + right: -6px; + width: 16px; + } + + .class-box .class-box-img { + width: 127px; + height: 103px; + } + + .title-line-blue { + font-size: 17px; + line-height: 21px; + padding: 7px; + text-align: center; + border-radius: 17px; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); + } + + .two-line { + max-height: 53px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + } + + .class-box-desc p, + .class-box-desc span { + font-size: 15px; + } + + .class-box-desc span.class-online, + .class-box-desc span.class-offline { + font-size: 18px; + font-family: "Myriadpro-SemiBold"; + } + + .sunE-main-title h1 { + font-size: 28px; + line-height: 38px; + padding-left: 7px; + } + + .sunE-main-title .line-h { + display: block; + width: 3px; + height: 35px; + background: #00bbb5; + border-radius: 2px; + border: none; + } + + .sunE-class-list { + padding-right: 17px; + max-height: calc(100vh - 190px); + padding-bottom: 28px; + overflow: auto; + } + + .class-index-box .class-index-box-img { + width: 244px; + height: 234px; + } + + .class-index-box { + box-sizing: border-box; + padding: 13px; + border-radius: 17px; + background: #fff; + display: inline-block; + width: 100%; + } + + .info-gr .info-img { + width: 28px; + } + + .info-gr { + margin: 11px 0 0; + } + + .info-gr img { + height: 18px; + cursor: pointer; + } + + .info-gr .info-con p { + font-size: 15px; + font-family: "Myriadpro-Light"; + line-height: 26px; + } + + .class-select-box { + padding: 17px 0px 0; + display: inline-block; + width: 140px; + height: 140px; + background: #fff; + margin: 0 6px; + border-radius: 12px; + border: none; + cursor: pointer; + box-sizing: border-box; + overflow: hidden; + } + + .class-select-box .select-img { + height: 78px; + } + + .class-select-box img { + height: 100%; + } + + .class-select-box p { + font-size: 15px; + padding: 9px 0 0; + margin: 0; + } + + .box-giaotrinh-gr.hei-custom.edit { + height: 130px; + padding: 0 13px 0 28px; + margin: 0 0 17px 0; + } + + .box-select-info p { + color: #221f1f; + font-size: 17px; + line-height: 21px; + } + + .box-select-info span { + font-size: 15px; + } + + .box-select-file-full { + flex: 1; + } + + .box-select-file-full p { + flex: 1; + text-align: left; + } + + .gtcn-menu-gr span { + font-size: 21px; + margin-right: 26px; + } + + .box-giaotrinh-gr.hei-custom { + height: 80px; + } + + .box-giaotrinh-gr .thumb { + position: absolute; + top: -5px; + left: -26px; + display: flex; + justify-content: center; + align-items: center; + background: #fff; + border: 3px solid #fff; + border-radius: 50%; + width: 65px; + height: 65px; + box-shadow: 0 1px 8px 0 rgb(21 27 38 / 24%); + } + + .box-giaotrinh-gr .thumb3 { + position: absolute; + top: -5px; + left: -26px; + display: flex; + justify-content: center; + align-items: center; + background: #ccedeb; + border: 3px solid #fff; + border-radius: 50%; + width: 65px; + height: 65px; + box-shadow: 0 1px 8px 0 rgb(21 27 38 / 24%); + } + + .box-giaotrinh-gr .thumb img { + width: 45px; + height: 45px; + object-fit: contain; + } + + .box-giaotrinh-gr .thumb3 img { + width: 35px; + height: 35px; + object-fit: contain; + } + + .box-giaotrinh-gr .thumb2 { + width: 75px; + height: 75px; + } + + .box-giaotrinh-gr.hei-custom .thumb { + top: 13px; + } + + .box-giaotrinh-gr.hei-custom .thumb3 { + top: 13px; + } + + .gt_list_hei { + max-height: calc(100vh - 280px); + padding: 0 13px; + overflow: auto; + } + + .btn-user-add img, + .btn-user-share img { + width: 37px; + } + + .sunE-title-medium { + font-size: 18px; + margin: 0; + padding: 0 0 17px; + } + + .sunE-right-container.add_student_container { + padding: 35px 16px 0 16px; + } + + .add_student { + height: calc(100vh - 103px); + width: 100%; + } + + .sunE-no-student .add_code_student-gr { + top: 480px; + } + + .add_code_student-gr { + width: 368px; + position: absolute; + left: 50%; + top: 510px; + transform: translate(-50%, -50%); + } + + .sunE-input-border-blue-gr input { + height: 37px; + border: 1px solid #399098; + border-radius: 18px; + padding: 0 41px; + } + + .sunE-input-border-blue-gr .ico_input { + position: absolute; + /* top: 7px; */ + /* left: 11px; */ + width: 28px; + } + + .btn-filter button { + padding: 0 30px 0 40px; + } + + .btn-filter img { + position: absolute; + top: 10px; + left: 24px; + width: 17px; + } + + .sunE-giaotrinh-item .img { + width: 104px; + height: 95px; + } + + .sunE-giaotrinh-item .content { + padding-left: 17px; + padding-top: 8px; + } + + .sunE-giaotrinh-item .content h2.title { + font-size: 16px; + line-height: 20px; + } + + h2.title { + font-family: "Myriadpro-Bold"; + font-size: 16px; + } + + .sunE-giaotrinh-item .content h3.desc { + font-size: 16px; + line-height: 20px; + margin: 0 0 8px; + } + + .sunE-giaotrinh-item .content .easy, + .sunE-giaotrinh-item .content .hard, + .sunE-giaotrinh-item .content .medium, + .sunE-giaotrinh-item .content .normal { + padding: 3px 8px; + } + + .lb-dc-gr .lb { + margin-right: 8px; + } + + .lb-dc-gr span { + color: #fff; + font-size: 14px; + padding: 4px 13px; + border-radius: 12px; + line-height: 18px; + } + + .topic { + background: #fff; + padding: 26px 18px; + border-radius: 18px; + margin: 0 0 13px; + } + + .cb-score-gr p { + font-size: 15px; + margin: 0 0 8px; + } + + .cb-score-gr span { + font-size: 28px; + font-family: "Myriadpro-Bold"; + color: #00a69c; + } + + .item-student .item-student-img { + width: 61px; + height: 61px; + border-radius: 31px; + } + + .list-detail .item-student { + background: #fff; + border-radius: 18px; + padding: 8px 8px 8px 26px; + margin: 0 0 8px 47px; + min-height: 90px; + } + + .list-detail .item-student-img { + position: absolute; + top: 10px; + left: -41px; + width: 73px; + height: 73px; + border-radius: 37px; + overflow: hidden; + } + + .item-student-name h2 { + font-size: 16px; + line-height: 18px; + margin: 12px 0 12px; + } + + .list-detail .item-student .item-student-name span { + font-size: 16px; + line-height: 32px; + } + + .list-detail .item-student .item-student-name img { + width: 32px; + } + + .box-title-bg { + border-radius: 21px; + height: 37px; + } + + .box-title-bg p { + font-size: 20px; + /* line-height: 42px; */ + } + + .box-criteria-score-title p { + font-size: 16px; + padding-left: 13px; + } + + .box-criteria-comment h2 { + font-size: 21px; + padding-left: 30px; + margin: 0 0 6px; + } + + .box-criteria-comment textarea { + padding: 13px 13px 8px 26px; + border-radius: 18px; + resize: none; + width: 100%; + height: 200px; + } + + .post-content { + background: #fff; + padding: 26px 18px; + border-radius: 18px; + margin: 0; + } + + .title-post-box { + font-size: 21px; + line-height: 35px; + } + + .btn-mark { + height: 35px; + line-height: 35px; + padding: 0 0 0 18px; + box-sizing: border-box; + border-radius: 20px; + border: none; + cursor: pointer; + margin: 0 8px 0 0; + } + + .btn-mark p { + font-size: 16px; + padding: 0 30px; + } + + .btn-mark img { + width: 32px; + } + + .btn-help { + height: 35px; + line-height: 35px; + border-radius: 20px; + border: none; + cursor: pointer; + padding: 0 26px; + } + + .btn-help img { + width: 16px; + } + + .chambai.writing { + margin: 0 0 13px; + } + + .post-content .content-box-edit { + padding: 13px 13px 8px 30px; + border-radius: 18px; + resize: none; + width: 100%; + font-size: 15px; + height: 170px; + overflow: auto; + } + + .popup-tag { + padding: 8px; + font-size: 18px; + } + + .sunE-giaobai-list { + padding: 18px 26px; + border-radius: 18px; + max-height: calc(100vh - 190px); + margin: 0 0 5px; + } + + .bg_no_gb { + width: 340px; + } + + .sunE-giaotrinh-item .content p, + .sunE-giaotrinh-item .content span { + font-size: 16px; + line-height: 21px; + margin: 0 0 8px; + } + + .wh27 { + width: 23px; + height: 23px; + } + + .btn-setting img { + top: 7px; + left: 17px; + width: 25px; + } + + .box-info-giaobai { + background: #fff; + padding: 24px 18px; + border-radius: 18px; + } + + .box-info-giaobai h3.desc { + font-size: 16px; + line-height: 21px; + margin: 0 0 26px; + } + + .box-info-giaobai p { + font-size: 15px; + line-height: 21px; + margin: 0 0 8px; + } + + .sunE-container-box.giaobai-ganday { + padding: 23px 18px 0; + } + + .list-giaobai.chualam { + max-height: calc(100vh - 260px); + } + + .item-student .stt { + line-height: 61px; + font-size: 15px; + width: 26px; + } + + .btn-check-gr { + padding-top: 15px; + } + + .f20 { + font-size: 18px !important; + } + + .sunE-input-group label { + display: block; + margin: 0; + padding: 0 0 8px; + font-size: 18px; + color: #000; + } + + .select-gr select { + width: 37px; + height: 47px; + border-radius: 12px; + font-size: 15px; + } + + .check-box-gr label { + font-size: 15px; + } + + .datlichnhac-input-gr .left, + .datlichnhac-input-gr .right { + font-size: 15px; + } + + .datlichnhac-input-gr input.dln-mins { + height: 37px; + outline: none; + border: none; + border-radius: 18px; + padding: 6px 18px; + box-shadow: 0 1px 6px 0 rgb(21 27 38 / 15%); + box-sizing: border-box; + text-align: center; + font-size: 15px; + } + + input.dln-mins::-webkit-outer-spin-button, + input.dln-mins::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + + .nhacnho-content .datlichnhac-input-gr input.dln-mins { + width: 71px; + } + + .err-nhacnho img { + margin: 13px 0 0; + } + + .nhacnho-content textarea { + height: 75px; + border-radius: 18px; + padding: 9px 18px; + font-size: 15px; + } + + .check-date-time-week { + width: 380px; + height: 37px; + background: #fff; + border-radius: 18px; + padding: 0 13px; + } + + .check-date-time-week img { + width: 12px; + } + + .check-date-time-week p { + font-size: 17px; + line-height: 37px; + } + + .student-list-container { + width: 330px; + } + + .tong-hs { + line-height: 21px; + font-size: 16px; + font-family: "Myriadpro-SemiBold"; + margin: 0 0 18px; + } + + .text-title-blue { + font-size: 16px; + } + + .box-chart p { + font-size: 16px; + } + + .dtb-sum .w { + width: 266px; + } + + .bdg-sum .w { + width: 248px; + } + + .f-24 { + font-size: 21px; + } + + .sunE-title-medium-p { + font-size: 16px; + line-height: 16px; + margin: 0 0 13px; + } + + .custom-list-student { + padding: 18px; + border-radius: 18px; + } + + .bcht .list-student { + max-height: calc(100vh - 260px); + } + + .student-info { + width: 300px; + margin-right: 18px; + } + + .student-info .avt-i { + width: 156px; + height: 156px; + border-radius: 78px; + border: 2px solid #e7ae38; + margin: 0 auto 18px; + } + + .student-info .name { + font-size: 21px; + margin: 0 0 12px; + } + + .email-gr img { + width: 20px; + } + + .email-gr p { + font-size: 16px; + line-height: 22px; + max-width: 200px; + } + + .box-bcht-top h2 { + font-size: 16px; + line-height: 37px; + } + + .btn-history-bcht { + border: 2px solid #00b9b7; + line-height: 33px; + height: 37px; + border-radius: 18px; + padding: 0 30px; + font-size: 16px; + } + + .title-info { + border-radius: 18px; + height: 37px; + padding-left: 18px; + } + + .title-info p { + line-height: 37px; + font-size: 16px; + } + + .score-info { + border-radius: 18px; + height: 37px; + width: 73px; + } + + .score-info p { + line-height: 37px; + font-size: 16px; + } + + .title-info.dtb-title p { + line-height: 18px; + font-size: 16px; + } + + .bcht { + padding: 20px 0 0; + } + + .box-bcht-date-custom-hei.box-bcht { + padding: 0; + width: 436px; + } + + .box-bcht-date-custom-hei .calendar .week-cell, + .box-bcht-date-custom-hei .calendar .day-cell { + flex-grow: 0; + flex-shrink: 0; + flex-basis: calc(100% / 7 - 22px); + display: flex; + justify-content: center; + align-items: center; + height: 35px; + width: 35px; + cursor: pointer; + margin: 5px 0px; + } + + .box-bcht.box-bcht-date-custom-hei .calendar .week-cell, + .box-bcht.box-bcht-date-custom-hei .calendar .day-cell { + flex-basis: calc(100% / 7 - 27px); + margin: 5px 0px; + } + + .collapse.showMonth .calendar { + height: 160px; + } + + .fullHeight.showMonth .calendar { + height: auto; + } + + .item-student-name p { + font-size: 15px; + } + + .item-student-name.max-w-1 p { + max-width: 160px; + } + + .score-tb-student span { + width: 75px; + height: 40px; + line-height: 40px; + font-size: 21px; + } + + .top p { + font-size: 18px; + } + + .vinhdanh-item img.vinhdanh-bg { + width: 168px; + } + + .avt-vd { + width: 94px; + height: 94px; + border-radius: 47px; + border: 2px solid #e9af38; + margin: 18px auto 0; + } + + .name-vd { + padding: 0 18px; + line-height: 32px; + font-size: 16px; + color: #fff; + border-radius: 18px; + position: absolute; + top: 94px; + left: 50%; + transform: translate(-50%, 0); + } + + .vd-info { + bottom: 9px; + font-size: 16px; + } + + .vinhdanh-content { + padding: 24px 0 0; + } + + .diemdanh-no-item img { + width: 363px; + } + + .diemdanh-no-item p { + font-size: 21px; + } + + .btn-create-diemdanh img { + width: 18px; + top: 10px; + } + + .btn-create-diemdanh button { + padding: 0 18px 0 47px; + } + + .medium-title { + font-size: 16px; + } + + .menu-gr-right input[type="text"].btn { + height: 42px; + border-radius: 21px; + font-size: 16px; + line-height: 42px; + padding: 0 28px; + } + + .btn-ob.select { + font-size: 16px; + height: 42px; + line-height: 42px; + border-radius: 21px; + } + + .btn-ob .select-styled { + border-radius: 21px; + font-size: 16px; + line-height: 42px; + height: 42px; + padding: 0 28px; + } + + .btn-ob .select-styled:after { + content: ""; + width: 21px; + height: 12px; + top: 16px; + right: 9px; + background: url(./../images/teacher/diemdanh/ico_dropdown_blue.png) 90% / + 21px no-repeat transparent; + } + + .btn-ob .select-styled.active:after { + background: url(./../images/teacher/diemdanh/ico_dropup_blue.png) 90% / 21px + no-repeat transparent; + } + + .btn-ob .select-options { + padding: 21px 22px 0; + } + + .btn-ob .select-options li { + text-indent: 21px; + } + + .menu-gr-right .react-datepicker-wrapper input[type="text"] { + height: 42px; + border-radius: 21px; + font-size: 16px; + line-height: 42px; + padding: 0 28px; + } + + .box-select-gr { + border-radius: 18px; + padding: 26px 0 26px 30px; + margin: 0 0 13px 18px; + } + + .box-select-gr .thumb { + position: absolute; + top: -3px; + left: -26px; + border: 5px solid #fff; + width: 92px; + height: 92px; + } + + .box-select-info h2 { + font-size: 16px; + line-height: 18px; + } + + .box-giaotrinh-gr { + border-radius: 18px; + height: 56px; + margin: 0 0 26px 18px; + padding: 0 13px 0 56px; + } + + .custom-select-no-bg .select-styled { + padding-left: 56px; + } + + .custom-select-no-bg .select-styled { + height: 37px; + border-radius: 18px; + font-size: 15px; + padding-right: 37px; + line-height: 37px; + /* background: url(./../images/icon/ico_dropdown_s.png) 96% / 18px no-repeat + #fff; */ + } + + .custom-select-no-bg .select { + font-size: 15px; + width: 100%; + height: 37px; + line-height: 37px; + border-radius: 19px; + } + + .btn-bar img { + height: 37px; + } + + .sunE-container-box.giaotrinh.unit { + padding: 0 18px; + } + + .sunE-unit-item h2 { + font-size: 20px; + } + + .sunE-unit-item p { + font-size: 15px; + } + + .img-bg-x { + width: 163px; + height: 250px; + background-size: 100%; + margin: auto; + } + + .img-bg-x .__avt_unit { + margin-top: 35px; + margin-left: -5px; + } + + .__way_map { + position: absolute; + transform: translate(75%, 115%); + } + + .__way_map_down { + position: absolute; + transform: translate(65%, 190%); + } + + .border-dash-map-down { + top: 238px; + } + + .border-dash-map-up { + top: 250px; + } + + .sunE-unit-item .h-287 { + height: 250px; + } + + .giaotrinh.unit .unit-list .box-giaotrinh-gr { + border-radius: 30px; + height: 47px; + } + + .btn-more-info { + width: 37px; + height: 37px; + border-radius: 19px; + right: 7px; + top: 5px; + } + + .btn-more-info img { + width: 13px; + } + + .btn-more-info .show_ { + margin: 16px 0 0 1px; + width: 9px; + } + + .info-item-desc h2 { + font-size: 15px; + line-height: 18px; + } + + .sunE-giaotrinh-resuft-filter { + padding: 18px 28px; + border-radius: 18px; + max-height: calc(100vh - 250px); + } + + .chk-custom-gr label:before { + padding: 10px; + margin-right: 9px; + border-radius: 2px; + margin-top: -1px; + } + + .chk-custom-gr input:checked + label:after { + top: -8px; + left: 10px; + width: 6px; + height: 18px; + } + + .sunE-giaotrinh-item .chk-gr .chk-custom-gr label:before { + margin-top: -10px; + } + + .sunE-giaotrinh-resuft-filter.box-shadow.scrollbar-custom.flex-1 + .sunE-giaotrinh-item + .chk-gr + .chk-custom-gr + label:before { + margin-top: -5px; + } + + .select-all .wh20.chk-custom-gr input:checked + label:after { + top: -5px; + } + + /* Check box select all */ + .checbox-right .wh20.check-select-student input:checked + label:after { + top: -8px; + } + + .btn-create-taomoi button, + .btn-create-datlai button { + padding: 0 30px 0 56px; + } + + .btn-create-taomoi img { + left: 13px; + top: 9px; + width: 21px; + } + + .class-box-desc .title-line-blue { + margin: 0 0 12px; + } + + .box-btn { + width: 28px; + height: 28px; + } + + .ico_ring-res-7 { + width: 16px; + } + + .ico_message-res-7 { + width: 17px; + } + + .reng { + width: 9px; + height: 9px; + border-radius: 5px; + bottom: 0; + right: 0; + } + + .tn-menu-item p { + font-size: 16px; + } + + .tinnhan-item h2 { + font-size: 16px; + line-height: 16px; + margin: 0 0 7px; + } + + .tinnhan-item span { + font-size: 12px; + } + + .tinnhan-item p.mes-info { + font-size: 16px; + line-height: 21px; + max-height: 64px; + } + + .mex-info-box p { + font-size: 16px; + } + + .mes-box-send { + height: 46px; + line-height: 25px; + font-size: 15px; + padding: 9px 18px 9px 18px; + border-top-left-radius: 23px; + border-bottom-left-radius: 23px; + } + + .box-btn-send { + height: 46px; + width: 46px; + border-top-right-radius: 23px; + border-bottom-right-radius: 23px; + } + + .send-mes img { + width: 23px; + } + + .search-gr-p { + height: 46px; + box-sizing: border-box; + margin: 17px 0 7px; + } + + .select-message.select { + font-size: 16px; + width: 175px; + height: 42px; + line-height: 42px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .select-message .select-styled { + font-size: 16px; + width: 175px; + height: 42px; + line-height: 42px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .search-custom { + width: 350px; + height: 42px; + line-height: 42px; + padding: 0 40px 0 21px; + font-size: 18px; + font-family: "Myriadpro-Regular"; + box-sizing: border-box; + border: none; + text-align: center; + border-top-right-radius: 21px; + border-bottom-right-radius: 21px; + outline: none; + } + + .icon_search { + position: absolute; + right: 13px; + top: 12px; + width: 21px; + } + + ._line_box { + padding: 6px 0; + height: 42px; + } + + ._line { + height: 30px; + top: 6px; + } + + .select-message .select-styled:after { + content: ""; + width: 16px; + height: 9px; + background: url(./../images/tinnhan/ico_dropdown.png) 97% / 16px no-repeat + transparent; + top: 16px; + right: 28px; + } + + .class_student_list_box { + padding: 18px; + border-radius: 18px; + height: calc(100vh - 180px); + } + + .box-shadow.custom-list-student.class_student_list_box.review { + height: calc(100vh - 220px); + } + + .list-student { + max-height: calc(100vh - 220px); + } + + .mex-box.cus-hei-2 { + height: calc(100vh - 180px); + } + + .tinnhan-item .dot-active { + width: 12px; + height: 12px; + top: 12px; + left: 12px; + } + + .box-detail-hs .avt-ab { + width: 178px; + height: 178px; + border-radius: 50%; + overflow: hidden; + } + + .box-detail-hs .avt-ab { + position: absolute; + top: -94px; + left: calc(50% - 94px); + } + + .box-detail-ab { + top: 130px; + padding: 0 71px; + } + + .box-detail-ab .box-detail-hs { + border-radius: 18px; + padding: 80px 18px 13px; + width: 368px; + } + + .box-detail-hs h2.name { + font-size: 28px; + } + + .detail-info { + padding: 0 35px 13px; + } + + .info-sum h3 { + font-size: 47px; + } + + .sunE-container-box.hoso { + min-height: auto; + } + + .info-sum { + margin: 47px 0 0; + } + + .avatar-edit { + margin: 20px 0 0; + } + + .avatar-edit-box { + background: #fff; + width: 185px; + height: 185px; + border-radius: 93px; + margin: 0 auto 30px; + padding: 4px; + } + + .hoso .btn-save button { + padding: 0 40px; + height: 46px; + line-height: 46px; + border-radius: 23px; + border: none; + font-size: 18px; + color: #fff; + transition: 0.8s; + font-family: "Myriadpro-SemiBold"; + min-width: 166px; + } + + .avatar-edit-box .img-edit-avt { + position: absolute; + bottom: 0; + background: #fff; + height: 46px; + width: 100%; + text-align: center; + } + + .avatar-edit-box .img-edit-avt img { + width: 34px; + height: 26px; + border-radius: 0; + margin-top: 9px; + } + + .list-menu-custom { + width: 285px; + } + + .btn-gr-text p { + font-size: 16px; + font-family: "Myriadpro-Bold"; + color: #00a79d; + line-height: 54px; + } + + .btn-gr { + margin: 0 0 12px; + border-radius: 13px; + height: 54px; + } + + .apdung label { + margin: 13px 0; + font-size: 16px; + padding: 0 0 9px 12px; + } + + .apdung.tp-k label { + margin: 15px 0 11px; + font-size: 14px; + padding: 0 0 8px 10px; + } + + .apdung.apdung-custom label { + margin: 12px 0 12px 12px; + padding: 0; + } + + .thoikhoabieu.tb .apdung .valid_to_input .react-datepicker-wrapper { + width: 118px; + } + + .valid_to_input input { + font-size: 16px; + width: 80px; + margin-right: 0; + text-align: center; + } + + .thoikhoabieu.tb .valid_to_input { + margin: 12px 0 0 17px; + } + + .btn-create-datlai img { + left: 13px; + top: 7px; + width: 21px; + } + + .orange span, + .red span, + .success-text span { + font-size: 14px; + line-height: 23px; + } + + .his { + margin-top: -6px; + width: 115px; + } + + .btn-select-year button { + padding: 0 53px; + } + + .btn-select-year .ico_right, + .btn-select-year .ico_left { + top: 8px; + width: 13px; + } + + .title-list-lichnam h2 { + font-size: 21px; + } + + .btn-remove-item { + width: 46px; + height: 46px; + } + + .btn-remove-item img { + width: 18px; + } + + .popup-filter-option .wh20.chk-custom-gr input:checked + label:after { + top: -5px; + } + + .ql-bt-dg.sunE-giaotrinh-resuft-filter { + max-height: calc(100vh - 160px); + } + + .box-setting-custom { + border-radius: 18px; + padding: 18px; + margin: 0 0 9px; + } + + .setting-title-blue { + font-size: 21px; + line-height: 28px; + margin: 0 0 9px; + } + + .w80 { + width: 70px; + } + + /*CUSTOM ON OFF BUTTON*/ + .toggle-button-cover { + position: relative; + width: 45px; + } + + .knobs, + .layer { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + .button { + top: calc(50% - 10px); + width: 45px; + height: 17px; + } + + .button.r, + .button.r .layer { + border-radius: 102px; + } + + /* Button 1 */ + .btn-on-off .knobs:before { + top: -6px; + left: -5px; + width: 28px; + height: 28px; + font-size: 10px; + } + + .btn-on-off.active .checkbox:checked + .knobs:before { + left: 21px; + } + + /*END CUSTOM ON OFF BUTTON*/ + .setting-on-off-box p { + font-size: 16px; + line-height: 21px; + } + + .setting-on-off-box { + margin: 0 0 1rem; + } + + .select-language .select-styled { + height: 21px; + line-height: 21px; + font-size: 15px; + } + + .setting-on-off-box .center-flex img { + width: 12px; + } + + .btn-gr-img { + width: 102px; + padding: 12px 0; + } + + .list-menu-custom .btn-gr-img.ico_ma img { + width: 33px; + } + + .list-menu-custom .btn-gr-img.ico_buy img { + width: 37px; + } + + .list-menu-custom .btn-gr-img.ico_time img { + width: 32px; + } + + .slider-custom { + max-width: 450px; + } + + .item-top-title p { + font-size: 18px; + } + + .item-price p { + font-size: 26px; + } + + .slider-custom .slider-item-content img.details-ig { + margin: auto; + width: 265px; + } + + .slider-custom .slick-arrow.slick-next { + left: calc(100% - 20px); + } + + .slider-custom .slick-arrow.slick-prev { + left: -10px; + } + + .custom-select-w { + width: 380px; + } + + .input-nm { + height: 36px; + line-height: 36px; + border-radius: 18px; + padding-left: 18px; + margin: 0 0 17px; + font-size: 16px; + } + + .box-white-content p, + .btn_click_link { + font-size: 16px; + } + + .student-index { + padding: 6vh 20px 10px; + } + + .map-skill span { + width: 212px; + height: 36px; + line-height: 36px; + border-radius: 18px; + font-size: 16px; + } + + .map-skill img { + top: -22px; + left: -5px; + width: 52px; + } + + .star img { + width: 36px; + height: 36px; + } + + .pink-ab { + bottom: 18px; + right: 65px; + } + + .pink-ab img { + width: 45px; + } + + .box-unit-info p, + .box-unit-info p span { + font-size: 16px; + } + + .giaotrinh.unit .box-giaotrinh-gr { + padding: 0 16px 0 40px; + margin: 0 0 18px 18px; + } + + .list-menu-custom.student { + width: 280px; + } + + .bg_top_tt { + width: 100%; + } + + .mte-gr .mte-thumb { + width: 56px; + height: 56px; + border: 4px solid #fff; + top: -6px; + left: -17px; + } + + .mte-gr { + background: #fff; + height: 45px; + width: 130px; + border-radius: 23px; + text-align: center; + padding-left: 24px; + } + + .mte-gr h2 { + line-height: 26px; + font-size: 26px; + } + + .circle-k { + width: 24px; + height: 24px; + border-radius: 12px; + margin-left: -2px; + } + + .line-k { + width: 42px; + height: 8px; + margin-top: 8px; + } + + .process-info-k .space { + width: 60px; + text-align: center; + } + + .process-info-k .space p { + font-size: 16px; + font-family: "Myriadpro-Light"; + line-height: 16px; + } + + .list-menu-custom.student .btn-gr-text p { + line-height: 60px; + } + + .list-menu-custom.student .btn-gr { + height: 60px; + } + + .btn-gr-img.ico_thanhtich_offline { + padding: 9px 0; + } + + .ico_thanhtich_offline img { + width: 46px; + } + + .ico_thanhtich_online img { + width: 33px; + } + + .ico_xephang img { + width: 45px; + } + + .process-thumb img { + width: 56px; + height: 56px; + } + + .skill-process-list { + margin: 26px 0 0; + padding: 16px 26px 9px 45px; + background: rgba(0, 0, 0, 0.2); + border-radius: 18px; + } + + .skill-process-item p.title { + line-height: 21px; + font-size: 16px; + } + + .process-100 { + height: 26px; + border-radius: 13px; + padding: 5px 5px 5px 36px; + } + + .process-due { + height: 16px; + } + + .sco { + width: 92px; + height: 26px; + border-radius: 13px; + box-sizing: border-box; + background: #fff; + padding: 0 6px 0 13px; + margin: 21px 0 0 12px; + } + + .sco .slp { + line-height: 26px; + font-size: 21px; + } + + .sco .slp-top { + line-height: 9px; + font-size: 12px; + top: -9px; + } + + .top-t { + height: 40px; + border-radius: 20px; + padding: 0 26px; + margin: 0 0 16px; + } + + .top-t p { + font-size: 16px; + line-height: 40px; + } + + .box-s { + padding: 0 6px 0 35px; + } + + .box-s span { + height: 30px; + margin-top: 6px; + border-radius: 16px; + font-size: 16px; + line-height: 30px; + padding: 0 5px 0 35px; + } + + .box-s img { + top: 5px; + left: 5px; + } + + .box-s .select { + font-size: 16px; + color: #00cbad; + width: 130px; + height: 30px; + line-height: 30px; + border-radius: 15px; + margin-top: 5px; + } + + .box-s .select-styled { + width: 150px; + height: 30px; + line-height: 30px; + border-radius: 15px; + font-size: 16px; + padding: 0 5px 0 35px; + } + + .select-chart .select-styled { + padding: 0 5px; + text-align: center; + width: 100%; + } + + .box-s .select-options { + padding: 21px 9px 0; + top: 21px; + border-radius: 21px; + max-height: calc(100vh - 140px); + } + + .box-s .select img { + top: 5px; + left: 5px; + width: 24px; + } + + .box-nhatkyhoctap-graph .bangdiem-menu-gr span { + font-size: 16px; + } + + .box-diem .top-o p { + font-size: 16px; + line-height: 18px; + } + + .box-diem h2 { + font-size: 40px; + } + + .his-hd { + height: auto; + min-height: calc(100vh - 140px); + padding: 16px 25px; + } + + .b-26-black { + line-height: 28px; + font-size: 22px; + font-family: "Myriadpro-Bold"; + margin: 13px 0 9px; + } + + .img-avatar-k { + width: 86px; + height: 86px; + border-radius: 43px; + border: 3px solid #fff; + margin-right: 17px; + } + + .bxh-info-student-box h3 { + font-size: 21px; + line-height: 26px; + margin: 0 0 9px; + } + + .gr-r p { + font-size: 16px; + line-height: 21px; + } + + .gr-r span { + font-size: 21px; + line-height: 26px; + } + + .ico_hc { + width: 18px; + } + + .sub-title-18 { + display: block; + font-size: 16px; + line-height: 21px; + } + + .box-top-k { + border-radius: 17px; + padding: 9px 17px; + } + + .top-k-score { + width: 70px; + height: 26px; + font-size: 16px; + line-height: 26px; + border-radius: 13px; + margin: 0 auto 13px; + } + + .top-k-item.v { + width: 150px; + margin: 0 13px; + } + + .top-k-item.s, + .top-k-item.b { + width: 104px; + } + + .top-k-item.s .avt-top-k .ico_avt, + .top-k-item.b .avt-top-k .ico_avt { + top: 15px; + left: 25px; + width: 52px; + height: 52px; + border-radius: 27px; + } + + .top-k-item.v .avt-top-k .ico_avt { + top: 35px; + left: 40px; + width: 66px; + height: 66px; + border-radius: 33px; + } + + .thanhtich-container { + padding: 12px 0 0; + } + + .student_bxh_list .item-student { + padding: 9px 17px; + border-radius: 17px; + margin: 0 0 9px; + } + + .student_bxh_list .item-student .item-student-img { + width: 46px; + height: 46px; + border-radius: 23px; + border: 1px solid #e9af38; + } + + .student_bxh_list .item-student-name p { + line-height: 46px; + font-size: 16px; + } + + .student_bxh_list .item-student .stt { + line-height: 46px; + font-size: 16px; + width: 26px; + } + + .hcs { + font-size: 16px; + line-height: 16px; + margin: 0 12px 0 5px; + } + + .lv-down img, + .lv-up img { + width: 18px; + } + + .student_bxh_list { + max-height: 390px; + } + + .edit-profile-student button { + padding: 0 23px 0 45px; + } + + .edit-profile-student .ico_edit_profile { + position: absolute; + left: 13px; + top: 7px; + width: 21px; + } + + .box-detail-hs.student .avt-ab { + width: 130px; + height: 130px; + top: -65px; + left: calc(50% - 65px); + } + + .ph-add-gr h2 { + font-size: 21px; + line-height: 26px; + margin-bottom: 15px; + } + + .parent-info .avatar { + width: 66px; + height: 66px; + border-radius: 33px; + margin-right: 17px; + } + + .parent-info p { + font-size: 16px; + line-height: 16px; + margin: 17px 0 6px; + } + + .parent-info span { + font-size: 16px; + line-height: 21px; + } + + .box-detail-ab.student-ab { + top: 106px; + } + + .avatar-edit-box.student { + width: 160px; + height: 160px; + margin: 30px auto; + } + + .bg_edit_student_profile { + top: -33px; + } + + .avatar-edit.student .sunE-input-gr { + margin: 0 0 15px; + } + + .avatar-edit.student { + padding-top: 0; + } + + .kh-title h2 { + font-size: 21px; + } + + .btn-create-khk span { + width: 94px; + height: 32px; + min-width: 94px; + padding: 0 17px; + line-height: 32px; + } + + .line38 { + line-height: 32px; + } + + .btn-create-khk .ico_add_kh { + position: absolute; + top: 8px; + left: 13px; + width: 16px; + } + + .btn-create-khk .ico_line_kh { + position: absolute; + top: 5px; + left: 52px; + } + + .btn-create-khk .ico_line_kh { + position: absolute; + left: 39px; + height: 26px; + } + + .f24 { + font-size: 20px !important; + } + + .slider-item-desc .btn-img img { + width: 18px; + top: 6px; + left: 11px; + } + + .slider-item-desc .btn-img img.ico_add_custom { + width: 22px; + top: 8px; + left: 14px; + } + + .plan-item-content { + padding: 10px 20px 10px 10px; + } + + .img-upload { + height: 450px; + } + + .edit-plan-box { + width: 136px; + background: #b7f2e4; + display: flex; + justify-content: center; + align-items: center; + margin-right: -136px; + transition: margin 0.6s ease; + padding-top: 5px; + } + + .edit-show .plan-item-content { + margin-left: -124px; + transition: margin 0.6s ease; + border-top-right-radius: 10px; + border-bottom-right-radius: 10px; + } + + .sunE-create-class-content { + margin-top: 30px; + } + + .btn-remove-student { + padding-top: 16px; + } + + .btn-remove-student img { + width: 18px; + } + + .btn-accept-reject-select-gr .btn-select-custom { + width: 100px; + height: 32px; + border-radius: 16px; + font-size: 14px; + } + + .add_code_student-gr .ico_err { + width: 24px; + right: 10px; + top: 7px; + } + + .title-info.dtb-title { + width: 100px; + } + + .box-criteria { + max-height: 235px; + /* max-height: fit-content; */ + } + + .box-criteria-full { + max-height: fit-content; + } + + .box-criteria-scroll { + max-height: 265px; + } + + .dk_class .select-all { + /* margin-right: 16px; */ + padding-right: 37px; + } + + .change_point_checkbox_add_exercise { + padding-right: 43px !important; + } + + .giaotrinh.unit .unit-list .box-giaotrinh-gr { + padding: 0 55px 0 25px; + } + + .box-bcht-date-custom-hei .calendar .day-cell.hide_collapse, + .box-bcht-date-custom-hei .calendar .day-cell.hide_collapse { + display: none; + } + + .box-bcht-date-custom-hei .fullHeight .calendar .hide_collapse, + .box-bcht-date-custom-hei .fullHeight .calendar .hide_collapse { + display: flex; + } + + .set-max-w { + max-width: 363px; + } + + .tb-mes { + bottom: 8px; + } + + .class-box-desc { + padding: 0 0 12px 15px; + } + + .mt-17 { + margin-top: 17px; + } + + .file-support-list { + overflow: auto; + max-height: 200px; + padding-right: 10px; + } + + .text-center.box-video-project.img-bg { + max-height: 220px; + } + + .responsive_video_marking_screen { + max-height: 215px; + } + + .box-video-project video { + width: 100%; + max-height: 215px; + } + + .sunE-box-tkh, + .sunE-box-xkh { + padding: 10px 20px; + } + + .input-gr label, + .laplai label, + .ct-hs label.ht { + font-size: 16px; + padding: 0 0 7px 12px; + } + + .input-gr textarea { + height: 80px; + font-size: 16px; + } + + .input-gr { + margin: 0 0 12px; + } + + .radio-item { + padding: 0 5px; + margin: 6px 0 0; + } + + .radio-item label:before { + top: 1px; + margin: 0 5px 0 0; + width: 12px; + height: 12px; + border-radius: 6px; + } + + .tp-k .time-to.select-time input { + font-size: 16px; + margin: 6px 0 0 15px; + } + + .apdung.tp-k .time-to.select-time .ico_edit_time_to { + top: 12px; + } + + .apdung .time-to.select-time .ico_edit_time_to { + left: 127px; + } + + .apdung.tp-k { + margin: 0; + } + + .laplai { + margin: 0 0 10px; + padding-left: 0; + } + + .time-to-khht-cn .ico_edit_time_to_khht { + top: -1px; + right: -24px; + } + + .valid_to_input { + margin: 14px 0 0 10px; + } + + .error-img { + height: 18px; + } + + .custom-4.slider-custom { + max-width: 380px; + } + + .thanhtich-offline-box .top-title-name.two-line { + max-height: 57px; + } + + .bg_auth { + max-width: 100%; + width: 100%; + } + + /* File Support CSS */ + .pasd.sunE-container-box { + padding: 20px 20px 0; + } + + .__overview_report { + padding: 25px 0px; + } + + /*responsive home teacher*/ + .p_responsive_home_page_teacher { + margin-top: -20px; + padding: 0px 20px 0px !important; + } + + .mb_mt_5px { + margin: 5px 0 !important; + } + + .__body_class_add_responsive_screen_small { + height: 50%; + } + + .responsive_plan_list_screen_small { + max-height: 21.7rem !important; + } + + .responsive_avatar_class_screen_small { + display: flex; + align-items: center; + justify-content: center; + width: 180px !important; + height: 180px !important; + } + + .responsive_avatar_class_screen_small_img { + width: 70% !important; + height: 70% !important; + } + + .slider-custom-student .responsive_avatar_class_screen_small { + width: 116px !important; + height: 116px !important; + } + .slider-custom-student + .img-thumb-student + .responsive_avatar_class_screen_small_img { + width: 100% !important; + height: 100% !important; + } + + .responsive_class_name_screen_small { + max-height: 30px !important; + padding: 5px 24px !important; + margin-bottom: 0 !important; + } + + .responsive_chart_screen_small { + width: 55%; + } + + .space_null_responsive_home_page_teacher { + width: 140px !important; + } + + /*end responsive home teacher*/ + + /* region avatar rank */ + .top { + width: 285px; + background: #fff; + border-radius: 20px; + padding: 30px 0 10px 0; + height: calc(100vh - 140px); + overflow: auto; + } + + .top-box { + margin: 0 0 10px; + } + + .top1 span { + height: 25px; + line-height: 25px; + } + + .top2 span { + height: 25px; + line-height: 25px; + } + + .top3 span { + height: 25px; + line-height: 25px; + } + + .top-hs { + width: 42%; + height: 103px; + margin: 0 auto 10px; + } + + .top1 .top-hs .avt { + position: absolute; + top: 33px; + left: 35px; + width: 50px; + height: 50px; + border-radius: 39px; + border: 2px solid #f7eda1; + box-sizing: border-box; + object-fit: cover; + } + + .top-hs .gold { + position: absolute; + top: 8px; + left: 37.5px; + } + + .__top_number { + position: absolute; + bottom: -10px; + left: 39%; + font-weight: bold; + border-radius: 50%; + background: #fff; + width: 25px; + height: 25px; + font-family: "Myriadpro-Bold" !important; + display: flex; + align-items: center; + } + + .top2 .top-hs { + width: 40%; + height: 100px; + margin: 0 auto 10px; + } + + .top2 .top-hs .avt { + position: absolute; + top: 15px; + left: 27.5px; + width: 60px; + height: 60px; + border-radius: 39px; + border: none; + border: 2px solid #d3d2d2; + box-sizing: border-box; + object-fit: cover; + } + + .top3 .top-hs { + width: 40%; + height: 100px; + margin: 0 auto 10px; + } + + .top3 .top-hs .avt { + position: absolute; + top: 15px; + left: 27.5px; + width: 60px; + height: 60px; + border-radius: 39px; + border: none; + border: 2px solid #d3d2d2; + box-sizing: border-box; + object-fit: cover; + } + + /* end region avatar rank */ + + .responsive_small_screen_margin_login { + margin-top: -30px !important; + } + + .register_account_type .account_content { + margin-bottom: 0 !important; + } + + .register_account_type .account_detail_school_title { + margin-bottom: 5px !important; + } + + .register_account_type .account_content_title { + margin-bottom: 5px !important; + } + + .register_account_type .account_detail_placeholder { + height: 90px !important; + } + + .register_update_info .button_submit { + margin-top: 10px !important; + } + + .responsive_screen_small_no_plan { + margin-top: 25px; + } + + .responsive_viewScheduleStudent_email, + .responsive_viewScheduleStudent_name { + margin: 0 !important; + } + + .responsive_viewScheduleStudent_name { + margin: 0 auto !important; + } + + .responsive_screen_popup_height { + max-height: 85vh !important; + height: 85vh !important; + width: 435px !important; + } + + .responsive_low_screen_files_support { + padding: 0 40px 0 47px !important; + } + + .success_register_teacher { + margin-top: 50px !important; + } + + .responsive_modal_authentication_teacher { + min-height: 22rem !important; + margin-top: 0 !important; + } + + .style_heading_authentication_teacher { + margin-top: 0 !important; + } + + .style_btn_agree_authentication_teacher { + padding-top: 1.5rem !important; + } + + .responsive_btn_assign_assignments { + width: 127px !important; + } + + .father_btn_assign_assignments { + margin-right: 15px !important; + } + + .quantity_from_teacher_choose { + min-width: 25px; + height: 25px; + top: -10px; + } + + .uk-modal-body .wh20.chk-custom-gr input:checked + label:after { + top: -5px !important; + left: 8px; + } + + .ml--5 { + margin-left: -5px; + } + + .height_top_3_golden_board { + height: calc(100vh - 140px) !important; + padding: 20px 0 20px 0; + } + + .slick-dots { + bottom: -30px !important; + } + + .slider-custom-student .slick-dots { + position: relative !important; + bottom: 0 !important; + margin: 0.2rem 0 0.4rem; + } + + .height_calendar_responsive { + min-height: 410px; + } + + .font_average_score { + margin-bottom: 10px !important; + } + + .upgrade_container { + padding-top: 0.5rem; + } + + .form_upgrade { + padding-top: 0.75rem !important; + } + + .title_upgrade { + padding-bottom: 1rem !important; + } + + .register-success-container { + margin-top: 0px !important; + } + + .content_homepage_student .slider_homepage_student { + margin-bottom: 0.25rem !important; + } +} + +@media screen and (max-height: 700px) { + /*RESET CSS*/ + html, + body, + div, + span, + object, + iframe, + h1, + h2, + h3, + h4, + h5, + h6, + p, + blockquote, + pre, + abbr, + address, + cite, + code, + del, + dfn, + em, + img, + ins, + kbd, + q, + samp, + small, + strong, + sub, + sup, + var, + b, + i, + dl, + dt, + dd, + ol, + ul, + li, + fieldset, + form, + label, + legend, + table, + caption, + tbody, + tfoot, + thead, + tr, + th, + td, + article, + aside, + canvas, + details, + figcaption, + figure, + footer, + header, + hgroup, + menu, + nav, + section, + summary, + time, + mark, + audio, + video { + /* font-size: 14px; */ + } + + .home_curriculum .select-options { + top: -4px !important; + } + + .sunE-container { + width: 100%; + height: auto; + max-width: 1200px; + margin: 0 auto; + /* padding: 0; */ + } + + .list-menu-i a.menu-item { + font-size: 14px; + color: #404041; + line-height: 29px; + align-items: center; + padding: 9px 0 9px 27px; + text-decoration: none; + margin: 7px 0; + } + + .iZROEJ .select-styled { + height: 44px !important; + } + + .list-menu-i .menu-img { + width: 50px; + max-height: 27px; + } + + .list-menu-i .menu-img img { + width: 25px; + } + + .list-menu-i a.menu-item span { + font-size: 14px; + color: #404041; + } + + .sunE-sidebar { + display: flex; + height: 100vh; + -webkit-box-flex: 0; + background-color: rgba(172, 241, 228, 0.66); + flex: 0 0 auto; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + flex-direction: column; + -webkit-transition: margin-left 250ms ease-out, + -webkit-transform 250ms ease-out; + transition: margin-left 250ms ease-out, -webkit-transform 250ms ease-out; + transition: margin-left 250ms ease-out, transform 250ms ease-out; + transition: margin-left 250ms ease-out, transform 250ms ease-out, + -webkit-transform 250ms ease-out; + width: 215px; + } + + .plan-item-content p { + font-size: 14px; + } + + .btn-plan-item { + width: 18px; + } + + .his img { + width: 23px; + } + + .plan-item-content p.text-light { + padding: 0 0 0 10px; + } + + .slider-custom-2 .slick-arrow.slick-prev { + left: -9px; + } + + /* Slider for student homepage */ + .slider_homepage_student .slider-custom-student { + /* margin-bottom: 0.9rem !important; */ + } + + .slider-custom-student .slick-arrow.slick-prev { + left: 39px; + } + + .slider-custom-2 .slick-next, + .slider-custom-2 .slick-prev { + width: 36px; + height: auto; + } + + .slider-custom-2 .slick-arrow { + background: #00bbb6; + padding: 10px 12px; + position: absolute; + border-radius: 10px; + border: none; + z-index: 9; + text-align: center; + } + + .item-top-title-main p { + text-align: center; + font-size: 14px; + padding: 0; + color: #fff; + font-family: "Myriadpro-SemiBold"; + } + + .slick-dots li button:before { + font-size: 6px; + line-height: 15px; + position: absolute; + top: 0; + left: 0; + width: 12px; + height: 12px; + content: "•"; + text-align: center; + opacity: 0.25; + color: #000; + } + + .slider-custom-2 .slick-dots li button:before { + font-size: 14px; + color: #00a79d; + } + + .slider-item-content .img-thumb { + margin: 10px; + width: 200px; + height: 177px; + border-radius: 10px; + overflow: hidden; + } + + .slider-custom-2 .slider-item-content { + margin: 10px; + padding: 5px 11px; + } + + /* For Student */ + .slider-custom-student .slider-item-content { + margin: 12px; + padding: 5px 8px; + } + + .slider-custom-student .slider_student_wrapper .slider-item-content { + margin-top: 0.55rem !important; + margin-bottom: 0.45rem !important; + } + + .slider-item-desc .item-top-title-main { + margin: 10px 0; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); + padding: 10px 20px; + border-radius: 25px; + max-height: 56px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + margin-bottom: 25px; + } + + .edit-plan-box .btn p { + font-size: 14px; + line-height: 14px; + } + + .edit-plan-box .btn img { + width: 23px; + } + + .sunE-right-container { + width: 100%; + height: 100vh; + overflow: auto; + padding: 20px 15px 10px 15px; + } + + .sunE-container-box { + padding: 20px 10px 10px; + } + + .orange span, + .red span, + .success-text span { + line-height: 23px; + } + + .chart-content canvas { + margin-left: 0; + } + + .sunE-plan-list { + max-height: 270px; + overflow: auto; + padding-right: 8px; + } + + .no-plan img { + width: 205px; + } + + .no-plan h2 { + font-family: "Myriadpro-SemiBold"; + font-size: 18px; + padding: 0; + margin: 0; + color: #00a79d; + } + + .dtb-sum-slider { + bottom: -45px; + } + + .dtb-sum-slider .w { + width: 142px; + } + + .slider-custom-2 .dtb-sum-slider .w { + width: 123px; + } + + .img-check-calendar { + top: -1px; + right: -5px; + width: 14px; + } + + .class-box .class-box-img { + width: 107px; + height: 87px; + } + + .title-line-blue { + font-size: 14px; + line-height: 18px; + padding: 6px; + text-align: center; + border-radius: 15px; + background-image: linear-gradient(to right, #00e1a0, #00b9b7); + } + + .two-line { + max-height: 43px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + } + + .class-box-desc p, + .class-box-desc span { + font-size: 14px; + } + + .sunE-main-title h1 { + font-size: 24px; + line-height: 32px; + padding-left: 6px; + } + + .sunE-main-title .line-h { + display: block; + width: 3px; + height: 30px; + background: #00bbb5; + border-radius: 2px; + border: none; + } + + .sunE-class-list { + padding-right: 15px; + max-height: calc(100vh - 155px); + padding-bottom: 24px; + overflow: auto; + } + + .class-index-box .class-index-box-img { + width: 206px; + height: 209px; + } + + .class-index-box { + box-sizing: border-box; + padding: 11px; + border-radius: 15px; + background: #fff; + display: inline-block; + width: 100%; + } + + .info-gr .info-img { + width: 24px; + } + + .info-gr { + margin: 10px 0 0; + } + + .info-gr img { + height: 16px; + cursor: pointer; + } + + .info-gr .info-con p { + font-size: 14px; + font-family: "Myriadpro-Light"; + line-height: 22px; + } + + .class-select-box { + padding: 15px 0px 0; + display: inline-block; + width: 118px; + height: 118px; + background: #fff; + margin: 0 5px; + border-radius: 10px; + border: none; + cursor: pointer; + box-sizing: border-box; + overflow: hidden; + } + + .class-select-box .select-img { + height: 66px; + } + + .class-select-box img { + height: 100%; + } + + .class-select-box p { + font-size: 14px; + padding: 8px 0 0; + margin: 0; + } + + .box-giaotrinh-gr.hei-custom.edit { + height: 110px; + padding: 0 11px 0 24px; + margin: 0 0 15px 0; + } + + .box-select-info p { + color: #221f1f; + font-size: 14px; + line-height: 19px; + } + + .box-select-info span { + font-size: 14px; + } + + .box-select-file-full { + flex: 1; + } + + .box-select-file-full p { + flex: 1; + text-align: left; + } + + .gtcn-menu-gr span { + font-size: 18px; + margin-right: 22px; + } + + .box-giaotrinh-gr.hei-custom { + height: 75px; + } + + .box-giaotrinh-gr .thumb { + position: absolute; + top: -4px; + left: -22px; + display: flex; + justify-content: center; + align-items: center; + background: #fff; + border: 3px solid #fff; + border-radius: 50%; + width: 55px; + height: 55px; + box-shadow: 0 1px 8px 0 rgb(21 27 38 / 24%); + } + + .box-giaotrinh-gr .thumb3 { + position: absolute; + top: -4px; + left: -22px; + display: flex; + justify-content: center; + align-items: center; + background: #ccedeb; + border: 3px solid #fff; + border-radius: 50%; + width: 55px; + height: 55px; + box-shadow: 0 1px 8px 0 rgb(21 27 38 / 24%); + } + + .box-giaotrinh-gr .thumb2 { + width: 65px; + height: 65px; + left: -24px; + } + + .box-giaotrinh-gr.hei-custom .thumb { + top: 11px; + } + + .box-giaotrinh-gr.hei-custom .thumb3 { + top: 11px; + } + + .gt_list_hei { + max-height: calc(100vh - 260px); + padding: 0 11px; + overflow: auto; + } + + .btn-user-add img, + .btn-user-share img { + width: 32px; + } + + .sunE-title-medium { + font-size: 16px; + margin: 0; + padding: 0 0 15px; + + span { + font-size: 16px !important; + } + } + + .sunE-right-container.add_student_container { + padding: 30px 14px 0 14px; + } + + .add_student { + height: calc(100vh - 90px); + width: 100%; + } + + .sunE-no-student .add_code_student-gr { + top: 440px; + } + + .add_code_student-gr { + width: 310px; + position: absolute; + left: 50%; + top: 450px; + transform: translate(-50%, -50%); + } + + .sunE-input-border-blue-gr input { + height: 32px; + border: 1px solid #399098; + border-radius: 16px; + padding: 0 35px; + } + + .sunE-input-border-blue-gr .ico_input { + position: absolute; + /* top: 4.5px; */ + /* left: 10px; */ + width: 24px; + } + + .btn-filter button { + padding: 0 26px 0 33px; + } + + .btn-filter img { + position: absolute; + top: 9px; + left: 12px; + width: 15px; + } + + .sunE-giaotrinh-item .img { + width: 88px; + height: 80px; + } + + .sunE-giaotrinh-item .content { + padding-left: 15px; + padding-top: 7px; + } + + .sunE-giaotrinh-item .content h2.title { + font-size: 14px; + line-height: 17px; + } + + h2.title { + font-family: "Myriadpro-Bold"; + font-size: 14px; + } + + .sunE-giaotrinh-item .content h3.desc { + font-size: 14px; + line-height: 17px; + margin: 0 0 7px; + } + + .sunE-giaotrinh-item .content .easy, + .sunE-giaotrinh-item .content .hard, + .sunE-giaotrinh-item .content .medium, + .sunE-giaotrinh-item .content .normal { + padding: 2px 7px; + } + + .lb-dc-gr .lb { + margin-right: 7px; + } + + .lb-dc-gr span { + color: #fff; + font-size: 14px; + padding: 3px 11px; + border-radius: 10px; + line-height: 16px; + } + + .topic { + background: #fff; + padding: 22px 16px; + border-radius: 16px; + margin: 0 0 11px; + } + + .cb-score-gr p { + font-size: 14px; + margin: 0 0 7px; + } + + .cb-score-gr span { + font-size: 24px; + font-family: "Myriadpro-Bold"; + color: #00a69c; + } + + .item-student .item-student-img { + width: 52px; + height: 52px; + border-radius: 26px; + } + + .list-detail .item-student { + background: #fff; + border-radius: 16px; + padding: 7px 7px 7px 22px; + margin: 0 0 7px 40px; + min-height: 76px; + } + + .list-detail .item-student-img { + position: absolute; + top: 9px; + left: -35px; + width: 62px; + height: 62px; + border-radius: 31px; + overflow: hidden; + } + + .item-student-name h2 { + font-size: 14px; + line-height: 16px; + margin: 10px 0 10px; + } + + .list-detail .item-student .item-student-name span { + font-size: 14px; + line-height: 27px; + } + + .list-detail .item-student .item-student-name img { + width: 27px; + } + + .box-title-bg { + border-radius: 18px; + height: 34px; + } + + .box-title-bg p { + font-size: 18px; + /* line-height: 36px; */ + } + + .box-criteria-score-title p { + font-size: 14px; + padding-left: 11px; + } + + .box-criteria-comment h2 { + font-size: 18px; + padding-left: 25px; + margin: 0 0 5px; + } + + .box-criteria-comment textarea { + padding: 11px 11px 7px 22px; + border-radius: 16px; + resize: none; + width: 100%; + height: 200px; + } + + .post-content { + background: #fff; + padding: 22px 16px; + border-radius: 16px; + margin: 0; + } + + .title-post-box { + font-size: 18px; + line-height: 30px; + } + + .btn-mark { + height: 30px; + line-height: 30px; + padding: 0 0 0 16px; + box-sizing: border-box; + border-radius: 17px; + border: none; + cursor: pointer; + margin: 0 7px 0 0; + } + + .btn-mark p { + font-size: 14px; + padding: 0 25px; + } + + .btn-mark img { + width: 27px; + } + + .btn-help { + height: 30px; + line-height: 30px; + border-radius: 17px; + border: none; + cursor: pointer; + padding: 0 22px; + } + + .btn-help img { + width: 14px; + } + + .chambai.writing { + margin: 0 0 11px; + } + + .post-content .content-box-edit { + padding: 11px 11px 7px 25px; + border-radius: 16px; + resize: none; + width: 100%; + font-size: 14px; + height: 125px; + overflow: auto; + } + + .popup-tag { + padding: 7px; + font-size: 16px; + } + + .sunE-giaobai-list { + padding: 16px 22px; + border-radius: 16px; + max-height: calc(100vh - 170px); + margin: 0; + } + + .bg_no_gb { + width: 286px; + } + + .sunE-giaotrinh-item .content p, + .sunE-giaotrinh-item .content span { + font-size: 14px; + line-height: 18px; + margin: 0 0 7px; + } + + .wh27 { + width: 20px; + height: 20px; + } + + .btn-setting img { + top: 6px; + left: 15px; + width: 21px; + } + + .box-info-giaobai { + background: #fff; + padding: 19px 16px; + border-radius: 16px; + } + + .box-info-giaobai h3.desc { + font-size: 14px; + line-height: 18px; + margin: 0 0 22px; + } + + .box-info-giaobai p { + font-size: 12px; + line-height: 18px; + margin: 0 0 7px; + } + + .box-info-giaobai .text_detail { + font-size: 14px; + line-height: 18px; + margin: 0 0 7px; + } + .sunE-container-box.giaobai-ganday { + padding: 15px 16px 0; + } + + .list-giaobai.chualam { + max-height: calc(100vh - 240px); + } + + .item-student .stt { + line-height: 52px; + font-size: 14px; + width: 22px; + } + + .btn-check-gr { + padding-top: 13px; + } + + .f20 { + font-size: 16px !important; + } + + .sunE-input-group label { + display: block; + margin: 0; + padding: 0 0 7px; + font-size: 16px; + color: #000; + } + + .select-gr select { + width: 32px; + height: 40px; + border-radius: 10px; + font-size: 14px; + margin: 0 4px 0 0; + } + + .check-box-gr label { + font-size: 14px; + } + + .datlichnhac-input-gr .left, + .datlichnhac-input-gr .right { + font-size: 14px; + } + + .datlichnhac-input-gr input.dln-mins { + height: 32px; + outline: none; + border: none; + border-radius: 16px; + padding: 5px 16px; + box-shadow: 0 1px 6px 0 rgb(21 27 38 / 15%); + box-sizing: border-box; + text-align: center; + font-size: 14px; + } + + input.dln-mins::-webkit-outer-spin-button, + input.dln-mins::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; + } + + .nhacnho-content .datlichnhac-input-gr input.dln-mins { + width: 60px; + } + + .err-nhacnho img { + margin: 11px 0 0; + } + + .nhacnho-content textarea { + height: 64px; + border-radius: 16px; + padding: 8px 16px; + font-size: 14px; + } + + .check-date-time-week { + width: 320px; + height: 32px; + background: #fff; + border-radius: 16px; + padding: 0 11px; + } + + .check-date-time-week img { + width: 10px; + } + + .check-date-time-week p { + font-size: 15px; + line-height: 32px; + } + + .student-list-container { + width: 280px; + } + + .tong-hs { + line-height: 18px; + font-size: 14px; + font-family: "Myriadpro-SemiBold"; + margin: 0 0 16px; + } + + .text-title-blue { + font-size: 14px; + } + + .box-chart p { + font-size: 14px; + } + + .dtb-sum .w { + width: 184px; + } + + .bdg-sum .w { + width: 151px; + } + + .f-24 { + font-size: 18px; + } + + .sunE-title-medium-p { + font-size: 14px; + line-height: 14px; + margin: 0 0 11px; + } + + .custom-list-student { + padding: 16px; + border-radius: 16px; + } + + .bcht .list-student { + max-height: calc(100vh - 240px); + } + + .student-info { + width: 254px; + margin-right: 16px; + } + + .student-info .avt-i { + width: 132px; + height: 132px; + border-radius: 66px; + border: 2px solid #e7ae38; + margin: 0 auto 16px; + } + + .student-info .name { + font-size: 18px; + margin: 0 0 10px; + } + + .email-gr img { + width: 17px; + } + + .email-gr p { + font-size: 14px; + line-height: 18px; + } + + .box-bcht-top h2 { + font-size: 14px; + line-height: 32px; + } + + .btn-history-bcht { + border: 2px solid #00b9b7; + line-height: 28px; + height: 32px; + border-radius: 16px; + padding: 0 25px; + font-size: 14px; + } + + .title-info { + border-radius: 16px; + height: 32px; + padding-left: 16px; + } + + .title-info p { + line-height: 32px; + font-size: 14px; + } + + .score-info { + border-radius: 16px; + height: 32px; + width: 62px; + } + + .score-info p { + line-height: 32px; + font-size: 14px; + } + + .title-info.dtb-title p { + line-height: 16px; + font-size: 14px; + } + + .bcht { + padding: 10px 0 0; + } + + .box-bcht-date-custom-hei.box-bcht { + padding: 0; + width: 368px; + } + + .box-bcht.box-bcht-date-custom-hei .calendar .week-cell, + .box-bcht.box-bcht-date-custom-hei .calendar .day-cell { + flex-grow: 0; + flex-shrink: 0; + flex-basis: calc(100% / 7 - 22px); + display: flex; + justify-content: center; + align-items: center; + height: 30px; + width: 30px; + cursor: pointer; + margin: 5px 0px; + } + + .fullHeight.showMonth .calendar { + height: auto; + } + + .item-student-name p { + font-size: 14px; + } + + .score-tb-student span { + width: 64px; + height: 34px; + line-height: 34px; + font-size: 18px; + } + + .top p { + font-size: 16px; + } + + .vinhdanh-item img.vinhdanh-bg { + width: 140px; + } + + .avt-vd { + width: 80px; + height: 80px; + border-radius: 40px; + border: 2px solid #e9af38; + margin: 16px auto 0; + } + + .name-vd { + padding: 0 16px; + line-height: 27px; + font-size: 14px; + color: #fff; + border-radius: 16px; + position: absolute; + top: 80px; + left: 50%; + transform: translate(-50%, 0); + } + + .vd-info { + bottom: 8px; + font-size: 14px; + } + + .vinhdanh-content { + padding: 20px 0 0; + } + + .diemdanh-no-item img { + width: 306px; + } + + .diemdanh-no-item p { + font-size: 18px; + } + + .btn-create-diemdanh img { + width: 16px; + top: 7px; + } + + .btn-create-diemdanh button { + padding: 0 16px 0 40px; + } + + .medium-title { + font-size: 14px; + } + + .menu-gr-right input[type="text"].btn { + height: 36px; + border-radius: 18px; + font-size: 14px; + line-height: 36px; + padding: 0 24px; + } + + .btn-ob.select { + font-size: 14px; + height: 36px; + line-height: 36px; + border-radius: 18px; + } + + .btn-ob .select-styled { + border-radius: 18px; + font-size: 14px; + line-height: 36px; + height: 36px; + padding: 0 24px; + } + + .btn-ob .select-styled:after { + content: ""; + width: 18px; + height: 10px; + top: 14px; + right: 8px; + background: url(./../images/teacher/diemdanh/ico_dropdown_blue.png) 90% / + 18px no-repeat transparent; + } + + .btn-ob .select-styled.active:after { + background: url(./../images/teacher/diemdanh/ico_dropup_blue.png) 90% / 18px + no-repeat transparent; + } + + .btn-ob .select-options { + padding: 37px 19px 0; + } + + .btn-ob .select-options li { + text-indent: 18px; + } + + .menu-gr-right .react-datepicker-wrapper input[type="text"] { + height: 36px; + border-radius: 18px; + font-size: 14px; + line-height: 36px; + padding: 0 24px; + } + + .box-select-gr { + border-radius: 16px; + padding: 22px 0 22px 25px; + margin: 0 0 11px 16px; + } + + .box-select-gr .thumb { + position: absolute; + top: -2px; + left: -24px; + border: 4px solid #fff; + width: 78px; + height: 78px; + } + + .box-select-info h2 { + font-size: 14px; + line-height: 16px; + } + + .box-giaotrinh-gr { + border-radius: 16px; + height: 48px; + margin: 0 0 22px 16px; + padding: 0 11px 0 48px; + } + + .custom-select-no-bg .select-styled { + padding-left: 48px; + } + + .custom-select-no-bg .select-styled { + height: 32px; + border-radius: 16px; + font-size: 14px; + padding-right: 32px; + line-height: 32px; + /* background: url(./../images/icon/ico_dropdown_s.png) 97% / 16px no-repeat + #fff; */ + } + + .custom-select-no-bg .select { + font-size: 14px; + width: 100%; + height: 32px; + line-height: 32px; + border-radius: 16px; + } + + .btn-bar img { + height: 32px; + } + + .sunE-container-box.giaotrinh.unit { + padding: 0 16px; + } + + .sunE-unit-item h2 { + font-size: 16px; + } + + .sunE-unit-item p { + font-size: 14px; + } + + .img-bg-x { + width: 138px; + height: 212px; + background-size: 100%; + margin: auto; + } + + .img-bg-x .__avt_unit { + margin-top: 30px; + margin-left: -5px; + } + + .__way_map { + position: absolute; + transform: translate(75%, 95%); + } + + .__way_map_down { + position: absolute; + transform: translate(65%, 150%); + } + + .sunE-unit-item .h-287 { + height: 212px; + } + + .giaotrinh.unit .unit-list .box-giaotrinh-gr { + border-radius: 26px; + height: 40px; + } + + .btn-more-info { + width: 32px; + height: 32px; + border-radius: 16px; + right: 6px; + top: 4px; + } + + .btn-more-info img { + width: 11px; + } + + .btn-more-info .show_img { + width: 6px; + } + + .btn-more-info .show_ { + margin: 14px 0 0 1px; + width: 8px; + } + + .info-item-desc h2 { + font-size: 14px; + line-height: 16px; + } + + .sunE-giaotrinh-resuft-filter { + padding: 16px 24px; + border-radius: 16px; + max-height: calc(100vh - 230px); + } + + .chk-custom-gr label:before { + padding: 9px; + margin-right: 8px; + border-radius: 2px; + margin-top: -1px; + } + + .chk-custom-gr input:checked + label:after { + top: -7px; + left: 9px; + width: 5px; + height: 16px; + } + + .sunE-giaotrinh-item .chk-gr .chk-custom-gr label:before { + margin-top: -9px; + } + + .sunE-giaotrinh-resuft-filter.box-shadow.scrollbar-custom.flex-1 + .sunE-giaotrinh-item + .chk-gr + .chk-custom-gr + label:before { + margin-top: -5px; + } + + .select-all .wh20.chk-custom-gr input:checked + label:after { + top: -4px; + } + + /* Check box select all */ + .checbox-right .wh20.check-select-student input:checked + label:after { + top: -8px; + } + + .btn-create-taomoi button, + .btn-create-datlai button { + padding: 0 25px 0 48px; + } + + .btn-create-taomoi img { + left: 11px; + top: 8px; + width: 18px; + } + + .class-box-desc .title-line-blue { + margin: 0 0 10px; + } + + .box-btn { + width: 24px; + height: 24px; + } + + .ico_ring-res-7 { + width: 14px; + } + + .ico_message-res-7 { + width: 15px; + } + + .reng { + width: 8px; + height: 8px; + border-radius: 4px; + bottom: 0; + right: 0; + } + + .tn-menu-item p { + font-size: 14px; + } + + .tinnhan-item h2 { + font-size: 14px; + line-height: 14px; + margin: 0 0 6px; + } + + .tinnhan-item span { + font-size: 10px; + } + + .tinnhan-item p.mes-info { + font-size: 14px; + line-height: 18px; + max-height: 54px; + } + + .mex-info-box p { + font-size: 14px; + } + + .mes-box-send { + height: 40px; + line-height: 21px; + font-size: 14px; + padding: 8px 16px 8px 16px; + border-top-left-radius: 20px; + border-bottom-left-radius: 20px; + } + + .box-btn-send { + height: 40px; + width: 40px; + border-top-right-radius: 20px; + border-bottom-right-radius: 20px; + } + + .send-mes img { + width: 20px; + } + + .search-gr-p { + height: 40px; + box-sizing: border-box; + margin: 15px 0 6px; + } + + .select-message.select { + font-size: 14px; + width: 148px; + height: 36px; + line-height: 36px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .select-message .select-styled { + font-size: 14px; + width: 148px; + height: 36px; + line-height: 36px; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .search-custom { + width: 296px; + height: 36px; + line-height: 36px; + padding: 0 34px 0 16px; + font-size: 14px; + font-family: "Myriadpro-Regular"; + box-sizing: border-box; + border: none; + text-align: center; + border-top-right-radius: 18px; + border-bottom-right-radius: 18px; + outline: none; + } + + .icon_search { + position: absolute; + right: 11px; + top: 10px; + width: 18px; + } + + ._line_box { + padding: 5px 0; + height: 36px; + } + + ._line { + height: 26px; + top: 5px; + } + + .select-message .select-styled:after { + content: ""; + width: 14px; + height: 8px; + background: url(./../images/tinnhan/ico_dropdown.png) 98% / 14px no-repeat + transparent; + top: 14px; + right: 24px; + } + + .class_student_list_box { + padding: 16px; + border-radius: 16px; + height: calc(100vh - 160px); + } + + .list-student { + max-height: calc(100vh - 200px); + } + + .mex-box.cus-hei-2 { + height: calc(100vh - 160px); + } + + .tinnhan-item .dot-active { + width: 10px; + height: 10px; + top: 10px; + left: 10px; + } + + .box-detail-hs .avt-ab { + width: 160px; + height: 160px; + border-radius: 50%; + overflow: hidden; + } + + .box-detail-hs .avt-ab { + position: absolute; + top: -80px; + left: calc(50% - 80px); + } + + .box-detail-ab { + top: 110px; + padding: 0 60px; + } + + .box-detail-ab .box-detail-hs { + border-radius: 16px; + padding: 70px 16px 10px; + width: 310px; + } + + .box-detail-hs h2.name { + font-size: 24px; + } + + .detail-info { + padding: 0 20px 10px; + } + + .info-sum h3 { + font-size: 40px; + } + + .sunE-container-box.hoso { + min-height: auto; + } + + .info-sum { + margin: 40px 0 0; + } + + .avatar-edit { + margin: 20px 0 0; + } + + .avatar-edit-box { + background: #fff; + width: 156px; + height: 156px; + border-radius: 78px; + margin: 0 auto 25px; + padding: 3px; + } + + .hoso .btn-save button { + padding: 0 25px; + height: 32px; + line-height: 32px; + border-radius: 16px; + font-size: 14px; + min-width: 100px; + } + + .avatar-edit-box .img-edit-avt { + position: absolute; + bottom: 0; + background: #fff; + height: 40px; + width: 100%; + text-align: center; + } + + .avatar-edit-box .img-edit-avt img { + width: 29px; + height: 22px; + border-radius: 0; + margin-top: 8px; + } + + .list-menu-custom { + width: 240px; + } + + .btn-gr-text p { + font-size: 14px; + font-family: "Myriadpro-Bold"; + color: #00a79d; + line-height: 46px; + } + + .btn-gr { + margin: 0 0 10px; + border-radius: 11px; + height: 46px; + } + + .apdung label { + margin: 11px 0; + font-size: 14px; + padding: 0 0 8px 10px; + } + + .apdung.apdung-custom label { + margin: 10px 0 10px 10px; + padding: 0; + } + + .thoikhoabieu.tb .apdung .valid_to_input .react-datepicker-wrapper { + width: 100px; + } + + .valid_to_input input { + font-size: 14px; + width: 80px; + margin-right: 0; + text-align: center; + } + + .thoikhoabieu.tb .valid_to_input { + margin: 10px 0 0 15px; + } + + .btn-create-datlai img { + left: 11px; + top: 6px; + width: 18px; + } + + .orange span, + .red span, + .success-text span { + font-size: 14px; + line-height: 20px; + } + + .his { + margin-top: -5px; + width: 95px; + } + + .btn-select-year button { + padding: 0 45px; + } + + .btn-select-year .ico_right, + .btn-select-year .ico_left { + top: 7px; + width: 11px; + } + + .title-list-lichnam h2 { + font-size: 18px; + } + + .btn-remove-item { + width: 40px; + height: 40px; + } + + .btn-remove-item img { + width: 16px; + } + + .popup-filter-option .wh20.chk-custom-gr input:checked + label:after { + top: -4px; + } + + .ql-bt-dg.sunE-giaotrinh-resuft-filter { + max-height: calc(100vh - 140px); + } + + .box-setting-custom { + border-radius: 16px; + padding: 16px; + margin: 0 0 8px; + } + + .setting-title-blue { + font-size: 18px; + line-height: 24px; + margin: 0 0 8px; + } + + .w80 { + width: 60px; + } + + /*CUSTOM ON OFF BUTTON*/ + .toggle-button-cover { + position: relative; + width: 38px; + } + + .knobs, + .layer { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + .button { + top: calc(50% - 10px); + width: 38px; + height: 15px; + } + + .button.r, + .button.r .layer { + border-radius: 86px; + } + + /* Button 1 */ + .btn-on-off .knobs:before { + top: -5px; + left: -4px; + width: 24px; + height: 24px; + font-size: 10px; + } + + .btn-on-off.active .checkbox:checked + .knobs:before { + left: 18px; + } + + /*END CUSTOM ON OFF BUTTON*/ + .setting-on-off-box p { + font-size: 14px; + line-height: 18px; + } + + .setting-on-off-box { + margin: 0 0 1rem; + } + + .select-language .select-styled { + height: 18px; + line-height: 18px; + font-size: 14px; + } + + .setting-on-off-box .center-flex img { + width: 10px; + } + + .btn-gr-img { + width: 86px; + padding: 10px 0; + } + + .list-menu-custom .btn-gr-img.ico_ma img { + width: 28px; + } + + .list-menu-custom .btn-gr-img.ico_buy img { + width: 32px; + } + + .list-menu-custom .btn-gr-img.ico_time img { + width: 27px; + } + + .slider-custom { + max-width: 380px; + } + + .item-top-title p { + font-size: 16px; + } + + .item-price p { + font-size: 22px; + } + + .slider-custom .slider-item-content img.details-ig { + margin: auto; + width: 224px; + } + + .slider-custom .slick-arrow.slick-next { + left: calc(100% - 22px); + } + + .slider-custom .slick-arrow.slick-prev { + left: -9px; + } + + .custom-select-w { + width: 320px; + } + + .input-nm { + height: 32px; + line-height: 32px; + border-radius: 16px; + padding-left: 16px; + margin: 0 0 15px; + font-size: 14px; + } + + .box-white-content p, + .btn_click_link { + font-size: 14px; + } + + .student-index { + padding: 5.5vh 20px 10px; + } + + .map-skill span { + width: 160px; + height: 32px; + line-height: 32px; + border-radius: 16px; + font-size: 14px; + } + + .map-skill img { + top: -19px; + left: -4px; + width: 44px; + } + + .star img { + width: 32px; + height: 32px; + } + + .pink-ab { + bottom: 16px; + right: 55px; + } + + .pink-ab img { + width: 45px; + } + + .box-unit-info p, + .box-unit-info p span { + font-size: 14px; + } + + .giaotrinh.unit .box-giaotrinh-gr { + padding: 0 15px 0 34px; + margin: 0 0 16px 16px; + } + + .list-menu-custom.student { + width: 240px; + } + + .bg_top_tt { + width: 100%; + } + + .mte-gr .mte-thumb { + width: 48px; + height: 48px; + border: 3px solid #fff; + top: -5px; + left: -15px; + } + + .mte-gr { + background: #fff; + height: 38px; + width: 110px; + border-radius: 19px; + text-align: center; + padding-left: 20px; + } + + .mte-gr h2 { + line-height: 22px; + font-size: 22px; + } + + .circle-k { + width: 20px; + height: 20px; + border-radius: 10px; + margin-left: -2px; + } + + .line-k { + width: 36px; + height: 7px; + margin-top: 7px; + } + + .process-info-k .space { + width: 50px; + text-align: center; + } + + .process-info-k .space p { + font-size: 14px; + font-family: "Myriadpro-Light"; + line-height: 14px; + } + + .list-menu-custom.student .btn-gr-text p { + line-height: 50px; + } + + .list-menu-custom.student .btn-gr { + height: 50px; + } + + .btn-gr-img.ico_thanhtich_offline { + padding: 8px 0; + } + + .ico_thanhtich_offline img { + width: 40px; + } + + .ico_thanhtich_online img { + width: 28px; + } + + .ico_xephang img { + width: 38px; + } + + .process-thumb img { + width: 48px; + height: 48px; + } + + .skill-process-list { + margin: 22px 0 0; + padding: 14px 22px 8px 38px; + background: rgba(0, 0, 0, 0.2); + border-radius: 16px; + } + + .skill-process-item p.title { + line-height: 18px; + font-size: 14px; + } + + .process-100 { + height: 22px; + border-radius: 11px; + padding: 4px 4px 4px 31px; + } + + .process-due { + height: 14px; + } + + .sco { + width: 78px; + height: 22px; + border-radius: 11px; + box-sizing: border-box; + background: #fff; + padding: 0 5px 0 11px; + margin: 18px 0 0 10px; + } + + .sco .slp { + line-height: 22px; + font-size: 18px; + } + + .sco .slp-top { + line-height: 8px; + font-size: 10px; + top: -8px; + } + + .top-t { + height: 34px; + border-radius: 17px; + padding: 0 22px; + margin: 0 0 14px; + } + + .top-t p { + font-size: 14px; + line-height: 34px; + } + + .box-s { + padding: 0 5px 0 30px; + } + + .box-s span { + height: 26px; + margin-top: 5px; + border-radius: 14px; + font-size: 14px; + line-height: 26px; + padding: 0 4px 0 30px; + } + + .box-s img { + top: 4px; + left: 4px; + } + + .box-s .select { + font-size: 14px; + color: #00cbad; + width: 110px; + height: 26px; + line-height: 26px; + border-radius: 13px; + margin-top: 4px; + } + + .box-s .select-styled { + width: 110px; + height: 26px; + line-height: 26px; + border-radius: 13px; + font-size: 14px; + padding: 0 4px 0 30px; + } + + .select-chart .select-styled { + padding: 0 5px; + text-align: center; + width: 100%; + } + + .box-s .select-options { + padding: 18px 8px 0; + top: 18px; + border-radius: 18px; + max-height: calc(100vh - 100px); + } + + .box-s .select img { + top: 4px; + left: 4px; + width: 20px; + } + + .box-nhatkyhoctap-graph .bangdiem-menu-gr span { + font-size: 14px; + } + + .box-diem .top-o p { + font-size: 14px; + line-height: 16px; + } + + .box-diem h2 { + font-size: 35px; + } + + .his-hd { + height: auto; + min-height: calc(100vh - 130px); + padding: 14px 21px; + } + + .b-26-black { + line-height: 24px; + font-size: 18px; + font-family: "Myriadpro-Bold"; + margin: 11px 0 8px; + } + + .img-avatar-k { + width: 72px; + height: 72px; + border-radius: 36px; + border: 3px solid #fff; + margin-right: 15px; + } + + .bxh-info-student-box h3 { + font-size: 18px; + line-height: 22px; + margin: 0 0 8px; + } + + .gr-r p { + font-size: 14px; + line-height: 18px; + } + + .gr-r span { + font-size: 18px; + line-height: 22px; + } + + .ico_hc { + width: 16px; + } + + .sub-title-18 { + display: block; + font-size: 14px; + line-height: 18px; + } + + .box-top-k { + border-radius: 15px; + padding: 8px 15px; + } + + .top-k-score { + width: 60px; + height: 22px; + font-size: 14px; + line-height: 22px; + border-radius: 11px; + margin: 0 auto 11px; + } + + .top-k-item.v { + width: 126px; + margin: 0 11px; + } + + .top-k-item.s, + .top-k-item.b { + width: 88px; + } + + .top-k-item.s .avt-top-k .ico_avt, + .top-k-item.b .avt-top-k .ico_avt { + top: 13px; + left: 21px; + width: 45px; + height: 45px; + border-radius: 23px; + } + + .top-k-item.v .avt-top-k .ico_avt { + top: 30px; + left: 35px; + width: 56px; + height: 56px; + border-radius: 29px; + } + + .thanhtich-container { + padding: 10px 0 0; + } + + .student_bxh_list .item-student { + padding: 8px 15px; + border-radius: 15px; + margin: 0 0 8px; + } + + .student_bxh_list .item-student .item-student-img { + width: 40px; + height: 40px; + border-radius: 20px; + border: 1px solid #e9af38; + } + + .student_bxh_list .item-student-name p { + line-height: 40px; + font-size: 14px; + } + + .student_bxh_list .item-student .stt { + line-height: 40px; + font-size: 14px; + width: 22px; + } + + .hcs { + font-size: 14px; + line-height: 14px; + margin: 0 10px 0 4px; + } + + .lv-down img, + .lv-up img { + width: 16px; + } + + .student_bxh_list { + max-height: 350px; + } + + .edit-profile-student button { + padding: 0 15px 0 35px; + } + + .edit-profile-student .ico_edit_profile { + position: absolute; + left: 11px; + top: 6px; + width: 18px; + } + + .box-detail-hs.student .avt-ab { + width: 110px; + height: 110px; + top: -55px; + left: calc(50% - 55px); + } + + .ph-add-gr h2 { + font-size: 18px; + line-height: 22px; + margin-bottom: 10px; + } + + .parent-info .avatar { + width: 56px; + height: 56px; + border-radius: 28px; + margin-right: 15px; + } + + .parent-info p { + font-size: 14px; + line-height: 14px; + margin: 15px 0 5px; + } + + .parent-info span { + font-size: 14px; + line-height: 18px; + } + + .box-detail-ab.student-ab { + top: 86px; + } + + .avatar-edit-box.student { + width: 136px; + height: 136px; + } + + .avatar-edit.student { + padding-top: 0; + } + + .kh-title h2 { + font-size: 18px; + } + + .btn-create-khk span { + width: 80px; + height: 28px; + min-width: 80px; + padding: 0 15px; + line-height: 28px; + } + + .line38 { + line-height: 28px; + } + + .btn-create-khk .ico_add_kh { + position: absolute; + top: 7px; + left: 11px; + width: 14px; + } + + .btn-create-khk .ico_line_kh { + position: absolute; + top: 4px; + left: 45px; + } + + .btn-create-khk .ico_line_kh { + position: absolute; + left: 33px; + height: 22px; + } + + .sunE-time-lcv .select-custom-bg .select-styled:after { + top: 6px; + right: 6px; + } + + .f24 { + font-size: 18px !important; + } + + .img-upload { + height: 400px; + } + + .class-box-desc span.class-online, + .class-box-desc span.class-offline { + font-size: 18px; + font-family: "Myriadpro-SemiBold"; + } + + .btn-remove-student { + padding-top: 16px; + } + + .btn-remove-student img { + width: 18px; + } + + .box-shadow.custom-list-student.class_student_list_box.review { + height: calc(100vh - 200px); + } + + .mg-top-0 .chk-custom-gr label:before { + margin-top: 0px; + } + + .box-criteria { + max-height: 217px; + /* max-height: fit-content; */ + } + + .box-criteria-full { + max-height: fit-content; + } + + .box-criteria-scroll { + max-height: 250px; + } + + .dk_class .select-all { + /* margin-right: 14px; */ + padding-right: 35px; + } + + .change_point_checkbox_add_exercise { + padding-right: 40px !important; + } + + .giaotrinh.unit .unit-list .box-giaotrinh-gr { + padding: 0 45px 0 25px; + } + + .box-bcht-date-custom-hei .calendar .day-cell.hide_collapse, + .box-bcht-date-custom-hei .calendar .day-cell.hide_collapse { + display: none; + } + + .box-bcht-date-custom-hei .fullHeight .calendar .hide_collapse, + .box-bcht-date-custom-hei .fullHeight .calendar .hide_collapse { + display: flex; + } + + .set-max-w { + max-width: 302px; + } + + .select-all-k.mg-top-0.flex-m { + margin-right: 10px; + } + + .max-w-hidden { + max-width: 220px; + margin: 0px auto 10px; + } + + .setting-on-off-box .btn.f-13 { + font-size: 14px; + } + + .sunE-container-box.setting { + padding: 10px 10px 0; + } + + .gioithieu-info p { + line-height: 18px; + font-size: 16px; + } + + .term-info p { + line-height: 20px; + color: #404041; + font-size: 14px; + font-family: "Myriadpro-Regular"; + padding: 0 0 20px; + } + + .chk-custom-gr.top-1 { + margin-top: -1px; + } + + .mt-17 { + margin-top: 17px; + } + + .box-video-project { + height: 200px; + } + + .box-giaotrinh-gr.rel.box-shadow .thumb img { + /* max-width: 30px; */ + } + + .file-support-list { + overflow: auto; + max-height: 90px; + padding-right: 10px; + } + + .ldjas + .giaotrinh.teacher-giaobai + .giaotrinh.filter + .sunE-giaotrinh-resuft-filter { + height: calc(100vh - 230px); + } + + .text-center.box-video-project.img-bg { + max-height: 180px; + } + + .list-chart-gr .dtb-sum .w { + width: 183px; + } + + .list-chart-gr .bdg-sum .w { + width: 178px; + } + + .sunE-box-tkh, + .sunE-box-xkh { + padding: 0 15px; + } + + .input-gr input, + .input-gr select { + height: 32px; + border-radius: 16px; + padding: 5px 15px; + font-size: 14px; + } + + .input-gr label, + .laplai label, + .ct-hs label.ht { + font-size: 14px; + padding: 0 0 7px 12px; + } + + .input-gr textarea { + height: 60px; + font-size: 14px; + } + + .input-gr { + margin: 0 0 12px; + } + + .radio-item { + padding: 0 5px; + margin: 6px 0 0; + } + + .radio-item label:before { + top: 1px; + margin: 0 5px 0 0; + width: 12px; + height: 12px; + border-radius: 6px; + } + + .tp-k .time-to.select-time input { + font-size: 14px; + margin: 11px 0 0 15px; + } + + .apdung.tp-k .time-to.select-time .ico_edit_time_to { + top: 12px; + } + + .apdung .time-to.select-time .ico_edit_time_to { + left: 119px; + } + + .apdung.tp-k { + margin: 0; + } + + .laplai { + margin: 0 0 10px; + padding-left: 0; + } + + .select-custom-bg .select-styled { + height: 32px; + border-radius: 16px; + font-size: 14px; + line-height: 32px; + } + + .select-custom-bg .select { + height: 32px; + line-height: 32px; + border-radius: 16px; + } + + .select-custom-bg .select-styled:after { + content: ""; + width: 20px; + height: 20px; + top: 4px; + right: 5px; + background: url(./../images/icon/ico_dropdown_border_white.png) 96% / 20px + no-repeat transparent; + } + + ._detail p { + font-size: 14px; + line-height: 20px; + max-height: 40px; + } + + ._tb .title p { + font-size: 16px; + } + + .nkht-op.list-schedule { + max-height: calc(100vh - 100px); + } + + .schedule-i p { + font-size: 14px; + } + + .time-h { + width: 60px; + } + + .time-h p { + font-size: 16px; + padding-left: 5px; + } + + .score-d p { + font-size: 16px; + text-align: center; + } + + .bg_edit_student_profile { + top: -27px; + } + + .iZROEJ .select-styled { + height: 36px !important; + } + + .iZROEJ .select-styled::after { + top: 4px !important; + } + + .iZROEJ .select-options { + margin-top: 10px; + } + + .sunE-input-gr input { + height: 36px; + line-height: 36px; + font-size: 14px; + padding-left: 20px; + border-radius: 18px; + } + + .sunE-input-gr label { + padding: 0 0 0 15px; + font-size: 14px; + } + + .hoso .sunE-male-female { + width: 36px; + height: 36px; + border-radius: 18px; + line-height: 36px; + } + + .hoso .ico_male, + .hoso .ico_male_active { + width: 17px; + margin: 10px; + } + + .hoso .ico_female, + .hoso .ico_female_active { + width: 12px; + margin: 8px 12px; + } + + .hoso .sunE-male-female span { + font-size: 16px; + line-height: 36px; + } + + .sunE-container-box.hoso .form-sunE-button { + margin: 10px 0 0 !important; + } + + .box-detail-hs .avt-ab { + border: 3px solid #fff; + } + + .add_code_student-gr .ico_err { + top: 4px; + } + + .time-to-khht-cn .ico_edit_time_to_khht { + top: -1px; + right: -24px; + } + + .valid_to_input { + margin: 13px 0 0 10px; + } + + .item-student-name span { + font-size: 16px; + line-height: 20px; + } + + .slider-item-desc .btn-img img.ico_add_custom { + width: 16px; + top: 8px; + left: 10px; + } + + .btn-img .create_class_new.btn-line-blue { + padding-left: 35px; + } + + .item-student-name.max-w-1 p { + max-width: 130px; + } + + .custom-4.slider-custom { + max-width: 320px; + } + + .thanhtich-offline-box .top-title-name.two-line { + max-height: 55px; + } + + .top-title-name p { + font-size: 18px; + line-height: 23px; + font-family: "Myriadpro-SemiBold"; + color: #00a79d; + text-align: center; + } + + .title-k { + font-size: 20px; + line-height: 24px; + font-family: "Myriadpro-SemiBold"; + color: #00a79d; + margin: 0 0 10px; + text-transform: uppercase; + } + + .gr-k p { + text-align: left; + font-size: 16px; + line-height: 45px; + font-family: "Myriadpro-Light"; + color: #231f20; + margin: 0; + padding: 0; + } + + .gr-k span { + display: block; + font-size: 18px; + line-height: 45px; + font-family: "Myriadpro-Bold"; + color: #00a79d; + margin: 0; + padding: 0; + } + + .slider-custom.custom-4 .slick-dots { + bottom: -60px; + } + + .bg_auth { + max-width: 100%; + width: 100%; + } + + /* File Support CSS */ + .pasd.sunE-container-box { + padding: 17px 20px 0; + } + + .__overview_report { + padding: 20px 0px; + } + + .responsive_low_screen_files_support { + padding: 0 40px 0 40px !important; + } + + .responsive_btn_assign_assignments { + width: 100px !important; + } + + .ml--5 { + margin-left: 0; + } + + /*golden board*/ + .block_golden_board { + padding: 0; + } + + .height_top_3_golden_board { + height: calc(100vh - 100px) !important; + padding: 10px 0 10px 0; + } + + .padding_tops_golden_board { + padding: 15px 10px 15px 20px !important; + } + + .width_block_top_golden_board { + height: 80px; + width: 35%; + } + + .top_1_crown { + width: 35%; + left: 33px !important; + top: 7px !important; + } + + .top_1_avatar { + top: 25px !important; + left: 30px !important; + width: 40px !important; + height: 40px !important; + } + + .slick-dots { + bottom: -30px !important; + } + + .slider-custom-student .slider_student_wrapper .slick-dots { + position: relative !important; + bottom: 0 !important; + margin: 0.3rem 0 0.5rem; + } + + .space_null_responsive_home_page_teacher { + width: 145px !important; + } + + .font_average_score { + margin-bottom: 10px !important; + } + + .height_calendar_responsive { + min-height: 335px; + } + + .upgrade_container { + padding-top: 0.25rem; + } + + .form_upgrade { + padding-top: 0.75rem !important; + } + + .title_upgrade { + padding-bottom: 0.5rem !important; + } + + .content_homepage_student .slider_homepage_student { + margin-bottom: 0.25rem !important; + } +} diff --git a/public/assets/fonts/AvertaStdCY-Black_1.otf b/public/assets/fonts/AvertaStdCY-Black_1.otf new file mode 100644 index 0000000..adfbc30 Binary files /dev/null and b/public/assets/fonts/AvertaStdCY-Black_1.otf differ diff --git a/public/assets/fonts/AvertaStdCY-Bold_1.otf b/public/assets/fonts/AvertaStdCY-Bold_1.otf new file mode 100644 index 0000000..6e8877a Binary files /dev/null and b/public/assets/fonts/AvertaStdCY-Bold_1.otf differ diff --git a/public/assets/fonts/AvertaStdCY-ExtraboldItalic_1.otf b/public/assets/fonts/AvertaStdCY-ExtraboldItalic_1.otf new file mode 100644 index 0000000..f5c8e12 Binary files /dev/null and b/public/assets/fonts/AvertaStdCY-ExtraboldItalic_1.otf differ diff --git a/public/assets/fonts/AvertaStdCY-Extrabold_1.otf b/public/assets/fonts/AvertaStdCY-Extrabold_1.otf new file mode 100644 index 0000000..fe697ac Binary files /dev/null and b/public/assets/fonts/AvertaStdCY-Extrabold_1.otf differ diff --git a/public/assets/fonts/AvertaStdCY-RegularItalic_1.otf b/public/assets/fonts/AvertaStdCY-RegularItalic_1.otf new file mode 100644 index 0000000..ef6e9b3 Binary files /dev/null and b/public/assets/fonts/AvertaStdCY-RegularItalic_1.otf differ diff --git a/public/assets/fonts/AvertaStdCY-Regular_3.otf b/public/assets/fonts/AvertaStdCY-Regular_3.otf new file mode 100644 index 0000000..ebe3348 Binary files /dev/null and b/public/assets/fonts/AvertaStdCY-Regular_3.otf differ diff --git a/public/assets/fonts/AvertaStdCY-Semibold_1.otf b/public/assets/fonts/AvertaStdCY-Semibold_1.otf new file mode 100644 index 0000000..f3b2dc5 Binary files /dev/null and b/public/assets/fonts/AvertaStdCY-Semibold_1.otf differ diff --git a/public/assets/fonts/Barlow-Bold.ttf b/public/assets/fonts/Barlow-Bold.ttf new file mode 100644 index 0000000..28f2d3a Binary files /dev/null and b/public/assets/fonts/Barlow-Bold.ttf differ diff --git a/public/assets/fonts/MYRIADPRO-BOLD.woff b/public/assets/fonts/MYRIADPRO-BOLD.woff new file mode 100644 index 0000000..5fe67eb Binary files /dev/null and b/public/assets/fonts/MYRIADPRO-BOLD.woff differ diff --git a/public/assets/fonts/MYRIADPRO-LIGHT_0.OTF b/public/assets/fonts/MYRIADPRO-LIGHT_0.OTF new file mode 100644 index 0000000..2ede04b Binary files /dev/null and b/public/assets/fonts/MYRIADPRO-LIGHT_0.OTF differ diff --git a/public/assets/fonts/MYRIADPRO-REGULAR.OTF b/public/assets/fonts/MYRIADPRO-REGULAR.OTF new file mode 100644 index 0000000..5097866 Binary files /dev/null and b/public/assets/fonts/MYRIADPRO-REGULAR.OTF differ diff --git a/public/assets/fonts/MYRIADPRO-REGULAR.woff b/public/assets/fonts/MYRIADPRO-REGULAR.woff new file mode 100644 index 0000000..40c795d Binary files /dev/null and b/public/assets/fonts/MYRIADPRO-REGULAR.woff differ diff --git a/public/assets/fonts/MYRIADPRO-SEMIBOLD.woff b/public/assets/fonts/MYRIADPRO-SEMIBOLD.woff new file mode 100644 index 0000000..79ee0c1 Binary files /dev/null and b/public/assets/fonts/MYRIADPRO-SEMIBOLD.woff differ diff --git a/public/assets/fonts/MyriadProCondensedItalic.ttf b/public/assets/fonts/MyriadProCondensedItalic.ttf new file mode 100644 index 0000000..2f65020 Binary files /dev/null and b/public/assets/fonts/MyriadProCondensedItalic.ttf differ diff --git a/public/assets/fonts/iCiel-Alina.otf b/public/assets/fonts/iCiel-Alina.otf new file mode 100644 index 0000000..37e4996 Binary files /dev/null and b/public/assets/fonts/iCiel-Alina.otf differ diff --git a/public/assets/fonts/myriad-pro/MYRIADPRO-BOLD.OTF b/public/assets/fonts/myriad-pro/MYRIADPRO-BOLD.OTF new file mode 100644 index 0000000..93b53b5 Binary files /dev/null and b/public/assets/fonts/myriad-pro/MYRIADPRO-BOLD.OTF differ diff --git a/public/assets/fonts/myriad-pro/MYRIADPRO-REGULAR.OTF b/public/assets/fonts/myriad-pro/MYRIADPRO-REGULAR.OTF new file mode 100644 index 0000000..5097866 Binary files /dev/null and b/public/assets/fonts/myriad-pro/MYRIADPRO-REGULAR.OTF differ diff --git a/public/assets/fonts/myriad-pro/MYRIADPRO-SEMIBOLD.OTF b/public/assets/fonts/myriad-pro/MYRIADPRO-SEMIBOLD.OTF new file mode 100644 index 0000000..18ff7db Binary files /dev/null and b/public/assets/fonts/myriad-pro/MYRIADPRO-SEMIBOLD.OTF differ diff --git a/public/assets/images/Group_7168.png b/public/assets/images/Group_7168.png new file mode 100644 index 0000000..bc07a47 Binary files /dev/null and b/public/assets/images/Group_7168.png differ diff --git a/public/assets/images/accountActivationNews/arrow.png b/public/assets/images/accountActivationNews/arrow.png new file mode 100644 index 0000000..a9c2906 Binary files /dev/null and b/public/assets/images/accountActivationNews/arrow.png differ diff --git a/public/assets/images/accountActivationNews/ico_computer.png b/public/assets/images/accountActivationNews/ico_computer.png new file mode 100644 index 0000000..7d1d3fa Binary files /dev/null and b/public/assets/images/accountActivationNews/ico_computer.png differ diff --git a/public/assets/images/accountActivationNews/ico_mobile.png b/public/assets/images/accountActivationNews/ico_mobile.png new file mode 100644 index 0000000..f1a3929 Binary files /dev/null and b/public/assets/images/accountActivationNews/ico_mobile.png differ diff --git a/public/assets/images/accountActivationNews/mobile_student_acc_1_1.png b/public/assets/images/accountActivationNews/mobile_student_acc_1_1.png new file mode 100644 index 0000000..6ec01d5 Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_student_acc_1_1.png differ diff --git a/public/assets/images/accountActivationNews/mobile_student_acc_1_2.png b/public/assets/images/accountActivationNews/mobile_student_acc_1_2.png new file mode 100644 index 0000000..129120b Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_student_acc_1_2.png differ diff --git a/public/assets/images/accountActivationNews/mobile_student_acc_2_1.png b/public/assets/images/accountActivationNews/mobile_student_acc_2_1.png new file mode 100644 index 0000000..cbb40bb Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_student_acc_2_1.png differ diff --git a/public/assets/images/accountActivationNews/mobile_student_acc_3_1.png b/public/assets/images/accountActivationNews/mobile_student_acc_3_1.png new file mode 100644 index 0000000..ecb08ac Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_student_acc_3_1.png differ diff --git a/public/assets/images/accountActivationNews/mobile_student_acc_3_2.png b/public/assets/images/accountActivationNews/mobile_student_acc_3_2.png new file mode 100644 index 0000000..a1de2ce Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_student_acc_3_2.png differ diff --git a/public/assets/images/accountActivationNews/mobile_student_acc_3_3.png b/public/assets/images/accountActivationNews/mobile_student_acc_3_3.png new file mode 100644 index 0000000..2fcd1ad Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_student_acc_3_3.png differ diff --git a/public/assets/images/accountActivationNews/mobile_student_acc_4_1.png b/public/assets/images/accountActivationNews/mobile_student_acc_4_1.png new file mode 100644 index 0000000..bad1a7d Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_student_acc_4_1.png differ diff --git a/public/assets/images/accountActivationNews/mobile_student_acc_4_2.png b/public/assets/images/accountActivationNews/mobile_student_acc_4_2.png new file mode 100644 index 0000000..0501794 Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_student_acc_4_2.png differ diff --git a/public/assets/images/accountActivationNews/mobile_student_acc_4_3.png b/public/assets/images/accountActivationNews/mobile_student_acc_4_3.png new file mode 100644 index 0000000..8f1a099 Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_student_acc_4_3.png differ diff --git a/public/assets/images/accountActivationNews/mobile_student_package_2.png b/public/assets/images/accountActivationNews/mobile_student_package_2.png new file mode 100644 index 0000000..6e09e19 Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_student_package_2.png differ diff --git a/public/assets/images/accountActivationNews/mobile_student_package_3.png b/public/assets/images/accountActivationNews/mobile_student_package_3.png new file mode 100644 index 0000000..f1668c7 Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_student_package_3.png differ diff --git a/public/assets/images/accountActivationNews/mobile_student_package_4.png b/public/assets/images/accountActivationNews/mobile_student_package_4.png new file mode 100644 index 0000000..26f88d4 Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_student_package_4.png differ diff --git a/public/assets/images/accountActivationNews/mobile_teacher_acc_1_1.png b/public/assets/images/accountActivationNews/mobile_teacher_acc_1_1.png new file mode 100644 index 0000000..dc144e8 Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_teacher_acc_1_1.png differ diff --git a/public/assets/images/accountActivationNews/mobile_teacher_acc_1_2.png b/public/assets/images/accountActivationNews/mobile_teacher_acc_1_2.png new file mode 100644 index 0000000..4c3152c Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_teacher_acc_1_2.png differ diff --git a/public/assets/images/accountActivationNews/mobile_teacher_acc_3_2.png b/public/assets/images/accountActivationNews/mobile_teacher_acc_3_2.png new file mode 100644 index 0000000..a9d4a7c Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_teacher_acc_3_2.png differ diff --git a/public/assets/images/accountActivationNews/mobile_teacher_acc_3_3.png b/public/assets/images/accountActivationNews/mobile_teacher_acc_3_3.png new file mode 100644 index 0000000..9bf3a25 Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_teacher_acc_3_3.png differ diff --git a/public/assets/images/accountActivationNews/mobile_teacher_acc_4_1.png b/public/assets/images/accountActivationNews/mobile_teacher_acc_4_1.png new file mode 100644 index 0000000..8615884 Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_teacher_acc_4_1.png differ diff --git a/public/assets/images/accountActivationNews/mobile_teacher_acc_4_2.png b/public/assets/images/accountActivationNews/mobile_teacher_acc_4_2.png new file mode 100644 index 0000000..a8a526a Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_teacher_acc_4_2.png differ diff --git a/public/assets/images/accountActivationNews/mobile_teacher_acc_5_1.png b/public/assets/images/accountActivationNews/mobile_teacher_acc_5_1.png new file mode 100644 index 0000000..287abbb Binary files /dev/null and b/public/assets/images/accountActivationNews/mobile_teacher_acc_5_1.png differ diff --git a/public/assets/images/accountActivationNews/pc_student_acc_2.png b/public/assets/images/accountActivationNews/pc_student_acc_2.png new file mode 100644 index 0000000..3a2d60d Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_student_acc_2.png differ diff --git a/public/assets/images/accountActivationNews/pc_student_acc_3.png b/public/assets/images/accountActivationNews/pc_student_acc_3.png new file mode 100644 index 0000000..01048d7 Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_student_acc_3.png differ diff --git a/public/assets/images/accountActivationNews/pc_student_acc_4.png b/public/assets/images/accountActivationNews/pc_student_acc_4.png new file mode 100644 index 0000000..9fe9d5f Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_student_acc_4.png differ diff --git a/public/assets/images/accountActivationNews/pc_student_acc_5.png b/public/assets/images/accountActivationNews/pc_student_acc_5.png new file mode 100644 index 0000000..f5e6f69 Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_student_acc_5.png differ diff --git a/public/assets/images/accountActivationNews/pc_student_acc_6.png b/public/assets/images/accountActivationNews/pc_student_acc_6.png new file mode 100644 index 0000000..d057bd4 Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_student_acc_6.png differ diff --git a/public/assets/images/accountActivationNews/pc_student_package_2.png b/public/assets/images/accountActivationNews/pc_student_package_2.png new file mode 100644 index 0000000..85b92e3 Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_student_package_2.png differ diff --git a/public/assets/images/accountActivationNews/pc_student_package_3.png b/public/assets/images/accountActivationNews/pc_student_package_3.png new file mode 100644 index 0000000..182aceb Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_student_package_3.png differ diff --git a/public/assets/images/accountActivationNews/pc_teacher_acc_3.png b/public/assets/images/accountActivationNews/pc_teacher_acc_3.png new file mode 100644 index 0000000..3a0c2ce Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_teacher_acc_3.png differ diff --git a/public/assets/images/accountActivationNews/pc_teacher_acc_4.png b/public/assets/images/accountActivationNews/pc_teacher_acc_4.png new file mode 100644 index 0000000..f50603b Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_teacher_acc_4.png differ diff --git a/public/assets/images/accountActivationNews/pc_teacher_acc_5_1.png b/public/assets/images/accountActivationNews/pc_teacher_acc_5_1.png new file mode 100644 index 0000000..5dd26f1 Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_teacher_acc_5_1.png differ diff --git a/public/assets/images/accountActivationNews/pc_teacher_acc_5_2.png b/public/assets/images/accountActivationNews/pc_teacher_acc_5_2.png new file mode 100644 index 0000000..ba566ea Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_teacher_acc_5_2.png differ diff --git a/public/assets/images/accountActivationNews/pc_teacher_acc_5_3.png b/public/assets/images/accountActivationNews/pc_teacher_acc_5_3.png new file mode 100644 index 0000000..e26a96b Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_teacher_acc_5_3.png differ diff --git a/public/assets/images/accountActivationNews/pc_teacher_acc_5_4.png b/public/assets/images/accountActivationNews/pc_teacher_acc_5_4.png new file mode 100644 index 0000000..82f48a7 Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_teacher_acc_5_4.png differ diff --git a/public/assets/images/accountActivationNews/pc_teacher_acc_6_1.png b/public/assets/images/accountActivationNews/pc_teacher_acc_6_1.png new file mode 100644 index 0000000..ec37f96 Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_teacher_acc_6_1.png differ diff --git a/public/assets/images/accountActivationNews/pc_teacher_acc_6_2.png b/public/assets/images/accountActivationNews/pc_teacher_acc_6_2.png new file mode 100644 index 0000000..6fa0770 Binary files /dev/null and b/public/assets/images/accountActivationNews/pc_teacher_acc_6_2.png differ diff --git a/public/assets/images/accountActivationNews/slide.png b/public/assets/images/accountActivationNews/slide.png new file mode 100644 index 0000000..c4a7bef Binary files /dev/null and b/public/assets/images/accountActivationNews/slide.png differ diff --git a/public/assets/images/accountActivationNews/slide_mobile.png b/public/assets/images/accountActivationNews/slide_mobile.png new file mode 100644 index 0000000..89d22be Binary files /dev/null and b/public/assets/images/accountActivationNews/slide_mobile.png differ diff --git a/public/assets/images/arrow_left_circle.png b/public/assets/images/arrow_left_circle.png new file mode 100644 index 0000000..df31650 Binary files /dev/null and b/public/assets/images/arrow_left_circle.png differ diff --git a/public/assets/images/arrow_right_circle.png b/public/assets/images/arrow_right_circle.png new file mode 100644 index 0000000..dfef10b Binary files /dev/null and b/public/assets/images/arrow_right_circle.png differ diff --git a/public/assets/images/auth/img_gen_female_active.png b/public/assets/images/auth/img_gen_female_active.png new file mode 100644 index 0000000..df32b7f Binary files /dev/null and b/public/assets/images/auth/img_gen_female_active.png differ diff --git a/public/assets/images/auth/img_gen_female_disabled.png b/public/assets/images/auth/img_gen_female_disabled.png new file mode 100644 index 0000000..7032b1a Binary files /dev/null and b/public/assets/images/auth/img_gen_female_disabled.png differ diff --git a/public/assets/images/auth/img_gen_male_active.png b/public/assets/images/auth/img_gen_male_active.png new file mode 100644 index 0000000..8548689 Binary files /dev/null and b/public/assets/images/auth/img_gen_male_active.png differ diff --git a/public/assets/images/auth/img_gen_male_disabled.png b/public/assets/images/auth/img_gen_male_disabled.png new file mode 100644 index 0000000..8191970 Binary files /dev/null and b/public/assets/images/auth/img_gen_male_disabled.png differ diff --git a/public/assets/images/auth/parent.png b/public/assets/images/auth/parent.png new file mode 100644 index 0000000..ef20e7f Binary files /dev/null and b/public/assets/images/auth/parent.png differ diff --git a/public/assets/images/auth/student.png b/public/assets/images/auth/student.png new file mode 100644 index 0000000..e5014f1 Binary files /dev/null and b/public/assets/images/auth/student.png differ diff --git a/public/assets/images/auth/teacher.png b/public/assets/images/auth/teacher.png new file mode 100644 index 0000000..fdd6b74 Binary files /dev/null and b/public/assets/images/auth/teacher.png differ diff --git a/public/assets/images/authNews/bg_login.png b/public/assets/images/authNews/bg_login.png new file mode 100644 index 0000000..0e7aa1c Binary files /dev/null and b/public/assets/images/authNews/bg_login.png differ diff --git a/public/assets/images/authNews/ico_birthday.png b/public/assets/images/authNews/ico_birthday.png new file mode 100644 index 0000000..8e1cf6c Binary files /dev/null and b/public/assets/images/authNews/ico_birthday.png differ diff --git a/public/assets/images/authNews/ico_cf_password.png b/public/assets/images/authNews/ico_cf_password.png new file mode 100644 index 0000000..35bf624 Binary files /dev/null and b/public/assets/images/authNews/ico_cf_password.png differ diff --git a/public/assets/images/authNews/ico_city.png b/public/assets/images/authNews/ico_city.png new file mode 100644 index 0000000..1d8a99c Binary files /dev/null and b/public/assets/images/authNews/ico_city.png differ diff --git a/public/assets/images/authNews/ico_district.png b/public/assets/images/authNews/ico_district.png new file mode 100644 index 0000000..ede3c81 Binary files /dev/null and b/public/assets/images/authNews/ico_district.png differ diff --git a/public/assets/images/authNews/ico_email.png b/public/assets/images/authNews/ico_email.png new file mode 100644 index 0000000..4cc1273 Binary files /dev/null and b/public/assets/images/authNews/ico_email.png differ diff --git a/public/assets/images/authNews/ico_gender.png b/public/assets/images/authNews/ico_gender.png new file mode 100644 index 0000000..8bdc8fd Binary files /dev/null and b/public/assets/images/authNews/ico_gender.png differ diff --git a/public/assets/images/authNews/ico_gg.png b/public/assets/images/authNews/ico_gg.png new file mode 100644 index 0000000..2ddad1f Binary files /dev/null and b/public/assets/images/authNews/ico_gg.png differ diff --git a/public/assets/images/authNews/ico_grade.png b/public/assets/images/authNews/ico_grade.png new file mode 100644 index 0000000..88bd05b Binary files /dev/null and b/public/assets/images/authNews/ico_grade.png differ diff --git a/public/assets/images/authNews/ico_home_address.png b/public/assets/images/authNews/ico_home_address.png new file mode 100644 index 0000000..f84ba59 Binary files /dev/null and b/public/assets/images/authNews/ico_home_address.png differ diff --git a/public/assets/images/authNews/ico_name.png b/public/assets/images/authNews/ico_name.png new file mode 100644 index 0000000..dfa273e Binary files /dev/null and b/public/assets/images/authNews/ico_name.png differ diff --git a/public/assets/images/authNews/ico_password.png b/public/assets/images/authNews/ico_password.png new file mode 100644 index 0000000..f588dcf Binary files /dev/null and b/public/assets/images/authNews/ico_password.png differ diff --git a/public/assets/images/authNews/ico_phone.png b/public/assets/images/authNews/ico_phone.png new file mode 100644 index 0000000..3176f79 Binary files /dev/null and b/public/assets/images/authNews/ico_phone.png differ diff --git a/public/assets/images/authNews/ico_school.png b/public/assets/images/authNews/ico_school.png new file mode 100644 index 0000000..3316dff Binary files /dev/null and b/public/assets/images/authNews/ico_school.png differ diff --git a/public/assets/images/authNews/ico_search.png b/public/assets/images/authNews/ico_search.png new file mode 100644 index 0000000..7f10bd6 Binary files /dev/null and b/public/assets/images/authNews/ico_search.png differ diff --git a/public/assets/images/authNews/ico_tick_select.png b/public/assets/images/authNews/ico_tick_select.png new file mode 100644 index 0000000..1e7eb67 Binary files /dev/null and b/public/assets/images/authNews/ico_tick_select.png differ diff --git a/public/assets/images/authNews/open_eye.png b/public/assets/images/authNews/open_eye.png new file mode 100644 index 0000000..0195bcf Binary files /dev/null and b/public/assets/images/authNews/open_eye.png differ diff --git a/public/assets/images/authNews/parent.png b/public/assets/images/authNews/parent.png new file mode 100644 index 0000000..4e3f79d Binary files /dev/null and b/public/assets/images/authNews/parent.png differ diff --git a/public/assets/images/authNews/qr_app_store.png b/public/assets/images/authNews/qr_app_store.png new file mode 100644 index 0000000..4d52a3b Binary files /dev/null and b/public/assets/images/authNews/qr_app_store.png differ diff --git a/public/assets/images/authNews/qr_gg_play.png b/public/assets/images/authNews/qr_gg_play.png new file mode 100644 index 0000000..d5d7740 Binary files /dev/null and b/public/assets/images/authNews/qr_gg_play.png differ diff --git a/public/assets/images/authNews/student.png b/public/assets/images/authNews/student.png new file mode 100644 index 0000000..6576ae4 Binary files /dev/null and b/public/assets/images/authNews/student.png differ diff --git a/public/assets/images/authNews/teacher.png b/public/assets/images/authNews/teacher.png new file mode 100644 index 0000000..b919dd0 Binary files /dev/null and b/public/assets/images/authNews/teacher.png differ diff --git a/public/assets/images/authNews/visible.png b/public/assets/images/authNews/visible.png new file mode 100644 index 0000000..48be14c Binary files /dev/null and b/public/assets/images/authNews/visible.png differ diff --git a/public/assets/images/banner_contact.png b/public/assets/images/banner_contact.png new file mode 100644 index 0000000..e01c199 Binary files /dev/null and b/public/assets/images/banner_contact.png differ diff --git a/public/assets/images/banner_contact_mobile.png b/public/assets/images/banner_contact_mobile.png new file mode 100644 index 0000000..40aa212 Binary files /dev/null and b/public/assets/images/banner_contact_mobile.png differ diff --git a/public/assets/images/banner_side.png b/public/assets/images/banner_side.png new file mode 100644 index 0000000..4fbd770 Binary files /dev/null and b/public/assets/images/banner_side.png differ diff --git a/public/assets/images/banner_side_mobile.png b/public/assets/images/banner_side_mobile.png new file mode 100644 index 0000000..2340b3c Binary files /dev/null and b/public/assets/images/banner_side_mobile.png differ diff --git a/public/assets/images/banner_upgrade_account.png b/public/assets/images/banner_upgrade_account.png new file mode 100644 index 0000000..e67b492 Binary files /dev/null and b/public/assets/images/banner_upgrade_account.png differ diff --git a/public/assets/images/banner_upgrade_account_teacher.png b/public/assets/images/banner_upgrade_account_teacher.png new file mode 100644 index 0000000..53b4dc8 Binary files /dev/null and b/public/assets/images/banner_upgrade_account_teacher.png differ diff --git a/public/assets/images/bg-detail-unit.jpg b/public/assets/images/bg-detail-unit.jpg new file mode 100644 index 0000000..6f90c47 Binary files /dev/null and b/public/assets/images/bg-detail-unit.jpg differ diff --git a/public/assets/images/bg-result-exam.png b/public/assets/images/bg-result-exam.png new file mode 100644 index 0000000..7b620e2 Binary files /dev/null and b/public/assets/images/bg-result-exam.png differ diff --git a/public/assets/images/bg_add_student.png b/public/assets/images/bg_add_student.png new file mode 100644 index 0000000..eabc1a6 Binary files /dev/null and b/public/assets/images/bg_add_student.png differ diff --git a/public/assets/images/bg_auth.png b/public/assets/images/bg_auth.png new file mode 100644 index 0000000..02a78f8 Binary files /dev/null and b/public/assets/images/bg_auth.png differ diff --git a/public/assets/images/bg_auth_full.png b/public/assets/images/bg_auth_full.png new file mode 100644 index 0000000..563bd4d Binary files /dev/null and b/public/assets/images/bg_auth_full.png differ diff --git a/public/assets/images/bg_auth_full_1.png b/public/assets/images/bg_auth_full_1.png new file mode 100644 index 0000000..0dda273 Binary files /dev/null and b/public/assets/images/bg_auth_full_1.png differ diff --git a/public/assets/images/bg_auth_full_2.png b/public/assets/images/bg_auth_full_2.png new file mode 100644 index 0000000..b1ee7d4 Binary files /dev/null and b/public/assets/images/bg_auth_full_2.png differ diff --git a/public/assets/images/bg_gv.png b/public/assets/images/bg_gv.png new file mode 100644 index 0000000..b260da8 Binary files /dev/null and b/public/assets/images/bg_gv.png differ diff --git a/public/assets/images/bg_login.png b/public/assets/images/bg_login.png new file mode 100644 index 0000000..83c9a88 Binary files /dev/null and b/public/assets/images/bg_login.png differ diff --git a/public/assets/images/bg_register.png b/public/assets/images/bg_register.png new file mode 100644 index 0000000..c326ba0 Binary files /dev/null and b/public/assets/images/bg_register.png differ diff --git a/public/assets/images/chambai/Group 5107.png b/public/assets/images/chambai/Group 5107.png new file mode 100644 index 0000000..32dab5c Binary files /dev/null and b/public/assets/images/chambai/Group 5107.png differ diff --git a/public/assets/images/chambai/Group 5263.png b/public/assets/images/chambai/Group 5263.png new file mode 100644 index 0000000..9e47896 Binary files /dev/null and b/public/assets/images/chambai/Group 5263.png differ diff --git a/public/assets/images/chambai/Group 5280.png b/public/assets/images/chambai/Group 5280.png new file mode 100644 index 0000000..10a74d6 Binary files /dev/null and b/public/assets/images/chambai/Group 5280.png differ diff --git a/public/assets/images/chambai/Group 6074.png b/public/assets/images/chambai/Group 6074.png new file mode 100644 index 0000000..4a46d72 Binary files /dev/null and b/public/assets/images/chambai/Group 6074.png differ diff --git a/public/assets/images/chambai/Group 6076.png b/public/assets/images/chambai/Group 6076.png new file mode 100644 index 0000000..aed7734 Binary files /dev/null and b/public/assets/images/chambai/Group 6076.png differ diff --git a/public/assets/images/chambai/Group 6135.png b/public/assets/images/chambai/Group 6135.png new file mode 100644 index 0000000..825ff11 Binary files /dev/null and b/public/assets/images/chambai/Group 6135.png differ diff --git a/public/assets/images/chambai/Group 6144.png b/public/assets/images/chambai/Group 6144.png new file mode 100644 index 0000000..aa6fd49 Binary files /dev/null and b/public/assets/images/chambai/Group 6144.png differ diff --git a/public/assets/images/chambai/HOCVIEN-CLASS.png b/public/assets/images/chambai/HOCVIEN-CLASS.png new file mode 100644 index 0000000..91e8780 Binary files /dev/null and b/public/assets/images/chambai/HOCVIEN-CLASS.png differ diff --git a/public/assets/images/chambai/Path 21632.png b/public/assets/images/chambai/Path 21632.png new file mode 100644 index 0000000..3f312d5 Binary files /dev/null and b/public/assets/images/chambai/Path 21632.png differ diff --git a/public/assets/images/chambai/Path 232.png b/public/assets/images/chambai/Path 232.png new file mode 100644 index 0000000..8be49cf Binary files /dev/null and b/public/assets/images/chambai/Path 232.png differ diff --git a/public/assets/images/chambai/Path 23237.png b/public/assets/images/chambai/Path 23237.png new file mode 100644 index 0000000..9a2fd09 Binary files /dev/null and b/public/assets/images/chambai/Path 23237.png differ diff --git a/public/assets/images/chambai/badge-vodich.png b/public/assets/images/chambai/badge-vodich.png new file mode 100644 index 0000000..ad144ad Binary files /dev/null and b/public/assets/images/chambai/badge-vodich.png differ diff --git a/public/assets/images/chambai/badge-vodich1.png b/public/assets/images/chambai/badge-vodich1.png new file mode 100644 index 0000000..0c61d04 Binary files /dev/null and b/public/assets/images/chambai/badge-vodich1.png differ diff --git a/public/assets/images/chambai/badge-vodich2.png b/public/assets/images/chambai/badge-vodich2.png new file mode 100644 index 0000000..81f48e7 Binary files /dev/null and b/public/assets/images/chambai/badge-vodich2.png differ diff --git a/public/assets/images/chambai/badge-vodich3.png b/public/assets/images/chambai/badge-vodich3.png new file mode 100644 index 0000000..8512a41 Binary files /dev/null and b/public/assets/images/chambai/badge-vodich3.png differ diff --git a/public/assets/images/chambai/ico_+.png b/public/assets/images/chambai/ico_+.png new file mode 100644 index 0000000..0a6c189 Binary files /dev/null and b/public/assets/images/chambai/ico_+.png differ diff --git a/public/assets/images/chambai/ico_add_small.png b/public/assets/images/chambai/ico_add_small.png new file mode 100644 index 0000000..0fe6d08 Binary files /dev/null and b/public/assets/images/chambai/ico_add_small.png differ diff --git a/public/assets/images/chambai/ico_avt_detail.png b/public/assets/images/chambai/ico_avt_detail.png new file mode 100644 index 0000000..684c12f Binary files /dev/null and b/public/assets/images/chambai/ico_avt_detail.png differ diff --git a/public/assets/images/chambai/ico_clock_orange.png b/public/assets/images/chambai/ico_clock_orange.png new file mode 100644 index 0000000..49578fd Binary files /dev/null and b/public/assets/images/chambai/ico_clock_orange.png differ diff --git a/public/assets/images/chambai/ico_email.png b/public/assets/images/chambai/ico_email.png new file mode 100644 index 0000000..141127c Binary files /dev/null and b/public/assets/images/chambai/ico_email.png differ diff --git a/public/assets/images/chambai/ico_remove_small.png b/public/assets/images/chambai/ico_remove_small.png new file mode 100644 index 0000000..24f3db1 Binary files /dev/null and b/public/assets/images/chambai/ico_remove_small.png differ diff --git a/public/assets/images/chambai/ico_right.png b/public/assets/images/chambai/ico_right.png new file mode 100644 index 0000000..a3ca709 Binary files /dev/null and b/public/assets/images/chambai/ico_right.png differ diff --git a/public/assets/images/coursesNews/bg_content_1.png b/public/assets/images/coursesNews/bg_content_1.png new file mode 100644 index 0000000..391f9c8 Binary files /dev/null and b/public/assets/images/coursesNews/bg_content_1.png differ diff --git a/public/assets/images/coursesNews/book_baby.png b/public/assets/images/coursesNews/book_baby.png new file mode 100644 index 0000000..0b819dd Binary files /dev/null and b/public/assets/images/coursesNews/book_baby.png differ diff --git a/public/assets/images/coursesNews/book_box.png b/public/assets/images/coursesNews/book_box.png new file mode 100644 index 0000000..c252d61 Binary files /dev/null and b/public/assets/images/coursesNews/book_box.png differ diff --git a/public/assets/images/coursesNews/border_1.png b/public/assets/images/coursesNews/border_1.png new file mode 100644 index 0000000..b83fb91 Binary files /dev/null and b/public/assets/images/coursesNews/border_1.png differ diff --git a/public/assets/images/coursesNews/border_2.png b/public/assets/images/coursesNews/border_2.png new file mode 100644 index 0000000..0cea0d9 Binary files /dev/null and b/public/assets/images/coursesNews/border_2.png differ diff --git a/public/assets/images/coursesNews/clock_box.png b/public/assets/images/coursesNews/clock_box.png new file mode 100644 index 0000000..b74fb07 Binary files /dev/null and b/public/assets/images/coursesNews/clock_box.png differ diff --git a/public/assets/images/coursesNews/earth.png b/public/assets/images/coursesNews/earth.png new file mode 100644 index 0000000..f7cdb01 Binary files /dev/null and b/public/assets/images/coursesNews/earth.png differ diff --git a/public/assets/images/coursesNews/img_courses_tree.png b/public/assets/images/coursesNews/img_courses_tree.png new file mode 100644 index 0000000..f516a7b Binary files /dev/null and b/public/assets/images/coursesNews/img_courses_tree.png differ diff --git a/public/assets/images/coursesNews/img_item_2.png b/public/assets/images/coursesNews/img_item_2.png new file mode 100644 index 0000000..eb6de3d Binary files /dev/null and b/public/assets/images/coursesNews/img_item_2.png differ diff --git a/public/assets/images/coursesNews/img_item_3.png b/public/assets/images/coursesNews/img_item_3.png new file mode 100644 index 0000000..38664f4 Binary files /dev/null and b/public/assets/images/coursesNews/img_item_3.png differ diff --git a/public/assets/images/coursesNews/img_item_4.png b/public/assets/images/coursesNews/img_item_4.png new file mode 100644 index 0000000..455542b Binary files /dev/null and b/public/assets/images/coursesNews/img_item_4.png differ diff --git a/public/assets/images/coursesNews/img_student_1.png b/public/assets/images/coursesNews/img_student_1.png new file mode 100644 index 0000000..4615662 Binary files /dev/null and b/public/assets/images/coursesNews/img_student_1.png differ diff --git a/public/assets/images/coursesNews/img_student_2.png b/public/assets/images/coursesNews/img_student_2.png new file mode 100644 index 0000000..bd53554 Binary files /dev/null and b/public/assets/images/coursesNews/img_student_2.png differ diff --git a/public/assets/images/coursesNews/older/2.png b/public/assets/images/coursesNews/older/2.png new file mode 100644 index 0000000..e3af62f Binary files /dev/null and b/public/assets/images/coursesNews/older/2.png differ diff --git a/public/assets/images/coursesNews/older/3.png b/public/assets/images/coursesNews/older/3.png new file mode 100644 index 0000000..1ffbbaf Binary files /dev/null and b/public/assets/images/coursesNews/older/3.png differ diff --git a/public/assets/images/coursesNews/older/banner.png b/public/assets/images/coursesNews/older/banner.png new file mode 100644 index 0000000..e01c199 Binary files /dev/null and b/public/assets/images/coursesNews/older/banner.png differ diff --git a/public/assets/images/coursesNews/older/border1.png b/public/assets/images/coursesNews/older/border1.png new file mode 100644 index 0000000..968ca96 Binary files /dev/null and b/public/assets/images/coursesNews/older/border1.png differ diff --git a/public/assets/images/coursesNews/older/border2.png b/public/assets/images/coursesNews/older/border2.png new file mode 100644 index 0000000..5bae8d1 Binary files /dev/null and b/public/assets/images/coursesNews/older/border2.png differ diff --git a/public/assets/images/coursesNews/older/grade6.png b/public/assets/images/coursesNews/older/grade6.png new file mode 100644 index 0000000..8b2aa8d Binary files /dev/null and b/public/assets/images/coursesNews/older/grade6.png differ diff --git a/public/assets/images/coursesNews/older/grade7.png b/public/assets/images/coursesNews/older/grade7.png new file mode 100644 index 0000000..373dfdb Binary files /dev/null and b/public/assets/images/coursesNews/older/grade7.png differ diff --git a/public/assets/images/coursesNews/older/grade8.png b/public/assets/images/coursesNews/older/grade8.png new file mode 100644 index 0000000..910ab06 Binary files /dev/null and b/public/assets/images/coursesNews/older/grade8.png differ diff --git a/public/assets/images/coursesNews/older/grade9.png b/public/assets/images/coursesNews/older/grade9.png new file mode 100644 index 0000000..d19481f Binary files /dev/null and b/public/assets/images/coursesNews/older/grade9.png differ diff --git a/public/assets/images/coursesNews/parent_box.png b/public/assets/images/coursesNews/parent_box.png new file mode 100644 index 0000000..7c502f4 Binary files /dev/null and b/public/assets/images/coursesNews/parent_box.png differ diff --git a/public/assets/images/coursesNews/student_box.png b/public/assets/images/coursesNews/student_box.png new file mode 100644 index 0000000..2768a63 Binary files /dev/null and b/public/assets/images/coursesNews/student_box.png differ diff --git a/public/assets/images/coursesNews/table_convert.png b/public/assets/images/coursesNews/table_convert.png new file mode 100644 index 0000000..d5bdd3f Binary files /dev/null and b/public/assets/images/coursesNews/table_convert.png differ diff --git a/public/assets/images/coursesNews/table_convert_mobile.png b/public/assets/images/coursesNews/table_convert_mobile.png new file mode 100644 index 0000000..73df4e6 Binary files /dev/null and b/public/assets/images/coursesNews/table_convert_mobile.png differ diff --git a/public/assets/images/coursesNews/teacher_box.png b/public/assets/images/coursesNews/teacher_box.png new file mode 100644 index 0000000..109b4d3 Binary files /dev/null and b/public/assets/images/coursesNews/teacher_box.png differ diff --git a/public/assets/images/detail2.png b/public/assets/images/detail2.png new file mode 100644 index 0000000..454d584 Binary files /dev/null and b/public/assets/images/detail2.png differ diff --git a/public/assets/images/details.png b/public/assets/images/details.png new file mode 100644 index 0000000..a4c499b Binary files /dev/null and b/public/assets/images/details.png differ diff --git a/public/assets/images/empty_confirm_excercise.png b/public/assets/images/empty_confirm_excercise.png new file mode 100644 index 0000000..2a881f7 Binary files /dev/null and b/public/assets/images/empty_confirm_excercise.png differ diff --git a/public/assets/images/empty_excercise.png b/public/assets/images/empty_excercise.png new file mode 100644 index 0000000..20ec692 Binary files /dev/null and b/public/assets/images/empty_excercise.png differ diff --git a/public/assets/images/empty_leaderboard.png b/public/assets/images/empty_leaderboard.png new file mode 100644 index 0000000..fd472cc Binary files /dev/null and b/public/assets/images/empty_leaderboard.png differ diff --git a/public/assets/images/empty_messagebox.png b/public/assets/images/empty_messagebox.png new file mode 100644 index 0000000..94859b3 Binary files /dev/null and b/public/assets/images/empty_messagebox.png differ diff --git a/public/assets/images/entrance_body.png b/public/assets/images/entrance_body.png new file mode 100644 index 0000000..fb7a86f Binary files /dev/null and b/public/assets/images/entrance_body.png differ diff --git a/public/assets/images/entrance_header.png b/public/assets/images/entrance_header.png new file mode 100644 index 0000000..4cce8af Binary files /dev/null and b/public/assets/images/entrance_header.png differ diff --git a/public/assets/images/exam_empty.png b/public/assets/images/exam_empty.png new file mode 100644 index 0000000..eedaf3c Binary files /dev/null and b/public/assets/images/exam_empty.png differ diff --git a/public/assets/images/exam_history_empty.png b/public/assets/images/exam_history_empty.png new file mode 100644 index 0000000..4074633 Binary files /dev/null and b/public/assets/images/exam_history_empty.png differ diff --git a/public/assets/images/exam_not_found.png b/public/assets/images/exam_not_found.png new file mode 100644 index 0000000..abbb721 Binary files /dev/null and b/public/assets/images/exam_not_found.png differ diff --git a/public/assets/images/faqNews/feature_2_1.png b/public/assets/images/faqNews/feature_2_1.png new file mode 100644 index 0000000..ec82c85 Binary files /dev/null and b/public/assets/images/faqNews/feature_2_1.png differ diff --git a/public/assets/images/faqNews/feature_2_2.png b/public/assets/images/faqNews/feature_2_2.png new file mode 100644 index 0000000..4f8654f Binary files /dev/null and b/public/assets/images/faqNews/feature_2_2.png differ diff --git a/public/assets/images/faqNews/feature_2_3.png b/public/assets/images/faqNews/feature_2_3.png new file mode 100644 index 0000000..62fdd95 Binary files /dev/null and b/public/assets/images/faqNews/feature_2_3.png differ diff --git a/public/assets/images/faqNews/feature_2_4.png b/public/assets/images/faqNews/feature_2_4.png new file mode 100644 index 0000000..8f4cbcd Binary files /dev/null and b/public/assets/images/faqNews/feature_2_4.png differ diff --git a/public/assets/images/faqNews/feature_3_1.png b/public/assets/images/faqNews/feature_3_1.png new file mode 100644 index 0000000..0e7841b Binary files /dev/null and b/public/assets/images/faqNews/feature_3_1.png differ diff --git a/public/assets/images/faqNews/feature_3_2.png b/public/assets/images/faqNews/feature_3_2.png new file mode 100644 index 0000000..99315f1 Binary files /dev/null and b/public/assets/images/faqNews/feature_3_2.png differ diff --git a/public/assets/images/faqNews/feature_4_1.png b/public/assets/images/faqNews/feature_4_1.png new file mode 100644 index 0000000..66a19dd Binary files /dev/null and b/public/assets/images/faqNews/feature_4_1.png differ diff --git a/public/assets/images/faqNews/feature_4_2.png b/public/assets/images/faqNews/feature_4_2.png new file mode 100644 index 0000000..9e389ea Binary files /dev/null and b/public/assets/images/faqNews/feature_4_2.png differ diff --git a/public/assets/images/faqNews/feature_5_1.png b/public/assets/images/faqNews/feature_5_1.png new file mode 100644 index 0000000..b721e8c Binary files /dev/null and b/public/assets/images/faqNews/feature_5_1.png differ diff --git a/public/assets/images/faqNews/feature_5_2.png b/public/assets/images/faqNews/feature_5_2.png new file mode 100644 index 0000000..433a9fb Binary files /dev/null and b/public/assets/images/faqNews/feature_5_2.png differ diff --git a/public/assets/images/faqNews/feature_5_3.png b/public/assets/images/faqNews/feature_5_3.png new file mode 100644 index 0000000..929103e Binary files /dev/null and b/public/assets/images/faqNews/feature_5_3.png differ diff --git a/public/assets/images/faqNews/feature_5_4.png b/public/assets/images/faqNews/feature_5_4.png new file mode 100644 index 0000000..3ea75fd Binary files /dev/null and b/public/assets/images/faqNews/feature_5_4.png differ diff --git a/public/assets/images/faqNews/learning_1.png b/public/assets/images/faqNews/learning_1.png new file mode 100644 index 0000000..b5bb7a8 Binary files /dev/null and b/public/assets/images/faqNews/learning_1.png differ diff --git a/public/assets/images/faqNews/learning_2.png b/public/assets/images/faqNews/learning_2.png new file mode 100644 index 0000000..8198ae3 Binary files /dev/null and b/public/assets/images/faqNews/learning_2.png differ diff --git a/public/assets/images/faqNews/learning_2_1.png b/public/assets/images/faqNews/learning_2_1.png new file mode 100644 index 0000000..648aea5 Binary files /dev/null and b/public/assets/images/faqNews/learning_2_1.png differ diff --git a/public/assets/images/faqNews/learning_3_1.png b/public/assets/images/faqNews/learning_3_1.png new file mode 100644 index 0000000..2e5a3e4 Binary files /dev/null and b/public/assets/images/faqNews/learning_3_1.png differ diff --git a/public/assets/images/faqNews/learning_3_2.png b/public/assets/images/faqNews/learning_3_2.png new file mode 100644 index 0000000..545514a Binary files /dev/null and b/public/assets/images/faqNews/learning_3_2.png differ diff --git a/public/assets/images/faqNews/slide.png b/public/assets/images/faqNews/slide.png new file mode 100644 index 0000000..2c75d7a Binary files /dev/null and b/public/assets/images/faqNews/slide.png differ diff --git a/public/assets/images/faqNews/slide_mobile.png b/public/assets/images/faqNews/slide_mobile.png new file mode 100644 index 0000000..2a7367d Binary files /dev/null and b/public/assets/images/faqNews/slide_mobile.png differ diff --git a/public/assets/images/feeNews/bg_content.png b/public/assets/images/feeNews/bg_content.png new file mode 100644 index 0000000..c382c1c Binary files /dev/null and b/public/assets/images/feeNews/bg_content.png differ diff --git a/public/assets/images/feeNews/bg_diamond.png b/public/assets/images/feeNews/bg_diamond.png new file mode 100644 index 0000000..8e88c02 Binary files /dev/null and b/public/assets/images/feeNews/bg_diamond.png differ diff --git a/public/assets/images/feeNews/ico_payment.png b/public/assets/images/feeNews/ico_payment.png new file mode 100644 index 0000000..99b988d Binary files /dev/null and b/public/assets/images/feeNews/ico_payment.png differ diff --git a/public/assets/images/feeNews/slider_bg.png b/public/assets/images/feeNews/slider_bg.png new file mode 100644 index 0000000..4fbd770 Binary files /dev/null and b/public/assets/images/feeNews/slider_bg.png differ diff --git a/public/assets/images/feeNews/slider_bg_mobile.png b/public/assets/images/feeNews/slider_bg_mobile.png new file mode 100644 index 0000000..4767994 Binary files /dev/null and b/public/assets/images/feeNews/slider_bg_mobile.png differ diff --git a/public/assets/images/giaotrinh/avt_default_unit.png b/public/assets/images/giaotrinh/avt_default_unit.png new file mode 100644 index 0000000..67522cd Binary files /dev/null and b/public/assets/images/giaotrinh/avt_default_unit.png differ diff --git a/public/assets/images/giaotrinh/bg_gt.png b/public/assets/images/giaotrinh/bg_gt.png new file mode 100644 index 0000000..6747640 Binary files /dev/null and b/public/assets/images/giaotrinh/bg_gt.png differ diff --git a/public/assets/images/giaotrinh/bg_unit.png b/public/assets/images/giaotrinh/bg_unit.png new file mode 100644 index 0000000..e4813f7 Binary files /dev/null and b/public/assets/images/giaotrinh/bg_unit.png differ diff --git a/public/assets/images/giaotrinh/detais.png b/public/assets/images/giaotrinh/detais.png new file mode 100644 index 0000000..b8f0029 Binary files /dev/null and b/public/assets/images/giaotrinh/detais.png differ diff --git a/public/assets/images/giaotrinh/grammar.png b/public/assets/images/giaotrinh/grammar.png new file mode 100644 index 0000000..d1222c5 Binary files /dev/null and b/public/assets/images/giaotrinh/grammar.png differ diff --git a/public/assets/images/giaotrinh/ico_Aa.png b/public/assets/images/giaotrinh/ico_Aa.png new file mode 100644 index 0000000..bfb2749 Binary files /dev/null and b/public/assets/images/giaotrinh/ico_Aa.png differ diff --git a/public/assets/images/giaotrinh/ico_add_black.png b/public/assets/images/giaotrinh/ico_add_black.png new file mode 100644 index 0000000..07ab9fe Binary files /dev/null and b/public/assets/images/giaotrinh/ico_add_black.png differ diff --git a/public/assets/images/giaotrinh/ico_bar.png b/public/assets/images/giaotrinh/ico_bar.png new file mode 100644 index 0000000..67017fd Binary files /dev/null and b/public/assets/images/giaotrinh/ico_bar.png differ diff --git a/public/assets/images/giaotrinh/ico_bar_grid.png b/public/assets/images/giaotrinh/ico_bar_grid.png new file mode 100644 index 0000000..2c73b99 Binary files /dev/null and b/public/assets/images/giaotrinh/ico_bar_grid.png differ diff --git a/public/assets/images/giaotrinh/ico_book.png b/public/assets/images/giaotrinh/ico_book.png new file mode 100644 index 0000000..91411ff Binary files /dev/null and b/public/assets/images/giaotrinh/ico_book.png differ diff --git a/public/assets/images/giaotrinh/ico_book_blue.png b/public/assets/images/giaotrinh/ico_book_blue.png new file mode 100644 index 0000000..c44cfbe Binary files /dev/null and b/public/assets/images/giaotrinh/ico_book_blue.png differ diff --git a/public/assets/images/giaotrinh/ico_gt.png b/public/assets/images/giaotrinh/ico_gt.png new file mode 100644 index 0000000..4d52c3f Binary files /dev/null and b/public/assets/images/giaotrinh/ico_gt.png differ diff --git a/public/assets/images/giaotrinh/ico_gt_hs.png b/public/assets/images/giaotrinh/ico_gt_hs.png new file mode 100644 index 0000000..c4cef21 Binary files /dev/null and b/public/assets/images/giaotrinh/ico_gt_hs.png differ diff --git a/public/assets/images/giaotrinh/ico_gt_sun.png b/public/assets/images/giaotrinh/ico_gt_sun.png new file mode 100644 index 0000000..82711c5 Binary files /dev/null and b/public/assets/images/giaotrinh/ico_gt_sun.png differ diff --git a/public/assets/images/giaotrinh/ico_heart.png b/public/assets/images/giaotrinh/ico_heart.png new file mode 100644 index 0000000..835c73f Binary files /dev/null and b/public/assets/images/giaotrinh/ico_heart.png differ diff --git a/public/assets/images/giaotrinh/ico_lock_b.png b/public/assets/images/giaotrinh/ico_lock_b.png new file mode 100644 index 0000000..e0e709a Binary files /dev/null and b/public/assets/images/giaotrinh/ico_lock_b.png differ diff --git a/public/assets/images/giaotrinh/ico_lock_r.png b/public/assets/images/giaotrinh/ico_lock_r.png new file mode 100644 index 0000000..dcb8d05 Binary files /dev/null and b/public/assets/images/giaotrinh/ico_lock_r.png differ diff --git a/public/assets/images/giaotrinh/ico_mes.png b/public/assets/images/giaotrinh/ico_mes.png new file mode 100644 index 0000000..8b3fd6c Binary files /dev/null and b/public/assets/images/giaotrinh/ico_mes.png differ diff --git a/public/assets/images/giaotrinh/ico_note.png b/public/assets/images/giaotrinh/ico_note.png new file mode 100644 index 0000000..a153eee Binary files /dev/null and b/public/assets/images/giaotrinh/ico_note.png differ diff --git a/public/assets/images/giaotrinh/ico_show_.png b/public/assets/images/giaotrinh/ico_show_.png new file mode 100644 index 0000000..3f836c6 Binary files /dev/null and b/public/assets/images/giaotrinh/ico_show_.png differ diff --git a/public/assets/images/giaotrinh/ico_unit.png b/public/assets/images/giaotrinh/ico_unit.png new file mode 100644 index 0000000..c2fd5c2 Binary files /dev/null and b/public/assets/images/giaotrinh/ico_unit.png differ diff --git a/public/assets/images/giaotrinh/icon_check.png b/public/assets/images/giaotrinh/icon_check.png new file mode 100644 index 0000000..5b33f24 Binary files /dev/null and b/public/assets/images/giaotrinh/icon_check.png differ diff --git a/public/assets/images/giaotrinh/icon_check_active.png b/public/assets/images/giaotrinh/icon_check_active.png new file mode 100644 index 0000000..8794144 Binary files /dev/null and b/public/assets/images/giaotrinh/icon_check_active.png differ diff --git a/public/assets/images/giaotrinh/icon_close.png b/public/assets/images/giaotrinh/icon_close.png new file mode 100644 index 0000000..065372f Binary files /dev/null and b/public/assets/images/giaotrinh/icon_close.png differ diff --git a/public/assets/images/giaotrinh/icon_close_active.png b/public/assets/images/giaotrinh/icon_close_active.png new file mode 100644 index 0000000..cc12c77 Binary files /dev/null and b/public/assets/images/giaotrinh/icon_close_active.png differ diff --git a/public/assets/images/giaotrinh/icon_empty_complete.png b/public/assets/images/giaotrinh/icon_empty_complete.png new file mode 100644 index 0000000..bd2f95c Binary files /dev/null and b/public/assets/images/giaotrinh/icon_empty_complete.png differ diff --git a/public/assets/images/giaotrinh/icon_empty_incomplete.png b/public/assets/images/giaotrinh/icon_empty_incomplete.png new file mode 100644 index 0000000..f7790be Binary files /dev/null and b/public/assets/images/giaotrinh/icon_empty_incomplete.png differ diff --git a/public/assets/images/giaotrinh/listening.png b/public/assets/images/giaotrinh/listening.png new file mode 100644 index 0000000..c1aa073 Binary files /dev/null and b/public/assets/images/giaotrinh/listening.png differ diff --git a/public/assets/images/giaotrinh/listenning.png b/public/assets/images/giaotrinh/listenning.png new file mode 100644 index 0000000..cd9bb5c Binary files /dev/null and b/public/assets/images/giaotrinh/listenning.png differ diff --git a/public/assets/images/giaotrinh/mini_test.png b/public/assets/images/giaotrinh/mini_test.png new file mode 100644 index 0000000..7c21853 Binary files /dev/null and b/public/assets/images/giaotrinh/mini_test.png differ diff --git a/public/assets/images/giaotrinh/project.png b/public/assets/images/giaotrinh/project.png new file mode 100644 index 0000000..bb16a83 Binary files /dev/null and b/public/assets/images/giaotrinh/project.png differ diff --git a/public/assets/images/giaotrinh/pronunciation.png b/public/assets/images/giaotrinh/pronunciation.png new file mode 100644 index 0000000..cd68073 Binary files /dev/null and b/public/assets/images/giaotrinh/pronunciation.png differ diff --git a/public/assets/images/giaotrinh/reading.png b/public/assets/images/giaotrinh/reading.png new file mode 100644 index 0000000..ee006b3 Binary files /dev/null and b/public/assets/images/giaotrinh/reading.png differ diff --git a/public/assets/images/giaotrinh/speaking.png b/public/assets/images/giaotrinh/speaking.png new file mode 100644 index 0000000..28aaf54 Binary files /dev/null and b/public/assets/images/giaotrinh/speaking.png differ diff --git a/public/assets/images/giaotrinh/vocabulary.png b/public/assets/images/giaotrinh/vocabulary.png new file mode 100644 index 0000000..bf72e6d Binary files /dev/null and b/public/assets/images/giaotrinh/vocabulary.png differ diff --git a/public/assets/images/giaotrinh/vocabulary_.png b/public/assets/images/giaotrinh/vocabulary_.png new file mode 100644 index 0000000..bfb2749 Binary files /dev/null and b/public/assets/images/giaotrinh/vocabulary_.png differ diff --git a/public/assets/images/giaotrinh/writing.png b/public/assets/images/giaotrinh/writing.png new file mode 100644 index 0000000..50a6476 Binary files /dev/null and b/public/assets/images/giaotrinh/writing.png differ diff --git a/public/assets/images/homeNews/content/banner_1.png b/public/assets/images/homeNews/content/banner_1.png new file mode 100644 index 0000000..2f27500 Binary files /dev/null and b/public/assets/images/homeNews/content/banner_1.png differ diff --git a/public/assets/images/homeNews/content/banner_1_mobile.png b/public/assets/images/homeNews/content/banner_1_mobile.png new file mode 100644 index 0000000..43929ec Binary files /dev/null and b/public/assets/images/homeNews/content/banner_1_mobile.png differ diff --git a/public/assets/images/homeNews/content/banner_2.png b/public/assets/images/homeNews/content/banner_2.png new file mode 100644 index 0000000..945fbfd Binary files /dev/null and b/public/assets/images/homeNews/content/banner_2.png differ diff --git a/public/assets/images/homeNews/content/banner_2_mobile.png b/public/assets/images/homeNews/content/banner_2_mobile.png new file mode 100644 index 0000000..d7a1c3f Binary files /dev/null and b/public/assets/images/homeNews/content/banner_2_mobile.png differ diff --git a/public/assets/images/homeNews/content/banner_3.png b/public/assets/images/homeNews/content/banner_3.png new file mode 100644 index 0000000..64739a7 Binary files /dev/null and b/public/assets/images/homeNews/content/banner_3.png differ diff --git a/public/assets/images/homeNews/content/banner_4.png b/public/assets/images/homeNews/content/banner_4.png new file mode 100644 index 0000000..03914f7 Binary files /dev/null and b/public/assets/images/homeNews/content/banner_4.png differ diff --git a/public/assets/images/homeNews/content/banner_advisement.png b/public/assets/images/homeNews/content/banner_advisement.png new file mode 100644 index 0000000..d7e17d0 Binary files /dev/null and b/public/assets/images/homeNews/content/banner_advisement.png differ diff --git a/public/assets/images/homeNews/content/bg_1.png b/public/assets/images/homeNews/content/bg_1.png new file mode 100644 index 0000000..578168d Binary files /dev/null and b/public/assets/images/homeNews/content/bg_1.png differ diff --git a/public/assets/images/homeNews/content/bg_advisement.png b/public/assets/images/homeNews/content/bg_advisement.png new file mode 100644 index 0000000..0bd6dc3 Binary files /dev/null and b/public/assets/images/homeNews/content/bg_advisement.png differ diff --git a/public/assets/images/homeNews/content/bg_advisement_mobile.png b/public/assets/images/homeNews/content/bg_advisement_mobile.png new file mode 100644 index 0000000..2a5cb7a Binary files /dev/null and b/public/assets/images/homeNews/content/bg_advisement_mobile.png differ diff --git a/public/assets/images/homeNews/content/bg_banner.png b/public/assets/images/homeNews/content/bg_banner.png new file mode 100644 index 0000000..8559798 Binary files /dev/null and b/public/assets/images/homeNews/content/bg_banner.png differ diff --git a/public/assets/images/homeNews/content/bg_banner_mobile.png b/public/assets/images/homeNews/content/bg_banner_mobile.png new file mode 100644 index 0000000..6001758 Binary files /dev/null and b/public/assets/images/homeNews/content/bg_banner_mobile.png differ diff --git a/public/assets/images/homeNews/content/bg_banner_teacher.png b/public/assets/images/homeNews/content/bg_banner_teacher.png new file mode 100644 index 0000000..1bb05f6 Binary files /dev/null and b/public/assets/images/homeNews/content/bg_banner_teacher.png differ diff --git a/public/assets/images/homeNews/content/bg_banner_top.png b/public/assets/images/homeNews/content/bg_banner_top.png new file mode 100644 index 0000000..6971f4c Binary files /dev/null and b/public/assets/images/homeNews/content/bg_banner_top.png differ diff --git a/public/assets/images/homeNews/content/bg_border_student.png b/public/assets/images/homeNews/content/bg_border_student.png new file mode 100644 index 0000000..5e34c94 Binary files /dev/null and b/public/assets/images/homeNews/content/bg_border_student.png differ diff --git a/public/assets/images/homeNews/content/bg_border_student_mobile.png b/public/assets/images/homeNews/content/bg_border_student_mobile.png new file mode 100644 index 0000000..9618b3f Binary files /dev/null and b/public/assets/images/homeNews/content/bg_border_student_mobile.png differ diff --git a/public/assets/images/homeNews/content/bg_text_parent.png b/public/assets/images/homeNews/content/bg_text_parent.png new file mode 100644 index 0000000..ac41a29 Binary files /dev/null and b/public/assets/images/homeNews/content/bg_text_parent.png differ diff --git a/public/assets/images/homeNews/content/bg_text_parent_1.png b/public/assets/images/homeNews/content/bg_text_parent_1.png new file mode 100644 index 0000000..a8b0c9d Binary files /dev/null and b/public/assets/images/homeNews/content/bg_text_parent_1.png differ diff --git a/public/assets/images/homeNews/content/icon/ico_bonus_center.png b/public/assets/images/homeNews/content/icon/ico_bonus_center.png new file mode 100644 index 0000000..6d5fb32 Binary files /dev/null and b/public/assets/images/homeNews/content/icon/ico_bonus_center.png differ diff --git a/public/assets/images/homeNews/content/icon/ico_dots_teacher.png b/public/assets/images/homeNews/content/icon/ico_dots_teacher.png new file mode 100644 index 0000000..bbc1181 Binary files /dev/null and b/public/assets/images/homeNews/content/icon/ico_dots_teacher.png differ diff --git a/public/assets/images/homeNews/content/icon/ico_half_circle.png b/public/assets/images/homeNews/content/icon/ico_half_circle.png new file mode 100644 index 0000000..0cdf296 Binary files /dev/null and b/public/assets/images/homeNews/content/icon/ico_half_circle.png differ diff --git a/public/assets/images/homeNews/content/icon/ico_half_circle_yellow.png b/public/assets/images/homeNews/content/icon/ico_half_circle_yellow.png new file mode 100644 index 0000000..495b632 Binary files /dev/null and b/public/assets/images/homeNews/content/icon/ico_half_circle_yellow.png differ diff --git a/public/assets/images/homeNews/content/icon/ico_left_teacher.png b/public/assets/images/homeNews/content/icon/ico_left_teacher.png new file mode 100644 index 0000000..74713a0 Binary files /dev/null and b/public/assets/images/homeNews/content/icon/ico_left_teacher.png differ diff --git a/public/assets/images/homeNews/content/icon/ico_left_trial.png b/public/assets/images/homeNews/content/icon/ico_left_trial.png new file mode 100644 index 0000000..817fb6a Binary files /dev/null and b/public/assets/images/homeNews/content/icon/ico_left_trial.png differ diff --git a/public/assets/images/homeNews/content/icon/ico_right_teacher.png b/public/assets/images/homeNews/content/icon/ico_right_teacher.png new file mode 100644 index 0000000..816e3e4 Binary files /dev/null and b/public/assets/images/homeNews/content/icon/ico_right_teacher.png differ diff --git a/public/assets/images/homeNews/content/icon/ico_right_trial.png b/public/assets/images/homeNews/content/icon/ico_right_trial.png new file mode 100644 index 0000000..24553e6 Binary files /dev/null and b/public/assets/images/homeNews/content/icon/ico_right_trial.png differ diff --git a/public/assets/images/homeNews/content/icon/ico_text_left.png b/public/assets/images/homeNews/content/icon/ico_text_left.png new file mode 100644 index 0000000..0da4e84 Binary files /dev/null and b/public/assets/images/homeNews/content/icon/ico_text_left.png differ diff --git a/public/assets/images/homeNews/content/icon/ico_text_right.png b/public/assets/images/homeNews/content/icon/ico_text_right.png new file mode 100644 index 0000000..8982f73 Binary files /dev/null and b/public/assets/images/homeNews/content/icon/ico_text_right.png differ diff --git a/public/assets/images/homeNews/content/icon/ico_top_teacher.png b/public/assets/images/homeNews/content/icon/ico_top_teacher.png new file mode 100644 index 0000000..ae9e997 Binary files /dev/null and b/public/assets/images/homeNews/content/icon/ico_top_teacher.png differ diff --git a/public/assets/images/homeNews/content/img_advisement_side.png b/public/assets/images/homeNews/content/img_advisement_side.png new file mode 100644 index 0000000..301fd2f Binary files /dev/null and b/public/assets/images/homeNews/content/img_advisement_side.png differ diff --git a/public/assets/images/homeNews/content/img_bn_top.png b/public/assets/images/homeNews/content/img_bn_top.png new file mode 100644 index 0000000..9fa60b9 Binary files /dev/null and b/public/assets/images/homeNews/content/img_bn_top.png differ diff --git a/public/assets/images/homeNews/content/img_detail_student_mobile.png b/public/assets/images/homeNews/content/img_detail_student_mobile.png new file mode 100644 index 0000000..f300828 Binary files /dev/null and b/public/assets/images/homeNews/content/img_detail_student_mobile.png differ diff --git a/public/assets/images/homeNews/content/parent/box_trial_parent.png b/public/assets/images/homeNews/content/parent/box_trial_parent.png new file mode 100644 index 0000000..ccc65e6 Binary files /dev/null and b/public/assets/images/homeNews/content/parent/box_trial_parent.png differ diff --git a/public/assets/images/homeNews/content/parent/ico_left_mobile.png b/public/assets/images/homeNews/content/parent/ico_left_mobile.png new file mode 100644 index 0000000..49429ed Binary files /dev/null and b/public/assets/images/homeNews/content/parent/ico_left_mobile.png differ diff --git a/public/assets/images/homeNews/content/parent/ico_left_parent.png b/public/assets/images/homeNews/content/parent/ico_left_parent.png new file mode 100644 index 0000000..3fa3ca7 Binary files /dev/null and b/public/assets/images/homeNews/content/parent/ico_left_parent.png differ diff --git a/public/assets/images/homeNews/content/parent/ico_right_mobile.png b/public/assets/images/homeNews/content/parent/ico_right_mobile.png new file mode 100644 index 0000000..3137ee3 Binary files /dev/null and b/public/assets/images/homeNews/content/parent/ico_right_mobile.png differ diff --git a/public/assets/images/homeNews/content/parent/ico_right_parent.png b/public/assets/images/homeNews/content/parent/ico_right_parent.png new file mode 100644 index 0000000..31902fc Binary files /dev/null and b/public/assets/images/homeNews/content/parent/ico_right_parent.png differ diff --git a/public/assets/images/homeNews/content/parent/ico_right_slider.png b/public/assets/images/homeNews/content/parent/ico_right_slider.png new file mode 100644 index 0000000..97c1d79 Binary files /dev/null and b/public/assets/images/homeNews/content/parent/ico_right_slider.png differ diff --git a/public/assets/images/homeNews/content/parent/ico_slider_right.png b/public/assets/images/homeNews/content/parent/ico_slider_right.png new file mode 100644 index 0000000..a8999c9 Binary files /dev/null and b/public/assets/images/homeNews/content/parent/ico_slider_right.png differ diff --git a/public/assets/images/homeNews/content/parent/ico_slider_right_mobile.png b/public/assets/images/homeNews/content/parent/ico_slider_right_mobile.png new file mode 100644 index 0000000..6f0c35d Binary files /dev/null and b/public/assets/images/homeNews/content/parent/ico_slider_right_mobile.png differ diff --git a/public/assets/images/homeNews/content/parent/item_1.png b/public/assets/images/homeNews/content/parent/item_1.png new file mode 100644 index 0000000..e5b0d64 Binary files /dev/null and b/public/assets/images/homeNews/content/parent/item_1.png differ diff --git a/public/assets/images/homeNews/content/parent/item_2.png b/public/assets/images/homeNews/content/parent/item_2.png new file mode 100644 index 0000000..a17e384 Binary files /dev/null and b/public/assets/images/homeNews/content/parent/item_2.png differ diff --git a/public/assets/images/homeNews/content/parent/item_3.png b/public/assets/images/homeNews/content/parent/item_3.png new file mode 100644 index 0000000..93b9abb Binary files /dev/null and b/public/assets/images/homeNews/content/parent/item_3.png differ diff --git a/public/assets/images/homeNews/content/parent/item_4.png b/public/assets/images/homeNews/content/parent/item_4.png new file mode 100644 index 0000000..dc0e007 Binary files /dev/null and b/public/assets/images/homeNews/content/parent/item_4.png differ diff --git a/public/assets/images/homeNews/content/parent/item_5.png b/public/assets/images/homeNews/content/parent/item_5.png new file mode 100644 index 0000000..8a78cf4 Binary files /dev/null and b/public/assets/images/homeNews/content/parent/item_5.png differ diff --git a/public/assets/images/homeNews/content/parent/item_6.png b/public/assets/images/homeNews/content/parent/item_6.png new file mode 100644 index 0000000..1046f71 Binary files /dev/null and b/public/assets/images/homeNews/content/parent/item_6.png differ diff --git a/public/assets/images/homeNews/content/parent/item_7.png b/public/assets/images/homeNews/content/parent/item_7.png new file mode 100644 index 0000000..799cc14 Binary files /dev/null and b/public/assets/images/homeNews/content/parent/item_7.png differ diff --git a/public/assets/images/homeNews/content/phone_slide.png b/public/assets/images/homeNews/content/phone_slide.png new file mode 100644 index 0000000..2260903 Binary files /dev/null and b/public/assets/images/homeNews/content/phone_slide.png differ diff --git a/public/assets/images/homeNews/content/slogan_1.png b/public/assets/images/homeNews/content/slogan_1.png new file mode 100644 index 0000000..7772c2c Binary files /dev/null and b/public/assets/images/homeNews/content/slogan_1.png differ diff --git a/public/assets/images/homeNews/content/slogan_1_infor.png b/public/assets/images/homeNews/content/slogan_1_infor.png new file mode 100644 index 0000000..030672e Binary files /dev/null and b/public/assets/images/homeNews/content/slogan_1_infor.png differ diff --git a/public/assets/images/homeNews/content/slogan_1_mobile.png b/public/assets/images/homeNews/content/slogan_1_mobile.png new file mode 100644 index 0000000..49d4a66 Binary files /dev/null and b/public/assets/images/homeNews/content/slogan_1_mobile.png differ diff --git a/public/assets/images/homeNews/content/slogan_teacher.png b/public/assets/images/homeNews/content/slogan_teacher.png new file mode 100644 index 0000000..7f02af8 Binary files /dev/null and b/public/assets/images/homeNews/content/slogan_teacher.png differ diff --git a/public/assets/images/homeNews/content/slogan_teacher_mobile.png b/public/assets/images/homeNews/content/slogan_teacher_mobile.png new file mode 100644 index 0000000..e60f3b8 Binary files /dev/null and b/public/assets/images/homeNews/content/slogan_teacher_mobile.png differ diff --git a/public/assets/images/homeNews/content/student/banner_1.png b/public/assets/images/homeNews/content/student/banner_1.png new file mode 100644 index 0000000..aec2898 Binary files /dev/null and b/public/assets/images/homeNews/content/student/banner_1.png differ diff --git a/public/assets/images/homeNews/content/student/banner_2.png b/public/assets/images/homeNews/content/student/banner_2.png new file mode 100644 index 0000000..65a0881 Binary files /dev/null and b/public/assets/images/homeNews/content/student/banner_2.png differ diff --git a/public/assets/images/homeNews/content/student/bg_student.png b/public/assets/images/homeNews/content/student/bg_student.png new file mode 100644 index 0000000..79e9a6b Binary files /dev/null and b/public/assets/images/homeNews/content/student/bg_student.png differ diff --git a/public/assets/images/homeNews/content/student/box_trial.png b/public/assets/images/homeNews/content/student/box_trial.png new file mode 100644 index 0000000..19f25d4 Binary files /dev/null and b/public/assets/images/homeNews/content/student/box_trial.png differ diff --git a/public/assets/images/homeNews/content/student/ico_left_student.png b/public/assets/images/homeNews/content/student/ico_left_student.png new file mode 100644 index 0000000..5f63842 Binary files /dev/null and b/public/assets/images/homeNews/content/student/ico_left_student.png differ diff --git a/public/assets/images/homeNews/content/student/ico_right_student.png b/public/assets/images/homeNews/content/student/ico_right_student.png new file mode 100644 index 0000000..f9e7f95 Binary files /dev/null and b/public/assets/images/homeNews/content/student/ico_right_student.png differ diff --git a/public/assets/images/homeNews/content/teacher/bg_advisement_teacher.png b/public/assets/images/homeNews/content/teacher/bg_advisement_teacher.png new file mode 100644 index 0000000..f631797 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/bg_advisement_teacher.png differ diff --git a/public/assets/images/homeNews/content/teacher/bg_advisement_teacher_mobile.png b/public/assets/images/homeNews/content/teacher/bg_advisement_teacher_mobile.png new file mode 100644 index 0000000..370afb5 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/bg_advisement_teacher_mobile.png differ diff --git a/public/assets/images/homeNews/content/teacher/bg_teacher.png b/public/assets/images/homeNews/content/teacher/bg_teacher.png new file mode 100644 index 0000000..56b972d Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/bg_teacher.png differ diff --git a/public/assets/images/homeNews/content/teacher/box_trial_teacher.png b/public/assets/images/homeNews/content/teacher/box_trial_teacher.png new file mode 100644 index 0000000..1e2cdf5 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/box_trial_teacher.png differ diff --git a/public/assets/images/homeNews/content/teacher/ico_left_teacher.png b/public/assets/images/homeNews/content/teacher/ico_left_teacher.png new file mode 100644 index 0000000..b0347ae Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/ico_left_teacher.png differ diff --git a/public/assets/images/homeNews/content/teacher/ico_right_teacher.png b/public/assets/images/homeNews/content/teacher/ico_right_teacher.png new file mode 100644 index 0000000..27575df Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/ico_right_teacher.png differ diff --git a/public/assets/images/homeNews/content/teacher/ico_side_assistant.png b/public/assets/images/homeNews/content/teacher/ico_side_assistant.png new file mode 100644 index 0000000..d550785 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/ico_side_assistant.png differ diff --git a/public/assets/images/homeNews/content/teacher/img_bg_circle.png b/public/assets/images/homeNews/content/teacher/img_bg_circle.png new file mode 100644 index 0000000..e3e949e Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/img_bg_circle.png differ diff --git a/public/assets/images/homeNews/content/teacher/img_bg_sliding_center.png b/public/assets/images/homeNews/content/teacher/img_bg_sliding_center.png new file mode 100644 index 0000000..0b39cfc Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/img_bg_sliding_center.png differ diff --git a/public/assets/images/homeNews/content/teacher/img_bg_sliding_left.png b/public/assets/images/homeNews/content/teacher/img_bg_sliding_left.png new file mode 100644 index 0000000..0ed5193 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/img_bg_sliding_left.png differ diff --git a/public/assets/images/homeNews/content/teacher/img_bg_sliding_mobile.png b/public/assets/images/homeNews/content/teacher/img_bg_sliding_mobile.png new file mode 100644 index 0000000..4f6bc00 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/img_bg_sliding_mobile.png differ diff --git a/public/assets/images/homeNews/content/teacher/img_detail_assistant.png b/public/assets/images/homeNews/content/teacher/img_detail_assistant.png new file mode 100644 index 0000000..42f01c0 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/img_detail_assistant.png differ diff --git a/public/assets/images/homeNews/content/teacher/img_detail_assistant_mobile.png b/public/assets/images/homeNews/content/teacher/img_detail_assistant_mobile.png new file mode 100644 index 0000000..1c3bdb4 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/img_detail_assistant_mobile.png differ diff --git a/public/assets/images/homeNews/content/teacher/item_1.png b/public/assets/images/homeNews/content/teacher/item_1.png new file mode 100644 index 0000000..00b2a4a Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/item_1.png differ diff --git a/public/assets/images/homeNews/content/teacher/item_2.png b/public/assets/images/homeNews/content/teacher/item_2.png new file mode 100644 index 0000000..ecde428 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/item_2.png differ diff --git a/public/assets/images/homeNews/content/teacher/item_3.png b/public/assets/images/homeNews/content/teacher/item_3.png new file mode 100644 index 0000000..1475ef7 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/item_3.png differ diff --git a/public/assets/images/homeNews/content/teacher/item_4.png b/public/assets/images/homeNews/content/teacher/item_4.png new file mode 100644 index 0000000..79e332b Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/item_4.png differ diff --git a/public/assets/images/homeNews/content/teacher/item_5.png b/public/assets/images/homeNews/content/teacher/item_5.png new file mode 100644 index 0000000..adbb45f Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/item_5.png differ diff --git a/public/assets/images/homeNews/content/teacher/item_6.png b/public/assets/images/homeNews/content/teacher/item_6.png new file mode 100644 index 0000000..4fcb3f4 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/item_6.png differ diff --git a/public/assets/images/homeNews/content/teacher/list_benefits_teacher.png b/public/assets/images/homeNews/content/teacher/list_benefits_teacher.png new file mode 100644 index 0000000..67591e6 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/list_benefits_teacher.png differ diff --git a/public/assets/images/homeNews/content/teacher/list_benefits_teacher_mobile.png b/public/assets/images/homeNews/content/teacher/list_benefits_teacher_mobile.png new file mode 100644 index 0000000..d85093b Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/list_benefits_teacher_mobile.png differ diff --git a/public/assets/images/homeNews/content/teacher/title_advisement_teacher.png b/public/assets/images/homeNews/content/teacher/title_advisement_teacher.png new file mode 100644 index 0000000..e3bf70b Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/title_advisement_teacher.png differ diff --git a/public/assets/images/homeNews/content/teacher/title_advisement_teacher_1_mobile.png b/public/assets/images/homeNews/content/teacher/title_advisement_teacher_1_mobile.png new file mode 100644 index 0000000..1d28d79 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/title_advisement_teacher_1_mobile.png differ diff --git a/public/assets/images/homeNews/content/teacher/title_advisement_teacher_2_mobile.png b/public/assets/images/homeNews/content/teacher/title_advisement_teacher_2_mobile.png new file mode 100644 index 0000000..bce3814 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/title_advisement_teacher_2_mobile.png differ diff --git a/public/assets/images/homeNews/content/teacher/title_advisement_teacher_trial.png b/public/assets/images/homeNews/content/teacher/title_advisement_teacher_trial.png new file mode 100644 index 0000000..b5efff4 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/title_advisement_teacher_trial.png differ diff --git a/public/assets/images/homeNews/content/teacher/title_header_trial_mobile.png b/public/assets/images/homeNews/content/teacher/title_header_trial_mobile.png new file mode 100644 index 0000000..1bea886 Binary files /dev/null and b/public/assets/images/homeNews/content/teacher/title_header_trial_mobile.png differ diff --git a/public/assets/images/homeNews/content/title_advisement.png b/public/assets/images/homeNews/content/title_advisement.png new file mode 100644 index 0000000..ffa395d Binary files /dev/null and b/public/assets/images/homeNews/content/title_advisement.png differ diff --git a/public/assets/images/homeNews/content/title_header_1_mobile.png b/public/assets/images/homeNews/content/title_header_1_mobile.png new file mode 100644 index 0000000..7dc088e Binary files /dev/null and b/public/assets/images/homeNews/content/title_header_1_mobile.png differ diff --git a/public/assets/images/homeNews/content/title_header_2_mobile.png b/public/assets/images/homeNews/content/title_header_2_mobile.png new file mode 100644 index 0000000..75b1c6c Binary files /dev/null and b/public/assets/images/homeNews/content/title_header_2_mobile.png differ diff --git a/public/assets/images/homeNews/content/title_header_trial_mobile.png b/public/assets/images/homeNews/content/title_header_trial_mobile.png new file mode 100644 index 0000000..1bea886 Binary files /dev/null and b/public/assets/images/homeNews/content/title_header_trial_mobile.png differ diff --git a/public/assets/images/homeNews/downloadPage/img_side_parent.png b/public/assets/images/homeNews/downloadPage/img_side_parent.png new file mode 100644 index 0000000..c60d389 Binary files /dev/null and b/public/assets/images/homeNews/downloadPage/img_side_parent.png differ diff --git a/public/assets/images/homeNews/downloadPage/img_side_student.png b/public/assets/images/homeNews/downloadPage/img_side_student.png new file mode 100644 index 0000000..05fafd1 Binary files /dev/null and b/public/assets/images/homeNews/downloadPage/img_side_student.png differ diff --git a/public/assets/images/homeNews/downloadPage/img_side_teacher.png b/public/assets/images/homeNews/downloadPage/img_side_teacher.png new file mode 100644 index 0000000..c60d389 Binary files /dev/null and b/public/assets/images/homeNews/downloadPage/img_side_teacher.png differ diff --git a/public/assets/images/homeNews/downloadPage/slider_parent.png b/public/assets/images/homeNews/downloadPage/slider_parent.png new file mode 100644 index 0000000..42ce8af Binary files /dev/null and b/public/assets/images/homeNews/downloadPage/slider_parent.png differ diff --git a/public/assets/images/homeNews/downloadPage/slider_student.png b/public/assets/images/homeNews/downloadPage/slider_student.png new file mode 100644 index 0000000..44f7205 Binary files /dev/null and b/public/assets/images/homeNews/downloadPage/slider_student.png differ diff --git a/public/assets/images/homeNews/downloadPage/slider_teacher.png b/public/assets/images/homeNews/downloadPage/slider_teacher.png new file mode 100644 index 0000000..568c800 Binary files /dev/null and b/public/assets/images/homeNews/downloadPage/slider_teacher.png differ diff --git a/public/assets/images/homeNews/icon/ico_appstore.png b/public/assets/images/homeNews/icon/ico_appstore.png new file mode 100644 index 0000000..b075240 Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_appstore.png differ diff --git a/public/assets/images/homeNews/icon/ico_box_chat.png b/public/assets/images/homeNews/icon/ico_box_chat.png new file mode 100644 index 0000000..d995472 Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_box_chat.png differ diff --git a/public/assets/images/homeNews/icon/ico_fb.png b/public/assets/images/homeNews/icon/ico_fb.png new file mode 100644 index 0000000..05de3ec Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_fb.png differ diff --git a/public/assets/images/homeNews/icon/ico_ggplay.png b/public/assets/images/homeNews/icon/ico_ggplay.png new file mode 100644 index 0000000..12007eb Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_ggplay.png differ diff --git a/public/assets/images/homeNews/icon/ico_location.png b/public/assets/images/homeNews/icon/ico_location.png new file mode 100644 index 0000000..2060caf Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_location.png differ diff --git a/public/assets/images/homeNews/icon/ico_mail.png b/public/assets/images/homeNews/icon/ico_mail.png new file mode 100644 index 0000000..dc0a2a2 Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_mail.png differ diff --git a/public/assets/images/homeNews/icon/ico_msg.png b/public/assets/images/homeNews/icon/ico_msg.png new file mode 100644 index 0000000..431f1c6 Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_msg.png differ diff --git a/public/assets/images/homeNews/icon/ico_phone.png b/public/assets/images/homeNews/icon/ico_phone.png new file mode 100644 index 0000000..5a67579 Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_phone.png differ diff --git a/public/assets/images/homeNews/icon/ico_proactive.png b/public/assets/images/homeNews/icon/ico_proactive.png new file mode 100644 index 0000000..4ade62d Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_proactive.png differ diff --git a/public/assets/images/homeNews/icon/ico_qr.png b/public/assets/images/homeNews/icon/ico_qr.png new file mode 100644 index 0000000..d8703d8 Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_qr.png differ diff --git a/public/assets/images/homeNews/icon/ico_qr_appstore_parent.png b/public/assets/images/homeNews/icon/ico_qr_appstore_parent.png new file mode 100644 index 0000000..ac3c3fe Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_qr_appstore_parent.png differ diff --git a/public/assets/images/homeNews/icon/ico_qr_appstore_student.png b/public/assets/images/homeNews/icon/ico_qr_appstore_student.png new file mode 100644 index 0000000..a93b35b Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_qr_appstore_student.png differ diff --git a/public/assets/images/homeNews/icon/ico_qr_appstore_teacher.png b/public/assets/images/homeNews/icon/ico_qr_appstore_teacher.png new file mode 100644 index 0000000..8b18be0 Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_qr_appstore_teacher.png differ diff --git a/public/assets/images/homeNews/icon/ico_qr_ggplay_parent.png b/public/assets/images/homeNews/icon/ico_qr_ggplay_parent.png new file mode 100644 index 0000000..a3b37cd Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_qr_ggplay_parent.png differ diff --git a/public/assets/images/homeNews/icon/ico_qr_ggplay_student.png b/public/assets/images/homeNews/icon/ico_qr_ggplay_student.png new file mode 100644 index 0000000..d8703d8 Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_qr_ggplay_student.png differ diff --git a/public/assets/images/homeNews/icon/ico_qr_ggplay_teacher.png b/public/assets/images/homeNews/icon/ico_qr_ggplay_teacher.png new file mode 100644 index 0000000..a741058 Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_qr_ggplay_teacher.png differ diff --git a/public/assets/images/homeNews/icon/ico_school.png b/public/assets/images/homeNews/icon/ico_school.png new file mode 100644 index 0000000..01818e1 Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_school.png differ diff --git a/public/assets/images/homeNews/icon/ico_scroll_up.png b/public/assets/images/homeNews/icon/ico_scroll_up.png new file mode 100644 index 0000000..c93d5d1 Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_scroll_up.png differ diff --git a/public/assets/images/homeNews/icon/ico_ytb.png b/public/assets/images/homeNews/icon/ico_ytb.png new file mode 100644 index 0000000..82858d3 Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_ytb.png differ diff --git a/public/assets/images/homeNews/icon/ico_zalo.png b/public/assets/images/homeNews/icon/ico_zalo.png new file mode 100644 index 0000000..ddc235b Binary files /dev/null and b/public/assets/images/homeNews/icon/ico_zalo.png differ diff --git a/public/assets/images/homeNews/icon/icon_text_gv.png b/public/assets/images/homeNews/icon/icon_text_gv.png new file mode 100644 index 0000000..6086fc0 Binary files /dev/null and b/public/assets/images/homeNews/icon/icon_text_gv.png differ diff --git a/public/assets/images/homeNews/icon/icon_text_hs.png b/public/assets/images/homeNews/icon/icon_text_hs.png new file mode 100644 index 0000000..b66236f Binary files /dev/null and b/public/assets/images/homeNews/icon/icon_text_hs.png differ diff --git a/public/assets/images/homeNews/icon/icon_text_ph.png b/public/assets/images/homeNews/icon/icon_text_ph.png new file mode 100644 index 0000000..b370dcd Binary files /dev/null and b/public/assets/images/homeNews/icon/icon_text_ph.png differ diff --git a/public/assets/images/homeNews/icon/icon_view_detail_home_page.png b/public/assets/images/homeNews/icon/icon_view_detail_home_page.png new file mode 100644 index 0000000..5f6dd26 Binary files /dev/null and b/public/assets/images/homeNews/icon/icon_view_detail_home_page.png differ diff --git a/public/assets/images/homeNews/icon/img_bct.png b/public/assets/images/homeNews/icon/img_bct.png new file mode 100644 index 0000000..af2efce Binary files /dev/null and b/public/assets/images/homeNews/icon/img_bct.png differ diff --git a/public/assets/images/homeNews/slider/bg_tree_cloud.png b/public/assets/images/homeNews/slider/bg_tree_cloud.png new file mode 100644 index 0000000..391f9c8 Binary files /dev/null and b/public/assets/images/homeNews/slider/bg_tree_cloud.png differ diff --git a/public/assets/images/homeNews/slider/circle_bg_phone.png b/public/assets/images/homeNews/slider/circle_bg_phone.png new file mode 100644 index 0000000..e5a6cc1 Binary files /dev/null and b/public/assets/images/homeNews/slider/circle_bg_phone.png differ diff --git a/public/assets/images/homeNews/slider/parent_poster.jpg b/public/assets/images/homeNews/slider/parent_poster.jpg new file mode 100644 index 0000000..a2e8f19 Binary files /dev/null and b/public/assets/images/homeNews/slider/parent_poster.jpg differ diff --git a/public/assets/images/homeNews/slider/slider_1.png b/public/assets/images/homeNews/slider/slider_1.png new file mode 100644 index 0000000..b1d4996 Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_1.png differ diff --git a/public/assets/images/homeNews/slider/slider_2.png b/public/assets/images/homeNews/slider/slider_2.png new file mode 100644 index 0000000..96c1a2f Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_2.png differ diff --git a/public/assets/images/homeNews/slider/slider_2_mobile.png b/public/assets/images/homeNews/slider/slider_2_mobile.png new file mode 100644 index 0000000..8482182 Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_2_mobile.png differ diff --git a/public/assets/images/homeNews/slider/slider_3.png b/public/assets/images/homeNews/slider/slider_3.png new file mode 100644 index 0000000..0673f69 Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_3.png differ diff --git a/public/assets/images/homeNews/slider/slider_3_mobile.png b/public/assets/images/homeNews/slider/slider_3_mobile.png new file mode 100644 index 0000000..22a477c Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_3_mobile.png differ diff --git a/public/assets/images/homeNews/slider/slider_4.png b/public/assets/images/homeNews/slider/slider_4.png new file mode 100644 index 0000000..ea4fb12 Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_4.png differ diff --git a/public/assets/images/homeNews/slider/slider_4_full.png b/public/assets/images/homeNews/slider/slider_4_full.png new file mode 100644 index 0000000..302fa66 Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_4_full.png differ diff --git a/public/assets/images/homeNews/slider/slider_4_mobile.png b/public/assets/images/homeNews/slider/slider_4_mobile.png new file mode 100644 index 0000000..4943a60 Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_4_mobile.png differ diff --git a/public/assets/images/homeNews/slider/slider_bg.png b/public/assets/images/homeNews/slider/slider_bg.png new file mode 100644 index 0000000..fb68333 Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_bg.png differ diff --git a/public/assets/images/homeNews/slider/slider_bg_mobile.png b/public/assets/images/homeNews/slider/slider_bg_mobile.png new file mode 100644 index 0000000..d0f832c Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_bg_mobile.png differ diff --git a/public/assets/images/homeNews/slider/slider_bg_parent.png b/public/assets/images/homeNews/slider/slider_bg_parent.png new file mode 100644 index 0000000..b186292 Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_bg_parent.png differ diff --git a/public/assets/images/homeNews/slider/slider_bg_parent_mobile.png b/public/assets/images/homeNews/slider/slider_bg_parent_mobile.png new file mode 100644 index 0000000..67bec7a Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_bg_parent_mobile.png differ diff --git a/public/assets/images/homeNews/slider/slider_bg_student.png b/public/assets/images/homeNews/slider/slider_bg_student.png new file mode 100644 index 0000000..d3fdc9f Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_bg_student.png differ diff --git a/public/assets/images/homeNews/slider/slider_bg_teacher.png b/public/assets/images/homeNews/slider/slider_bg_teacher.png new file mode 100644 index 0000000..37c22c4 Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_bg_teacher.png differ diff --git a/public/assets/images/homeNews/slider/slider_bg_teacher_mobile.png b/public/assets/images/homeNews/slider/slider_bg_teacher_mobile.png new file mode 100644 index 0000000..2e07b0e Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_bg_teacher_mobile.png differ diff --git a/public/assets/images/homeNews/slider/slider_student.png b/public/assets/images/homeNews/slider/slider_student.png new file mode 100644 index 0000000..26c575b Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_student.png differ diff --git a/public/assets/images/homeNews/slider/slider_student_mobile.png b/public/assets/images/homeNews/slider/slider_student_mobile.png new file mode 100644 index 0000000..75c6ded Binary files /dev/null and b/public/assets/images/homeNews/slider/slider_student_mobile.png differ diff --git a/public/assets/images/homeNews/slider/student/img_circle_slider.png b/public/assets/images/homeNews/slider/student/img_circle_slider.png new file mode 100644 index 0000000..0ffbbd6 Binary files /dev/null and b/public/assets/images/homeNews/slider/student/img_circle_slider.png differ diff --git a/public/assets/images/homeNews/slider/student/img_side_home.png b/public/assets/images/homeNews/slider/student/img_side_home.png new file mode 100644 index 0000000..ae557a1 Binary files /dev/null and b/public/assets/images/homeNews/slider/student/img_side_home.png differ diff --git a/public/assets/images/homeNews/slider/student/slider_1.png b/public/assets/images/homeNews/slider/student/slider_1.png new file mode 100644 index 0000000..3f44641 Binary files /dev/null and b/public/assets/images/homeNews/slider/student/slider_1.png differ diff --git a/public/assets/images/homeNews/slider/student_poster.jpg b/public/assets/images/homeNews/slider/student_poster.jpg new file mode 100644 index 0000000..3c54dec Binary files /dev/null and b/public/assets/images/homeNews/slider/student_poster.jpg differ diff --git a/public/assets/images/homeNews/slider/teacher_poster.jpg b/public/assets/images/homeNews/slider/teacher_poster.jpg new file mode 100644 index 0000000..f76886d Binary files /dev/null and b/public/assets/images/homeNews/slider/teacher_poster.jpg differ diff --git a/public/assets/images/homeNews/slider/video_slider_parent.png b/public/assets/images/homeNews/slider/video_slider_parent.png new file mode 100644 index 0000000..f23f6c7 Binary files /dev/null and b/public/assets/images/homeNews/slider/video_slider_parent.png differ diff --git a/public/assets/images/homeNews/slider/video_slider_side.png b/public/assets/images/homeNews/slider/video_slider_side.png new file mode 100644 index 0000000..872c839 Binary files /dev/null and b/public/assets/images/homeNews/slider/video_slider_side.png differ diff --git a/public/assets/images/homeNews/slider/video_slider_teacher.png b/public/assets/images/homeNews/slider/video_slider_teacher.png new file mode 100644 index 0000000..d3c2a4b Binary files /dev/null and b/public/assets/images/homeNews/slider/video_slider_teacher.png differ diff --git a/public/assets/images/hoso/bg_hoso_detail.png b/public/assets/images/hoso/bg_hoso_detail.png new file mode 100644 index 0000000..aebfa5a Binary files /dev/null and b/public/assets/images/hoso/bg_hoso_detail.png differ diff --git a/public/assets/images/hoso/bg_hoso_detail_student.png b/public/assets/images/hoso/bg_hoso_detail_student.png new file mode 100644 index 0000000..c2483d0 Binary files /dev/null and b/public/assets/images/hoso/bg_hoso_detail_student.png differ diff --git a/public/assets/images/hoso/default_avt.png b/public/assets/images/hoso/default_avt.png new file mode 100644 index 0000000..28dbec5 Binary files /dev/null and b/public/assets/images/hoso/default_avt.png differ diff --git a/public/assets/images/hoso/ico_birthday.png b/public/assets/images/hoso/ico_birthday.png new file mode 100644 index 0000000..7d639b6 Binary files /dev/null and b/public/assets/images/hoso/ico_birthday.png differ diff --git a/public/assets/images/hoso/ico_edit_avt.png b/public/assets/images/hoso/ico_edit_avt.png new file mode 100644 index 0000000..cf9b936 Binary files /dev/null and b/public/assets/images/hoso/ico_edit_avt.png differ diff --git a/public/assets/images/hoso/ico_email.png b/public/assets/images/hoso/ico_email.png new file mode 100644 index 0000000..cf98799 Binary files /dev/null and b/public/assets/images/hoso/ico_email.png differ diff --git a/public/assets/images/hoso/ico_gender.png b/public/assets/images/hoso/ico_gender.png new file mode 100644 index 0000000..6febf3c Binary files /dev/null and b/public/assets/images/hoso/ico_gender.png differ diff --git a/public/assets/images/hoso/ico_phone.png b/public/assets/images/hoso/ico_phone.png new file mode 100644 index 0000000..7d0484a Binary files /dev/null and b/public/assets/images/hoso/ico_phone.png differ diff --git a/public/assets/images/hoso/ico_shcool.png b/public/assets/images/hoso/ico_shcool.png new file mode 100644 index 0000000..3c94c40 Binary files /dev/null and b/public/assets/images/hoso/ico_shcool.png differ diff --git a/public/assets/images/ico-play-audio.png b/public/assets/images/ico-play-audio.png new file mode 100644 index 0000000..0edacf2 Binary files /dev/null and b/public/assets/images/ico-play-audio.png differ diff --git a/public/assets/images/ico_danger.png b/public/assets/images/ico_danger.png new file mode 100644 index 0000000..242d2e3 Binary files /dev/null and b/public/assets/images/ico_danger.png differ diff --git a/public/assets/images/ico_hover_answer.png b/public/assets/images/ico_hover_answer.png new file mode 100644 index 0000000..5a2806e Binary files /dev/null and b/public/assets/images/ico_hover_answer.png differ diff --git a/public/assets/images/ico_user_border.png b/public/assets/images/ico_user_border.png new file mode 100644 index 0000000..5fe115a Binary files /dev/null and b/public/assets/images/ico_user_border.png differ diff --git a/public/assets/images/icon/checkbox_active.png b/public/assets/images/icon/checkbox_active.png new file mode 100644 index 0000000..e2bbf75 Binary files /dev/null and b/public/assets/images/icon/checkbox_active.png differ diff --git a/public/assets/images/icon/checkbox_danger.png b/public/assets/images/icon/checkbox_danger.png new file mode 100644 index 0000000..3b309c3 Binary files /dev/null and b/public/assets/images/icon/checkbox_danger.png differ diff --git a/public/assets/images/icon/checkbox_none.png b/public/assets/images/icon/checkbox_none.png new file mode 100644 index 0000000..78bfe43 Binary files /dev/null and b/public/assets/images/icon/checkbox_none.png differ diff --git a/public/assets/images/icon/ico_achievement.png b/public/assets/images/icon/ico_achievement.png new file mode 100644 index 0000000..184bd5e Binary files /dev/null and b/public/assets/images/icon/ico_achievement.png differ diff --git a/public/assets/images/icon/ico_add.png b/public/assets/images/icon/ico_add.png new file mode 100644 index 0000000..52e38d1 Binary files /dev/null and b/public/assets/images/icon/ico_add.png differ diff --git a/public/assets/images/icon/ico_add_circle.png b/public/assets/images/icon/ico_add_circle.png new file mode 100644 index 0000000..0029b15 Binary files /dev/null and b/public/assets/images/icon/ico_add_circle.png differ diff --git a/public/assets/images/icon/ico_add_lesson.png b/public/assets/images/icon/ico_add_lesson.png new file mode 100644 index 0000000..df552c8 Binary files /dev/null and b/public/assets/images/icon/ico_add_lesson.png differ diff --git a/public/assets/images/icon/ico_birthday.png b/public/assets/images/icon/ico_birthday.png new file mode 100644 index 0000000..2c0203b Binary files /dev/null and b/public/assets/images/icon/ico_birthday.png differ diff --git a/public/assets/images/icon/ico_book.png b/public/assets/images/icon/ico_book.png new file mode 100644 index 0000000..c143989 Binary files /dev/null and b/public/assets/images/icon/ico_book.png differ diff --git a/public/assets/images/icon/ico_book_active.png b/public/assets/images/icon/ico_book_active.png new file mode 100644 index 0000000..8212510 Binary files /dev/null and b/public/assets/images/icon/ico_book_active.png differ diff --git a/public/assets/images/icon/ico_box.png b/public/assets/images/icon/ico_box.png new file mode 100644 index 0000000..366ac12 Binary files /dev/null and b/public/assets/images/icon/ico_box.png differ diff --git a/public/assets/images/icon/ico_box_tick.png b/public/assets/images/icon/ico_box_tick.png new file mode 100644 index 0000000..e8c17bc Binary files /dev/null and b/public/assets/images/icon/ico_box_tick.png differ diff --git a/public/assets/images/icon/ico_buy.png b/public/assets/images/icon/ico_buy.png new file mode 100644 index 0000000..70319e1 Binary files /dev/null and b/public/assets/images/icon/ico_buy.png differ diff --git a/public/assets/images/icon/ico_buy_white.png b/public/assets/images/icon/ico_buy_white.png new file mode 100644 index 0000000..b6eae2a Binary files /dev/null and b/public/assets/images/icon/ico_buy_white.png differ diff --git a/public/assets/images/icon/ico_camera.png b/public/assets/images/icon/ico_camera.png new file mode 100644 index 0000000..98ffca7 Binary files /dev/null and b/public/assets/images/icon/ico_camera.png differ diff --git a/public/assets/images/icon/ico_cancel_schedule.png b/public/assets/images/icon/ico_cancel_schedule.png new file mode 100644 index 0000000..add4217 Binary files /dev/null and b/public/assets/images/icon/ico_cancel_schedule.png differ diff --git a/public/assets/images/icon/ico_cart.png b/public/assets/images/icon/ico_cart.png new file mode 100644 index 0000000..fa2ae3d Binary files /dev/null and b/public/assets/images/icon/ico_cart.png differ diff --git a/public/assets/images/icon/ico_check_calendar.png b/public/assets/images/icon/ico_check_calendar.png new file mode 100644 index 0000000..6d86bd3 Binary files /dev/null and b/public/assets/images/icon/ico_check_calendar.png differ diff --git a/public/assets/images/icon/ico_checkbox.png b/public/assets/images/icon/ico_checkbox.png new file mode 100644 index 0000000..57fcb72 Binary files /dev/null and b/public/assets/images/icon/ico_checkbox.png differ diff --git a/public/assets/images/icon/ico_checked.png b/public/assets/images/icon/ico_checked.png new file mode 100644 index 0000000..c85a24c Binary files /dev/null and b/public/assets/images/icon/ico_checked.png differ diff --git a/public/assets/images/icon/ico_checkedbox.png b/public/assets/images/icon/ico_checkedbox.png new file mode 100644 index 0000000..d2e8fec Binary files /dev/null and b/public/assets/images/icon/ico_checkedbox.png differ diff --git a/public/assets/images/icon/ico_circle_down.png b/public/assets/images/icon/ico_circle_down.png new file mode 100644 index 0000000..1fcad3b Binary files /dev/null and b/public/assets/images/icon/ico_circle_down.png differ diff --git a/public/assets/images/icon/ico_circle_up.png b/public/assets/images/icon/ico_circle_up.png new file mode 100644 index 0000000..4c929eb Binary files /dev/null and b/public/assets/images/icon/ico_circle_up.png differ diff --git a/public/assets/images/icon/ico_class.png b/public/assets/images/icon/ico_class.png new file mode 100644 index 0000000..a116966 Binary files /dev/null and b/public/assets/images/icon/ico_class.png differ diff --git a/public/assets/images/icon/ico_clock.png b/public/assets/images/icon/ico_clock.png new file mode 100644 index 0000000..af92b65 Binary files /dev/null and b/public/assets/images/icon/ico_clock.png differ diff --git a/public/assets/images/icon/ico_clock_entrance_white.png b/public/assets/images/icon/ico_clock_entrance_white.png new file mode 100644 index 0000000..9d4f9c6 Binary files /dev/null and b/public/assets/images/icon/ico_clock_entrance_white.png differ diff --git a/public/assets/images/icon/ico_clock_white.png b/public/assets/images/icon/ico_clock_white.png new file mode 100644 index 0000000..b05311a Binary files /dev/null and b/public/assets/images/icon/ico_clock_white.png differ diff --git a/public/assets/images/icon/ico_close_filter.png b/public/assets/images/icon/ico_close_filter.png new file mode 100644 index 0000000..208b1a0 Binary files /dev/null and b/public/assets/images/icon/ico_close_filter.png differ diff --git a/public/assets/images/icon/ico_close_menu.png b/public/assets/images/icon/ico_close_menu.png new file mode 100644 index 0000000..fd314f1 Binary files /dev/null and b/public/assets/images/icon/ico_close_menu.png differ diff --git a/public/assets/images/icon/ico_close_popup.png b/public/assets/images/icon/ico_close_popup.png new file mode 100644 index 0000000..c3f98c8 Binary files /dev/null and b/public/assets/images/icon/ico_close_popup.png differ diff --git a/public/assets/images/icon/ico_close_red.png b/public/assets/images/icon/ico_close_red.png new file mode 100644 index 0000000..5451dfd Binary files /dev/null and b/public/assets/images/icon/ico_close_red.png differ diff --git a/public/assets/images/icon/ico_close_white_popup.png b/public/assets/images/icon/ico_close_white_popup.png new file mode 100644 index 0000000..875518d Binary files /dev/null and b/public/assets/images/icon/ico_close_white_popup.png differ diff --git a/public/assets/images/icon/ico_dangdienra.png b/public/assets/images/icon/ico_dangdienra.png new file mode 100644 index 0000000..04d85c9 Binary files /dev/null and b/public/assets/images/icon/ico_dangdienra.png differ diff --git a/public/assets/images/icon/ico_dash_connect_1.png b/public/assets/images/icon/ico_dash_connect_1.png new file mode 100644 index 0000000..32e0b9f Binary files /dev/null and b/public/assets/images/icon/ico_dash_connect_1.png differ diff --git a/public/assets/images/icon/ico_dash_connect_2.png b/public/assets/images/icon/ico_dash_connect_2.png new file mode 100644 index 0000000..79aaa5e Binary files /dev/null and b/public/assets/images/icon/ico_dash_connect_2.png differ diff --git a/public/assets/images/icon/ico_date_active.png b/public/assets/images/icon/ico_date_active.png new file mode 100644 index 0000000..16f8a32 Binary files /dev/null and b/public/assets/images/icon/ico_date_active.png differ diff --git a/public/assets/images/icon/ico_date_buy.png b/public/assets/images/icon/ico_date_buy.png new file mode 100644 index 0000000..973dd8f Binary files /dev/null and b/public/assets/images/icon/ico_date_buy.png differ diff --git a/public/assets/images/icon/ico_decrease.png b/public/assets/images/icon/ico_decrease.png new file mode 100644 index 0000000..56d89b2 Binary files /dev/null and b/public/assets/images/icon/ico_decrease.png differ diff --git a/public/assets/images/icon/ico_delete.png b/public/assets/images/icon/ico_delete.png new file mode 100644 index 0000000..09d00a6 Binary files /dev/null and b/public/assets/images/icon/ico_delete.png differ diff --git a/public/assets/images/icon/ico_delete_full.png b/public/assets/images/icon/ico_delete_full.png new file mode 100644 index 0000000..d29ed56 Binary files /dev/null and b/public/assets/images/icon/ico_delete_full.png differ diff --git a/public/assets/images/icon/ico_delete_green.png b/public/assets/images/icon/ico_delete_green.png new file mode 100644 index 0000000..a0ca6a7 Binary files /dev/null and b/public/assets/images/icon/ico_delete_green.png differ diff --git a/public/assets/images/icon/ico_diamond.png b/public/assets/images/icon/ico_diamond.png new file mode 100644 index 0000000..54f3592 Binary files /dev/null and b/public/assets/images/icon/ico_diamond.png differ diff --git a/public/assets/images/icon/ico_diamond_white.png b/public/assets/images/icon/ico_diamond_white.png new file mode 100644 index 0000000..d148709 Binary files /dev/null and b/public/assets/images/icon/ico_diamond_white.png differ diff --git a/public/assets/images/icon/ico_dropdown.png b/public/assets/images/icon/ico_dropdown.png new file mode 100644 index 0000000..c3e4793 Binary files /dev/null and b/public/assets/images/icon/ico_dropdown.png differ diff --git a/public/assets/images/icon/ico_dropdown_blue.png b/public/assets/images/icon/ico_dropdown_blue.png new file mode 100644 index 0000000..080e3d8 Binary files /dev/null and b/public/assets/images/icon/ico_dropdown_blue.png differ diff --git a/public/assets/images/icon/ico_dropdown_border_white.png b/public/assets/images/icon/ico_dropdown_border_white.png new file mode 100644 index 0000000..2471a10 Binary files /dev/null and b/public/assets/images/icon/ico_dropdown_border_white.png differ diff --git a/public/assets/images/icon/ico_dropdown_s.png b/public/assets/images/icon/ico_dropdown_s.png new file mode 100644 index 0000000..96eb9c7 Binary files /dev/null and b/public/assets/images/icon/ico_dropdown_s.png differ diff --git a/public/assets/images/icon/ico_dropup.png b/public/assets/images/icon/ico_dropup.png new file mode 100644 index 0000000..e3eb8b2 Binary files /dev/null and b/public/assets/images/icon/ico_dropup.png differ diff --git a/public/assets/images/icon/ico_edit.png b/public/assets/images/icon/ico_edit.png new file mode 100644 index 0000000..1a15991 Binary files /dev/null and b/public/assets/images/icon/ico_edit.png differ diff --git a/public/assets/images/icon/ico_edit_class.png b/public/assets/images/icon/ico_edit_class.png new file mode 100644 index 0000000..8de53ac Binary files /dev/null and b/public/assets/images/icon/ico_edit_class.png differ diff --git a/public/assets/images/icon/ico_edit_white.png b/public/assets/images/icon/ico_edit_white.png new file mode 100644 index 0000000..e8bb20a Binary files /dev/null and b/public/assets/images/icon/ico_edit_white.png differ diff --git a/public/assets/images/icon/ico_email.png b/public/assets/images/icon/ico_email.png new file mode 100644 index 0000000..4f6668b Binary files /dev/null and b/public/assets/images/icon/ico_email.png differ diff --git a/public/assets/images/icon/ico_eye_close.png b/public/assets/images/icon/ico_eye_close.png new file mode 100644 index 0000000..87f0ecd Binary files /dev/null and b/public/assets/images/icon/ico_eye_close.png differ diff --git a/public/assets/images/icon/ico_eye_open.png b/public/assets/images/icon/ico_eye_open.png new file mode 100644 index 0000000..d70d18a Binary files /dev/null and b/public/assets/images/icon/ico_eye_open.png differ diff --git a/public/assets/images/icon/ico_female.png b/public/assets/images/icon/ico_female.png new file mode 100644 index 0000000..c092be9 Binary files /dev/null and b/public/assets/images/icon/ico_female.png differ diff --git a/public/assets/images/icon/ico_female_2.png b/public/assets/images/icon/ico_female_2.png new file mode 100644 index 0000000..6d2617c Binary files /dev/null and b/public/assets/images/icon/ico_female_2.png differ diff --git a/public/assets/images/icon/ico_filter.png b/public/assets/images/icon/ico_filter.png new file mode 100644 index 0000000..0abb870 Binary files /dev/null and b/public/assets/images/icon/ico_filter.png differ diff --git a/public/assets/images/icon/ico_filter_blue.png b/public/assets/images/icon/ico_filter_blue.png new file mode 100644 index 0000000..4152042 Binary files /dev/null and b/public/assets/images/icon/ico_filter_blue.png differ diff --git a/public/assets/images/icon/ico_filter_green.png b/public/assets/images/icon/ico_filter_green.png new file mode 100644 index 0000000..f8bd899 Binary files /dev/null and b/public/assets/images/icon/ico_filter_green.png differ diff --git a/public/assets/images/icon/ico_green_circle.png b/public/assets/images/icon/ico_green_circle.png new file mode 100644 index 0000000..ec6b786 Binary files /dev/null and b/public/assets/images/icon/ico_green_circle.png differ diff --git a/public/assets/images/icon/ico_home.png b/public/assets/images/icon/ico_home.png new file mode 100644 index 0000000..a42d222 Binary files /dev/null and b/public/assets/images/icon/ico_home.png differ diff --git a/public/assets/images/icon/ico_home_active.png b/public/assets/images/icon/ico_home_active.png new file mode 100644 index 0000000..bc5dced Binary files /dev/null and b/public/assets/images/icon/ico_home_active.png differ diff --git a/public/assets/images/icon/ico_idot.png b/public/assets/images/icon/ico_idot.png new file mode 100644 index 0000000..2a705cf Binary files /dev/null and b/public/assets/images/icon/ico_idot.png differ diff --git a/public/assets/images/icon/ico_idot_white.png b/public/assets/images/icon/ico_idot_white.png new file mode 100644 index 0000000..a447118 Binary files /dev/null and b/public/assets/images/icon/ico_idot_white.png differ diff --git a/public/assets/images/icon/ico_idots.png b/public/assets/images/icon/ico_idots.png new file mode 100644 index 0000000..59a9338 Binary files /dev/null and b/public/assets/images/icon/ico_idots.png differ diff --git a/public/assets/images/icon/ico_increase.png b/public/assets/images/icon/ico_increase.png new file mode 100644 index 0000000..f3972e4 Binary files /dev/null and b/public/assets/images/icon/ico_increase.png differ diff --git a/public/assets/images/icon/ico_khoi.png b/public/assets/images/icon/ico_khoi.png new file mode 100644 index 0000000..24ddd9e Binary files /dev/null and b/public/assets/images/icon/ico_khoi.png differ diff --git a/public/assets/images/icon/ico_left.png b/public/assets/images/icon/ico_left.png new file mode 100644 index 0000000..79cfb47 Binary files /dev/null and b/public/assets/images/icon/ico_left.png differ diff --git a/public/assets/images/icon/ico_left_calender.png b/public/assets/images/icon/ico_left_calender.png new file mode 100644 index 0000000..5f10acb Binary files /dev/null and b/public/assets/images/icon/ico_left_calender.png differ diff --git a/public/assets/images/icon/ico_left_circle_blue.png b/public/assets/images/icon/ico_left_circle_blue.png new file mode 100644 index 0000000..32972cf Binary files /dev/null and b/public/assets/images/icon/ico_left_circle_blue.png differ diff --git a/public/assets/images/icon/ico_left_weight.png b/public/assets/images/icon/ico_left_weight.png new file mode 100644 index 0000000..919d933 Binary files /dev/null and b/public/assets/images/icon/ico_left_weight.png differ diff --git a/public/assets/images/icon/ico_left_white.png b/public/assets/images/icon/ico_left_white.png new file mode 100644 index 0000000..c222b74 Binary files /dev/null and b/public/assets/images/icon/ico_left_white.png differ diff --git a/public/assets/images/icon/ico_left_white_small.png b/public/assets/images/icon/ico_left_white_small.png new file mode 100644 index 0000000..92fb844 Binary files /dev/null and b/public/assets/images/icon/ico_left_white_small.png differ diff --git a/public/assets/images/icon/ico_login_google.png b/public/assets/images/icon/ico_login_google.png new file mode 100644 index 0000000..ce356e4 Binary files /dev/null and b/public/assets/images/icon/ico_login_google.png differ diff --git a/public/assets/images/icon/ico_logout.png b/public/assets/images/icon/ico_logout.png new file mode 100644 index 0000000..144bc2b Binary files /dev/null and b/public/assets/images/icon/ico_logout.png differ diff --git a/public/assets/images/icon/ico_logout_green.png b/public/assets/images/icon/ico_logout_green.png new file mode 100644 index 0000000..ad1ad86 Binary files /dev/null and b/public/assets/images/icon/ico_logout_green.png differ diff --git a/public/assets/images/icon/ico_lop.png b/public/assets/images/icon/ico_lop.png new file mode 100644 index 0000000..369cad1 Binary files /dev/null and b/public/assets/images/icon/ico_lop.png differ diff --git a/public/assets/images/icon/ico_lop_active.png b/public/assets/images/icon/ico_lop_active.png new file mode 100644 index 0000000..b6fdfe2 Binary files /dev/null and b/public/assets/images/icon/ico_lop_active.png differ diff --git a/public/assets/images/icon/ico_lozenge.png b/public/assets/images/icon/ico_lozenge.png new file mode 100644 index 0000000..e880346 Binary files /dev/null and b/public/assets/images/icon/ico_lozenge.png differ diff --git a/public/assets/images/icon/ico_luyenthi.png b/public/assets/images/icon/ico_luyenthi.png new file mode 100644 index 0000000..bd36a59 Binary files /dev/null and b/public/assets/images/icon/ico_luyenthi.png differ diff --git a/public/assets/images/icon/ico_luyenthi_active.png b/public/assets/images/icon/ico_luyenthi_active.png new file mode 100644 index 0000000..bd36a59 Binary files /dev/null and b/public/assets/images/icon/ico_luyenthi_active.png differ diff --git a/public/assets/images/icon/ico_ma.png b/public/assets/images/icon/ico_ma.png new file mode 100644 index 0000000..1afde2a Binary files /dev/null and b/public/assets/images/icon/ico_ma.png differ diff --git a/public/assets/images/icon/ico_ma_white.png b/public/assets/images/icon/ico_ma_white.png new file mode 100644 index 0000000..6801368 Binary files /dev/null and b/public/assets/images/icon/ico_ma_white.png differ diff --git a/public/assets/images/icon/ico_male.png b/public/assets/images/icon/ico_male.png new file mode 100644 index 0000000..587e834 Binary files /dev/null and b/public/assets/images/icon/ico_male.png differ diff --git a/public/assets/images/icon/ico_male_2.png b/public/assets/images/icon/ico_male_2.png new file mode 100644 index 0000000..3cc1ff4 Binary files /dev/null and b/public/assets/images/icon/ico_male_2.png differ diff --git a/public/assets/images/icon/ico_menu.png b/public/assets/images/icon/ico_menu.png new file mode 100644 index 0000000..853163a Binary files /dev/null and b/public/assets/images/icon/ico_menu.png differ diff --git a/public/assets/images/icon/ico_message.png b/public/assets/images/icon/ico_message.png new file mode 100644 index 0000000..5eb1cf9 Binary files /dev/null and b/public/assets/images/icon/ico_message.png differ diff --git a/public/assets/images/icon/ico_message_active.png b/public/assets/images/icon/ico_message_active.png new file mode 100644 index 0000000..f8f3808 Binary files /dev/null and b/public/assets/images/icon/ico_message_active.png differ diff --git a/public/assets/images/icon/ico_missing_calendar.png b/public/assets/images/icon/ico_missing_calendar.png new file mode 100644 index 0000000..c45b4ea Binary files /dev/null and b/public/assets/images/icon/ico_missing_calendar.png differ diff --git a/public/assets/images/icon/ico_new_package.png b/public/assets/images/icon/ico_new_package.png new file mode 100644 index 0000000..f44159d Binary files /dev/null and b/public/assets/images/icon/ico_new_package.png differ diff --git a/public/assets/images/icon/ico_notification.jpg b/public/assets/images/icon/ico_notification.jpg new file mode 100644 index 0000000..071ca0f Binary files /dev/null and b/public/assets/images/icon/ico_notification.jpg differ diff --git a/public/assets/images/icon/ico_notification.png b/public/assets/images/icon/ico_notification.png new file mode 100644 index 0000000..eeb5bd9 Binary files /dev/null and b/public/assets/images/icon/ico_notification.png differ diff --git a/public/assets/images/icon/ico_participant.png b/public/assets/images/icon/ico_participant.png new file mode 100644 index 0000000..337c6ca Binary files /dev/null and b/public/assets/images/icon/ico_participant.png differ diff --git a/public/assets/images/icon/ico_password.png b/public/assets/images/icon/ico_password.png new file mode 100644 index 0000000..cf6bda1 Binary files /dev/null and b/public/assets/images/icon/ico_password.png differ diff --git a/public/assets/images/icon/ico_phone.png b/public/assets/images/icon/ico_phone.png new file mode 100644 index 0000000..718d5fd Binary files /dev/null and b/public/assets/images/icon/ico_phone.png differ diff --git a/public/assets/images/icon/ico_profile.png b/public/assets/images/icon/ico_profile.png new file mode 100644 index 0000000..3fbeec1 Binary files /dev/null and b/public/assets/images/icon/ico_profile.png differ diff --git a/public/assets/images/icon/ico_quagio.png b/public/assets/images/icon/ico_quagio.png new file mode 100644 index 0000000..81e1fb5 Binary files /dev/null and b/public/assets/images/icon/ico_quagio.png differ diff --git a/public/assets/images/icon/ico_ratio_active.png b/public/assets/images/icon/ico_ratio_active.png new file mode 100644 index 0000000..15e067e Binary files /dev/null and b/public/assets/images/icon/ico_ratio_active.png differ diff --git a/public/assets/images/icon/ico_ratio_none.png b/public/assets/images/icon/ico_ratio_none.png new file mode 100644 index 0000000..9655577 Binary files /dev/null and b/public/assets/images/icon/ico_ratio_none.png differ diff --git a/public/assets/images/icon/ico_remove.png b/public/assets/images/icon/ico_remove.png new file mode 100644 index 0000000..3f77ce3 Binary files /dev/null and b/public/assets/images/icon/ico_remove.png differ diff --git a/public/assets/images/icon/ico_remove_gray.png b/public/assets/images/icon/ico_remove_gray.png new file mode 100644 index 0000000..7eb62c2 Binary files /dev/null and b/public/assets/images/icon/ico_remove_gray.png differ diff --git a/public/assets/images/icon/ico_remove_schedule.png b/public/assets/images/icon/ico_remove_schedule.png new file mode 100644 index 0000000..f27f915 Binary files /dev/null and b/public/assets/images/icon/ico_remove_schedule.png differ diff --git a/public/assets/images/icon/ico_review_active.png b/public/assets/images/icon/ico_review_active.png new file mode 100644 index 0000000..25e0b1f Binary files /dev/null and b/public/assets/images/icon/ico_review_active.png differ diff --git a/public/assets/images/icon/ico_review_inactive.png b/public/assets/images/icon/ico_review_inactive.png new file mode 100644 index 0000000..7e9ad84 Binary files /dev/null and b/public/assets/images/icon/ico_review_inactive.png differ diff --git a/public/assets/images/icon/ico_right.png b/public/assets/images/icon/ico_right.png new file mode 100644 index 0000000..d7a9406 Binary files /dev/null and b/public/assets/images/icon/ico_right.png differ diff --git a/public/assets/images/icon/ico_right_calender.png b/public/assets/images/icon/ico_right_calender.png new file mode 100644 index 0000000..667dc2f Binary files /dev/null and b/public/assets/images/icon/ico_right_calender.png differ diff --git a/public/assets/images/icon/ico_right_circle_blue.png b/public/assets/images/icon/ico_right_circle_blue.png new file mode 100644 index 0000000..ca20c24 Binary files /dev/null and b/public/assets/images/icon/ico_right_circle_blue.png differ diff --git a/public/assets/images/icon/ico_right_weight.png b/public/assets/images/icon/ico_right_weight.png new file mode 100644 index 0000000..dc7492f Binary files /dev/null and b/public/assets/images/icon/ico_right_weight.png differ diff --git a/public/assets/images/icon/ico_right_white.png b/public/assets/images/icon/ico_right_white.png new file mode 100644 index 0000000..95d80b9 Binary files /dev/null and b/public/assets/images/icon/ico_right_white.png differ diff --git a/public/assets/images/icon/ico_right_white_small.png b/public/assets/images/icon/ico_right_white_small.png new file mode 100644 index 0000000..c6e2374 Binary files /dev/null and b/public/assets/images/icon/ico_right_white_small.png differ diff --git a/public/assets/images/icon/ico_rotate.png b/public/assets/images/icon/ico_rotate.png new file mode 100644 index 0000000..3dccd5f Binary files /dev/null and b/public/assets/images/icon/ico_rotate.png differ diff --git a/public/assets/images/icon/ico_save.png b/public/assets/images/icon/ico_save.png new file mode 100644 index 0000000..ec7196b Binary files /dev/null and b/public/assets/images/icon/ico_save.png differ diff --git a/public/assets/images/icon/ico_save_white.png b/public/assets/images/icon/ico_save_white.png new file mode 100644 index 0000000..42b94a4 Binary files /dev/null and b/public/assets/images/icon/ico_save_white.png differ diff --git a/public/assets/images/icon/ico_school.png b/public/assets/images/icon/ico_school.png new file mode 100644 index 0000000..6a71e5f Binary files /dev/null and b/public/assets/images/icon/ico_school.png differ diff --git a/public/assets/images/icon/ico_student.png b/public/assets/images/icon/ico_student.png new file mode 100644 index 0000000..ef3a265 Binary files /dev/null and b/public/assets/images/icon/ico_student.png differ diff --git a/public/assets/images/icon/ico_succes.png b/public/assets/images/icon/ico_succes.png new file mode 100644 index 0000000..1118093 Binary files /dev/null and b/public/assets/images/icon/ico_succes.png differ diff --git a/public/assets/images/icon/ico_succes_small.png b/public/assets/images/icon/ico_succes_small.png new file mode 100644 index 0000000..937b3ed Binary files /dev/null and b/public/assets/images/icon/ico_succes_small.png differ diff --git a/public/assets/images/icon/ico_success_schedule.png b/public/assets/images/icon/ico_success_schedule.png new file mode 100644 index 0000000..17372a9 Binary files /dev/null and b/public/assets/images/icon/ico_success_schedule.png differ diff --git a/public/assets/images/icon/ico_test.png b/public/assets/images/icon/ico_test.png new file mode 100644 index 0000000..7b162b8 Binary files /dev/null and b/public/assets/images/icon/ico_test.png differ diff --git a/public/assets/images/icon/ico_thanhtich.png b/public/assets/images/icon/ico_thanhtich.png new file mode 100644 index 0000000..c8edc77 Binary files /dev/null and b/public/assets/images/icon/ico_thanhtich.png differ diff --git a/public/assets/images/icon/ico_thanhtich_active.png b/public/assets/images/icon/ico_thanhtich_active.png new file mode 100644 index 0000000..57094dd Binary files /dev/null and b/public/assets/images/icon/ico_thanhtich_active.png differ diff --git a/public/assets/images/icon/ico_tick.png b/public/assets/images/icon/ico_tick.png new file mode 100644 index 0000000..1a17f6c Binary files /dev/null and b/public/assets/images/icon/ico_tick.png differ diff --git a/public/assets/images/icon/ico_tick_detail.png b/public/assets/images/icon/ico_tick_detail.png new file mode 100644 index 0000000..171fe81 Binary files /dev/null and b/public/assets/images/icon/ico_tick_detail.png differ diff --git a/public/assets/images/icon/ico_tick_detail_orange.png b/public/assets/images/icon/ico_tick_detail_orange.png new file mode 100644 index 0000000..8b8e41e Binary files /dev/null and b/public/assets/images/icon/ico_tick_detail_orange.png differ diff --git a/public/assets/images/icon/ico_tick_green.png b/public/assets/images/icon/ico_tick_green.png new file mode 100644 index 0000000..eccc450 Binary files /dev/null and b/public/assets/images/icon/ico_tick_green.png differ diff --git a/public/assets/images/icon/ico_tick_orange.png b/public/assets/images/icon/ico_tick_orange.png new file mode 100644 index 0000000..07441eb Binary files /dev/null and b/public/assets/images/icon/ico_tick_orange.png differ diff --git a/public/assets/images/icon/ico_tick_red.png b/public/assets/images/icon/ico_tick_red.png new file mode 100644 index 0000000..e3c0099 Binary files /dev/null and b/public/assets/images/icon/ico_tick_red.png differ diff --git a/public/assets/images/icon/ico_tick_success.png b/public/assets/images/icon/ico_tick_success.png new file mode 100644 index 0000000..a37c93a Binary files /dev/null and b/public/assets/images/icon/ico_tick_success.png differ diff --git a/public/assets/images/icon/ico_time.png b/public/assets/images/icon/ico_time.png new file mode 100644 index 0000000..1575b6d Binary files /dev/null and b/public/assets/images/icon/ico_time.png differ diff --git a/public/assets/images/icon/ico_time_white.png b/public/assets/images/icon/ico_time_white.png new file mode 100644 index 0000000..b05311a Binary files /dev/null and b/public/assets/images/icon/ico_time_white.png differ diff --git a/public/assets/images/icon/ico_trash.png b/public/assets/images/icon/ico_trash.png new file mode 100644 index 0000000..be87a55 Binary files /dev/null and b/public/assets/images/icon/ico_trash.png differ diff --git a/public/assets/images/icon/ico_upload_image.png b/public/assets/images/icon/ico_upload_image.png new file mode 100644 index 0000000..f2fc2be Binary files /dev/null and b/public/assets/images/icon/ico_upload_image.png differ diff --git a/public/assets/images/icon/ico_user.png b/public/assets/images/icon/ico_user.png new file mode 100644 index 0000000..0067ed0 Binary files /dev/null and b/public/assets/images/icon/ico_user.png differ diff --git a/public/assets/images/icon/ico_white_star.png b/public/assets/images/icon/ico_white_star.png new file mode 100644 index 0000000..147d218 Binary files /dev/null and b/public/assets/images/icon/ico_white_star.png differ diff --git a/public/assets/images/icon/ico_xemthem.png b/public/assets/images/icon/ico_xemthem.png new file mode 100644 index 0000000..1fd964b Binary files /dev/null and b/public/assets/images/icon/ico_xemthem.png differ diff --git a/public/assets/images/icon/ico_xemthem_active.png b/public/assets/images/icon/ico_xemthem_active.png new file mode 100644 index 0000000..806d5ec Binary files /dev/null and b/public/assets/images/icon/ico_xemthem_active.png differ diff --git a/public/assets/images/icon/ico_zoom_in.png b/public/assets/images/icon/ico_zoom_in.png new file mode 100644 index 0000000..ee2763d Binary files /dev/null and b/public/assets/images/icon/ico_zoom_in.png differ diff --git a/public/assets/images/icon/ico_zoom_out.png b/public/assets/images/icon/ico_zoom_out.png new file mode 100644 index 0000000..114c04c Binary files /dev/null and b/public/assets/images/icon/ico_zoom_out.png differ diff --git a/public/assets/images/icon/icon_login_fb.png b/public/assets/images/icon/icon_login_fb.png new file mode 100644 index 0000000..84ea09c Binary files /dev/null and b/public/assets/images/icon/icon_login_fb.png differ diff --git a/public/assets/images/icon/icon_user_2.png b/public/assets/images/icon/icon_user_2.png new file mode 100644 index 0000000..7e308a1 Binary files /dev/null and b/public/assets/images/icon/icon_user_2.png differ diff --git a/public/assets/images/icon/warning.png b/public/assets/images/icon/warning.png new file mode 100644 index 0000000..50330c0 Binary files /dev/null and b/public/assets/images/icon/warning.png differ diff --git a/public/assets/images/img-bg-parent.png b/public/assets/images/img-bg-parent.png new file mode 100644 index 0000000..89c2f37 Binary files /dev/null and b/public/assets/images/img-bg-parent.png differ diff --git a/public/assets/images/img_no_class.png b/public/assets/images/img_no_class.png new file mode 100644 index 0000000..3867b5b Binary files /dev/null and b/public/assets/images/img_no_class.png differ diff --git a/public/assets/images/img_no_class_big.png b/public/assets/images/img_no_class_big.png new file mode 100644 index 0000000..cdfe55c Binary files /dev/null and b/public/assets/images/img_no_class_big.png differ diff --git a/public/assets/images/introNews/banner_1.png b/public/assets/images/introNews/banner_1.png new file mode 100644 index 0000000..575b7ce Binary files /dev/null and b/public/assets/images/introNews/banner_1.png differ diff --git a/public/assets/images/introNews/bg_content_1.png b/public/assets/images/introNews/bg_content_1.png new file mode 100644 index 0000000..1b5dfa6 Binary files /dev/null and b/public/assets/images/introNews/bg_content_1.png differ diff --git a/public/assets/images/introNews/bg_content_1_mobile.png b/public/assets/images/introNews/bg_content_1_mobile.png new file mode 100644 index 0000000..9d038db Binary files /dev/null and b/public/assets/images/introNews/bg_content_1_mobile.png differ diff --git a/public/assets/images/introNews/icon/ico_mission_1.png b/public/assets/images/introNews/icon/ico_mission_1.png new file mode 100644 index 0000000..959624a Binary files /dev/null and b/public/assets/images/introNews/icon/ico_mission_1.png differ diff --git a/public/assets/images/introNews/icon/ico_mission_2.png b/public/assets/images/introNews/icon/ico_mission_2.png new file mode 100644 index 0000000..88cf73a Binary files /dev/null and b/public/assets/images/introNews/icon/ico_mission_2.png differ diff --git a/public/assets/images/introNews/icon/ico_mission_3.png b/public/assets/images/introNews/icon/ico_mission_3.png new file mode 100644 index 0000000..a09d1b5 Binary files /dev/null and b/public/assets/images/introNews/icon/ico_mission_3.png differ diff --git a/public/assets/images/introNews/icon/ico_mission_4.png b/public/assets/images/introNews/icon/ico_mission_4.png new file mode 100644 index 0000000..383750d Binary files /dev/null and b/public/assets/images/introNews/icon/ico_mission_4.png differ diff --git a/public/assets/images/introNews/icon/ico_rule_1.png b/public/assets/images/introNews/icon/ico_rule_1.png new file mode 100644 index 0000000..9dd4693 Binary files /dev/null and b/public/assets/images/introNews/icon/ico_rule_1.png differ diff --git a/public/assets/images/introNews/icon/ico_rule_2.png b/public/assets/images/introNews/icon/ico_rule_2.png new file mode 100644 index 0000000..d7eec21 Binary files /dev/null and b/public/assets/images/introNews/icon/ico_rule_2.png differ diff --git a/public/assets/images/introNews/icon/ico_rule_3.png b/public/assets/images/introNews/icon/ico_rule_3.png new file mode 100644 index 0000000..77cb571 Binary files /dev/null and b/public/assets/images/introNews/icon/ico_rule_3.png differ diff --git a/public/assets/images/introNews/icon/ico_rule_4.png b/public/assets/images/introNews/icon/ico_rule_4.png new file mode 100644 index 0000000..4bf1a49 Binary files /dev/null and b/public/assets/images/introNews/icon/ico_rule_4.png differ diff --git a/public/assets/images/introNews/icon/ico_scholary_1.png b/public/assets/images/introNews/icon/ico_scholary_1.png new file mode 100644 index 0000000..095a8ff Binary files /dev/null and b/public/assets/images/introNews/icon/ico_scholary_1.png differ diff --git a/public/assets/images/introNews/icon/ico_scholary_2.png b/public/assets/images/introNews/icon/ico_scholary_2.png new file mode 100644 index 0000000..e00c1e7 Binary files /dev/null and b/public/assets/images/introNews/icon/ico_scholary_2.png differ diff --git a/public/assets/images/introNews/icon/ico_scholary_3.png b/public/assets/images/introNews/icon/ico_scholary_3.png new file mode 100644 index 0000000..c77a182 Binary files /dev/null and b/public/assets/images/introNews/icon/ico_scholary_3.png differ diff --git a/public/assets/images/introNews/icon/ico_scholary_4.png b/public/assets/images/introNews/icon/ico_scholary_4.png new file mode 100644 index 0000000..f7e4b20 Binary files /dev/null and b/public/assets/images/introNews/icon/ico_scholary_4.png differ diff --git a/public/assets/images/introNews/icon/ico_scholary_5.png b/public/assets/images/introNews/icon/ico_scholary_5.png new file mode 100644 index 0000000..d42efa9 Binary files /dev/null and b/public/assets/images/introNews/icon/ico_scholary_5.png differ diff --git a/public/assets/images/introNews/icon/img_cell_1_1.png b/public/assets/images/introNews/icon/img_cell_1_1.png new file mode 100644 index 0000000..5b3728f Binary files /dev/null and b/public/assets/images/introNews/icon/img_cell_1_1.png differ diff --git a/public/assets/images/introNews/icon/img_cell_1_2.png b/public/assets/images/introNews/icon/img_cell_1_2.png new file mode 100644 index 0000000..a2feac8 Binary files /dev/null and b/public/assets/images/introNews/icon/img_cell_1_2.png differ diff --git a/public/assets/images/introNews/icon/img_cell_1_3.png b/public/assets/images/introNews/icon/img_cell_1_3.png new file mode 100644 index 0000000..885b001 Binary files /dev/null and b/public/assets/images/introNews/icon/img_cell_1_3.png differ diff --git a/public/assets/images/introNews/icon/img_cell_2_1.png b/public/assets/images/introNews/icon/img_cell_2_1.png new file mode 100644 index 0000000..9887dc2 Binary files /dev/null and b/public/assets/images/introNews/icon/img_cell_2_1.png differ diff --git a/public/assets/images/introNews/icon/img_cell_2_2.png b/public/assets/images/introNews/icon/img_cell_2_2.png new file mode 100644 index 0000000..34e45eb Binary files /dev/null and b/public/assets/images/introNews/icon/img_cell_2_2.png differ diff --git a/public/assets/images/introNews/icon/img_cell_2_3.png b/public/assets/images/introNews/icon/img_cell_2_3.png new file mode 100644 index 0000000..f52d154 Binary files /dev/null and b/public/assets/images/introNews/icon/img_cell_2_3.png differ diff --git a/public/assets/images/introNews/icon/img_cell_2_4.png b/public/assets/images/introNews/icon/img_cell_2_4.png new file mode 100644 index 0000000..420229b Binary files /dev/null and b/public/assets/images/introNews/icon/img_cell_2_4.png differ diff --git a/public/assets/images/introNews/icon/img_title_1.png b/public/assets/images/introNews/icon/img_title_1.png new file mode 100644 index 0000000..1381c2c Binary files /dev/null and b/public/assets/images/introNews/icon/img_title_1.png differ diff --git a/public/assets/images/introNews/icon/img_title_1_mobile.png b/public/assets/images/introNews/icon/img_title_1_mobile.png new file mode 100644 index 0000000..704cc12 Binary files /dev/null and b/public/assets/images/introNews/icon/img_title_1_mobile.png differ diff --git a/public/assets/images/introNews/icon/img_title_2.png b/public/assets/images/introNews/icon/img_title_2.png new file mode 100644 index 0000000..2ba68d3 Binary files /dev/null and b/public/assets/images/introNews/icon/img_title_2.png differ diff --git a/public/assets/images/introNews/icon/img_title_2_mobile.png b/public/assets/images/introNews/icon/img_title_2_mobile.png new file mode 100644 index 0000000..cdfc9af Binary files /dev/null and b/public/assets/images/introNews/icon/img_title_2_mobile.png differ diff --git a/public/assets/images/introNews/icon/img_title_3.png b/public/assets/images/introNews/icon/img_title_3.png new file mode 100644 index 0000000..5cccadc Binary files /dev/null and b/public/assets/images/introNews/icon/img_title_3.png differ diff --git a/public/assets/images/introNews/icon/img_title_3_mobile.png b/public/assets/images/introNews/icon/img_title_3_mobile.png new file mode 100644 index 0000000..9ea0209 Binary files /dev/null and b/public/assets/images/introNews/icon/img_title_3_mobile.png differ diff --git a/public/assets/images/introNews/icon/img_title_4.png b/public/assets/images/introNews/icon/img_title_4.png new file mode 100644 index 0000000..f8d301b Binary files /dev/null and b/public/assets/images/introNews/icon/img_title_4.png differ diff --git a/public/assets/images/introNews/icon/img_title_4_mobile.png b/public/assets/images/introNews/icon/img_title_4_mobile.png new file mode 100644 index 0000000..e4de377 Binary files /dev/null and b/public/assets/images/introNews/icon/img_title_4_mobile.png differ diff --git a/public/assets/images/introNews/icon/img_title_5.png b/public/assets/images/introNews/icon/img_title_5.png new file mode 100644 index 0000000..5615bc4 Binary files /dev/null and b/public/assets/images/introNews/icon/img_title_5.png differ diff --git a/public/assets/images/introNews/icon/img_title_5_mobile.png b/public/assets/images/introNews/icon/img_title_5_mobile.png new file mode 100644 index 0000000..48423dc Binary files /dev/null and b/public/assets/images/introNews/icon/img_title_5_mobile.png differ diff --git a/public/assets/images/introNews/img_banner_schoolary.png b/public/assets/images/introNews/img_banner_schoolary.png new file mode 100644 index 0000000..ebc9355 Binary files /dev/null and b/public/assets/images/introNews/img_banner_schoolary.png differ diff --git a/public/assets/images/introNews/img_left_bg.png b/public/assets/images/introNews/img_left_bg.png new file mode 100644 index 0000000..ca7c420 Binary files /dev/null and b/public/assets/images/introNews/img_left_bg.png differ diff --git a/public/assets/images/introNews/img_left_schoolary.png b/public/assets/images/introNews/img_left_schoolary.png new file mode 100644 index 0000000..6d6ceaa Binary files /dev/null and b/public/assets/images/introNews/img_left_schoolary.png differ diff --git a/public/assets/images/introNews/img_right_bg.png b/public/assets/images/introNews/img_right_bg.png new file mode 100644 index 0000000..1a8f1f3 Binary files /dev/null and b/public/assets/images/introNews/img_right_bg.png differ diff --git a/public/assets/images/introNews/img_right_schoolary.png b/public/assets/images/introNews/img_right_schoolary.png new file mode 100644 index 0000000..e61127e Binary files /dev/null and b/public/assets/images/introNews/img_right_schoolary.png differ diff --git a/public/assets/images/introNews/img_tree_intro.png b/public/assets/images/introNews/img_tree_intro.png new file mode 100644 index 0000000..81045ba Binary files /dev/null and b/public/assets/images/introNews/img_tree_intro.png differ diff --git a/public/assets/images/introNews/intro_banner.png b/public/assets/images/introNews/intro_banner.png new file mode 100644 index 0000000..0310e16 Binary files /dev/null and b/public/assets/images/introNews/intro_banner.png differ diff --git a/public/assets/images/introNews/intro_banner_mobile.png b/public/assets/images/introNews/intro_banner_mobile.png new file mode 100644 index 0000000..d45fe49 Binary files /dev/null and b/public/assets/images/introNews/intro_banner_mobile.png differ diff --git a/public/assets/images/introNews/title_intro.png b/public/assets/images/introNews/title_intro.png new file mode 100644 index 0000000..2a7674c Binary files /dev/null and b/public/assets/images/introNews/title_intro.png differ diff --git a/public/assets/images/license/ico_package_actived.png b/public/assets/images/license/ico_package_actived.png new file mode 100644 index 0000000..72383c0 Binary files /dev/null and b/public/assets/images/license/ico_package_actived.png differ diff --git a/public/assets/images/license/ico_package_failed.png b/public/assets/images/license/ico_package_failed.png new file mode 100644 index 0000000..5044348 Binary files /dev/null and b/public/assets/images/license/ico_package_failed.png differ diff --git a/public/assets/images/license/ico_package_gan.png b/public/assets/images/license/ico_package_gan.png new file mode 100644 index 0000000..19c357a Binary files /dev/null and b/public/assets/images/license/ico_package_gan.png differ diff --git a/public/assets/images/license/ico_package_pay.png b/public/assets/images/license/ico_package_pay.png new file mode 100644 index 0000000..83c1d77 Binary files /dev/null and b/public/assets/images/license/ico_package_pay.png differ diff --git a/public/assets/images/license/img_package.png b/public/assets/images/license/img_package.png new file mode 100644 index 0000000..ea3301f Binary files /dev/null and b/public/assets/images/license/img_package.png differ diff --git a/public/assets/images/license/no_payment.png b/public/assets/images/license/no_payment.png new file mode 100644 index 0000000..dd0bc32 Binary files /dev/null and b/public/assets/images/license/no_payment.png differ diff --git a/public/assets/images/logo.png b/public/assets/images/logo.png new file mode 100644 index 0000000..a9b1eca Binary files /dev/null and b/public/assets/images/logo.png differ diff --git a/public/assets/images/logo_S.png b/public/assets/images/logo_S.png new file mode 100644 index 0000000..4004094 Binary files /dev/null and b/public/assets/images/logo_S.png differ diff --git a/public/assets/images/logo_TS.png b/public/assets/images/logo_TS.png new file mode 100644 index 0000000..5a15c83 Binary files /dev/null and b/public/assets/images/logo_TS.png differ diff --git a/public/assets/images/logo_home.png b/public/assets/images/logo_home.png new file mode 100644 index 0000000..da6032b Binary files /dev/null and b/public/assets/images/logo_home.png differ diff --git a/public/assets/images/logo_se_parent.png b/public/assets/images/logo_se_parent.png new file mode 100644 index 0000000..a4e65b8 Binary files /dev/null and b/public/assets/images/logo_se_parent.png differ diff --git a/public/assets/images/logo_se_student.png b/public/assets/images/logo_se_student.png new file mode 100644 index 0000000..53221f3 Binary files /dev/null and b/public/assets/images/logo_se_student.png differ diff --git a/public/assets/images/logo_se_teacher.png b/public/assets/images/logo_se_teacher.png new file mode 100644 index 0000000..2390336 Binary files /dev/null and b/public/assets/images/logo_se_teacher.png differ diff --git a/public/assets/images/logo_white.png b/public/assets/images/logo_white.png new file mode 100644 index 0000000..55d5ac2 Binary files /dev/null and b/public/assets/images/logo_white.png differ diff --git a/public/assets/images/luyenthi/ico-backthi.png b/public/assets/images/luyenthi/ico-backthi.png new file mode 100644 index 0000000..b32a36f Binary files /dev/null and b/public/assets/images/luyenthi/ico-backthi.png differ diff --git a/public/assets/images/luyenthi/ico-checkboxanh.png b/public/assets/images/luyenthi/ico-checkboxanh.png new file mode 100644 index 0000000..8d5f514 Binary files /dev/null and b/public/assets/images/luyenthi/ico-checkboxanh.png differ diff --git a/public/assets/images/luyenthi/ico-expand.png b/public/assets/images/luyenthi/ico-expand.png new file mode 100644 index 0000000..182b850 Binary files /dev/null and b/public/assets/images/luyenthi/ico-expand.png differ diff --git a/public/assets/images/luyenthi/ico-history.png b/public/assets/images/luyenthi/ico-history.png new file mode 100644 index 0000000..41f9cef Binary files /dev/null and b/public/assets/images/luyenthi/ico-history.png differ diff --git a/public/assets/images/luyenthi/ico-nextthi.png b/public/assets/images/luyenthi/ico-nextthi.png new file mode 100644 index 0000000..15ce58d Binary files /dev/null and b/public/assets/images/luyenthi/ico-nextthi.png differ diff --git a/public/assets/images/luyenthi/ico-radioanh.png b/public/assets/images/luyenthi/ico-radioanh.png new file mode 100644 index 0000000..958cbea Binary files /dev/null and b/public/assets/images/luyenthi/ico-radioanh.png differ diff --git a/public/assets/images/luyenthi/ico-textboxthi.png b/public/assets/images/luyenthi/ico-textboxthi.png new file mode 100644 index 0000000..7632a82 Binary files /dev/null and b/public/assets/images/luyenthi/ico-textboxthi.png differ diff --git a/public/assets/images/luyenthi/ico-uncheckedBox.png b/public/assets/images/luyenthi/ico-uncheckedBox.png new file mode 100644 index 0000000..d868bd5 Binary files /dev/null and b/public/assets/images/luyenthi/ico-uncheckedBox.png differ diff --git a/public/assets/images/luyenthi/ico-unit-test.png b/public/assets/images/luyenthi/ico-unit-test.png new file mode 100644 index 0000000..73090d7 Binary files /dev/null and b/public/assets/images/luyenthi/ico-unit-test.png differ diff --git a/public/assets/images/mockTestNews/achievement.png b/public/assets/images/mockTestNews/achievement.png new file mode 100644 index 0000000..821c8bd Binary files /dev/null and b/public/assets/images/mockTestNews/achievement.png differ diff --git a/public/assets/images/mockTestNews/banner.png b/public/assets/images/mockTestNews/banner.png new file mode 100644 index 0000000..66581b8 Binary files /dev/null and b/public/assets/images/mockTestNews/banner.png differ diff --git a/public/assets/images/mockTestNews/banner_mobile.png b/public/assets/images/mockTestNews/banner_mobile.png new file mode 100644 index 0000000..a3c27e6 Binary files /dev/null and b/public/assets/images/mockTestNews/banner_mobile.png differ diff --git a/public/assets/images/mockTestNews/ico_filter.png b/public/assets/images/mockTestNews/ico_filter.png new file mode 100644 index 0000000..cd7e6a9 Binary files /dev/null and b/public/assets/images/mockTestNews/ico_filter.png differ diff --git a/public/assets/images/mockTestNews/ico_filter_done.png b/public/assets/images/mockTestNews/ico_filter_done.png new file mode 100644 index 0000000..016d15d Binary files /dev/null and b/public/assets/images/mockTestNews/ico_filter_done.png differ diff --git a/public/assets/images/no_payment.jpg b/public/assets/images/no_payment.jpg new file mode 100644 index 0000000..6eeab88 Binary files /dev/null and b/public/assets/images/no_payment.jpg differ diff --git a/public/assets/images/no_payment.png b/public/assets/images/no_payment.png new file mode 100644 index 0000000..dd0bc32 Binary files /dev/null and b/public/assets/images/no_payment.png differ diff --git a/public/assets/images/no_plan.png b/public/assets/images/no_plan.png new file mode 100644 index 0000000..5b5e1ff Binary files /dev/null and b/public/assets/images/no_plan.png differ diff --git a/public/assets/images/no_plan_2.png b/public/assets/images/no_plan_2.png new file mode 100644 index 0000000..fa7209f Binary files /dev/null and b/public/assets/images/no_plan_2.png differ diff --git a/public/assets/images/process/ico_pro_0.png b/public/assets/images/process/ico_pro_0.png new file mode 100644 index 0000000..8fbee9b Binary files /dev/null and b/public/assets/images/process/ico_pro_0.png differ diff --git a/public/assets/images/process/ico_pro_10.png b/public/assets/images/process/ico_pro_10.png new file mode 100644 index 0000000..decfaf6 Binary files /dev/null and b/public/assets/images/process/ico_pro_10.png differ diff --git a/public/assets/images/process/ico_pro_100_sub.png b/public/assets/images/process/ico_pro_100_sub.png new file mode 100644 index 0000000..4e16424 Binary files /dev/null and b/public/assets/images/process/ico_pro_100_sub.png differ diff --git a/public/assets/images/process/ico_pro_100_suc.png b/public/assets/images/process/ico_pro_100_suc.png new file mode 100644 index 0000000..4e16424 Binary files /dev/null and b/public/assets/images/process/ico_pro_100_suc.png differ diff --git a/public/assets/images/process/ico_pro_20.png b/public/assets/images/process/ico_pro_20.png new file mode 100644 index 0000000..224283c Binary files /dev/null and b/public/assets/images/process/ico_pro_20.png differ diff --git a/public/assets/images/process/ico_pro_30.png b/public/assets/images/process/ico_pro_30.png new file mode 100644 index 0000000..0bbb0a9 Binary files /dev/null and b/public/assets/images/process/ico_pro_30.png differ diff --git a/public/assets/images/process/ico_pro_40.png b/public/assets/images/process/ico_pro_40.png new file mode 100644 index 0000000..4fd3dbf Binary files /dev/null and b/public/assets/images/process/ico_pro_40.png differ diff --git a/public/assets/images/process/ico_pro_50.png b/public/assets/images/process/ico_pro_50.png new file mode 100644 index 0000000..9bcc311 Binary files /dev/null and b/public/assets/images/process/ico_pro_50.png differ diff --git a/public/assets/images/process/ico_pro_60.png b/public/assets/images/process/ico_pro_60.png new file mode 100644 index 0000000..f93bbad Binary files /dev/null and b/public/assets/images/process/ico_pro_60.png differ diff --git a/public/assets/images/process/ico_pro_70.png b/public/assets/images/process/ico_pro_70.png new file mode 100644 index 0000000..c1c0cac Binary files /dev/null and b/public/assets/images/process/ico_pro_70.png differ diff --git a/public/assets/images/process/ico_pro_80.png b/public/assets/images/process/ico_pro_80.png new file mode 100644 index 0000000..6b31edd Binary files /dev/null and b/public/assets/images/process/ico_pro_80.png differ diff --git a/public/assets/images/process/ico_pro_90.png b/public/assets/images/process/ico_pro_90.png new file mode 100644 index 0000000..4001037 Binary files /dev/null and b/public/assets/images/process/ico_pro_90.png differ diff --git a/public/assets/images/process/ico_pro_check.png b/public/assets/images/process/ico_pro_check.png new file mode 100644 index 0000000..57d6a67 Binary files /dev/null and b/public/assets/images/process/ico_pro_check.png differ diff --git a/public/assets/images/process/ico_pro_lock.png b/public/assets/images/process/ico_pro_lock.png new file mode 100644 index 0000000..d55adbc Binary files /dev/null and b/public/assets/images/process/ico_pro_lock.png differ diff --git a/public/assets/images/rootlessnessCourse/Giao_trinh_co_ban.png b/public/assets/images/rootlessnessCourse/Giao_trinh_co_ban.png new file mode 100644 index 0000000..05c047d Binary files /dev/null and b/public/assets/images/rootlessnessCourse/Giao_trinh_co_ban.png differ diff --git a/public/assets/images/rootlessnessCourse/Giao_trinh_mat_goc.png b/public/assets/images/rootlessnessCourse/Giao_trinh_mat_goc.png new file mode 100644 index 0000000..a4ea7be Binary files /dev/null and b/public/assets/images/rootlessnessCourse/Giao_trinh_mat_goc.png differ diff --git a/public/assets/images/rootlessnessCourse/Starfish_mark.png b/public/assets/images/rootlessnessCourse/Starfish_mark.png new file mode 100644 index 0000000..ff68a9e Binary files /dev/null and b/public/assets/images/rootlessnessCourse/Starfish_mark.png differ diff --git a/public/assets/images/rootlessnessCourse/active_btn_circle_choose_schedule.png b/public/assets/images/rootlessnessCourse/active_btn_circle_choose_schedule.png new file mode 100644 index 0000000..64b0f24 Binary files /dev/null and b/public/assets/images/rootlessnessCourse/active_btn_circle_choose_schedule.png differ diff --git a/public/assets/images/rootlessnessCourse/bg-first_step.png b/public/assets/images/rootlessnessCourse/bg-first_step.png new file mode 100644 index 0000000..24e5866 Binary files /dev/null and b/public/assets/images/rootlessnessCourse/bg-first_step.png differ diff --git a/public/assets/images/rootlessnessCourse/bg_first_step.png b/public/assets/images/rootlessnessCourse/bg_first_step.png new file mode 100644 index 0000000..0513df4 Binary files /dev/null and b/public/assets/images/rootlessnessCourse/bg_first_step.png differ diff --git a/public/assets/images/rootlessnessCourse/bg_result_placement_test.png b/public/assets/images/rootlessnessCourse/bg_result_placement_test.png new file mode 100644 index 0000000..9061530 Binary files /dev/null and b/public/assets/images/rootlessnessCourse/bg_result_placement_test.png differ diff --git a/public/assets/images/rootlessnessCourse/btn_circle_choose_schedule.png b/public/assets/images/rootlessnessCourse/btn_circle_choose_schedule.png new file mode 100644 index 0000000..6ba94b9 Binary files /dev/null and b/public/assets/images/rootlessnessCourse/btn_circle_choose_schedule.png differ diff --git a/public/assets/images/rootlessnessCourse/finish_study_schedule.png b/public/assets/images/rootlessnessCourse/finish_study_schedule.png new file mode 100644 index 0000000..0ab7c66 Binary files /dev/null and b/public/assets/images/rootlessnessCourse/finish_study_schedule.png differ diff --git a/public/assets/images/rootlessnessCourse/line_result.svg b/public/assets/images/rootlessnessCourse/line_result.svg new file mode 100644 index 0000000..0b281fd --- /dev/null +++ b/public/assets/images/rootlessnessCourse/line_result.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/images/rootlessnessCourse/list_courses_student.png b/public/assets/images/rootlessnessCourse/list_courses_student.png new file mode 100644 index 0000000..8dcaf49 Binary files /dev/null and b/public/assets/images/rootlessnessCourse/list_courses_student.png differ diff --git a/public/assets/images/rootlessnessCourse/new_logo_se.png b/public/assets/images/rootlessnessCourse/new_logo_se.png new file mode 100644 index 0000000..96b5497 Binary files /dev/null and b/public/assets/images/rootlessnessCourse/new_logo_se.png differ diff --git a/public/assets/images/rootlessnessCourse/question_result.png b/public/assets/images/rootlessnessCourse/question_result.png new file mode 100644 index 0000000..c99cbdc Binary files /dev/null and b/public/assets/images/rootlessnessCourse/question_result.png differ diff --git a/public/assets/images/rootlessnessCourse/time_result.png b/public/assets/images/rootlessnessCourse/time_result.png new file mode 100644 index 0000000..2b52b80 Binary files /dev/null and b/public/assets/images/rootlessnessCourse/time_result.png differ diff --git a/public/assets/images/setting/bg_gioithieu.png b/public/assets/images/setting/bg_gioithieu.png new file mode 100644 index 0000000..23fdc91 Binary files /dev/null and b/public/assets/images/setting/bg_gioithieu.png differ diff --git a/public/assets/images/setting/bg_gt_full.png b/public/assets/images/setting/bg_gt_full.png new file mode 100644 index 0000000..ecba0ac Binary files /dev/null and b/public/assets/images/setting/bg_gt_full.png differ diff --git a/public/assets/images/setting/ico_dropright_blue.png b/public/assets/images/setting/ico_dropright_blue.png new file mode 100644 index 0000000..329bcf5 Binary files /dev/null and b/public/assets/images/setting/ico_dropright_blue.png differ diff --git a/public/assets/images/setting/ico_email.png b/public/assets/images/setting/ico_email.png new file mode 100644 index 0000000..eca50d7 Binary files /dev/null and b/public/assets/images/setting/ico_email.png differ diff --git a/public/assets/images/setting/ico_eye.png b/public/assets/images/setting/ico_eye.png new file mode 100644 index 0000000..9cf30f2 Binary files /dev/null and b/public/assets/images/setting/ico_eye.png differ diff --git a/public/assets/images/setting/ico_group.png b/public/assets/images/setting/ico_group.png new file mode 100644 index 0000000..e0d3117 Binary files /dev/null and b/public/assets/images/setting/ico_group.png differ diff --git a/public/assets/images/setting/ico_map.png b/public/assets/images/setting/ico_map.png new file mode 100644 index 0000000..0f926a2 Binary files /dev/null and b/public/assets/images/setting/ico_map.png differ diff --git a/public/assets/images/setting/ico_password.png b/public/assets/images/setting/ico_password.png new file mode 100644 index 0000000..36c9a5d Binary files /dev/null and b/public/assets/images/setting/ico_password.png differ diff --git a/public/assets/images/setting/ico_phone.png b/public/assets/images/setting/ico_phone.png new file mode 100644 index 0000000..28f956f Binary files /dev/null and b/public/assets/images/setting/ico_phone.png differ diff --git a/public/assets/images/setting/ico_support.png b/public/assets/images/setting/ico_support.png new file mode 100644 index 0000000..18cb618 Binary files /dev/null and b/public/assets/images/setting/ico_support.png differ diff --git a/public/assets/images/setting/ico_visibility.png b/public/assets/images/setting/ico_visibility.png new file mode 100644 index 0000000..8df2d7f Binary files /dev/null and b/public/assets/images/setting/ico_visibility.png differ diff --git a/public/assets/images/setting/ico_warning.png b/public/assets/images/setting/ico_warning.png new file mode 100644 index 0000000..f66b163 Binary files /dev/null and b/public/assets/images/setting/ico_warning.png differ diff --git a/public/assets/images/student/Map-skill-final.png b/public/assets/images/student/Map-skill-final.png new file mode 100644 index 0000000..0e3815e Binary files /dev/null and b/public/assets/images/student/Map-skill-final.png differ diff --git a/public/assets/images/student/bg_edit_student_profile.png b/public/assets/images/student/bg_edit_student_profile.png new file mode 100644 index 0000000..59fda1f Binary files /dev/null and b/public/assets/images/student/bg_edit_student_profile.png differ diff --git a/public/assets/images/student/bg_no_homework.png b/public/assets/images/student/bg_no_homework.png new file mode 100644 index 0000000..827fa3b Binary files /dev/null and b/public/assets/images/student/bg_no_homework.png differ diff --git a/public/assets/images/student/bg_student_index.png b/public/assets/images/student/bg_student_index.png new file mode 100644 index 0000000..32171fd Binary files /dev/null and b/public/assets/images/student/bg_student_index.png differ diff --git a/public/assets/images/student/home/exam.png b/public/assets/images/student/home/exam.png new file mode 100644 index 0000000..1462882 Binary files /dev/null and b/public/assets/images/student/home/exam.png differ diff --git a/public/assets/images/student/home/grammar.png b/public/assets/images/student/home/grammar.png new file mode 100644 index 0000000..69fa4fb Binary files /dev/null and b/public/assets/images/student/home/grammar.png differ diff --git a/public/assets/images/student/home/ico_check.png b/public/assets/images/student/home/ico_check.png new file mode 100644 index 0000000..91f47d8 Binary files /dev/null and b/public/assets/images/student/home/ico_check.png differ diff --git a/public/assets/images/student/home/ico_lock.png b/public/assets/images/student/home/ico_lock.png new file mode 100644 index 0000000..d667364 Binary files /dev/null and b/public/assets/images/student/home/ico_lock.png differ diff --git a/public/assets/images/student/home/listening.png b/public/assets/images/student/home/listening.png new file mode 100644 index 0000000..98ad40c Binary files /dev/null and b/public/assets/images/student/home/listening.png differ diff --git a/public/assets/images/student/home/mini_test.png b/public/assets/images/student/home/mini_test.png new file mode 100644 index 0000000..1462882 Binary files /dev/null and b/public/assets/images/student/home/mini_test.png differ diff --git a/public/assets/images/student/home/project.png b/public/assets/images/student/home/project.png new file mode 100644 index 0000000..48ee1b0 Binary files /dev/null and b/public/assets/images/student/home/project.png differ diff --git a/public/assets/images/student/home/prononuciation.png b/public/assets/images/student/home/prononuciation.png new file mode 100644 index 0000000..98c0914 Binary files /dev/null and b/public/assets/images/student/home/prononuciation.png differ diff --git a/public/assets/images/student/home/pronunciation.png b/public/assets/images/student/home/pronunciation.png new file mode 100644 index 0000000..98c0914 Binary files /dev/null and b/public/assets/images/student/home/pronunciation.png differ diff --git a/public/assets/images/student/home/reading.png b/public/assets/images/student/home/reading.png new file mode 100644 index 0000000..3d2bb7b Binary files /dev/null and b/public/assets/images/student/home/reading.png differ diff --git a/public/assets/images/student/home/speaking.png b/public/assets/images/student/home/speaking.png new file mode 100644 index 0000000..f684a94 Binary files /dev/null and b/public/assets/images/student/home/speaking.png differ diff --git a/public/assets/images/student/home/vocab.png b/public/assets/images/student/home/vocab.png new file mode 100644 index 0000000..9f69b78 Binary files /dev/null and b/public/assets/images/student/home/vocab.png differ diff --git a/public/assets/images/student/home/vocabulary.png b/public/assets/images/student/home/vocabulary.png new file mode 100644 index 0000000..9f69b78 Binary files /dev/null and b/public/assets/images/student/home/vocabulary.png differ diff --git a/public/assets/images/student/home/writing.png b/public/assets/images/student/home/writing.png new file mode 100644 index 0000000..6199a1c Binary files /dev/null and b/public/assets/images/student/home/writing.png differ diff --git a/public/assets/images/student/homeworkdone/exam.png b/public/assets/images/student/homeworkdone/exam.png new file mode 100644 index 0000000..e112e5a Binary files /dev/null and b/public/assets/images/student/homeworkdone/exam.png differ diff --git a/public/assets/images/student/homeworkdone/grammar.png b/public/assets/images/student/homeworkdone/grammar.png new file mode 100644 index 0000000..27eb99f Binary files /dev/null and b/public/assets/images/student/homeworkdone/grammar.png differ diff --git a/public/assets/images/student/homeworkdone/listening.png b/public/assets/images/student/homeworkdone/listening.png new file mode 100644 index 0000000..353eff5 Binary files /dev/null and b/public/assets/images/student/homeworkdone/listening.png differ diff --git a/public/assets/images/student/homeworkdone/mini_test.png b/public/assets/images/student/homeworkdone/mini_test.png new file mode 100644 index 0000000..e112e5a Binary files /dev/null and b/public/assets/images/student/homeworkdone/mini_test.png differ diff --git a/public/assets/images/student/homeworkdone/project.png b/public/assets/images/student/homeworkdone/project.png new file mode 100644 index 0000000..5e8e330 Binary files /dev/null and b/public/assets/images/student/homeworkdone/project.png differ diff --git a/public/assets/images/student/homeworkdone/prononuciation.png b/public/assets/images/student/homeworkdone/prononuciation.png new file mode 100644 index 0000000..91e3b88 Binary files /dev/null and b/public/assets/images/student/homeworkdone/prononuciation.png differ diff --git a/public/assets/images/student/homeworkdone/pronunciation.png b/public/assets/images/student/homeworkdone/pronunciation.png new file mode 100644 index 0000000..91e3b88 Binary files /dev/null and b/public/assets/images/student/homeworkdone/pronunciation.png differ diff --git a/public/assets/images/student/homeworkdone/reading.png b/public/assets/images/student/homeworkdone/reading.png new file mode 100644 index 0000000..84fa975 Binary files /dev/null and b/public/assets/images/student/homeworkdone/reading.png differ diff --git a/public/assets/images/student/homeworkdone/speaking.png b/public/assets/images/student/homeworkdone/speaking.png new file mode 100644 index 0000000..d6a0a77 Binary files /dev/null and b/public/assets/images/student/homeworkdone/speaking.png differ diff --git a/public/assets/images/student/homeworkdone/vocab.png b/public/assets/images/student/homeworkdone/vocab.png new file mode 100644 index 0000000..d65487e Binary files /dev/null and b/public/assets/images/student/homeworkdone/vocab.png differ diff --git a/public/assets/images/student/homeworkdone/vocabulary.png b/public/assets/images/student/homeworkdone/vocabulary.png new file mode 100644 index 0000000..d65487e Binary files /dev/null and b/public/assets/images/student/homeworkdone/vocabulary.png differ diff --git a/public/assets/images/student/homeworkdone/writing.png b/public/assets/images/student/homeworkdone/writing.png new file mode 100644 index 0000000..39e882e Binary files /dev/null and b/public/assets/images/student/homeworkdone/writing.png differ diff --git a/public/assets/images/student/ico_add_blue.png b/public/assets/images/student/ico_add_blue.png new file mode 100644 index 0000000..e31a8c7 Binary files /dev/null and b/public/assets/images/student/ico_add_blue.png differ diff --git a/public/assets/images/student/ico_add_ph.png b/public/assets/images/student/ico_add_ph.png new file mode 100644 index 0000000..f2c4580 Binary files /dev/null and b/public/assets/images/student/ico_add_ph.png differ diff --git a/public/assets/images/student/ico_add_small.png b/public/assets/images/student/ico_add_small.png new file mode 100644 index 0000000..15375cf Binary files /dev/null and b/public/assets/images/student/ico_add_small.png differ diff --git a/public/assets/images/student/ico_baitap.png b/public/assets/images/student/ico_baitap.png new file mode 100644 index 0000000..2c67bdf Binary files /dev/null and b/public/assets/images/student/ico_baitap.png differ diff --git a/public/assets/images/student/ico_bar_grid.png b/public/assets/images/student/ico_bar_grid.png new file mode 100644 index 0000000..89aac35 Binary files /dev/null and b/public/assets/images/student/ico_bar_grid.png differ diff --git a/public/assets/images/student/ico_check_pink.png b/public/assets/images/student/ico_check_pink.png new file mode 100644 index 0000000..8bee154 Binary files /dev/null and b/public/assets/images/student/ico_check_pink.png differ diff --git a/public/assets/images/student/ico_checked_white.png b/public/assets/images/student/ico_checked_white.png new file mode 100644 index 0000000..52a5001 Binary files /dev/null and b/public/assets/images/student/ico_checked_white.png differ diff --git a/public/assets/images/student/ico_class.png b/public/assets/images/student/ico_class.png new file mode 100644 index 0000000..46aaccf Binary files /dev/null and b/public/assets/images/student/ico_class.png differ diff --git a/public/assets/images/student/ico_class_gr.png b/public/assets/images/student/ico_class_gr.png new file mode 100644 index 0000000..f244536 Binary files /dev/null and b/public/assets/images/student/ico_class_gr.png differ diff --git a/public/assets/images/student/ico_dropdown_blue.png b/public/assets/images/student/ico_dropdown_blue.png new file mode 100644 index 0000000..edee83d Binary files /dev/null and b/public/assets/images/student/ico_dropdown_blue.png differ diff --git a/public/assets/images/student/ico_dropup_blue.png b/public/assets/images/student/ico_dropup_blue.png new file mode 100644 index 0000000..ca2f058 Binary files /dev/null and b/public/assets/images/student/ico_dropup_blue.png differ diff --git a/public/assets/images/student/ico_edit_profile.png b/public/assets/images/student/ico_edit_profile.png new file mode 100644 index 0000000..dd251e5 Binary files /dev/null and b/public/assets/images/student/ico_edit_profile.png differ diff --git a/public/assets/images/student/ico_listening_large.png b/public/assets/images/student/ico_listening_large.png new file mode 100644 index 0000000..c1c71cd Binary files /dev/null and b/public/assets/images/student/ico_listening_large.png differ diff --git a/public/assets/images/student/ico_listening_medium.png b/public/assets/images/student/ico_listening_medium.png new file mode 100644 index 0000000..e4c80be Binary files /dev/null and b/public/assets/images/student/ico_listening_medium.png differ diff --git a/public/assets/images/student/ico_lock_pink.png b/public/assets/images/student/ico_lock_pink.png new file mode 100644 index 0000000..dcb8d05 Binary files /dev/null and b/public/assets/images/student/ico_lock_pink.png differ diff --git a/public/assets/images/student/ico_lock_white.png b/public/assets/images/student/ico_lock_white.png new file mode 100644 index 0000000..1acbcac Binary files /dev/null and b/public/assets/images/student/ico_lock_white.png differ diff --git a/public/assets/images/student/ico_sale_pink.png b/public/assets/images/student/ico_sale_pink.png new file mode 100644 index 0000000..67dc84d Binary files /dev/null and b/public/assets/images/student/ico_sale_pink.png differ diff --git a/public/assets/images/student/ico_school.png b/public/assets/images/student/ico_school.png new file mode 100644 index 0000000..4380927 Binary files /dev/null and b/public/assets/images/student/ico_school.png differ diff --git a/public/assets/images/student/ico_star.png b/public/assets/images/student/ico_star.png new file mode 100644 index 0000000..c5f27ed Binary files /dev/null and b/public/assets/images/student/ico_star.png differ diff --git a/public/assets/images/student/ico_success.png b/public/assets/images/student/ico_success.png new file mode 100644 index 0000000..d2d8bfe Binary files /dev/null and b/public/assets/images/student/ico_success.png differ diff --git a/public/assets/images/student/ico_teacher.png b/public/assets/images/student/ico_teacher.png new file mode 100644 index 0000000..1586e4d Binary files /dev/null and b/public/assets/images/student/ico_teacher.png differ diff --git a/public/assets/images/student/ico_thanhtich.png b/public/assets/images/student/ico_thanhtich.png new file mode 100644 index 0000000..6c0e4e7 Binary files /dev/null and b/public/assets/images/student/ico_thanhtich.png differ diff --git a/public/assets/images/student/ico_thanhvien.png b/public/assets/images/student/ico_thanhvien.png new file mode 100644 index 0000000..a0716ce Binary files /dev/null and b/public/assets/images/student/ico_thanhvien.png differ diff --git a/public/assets/images/student/ico_thumb.png b/public/assets/images/student/ico_thumb.png new file mode 100644 index 0000000..891da0b Binary files /dev/null and b/public/assets/images/student/ico_thumb.png differ diff --git a/public/assets/images/student/ico_vinhdanh.png b/public/assets/images/student/ico_vinhdanh.png new file mode 100644 index 0000000..887544d Binary files /dev/null and b/public/assets/images/student/ico_vinhdanh.png differ diff --git a/public/assets/images/student/icon_star_default.png b/public/assets/images/student/icon_star_default.png new file mode 100644 index 0000000..7cf2baf Binary files /dev/null and b/public/assets/images/student/icon_star_default.png differ diff --git a/public/assets/images/student/line.png b/public/assets/images/student/line.png new file mode 100644 index 0000000..285f7e9 Binary files /dev/null and b/public/assets/images/student/line.png differ diff --git a/public/assets/images/student/more/ico_class.png b/public/assets/images/student/more/ico_class.png new file mode 100644 index 0000000..98b829a Binary files /dev/null and b/public/assets/images/student/more/ico_class.png differ diff --git a/public/assets/images/student/more/ico_hoso.png b/public/assets/images/student/more/ico_hoso.png new file mode 100644 index 0000000..fdb9c4c Binary files /dev/null and b/public/assets/images/student/more/ico_hoso.png differ diff --git a/public/assets/images/student/more/ico_kehoachhoctap.png b/public/assets/images/student/more/ico_kehoachhoctap.png new file mode 100644 index 0000000..5d4b486 Binary files /dev/null and b/public/assets/images/student/more/ico_kehoachhoctap.png differ diff --git a/public/assets/images/student/more/ico_lienket.png b/public/assets/images/student/more/ico_lienket.png new file mode 100644 index 0000000..a7b0e6d Binary files /dev/null and b/public/assets/images/student/more/ico_lienket.png differ diff --git a/public/assets/images/student/more/ico_setting.png b/public/assets/images/student/more/ico_setting.png new file mode 100644 index 0000000..77d08a1 Binary files /dev/null and b/public/assets/images/student/more/ico_setting.png differ diff --git a/public/assets/images/student/more/ico_tinnhan.png b/public/assets/images/student/more/ico_tinnhan.png new file mode 100644 index 0000000..0c348b1 Binary files /dev/null and b/public/assets/images/student/more/ico_tinnhan.png differ diff --git a/public/assets/images/student/more/ico_upgrade.png b/public/assets/images/student/more/ico_upgrade.png new file mode 100644 index 0000000..c2da9ee Binary files /dev/null and b/public/assets/images/student/more/ico_upgrade.png differ diff --git a/public/assets/images/student/popup_add_hs.png b/public/assets/images/student/popup_add_hs.png new file mode 100644 index 0000000..388d163 Binary files /dev/null and b/public/assets/images/student/popup_add_hs.png differ diff --git a/public/assets/images/student/sunE_detail.png b/public/assets/images/student/sunE_detail.png new file mode 100644 index 0000000..aa5fd0d Binary files /dev/null and b/public/assets/images/student/sunE_detail.png differ diff --git a/public/assets/images/student/teacher_detail.png b/public/assets/images/student/teacher_detail.png new file mode 100644 index 0000000..6b6f688 Binary files /dev/null and b/public/assets/images/student/teacher_detail.png differ diff --git a/public/assets/images/student/thanhtich/HongNgoc.png b/public/assets/images/student/thanhtich/HongNgoc.png new file mode 100644 index 0000000..bf57aed Binary files /dev/null and b/public/assets/images/student/thanhtich/HongNgoc.png differ diff --git a/public/assets/images/student/thanhtich/bg_top_tt.png b/public/assets/images/student/thanhtich/bg_top_tt.png new file mode 100644 index 0000000..9444209 Binary files /dev/null and b/public/assets/images/student/thanhtich/bg_top_tt.png differ diff --git a/public/assets/images/student/thanhtich/ico_avt.png b/public/assets/images/student/thanhtich/ico_avt.png new file mode 100644 index 0000000..876bd70 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_avt.png differ diff --git a/public/assets/images/student/thanhtich/ico_b.png b/public/assets/images/student/thanhtich/ico_b.png new file mode 100644 index 0000000..a8a2791 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_b.png differ diff --git a/public/assets/images/student/thanhtich/ico_book.png b/public/assets/images/student/thanhtich/ico_book.png new file mode 100644 index 0000000..224e5c9 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_book.png differ diff --git a/public/assets/images/student/thanhtich/ico_cancu.png b/public/assets/images/student/thanhtich/ico_cancu.png new file mode 100644 index 0000000..841641c Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_cancu.png differ diff --git a/public/assets/images/student/thanhtich/ico_chamchap.png b/public/assets/images/student/thanhtich/ico_chamchap.png new file mode 100644 index 0000000..8271f3c Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_chamchap.png differ diff --git a/public/assets/images/student/thanhtich/ico_chamchi.png b/public/assets/images/student/thanhtich/ico_chamchi.png new file mode 100644 index 0000000..c4a8f11 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_chamchi.png differ diff --git a/public/assets/images/student/thanhtich/ico_diemthi.png b/public/assets/images/student/thanhtich/ico_diemthi.png new file mode 100644 index 0000000..117a7ad Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_diemthi.png differ diff --git a/public/assets/images/student/thanhtich/ico_dimo.png b/public/assets/images/student/thanhtich/ico_dimo.png new file mode 100644 index 0000000..a5f6f63 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_dimo.png differ diff --git a/public/assets/images/student/thanhtich/ico_grammar.png b/public/assets/images/student/thanhtich/ico_grammar.png new file mode 100644 index 0000000..2499ecf Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_grammar.png differ diff --git a/public/assets/images/student/thanhtich/ico_hc.png b/public/assets/images/student/thanhtich/ico_hc.png new file mode 100644 index 0000000..83599f0 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_hc.png differ diff --git a/public/assets/images/student/thanhtich/ico_hcs.png b/public/assets/images/student/thanhtich/ico_hcs.png new file mode 100644 index 0000000..54cca90 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_hcs.png differ diff --git a/public/assets/images/student/thanhtich/ico_hsg.png b/public/assets/images/student/thanhtich/ico_hsg.png new file mode 100644 index 0000000..4bf78a5 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_hsg.png differ diff --git a/public/assets/images/student/thanhtich/ico_lb.png b/public/assets/images/student/thanhtich/ico_lb.png new file mode 100644 index 0000000..30d1d06 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_lb.png differ diff --git a/public/assets/images/student/thanhtich/ico_listening.png b/public/assets/images/student/thanhtich/ico_listening.png new file mode 100644 index 0000000..c01cf97 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_listening.png differ diff --git a/public/assets/images/student/thanhtich/ico_pl_lucbao.png b/public/assets/images/student/thanhtich/ico_pl_lucbao.png new file mode 100644 index 0000000..329656f Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_pl_lucbao.png differ diff --git a/public/assets/images/student/thanhtich/ico_reading.png b/public/assets/images/student/thanhtich/ico_reading.png new file mode 100644 index 0000000..dbf1920 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_reading.png differ diff --git a/public/assets/images/student/thanhtich/ico_s.png b/public/assets/images/student/thanhtich/ico_s.png new file mode 100644 index 0000000..ef9059a Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_s.png differ diff --git a/public/assets/images/student/thanhtich/ico_search.png b/public/assets/images/student/thanhtich/ico_search.png new file mode 100644 index 0000000..140846e Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_search.png differ diff --git a/public/assets/images/student/thanhtich/ico_speaking.png b/public/assets/images/student/thanhtich/ico_speaking.png new file mode 100644 index 0000000..a174fb0 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_speaking.png differ diff --git a/public/assets/images/student/thanhtich/ico_thanhtich_offline.png b/public/assets/images/student/thanhtich/ico_thanhtich_offline.png new file mode 100644 index 0000000..4c99251 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_thanhtich_offline.png differ diff --git a/public/assets/images/student/thanhtich/ico_thanhtich_offline_active.png b/public/assets/images/student/thanhtich/ico_thanhtich_offline_active.png new file mode 100644 index 0000000..e805f10 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_thanhtich_offline_active.png differ diff --git a/public/assets/images/student/thanhtich/ico_thanhtich_online.png b/public/assets/images/student/thanhtich/ico_thanhtich_online.png new file mode 100644 index 0000000..b877658 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_thanhtich_online.png differ diff --git a/public/assets/images/student/thanhtich/ico_thanhtich_online_active.png b/public/assets/images/student/thanhtich/ico_thanhtich_online_active.png new file mode 100644 index 0000000..7211c90 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_thanhtich_online_active.png differ diff --git a/public/assets/images/student/thanhtich/ico_v.png b/public/assets/images/student/thanhtich/ico_v.png new file mode 100644 index 0000000..69c87ac Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_v.png differ diff --git a/public/assets/images/student/thanhtich/ico_voice.png b/public/assets/images/student/thanhtich/ico_voice.png new file mode 100644 index 0000000..0d33dc0 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_voice.png differ diff --git a/public/assets/images/student/thanhtich/ico_writing.png b/public/assets/images/student/thanhtich/ico_writing.png new file mode 100644 index 0000000..9987834 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_writing.png differ diff --git a/public/assets/images/student/thanhtich/ico_xephang.png b/public/assets/images/student/thanhtich/ico_xephang.png new file mode 100644 index 0000000..f0a523d Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_xephang.png differ diff --git a/public/assets/images/student/thanhtich/ico_xephang_active.png b/public/assets/images/student/thanhtich/ico_xephang_active.png new file mode 100644 index 0000000..f623d73 Binary files /dev/null and b/public/assets/images/student/thanhtich/ico_xephang_active.png differ diff --git a/public/assets/images/student/thanhtich/img_no_item.png b/public/assets/images/student/thanhtich/img_no_item.png new file mode 100644 index 0000000..3c67581 Binary files /dev/null and b/public/assets/images/student/thanhtich/img_no_item.png differ diff --git a/public/assets/images/student/thanhtich/thumb.png b/public/assets/images/student/thanhtich/thumb.png new file mode 100644 index 0000000..e0b2d7e Binary files /dev/null and b/public/assets/images/student/thanhtich/thumb.png differ diff --git a/public/assets/images/teacher/baocao.png b/public/assets/images/teacher/baocao.png new file mode 100644 index 0000000..c951e24 Binary files /dev/null and b/public/assets/images/teacher/baocao.png differ diff --git a/public/assets/images/teacher/chambai.png b/public/assets/images/teacher/chambai.png new file mode 100644 index 0000000..363575c Binary files /dev/null and b/public/assets/images/teacher/chambai.png differ diff --git a/public/assets/images/teacher/chambai/ico_cham_bai.png b/public/assets/images/teacher/chambai/ico_cham_bai.png new file mode 100644 index 0000000..4a46d72 Binary files /dev/null and b/public/assets/images/teacher/chambai/ico_cham_bai.png differ diff --git a/public/assets/images/teacher/chambai/ico_help.png b/public/assets/images/teacher/chambai/ico_help.png new file mode 100644 index 0000000..aed7734 Binary files /dev/null and b/public/assets/images/teacher/chambai/ico_help.png differ diff --git a/public/assets/images/teacher/chambai/project_large.png b/public/assets/images/teacher/chambai/project_large.png new file mode 100644 index 0000000..aa6fd49 Binary files /dev/null and b/public/assets/images/teacher/chambai/project_large.png differ diff --git a/public/assets/images/teacher/chambai/project_small.png b/public/assets/images/teacher/chambai/project_small.png new file mode 100644 index 0000000..825ff11 Binary files /dev/null and b/public/assets/images/teacher/chambai/project_small.png differ diff --git a/public/assets/images/teacher/diemdanh.png b/public/assets/images/teacher/diemdanh.png new file mode 100644 index 0000000..dd3375d Binary files /dev/null and b/public/assets/images/teacher/diemdanh.png differ diff --git a/public/assets/images/teacher/diemdanh/bg_diemdanh_no_item.png b/public/assets/images/teacher/diemdanh/bg_diemdanh_no_item.png new file mode 100644 index 0000000..050d883 Binary files /dev/null and b/public/assets/images/teacher/diemdanh/bg_diemdanh_no_item.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_calender.png b/public/assets/images/teacher/diemdanh/ico_calender.png new file mode 100644 index 0000000..a926ced Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_calender.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_calender_blue.png b/public/assets/images/teacher/diemdanh/ico_calender_blue.png new file mode 100644 index 0000000..ad8ad46 Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_calender_blue.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_check_large.png b/public/assets/images/teacher/diemdanh/ico_check_large.png new file mode 100644 index 0000000..f1ae4c6 Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_check_large.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_checked.png b/public/assets/images/teacher/diemdanh/ico_checked.png new file mode 100644 index 0000000..a825f0f Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_checked.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_clock.png b/public/assets/images/teacher/diemdanh/ico_clock.png new file mode 100644 index 0000000..f1b7796 Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_clock.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_clock_orange.png b/public/assets/images/teacher/diemdanh/ico_clock_orange.png new file mode 100644 index 0000000..58b6adf Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_clock_orange.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_date.png b/public/assets/images/teacher/diemdanh/ico_date.png new file mode 100644 index 0000000..8c2050f Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_date.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_dropdown_blue.png b/public/assets/images/teacher/diemdanh/ico_dropdown_blue.png new file mode 100644 index 0000000..24078ac Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_dropdown_blue.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_dropdown_green.png b/public/assets/images/teacher/diemdanh/ico_dropdown_green.png new file mode 100644 index 0000000..a01ac5f Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_dropdown_green.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_dropdown_orange.png b/public/assets/images/teacher/diemdanh/ico_dropdown_orange.png new file mode 100644 index 0000000..752f7af Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_dropdown_orange.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_dropdown_red.png b/public/assets/images/teacher/diemdanh/ico_dropdown_red.png new file mode 100644 index 0000000..e6157b4 Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_dropdown_red.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_dropup_blue.png b/public/assets/images/teacher/diemdanh/ico_dropup_blue.png new file mode 100644 index 0000000..d217ddc Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_dropup_blue.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_luyenthiact.png b/public/assets/images/teacher/diemdanh/ico_luyenthiact.png new file mode 100644 index 0000000..e12077d Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_luyenthiact.png differ diff --git a/public/assets/images/teacher/diemdanh/ico_users.png b/public/assets/images/teacher/diemdanh/ico_users.png new file mode 100644 index 0000000..117f92a Binary files /dev/null and b/public/assets/images/teacher/diemdanh/ico_users.png differ diff --git a/public/assets/images/teacher/giaobai.png b/public/assets/images/teacher/giaobai.png new file mode 100644 index 0000000..869c1c0 Binary files /dev/null and b/public/assets/images/teacher/giaobai.png differ diff --git a/public/assets/images/teacher/giaobai/Group 6310.png b/public/assets/images/teacher/giaobai/Group 6310.png new file mode 100644 index 0000000..5dc8b69 Binary files /dev/null and b/public/assets/images/teacher/giaobai/Group 6310.png differ diff --git a/public/assets/images/teacher/giaobai/Nhac_nho.png b/public/assets/images/teacher/giaobai/Nhac_nho.png new file mode 100644 index 0000000..5a61b05 Binary files /dev/null and b/public/assets/images/teacher/giaobai/Nhac_nho.png differ diff --git a/public/assets/images/teacher/giaobai/bg_no_gb.png b/public/assets/images/teacher/giaobai/bg_no_gb.png new file mode 100644 index 0000000..ff3b1a3 Binary files /dev/null and b/public/assets/images/teacher/giaobai/bg_no_gb.png differ diff --git a/public/assets/images/teacher/giaobai/detail_small.png b/public/assets/images/teacher/giaobai/detail_small.png new file mode 100644 index 0000000..e1a8009 Binary files /dev/null and b/public/assets/images/teacher/giaobai/detail_small.png differ diff --git a/public/assets/images/teacher/giaobai/details.png b/public/assets/images/teacher/giaobai/details.png new file mode 100644 index 0000000..4772f76 Binary files /dev/null and b/public/assets/images/teacher/giaobai/details.png differ diff --git a/public/assets/images/teacher/giaobai/exam.png b/public/assets/images/teacher/giaobai/exam.png new file mode 100644 index 0000000..c61cea6 Binary files /dev/null and b/public/assets/images/teacher/giaobai/exam.png differ diff --git a/public/assets/images/teacher/giaobai/grammar.png b/public/assets/images/teacher/giaobai/grammar.png new file mode 100644 index 0000000..8a8eb8c Binary files /dev/null and b/public/assets/images/teacher/giaobai/grammar.png differ diff --git a/public/assets/images/teacher/giaobai/ico_audio.png b/public/assets/images/teacher/giaobai/ico_audio.png new file mode 100644 index 0000000..717b635 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_audio.png differ diff --git a/public/assets/images/teacher/giaobai/ico_book.png b/public/assets/images/teacher/giaobai/ico_book.png new file mode 100644 index 0000000..57adca5 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_book.png differ diff --git a/public/assets/images/teacher/giaobai/ico_capacity_assign.png b/public/assets/images/teacher/giaobai/ico_capacity_assign.png new file mode 100644 index 0000000..eecfe0a Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_capacity_assign.png differ diff --git a/public/assets/images/teacher/giaobai/ico_check.png b/public/assets/images/teacher/giaobai/ico_check.png new file mode 100644 index 0000000..e8f4bab Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_check.png differ diff --git a/public/assets/images/teacher/giaobai/ico_clock.png b/public/assets/images/teacher/giaobai/ico_clock.png new file mode 100644 index 0000000..c413599 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_clock.png differ diff --git a/public/assets/images/teacher/giaobai/ico_demand_assign.png b/public/assets/images/teacher/giaobai/ico_demand_assign.png new file mode 100644 index 0000000..5465ca2 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_demand_assign.png differ diff --git a/public/assets/images/teacher/giaobai/ico_doc.png b/public/assets/images/teacher/giaobai/ico_doc.png new file mode 100644 index 0000000..00f12a9 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_doc.png differ diff --git a/public/assets/images/teacher/giaobai/ico_document.png b/public/assets/images/teacher/giaobai/ico_document.png new file mode 100644 index 0000000..a13f9b0 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_document.png differ diff --git a/public/assets/images/teacher/giaobai/ico_excel.png b/public/assets/images/teacher/giaobai/ico_excel.png new file mode 100644 index 0000000..13126ec Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_excel.png differ diff --git a/public/assets/images/teacher/giaobai/ico_file.png b/public/assets/images/teacher/giaobai/ico_file.png new file mode 100644 index 0000000..acb912b Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_file.png differ diff --git a/public/assets/images/teacher/giaobai/ico_file_active.png b/public/assets/images/teacher/giaobai/ico_file_active.png new file mode 100644 index 0000000..9d3babe Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_file_active.png differ diff --git a/public/assets/images/teacher/giaobai/ico_filter.png b/public/assets/images/teacher/giaobai/ico_filter.png new file mode 100644 index 0000000..0abb870 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_filter.png differ diff --git a/public/assets/images/teacher/giaobai/ico_freedom_assign.png b/public/assets/images/teacher/giaobai/ico_freedom_assign.png new file mode 100644 index 0000000..c657fcf Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_freedom_assign.png differ diff --git a/public/assets/images/teacher/giaobai/ico_heart.png b/public/assets/images/teacher/giaobai/ico_heart.png new file mode 100644 index 0000000..69b92f0 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_heart.png differ diff --git a/public/assets/images/teacher/giaobai/ico_heart_no.png b/public/assets/images/teacher/giaobai/ico_heart_no.png new file mode 100644 index 0000000..8bc85e8 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_heart_no.png differ diff --git a/public/assets/images/teacher/giaobai/ico_img.png b/public/assets/images/teacher/giaobai/ico_img.png new file mode 100644 index 0000000..98d8c07 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_img.png differ diff --git a/public/assets/images/teacher/giaobai/ico_mp3.png b/public/assets/images/teacher/giaobai/ico_mp3.png new file mode 100644 index 0000000..f4b56b7 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_mp3.png differ diff --git a/public/assets/images/teacher/giaobai/ico_pdf.png b/public/assets/images/teacher/giaobai/ico_pdf.png new file mode 100644 index 0000000..b0d5453 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_pdf.png differ diff --git a/public/assets/images/teacher/giaobai/ico_ppt.png b/public/assets/images/teacher/giaobai/ico_ppt.png new file mode 100644 index 0000000..2a189d9 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_ppt.png differ diff --git a/public/assets/images/teacher/giaobai/ico_remove.png b/public/assets/images/teacher/giaobai/ico_remove.png new file mode 100644 index 0000000..5dc8b69 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_remove.png differ diff --git a/public/assets/images/teacher/giaobai/ico_setting.png b/public/assets/images/teacher/giaobai/ico_setting.png new file mode 100644 index 0000000..db1b085 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_setting.png differ diff --git a/public/assets/images/teacher/giaobai/ico_users_active.png b/public/assets/images/teacher/giaobai/ico_users_active.png new file mode 100644 index 0000000..2926022 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_users_active.png differ diff --git a/public/assets/images/teacher/giaobai/ico_video.png b/public/assets/images/teacher/giaobai/ico_video.png new file mode 100644 index 0000000..959916a Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_video.png differ diff --git a/public/assets/images/teacher/giaobai/ico_word.png b/public/assets/images/teacher/giaobai/ico_word.png new file mode 100644 index 0000000..a13f9b0 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_word.png differ diff --git a/public/assets/images/teacher/giaobai/ico_writing.png b/public/assets/images/teacher/giaobai/ico_writing.png new file mode 100644 index 0000000..a13f9b0 Binary files /dev/null and b/public/assets/images/teacher/giaobai/ico_writing.png differ diff --git a/public/assets/images/teacher/giaobai/listening.png b/public/assets/images/teacher/giaobai/listening.png new file mode 100644 index 0000000..e29c6c2 Binary files /dev/null and b/public/assets/images/teacher/giaobai/listening.png differ diff --git a/public/assets/images/teacher/giaobai/mini_test.png b/public/assets/images/teacher/giaobai/mini_test.png new file mode 100644 index 0000000..c61cea6 Binary files /dev/null and b/public/assets/images/teacher/giaobai/mini_test.png differ diff --git a/public/assets/images/teacher/giaobai/project.png b/public/assets/images/teacher/giaobai/project.png new file mode 100644 index 0000000..549c01e Binary files /dev/null and b/public/assets/images/teacher/giaobai/project.png differ diff --git a/public/assets/images/teacher/giaobai/pronunciation.png b/public/assets/images/teacher/giaobai/pronunciation.png new file mode 100644 index 0000000..5d9a612 Binary files /dev/null and b/public/assets/images/teacher/giaobai/pronunciation.png differ diff --git a/public/assets/images/teacher/giaobai/reading.png b/public/assets/images/teacher/giaobai/reading.png new file mode 100644 index 0000000..3f73ec0 Binary files /dev/null and b/public/assets/images/teacher/giaobai/reading.png differ diff --git a/public/assets/images/teacher/giaobai/skill_guide.png b/public/assets/images/teacher/giaobai/skill_guide.png new file mode 100644 index 0000000..0523d35 Binary files /dev/null and b/public/assets/images/teacher/giaobai/skill_guide.png differ diff --git a/public/assets/images/teacher/giaobai/speaking.png b/public/assets/images/teacher/giaobai/speaking.png new file mode 100644 index 0000000..67d0745 Binary files /dev/null and b/public/assets/images/teacher/giaobai/speaking.png differ diff --git a/public/assets/images/teacher/giaobai/vocab.png b/public/assets/images/teacher/giaobai/vocab.png new file mode 100644 index 0000000..3d87ee1 Binary files /dev/null and b/public/assets/images/teacher/giaobai/vocab.png differ diff --git a/public/assets/images/teacher/giaobai/vocabulary.png b/public/assets/images/teacher/giaobai/vocabulary.png new file mode 100644 index 0000000..3d87ee1 Binary files /dev/null and b/public/assets/images/teacher/giaobai/vocabulary.png differ diff --git a/public/assets/images/teacher/giaobai/writing.png b/public/assets/images/teacher/giaobai/writing.png new file mode 100644 index 0000000..9db2aa6 Binary files /dev/null and b/public/assets/images/teacher/giaobai/writing.png differ diff --git a/public/assets/images/teacher/ico_book.png b/public/assets/images/teacher/ico_book.png new file mode 100644 index 0000000..14244bb Binary files /dev/null and b/public/assets/images/teacher/ico_book.png differ diff --git a/public/assets/images/teacher/ico_clock.png b/public/assets/images/teacher/ico_clock.png new file mode 100644 index 0000000..c96a449 Binary files /dev/null and b/public/assets/images/teacher/ico_clock.png differ diff --git a/public/assets/images/teacher/ico_code.png b/public/assets/images/teacher/ico_code.png new file mode 100644 index 0000000..ed11660 Binary files /dev/null and b/public/assets/images/teacher/ico_code.png differ diff --git a/public/assets/images/teacher/ico_filter.png b/public/assets/images/teacher/ico_filter.png new file mode 100644 index 0000000..0abb870 Binary files /dev/null and b/public/assets/images/teacher/ico_filter.png differ diff --git a/public/assets/images/teacher/ico_left_ca.png b/public/assets/images/teacher/ico_left_ca.png new file mode 100644 index 0000000..ba7c251 Binary files /dev/null and b/public/assets/images/teacher/ico_left_ca.png differ diff --git a/public/assets/images/teacher/ico_remove_blue.png b/public/assets/images/teacher/ico_remove_blue.png new file mode 100644 index 0000000..7e49999 Binary files /dev/null and b/public/assets/images/teacher/ico_remove_blue.png differ diff --git a/public/assets/images/teacher/ico_remove_white.png b/public/assets/images/teacher/ico_remove_white.png new file mode 100644 index 0000000..02ed338 Binary files /dev/null and b/public/assets/images/teacher/ico_remove_white.png differ diff --git a/public/assets/images/teacher/ico_right_blue.png b/public/assets/images/teacher/ico_right_blue.png new file mode 100644 index 0000000..d350761 Binary files /dev/null and b/public/assets/images/teacher/ico_right_blue.png differ diff --git a/public/assets/images/teacher/ico_right_ca.png b/public/assets/images/teacher/ico_right_ca.png new file mode 100644 index 0000000..01ea4c1 Binary files /dev/null and b/public/assets/images/teacher/ico_right_ca.png differ diff --git a/public/assets/images/teacher/ico_school.png b/public/assets/images/teacher/ico_school.png new file mode 100644 index 0000000..7bdf7d4 Binary files /dev/null and b/public/assets/images/teacher/ico_school.png differ diff --git a/public/assets/images/teacher/ico_user_add.png b/public/assets/images/teacher/ico_user_add.png new file mode 100644 index 0000000..9f8ba4d Binary files /dev/null and b/public/assets/images/teacher/ico_user_add.png differ diff --git a/public/assets/images/teacher/ico_user_share.png b/public/assets/images/teacher/ico_user_share.png new file mode 100644 index 0000000..486d22f Binary files /dev/null and b/public/assets/images/teacher/ico_user_share.png differ diff --git a/public/assets/images/teacher/ico_users.png b/public/assets/images/teacher/ico_users.png new file mode 100644 index 0000000..cdf1f61 Binary files /dev/null and b/public/assets/images/teacher/ico_users.png differ diff --git a/public/assets/images/teacher/icon_not_yet_filter.png b/public/assets/images/teacher/icon_not_yet_filter.png new file mode 100644 index 0000000..5878952 Binary files /dev/null and b/public/assets/images/teacher/icon_not_yet_filter.png differ diff --git a/public/assets/images/teacher/lichlamviec/ico_+.png b/public/assets/images/teacher/lichlamviec/ico_+.png new file mode 100644 index 0000000..9cf62eb Binary files /dev/null and b/public/assets/images/teacher/lichlamviec/ico_+.png differ diff --git a/public/assets/images/teacher/lichlamviec/ico_add.png b/public/assets/images/teacher/lichlamviec/ico_add.png new file mode 100644 index 0000000..10e79a5 Binary files /dev/null and b/public/assets/images/teacher/lichlamviec/ico_add.png differ diff --git a/public/assets/images/teacher/lichlamviec/ico_add_small.png b/public/assets/images/teacher/lichlamviec/ico_add_small.png new file mode 100644 index 0000000..9cf62eb Binary files /dev/null and b/public/assets/images/teacher/lichlamviec/ico_add_small.png differ diff --git a/public/assets/images/teacher/lichlamviec/ico_caidat.png b/public/assets/images/teacher/lichlamviec/ico_caidat.png new file mode 100644 index 0000000..a5e7d80 Binary files /dev/null and b/public/assets/images/teacher/lichlamviec/ico_caidat.png differ diff --git a/public/assets/images/teacher/lichlamviec/ico_edit.png b/public/assets/images/teacher/lichlamviec/ico_edit.png new file mode 100644 index 0000000..64a2718 Binary files /dev/null and b/public/assets/images/teacher/lichlamviec/ico_edit.png differ diff --git a/public/assets/images/teacher/lichlamviec/ico_hoso.png b/public/assets/images/teacher/lichlamviec/ico_hoso.png new file mode 100644 index 0000000..c96c47f Binary files /dev/null and b/public/assets/images/teacher/lichlamviec/ico_hoso.png differ diff --git a/public/assets/images/teacher/lichlamviec/ico_huongdan.png b/public/assets/images/teacher/lichlamviec/ico_huongdan.png new file mode 100644 index 0000000..0b39fd8 Binary files /dev/null and b/public/assets/images/teacher/lichlamviec/ico_huongdan.png differ diff --git a/public/assets/images/teacher/lichlamviec/ico_lichlamviec.png b/public/assets/images/teacher/lichlamviec/ico_lichlamviec.png new file mode 100644 index 0000000..3ff37bf Binary files /dev/null and b/public/assets/images/teacher/lichlamviec/ico_lichlamviec.png differ diff --git a/public/assets/images/teacher/lichlamviec/ico_nangcap.png b/public/assets/images/teacher/lichlamviec/ico_nangcap.png new file mode 100644 index 0000000..4017acc Binary files /dev/null and b/public/assets/images/teacher/lichlamviec/ico_nangcap.png differ diff --git a/public/assets/images/teacher/lichlamviec/ico_no_kh.png b/public/assets/images/teacher/lichlamviec/ico_no_kh.png new file mode 100644 index 0000000..e16b8d9 Binary files /dev/null and b/public/assets/images/teacher/lichlamviec/ico_no_kh.png differ diff --git a/public/assets/images/teacher/lichlamviec/ico_quanly.png b/public/assets/images/teacher/lichlamviec/ico_quanly.png new file mode 100644 index 0000000..c32de1d Binary files /dev/null and b/public/assets/images/teacher/lichlamviec/ico_quanly.png differ diff --git a/public/assets/images/teacher/lichlamviec/ico_reload.png b/public/assets/images/teacher/lichlamviec/ico_reload.png new file mode 100644 index 0000000..8bccf84 Binary files /dev/null and b/public/assets/images/teacher/lichlamviec/ico_reload.png differ diff --git a/public/assets/images/teacher/phieudiem.png b/public/assets/images/teacher/phieudiem.png new file mode 100644 index 0000000..229a7df Binary files /dev/null and b/public/assets/images/teacher/phieudiem.png differ diff --git a/public/assets/images/teacher/student.png b/public/assets/images/teacher/student.png new file mode 100644 index 0000000..a7e8164 Binary files /dev/null and b/public/assets/images/teacher/student.png differ diff --git a/public/assets/images/teacher/thanhtich.png b/public/assets/images/teacher/thanhtich.png new file mode 100644 index 0000000..35f78d9 Binary files /dev/null and b/public/assets/images/teacher/thanhtich.png differ diff --git a/public/assets/images/thanhtich/badge-vodich1.png b/public/assets/images/thanhtich/badge-vodich1.png new file mode 100644 index 0000000..0c61d04 Binary files /dev/null and b/public/assets/images/thanhtich/badge-vodich1.png differ diff --git a/public/assets/images/thanhtich/badge-vodich2.png b/public/assets/images/thanhtich/badge-vodich2.png new file mode 100644 index 0000000..81f48e7 Binary files /dev/null and b/public/assets/images/thanhtich/badge-vodich2.png differ diff --git a/public/assets/images/thanhtich/badge-vodich3.png b/public/assets/images/thanhtich/badge-vodich3.png new file mode 100644 index 0000000..04f9d8d Binary files /dev/null and b/public/assets/images/thanhtich/badge-vodich3.png differ diff --git a/public/assets/images/thanhtich/badge-vodich4.png b/public/assets/images/thanhtich/badge-vodich4.png new file mode 100644 index 0000000..91e8780 Binary files /dev/null and b/public/assets/images/thanhtich/badge-vodich4.png differ diff --git a/public/assets/images/thanhtich/badge-vodich5.png b/public/assets/images/thanhtich/badge-vodich5.png new file mode 100644 index 0000000..ad144ad Binary files /dev/null and b/public/assets/images/thanhtich/badge-vodich5.png differ diff --git a/public/assets/images/thanhtich/down.png b/public/assets/images/thanhtich/down.png new file mode 100644 index 0000000..9a2fd09 Binary files /dev/null and b/public/assets/images/thanhtich/down.png differ diff --git a/public/assets/images/thanhtich/gold.png b/public/assets/images/thanhtich/gold.png new file mode 100644 index 0000000..3f312d5 Binary files /dev/null and b/public/assets/images/thanhtich/gold.png differ diff --git a/public/assets/images/thanhtich/top1.png b/public/assets/images/thanhtich/top1.png new file mode 100644 index 0000000..32dab5c Binary files /dev/null and b/public/assets/images/thanhtich/top1.png differ diff --git a/public/assets/images/thanhtich/top2.png b/public/assets/images/thanhtich/top2.png new file mode 100644 index 0000000..9e47896 Binary files /dev/null and b/public/assets/images/thanhtich/top2.png differ diff --git a/public/assets/images/thanhtich/top3.png b/public/assets/images/thanhtich/top3.png new file mode 100644 index 0000000..10a74d6 Binary files /dev/null and b/public/assets/images/thanhtich/top3.png differ diff --git a/public/assets/images/thanhtich/up.png b/public/assets/images/thanhtich/up.png new file mode 100644 index 0000000..8be49cf Binary files /dev/null and b/public/assets/images/thanhtich/up.png differ diff --git a/public/assets/images/tinnhan/avata.png b/public/assets/images/tinnhan/avata.png new file mode 100644 index 0000000..de40cf9 Binary files /dev/null and b/public/assets/images/tinnhan/avata.png differ diff --git a/public/assets/images/tinnhan/bg_message.png b/public/assets/images/tinnhan/bg_message.png new file mode 100644 index 0000000..a5f61cb Binary files /dev/null and b/public/assets/images/tinnhan/bg_message.png differ diff --git a/public/assets/images/tinnhan/bg_update.png b/public/assets/images/tinnhan/bg_update.png new file mode 100644 index 0000000..4928a3d Binary files /dev/null and b/public/assets/images/tinnhan/bg_update.png differ diff --git a/public/assets/images/tinnhan/ico_dropdown.png b/public/assets/images/tinnhan/ico_dropdown.png new file mode 100644 index 0000000..380b430 Binary files /dev/null and b/public/assets/images/tinnhan/ico_dropdown.png differ diff --git a/public/assets/images/tinnhan/ico_message.png b/public/assets/images/tinnhan/ico_message.png new file mode 100644 index 0000000..3f53bc9 Binary files /dev/null and b/public/assets/images/tinnhan/ico_message.png differ diff --git a/public/assets/images/tinnhan/ico_ring.png b/public/assets/images/tinnhan/ico_ring.png new file mode 100644 index 0000000..91c1978 Binary files /dev/null and b/public/assets/images/tinnhan/ico_ring.png differ diff --git a/public/assets/images/tinnhan/ico_search.png b/public/assets/images/tinnhan/ico_search.png new file mode 100644 index 0000000..83f937a Binary files /dev/null and b/public/assets/images/tinnhan/ico_search.png differ diff --git a/public/assets/images/tinnhan/ico_send_mes.png b/public/assets/images/tinnhan/ico_send_mes.png new file mode 100644 index 0000000..6fc2ce1 Binary files /dev/null and b/public/assets/images/tinnhan/ico_send_mes.png differ diff --git a/public/assets/images/tinnhan/ico_tb.png b/public/assets/images/tinnhan/ico_tb.png new file mode 100644 index 0000000..93485da Binary files /dev/null and b/public/assets/images/tinnhan/ico_tb.png differ diff --git a/public/assets/images/underline-score.png b/public/assets/images/underline-score.png new file mode 100644 index 0000000..17591be Binary files /dev/null and b/public/assets/images/underline-score.png differ diff --git a/public/assets/js/all.js b/public/assets/js/all.js new file mode 100644 index 0000000..e69de29 diff --git a/public/assets/js/select.js b/public/assets/js/select.js new file mode 100644 index 0000000..e69de29 diff --git a/public/assets/videos/parent_video.mp4 b/public/assets/videos/parent_video.mp4 new file mode 100644 index 0000000..b576b00 Binary files /dev/null and b/public/assets/videos/parent_video.mp4 differ diff --git a/public/assets/videos/student_video.mp4 b/public/assets/videos/student_video.mp4 new file mode 100644 index 0000000..c9418b4 Binary files /dev/null and b/public/assets/videos/student_video.mp4 differ diff --git a/public/assets/videos/teacher_video.mp4 b/public/assets/videos/teacher_video.mp4 new file mode 100644 index 0000000..2c7f4ba Binary files /dev/null and b/public/assets/videos/teacher_video.mp4 differ diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..bbb385f Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..728dbb5 --- /dev/null +++ b/public/index.html @@ -0,0 +1,82 @@ + + + + + + + + + + + + + Sunday English - Nâng cao điểm số Tiếng Anh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/public/logo192.png b/public/logo192.png new file mode 100644 index 0000000..fc44b0a Binary files /dev/null and b/public/logo192.png differ diff --git a/public/logo512.png b/public/logo512.png new file mode 100644 index 0000000..a4e47a6 Binary files /dev/null and b/public/logo512.png differ diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000..080d6c7 --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/public/web.config b/public/web.config new file mode 100644 index 0000000..9ff871c --- /dev/null +++ b/public/web.config @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/App.js b/src/App.js new file mode 100644 index 0000000..996748e --- /dev/null +++ b/src/App.js @@ -0,0 +1,106 @@ +import React, { useEffect, useState, useLayoutEffect } from "react"; +import { Router, Route, Switch, Redirect } from "react-router-dom"; +import { useSelector, useDispatch } from "react-redux"; + +import { + RouteRedirectToLogin, + RouteRedirectToAdmin, +} from "./_components/Router"; +import { studentConstants, userConstants } from "./_constants"; +import { alertActions } from "./_actions"; +import { history } from "./_helpers"; +import { getListClassService, getLocationService } from "./_services/user"; +import { + HomePage, + BenefitTeacher, + BenefitParent, + DownloadPage, +} from "./_screens"; +import { TypeHeaderNewsItem } from "./_constants/headerNews"; + +function App() { + const dispatch = useDispatch(); + const authentication = useSelector((state) => state.authentication); + const sideBarRootLessness = useSelector( + (state) => state.rootlessness.sideBarRootLessness + ); + + String.prototype.capitalize = function () { + var letters = + "\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00DF-\\u00F6\\u00F8-\\u00FF\\u0101\\u0103\\u0105\\u0107\\u0109\\u010B\\u010D\\u010F\\u0111\\u0113\\u0115\\u0117\\u0119\\u011B\\u011D\\u011F\\u0121\\u0123\\u0125\\u0127\\u0129\\u012B\\u012D\\u012F\\u0131\\u0133\\u0135\\u0137\\u0138\\u013A\\u013C\\u013E\\u0140\\u0142\\u0144\\u0146\\u0148\\u0149\\u014B\\u014D\\u014F\\u0151\\u0153\\u0155\\u0157\\u0159\\u015B\\u015D\\u015F\\u0161\\u0163\\u0165\\u0167\\u0169\\u016B\\u016D\\u016F\\u0171\\u0173\\u0175\\u0177\\u017A\\u017C\\u017E-\\u0180\\u0183\\u0185\\u0188\\u018C\\u018D\\u0192\\u0195\\u0199-\\u019B\\u019E\\u01A1\\u01A3\\u01A5\\u01A8\\u01AA\\u01AB\\u01AD\\u01B0\\u01B4\\u01B6\\u01B9\\u01BA\\u01BD-\\u01BF\\u01C6\\u01C9\\u01CC\\u01CE\\u01D0\\u01D2\\u01D4\\u01D6\\u01D8\\u01DA\\u01DC\\u01DD\\u01DF\\u01E1\\u01E3\\u01E5\\u01E7\\u01E9\\u01EB\\u01ED\\u01EF\\u01F0\\u01F3\\u01F5\\u01F9\\u01FB\\u01FD\\u01FF\\u0201\\u0203\\u0205\\u0207\\u0209\\u020B\\u020D\\u020F\\u0211\\u0213\\u0215\\u0217\\u0219\\u021B\\u021D\\u021F\\u0221\\u0223\\u0225\\u0227\\u0229\\u022B\\u022D\\u022F\\u0231\\u0233-\\u0239\\u023C\\u023F\\u0240\\u0242\\u0247\\u0249\\u024B\\u024D\\u024F-\\u0293\\u0295-\\u02AF\\u0371\\u0373\\u0377\\u037B-\\u037D\\u0390\\u03AC-\\u03CE\\u03D0\\u03D1\\u03D5-\\u03D7\\u03D9\\u03DB\\u03DD\\u03DF\\u03E1\\u03E3\\u03E5\\u03E7\\u03E9\\u03EB\\u03ED\\u03EF-\\u03F3\\u03F5\\u03F8\\u03FB\\u03FC\\u0430-\\u045F\\u0461\\u0463\\u0465\\u0467\\u0469\\u046B\\u046D\\u046F\\u0471\\u0473\\u0475\\u0477\\u0479\\u047B\\u047D\\u047F\\u0481\\u048B\\u048D\\u048F\\u0491\\u0493\\u0495\\u0497\\u0499\\u049B\\u049D\\u049F\\u04A1\\u04A3\\u04A5\\u04A7\\u04A9\\u04AB\\u04AD\\u04AF\\u04B1\\u04B3\\u04B5\\u04B7\\u04B9\\u04BB\\u04BD\\u04BF\\u04C2\\u04C4\\u04C6\\u04C8\\u04CA\\u04CC\\u04CE\\u04CF\\u04D1\\u04D3\\u04D5\\u04D7\\u04D9\\u04DB\\u04DD\\u04DF\\u04E1\\u04E3\\u04E5\\u04E7\\u04E9\\u04EB\\u04ED\\u04EF\\u04F1\\u04F3\\u04F5\\u04F7\\u04F9\\u04FB\\u04FD\\u04FF\\u0501\\u0503\\u0505\\u0507\\u0509\\u050B\\u050D\\u050F\\u0511\\u0513\\u0515\\u0517\\u0519\\u051B\\u051D\\u051F\\u0521\\u0523\\u0525\\u0561-\\u0587\\u1D00-\\u1D2B\\u1D62-\\u1D77\\u1D79-\\u1D9A\\u1E01\\u1E03\\u1E05\\u1E07\\u1E09\\u1E0B\\u1E0D\\u1E0F\\u1E11\\u1E13\\u1E15\\u1E17\\u1E19\\u1E1B\\u1E1D\\u1E1F\\u1E21\\u1E23\\u1E25\\u1E27\\u1E29\\u1E2B\\u1E2D\\u1E2F\\u1E31\\u1E33\\u1E35\\u1E37\\u1E39\\u1E3B\\u1E3D\\u1E3F\\u1E41\\u1E43\\u1E45\\u1E47\\u1E49\\u1E4B\\u1E4D\\u1E4F\\u1E51\\u1E53\\u1E55\\u1E57\\u1E59\\u1E5B\\u1E5D\\u1E5F\\u1E61\\u1E63\\u1E65\\u1E67\\u1E69\\u1E6B\\u1E6D\\u1E6F\\u1E71\\u1E73\\u1E75\\u1E77\\u1E79\\u1E7B\\u1E7D\\u1E7F\\u1E81\\u1E83\\u1E85\\u1E87\\u1E89\\u1E8B\\u1E8D\\u1E8F\\u1E91\\u1E93\\u1E95-\\u1E9D\\u1E9F\\u1EA1\\u1EA3\\u1EA5\\u1EA7\\u1EA9\\u1EAB\\u1EAD\\u1EAF\\u1EB1\\u1EB3\\u1EB5\\u1EB7\\u1EB9\\u1EBB\\u1EBD\\u1EBF\\u1EC1\\u1EC3\\u1EC5\\u1EC7\\u1EC9\\u1ECB\\u1ECD\\u1ECF\\u1ED1\\u1ED3\\u1ED5\\u1ED7\\u1ED9\\u1EDB\\u1EDD\\u1EDF\\u1EE1\\u1EE3\\u1EE5\\u1EE7\\u1EE9\\u1EEB\\u1EED\\u1EEF\\u1EF1\\u1EF3\\u1EF5\\u1EF7\\u1EF9\\u1EFB\\u1EFD\\u1EFF-\\u1F07\\u1F10-\\u1F15\\u1F20-\\u1F27\\u1F30-\\u1F37\\u1F40-\\u1F45\\u1F50-\\u1F57\\u1F60-\\u1F67\\u1F70-\\u1F7D\\u1F80-\\u1F87\\u1F90-\\u1F97\\u1FA0-\\u1FA7\\u1FB0-\\u1FB4\\u1FB6\\u1FB7\\u1FBE\\u1FC2-\\u1FC4\\u1FC6\\u1FC7\\u1FD0-\\u1FD3\\u1FD6\\u1FD7\\u1FE0-\\u1FE7\\u1FF2-\\u1FF4\\u1FF6\\u1FF7\\u210A\\u210E\\u210F\\u2113\\u212F\\u2134\\u2139\\u213C\\u213D\\u2146-\\u2149\\u214E\\u2184\\u2C30-\\u2C5E\\u2C61\\u2C65\\u2C66\\u2C68\\u2C6A\\u2C6C\\u2C71\\u2C73\\u2C74\\u2C76-\\u2C7C\\u2C81\\u2C83\\u2C85\\u2C87\\u2C89\\u2C8B\\u2C8D\\u2C8F\\u2C91\\u2C93\\u2C95\\u2C97\\u2C99\\u2C9B\\u2C9D\\u2C9F\\u2CA1\\u2CA3\\u2CA5\\u2CA7\\u2CA9\\u2CAB\\u2CAD\\u2CAF\\u2CB1\\u2CB3\\u2CB5\\u2CB7\\u2CB9\\u2CBB\\u2CBD\\u2CBF\\u2CC1\\u2CC3\\u2CC5\\u2CC7\\u2CC9\\u2CCB\\u2CCD\\u2CCF\\u2CD1\\u2CD3\\u2CD5\\u2CD7\\u2CD9\\u2CDB\\u2CDD\\u2CDF\\u2CE1\\u2CE3\\u2CE4\\u2CEC\\u2CEE\\u2D00-\\u2D25\\uA641\\uA643\\uA645\\uA647\\uA649\\uA64B\\uA64D\\uA64F\\uA651\\uA653\\uA655\\uA657\\uA659\\uA65B\\uA65D\\uA65F\\uA663\\uA665\\uA667\\uA669\\uA66B\\uA66D\\uA681\\uA683\\uA685\\uA687\\uA689\\uA68B\\uA68D\\uA68F\\uA691\\uA693\\uA695\\uA697\\uA723\\uA725\\uA727\\uA729\\uA72B\\uA72D\\uA72F-\\uA731\\uA733\\uA735\\uA737\\uA739\\uA73B\\uA73D\\uA73F\\uA741\\uA743\\uA745\\uA747\\uA749\\uA74B\\uA74D\\uA74F\\uA751\\uA753\\uA755\\uA757\\uA759\\uA75B\\uA75D\\uA75F\\uA761\\uA763\\uA765\\uA767\\uA769\\uA76B\\uA76D\\uA76F\\uA771-\\uA778\\uA77A\\uA77C\\uA77F\\uA781\\uA783\\uA785\\uA787\\uA78C\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFF41-\\uFF5A\\u0041-\\u005A\\u00C0-\\u00D6\\u00D8-\\u00DE\\u0100\\u0102\\u0104\\u0106\\u0108\\u010A\\u010C\\u010E\\u0110\\u0112\\u0114\\u0116\\u0118\\u011A\\u011C\\u011E\\u0120\\u0122\\u0124\\u0126\\u0128\\u012A\\u012C\\u012E\\u0130\\u0132\\u0134\\u0136\\u0139\\u013B\\u013D\\u013F\\u0141\\u0143\\u0145\\u0147\\u014A\\u014C\\u014E\\u0150\\u0152\\u0154\\u0156\\u0158\\u015A\\u015C\\u015E\\u0160\\u0162\\u0164\\u0166\\u0168\\u016A\\u016C\\u016E\\u0170\\u0172\\u0174\\u0176\\u0178\\u0179\\u017B\\u017D\\u0181\\u0182\\u0184\\u0186\\u0187\\u0189-\\u018B\\u018E-\\u0191\\u0193\\u0194\\u0196-\\u0198\\u019C\\u019D\\u019F\\u01A0\\u01A2\\u01A4\\u01A6\\u01A7\\u01A9\\u01AC\\u01AE\\u01AF\\u01B1-\\u01B3\\u01B5\\u01B7\\u01B8\\u01BC\\u01C4\\u01C7\\u01CA\\u01CD\\u01CF\\u01D1\\u01D3\\u01D5\\u01D7\\u01D9\\u01DB\\u01DE\\u01E0\\u01E2\\u01E4\\u01E6\\u01E8\\u01EA\\u01EC\\u01EE\\u01F1\\u01F4\\u01F6-\\u01F8\\u01FA\\u01FC\\u01FE\\u0200\\u0202\\u0204\\u0206\\u0208\\u020A\\u020C\\u020E\\u0210\\u0212\\u0214\\u0216\\u0218\\u021A\\u021C\\u021E\\u0220\\u0222\\u0224\\u0226\\u0228\\u022A\\u022C\\u022E\\u0230\\u0232\\u023A\\u023B\\u023D\\u023E\\u0241\\u0243-\\u0246\\u0248\\u024A\\u024C\\u024E\\u0370\\u0372\\u0376\\u0386\\u0388-\\u038A\\u038C\\u038E\\u038F\\u0391-\\u03A1\\u03A3-\\u03AB\\u03CF\\u03D2-\\u03D4\\u03D8\\u03DA\\u03DC\\u03DE\\u03E0\\u03E2\\u03E4\\u03E6\\u03E8\\u03EA\\u03EC\\u03EE\\u03F4\\u03F7\\u03F9\\u03FA\\u03FD-\\u042F\\u0460\\u0462\\u0464\\u0466\\u0468\\u046A\\u046C\\u046E\\u0470\\u0472\\u0474\\u0476\\u0478\\u047A\\u047C\\u047E\\u0480\\u048A\\u048C\\u048E\\u0490\\u0492\\u0494\\u0496\\u0498\\u049A\\u049C\\u049E\\u04A0\\u04A2\\u04A4\\u04A6\\u04A8\\u04AA\\u04AC\\u04AE\\u04B0\\u04B2\\u04B4\\u04B6\\u04B8\\u04BA\\u04BC\\u04BE\\u04C0\\u04C1\\u04C3\\u04C5\\u04C7\\u04C9\\u04CB\\u04CD\\u04D0\\u04D2\\u04D4\\u04D6\\u04D8\\u04DA\\u04DC\\u04DE\\u04E0\\u04E2\\u04E4\\u04E6\\u04E8\\u04EA\\u04EC\\u04EE\\u04F0\\u04F2\\u04F4\\u04F6\\u04F8\\u04FA\\u04FC\\u04FE\\u0500\\u0502\\u0504\\u0506\\u0508\\u050A\\u050C\\u050E\\u0510\\u0512\\u0514\\u0516\\u0518\\u051A\\u051C\\u051E\\u0520\\u0522\\u0524\\u0531-\\u0556\\u10A0-\\u10C5\\u1E00\\u1E02\\u1E04\\u1E06\\u1E08\\u1E0A\\u1E0C\\u1E0E\\u1E10\\u1E12\\u1E14\\u1E16\\u1E18\\u1E1A\\u1E1C\\u1E1E\\u1E20\\u1E22\\u1E24\\u1E26\\u1E28\\u1E2A\\u1E2C\\u1E2E\\u1E30\\u1E32\\u1E34\\u1E36\\u1E38\\u1E3A\\u1E3C\\u1E3E\\u1E40\\u1E42\\u1E44\\u1E46\\u1E48\\u1E4A\\u1E4C\\u1E4E\\u1E50\\u1E52\\u1E54\\u1E56\\u1E58\\u1E5A\\u1E5C\\u1E5E\\u1E60\\u1E62\\u1E64\\u1E66\\u1E68\\u1E6A\\u1E6C\\u1E6E\\u1E70\\u1E72\\u1E74\\u1E76\\u1E78\\u1E7A\\u1E7C\\u1E7E\\u1E80\\u1E82\\u1E84\\u1E86\\u1E88\\u1E8A\\u1E8C\\u1E8E\\u1E90\\u1E92\\u1E94\\u1E9E\\u1EA0\\u1EA2\\u1EA4\\u1EA6\\u1EA8\\u1EAA\\u1EAC\\u1EAE\\u1EB0\\u1EB2\\u1EB4\\u1EB6\\u1EB8\\u1EBA\\u1EBC\\u1EBE\\u1EC0\\u1EC2\\u1EC4\\u1EC6\\u1EC8\\u1ECA\\u1ECC\\u1ECE\\u1ED0\\u1ED2\\u1ED4\\u1ED6\\u1ED8\\u1EDA\\u1EDC\\u1EDE\\u1EE0\\u1EE2\\u1EE4\\u1EE6\\u1EE8\\u1EEA\\u1EEC\\u1EEE\\u1EF0\\u1EF2\\u1EF4\\u1EF6\\u1EF8\\u1EFA\\u1EFC\\u1EFE\\u1F08-\\u1F0F\\u1F18-\\u1F1D\\u1F28-\\u1F2F\\u1F38-\\u1F3F\\u1F48-\\u1F4D\\u1F59\\u1F5B\\u1F5D\\u1F5F\\u1F68-\\u1F6F\\u1FB8-\\u1FBB\\u1FC8-\\u1FCB\\u1FD8-\\u1FDB\\u1FE8-\\u1FEC\\u1FF8-\\u1FFB\\u2102\\u2107\\u210B-\\u210D\\u2110-\\u2112\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u2130-\\u2133\\u213E\\u213F\\u2145\\u2183\\u2C00-\\u2C2E\\u2C60\\u2C62-\\u2C64\\u2C67\\u2C69\\u2C6B\\u2C6D-\\u2C70\\u2C72\\u2C75\\u2C7E-\\u2C80\\u2C82\\u2C84\\u2C86\\u2C88\\u2C8A\\u2C8C\\u2C8E\\u2C90\\u2C92\\u2C94\\u2C96\\u2C98\\u2C9A\\u2C9C\\u2C9E\\u2CA0\\u2CA2\\u2CA4\\u2CA6\\u2CA8\\u2CAA\\u2CAC\\u2CAE\\u2CB0\\u2CB2\\u2CB4\\u2CB6\\u2CB8\\u2CBA\\u2CBC\\u2CBE\\u2CC0\\u2CC2\\u2CC4\\u2CC6\\u2CC8\\u2CCA\\u2CCC\\u2CCE\\u2CD0\\u2CD2\\u2CD4\\u2CD6\\u2CD8\\u2CDA\\u2CDC\\u2CDE\\u2CE0\\u2CE2\\u2CEB\\u2CED\\uA640\\uA642\\uA644\\uA646\\uA648\\uA64A\\uA64C\\uA64E\\uA650\\uA652\\uA654\\uA656\\uA658\\uA65A\\uA65C\\uA65E\\uA662\\uA664\\uA666\\uA668\\uA66A\\uA66C\\uA680\\uA682\\uA684\\uA686\\uA688\\uA68A\\uA68C\\uA68E\\uA690\\uA692\\uA694\\uA696\\uA722\\uA724\\uA726\\uA728\\uA72A\\uA72C\\uA72E\\uA732\\uA734\\uA736\\uA738\\uA73A\\uA73C\\uA73E\\uA740\\uA742\\uA744\\uA746\\uA748\\uA74A\\uA74C\\uA74E\\uA750\\uA752\\uA754\\uA756\\uA758\\uA75A\\uA75C\\uA75E\\uA760\\uA762\\uA764\\uA766\\uA768\\uA76A\\uA76C\\uA76E\\uA779\\uA77B\\uA77D\\uA77E\\uA780\\uA782\\uA784\\uA786\\uA78B\\uFF21-\\uFF3A\\u01C5\\u01C8\\u01CB\\u01F2\\u1F88-\\u1F8F\\u1F98-\\u1F9F\\u1FA8-\\u1FAF\\u1FBC\\u1FCC\\u1FFC\\u02B0-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0374\\u037A\\u0559\\u0640\\u06E5\\u06E6\\u07F4\\u07F5\\u07FA\\u081A\\u0824\\u0828\\u0971\\u0E46\\u0EC6\\u10FC\\u17D7\\u1843\\u1AA7\\u1C78-\\u1C7D\\u1D2C-\\u1D61\\u1D78\\u1D9B-\\u1DBF\\u2071\\u207F\\u2090-\\u2094\\u2C7D\\u2D6F\\u2E2F\\u3005\\u3031-\\u3035\\u303B\\u309D\\u309E\\u30FC-\\u30FE\\uA015\\uA4F8-\\uA4FD\\uA60C\\uA67F\\uA717-\\uA71F\\uA770\\uA788\\uA9CF\\uAA70\\uAADD\\uFF70\\uFF9E\\uFF9F\\u01BB\\u01C0-\\u01C3\\u0294\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0621-\\u063F\\u0641-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u0800-\\u0815\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0972\\u0979-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D3D\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E45\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EDC\\u0EDD\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8B\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10D0-\\u10FA\\u1100-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17DC\\u1820-\\u1842\\u1844-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C77\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u2135-\\u2138\\u2D30-\\u2D65\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u3006\\u303C\\u3041-\\u3096\\u309F\\u30A1-\\u30FA\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31B7\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCB\\uA000-\\uA014\\uA016-\\uA48C\\uA4D0-\\uA4F7\\uA500-\\uA60B\\uA610-\\uA61F\\uA62A\\uA62B\\uA66E\\uA6A0-\\uA6E5\\uA7FB-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA6F\\uAA71-\\uAA76\\uAA7A\\uAA80-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB\\uAADC\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA2D\\uFA30-\\uFA6D\\uFA70-\\uFAD9\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF66-\\uFF6F\\uFF71-\\uFF9D\\uFFA0-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC"; + var regex = new RegExp("(^|[^" + letters + "])([" + letters + "])", "g"); + + return this.replace(regex, function (s, m1, m2) { + return m1 + m2.toUpperCase(); + }); + }; + + useEffect(() => { + history.listen(() => { + dispatch(alertActions?.clear()); + }); + }, []); + + useEffect(() => { + if (authentication.role === userConstants.ROLE_STUDENT) { + getLocation(); + getClass(); + } + }, [authentication.role]); + + const getLocation = async () => { + try { + const res = await getLocationService(); + if (res?.data?.status) { + let list = res.data.list_address || []; + dispatch({ type: studentConstants.LIST_ADDRESS_FILTER, payload: list }); + } + } catch (e) {} + }; + + const getClass = async () => { + try { + const res = await getListClassService(); + if (res?.data?.status) { + let list = res.data.list_grade || []; + dispatch({ type: studentConstants.LIST_CLASS_FILTER, payload: list }); + } + } catch (e) {} + }; + + return ( +
+
+
+
+
+ + + + + + + + + +
+ ); +} + +export default App; diff --git a/src/_actions/alerts.js b/src/_actions/alerts.js new file mode 100644 index 0000000..3e75245 --- /dev/null +++ b/src/_actions/alerts.js @@ -0,0 +1,19 @@ +import { alertConstants } from './../_constants'; + +export const alertActions = { + success, + error, + clear +}; + +function success(alert) { + return { type: alertConstants.SUCCESS, alert }; +} + +function error(alert) { + return { type: alertConstants.ERROR, alert }; +} + +function clear() { + return { type: alertConstants.CLEAR }; +} \ No newline at end of file diff --git a/src/_actions/index.js b/src/_actions/index.js new file mode 100644 index 0000000..20c6a72 --- /dev/null +++ b/src/_actions/index.js @@ -0,0 +1,6 @@ +export * from './users'; +export * from './alerts'; +export * from './students'; +export * from './licenses'; +export * from './teachers'; +export * from './schedules'; diff --git a/src/_actions/licenses.js b/src/_actions/licenses.js new file mode 100644 index 0000000..b59789d --- /dev/null +++ b/src/_actions/licenses.js @@ -0,0 +1,86 @@ +import { apiCaller } from "./../_helpers"; +import { alertActions } from "./"; +import { licenseConstants } from "./../_constants"; +import { configConstants } from "./../_constants"; +import API from "../_apis/APIConstants"; +import APIBase from "../_base/APIBase"; + +export const licenseActions = { + getCurrentLicense, + addCodeLicense, + getHistoryLicense, +}; + +function getCurrentLicense() { + let urlApi = `${API.baseURL}${API.get_packages_available}`; + return (dispatch) => { + return APIBase.apiBaseCaller("GET", urlApi, {}).then( + (licenses) => { + dispatch({ + type: licenseConstants.GET_CURRENT_LICENSE, + listCurentLicenses: licenses.data ?? [], + }); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: licenseConstants.SCREEN_GET_CURREN_LICENSE, + }) + ); + } + ); + }; +} + +function addCodeLicense(data) { + return (dispatch) => { + return apiCaller( + "/apilicense_management/api/license/active_license_code", + "POST", + data, + null, + true, + configConstants.API_URL_SELICENSE + ).then( + () => { + dispatch( + alertActions.success({ + message: licenseConstants.MESSAGE_LICENSE_ADD_CODE_COMPLETE, + screen: licenseConstants.SCREEN_LICENSE_ADD_CODE, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: licenseConstants.SCREEN_LICENSE_ADD_CODE, + }) + ); + } + ); + }; +} + +function getHistoryLicense() { + let urlApi = `${API.baseURL}${API.get_package_history}`; + return (dispatch) => { + return APIBase.apiBaseCaller("GET", urlApi, {}).then( + (licenses) => { + dispatch({ + type: licenseConstants.GET_HISTORY_LICENSE, + listHistoryLicenses: licenses.data ?? [], + }); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: licenseConstants.SCREEN_GET_HISTORY_LICENSE, + }) + ); + } + ); + }; +} diff --git a/src/_actions/schedules.js b/src/_actions/schedules.js new file mode 100644 index 0000000..88124eb --- /dev/null +++ b/src/_actions/schedules.js @@ -0,0 +1,579 @@ +import { apiCaller } from "./../_helpers"; +import { alertActions } from "./"; +import { scheduleConstants, popupConstants, configConstants } from "./../_constants"; +import moment from "moment"; +import { forEach } from "lodash"; + +export const scheduleActions = { + getTimetable, + getScheduleToday, + addSchedule, + addTimeTable, + editTimeTable, + deleteTimeTable, + resetTimeTable, + editSchedule, + deleteSchedule, + getScheduleYear, + addScheduleYear, + editScheduleYear, + updateTimeForTimeTable, + completeSchedule, + getStatus, + getScheduleStatus, + deleteScheduleYear, +}; + +function getTimetable(start_time, end_time) { + // BE required dont request param time + const checkUrl = + !!start_time && !!end_time + ? `?start_time=${start_time}&&end_time=${end_time}` + : ""; + return (dispatch) => { + return apiCaller( + "/API_schedule_lock/get_all_schedule", + "GET", + {}, + null, + true + ).then( + (timeTable) => { + // console.log(timeTable); + dispatch({ + type: scheduleConstants.GET_TIME_TABLE, + timeTable, + }); + }, + () => { + dispatch({ + type: scheduleConstants.GET_TIME_TABLE, + timeTable: { + data: [], + valid_to: "", + }, + }); + } + ); + }; +} + +function addSchedule(data) { + return (dispatch) => { + return apiCaller( + "/API_schedule/insert_schedule", + "POST", + data, + null, + true + ).then( + () => { + dispatch( + alertActions.success({ + message: "Thêm kế hoạch thành công", + screen: scheduleConstants.SCREEN_ADD_SCHEDULE, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: scheduleConstants.SCREEN_ADD_SCHEDULE, + isShowPopup: true + }) + ); + } + ); + }; +} + +function deleteSchedule(data, time, student) { + var urlencoded = new URLSearchParams(); + urlencoded.append("id", data.id); + urlencoded.append("update_all", data.update_all); + return (dispatch) => { + return apiCaller( + "/API_schedule/delete_schedule", + "DELETE", + urlencoded, + null, + true + ).then(() => { + dispatch({ + type: scheduleConstants.RESET_DELETE_SCHEDULE_DAY, + }); + // if (data.selectedDate) { + // dispatch(getScheduleToday(data.user_id, data.selectedDate)); + // } else { + // dispatch(getScheduleToday(data.user_id)); + // } + let authentication = JSON.parse(localStorage.getItem("authentication")); + if (authentication.role === "student") { + dispatch( + getScheduleStatus( + moment(time).format("MM"), + moment(time).format("YYYY") + ) + ); + } + dispatch( + getStatus( + moment(time).format("MM"), + moment(time).format("YYYY"), + authentication.role + ) + ); + }); + }; +} + +function editSchedule(data) { + return (dispatch) => { + return apiCaller( + "/API_schedule/edit_schedule", + "PUT", + data, + null, + true + ).then( + () => { + dispatch( + alertActions.success({ + message: "Sửa kế hoạch thành công", + screen: scheduleConstants.SCREEN_ADD_SCHEDULE, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: scheduleConstants.SCREEN_ADD_SCHEDULE, + }) + ); + } + ); + }; +} + +function getScheduleToday(id_user, time) { + if (!time) { + time = moment().format("YYYY-MM-DD"); + } + return (dispatch) => { + dispatch({ + type: scheduleConstants.SET_SELECT_DATE, + time, + }); + return apiCaller( + "/API_schedule/get_all_schedule?id_user=" + + id_user + + "&start_time=" + + time + + "&end_time=" + + time, + "GET", + {}, + null, + true + ).then((schedules) => { + dispatch({ + type: scheduleConstants.GET_SCHEDULE_TODAY, + today: schedules.data, + }); + dispatch({ + type: scheduleConstants.SET_SELECT_DATE, + time, + }); + }); + }; +} + +function getScheduleYear(year) { + return (dispatch) => { + return apiCaller( + "/API_schedule_year/list_schedule_year?year=" + year, + "GET", + {}, + null, + true + ).then((schedules) => { + dispatch({ + type: scheduleConstants.GET_SCHEDULE_YEAR, + year: schedules.data, + }); + dispatch({ + type: scheduleConstants.ADD_DATA_SCHEDULE_YEAR, + dataAddScheduleYear: { + showForm: false, + }, + }); + }); + }; +} + +function addTimeTable(data) { + return (dispatch) => { + return apiCaller( + "/API_schedule_lock/schedule_lock", + "POST", + data, + null, + true + ).then( + () => { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + dispatch( + alertActions.success({ + message: "Thêm thời khoá biểu thành công", + screen: scheduleConstants.SCREEN_ADD_TIME_TABLE, + }) + ); + + dispatch(getTimetable()); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: scheduleConstants.SCREEN_ADD_TIME_TABLE, + }) + ); + } + ); + }; +} + +function editTimeTable(data) { + return (dispatch) => { + dispatch(getTimetable()); + return apiCaller( + "/API_schedule_lock/schedule_lock", + "PUT", + data, + null, + true + ).then( + () => { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + dispatch( + alertActions.success({ + message: "Sửa thời khóa biểu thành công.", + screen: scheduleConstants.SCREEN_ADD_TIME_TABLE, + }) + ); + dispatch(getTimetable()); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: scheduleConstants.SCREEN_ADD_TIME_TABLE, + }) + ); + } + ); + }; +} + +function updateTimeForTimeTable(data) { + return (dispatch) => { + return apiCaller( + "/API_schedule_lock/schedule_config", + "PUT", + data, + null, + true + ).then( + () => { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + dispatch( + alertActions.success({ + message: "Cập nhật thời khoá biểu hoạch thành công", + screen: scheduleConstants.SCREEN_UPDATE_TIME_TIME_TABLE, + }) + ); + dispatch(getTimetable()); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: scheduleConstants.SCREEN_UPDATE_TIME_TIME_TABLE, + }) + ); + } + ); + }; +} + +function deleteTimeTable(id) { + var urlencoded = new URLSearchParams(); + urlencoded.append("id", id); + return (dispatch) => { + // dispatch(getTimetable()); + return apiCaller( + "/API_schedule_lock/schedule_lock", + "DELETE", + urlencoded, + null, + true, + configConstants.API_URL_SETEST, + false + ).then(() => { + dispatch(getTimetable()); + }).catch((e) => { + $(".loading").addClass("hide"); + }); + }; +} + +function resetTimeTable(data) { + return (dispatch) => { + return apiCaller( + "/API_schedule_lock/reset_schedule", + "DELETE", + data, + null, + true + ).then( + () => { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + dispatch( + alertActions.success({ + message: "Đặt lại thời khoá biểu thành công", + screen: scheduleConstants.SCREEN_RESET_TIME_TABLE, + }) + ); + dispatch(getTimetable()); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: scheduleConstants.SCREEN_RESET_TIME_TABLE, + }) + ); + } + ); + }; +} + +function addScheduleYear(data) { + return (dispatch) => { + return apiCaller( + "/API_schedule_year/create_schedule_year", + "POST", + data, + null, + true + ).then( + () => { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + dispatch( + alertActions.success({ + message: "Thêm kế hoạch thành công", + screen: scheduleConstants.SCREEN_ADD_SCHEDULE_YEAR, + }) + ); + dispatch(getScheduleYear(data.year)); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: scheduleConstants.SCREEN_ADD_SCHEDULE_YEAR, + }) + ); + } + ); + }; +} + +function editScheduleYear(data) { + return (dispatch) => { + return apiCaller( + "/API_schedule_year/edit_schedule_year", + "PUT", + data, + null, + true + ).then( + () => { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + dispatch( + alertActions.success({ + message: "Sửa kế hoạch thành công", + screen: scheduleConstants.SCREEN_ADD_SCHEDULE_YEAR, + }) + ); + dispatch(getScheduleYear(data.year)); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: scheduleConstants.SCREEN_ADD_SCHEDULE_YEAR, + }) + ); + } + ); + }; +} + +function deleteScheduleYear(data) { + return (dispatch) => { + return apiCaller( + "/API_schedule_year/edit_schedule_year", + "PUT", + data, + null, + true + ).then( + () => { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + dispatch( + alertActions.success({ + message: "Xóa kế hoạch thành công", + screen: scheduleConstants.SCREEN_ADD_SCHEDULE_YEAR, + }) + ); + dispatch(getScheduleYear(data.year)); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: scheduleConstants.SCREEN_ADD_SCHEDULE_YEAR, + }) + ); + } + ); + }; +} + +function completeSchedule(data, user_id, time) { + // var urlencoded = new URLSearchParams(); + // urlencoded.append("id", data.id); + // urlencoded.append("status", data.status); + return (dispatch) => { + return apiCaller( + "/API_schedule/edit_schedule", + "PUT", + data, + null, + true + ).then(() => { + dispatch(getScheduleToday(user_id, time)); + dispatch( + getStatus( + moment(time).format("MM"), + moment(time).format("YYYY"), + "teacher" + ) + ); + }); + }; +} + +function getStatus(month, year, role = "", student_id = "", class_id) { + let uri = "/API_schedule/schedule_status?month=" + month + "&year=" + year; + if (role === "teacher") { + } else if (role === "student") { + uri = + "/api_student/log_learning_status?student_id=" + + student_id + + (class_id ? "&class_id=" + class_id : "") + + "&month=" + + month + + "&year=" + + year; + } else { + if (localStorage.getItem("authentication")) { + let authentication = JSON.parse(localStorage.getItem("authentication")); + if (authentication.role === "student") { + uri = + "/api_student/log_learning_status?student_id=" + + authentication.id + + (class_id ? "&class_id=" + class_id : "") + + "&month=" + + month + + "&year=" + + year; + } + } + } + + return (dispatch) => { + return apiCaller(uri, "GET", {}, null, true).then((status) => { + let in_complete = []; + let complete = []; + let has_log = []; + forEach(status.data, function (value) { + if (value.status === "in_complete") { + in_complete.push(value.date); + } + if (value.status === "complete") { + complete.push(value.date); + } + if (value.status === "has_log") { + has_log.push(value.date); + } + }); + dispatch({ + type: scheduleConstants.GET_STATUS, + data: { + in_complete, + complete, + has_log, + }, + }); + }); + }; +} + +function getScheduleStatus(month, year) { + let uri = "/API_schedule/schedule_status?month=" + month + "&year=" + year; + + return (dispatch) => { + return apiCaller(uri, "GET", {}, null, true).then((status) => { + let in_complete = []; + let complete = []; + let has_log = []; + forEach(status.data, function (value) { + if (value.status === "in_complete") { + in_complete.push(value.date); + } + if (value.status === "complete") { + complete.push(value.date); + } + if (value.status === "has_log") { + has_log.push(value.date); + } + }); + dispatch({ + type: scheduleConstants.GET_STATUS, + data: { + in_complete, + complete, + has_log, + }, + }); + }); + }; +} diff --git a/src/_actions/students.js b/src/_actions/students.js new file mode 100644 index 0000000..9019669 --- /dev/null +++ b/src/_actions/students.js @@ -0,0 +1,563 @@ +import { apiCaller, history } from "./../_helpers"; +import { + studentConstants, + curriculumConstants, + teacherConstants, + popupConstants, + configConstants, +} from "./../_constants"; +import { alertActions } from "./"; +import $ from "jquery"; +import { studentService } from "../_services"; + +export const studentActions = { + getAllGrade, + getExerciseByTeacherId, + getExerciseByTeacherIdV2, + getExerciseByCurriculumId, + getDetailCurriculumById, + getDataMapCurriculum, + getDataMapByClassId, + getDataGridCurriculum, + getListCurriculum, + getLessonCurriculum, + getListClass, + addParent, + checkParent, + applyForClass, + checkClass, + getAssessmentsOnline, + getLogLearningByDate, + getListLogLearning, + updateDefaultCurriculum, + updateDefaultCurriculumFirst, + getExerciseByParentIdV2 +}; + +function getAllGrade(data) { + return (dispatch) => { + return apiCaller("/api_login/grade", "GET", data, null, false).then( + (grade) => { + dispatch({ + type: studentConstants.GET_ALL_GRADE, + grade: grade.list_grade, + }); + } + ); + }; +} + +function getExerciseByTeacherId(teacher_id) { + return (dispatch) => { + return apiCaller( + "/api_student/homework_by_teacher_homepage?teacher_id=" + teacher_id, + "GET", + {}, + null, + false + ).then((exercises) => { + dispatch({ + type: studentConstants.GET_LIST_EXERCISE_STUDENT, + exercises, + }); + }); + }; +} + +function getExerciseByTeacherIdV2(teacher_id) { + $(".loading-side").removeClass("hide"); + return (dispatch) => { + return apiCaller( + "/api_student/homework_by_teacher?teacher_id=" + teacher_id, + "GET", + {}, + null, + false, + configConstants.API_URL_SETEST, + false + ).then((exercises) => { + dispatch({ + type: studentConstants.GET_LIST_EXERCISE_STUDENT, + exercises, + }); + + $(".loading-side").addClass("hide"); + }); + }; +} + +function getExerciseByParentIdV2(parent_id) { + $(".loading-side").removeClass("hide"); + return (dispatch) => { + return apiCaller( + "/api_student/homework_by_parent?parent_id=" + parent_id, + "GET", + {}, + null, + false, + configConstants.API_URL_SETEST, + false + ).then((exercises) => { + dispatch({ + type: studentConstants.GET_LIST_EXERCISE_STUDENT, + exercises, + }); + + $(".loading-side").addClass("hide"); + }); + }; +} + +function getExerciseByCurriculumId(curriculum_id) { + $(".loading-side").removeClass("hide"); + return (dispatch) => { + return apiCaller( + "/api_student/exercise_by_curriculum?curriculum_id=" + curriculum_id, + "GET", + {}, + null, + false, + configConstants.API_URL_SETEST, + false + ).then((exercises) => { + const modifiedExercises = { + ...exercises, + list_home_work: exercises.list_home_work?.map((homework) => ({ + ...homework, + curriculum_id: curriculum_id, + })), + }; + dispatch({ + type: studentConstants.GET_LIST_EXERCISE_STUDENT, + exercises: modifiedExercises, + }); + $(".loading-side").addClass("hide"); + }); + }; +} + +function getDetailCurriculumById(id) { + return (dispatch) => { + return apiCaller( + "/student/api_student_curriculum/map_unit?curriculum_id=" + id, + "GET", + {}, + null, + true + ).then((curriculum) => { + dispatch({ + type: curriculumConstants.GET_DETAIL_CURRICULUM, + curriculum, + }); + }); + }; +} + +function getDataMapCurriculum(id) { + return (dispatch) => { + return apiCaller( + "/student/api_student_curriculum/map_unit?curriculum_id=" + id, + "GET", + {}, + null, + true + ).then((data_map) => { + dispatch({ + type: curriculumConstants.GET_DATA_MAP_CURRICULUM_STUDENT, + data_map, + }); + }); + }; +} + +function getDataMapByClassId(id) { + return (dispatch) => { + return apiCaller( + "/student/api_student_curriculum/map_unit?class_id=" + id, + "GET", + {}, + null, + true + ).then((data_map) => { + dispatch({ + type: curriculumConstants.GET_DATA_MAP_CURRICULUM_STUDENT, + data_map, + }); + }); + }; +} + +function getDataGridCurriculum(id, isLoading) { + return (dispatch) => { + return apiCaller( + "/api_class/class_curriculum?curriculum_id=" + id, + "GET", + {}, + null, + true, + configConstants.API_URL_SETEST, + isLoading + ).then((data_grid) => { + dispatch({ + type: curriculumConstants.GET_DATA_GRID_CURRICULUM_STUDENT, + data_grid, + }); + }); + }; +} + +function getListCurriculum() { + return (dispatch) => { + return apiCaller( + "/student/api_student_curriculum/courses_name_follow_class_v2", + "GET", + {}, + null, + true + ).then((data_grid) => { + dispatch({ + type: curriculumConstants.GET_LIST_CURRICULUM_STUDENT, + data_grid, + }); + }); + }; +} + +function getLessonCurriculum(unit_id, isLoading) { + return (dispatch) => { + return apiCaller( + "/student/api_student_curriculum/lessons_by_skill?unit_id=" + unit_id, + "GET", + {}, + null, + true, + configConstants.API_URL_SETEST, + isLoading ?? true + ) + .then((lessons) => { + dispatch({ + type: curriculumConstants.GET_LESSON_CURRICULUM_STUDENT, + lessons, + }); + }) + .catch((error) => { + dispatch( + alertActions.success({ + message: error.toString(), + screen: studentConstants.SCREEN_LESSSON_SKILL, + }) + ); + }); + }; +} + +function getListClass() { + return (dispatch) => { + return apiCaller("/api_class/my_classes", "GET", {}, null, true).then( + (classes) => { + dispatch({ + type: teacherConstants.GET_LIST_CLASS, + classes: classes, + }); + } + ); + }; +} + +function checkParent(data) { + return async (dispatch) => { + try { + const resCheckParent = await studentService.checkParent(data?.user_code) + if(!!resCheckParent?.status) { + const infoParent = resCheckParent?.data + const addStudent = { + user_data: { + ...infoParent, + user_code: data.user_code + } + }; + dispatch({ + type: popupConstants.SHOW_FORM_POPUP, + data: { + showFormAddStudent: true, + }, + }); + dispatch(alertActions.clear()); + dispatch({ + type: teacherConstants.ADD_STUDENT, + data: addStudent, + }); + } else { + const statusRelationship = resCheckParent?.statusRelationship + let isShowPopup = false; + let hasBtnClosePopup = false; + let textComplete = ''; + let textClose = ''; + let onComplete = () => { + history.goBack() + } + if (statusRelationship === 1) { + isShowPopup=true + } else if(statusRelationship === 2) { + isShowPopup = true; + hasBtnClosePopup = true; + textComplete = 'Đồng ý'; + textClose = 'Không'; + onComplete = async () => { + try { + const res = await studentService.acceptInvitationParent({parent_id: resCheckParent?.parent_id}) + dispatch(alertActions.clear()) + dispatch( + alertActions.success({ + message: res?.msg, + screen: studentConstants.SCREEN_ADD_PARENT, + isShowPopup, + onComplete: () => { + history.goBack() + }, + }) + ); + } catch (err) { + dispatch(alertActions.clear()) + dispatch( + alertActions.error({ + message: err.toString(), + screen: studentConstants.SCREEN_ADD_PARENT, + isShowPopup + }) + ); + } + } + } + dispatch( + alertActions.error({ + message: resCheckParent?.msg, + screen: studentConstants.SCREEN_ADD_PARENT, + isShowPopup, + onComplete, + hasBtnClosePopup, + textComplete, + textClose, + }) + ); + } + } catch (error) { + dispatch( + alertActions.error({ + message: error.toString(), + screen: studentConstants.SCREEN_ADD_PARENT, + }) + ); + } + }; +} + +function addParent(data) { + return (dispatch) => { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + return apiCaller( + "/api_relationship/send_request", + "POST", + data, + null, + false + ).then( + (res) => { + if ( + res.code === null || + res.code === "MTY0OTc4MTc5NA==" || + res.msg === + "Bạn đã tạo link liên kết với tài khoản này trước đó. Vui lòng đợi phụ huynh xác nhận." + ) { + dispatch( + alertActions.error({ + message: + "Bạn đã gửi yêu cầu liên kết với tài khoản này trước đó. Vui lòng đợi phụ huynh xác nhận.", + screen: studentConstants.SCREEN_ADD_PARENT, + }) + ); + } else { + dispatch( + alertActions.success({ + message: studentConstants.ADD_PARENT_COMPLETE, + screen: studentConstants.SCREEN_ADD_PARENT, + }) + ); + } + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: studentConstants.SCREEN_ADD_PARENT, + }) + ); + } + ); + }; +} + +function applyForClass(data) { + return (dispatch) => { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + return apiCaller( + "/api_class/class_request", + "POST", + data, + null, + false + ).then( + (data) => { + dispatch( + alertActions.success({ + message: data.msg, + screen: studentConstants.SCREEN_APPLY_CLASS, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: studentConstants.SCREEN_APPLY_CLASS, + }) + ); + } + ); + }; +} + +function checkClass(data) { + return (dispatch) => { + return apiCaller( + "/api_class/code?class_code=" + data.class_code, + "GET", + {}, + null, + false + ).then( + (applyClass) => { + applyClass.class_data.class_code = data.class_code; + dispatch({ + type: popupConstants.SHOW_FORM_POPUP, + data: { + showFormApplyClass: true, + }, + }); + dispatch(alertActions.clear()); + dispatch({ + type: teacherConstants.GET_DETAIL_CLASS, + class: applyClass, + }); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: studentConstants.SCREEN_APPLY_CLASS, + }) + ); + } + ); + }; +} + +function getAssessmentsOnline(student_id) { + return (dispatch) => { + return apiCaller( + "/api_student/student_assessment?student_id=" + student_id, + "GET", + {}, + null, + true + ).then((assessments) => { + if (assessments.data_assessment) { + dispatch({ + type: studentConstants.GET_ASSESSMENT_ONLINE, + assessments, + }); + } + }); + }; +} + +function getLogLearningByDate(date, id) { + return (dispatch) => { + return apiCaller( + `/api_student/log_learning_by_date?date=${date}&student_id=${id}`, + "GET", + {}, + null, + true + ).then((learnings) => { + dispatch({ + type: studentConstants.GET_LOG_LEARNING_BY_DATE, + learnings, + }); + }); + }; +} + +function getListLogLearning(from_time, student_id) { + return (dispatch) => { + return apiCaller( + "/api_student/student_log_learning?from_time=" + + from_time + + "&student_id=" + + student_id, + "GET", + {}, + null, + true + ).then((learnings) => { + dispatch({ + type: studentConstants.GET_LIST_LOG_LEARNING, + learnings, + }); + }); + }; +} + +function updateDefaultCurriculum(curriculumId) { + let data = { + curriculum_id: curriculumId, + }; + return apiCaller( + "/api_student/save_default_curriculum", + "POST", + data, + null, + false + ).then( + (res) => { + return res; + }, + (error) => { + return false; + } + ); +} + +function updateDefaultCurriculumFirst(curriculumId) { + let data = { + curriculum_id: curriculumId, + }; + return apiCaller( + "/api_student/save_user_curriculum", + "POST", + data, + null, + false + ).then( + (res) => { + return res; + }, + (error) => { + return false; + } + ); +} diff --git a/src/_actions/teachers.js b/src/_actions/teachers.js new file mode 100644 index 0000000..c04a5ca --- /dev/null +++ b/src/_actions/teachers.js @@ -0,0 +1,1776 @@ +import { apiCaller } from "./../_helpers"; +import { + configConstants, + teacherConstants, + userConstants, + curriculumConstants, + popupConstants, + scheduleConstants, +} from "./../_constants"; +import { alertActions } from "./"; +import { history } from "../_helpers"; +import { teacherService } from "../_services"; +import moment from "moment"; +import { Link } from "react-router-dom"; +import { HashLink } from "react-router-hash-link"; +import { isEmpty } from "lodash"; +import $ from "jquery"; + +export const teacherActions = { + getListClass, + getListClassOffline, + getDetailClass, + addClass, + updateClassById, + getStudentOfClass, + addStudent, + checkStudent, + getRequestStudent, + acceptRequestStudent, + rejectRequestStudent, + removeStudent, + removeStudentOffline, + getCurriculum, + getCurriculumV2, + getCurriculumPersonal, + addCurriculum, + removeCurriculum, + getDetailCurriculumOfClass, + editCurriculum, + getDetailCurriculumById, + getCurriculumFavorite, + getCurriculumFavoriteV2, + filterSkill, + getHistoryExercise, + getDetailExercise, + udpateExercise, + getFileExercise, + addExercise, + getListHomeWork, + getDetailHomeWork, + getDetailHomeWorkExercise, + updatelHomeWorkExercise, + getProfile, + updateProfile, + callAIHomeWork, + getStudentRanking, + getClassRanking, + getDetailClassOffline, + createRollUp, + updateRollUp, + getExamcardOffline, + createExamCard, + updateExamCard, + deleteFileExercise, + addFileResource, + getReportClass, + getReportByStudentId, + getReportByStudentIdByDateTime, + getLogLearningByStudentId, + resetPassword, + getHistoryExerciseWithoutClass, + getDetailExerciseWithoutClass, + updateCriteria, + getListCriteria, + remindStudent, + addWish, + removeWish, + getRollUpById, + deleteClassById, + getProfileNews, + getLogLearningByDate, + getProfileV2, +}; + +function hasDuplicates(array1, array2) { + var combinedArray = array1.concat(array2); + return new Set(combinedArray).size !== combinedArray.length; +} + +function getListClass(screen, exercises = false, loadingCommond = true) { + !loadingCommond && $(".loading-side").removeClass("hide"); + return (dispatch) => { + return apiCaller( + `/api_teacher/my_classes?screen=${screen}`, + "GET", + {}, + null, + true, + configConstants.API_URL_SETEST, + loadingCommond + ).then((classes) => { + dispatch({ + type: teacherConstants.GET_LIST_CLASS, + classes: classes, + }); + + if (exercises === true) { + if (classes.data.length === 1) { + history.push( + "/teacher/class/view/" + classes.data[0].id + "/exercise/student" + ); + } else { + history.push("/teacher/curriculum/exercise/class"); + } + } + + !loadingCommond && $(".loading-side").addClass("hide"); + }); + }; +} + +function getListClassOffline() { + return (dispatch) => { + return apiCaller( + "/api_class_offline/my_classes", + "GET", + {}, + null, + true, + configConstants.API_URL_SETEST, + false + ).then((classes) => { + dispatch({ + type: teacherConstants.GET_LIST_CLASS_OFFLINE, + classes: classes, + }); + }); + }; +} + +function getDetailClass(id, type) { + return (dispatch) => { + return apiCaller("/api_class/class?id=" + id, "GET", {}, null, true).then( + (dataClass) => { + // console.log(dataClass); + dispatch({ + type: teacherConstants.GET_DETAIL_CLASS, + class: dataClass.data, + }); + if (type !== "ONLY_DATA_CLASS") { + dispatch( + teacherActions.getDetailCurriculumOfClass( + dataClass.data.curriculum_id + ) + ); + } + } + ); + }; +} + +function getDetailClassOffline(id) { + return (dispatch) => { + return apiCaller( + "/api_class_offline/class?id=" + id, + "GET", + {}, + null, + true + ).then((dataClass) => { + dispatch({ + type: teacherConstants.GET_DETAIL_CLASS_OFFLINE, + class: dataClass, + }); + }); + }; +} + +function addClass(data, page) { + return (dispatch) => { + return apiCaller("/api_class/class", "POST", data, null, true).then( + () => { + if (page == "homepage") { + dispatch( + alertActions.success({ + message: teacherConstants.MESSAGE_ADD_CLASS_COMPLETE, + screen: teacherConstants.SCREEN_HOME_PAGE, + }) + ); + } else { + dispatch( + alertActions.success({ + message: teacherConstants.MESSAGE_ADD_CLASS_COMPLETE, + screen: teacherConstants.SCREEN_ADD_CLASS, + }) + ); + } + }, + (error) => { + if (page == "homepage") { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_HOME_PAGE, + }) + ); + } else { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_ADD_CLASS, + }) + ); + } + } + ); + }; +} + +function updateClassById(data) { + return (dispatch) => { + return apiCaller("/api_class/class_edit", "POST", data, null, true).then( + () => { + dispatch( + alertActions.success({ + message: "Chỉnh sửa lớp học thành công", + screen: teacherConstants.SCREEN_ADD_CLASS, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_ADD_CLASS, + }) + ); + } + ); + }; +} + +function deleteClassById(id) { + var urlencoded = new URLSearchParams(); + urlencoded.append("class_id", id); + + return (dispatch) => { + return apiCaller("/api_class/class", "DELETE", urlencoded, null, true).then( + () => { + dispatch( + alertActions.success({ + message: "Giải tán lớp thành công", + screen: teacherConstants.SCREEN_ADD_CLASS, + }) + ); + // dispatch(getListClass()); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_ADD_CLASS, + }) + ); + } + ); + }; +} + +function getStudentOfClass( + id, + limit = configConstants.DEFAULT_LIMIT, + offset = 0 +) { + return (dispatch) => { + return teacherService + .getStudentOfClass(id, limit, offset) + .then((students) => { + dispatch({ + type: teacherConstants.GET_STUDENT_OFF_CLASS, + students, + }); + return students; + }); + }; +} + +function checkStudent(data) { + return (dispatch) => { + return apiCaller( + "/api_user/code?user_code=" + data.user_code, + "GET", + {}, + null, + false + ).then( + (addStudent) => { + addStudent.user_data.user_code = data.user_code; + dispatch({ + type: popupConstants.SHOW_FORM_POPUP, + data: { + showFormAddStudent: true, + }, + }); + dispatch(alertActions.clear()); + dispatch({ + type: teacherConstants.ADD_STUDENT, + data: addStudent, + }); + }, + (error) => { + if (error.toString() == "Server Error") { + dispatch( + alertActions.error({ + message: "Không tìm thấy tài khoản", + screen: teacherConstants.SCREEN_ADD_STUDENT, + }) + ); + } else { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_ADD_STUDENT, + }) + ); + } + } + ); + }; +} + +function addStudent(data) { + return (dispatch) => { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + return apiCaller("/api_class/add_student", "POST", data, null, false).then( + () => { + dispatch( + alertActions.success({ + message: teacherConstants.ADD_STUDENT_COMPLETE, + screen: teacherConstants.SCREEN_ADD_STUDENT, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_ADD_STUDENT, + }) + ); + } + ); + }; +} + +function getRequestStudent(id) { + return (dispatch) => { + return apiCaller( + "/api_class/class_member_request?class_id=" + id, + "GET", + {}, + null, + true + ).then((requests) => { + dispatch({ + type: teacherConstants.GET_STUDENT_REQUEST, + requests: requests, + }); + }); + }; +} + +function acceptRequestStudent(data, final = false) { + var urlencoded = new URLSearchParams(); + urlencoded.append("class_id", data.class_id); + urlencoded.append("list_request_id", JSON.stringify(data.list_request_id)); + return (dispatch) => { + return apiCaller( + "/api_class/accept_member_request", + "PUT", + urlencoded, + null, + true + ).then( + () => { + dispatch( + alertActions.success({ + message: "Duyệt học sinh thành công", + screen: teacherConstants.SCREEN_REVIEW_STUDENT, + }) + ); + if (final) { + setTimeout(() => { + history.push("/teacher/class/view/" + data.class_id + "/student"); + }, 2000); + } else { + dispatch(getRequestStudent(data.class_id)); + } + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_REVIEW_STUDENT, + }) + ); + } + ); + }; +} + +function rejectRequestStudent(data, final = false) { + var urlencoded = new URLSearchParams(); + urlencoded.append("class_id", data.class_id); + urlencoded.append("list_request_id", JSON.stringify(data.list_request_id)); + return (dispatch) => { + return apiCaller( + "/api_class/reject_member_request", + "PUT", + urlencoded, + null, + true + ).then( + () => { + dispatch( + alertActions.success({ + message: "Từ chối học sinh thành công", + screen: teacherConstants.SCREEN_REVIEW_STUDENT, + }) + ); + if (final) { + setTimeout(() => { + history.push("/teacher/class/view/" + data.class_id + "/student"); + }, 2000); + } else { + dispatch(getRequestStudent(data.class_id)); + } + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_REVIEW_STUDENT, + }) + ); + } + ); + }; +} + +function removeStudent(data) { + var urlencoded = new URLSearchParams(); + urlencoded.append("id", data.id); + urlencoded.append("students", JSON.stringify([data.students])); + return apiCaller("/api_class/students", "DELETE", urlencoded, null, false); +} + +function removeStudentOffline(member_id) { + var urlencoded = new URLSearchParams(); + urlencoded.append("class_member_id", member_id); + return apiCaller( + "/api_class_offline/student", + "DELETE", + urlencoded, + null, + false + ); +} + +function addCurriculum(data) { + return (dispatch) => { + return apiCaller( + "/api_class/class_curriculum", + "POST", + data, + null, + true + ).then(() => { + dispatch( + alertActions.success({ + message: "Thêm giáo trình thành công", + screen: curriculumConstants.ADD_CURRICULUM, + }) + ); + }); + }; +} + +function editCurriculum(data) { + return (dispatch) => { + return apiCaller( + "/api_class/class_curriculum_edit", + "PUT", + data, + null, + true + ).then(() => { + dispatch( + alertActions.success({ + message: "Thay giáo trình thành công", + screen: curriculumConstants.ADD_CURRICULUM, + }) + ); + }); + }; +} + +function removeCurriculum(data) { + var urlencoded = new URLSearchParams(); + urlencoded.append("curriculum_id", data.curriculum_id); + urlencoded.append("class_id", data.class_id); + return (dispatch) => { + return apiCaller( + "/api_class/class_curriculum", + "DELETE", + urlencoded, + null, + true + ).then(() => { + dispatch( + alertActions.success({ + message: "Xoá giáo trình thành công", + screen: curriculumConstants.SCREEN_DETAIL_CURRICULUM, + }) + ); + dispatch({ + type: curriculumConstants.CLEAR_DETAIL_CURRICULUM, + }); + dispatch(getDetailClass(data.class_id)); + }); + }; +} + +function getCurriculum(type, exercise = false) { + return (dispatch) => { + return apiCaller( + "/api_curriculum/courses_name?type=" + type, + "GET", + {}, + null, + true + ).then((curriculums) => { + let type = exercise + ? curriculumConstants.GET_LIST_CURRICULUM_EXERCISE + : curriculumConstants.GET_LIST_CURRICULUM; + dispatch({ + type, + curriculums: curriculums.courses, + }); + }); + }; +} + +function getCurriculumV2(type) { + return apiCaller( + "/api_curriculum/courses_name?type=" + type, + "GET", + {}, + null, + true, + configConstants.API_URL_SETEST, + false + ).then((curriculums) => { + return curriculums.courses; + }); +} + +function getCurriculumPersonal(type, exercise = false) { + return apiCaller( + "/api_curriculum/courses_name?type=" + type, + "GET", + {}, + null, + true + ).then((curriculums) => { + return curriculums.courses; + }); +} + +function getDetailCurriculumOfClass(curriculum_id) { + return (dispatch) => { + return apiCaller( + "/api_class/class_curriculum?curriculum_id=" + curriculum_id, + "GET", + {}, + null, + true + ).then( + (curriculum) => { + // console.log(curriculum); + dispatch({ + type: curriculumConstants.GET_DETAIL_CURRICULUM_CLASS, + curriculum: curriculum.data, + }); + }, + () => { + dispatch({ + type: curriculumConstants.CLEAR_DETAIL_CURRICULUM_CLASS, + }); + } + ); + }; +} + +function getDetailCurriculumById(id) { + return (dispatch) => { + return apiCaller( + "/api_curriculum/course?id=" + id, + "GET", + {}, + null, + true + ).then((curriculum) => { + dispatch({ + type: curriculumConstants.GET_DETAIL_CURRICULUM, + curriculum, + }); + }); + }; +} + +function getCurriculumFavorite(user_id) { + return (dispatch) => { + dispatch({ + type: curriculumConstants.GET_LIST_CURRICULUM_FAVORITE_START, + }); + return apiCaller( + "/api_wish_list/my_wish_list?user_id=" + user_id, + "GET", + {}, + null, + true + ).then((curriculums) => { + dispatch({ + type: curriculumConstants.GET_LIST_CURRICULUM_FAVORITE, + curriculums, + }); + }); + }; +} + +function getCurriculumFavoriteV2(user_id, limit, offset) { + return apiCaller( + "/api_wish_list/my_wish_list?user_id=" + + user_id + + `&limit=${limit}&offset=${offset}`, + "GET", + {}, + null, + true + ).then((curriculums) => { + return curriculums; + }); +} + +function filterSkill( + filter, + class_id, + limit, + offset, + filterCurriculum, + listDataPrev, + fromPage, + assignAndUserID +) { + return (dispatch) => { + return apiCaller( + ( + `/api_curriculum/search_lesson?${ + filterCurriculum == "filterCurriculum" + ? `limit=${limit}&offset=${offset}&` + : "" + }topic=` + + filter.topic + + "&skill=" + + JSON.stringify(filter.skill) + + "&grade_id=" + + JSON.stringify(filter.grade_id) + + "&level=" + + JSON.stringify(filter.level) + ).toLowerCase(), + "GET", + {}, + null, + true + ).then((data) => { + if (filterCurriculum == "filterCurriculum") { + if (!hasDuplicates(data.list_data_result, listDataPrev)) { + dispatch({ + type: curriculumConstants.ADD_PARAM_FILTER_CURRICULUM, + param: filter, + }); + dispatch({ + type: curriculumConstants.GET_FILTER_CURRICULUM, + data: data.list_data_result.concat(...listDataPrev), + }); + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + if (class_id) { + // history.push("/teacher/curriculum/filter/" + class_id); + history.replace("/teacher/curriculum/filter/" + class_id); + } else { + history.replace( + `/teacher/curriculum/filter?${ + !isEmpty(fromPage) ? `page=${fromPage}` : "" + }`, + { + curriculum_sunday: true, + } + ); + } + } + } else { + dispatch({ + type: curriculumConstants.ADD_PARAM_FILTER_CURRICULUM, + param: filter, + }); + dispatch({ + type: curriculumConstants.GET_FILTER_CURRICULUM, + data: data.list_data_result, + }); + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + if (class_id) { + // history.push("/teacher/curriculum/filter/" + class_id); + history.replace("/teacher/curriculum/filter/" + class_id); + } else { + history.replace( + !isEmpty(assignAndUserID) + ? `/teacher/curriculum/filter?${ + !isEmpty(assignAndUserID) + ? `assign=${assignAndUserID.assign}&user_id=${assignAndUserID.user_id}` + : "" + }` + : `/teacher/curriculum/filter?${ + !isEmpty(fromPage) ? `page=${fromPage}` : "" + }`, + { + curriculum_sunday: true, + } + ); + } + } + + return data; + }); + }; +} + +function getHistoryExercise( + class_id, + param = { skill: [], level: [], start_time: "", end_time: "" }, + type, + limitDefault, + offset, + prevState +) { + let uri = + type == "class" + ? `/api_class/class_homework_v2?&limit=${limitDefault}&offset=${offset}&class_id=${class_id}&type=class` + : type == "class_mark" + ? `/api_class/class_homework_v2?&limit=${limitDefault}&offset=${offset}&class_id=` + + class_id + + "&type=class_mark" + : `/api_class/class_homework_v2?&type=class&limit=${limitDefault}&offset=${offset}&class_id=` + + class_id; + if (param.skill?.length) { + param.skill.forEach((skill) => { + uri += "&skill[]=" + skill.toLocaleLowerCase(); + }); + } + if (param.level?.length) { + param.level.forEach((skill) => { + uri += "&level[]=" + skill.toLocaleLowerCase(); + }); + } + if (param.start_time) { + uri += "&start_time=" + JSON.stringify(param.start_time); + } + if (param.end_time) { + uri += "&end_time=" + JSON.stringify(param.end_time); + } + return (dispatch) => { + return apiCaller(uri, "GET", {}, null, true).then((histories) => { + if (!hasDuplicates(prevState, histories.data)) { + dispatch({ + type: teacherConstants.GET_LIST_HISTORY_EXERCISE, + histories: histories.data.concat(...prevState), + }); + dispatch({ + type: teacherConstants.GET_LIST_HOMEWORK, + homeworks: histories.data.concat(...prevState), + }); + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + } + return histories; + }); + }; +} + +function getHistoryExerciseWithoutClass( + param = { skill: [] }, + filter_time = false +) { + let uri = "/api_class/class_homework_v2?limit=999&offset=0"; + param.skill.forEach((skill) => { + uri += "&skill[]=" + skill.toLocaleLowerCase(); + }); + if (filter_time) { + uri += + "&start_time=" + + JSON.stringify(param.start_time) + + "&end_time=" + + JSON.stringify(param.end_time); + } + return (dispatch) => { + return apiCaller(uri, "GET", {}, null, true).then((histories) => { + dispatch({ + type: teacherConstants.GET_LIST_HISTORY_EXERCISE, + histories: histories.data, + }); + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + }); + }; +} + +function getDetailExercise(class_id, exercise_id) { + return (dispatch) => { + return apiCaller( + "/api_class/class_homework_detail?class_id=" + + class_id + + "&exercise_id=" + + exercise_id, + "GET", + {}, + null, + true + ).then((histories) => { + dispatch({ + type: teacherConstants.GET_DETAIL_HISTORY_EXERCISE, + histories: histories, + }); + }); + }; +} + +function getDetailExerciseWithoutClass(exercise_id, skill, curriculum_id) { + return (dispatch) => { + return apiCaller( + "/api_wish_list/wish_list_history?exercise_id=" + + exercise_id + + (skill ? "&lesson_type=exam" : "") + + `&curriculum_id=${curriculum_id}`, + "GET", + {}, + null, + true + ).then((histories) => { + dispatch({ + type: teacherConstants.GET_DETAIL_HISTORY_EXERCISE, + histories: histories, + }); + }); + }; +} + +function udpateExercise(data) { + var urlencoded = new URLSearchParams(); + urlencoded.append("class_id", data.class_id); + urlencoded.append("start_time", data.start_time); + urlencoded.append("end_time", data.end_time); + urlencoded.append("before_start_time", data.before_start_time); + urlencoded.append("note", data.note); + urlencoded.append("exercise_id", data.exercise_id); + urlencoded.append("remind_before", data.remind_before); + urlencoded.append("students", JSON.stringify(data.students)); + return (dispatch) => { + return apiCaller( + "/api_class/class_homework", + "PUT", + urlencoded, + null, + true + ).then( + () => { + dispatch( + alertActions.success({ + message: "Cập nhật bài thành công", + screen: teacherConstants.SCREEN_ADD_STUDENT_EXERCISE, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_ADD_STUDENT_EXERCISE, + }) + ); + } + ); + }; +} + +function getProfile(id) { + return (dispatch) => { + return apiCaller("/api_user/user?id=" + id, "GET", {}, null, true).then( + (data) => { + localStorage.setItem("info_header_user", JSON.stringify(data.data)); + dispatch({ + type: userConstants.GET_PROFILE, + data: data.data, + base_url: data.base_url, + }); + } + ); + }; +} + +function getProfileV2(id) { + return (dispatch) => { + return apiCaller( + "/api_profile/profile?id=" + id, + "GET", + {}, + null, + true + ).then((data) => { + // console.log(data); + + const convertData = { + ...data.user, + // add other objects to the user object + parent_info: data?.parent_info, + parent_exercise: data?.parent_exercise, + teacher_exercise: data?.teacher_exercise, + class_exercise: data?.class_exercise, + package: data?.package, + }; + + dispatch({ + type: userConstants.GET_PROFILE, + data: convertData, + base_url: data.base_url, + }); + + let authentication = JSON.parse(localStorage.getItem("authentication")); + authentication?.isLogin && + dispatch({ + type: userConstants.LOGIN, + user: { + ...authentication, + curriculum_default: data.user?.curriculum_default, + fullname: data.user?.fullname, + avatar: configConstants.BASE_URL + data.user?.avatar, + birthday: data.user?.birthday, + school: data.user?.school, + class: data.user?.class, + phone: data.user?.phone, + gender: data.user?.gender, + grade_id: data.user?.grade_id, + total_diamond: data.user?.total_diamond, + package: data?.package, + }, + }); + }); + }; +} + +function getProfileNews(id) { + return (dispatch) => { + return apiCaller( + "/api_profile/profile?id=" + id, + "GET", + {}, + null, + true + ).then((data) => { + // console.log(data); + dispatch({ + type: userConstants.GET_PROFILE_NEWS, + data: data.user, + base_url: data.base_url, + }); + }); + }; +} + +function updateProfile(data) { + return (dispatch) => { + return apiCaller("/api_user/user", "PUT", data, null, false).then( + () => { + dispatch( + alertActions.success({ + message: userConstants.MESSAGE_UPDATE_PROFILE_COMPLETE, + screen: userConstants.SCREEN_UPDATE_PROFILE, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: userConstants.SCREEN_UPDATE_PROFILE, + }) + ); + } + ); + }; +} + +function getFileExercise(param, clear_popup = true) { + return (dispatch) => { + return apiCaller( + "/api_resources/my_resources?type=" + + JSON.stringify(param.type) + + "&skill=" + + JSON.stringify(param.skill) + + "&grade_id=" + + JSON.stringify(param.grade_id), + "GET", + {}, + null, + true + ).then((files) => { + dispatch({ + type: teacherConstants.ADD_DATA_FILE, + data: files.resources, + }); + if (clear_popup) { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + } + }); + }; +} + +function addExercise(data) { + var urlencoded = new URLSearchParams(); + urlencoded.append("students", JSON.stringify(data.students)); + urlencoded.append("data_exercise", JSON.stringify(data.data_exercise)); + urlencoded.append("before_start_time", data.before_start_time); + urlencoded.append("class_id", data.class_id); + urlencoded.append("note", data.note); + urlencoded.append("remind_before", data.remind_before); + urlencoded.append("end_time", data.end_time); + return (dispatch) => { + return apiCaller( + "/api_class/give_homework", + "POST", + urlencoded, + null, + true + ).then( + () => { + dispatch( + alertActions.success({ + message: "Giao bài thành công", + screen: teacherConstants.SCREEN_ADD_EXERCISE, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_ADD_EXERCISE, + }) + ); + } + ); + }; +} + +function getListHomeWork(class_id, type, limit, offset, listHomeWork) { + // const url = `/api_class/class_homework_v2?class_id=${class_id}&type=${type}&limit=${limit}&offset=${offset}`; + const url = `/api_class/class_homework_v2?class_id=${class_id}&type=${type}`; + return (dispatch) => { + return apiCaller(url, "GET", {}, null, true).then((homeworks) => { + if (!hasDuplicates(homeworks.data, listHomeWork)) { + dispatch({ + type: teacherConstants.GET_LIST_HOMEWORK, + homeworks: homeworks.data, + }); + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + } + return homeworks; + }); + }; +} + +function getDetailHomeWork(class_id, exercise_id, library, type) { + return (dispatch) => { + return apiCaller( + "/api_class/home_work_detail?class_id=" + + class_id + + "&exercise_id=" + + exercise_id + + "&library=" + + library + + "&type=" + + type, + "GET", + {}, + null, + true + ).then((homeworks) => { + dispatch({ + type: teacherConstants.GET_DETAIL_HOMEWORK, + homeworks: homeworks, + }); + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + }); + }; +} + +function getDetailHomeWorkExercise(user_exercise_id, library, exercise_type) { + return (dispatch) => { + return apiCaller( + "/student/api_homework/homework_detail?user_exercise_id=" + + user_exercise_id + + "&library=" + + library + + "&exercise_type=" + + exercise_type, + "GET", + {}, + null, + true + ).then((exercises) => { + dispatch({ + type: teacherConstants.GET_DETAIL_HOMEWORK_EXERCISE, + exercises: exercises, + }); + }); + }; +} + +function updatelHomeWorkExercise(data, messageSuccess) { + var urlencoded = new URLSearchParams(); + urlencoded.append( + "json_criteria_score", + JSON.stringify(data.json_criteria_score) + ); + urlencoded.append("user_exercise_id", data.user_exercise_id); + urlencoded.append("score", data.score); + urlencoded.append("comment", data.comment); + urlencoded.append( + "json_writing_check", + JSON.stringify(data.json_writing_check) + ); + urlencoded.append("library", data.library); + urlencoded.append("exercise_type", data.exercise_type); + return (dispatch) => { + return apiCaller( + "/api_class/save_mark_exercise", + "PUT", + urlencoded, + null, + true + ).then( + () => { + dispatch( + alertActions.success({ + message: messageSuccess || "Cập nhật bài thành công", + screen: teacherConstants.SCREEN_EDIT_HOME_WORK, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_EDIT_HOME_WORK, + }) + ); + } + ); + }; +} + +function callAIHomeWork( + content, + user_received_id = "", + library, + user_exercise_id, + class_id +) { + return (dispatch) => { + return apiCaller( + "/api_class/ai_check_writing", + "POST", + { + content, + user_received_id, + library, + user_exercise_id, + class_id, + }, + null, + true + ).then((data) => { + dispatch({ + type: teacherConstants.CALL_AI_HOMEWORK, + data: data.data_check, + }); + }); + }; +} + +function getStudentRanking(type, class_id) { + return (dispatch) => { + return apiCaller( + "/api_student/ranking?type=" + type + "&class_id=" + class_id, + "GET", + {}, + null, + true + ).then((data) => { + dispatch({ + type: teacherConstants.GET_STUDENT_RANKING, + data: data.data, + base_url: data.base_url, + }); + }); + }; +} + +function getClassRanking(id) { + return (dispatch) => { + return apiCaller("/api_class/ranking?id=" + id, "GET", {}, null, true).then( + (data) => { + dispatch({ + type: teacherConstants.GET_CLASS_RANKING, + data: data.data, + }); + } + ); + }; +} + +// Roll Up +function createRollUp(data) { + var urlencoded = new URLSearchParams(); + urlencoded.append("list_student", JSON.stringify(data.list_student)); + urlencoded.append("class_id", data.class_id); + urlencoded.append("send_to_parent", data.send_to_parent); + urlencoded.append("date", data.date); + urlencoded.append("send_content", data.send_content); + urlencoded.append("total_student", data.total_student); + urlencoded.append("number_absence", data.number_absence); + urlencoded.append("general_comment", data.general_comment); + return (dispatch) => { + return apiCaller( + "/api_class_offline/roll_up", + "POST", + urlencoded, + null, + true + ).then( + () => { + dispatch( + alertActions.success({ + message: "Tạo điểm danh thành công", + screen: teacherConstants.SCREEN_ADD_ROLL_UP, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_ADD_ROLL_UP, + }) + ); + } + ); + }; +} + +function updateRollUp(data) { + var urlencoded = new URLSearchParams(); + urlencoded.append("list_student", JSON.stringify(data.list_student)); + urlencoded.append("class_id", data.class_id); + urlencoded.append("send_to_parent", data.send_to_parent); + urlencoded.append("roll_up_id", data.roll_up_id); + urlencoded.append("total_student", data.total_student); + urlencoded.append("number_absence", data.number_absence); + urlencoded.append("general_comment", data.general_comment); + return (dispatch) => { + return apiCaller( + "/api_class_offline/roll_up", + "PUT", + urlencoded, + null, + true + ).then( + () => { + dispatch( + alertActions.success({ + message: "Cập nhật điểm danh thành công", + screen: teacherConstants.SCREEN_ADD_ROLL_UP, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_ADD_ROLL_UP, + }) + ); + } + ); + }; +} + +function getExamcardOffline(class_id) { + return (dispatch) => { + return apiCaller( + "/api_class_offline/class_exam_card?class_id=" + class_id, + "GET", + {}, + null, + true + ).then((exam_card) => { + dispatch({ + type: teacherConstants.GET_EXAM_CARD, + exam_card, + }); + }); + }; +} + +function createExamCard(data) { + var urlencoded = new URLSearchParams(); + urlencoded.append("exam_mark_detail", JSON.stringify(data.exam_mark_detail)); + urlencoded.append("class_id", data.class_id); + urlencoded.append("exam_name", data.exam_name); + urlencoded.append("date_test", data.date_test); + urlencoded.append("is_send_parent", data.is_send_parent); + urlencoded.append("type", data.type); + urlencoded.append("score_percent", data.score_percent); + urlencoded.append("semester", data.semester); + urlencoded.append("send_content", data.send_content); + return (dispatch) => { + return apiCaller( + "/api_class_offline/exam_card", + "POST", + urlencoded, + null, + true + ).then( + () => { + dispatch( + alertActions.success({ + message: "Tạo phiếu điểm thành công", + screen: teacherConstants.SCREEN_ADD_EXAM_CARD, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_ADD_EXAM_CARD, + }) + ); + } + ); + }; +} + +function updateExamCard(data) { + var urlencoded = new URLSearchParams(); + urlencoded.append("exam_mark_detail", JSON.stringify(data.exam_mark_detail)); + urlencoded.append("card_id", data.card_id); + urlencoded.append("exam_name", data.exam_name); + urlencoded.append("date_test", data.date_test); + urlencoded.append("is_send_parent", data.is_send_parent); + urlencoded.append("type", data.type); + urlencoded.append("score_percent", data.score_percent); + urlencoded.append("semester", data.semester); + urlencoded.append("send_content", data.send_content); + return (dispatch) => { + return apiCaller( + "/api_class_offline/exam_card", + "PUT", + urlencoded, + null, + true + ).then( + () => { + dispatch( + alertActions.success({ + message: "Cập nhật phiếu điểm thành công", + screen: teacherConstants.SCREEN_ADD_EXAM_CARD, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_ADD_EXAM_CARD, + }) + ); + } + ); + }; +} + +function deleteFileExercise(data) { + var urlencoded = new URLSearchParams(); + urlencoded.append("id", data.id); + return (dispatch) => { + return apiCaller( + "/api_resources/resource", + "DELETE", + urlencoded, + null, + true + ).then( + () => { + dispatch( + alertActions.success({ + message: "Xóa hướng dẫn học tập thành công.", + screen: teacherConstants.SCREEN_LIST_FILE, + }) + ); + dispatch(getFileExercise(data.param)); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_LIST_FILE, + }) + ); + } + ); + }; +} + +function addFileResource(data, param) { + return (dispatch) => { + return apiCaller( + "/api_resources/upload_guide", + "POST", + data, + null, + true + ).then( + () => { + dispatch({ + type: popupConstants.SHOW_FORM_POPUP, + data: { + addFileCompleteResource: true, + }, + }); + dispatch(getFileExercise(param, false)); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_LIST_FILE, + }) + ); + } + ); + }; +} + +function getReportClass(class_id, from_date, to_date) { + return (dispatch) => { + return apiCaller( + "/api_student/report_overview_class?class_id=" + + class_id + + "&from_date=" + + from_date + + "&to_date=" + + to_date, + "GET", + {}, + null, + true + ).then((reports) => { + dispatch({ + type: teacherConstants.GET_LIST_REPORT_CLASS, + reports, + }); + }); + }; +} + +function getReportByStudentId(class_id, student_id, from_date, date_time) { + return (dispatch) => { + return apiCaller( + "/api_student/report_overview_student?student_id=" + + student_id + + "&class_id=" + + class_id + + "&from_date=" + + from_date + + "&to_date=" + + date_time + + "&date_time=" + + date_time, + "GET", + {}, + null, + true + ).then((students) => { + dispatch({ + type: teacherConstants.GET_REPORT_BY_STUDENT_ID, + students, + }); + }); + }; +} + +function getReportByStudentIdByDateTime( + class_id, + student_id, + from_date, + date_time +) { + return (dispatch) => { + return apiCaller( + "/api_student/report_overview_student?student_id=" + + student_id + + "&class_id=" + + class_id + + "&date_time=" + + date_time, + "GET", + {}, + null, + true + ).then((students) => { + dispatch({ + type: teacherConstants.GET_REPORT_BY_STUDENT_ID, + students, + }); + }); + }; +} + +function getLogLearningByStudentId(student_id, class_id, from_time) { + if (!from_time) { + from_time = moment().format("YYYY-MM-DD"); + } + return (dispatch) => { + return apiCaller( + "/api_student/student_log_learning?student_id=" + + student_id + + "&class_id=" + + class_id + + "&from_time=" + + from_time, + "GET", + {}, + null, + true + ).then((log_learning) => { + dispatch({ + type: teacherConstants.GET_LOG_LEARNING_BY_STUDENT_ID, + log_learning, + }); + dispatch({ + type: scheduleConstants.SET_SELECT_DATE, + time: from_time, + }); + }); + }; +} + +function resetPassword(data) { + return (dispatch) => { + return apiCaller("/api_user/user/", "PUT", data, null, false).then( + () => { + dispatch( + alertActions.success({ + message: userConstants.MESSAGE_CHANGE_PASSWORD_COMPLETE, + screen: userConstants.SCREEN_RESET_PASSWORD, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: userConstants.SCREEN_RESET_PASSWORD, + }) + ); + } + ); + }; +} + +function getListCriteria(exercise_id) { + return (dispatch) => { + return apiCaller( + "/api_class/load_exercise_criteria?exercise_id=" + exercise_id, + "GET", + {}, + null, + false + ).then((criteria) => { + dispatch({ + type: teacherConstants.GET_LIST_CRITERIA, + criteria: criteria.data_criteria, + }); + }); + }; +} + +function updateCriteria(json_criteria, exercise_id, exerciseId) { + var urlencoded = new URLSearchParams(); + urlencoded.append("json_criteria", JSON.stringify(json_criteria)); + urlencoded.append("exercise_id", exercise_id); + return (dispatch) => { + return apiCaller( + "/api_class/writing_criteria", + "PUT", + urlencoded, + null, + false + ).then(() => { + dispatch(getListCriteria(exercise_id === 0 ? null : exercise_id)); + }); + }; +} + +function remindStudent(data) { + var urlencoded = new URLSearchParams(); + urlencoded.append("msg", data.msg); + urlencoded.append( + "list_user_exercise_id", + JSON.stringify(data.list_user_exercise_id) + ); + + return (dispatch) => { + return apiCaller( + "/api_inbox/remind_all", + "POST", + urlencoded, + null, + false + ).then( + () => { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + dispatch(getDetailExercise(data.class_id, data.exercise_id)); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_REMIND_STUDENT, + }) + ); + } + ); + }; +} + +function addWish(data) { + return (dispatch) => { + return apiCaller( + "/api_wish_list/my_wish_list", + "POST", + data, + null, + false + ).then( + () => { + dispatch( + alertActions.success({ + message: "Thêm bài tập vào danh sách yêu thích", + screen: teacherConstants.ADD_WISH, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.ADD_WISH, + }) + ); + } + ); + }; +} + +function removeWish(data) { + var urlencoded = new URLSearchParams(); + // urlencoded.append("user_wish_id", data.user_wish_id); + urlencoded.append("exercise_id", data.exercise_id); + + return (dispatch) => { + return apiCaller( + "/api_wish_list/my_wish_list", + "DELETE", + urlencoded, + null, + false + ).then( + () => { + dispatch( + alertActions.success({ + message: "Xóa bài tập khỏi danh sách yêu thích", + screen: teacherConstants.ADD_WISH, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.ADD_WISH, + }) + ); + } + ); + }; +} + +function getRollUpById(id = "", callback = (res) => {}) { + return (dispatch) => { + return apiCaller( + "/api_class_offline/roll_up?id=" + id, + "GET", + {}, + null, + true + ).then((res) => { + if (callback) { + callback(res); + } + }); + }; +} + +function getLogLearningByDate(date, student_id, class_id) { + return (dispatch) => { + return apiCaller( + `/api_student/log_learning_by_date?date=${date}&student_id=${student_id}&class_id=${class_id}`, + "GET", + {}, + null, + true + ).then((learnings) => { + dispatch({ + type: teacherConstants.GET_LOG_LEARNING_BY_DATE, + learnings, + }); + }); + }; +} diff --git a/src/_actions/users.js b/src/_actions/users.js new file mode 100644 index 0000000..071d6e8 --- /dev/null +++ b/src/_actions/users.js @@ -0,0 +1,691 @@ +import { apiCaller } from "./../_helpers"; +import axios from "axios"; +import { alertActions } from "./"; +import { + configConstants, + studentConstants, + teacherConstants, + userConstants, +} from "./../_constants"; +import { history } from "../_helpers"; +import { isNull } from "lodash"; +import { teacherService } from "../_services"; +import { teacherActions } from "./"; +import APIBase from "../_base/APIBase"; + +export const userActions = { + login, + udpateInformation, + forgotPassword, + resetPassword, + register, + uploadAvatar, + getRoomChat, + getPrivateMessages, + getSystemNotification, + getDetailMessage, + sendMessage, + getInfoContact, + getDeviceDetail, + saveUserSetting, + updateStatusInbox, +}; + +function login(data, type = "", typeWeb) { + const device_id = data["device_id"]; + return (dispatch) => { + let url_call_api = "/api_login/check"; + let method = "PUT"; + if (type === configConstants.LOGIN_VIA_FACEBOOK) { + url_call_api = "/api_login/facebook_auth"; + method = "POST"; + return callApiLoginSocialMedia( + url_call_api, + method, + data, + type, + device_id, + dispatch, + typeWeb + ); + } else if (type === configConstants.LOGIN_VIA_GOOLE) { + url_call_api = "/api_login/google_auth"; + method = "POST"; + return callApiLoginSocialMedia( + url_call_api, + method, + data, + type, + device_id, + dispatch, + typeWeb + ); + } else if (type === configConstants.LOGIN_VIA_APPLE) { + url_call_api = "/api_login/apple_auth"; + method = "POST"; + return callApiLoginSocialMedia( + url_call_api, + method, + data, + type, + device_id, + dispatch, + typeWeb + ); + } + return apiCaller(url_call_api, method, data, null, false).then( + async (data) => { + if (data?.data_user?.role == "parent") { + const warningText = 'Hiện tại chúng tôi chưa hỗ trợ tài khoản phụ huynh trên website. Vui lòng tải app Sunday Parent và đăng nhập để sử dụng.' + dispatch( + alertActions.error({ + message: warningText, + screen: userConstants.SCREEN_LOGIN, + }) + ); + return + } + let url_auto_login_for_teacher = `${configConstants.BASE_URL}login/api_teacher_auto_login`; + let url_auto_login = `${configConstants.EXCERCISE_URL}login/api_auto_login`; + let user = data?.data_user; + user.isLogin = true; + user.jwt_token = data.jwt_token; + user.is_new_acc = data.is_new_acc; + user.loginType = type; + const dataUser = new FormData(); + dataUser.append("user_id", data?.data_user?.id); + dataUser.append("jwt_token", data?.jwt_token); + dataUser.append("signature", "1"); + if (data?.data_user?.role == "teacher") { + await APIBase.apiBaseCaller( + "POST", + url_auto_login_for_teacher, + dataUser + ) + .then((apiExerciseToWeb) => { + if ( + apiExerciseToWeb.code == 0 || + apiExerciseToWeb.message == "Login_Is_Success" + ) { + dispatch({ + type: teacherConstants.GET_SERVICE_TEACHER, + data: apiExerciseToWeb, + }); + } else { + dispatch({ + type: teacherConstants.GET_SERVICE_TEACHER, + data: { + redirect_url: "", + message: apiExerciseToWeb.message, + status: false, + }, + }); + } + }) + .catch((error) => { + return dispatch( + alertActions.error({ + message: error?.message?.toString(), + screen: userConstants.SCREEN_LOGIN, + data: error?.message, + }) + ); + }); + } + // else if (data?.data_user?.role == "student") { + // await APIBase.apiBaseCaller("POST", url_auto_login, dataUser) + // .then((apiExerciseToWeb) => { + // if (apiExerciseToWeb.code == 0) { + // dispatch({ + // type: studentConstants.GET_REDIRECT_URL, + // data: { + // redirect_url: apiExerciseToWeb?.url_data?.redirect_url, + // message: apiExerciseToWeb.message, + // status: true, + // }, + // }); + // } else { + // dispatch({ + // type: studentConstants.GET_REDIRECT_URL, + // data: { + // redirect_url: "", + // message: apiExerciseToWeb.message, + // status: false, + // }, + // }); + // } + // }) + // .catch((error) => {}); + // } + + dispatch({ + type: userConstants.LOGIN, + user, + }); + localStorage.setItem("authentication", JSON.stringify(user)); + localStorage.setItem("access_token", JSON.stringify(data.access_token)); + if ( + data?.data_user?.last_login == null && + data?.data_user?.role == userConstants.ROLE_STUDENT + ) { + dispatch({ type: userConstants.ON_ROOTLESSNESS }); + dispatch({ type: userConstants.SHOW_SIDEBAR_ROOTLESSNESS }); + } + dispatch(teacherActions.getProfileV2(user.id)); + + let keyId = "device_id_" + data.id; + const cachedDeviceId = localStorage.getItem(keyId); + if (isNull(cachedDeviceId)) { + localStorage.setItem(keyId, device_id); + localStorage.setItem("device_id_commond", device_id); + } else { + localStorage.setItem("device_id_commond", cachedDeviceId); + } + + const purposeLogin = JSON.parse(localStorage.getItem("purposeLogin")); + + let authentication = JSON.parse(localStorage.getItem("authentication")); + // typeWeb == "news" ? history.push("/") : purposeLogin.purpose history.push("/" + user.role); + if (typeWeb == "news") { + history.push("/"); + } else { + if (purposeLogin) { + switch (purposeLogin?.purpose) { + case "mock_test": + if (authentication.role == userConstants.ROLE_STUDENT) { + history.push( + `/${authentication?.role}/exam-test/${purposeLogin.exam_id}/experience` + ); + } else { + history.push(`/exam-test/${purposeLogin.exam_id}/experience`); + } + return; + case "curriculum": + history.push(`/${authentication.role}/curriculum`); + return; + default: + history.push("/" + user.role); + } + localStorage.removeItem("purposeLogin"); + } else { + history.push("/" + user.role); + } + } + }, + (error) => { + if (error.toString() === "Vui lòng nhập mật khẩu.") { + error = "Mật khẩu cần tối thiểu 6 kí tự và không gồm toàn dấu cách"; + } + dispatch( + alertActions.error({ + message: error.toString(), + screen: userConstants.SCREEN_LOGIN, + data: error, + }) + ); + if (error.toString()?.includes("Tài khoản chưa được xác thực")) { + dispatch({ type: userConstants.REGISTER_STATUS }); + } + // dispatch({ + // type: userConstants.CHANGE_LOGIN_TYPE, + // data + // }); + // history.push('/register'); + } + ); + }; +} + +function callApiLoginSocialMedia( + url_call_api, + method, + data, + type, + device_id, + dispatch, + typeWeb +) { + return apiCallerSocialMedia(url_call_api, method, data, null, false).then( + (data) => { + if (data.data_user) { + // console.log(data.data_user) + let user = data?.data_user; + user.isLogin = true; + user.jwt_token = data.jwt_token; + user.is_new_acc = data.is_new_acc; + user.loginType = type; + localStorage.setItem("authentication", JSON.stringify(user)); + // console.log("disconnect: ", type); + localStorage.setItem("access_token", JSON.stringify(data.access_token)); + if (type === configConstants.LOGIN_VIA_GOOLE) { + window.gapi.auth2.getAuthInstance().disconnect(); + window.gapi.auth2?.getAuthInstance()?.signOut && + window.gapi.auth2.getAuthInstance().signOut(); + } + if (type === configConstants.LOGIN_VIA_FACEBOOK) { + if (window.FB) { + window.FB.api("/me/permissions", "delete", null, () => + window.FB.logout() + ); + } + } + dispatch({ + type: userConstants.LOGIN, + user, + }); + dispatch(teacherActions.getProfileV2(user.id)); + let keyId = "device_id_" + data.id; + const cachedDeviceId = localStorage.getItem(keyId); + if (isNull(cachedDeviceId)) { + localStorage.setItem(keyId, device_id); + localStorage.setItem("device_id_commond", device_id); + } else { + localStorage.setItem("device_id_commond", cachedDeviceId); + } + const purposeLogin = JSON.parse(localStorage.getItem("purposeLogin")); + + let authentication = JSON.parse(localStorage.getItem("authentication")); + // typeWeb == "news" ? history.push("/") : purposeLogin.purpose history.push("/" + user.role); + if (typeWeb == "news") { + history.push("/"); + } else { + if (purposeLogin) { + switch (purposeLogin?.purpose) { + case "mock_test": + if (authentication.role == userConstants.ROLE_STUDENT) { + history.push( + `/${authentication?.role}/exam-test/${purposeLogin.exam_id}/experience` + ); + } else { + history.push(`/exam-test/${purposeLogin.exam_id}/experience`); + } + return; + case "curriculum": + history.push(`/${authentication.role}/curriculum`); + return; + default: + history.push("/" + user.role); + } + localStorage.removeItem("purposeLogin"); + } else { + history.push("/" + user.role); + } + } + } else if (!data.data_user && data.is_new_acc === "1") { + dispatch({ + type: userConstants.LOGIN, + user: { + loginType: type, + is_new_acc: true, + }, + }); + typeWeb == "news" && history.push("/register_news/google"); + // dispatch(teacherActions.getProfile(user.id)); + } else { + dispatch( + alertActions.error({ + message: data?.msg?.toString(), + screen: userConstants.SCREEN_LOGIN, + data: data.msg, + }) + ); + } + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: userConstants.SCREEN_LOGIN, + data: error, + }) + ); + // dispatch({ + // type: userConstants.CHANGE_LOGIN_TYPE, + // data + // }); + // history.push('/register'); + } + ); +} + +function register(data) { + return (dispatch) => { + return apiCaller("/api_register/register", "POST", data, null, false).then( + () => { + dispatch( + alertActions.success({ + message: userConstants.MESSAGE_REGISTER_COMPLETE, + screen: userConstants.SCREEN_COMPLETE_DATA_REGISTER, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: userConstants.SCREEN_COMPLETE_DATA_REGISTER, + }) + ); + } + ); + }; +} + +function udpateInformation(data) { + return (dispatch) => { + dispatch({ + type: userConstants.ADD_DATA_REGISTER, + data, + }); + history.push("/add-infomation"); + }; +} + +function forgotPassword(email) { + return (dispatch) => { + return apiCaller( + "/api_login/forget_password", + "PUT", + { email, forget_password_web: "1" }, + null, + false + ).then( + () => { + dispatch( + alertActions.success({ + message: userConstants.MESSAGE_REQUEST_CHANGE_PASSWORD_COMPLETE, + screen: userConstants.SCREEN_FORGOT_PASSWORD, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: userConstants.SCREEN_FORGOT_PASSWORD, + }) + ); + } + ); + }; +} + +function resetPassword(data) { + return (dispatch) => { + return apiCaller( + "/api_login/reset_password", + "PUT", + data, + null, + false + ).then( + () => { + dispatch( + alertActions.success({ + message: userConstants.MESSAGE_CHANGE_PASSWORD_COMPLETE, + screen: userConstants.SCREEN_RESET_PASSWORD, + }) + ); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: userConstants.SCREEN_RESET_PASSWORD, + }) + ); + } + ); + }; +} + +function uploadAvatar(data) { + return (dispatch) => { + return apiCaller("/api_user/update_avatar", "POST", data, null, false).then( + () => { + // dispatch(alertActions.success({ 'message': userConstants.MESSAGE_UPDATE_AVATAR_COMPLETE, 'screen': userConstants.SCREEN_UPDATE_PROFILE })); + console.log("upload avatar success"); + }, + (error) => { + // dispatch(alertActions.error({ 'message': error.toString(), 'screen': userConstants.SCREEN_UPDATE_PROFILE })); + console.log(error); + } + ); + }; +} + +function getRoomChat(id) { + return (dispatch) => { + return apiCaller( + "/api_inbox/check_room?to_user_id=" + id, + "GET", + {}, + null, + true + ).then((data) => { + dispatch({ + type: userConstants.GET_ROOM_CHAT, + data: data.room_id, + }); + dispatch(userActions.getDetailMessage(data.room_id)); + }); + }; +} + +function getPrivateMessages() { + return (dispatch) => { + return apiCaller("/api_inbox/inbox", "GET", {}, null, true).then( + (data_message) => { + dispatch({ + type: userConstants.GET_CLASS_MESSAGE, + data_message, + }); + } + ); + }; +} + +function getInfoContact(class_id, role) { + const url = class_id ? "&class_id=" + class_id : ""; + return (dispatch) => { + return apiCaller( + "/api_inbox/list_contact?user_role=" + role + url, + "GET", + {}, + null, + true + ).then((data) => { + dispatch({ + type: userConstants.GET_CONTACT_INFO, + data: data.data_contact, + base_url: data.base_url, + }); + dispatch({ + type: userConstants.GET_DETAIL_MESSAGE, + data: [], + }); + }); + }; +} + +function getDetailMessage(id, latest_msg_id, latest_msg_status) { + var urlencoded = new URLSearchParams(); + urlencoded.append("inbox_id", latest_msg_id); + urlencoded.append("seen_status", "1"); + urlencoded.append("subject", ""); + urlencoded.append("content", ""); + return (dispatch) => { + return apiCaller( + "/api_inbox/inbox_detail?id=" + id, + "GET", + {}, + null, + true + ).then((data) => { + dispatch({ + type: userConstants.GET_DETAIL_MESSAGE, + data: data.data, + }); + if (urlencoded && latest_msg_id && latest_msg_status === 0) { + // console.log(latest_msg_status); + dispatch(updateStatusInbox(urlencoded)); + } + }); + }; +} + +function sendMessage(data, roomId) { + return (dispatch) => { + return apiCaller("/api_inbox/send", "POST", data, null, false).then( + () => { + dispatch(userActions.getDetailMessage(roomId)); + dispatch(userActions.getPrivateMessages()); + }, + (error) => { + console.log(error); + } + ); + }; +} + +function getSystemNotification(class_id) { + const url = class_id ? "?class_id=" + class_id : ""; + return (dispatch) => { + return apiCaller( + "/api_inbox/inbox_system" + url, + "GET", + {}, + null, + true + ).then((data) => { + dispatch({ + type: userConstants.GET_CLASS_NOTIFICATION, + data: data.data, + }); + }); + }; +} + +function getDeviceDetail(device_id) { + return (dispatch) => { + return apiCaller( + "/api_user/load_setting_app?device_id=" + device_id, + "GET", + {}, + null, + true + ).then((data) => { + dispatch({ + type: userConstants.GET_SETTING_DETAIL, + data: data.data_setting, + }); + }); + }; +} + +function saveUserSetting(data, user_device_id) { + var urlencoded = new URLSearchParams(); + urlencoded.append("user_device_id", user_device_id); + urlencoded.append("json_setting", JSON.stringify(data)); + return () => { + return apiCaller( + "/api_user/save_setting", + "PUT", + urlencoded, + null, + false + ).then( + () => { + console.log("save success"); + }, + (error) => { + console.log(error); + } + ); + }; +} + +function updateStatusInbox(data) { + return (dispatch) => { + return apiCaller("/api_inbox/update_inbox", "PUT", data, null, false).then( + () => { + teacherService.getInboxInfo().then((data) => { + dispatch({ + type: userConstants.GET_TOTAL_MESSAGE, + number_msg_new: data.number_msg_new, + number_system_new: data.number_system_new, + }); + }); + }, + (error) => { + console.log(error); + } + ); + }; +} + +function apiCallerSocialMedia( + endpoint, + method = "GET", + body = {}, + headers = null, + clearToken = true, + basUrl = configConstants.API_URL_SETEST +) { + if (headers === undefined || headers === null) { + headers = { + "X-API-KEY": configConstants.API_KEY, + }; + if (localStorage.getItem("authentication")) { + let authentication = JSON.parse(localStorage.getItem("authentication")); + headers["jwt_token"] = authentication.jwt_token; + } + } + $(".loading").removeClass("hide"); + return axios({ + method, + timeout: configConstants.API_TIMEOUT, + url: `${basUrl}${endpoint}`, + auth: { + username: configConstants.AUTH_BASIC_USER_NAME, + password: configConstants.AUTH_BASIC_PASSWORD, + }, + data: body, + headers: headers, + }) + .then(handleResponse) + .catch((error) => { + $(".loading").addClass("hide"); + if (error && error.response) { + if (clearToken && error.response.status === 401) { + clearLocalStorage(); + } else { + let msg = "Server Error"; + if (error.response.data.msg || error.response.data.error) { + msg = error.response.data.msg + ? error.response.data.msg + : error.response.data.error; + } + return Promise.reject(msg); + } + } else { + if (typeof error === "string" || error instanceof String) { + return Promise.reject(error); + } else { + return Promise.reject("Server Error"); + } + } + }); +} + +function clearLocalStorage() { + // localStorage.clear(); + localStorage.removeItem("authentication"); + localStorage.removeItem("access_token"); + history.push("/login"); +} + +function handleResponse(response) { + $(".loading").addClass("hide"); + return response.data; +} diff --git a/src/_apis/APIConstants.js b/src/_apis/APIConstants.js new file mode 100644 index 0000000..7664b6d --- /dev/null +++ b/src/_apis/APIConstants.js @@ -0,0 +1,19 @@ +import { configConstants } from "../_constants/config"; + +const API = { + baseURL: configConstants.AUTH_URL, + get_packages: "api/package", + get_packages_available: "api/package/available_package_list", + get_packages_teacher: "api/package/package_teacher", + payment_history: "api/web_advertise/history_payment", + register_teacher: "api/teacher/register", + verify_resgiter_teacher: "api/teacher/verify_auth", + verify_register_teacher_by_zalo: "api/teacher/verify_auth", + logout_account_service: `${configConstants.BASE_URL}login/logout?logout_app_id=VK7JG-NPHTM-C97JM-9MPGT-3V66T`, + logout_account_exercise: `${configConstants.BASE_URL}account/logout?logout_app_id=VK7JG-NPHTM-C97JM-9MPGT-3V66T`, + upgradeAccountByCode: "api/package/active_by_code", + get_package_history: "api/payment/history_payment", + post_package_active: "api/package/active", +}; + +export default API; diff --git a/src/_base/APIBase.js b/src/_base/APIBase.js new file mode 100644 index 0000000..aa9b54c --- /dev/null +++ b/src/_base/APIBase.js @@ -0,0 +1,173 @@ +import axios from "axios"; +import { configConstants } from "../_constants"; +import { handleResponse } from "../_helpers"; +import $ from "jquery"; + +class APIBase { + static apiBaseCaller(method, url, data, isLoading) { + return new Promise((resolve, reject) => { + $(".loading").removeClass("hide"); + let headers = { + // "Content-Type": "application/json", + // "Access-Control-Allow-Origin": "*", + Accept: "application/json", + Authorization: "", + }; + + if (localStorage.getItem("access_token")) { + let access_token = JSON.parse(localStorage.getItem("access_token")); + + headers["Authorization"] = `Bearer ${access_token}`; + } + + axios({ + method, + url, + headers: headers, + data, + }) + .then((response) => { + resolve(response.data); + $(".loading").addClass("hide"); + }) + .catch((error) => { + $(".loading").removeClass("hide"); + setTimeout(() => { + $(".loading").addClass("hide"); + }, 2000); + reject(error.response.data); + if (error.message == "Network Error") { + alert("Vui lòng kiểm tra kết nối Internet"); + } + + console.log("error2 ====", error); + }); + }); + } + + static apiBaseNoLoading(method, url, data) { + return new Promise((resolve, reject) => { + let headers = { + // "Content-Type": "application/json", + // "Access-Control-Allow-Origin": "*", + Accept: "application/json", + Authorization: "", + }; + + if (localStorage.getItem("access_token")) { + let access_token = JSON.parse(localStorage.getItem("access_token")); + + headers["Authorization"] = `Bearer ${access_token}`; + } + + axios({ + method, + url, + headers: headers, + data, + }) + .then((response) => { + resolve(response.data); + }) + .catch((error) => { + reject(error); + if (error.message == "Network Error") { + alert("Vui lòng kiểm tra kết nối Internet"); + } + }); + }); + } + + static apiBaseCallerControlLoading(method, url, data, isLoading) { + return new Promise((resolve, reject) => { + isLoading && $(".loading").removeClass("hide"); + let headers = { + // "Content-Type": "application/json", + // "Access-Control-Allow-Origin": "*", + Accept: "application/json", + Authorization: "", + }; + + if (localStorage.getItem("access_token")) { + let access_token = JSON.parse(localStorage.getItem("access_token")); + + headers["Authorization"] = `Bearer ${access_token}`; + } + + axios({ + method, + url, + headers: headers, + data, + }) + .then((response) => { + resolve(response.data); + isLoading && $(".loading").addClass("hide"); + }) + .catch((error) => { + isLoading && $(".loading").removeClass("hide"); + setTimeout(() => { + isLoading && $(".loading").addClass("hide"); + }, 3000); + reject(error); + if (error.message == "Network Error") { + alert("Vui lòng kiểm tra kết nối Internet"); + } + }); + }); + } + + static apiBaseCallerMsg(method, url, data, isLoading = true) { + let headers = { + // "Content-Type": "application/json", + // "Access-Control-Allow-Origin": "*", + Accept: "application/json", + Authorization: "", + }; + + if (localStorage.getItem("access_token")) { + let access_token = JSON.parse(localStorage.getItem("access_token")); + + headers["Authorization"] = `Bearer ${access_token}`; + } + + return axios({ + method, + timeout: configConstants.API_TIMEOUT, + url: url, + data: data, + headers: headers, + }) + .then((res) => handleResponse(res, isLoading)) + .catch((error) => { + if (isLoading) { + $(".loading").addClass("hide"); + } + if (error && error.message) { + let msg = error.message; + // if ( + // error.response.data.msg || + // error.response.data.error || + // error.phone + // ) { + // msg = error.response.data.msg + // ? error.response.data.msg + // : error.response.data.error; + // } + return Promise.reject(msg); + } else { + if ( + typeof error === "string" || + error instanceof String || + typeof error == "object" + ) { + return Promise.reject(error); + } else { + return Promise.reject("Server Error 123123"); + } + } + }); + } +} + +export default APIBase; diff --git a/src/_base/DetailListNews.js b/src/_base/DetailListNews.js new file mode 100644 index 0000000..23036ef --- /dev/null +++ b/src/_base/DetailListNews.js @@ -0,0 +1,788 @@ +import { BoxTitlte } from "../_components/BoxTitle/BoxTitle"; +import { handleCheckEven } from "./Validate"; +import { LinkApp } from "../_constants/linkDownloadApp"; +import LazyLoad from "react-lazyload"; +import { isEmpty } from "lodash"; + +// List detail with image success +const renderListDetail = (item, numberLine, typeFontSize) => { + return ( +
+ Icon Tick +
+ {item?.name} +
+
+ ); +}; + +const renderListDot = (item) => { + return ( +
+
+ {item.name} +
+
+ {item?.content} +
+ {item?.content_1 && ( +
+ {item?.content_1} +
+ )} + {item?.lists_1?.map((item) => renderListContent1(item))} +
+ ); +}; + +const renderListContent1 = (item) => { + return ( +
+ {item?.contentLink && } + {item.content && ( + + {item.content} + + {item.content_1_bold && ( + + {item.content_1_bold}{" "} + + )} + {item.content_1_regular && ( + + {item.content_1_regular} + + )} + + )}{" "} + {item.content_bold && ( + + {item.content_bold} + + )}{" "} + {item.content_note && ( + + {item.content_note}{" "} + {item.content_note_1} + + {item.content_note_bold} + + + )}{" "} + {item?.link && ( +
+ + {item?.link} + +
+ )} + {item?.lists_1 && ( +
+ {item?.lists_1?.map((item) => renderListContent1(item))} +
+ )} +
+ ); +}; + +const renderListContent2 = (item) => { + return ( + <> +
+ {item?.title && ( + + {item.title} + + )} + + + +
+ {!!item?.lists_1?.length && item?.lists_1?.map((item) => renderListContent2(item))} + + ); +}; + +const renderListContent3 = (item) => { + return ( +
+
+ {item.title} +
+ +
+ ); +}; + +const renderListContentDefault = (item) => { + return ( +
  • +
    + {item.content} +
    + {item?.lists_1?.map((item) => renderListContent1(item))} +
  • + ); +}; + +const renderListEleSide = (item) => { + return ( +
    +
    + {item.name} +
    + {item?.lists_1?.map((item) => renderListContent1(item))} + {item?.lists_2?.map((item) => renderListContent3(item))} +
    + ); +}; + +const renderListPage1 = (data) => { + return ( +
    +
    + {data.title} +
    + +
    + {data?.content_1 && ( +
    + {data?.content_1} +
    + )} + {data?.lists_1?.map((item) => renderListContent1(item))} + {data?.content_2 && ( +
    + {data?.content_2} +
    + )} + {data?.lists_2?.map((item) => renderListContent1(item))} + {data?.content_3 && ( +
    + {data?.content_3} +
    + )} +
    + {data?.list_dot?.map((item) => renderListDot(item))} +
    +
    +
    + ); +}; + +const renderListPage2 = (data) => { + return ( +
    +
    + {data.title} +
    + +
    + {data?.content_1 && ( +
    + {data?.content_1} +
    + )} + {data?.lists_1?.map((item) => renderListContent2(item))} + {data?.lists_ele_side_1?.map((item) => renderListEleSide(item))} + {data?.content_2 && ( +
    + {data?.content_2} +
    + )} +
    +
    + ); +}; + +// Content Payment +const renderContentPolicyPayment = (item) => { + return ( +
    +
    + {item.title} +
    +
    + {item?.data.map((item) => renderContentDefaultPolicyPayment(item))} +
    +
    + ); +}; + +const renderContentDefaultPolicyPayment = (item) => { + return ( +
    +
    + {item.title} +
    + +
    + ); +}; + +const renderListContentDotPayment = (item) => { + return ( +
  • + {item?.content_bold && ( + + {item.content_bold} + + )}{" "} +
    +
    +
    + {item.content_note}{" "} + +
    + {!!item?.lists_1?.length && item?.lists_1?.map((subItem) => renderListContentDotPayment(subItem))} +
  • + ); +}; + +// + +const renderContentPolicyPayment2 = (item) => { + return ( +
    +
    + {item.title} +
    +
    + {item?.data.map((item) => renderListContentDotPayment(item))} +
    +
    + ); +}; + +//==== CONTENT COURSES ===== +const renderItemListDetailCourse = (item, courseID) => { + return ( +
    + Icon Tick +
    + {item?.content}{" "} + + {item?.content_1} + {" "} + + {item?.content_2 || null} + {" "} + + {item?.tail_content} + {" "} + + {item?.content_3} + {" "} +
    +
    + ); +}; + +const renderListDetailCourse = (item, courseID) => { + return ( +
    +
    + {item?.imageLeft && } + {item?.content} + {item?.imageRight && } +
    + {item?.list_detail?.map((item) => + renderItemListDetailCourse(item, courseID) + )} + {item?.imageLeftOutside && } + {item?.imageTopOutside && } + + {/* {courseID == 1 && } */} + {/* {item.id == 2 && ( +
    + Img Goal +
    + )} */} + {/* {item.id == 4 && ( +
    + Img Order +
    + )} */} + {/* {item.id == 3 && courseID == 1 && ( +
    + Img Book +
    + )} */} +
    + ); +}; + +const renderCourseItem = (data) => { + return ( +
    + {/*
    +
    +
    + {data.name} +
    +
    +
    */} + +
    + {data.data.map((item) => renderListDetailCourse(item, data.id))} +
    +
    + ); +}; + +// Courses Mobile +const renderListDetailCourseMobile = (item, courseID) => { + return ( +
    + {item.id == 1 && ( +
    + Img Student +
    + )} + + {item?.content} + {item?.tail_content} + {item?.list_detail?.map((item) => + renderItemListDetailCourse(item, courseID) + )} + + +
    + +
    + +
    + {item.id != 1 && ( +
    + Img Goal +
    + )} +
    +
    + ); +}; + +// Render List Content Data Question +const renderListContentFAQ = (element) => { + return ( +
    + + {element?.content_bold_black && ( + + {element?.content_bold_black} + + )}{" "} + {element?.content_1}{" "} + {element?.content_green_1 && ( + + {element?.content_green_1} + + )}{" "} + {element?.content_1_email && ( + + {element?.content_1_email} + + )}{" "} + {element?.content_1_phone && ( + + {element?.content_1_phone} + + )}{" "} + {element?.content_2 && ( + + {element?.content_2} + + )}{" "} + {element?.content_green_2 && ( + + {element?.content_green_2} + + )}{" "} + {element?.content_3 && ( + + {element?.content_3} + + )}{" "} + {element?.content_green_3 && ( + + {element?.content_green_3} + + )}{" "} + {element?.content_4 && ( + + {element?.content_4} + + )}{" "} + + {element?.image_download && ( +
    +
    window.open(LinkApp["student"].APP_STORE, "_blank")} + > + Icon App Store +
    +
    window.open(LinkApp["student"].GG_PLAY, "_blank")} + > + Icon GG Play +
    +
    + )} + {element?.content_list_child && ( +
    + {element?.content_list_child?.map((child) => { + return ( +
    + {child?.content} +
    + ); + })} +
    + )} +
    + ); +}; + +// Render Data Question 1 +const renderDataQuestion1 = (data) => { + return ( +
    +
    + {data?.content_0 && ( +
    + {data?.content_0} +
    + )}{" "} + + {data?.content_1}{" "} + {data?.content_1_bold && ( + + {data?.content_1_bold} + + )}{" "} + {data?.content_1_link && ( + + {data?.content_1_link} + + )}{" "} + {data?.content_1_side && ( + + {data?.content_1_side} + + )} + + {!isEmpty(data?.content_list_1) && + data?.content_list_1.map((element) => renderListContentFAQ(element))} + {!!data?.content_side_1 && renderListContentFAQ(data?.content_side_1)} + {data?.content_side_italic && ( +
    + {data?.content_side_italic} +
    + )} + {!isEmpty(data?.content_images) ? ( +
    + {data?.content_images.map((content_image) => { + return ( +
    + Image Content +
    + ); + })} +
    + ) : null} +
    + {data?.image_right ? ( +
    + Image Support +
    + ) : null} +
    + ); +}; + +const renderListPolicy = (data) => { + return ( +
    console.log(e)}> +
    + {data?.title} +
    + +
    + {/* {data?.content_1 && ( +
    + {data?.content_1} +
    + )} */} + {data?.contents?.map((item) => renderContentPolicy(item))} + {/*
    + {data?.list_dot?.map((item) => renderListDot(item))} +
    */} +
    +
    + ); +}; + +const renderContentPolicy = (item) => { + return ( +
    + {item?.title && } + {item?.titleDot && } + {item?.content && } + {item?.contentDot && } + {item?.contents && ( +
    + {item?.contents?.map((item) => renderContentPolicy(item))} +
    + )} +
    + ); +}; + +export { + renderListContent1, + renderListDetail, + renderListDot, + renderListPage1, + renderListPage2, + renderListContent3, + renderContentPolicyPayment, + renderContentPolicyPayment2, + renderListDetailCourse, + renderCourseItem, + renderListDetailCourseMobile, + renderDataQuestion1, + renderListContentFAQ, + renderListPolicy, + renderContentPolicy +}; diff --git a/src/_base/FunctionBase.js b/src/_base/FunctionBase.js new file mode 100644 index 0000000..6e5c01a --- /dev/null +++ b/src/_base/FunctionBase.js @@ -0,0 +1,26 @@ +import { getMobileOperatingSystem } from "./Validate"; +import { LinkApp } from "../_constants/linkDownloadApp"; +import { history } from "../_helpers"; + +export const handleNavigateCurriculumDownload = (type) => { + const osMobile = getMobileOperatingSystem(); + if (osMobile == "Android") { + window.open(LinkApp[`${type}`].GG_PLAY, "_blank"); + } else if (osMobile == "iOS") { + window.open(LinkApp[`${type}`].APP_STORE, "_blank"); + } else { + // if (authentication.isLogin) { + // history.push(`/${authentication.role}/curriculum`); + // } else { + // // localStorage.setItem( + // // "purposeLogin", + // // JSON.stringify({ + // // purpose: "curriculum", + // // }) + // // ); + // // history.push(`/login`); + + // } + history.push(`/download_page/${type}`); + } +}; diff --git a/src/_base/LessonBase.js b/src/_base/LessonBase.js new file mode 100644 index 0000000..ebb484a --- /dev/null +++ b/src/_base/LessonBase.js @@ -0,0 +1,43 @@ +import { configConstants } from '../_constants'; +import { replaceAnd } from './Validate'; + +class LessonBase{ + + static Type = { + teacher : 'teacher', + curriculum : 'curriculum', + homework : 'homework', + masterUnit : 'masterUnit' + }; + + static _moveLesson = (type, auth, data, navigation, from) => { + let dataSide = replaceAnd(data) + if (['exam', 'mini_test'].includes(data?.exercise_type)) { + //navigate to the minitest/exam screen + return + } + var id = ""; + switch (type) { + case LessonBase.Type.homework: + id = data?.id + break; + case LessonBase.Type.masterUnit: + id = data?.id + break; + default: + id = (data?.lesson_id || data?.exercise_id) + break; + } + const deviceID = localStorage.getItem('device_id_commond'); + // console.log("=====Go to type", type) + // console.log("=====Go to id", id) + // console.log("=====Go to with data", data) + // console.log("=====Go to from", from) + // var id = type == (LessonBase.Type.homework || LessonBase.Type.masterUnit) ? data?.id : (data?.lesson_id || data?.exercise_id) + // const url = `${configConstants.EXCERCISE_URL}index.php/example/lesson_demo?type=${type}&dataL=${JSON.stringify(dataSide)}&id=${id}&deviceID=${deviceID}&token=${auth?.jwt_token}` + const url = `http://localhost:11808/index.php/example/lesson_demo?type=${type}&dataL=${JSON.stringify(dataSide)}&id=${id}&deviceID=${deviceID}&token=${auth?.jwt_token}` + window.location.href = url + }; +} + +export default LessonBase; \ No newline at end of file diff --git a/src/_base/Mydata.js b/src/_base/Mydata.js new file mode 100644 index 0000000..758247d --- /dev/null +++ b/src/_base/Mydata.js @@ -0,0 +1,3 @@ +export const Mydata = { + version: 'v1.1.3' +} \ No newline at end of file diff --git a/src/_base/SmartScreenBase.js b/src/_base/SmartScreenBase.js new file mode 100644 index 0000000..e59ed1a --- /dev/null +++ b/src/_base/SmartScreenBase.js @@ -0,0 +1,38 @@ +class SmartBaseScreen { + static smBaseWidth = 0; // Width of Image + static smBaseHeight = 0; // Height of Image + + static smPercentWidth = 0; // calculate width % of screen device's width + static smPercentHeight = 0; // calculate width % of screen device's height + + static smFontSize = 0; // Scale fontSize adapt for each screen + + static basePadding = 0; //default padding + + // Intialize set up for each variable + static baseSetup() { + if (SmartBaseScreen.smPercentWidth == 0) { + let sWidth = window.innerWidth; + let sHeight = window.innerHeight; + + // window.addEventListener("resize", () => { + // sWidth = window.innerWidth; + // sHeight = window.innerHeight; + // SmartBaseScreen.smBaseWidth = sWidth / 1920; + // SmartBaseScreen.smBaseHeight = sHeight / 1080; + // SmartBaseScreen.smFontSize = sWidth / 1920; + // }); + + SmartBaseScreen.smPercentWidth = sWidth / 100; + SmartBaseScreen.smPercentHeight = sHeight / 100; + + SmartBaseScreen.smBaseWidth = sWidth / 1920; + SmartBaseScreen.smBaseHeight = sHeight / 1080; + SmartBaseScreen.smFontSize = sWidth / 1920; + + SmartBaseScreen.basePadding = SmartBaseScreen.smPercentWidth * 4; + } + } +} + +export default SmartBaseScreen; diff --git a/src/_base/Validate.js b/src/_base/Validate.js new file mode 100644 index 0000000..277aea6 --- /dev/null +++ b/src/_base/Validate.js @@ -0,0 +1,272 @@ +import { TypeHeaderNewsItem } from "../_constants/headerNews"; + +// Validate Email Regex +export const validateEmail = (email) => { + var regex = /^[\w\-\.]+@([\w-]+\.)+[\w-]{2,}$/gm; + return regex.test(email); +}; + +export const validatePhoneNumber = (phoneNumber) => { + // Regex check format of phone number in vietnam + const phoneNumberRegex = /(84|0[3|5|7|8|9])+([0-9]{8})\b/g; + + return phoneNumberRegex.test(phoneNumber); +}; + +// Validate Number Regex +export const validateNumber = (value) => { + return value?.replace(/[^0-9]/g, ""); +}; + +// Convert Time Package Fee +export const convertTimePackage = (time) => { + let resultTime = ""; + + let textTime = ""; + + switch (true) { + case time < 30: + textTime = "ngày"; + resultTime = time; + break; + case time >= 30 && time < 365: + textTime = "tháng"; + resultTime = Math.floor(time / 30); + break; + case time >= 365: + textTime = "năm"; + resultTime = Math.floor(time / 365); + break; + default: + } + + return `(${resultTime} ${textTime})`; +}; + +// Format Price +export const validatePrice = (value) => { + let formattedPrice = ""; + let price = parseFloat(value); + if (price >= 1000) { + // If it's greater than or equal to 1000, format it with commas + formattedPrice = price.toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, "."); + } else { + // If it's less than 1000, format it with three decimal places + formattedPrice = price.toFixed(0); + } + + return formattedPrice; +}; + +// Format Date +export const validateTime = (timer) => { + /* eslint-disable no-unsafe-optional-chaining */ + const [date, time] = timer?.split(" "); + + const [year, month, day] = date.split("-"); + + return `${day}/ ${month}/ ${year}`; +}; + +// Check Even +export const handleCheckEven = (number) => { + return number % 2 == 0; +}; + +// Round Number to Fixed Specific Number +export const roundNumber = (number, valueRound) => { + return parseFloat(Number.parseFloat(number).toFixed(valueRound)); +}; + +// Validate positive decimal number 2 +export const validateDecimal2Number = (number) => { + return number?.replace(/^(\\d+(?:[.,]\d{0,2}))?$/, ""); +}; + +// Check Positive Float +export const checkPositiveFloat = (number) => { + const regex = /^(?:10(\.0{1,2})?|[1-9]\d*(\.\d{1,2})?|0(\.\d{1,2})?)?$/; + return regex.test(number); +}; + +// Handle Click Link App Mobile +/** + * Determine the mobile operating system. + * This function returns one of 'iOS', 'Android', 'Windows Phone', or 'unknown'. + * + * @returns {String} + */ +export const getMobileOperatingSystem = () => { + var userAgent = navigator.userAgent || navigator.vendor || window.opera; + // Windows Phone must come first because its UA also contains "Android" + if (/windows phone/i.test(userAgent)) { + return "Windows Phone"; + } + + if (/android/i.test(userAgent)) { + return "Android"; + } + + if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) { + return "iOS"; + } +}; + +// Has Duplicate Data +export function hasDuplicates(array1, array2) { + var combinedArray = array1.concat(array2); + return new Set(combinedArray).size !== combinedArray.length; +} + +// func convert title +export const convertTitleAssign = (stand) => { + switch (stand.toLowerCase()) { + case "hard": + case "good": + case "senior": + return "Senior"; + case "medium": + case "normal": + case "middle": + return "Middle"; + case "easy": + case "weak": + case "junior": + return "Junior"; + default: + } +}; + +// Convert SKill Name +export const vietsubSkillName = (skill) => { + switch (skill) { + case "pronunciation": + return "Phát âm"; + case "vocabulary": + return "Từ vựng"; + case "grammar": + return "Ngữ pháp"; + case "reading": + return "Đọc"; + case "listening": + return "Nghe"; + case "speaking": + return "Nói"; + case "writing": + return "Viết"; + default: + return ""; + } +}; + +// Float Array +export const floatObjectToArray = (object) => { + const array = Object.keys(object).reduce(function (res, curr) { + return res.concat(object[curr]); + }, []); + + return array; +}; + +// Has Domain Store +export const hasDomainStore = () => { + var currentDomain = window.location.hostname; + + return currentDomain.includes("gkcorp.com.vn"); +}; + +// Convert Header Item Vietsub + +export const convertNameHeaderItem = (type) => { + switch (type) { + case TypeHeaderNewsItem.INTRODUCTION: + return "Ứng dụng DẠY và HỌC Tiếng Anh dành cho học sinh THCS | Sunday English"; + case TypeHeaderNewsItem.COURSES: + return "Trọn bộ Khóa học | Sunday English"; + case TypeHeaderNewsItem.FEE: + case TypeHeaderNewsItem.TARIFF: + return "Bảng giá | Sunday English"; + case TypeHeaderNewsItem.PARENT: + return "Giúp ba mẹ kèm con học Tiếng Anh | Sunday Parent"; + case TypeHeaderNewsItem.TEACHER: + return "Trợ giảng đắc lực của thầy cô | Sunday Teacher"; + case TypeHeaderNewsItem.MOCK_TEST: + return "Thi thử và Giải đề miễn phí | Sunday English"; + case "fee_policy": + return "Hướng dẫn thanh toán | Sunday English"; + case "policy": + return "Điều khoản và Chính sách dịch vụ | Sunday English"; + case "faq": + return "Câu hỏi thường gặp | Sunday English"; + case "account_activation": + return "Hướng dẫn Đăng ký - Đăng nhập - Kích hoạt tài khoản | Sunday English"; + default: + return "Sunday English - Nâng cao điểm số Tiếng Anh"; + } +}; + +// Function to remove Vietnamese diacritics +export const removeVietnameseDiacritics = (str) => { + return str.normalize("NFD").replace(/[\u0300-\u036f]/g, ""); +}; + +// Convert Skill name to Vietnamese +export const convertNameSkillVn = (skill) => { + switch (skill) { + case "exam": + return "Bài kiểm tra"; + case "project": + return "Bài tập lớn"; + case "mini_test": + return "Bài kiểm tra"; + case "pronunciation": + return "Phát âm"; + case "vocabulary": + return "Từ vựng"; + case "grammar": + return "Ngữ pháp"; + case "reading": + return "Đọc"; + case "listening": + return "Nghe"; + case "speaking": + return "Nói"; + case "writing": + return "Viết"; + default: + return ""; + } +}; + +// Check equal between 2 arrays +export function arraysAreEqual(arr1, arr2) { + // Check if arrays have the same length + if (arr1.length !== arr2.length) { + return false; + } + + // Check if each object in the arrays is equal based on object properties + return arr1.every((obj1, index) => { + const obj2 = arr2[index]; + // Check if the number of keys is equal + if (Object.keys(obj1).length !== Object.keys(obj2).length) { + return false; + } + // Check if all key-value pairs are equal + return Object.keys(obj1).every((key) => obj1[key] === obj2[key]); + }); +} + +// Convert & +export function replaceAnd(obj) { + for (let key in obj) { + if (obj.hasOwnProperty(key)) { + if (typeof obj[key] == "string") { + obj[key] = obj[key].replace(/&/g, "and"); + } else if (typeof obj[key] == "object" && obj[key] !== null) { + replaceAnd(obj[key]); + } + } + } + return obj; +} diff --git a/src/_base/animsScroll.js b/src/_base/animsScroll.js new file mode 100644 index 0000000..a15f066 --- /dev/null +++ b/src/_base/animsScroll.js @@ -0,0 +1,29 @@ +// Function Animation Scroll +function easeInOutQuad(t, b, c, d) { + t /= d / 2; + if (t < 1) return (c / 2) * t * t + b; + t--; + return (-c / 2) * (t * (t - 2) - 1) + b; +} + +export function smoothScroll(container, change, duration) { + const startTime = performance.now(); + const initialScrollLeft = container.scrollLeft; + + function step(currentTime) { + const elapsedTime = currentTime - startTime; + if (elapsedTime < duration) { + container.scrollLeft = easeInOutQuad( + elapsedTime, + initialScrollLeft, + change, + duration + ); + requestAnimationFrame(step); + } else { + container.scrollLeft = initialScrollLeft + change; + } + } + + requestAnimationFrame(step); +} diff --git a/src/_components/Admin/Curriculum/ChangView.js b/src/_components/Admin/Curriculum/ChangView.js new file mode 100644 index 0000000..4e1e5aa --- /dev/null +++ b/src/_components/Admin/Curriculum/ChangView.js @@ -0,0 +1,31 @@ +import React, { useState } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { curriculumConstants } from '../../../_constants'; + +function ChangView(props) { + const dispatch = useDispatch(); + const curriculums = useSelector(state => state.curriculums); + + const [view, setView] = useState(curriculums.view); + let { student } = props; + function changeView(view) { + setView(view); + dispatch({ + type: curriculumConstants.CHANGE_VIEW, + view + }) + } + + return ( +
    + ico_bar changeView('grid')} /> + { student ? + ico_bar changeView('map')} /> + : + ico_bar changeView('map')} /> + } +
    + ); +} + +export { ChangView }; \ No newline at end of file diff --git a/src/_components/Admin/Curriculum/ShowMapGrid.js b/src/_components/Admin/Curriculum/ShowMapGrid.js new file mode 100644 index 0000000..c306311 --- /dev/null +++ b/src/_components/Admin/Curriculum/ShowMapGrid.js @@ -0,0 +1,319 @@ +import React, { useState, Fragment, useEffect, useCallback } from "react"; +import { useSelector } from "react-redux"; +import { useParams, Link } from "react-router-dom"; +import "../../../_containers/StudentPage/style.scss"; +import { smoothScroll } from "../../../_base/animsScroll"; +import $ from "jquery"; +import LazyLoad from "react-lazyload"; +import { history } from "../../../_helpers"; +import { isEmpty } from "lodash"; + +function ShowMapGrid(props) { + const { view, curriculums } = props; + const authentication = useSelector((state) => state.authentication); + const { id } = useParams(); + const [unitIdSelected, setnitIdSelected] = useState(false); + + // Define the amount to scroll by when the buttons are clicked + const scrollAmount = 750; + const animationDuration = 300; + const [canPrev, setCanPrev] = useState(false); + const [canNext, setCanNext] = useState(true); + const search = history?.location?.search; + const params = new URLSearchParams(search); + const fromPage = params?.get("page"); + + const [contentMapCurriculum, setContentMapCurriculum] = useState( + document.querySelector("#sunE_map_curriculum") + ); + + useEffect(() => { + setContentMapCurriculum(document.querySelector("#sunE_map_curriculum")); + }, []); + + useEffect(() => { + $(document).ready(function ($) { + var down = false; + var scrollLeft = 0; + var x = 0; + + $(".sunE-content-unit") + .mousedown(function (e) { + down = true; + scrollLeft = this.scrollLeft; + x = e.clientX; + }) + .mouseup(function () { + down = false; + }) + .mousemove(function (e) { + var maxScroll = this.scrollWidth - this.clientWidth; + + if (down) { + this.scrollLeft = scrollLeft + x - e.clientX; + if (this.scrollLeft == 0) { + setCanPrev(false); + } else { + setCanPrev(true); + if (this.scrollLeft >= maxScroll) { + setCanNext(false); + } else { + setCanNext(true); + } + } + } + }) + .mouseleave(function () { + down = false; + }); + }); + }, []); + + // Handlle Click Btn Move Map + const handleClickBtnMap = (type) => { + switch (type) { + case "prev": + if (contentMapCurriculum.scrollLeft > 0) { + setCanNext(true); + smoothScroll(contentMapCurriculum, -scrollAmount, animationDuration); + if (contentMapCurriculum?.scrollLeft - scrollAmount <= 0) { + setCanPrev(false); + } + } else { + setCanPrev(false); + } + break; + case "next": + if ( + contentMapCurriculum?.scrollLeft + contentMapCurriculum.clientWidth < + contentMapCurriculum.scrollWidth + ) { + setCanPrev(true); + smoothScroll(contentMapCurriculum, scrollAmount, animationDuration); + if ( + contentMapCurriculum?.scrollLeft + + contentMapCurriculum.clientWidth + + scrollAmount >= + contentMapCurriculum.scrollWidth + ) { + setCanNext(false); + } + } else { + setCanNext(false); + } + break; + default: + } + }; + + const upperFirstCase = useCallback( + (actionName) => { + if (!actionName) { + return ""; + } + return actionName.charAt(0).toUpperCase() + actionName.slice(1); + }, + [curriculums] + ); + + return ( +
    + {view === "map" && ( + <> +
    +
    + {curriculums.detail.data_lesson.unit_name.map((data, i) => { + let avatar = "/assets/images/giaotrinh/avt_default_unit.png"; + if (data.unit_avatar) { + avatar = curriculums?.detail.base_url + data?.unit_avatar; + } + return ( +
    + {i % 2 === 0 ? ( + + +
    +

    {data?.stt}

    +

    {data?.unit_name}

    +
    + +
    +
    + +
    +

     

    +
    + {curriculums.detail.data_lesson.unit_name.length - 1 !== + i && ( + + )} +
    + ) : ( + +
    +

     

    +
    + +
    +

    {data.stt}

    +

    {data.unit_name}

    +
    + +
    +
    + + {curriculums.detail.data_lesson.unit_name.length - 1 !== + i && ( + + )} +
    + )} +
    + ); + })} +
    +
    + +
    + + +
    + + )} + {view === "grid" && ( +
    +
    + {curriculums.detail.data_lesson.unit_name.map((data, i) => { + return ( +
    +
    +
    + setnitIdSelected( + unitIdSelected === data.unit_id ? false : data.unit_id + ) + } + > +
    +

    + + {data.stt + (_.isEmpty(data.stt) ? "" : ": ")} + {data.unit_name} + +

    +
    +
    setnitIdSelected(false)} + > + - +
    +
    + {data.list_skill.map((dataSkill, i) => { + return ( + +
    +
    +
    +

    + {upperFirstCase( + dataSkill?.skill_name + ? dataSkill.skill_name + : dataSkill?.skill + ?.replace("_", " ") + ?.capitalize() + )} +

    +
    +
    +
    + + ); + })} +
    +
    + ); + })} +
    +
    + )} +
    + ); +} + +export { ShowMapGrid }; diff --git a/src/_components/Admin/Curriculum/index.js b/src/_components/Admin/Curriculum/index.js new file mode 100644 index 0000000..b053d79 --- /dev/null +++ b/src/_components/Admin/Curriculum/index.js @@ -0,0 +1,2 @@ +export * from './ShowMapGrid'; +export * from './ChangView'; \ No newline at end of file diff --git a/src/_components/Admin/Header/Header.js b/src/_components/Admin/Header/Header.js new file mode 100644 index 0000000..9e12607 --- /dev/null +++ b/src/_components/Admin/Header/Header.js @@ -0,0 +1,31 @@ +import React from "react"; +import { useHistory } from "react-router-dom"; + +function Header(props) { + const title = props.title; + const component = props.component ? props.component : null; + const isBack = props.isBack ? true : false; + const history = useHistory(); + const clickBack = props.clickBack + ? () => props.clickBack() + : () => history.goBack(); + + return ( +
    + +

    {title}

    + {component} + {isBack ? ( +
    + +
    + ) : ( + "" + )} +
    + ); +} + +export { Header }; diff --git a/src/_components/Admin/Header/index.js b/src/_components/Admin/Header/index.js new file mode 100644 index 0000000..64f7c87 --- /dev/null +++ b/src/_components/Admin/Header/index.js @@ -0,0 +1 @@ +export * from './Header'; \ No newline at end of file diff --git a/src/_components/Admin/More/License/SideBar.js b/src/_components/Admin/More/License/SideBar.js new file mode 100644 index 0000000..ab92a15 --- /dev/null +++ b/src/_components/Admin/More/License/SideBar.js @@ -0,0 +1,42 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; + +import { NavLink } from 'react-router-dom'; + +function SideBar() { + const authentication = useSelector(state => state.authentication); + + return ( +
    + {/* + + {"alt_image"} + {"alt_image"} + +
    +

    Nhập mã

    +
    +
    */} + + + {"alt_image"} + {"alt_image"} + +
    +

    Mua gói mới

    +
    +
    + + + {"alt_image"} + {"alt_image"} + +
    +

    Lịch sử giao dịch

    +
    +
    +
    + ); +} + +export { SideBar }; \ No newline at end of file diff --git a/src/_components/Admin/More/License/index.js b/src/_components/Admin/More/License/index.js new file mode 100644 index 0000000..88ce129 --- /dev/null +++ b/src/_components/Admin/More/License/index.js @@ -0,0 +1 @@ +export * from './SideBar'; \ No newline at end of file diff --git a/src/_components/Admin/More/Schedule/EmptyScheduleToday.js b/src/_components/Admin/More/Schedule/EmptyScheduleToday.js new file mode 100644 index 0000000..7b21863 --- /dev/null +++ b/src/_components/Admin/More/Schedule/EmptyScheduleToday.js @@ -0,0 +1,64 @@ +import React from "react"; +import { Link } from "react-router-dom"; +import { useSelector } from "react-redux"; +import moment from "moment"; +import LazyLoad from "react-lazyload"; + +function EmptyScheduleToday(props) { + const { selectedDate } = props; + const authentication = useSelector((state) => state.authentication); + const schedules = useSelector((state) => state.schedules); + let isButtonTKH = props.isButtonTKH ? true : false; + let isBCHT = props.isBCHT ? true : false; + let ViewScheduleStudentDetail = props.ViewScheduleStudentDetail; + + const isTodaySchedule = + moment( + ViewScheduleStudentDetail + ? schedules.dateSelectedCalendar + : schedules.selectDate + ).format("YYYY-MM-DD") == moment().format("YYYY-MM-DD"); + return ( +
    + + {"no_plan"} +

    + {isBCHT + ? "CHƯA CÓ HOẠT ĐỘNG" + : isTodaySchedule + ? "BẠN CHƯA CÓ KẾ HOẠCH NÀO" + : "BẠN CHƯA TẠO KẾ HOẠCH NÀO"} +
    + CHO{" "} + {isTodaySchedule + ? isBCHT + ? "NGÀY HÔM NAY" + : "NGÀY HÔM NAY" + : "NGÀY NÀY"} +

    + {isButtonTKH && ( +
    + + + +
    + )} +
    +
    + ); +} + +export { EmptyScheduleToday }; diff --git a/src/_components/Admin/More/Schedule/ScheduleToday.js b/src/_components/Admin/More/Schedule/ScheduleToday.js new file mode 100644 index 0000000..94a62ec --- /dev/null +++ b/src/_components/Admin/More/Schedule/ScheduleToday.js @@ -0,0 +1,51 @@ +import React, { useEffect } from "react"; +import { ScheduleTodayItem } from "./ScheduleTodayItem"; +import { scheduleConstants } from "../../../../_constants"; +import { PopUpRadio } from "./../../../Popup"; +import { useDispatch } from "react-redux"; + +function ScheduleToday(props) { + const { selectedDate, type } = props; + const dispatch = useDispatch(); + const schedules = props.schedules; + let { student, page } = props; + if (page === undefined) { + page = "schedule"; + } + useEffect(() => { + dispatch({ + type: scheduleConstants.REMOVE_DETAIL_SCHEDULE_DAY, + }); + }, []); + + return ( +
    + + {schedules.map((schedule, i) => { + if (type === "personal") { + return ( + schedule.type === "personal" && ( + + ) + ); + } else { + return ( + + ); + } + })} +
    + ); +} + +export { ScheduleToday }; diff --git a/src/_components/Admin/More/Schedule/ScheduleTodayItem.js b/src/_components/Admin/More/Schedule/ScheduleTodayItem.js new file mode 100644 index 0000000..b9b4e33 --- /dev/null +++ b/src/_components/Admin/More/Schedule/ScheduleTodayItem.js @@ -0,0 +1,305 @@ +import React, { Fragment, useEffect, useState } from "react"; +import moment from "moment"; +import { scheduleConstants } from "../../../../_constants"; +import { scheduleActions } from "../../../../_actions"; +import { Link } from "react-router-dom"; +import { useSelector, useDispatch } from "react-redux"; +import { scheduleService } from "../../../../_services"; +import "./styles.scss"; + +function ScheduleTodayItem(props) { + const authentication = useSelector((state) => state.authentication); + const schedules = useSelector((state) => state.schedules); + const dispatch = useDispatch(); + let { schedule, page, selectedDate } = props; + const [showEdit, setShowEdit] = useState(false); + + function showEditFunc() { + setShowEdit(true); + } + + function hideEditFunc() { + setShowEdit(false); + } + + function addDataDetailScheduleDay(data) { + data.action = "edit"; + data.checkRemind = parseInt(data.remind_time) > 0 ? true : false; + dispatch({ + type: scheduleConstants.ADD_DETAIL_SCHEDULE_DAY, + data, + }); + } + + function removeDataDeleteScheduleDay(id) { + let data = { + id, + showForm: true, + repeatType: schedule.repeat_type, + }; + dispatch({ + type: scheduleConstants.ADD_DELETE_SCHEDULE_DAY, + data, + }); + setShowEdit(false); + } + + function successScheduleDay(id) { + let data = { + ...schedule, + status: "done", + }; + dispatch( + scheduleActions.completeSchedule( + data, + authentication.id, + schedules.selectDate + ) + ); + setShowEdit(false); + } + + const cancelScheduleDay = (id) => { + let now = new Date(); + const scheduleDate = new Date(schedule.end_time); + + let distanceTime = (now - scheduleDate) / (1000 * 60); + let status = ""; + + if (distanceTime > 0) { + status = "over_time"; + } else if (distanceTime >= 0 && distanceTime <= 30) { + status = "upcoming"; + } else { + status = "no_status"; + } + + let data = { + id, + status: status, + }; + + dispatch( + scheduleActions.completeSchedule( + data, + authentication.id, + schedules.selectDate + ) + ); + setShowEdit(false); + }; + + let isPageMore = window.location.pathname.indexOf("/more/") !== -1; + + useEffect(() => { + setShowEdit(false) + }, [schedules?.dateSelectedCalendar]) + + return ( +
    +
    +
    +
    +

    + {moment(schedule.start_time).format("HH:mm")} +

    + addDataDetailScheduleDay(schedule)} + > +

    + {(schedule.type === "teaching_work" + ? "Giảng dạy tại lớp " + : "") + schedule.title} +

    + +
    +
    + {scheduleConstants.TEXT_ICON_SCHEDULE_STATUS[schedule.status] && ( + +
    + {schedule.status} +
    + + { + scheduleConstants.TEXT_ICON_SCHEDULE_STATUS[ + schedule.status + ]["title"] + } + +
    + )} +
    +
    + addDataDetailScheduleDay(schedule)} + > +

    + {schedule.content} +

    + + ico_left_circle_blue + ico_right_circle_blue +
    +
    +
    + {!(schedule.status === "done") ? ( +
    successScheduleDay(schedule.id)} + > + ico_succes_small + {/*
    +

    Hoàn thành

    */} +
    + ) : ( +
    cancelScheduleDay(schedule.id)} + > + ico_delete + {/*
    +

    Bỏ Tick

    */} +
    + )} +
    + addDataDetailScheduleDay(schedule)} + > + ico_edit + {/*
    +

    Sửa

    */} + +
    +
    removeDataDeleteScheduleDay(schedule.id)} + > + ico_remove + {/*
    +

    Hủy

    */} +
    +
    +
    +
    + ); +} + +export { ScheduleTodayItem }; diff --git a/src/_components/Admin/More/Schedule/index.js b/src/_components/Admin/More/Schedule/index.js new file mode 100644 index 0000000..0b34a51 --- /dev/null +++ b/src/_components/Admin/More/Schedule/index.js @@ -0,0 +1,2 @@ +export * from './EmptyScheduleToday'; +export * from './ScheduleToday'; \ No newline at end of file diff --git a/src/_components/Admin/More/Schedule/styles.scss b/src/_components/Admin/More/Schedule/styles.scss new file mode 100644 index 0000000..86f30db --- /dev/null +++ b/src/_components/Admin/More/Schedule/styles.scss @@ -0,0 +1,4 @@ +.icon_status { + width: 1.8rem !important; + height: auto; +} diff --git a/src/_components/Admin/Schedule/SideBar/SideBar.js b/src/_components/Admin/Schedule/SideBar/SideBar.js new file mode 100644 index 0000000..969951b --- /dev/null +++ b/src/_components/Admin/Schedule/SideBar/SideBar.js @@ -0,0 +1,30 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; + +import { NavLink } from 'react-router-dom'; + +function SideBar() { + const authentication = useSelector(state => state.authentication); + + return ( +
    + +
    +

    Thời khóa biểu giảng dạy

    +
    +
    + +
    +

    Lịch làm việc ngày

    +
    +
    + +
    +

    Lịch làm việc năm

    +
    +
    +
    + ); +} + +export { SideBar }; \ No newline at end of file diff --git a/src/_components/Admin/Schedule/SideBar/index.js b/src/_components/Admin/Schedule/SideBar/index.js new file mode 100644 index 0000000..88ce129 --- /dev/null +++ b/src/_components/Admin/Schedule/SideBar/index.js @@ -0,0 +1 @@ +export * from './SideBar'; \ No newline at end of file diff --git a/src/_components/Admin/SideBar/SideBar.js b/src/_components/Admin/SideBar/SideBar.js new file mode 100644 index 0000000..05d6173 --- /dev/null +++ b/src/_components/Admin/SideBar/SideBar.js @@ -0,0 +1,315 @@ +import React, { useEffect, useState } from "react"; +import { NavLink } from "react-router-dom"; +import { useSelector, useDispatch } from "react-redux"; +import { userConstants } from "../../../_constants"; +import { useHistory } from "react-router-dom"; +import "./SideBar.styles.scss"; +import { PopUpYesNo } from "../../Popup"; +import { apiRequestLogout } from "../../../_helpers"; +import { persistor } from "../../../index"; +import API from "../../../_apis/APIConstants"; + +function SideBar() { + const history = useHistory(); + const search = history?.location?.search; + const params = new URLSearchParams(search); + const page = params.get("page"); + const authentication = useSelector((state) => state.authentication); + const chooseListCurriculum = useSelector( + (state) => state.rootlessness.chooseListCurriculum + ); + const assign = params.get("assign"); + const dispatch = useDispatch(); + + var isActiveHome = + window.location.pathname.indexOf("student/homework_by_teacher") !== -1 || + window.location.pathname.indexOf("teacher/more/schedule/edit/homepage") !== + -1 || + window.location.pathname.indexOf("teacher/more/schedule/add/homepage") !== + -1 || + page === "homepage"; + + // Logout Function + const [visibleModalLogout, setVisibleModalLogout] = useState(false); + + function logout() { + apiRequestLogout(`${API.logout_account_service}`); + apiRequestLogout(`${API.logout_account_exercise}`); + window.location.href = "/login"; + dispatch({ + type: userConstants.RESET_ALL_STATE, + }); + dispatch({ + type: userConstants.LOGOUT, + }); + persistor.purge(); + // localStorage.clear(); + localStorage.removeItem("authentication"); + localStorage.removeItem("access_token"); + localStorage.removeItem("info_header_user"); + localStorage.removeItem("purposeLogin"); + localStorage.removeItem("date_selected"); + localStorage.removeItem("curriculum_info"); + localStorage.removeItem("curriculum_id_Selected"); + + // localStorage.removeItem("device_id_commond"); + // history.push("/login"); + } + + return ( +
    +
    + e.preventDefault() + : () => {} + } + > + Logo + +
    +
    + e.preventDefault() + : () => {} + } + > +
    + ico_home + ico_home_active +
    + Trang chủ +
    + {authentication.role === userConstants.ROLE_TEACHER && ( + +
    + ico_lop + ico_lop +
    + Quản lý lớp +
    + )} + e.preventDefault() + : () => {} + } + > +
    + ico_book + ico_book +
    + Giáo trình +
    + {authentication.role === userConstants.ROLE_STUDENT && ( + e.preventDefault() + : () => {} + } + > +
    + ico_luyenthi + ico_luyenthi +
    + Luyện thi +
    + )} + {authentication.role === userConstants.ROLE_STUDENT && ( + e.preventDefault() + : () => {} + } + > +
    + ico_thanhtich + ico_thanhtich +
    + Thành tích +
    + )} + {authentication.role === userConstants.ROLE_TEACHER && ( + +
    + ico_message + ico_message +
    + Tin nhắn +
    + )} + e.preventDefault() + : () => {} + } + > +
    + ico_xemthem + ico_xemthem +
    + Thêm +
    +
    + +
    + setVisibleModalLogout(true)} + className='flex menu-item flex-center menu-item-logout' + > +
    + ico_xemthem +
    + Đăng xuất +
    +
    + {visibleModalLogout && ( + logout()} + onClickNo={() => setVisibleModalLogout(false)} + labelNo={"Không"} + message={["Bạn có muốn đăng xuất tài khoản không?"]} + customWidthBtn={"customWidthBtn"} + /> + )} +
    + ); +} + +export { SideBar }; diff --git a/src/_components/Admin/SideBar/SideBar.styles.scss b/src/_components/Admin/SideBar/SideBar.styles.scss new file mode 100644 index 0000000..613281c --- /dev/null +++ b/src/_components/Admin/SideBar/SideBar.styles.scss @@ -0,0 +1,11 @@ +.not_allowed_first_choose_curriculum { + cursor: not-allowed; +} + +.not_allowed_first_choose_curriculum:hover { + background: none !important; +} + +.not_allowed_curriculum { + cursor: not-allowed !important; +} diff --git a/src/_components/Admin/SideBar/index.js b/src/_components/Admin/SideBar/index.js new file mode 100644 index 0000000..88ce129 --- /dev/null +++ b/src/_components/Admin/SideBar/index.js @@ -0,0 +1 @@ +export * from './SideBar'; \ No newline at end of file diff --git a/src/_components/Admin/Student/SideBarAssessment.js b/src/_components/Admin/Student/SideBarAssessment.js new file mode 100644 index 0000000..76f384e --- /dev/null +++ b/src/_components/Admin/Student/SideBarAssessment.js @@ -0,0 +1,69 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; + +import { NavLink } from 'react-router-dom'; + +function SideBarAssessment(props) { + const activeHome = props.home; + const authentication = useSelector(state => state.authentication); + return ( +
    + + + ico_default + ico_default + +
    +

    Thành tích Online

    +
    +
    + + + ico_default + ico_default + +
    +

    Thành tích Offline

    +
    +
    + + + ico_default + ico_default + +
    +

    Bảng xếp hạng

    +
    +
    + + {activeHome &&
    +

    Thành tích cá nhân

    +
    +
    + ico_avt +
    +

    Nguyễn Anh Hùng

    +
    +

    Thứ Hạng:

    +
    + 4 +
    +
    +
    +

    Điểm:

    +
    + 1200 +
    +
    +

    Bạn đang ở hạng Lục bảo

    +
    + ico_pl_lucbao +
    +
    +
    } + +
    + ); +} + +export { SideBarAssessment }; \ No newline at end of file diff --git a/src/_components/Admin/Student/SlideHomePage.js b/src/_components/Admin/Student/SlideHomePage.js new file mode 100644 index 0000000..c5a53b2 --- /dev/null +++ b/src/_components/Admin/Student/SlideHomePage.js @@ -0,0 +1,202 @@ +import React, { useEffect, useState, useRef } from "react"; +import Slider from "react-slick"; +import { ChartDoughnut } from "./../../Chart"; +import { Link } from "react-router-dom"; +import { isEmpty } from "lodash"; +import { configConstants } from "../../../_constants"; +import { homeType } from "../../../_constants"; +import { useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import $ from "jquery"; + +function SampleNextArrow(props) { + const { className, onClick } = props; + return ( +
    + ico_right_white +
    + ); +} + +function SamplePrevArrow(props) { + const { className, onClick } = props; + return ( +
    + ico_left_white +
    + ); +} + +function SliderHomePage(props) { + const dispatch = useDispatch(); + const learns = useSelector((state) => state.learns); + const [currentSlideIndex, setCurrentSlideIndex] = useState(0); // State to track the current slide index + const sliderRef = useRef(null); // Ref for Slider component + const itemActiveHomeStudent = useSelector( + (state) => state.home_page_reducer.itemActiveHomeStudent + ); + let { dataList, role, getExercises, examSelected, setLoading } = props; + + const reRenderSlide = () => { + if ( + sliderRef && + sliderRef.current && + dataList?.length > 0 && + !examSelected + ) { + if (itemActiveHomeStudent && itemActiveHomeStudent.type) { + const checkTypeIndex = (item) => { + return itemActiveHomeStudent.type == "curriculum" + ? item?.curriculum_id?.trim() + : item?.id?.trim(); + }; + + const index = dataList.findIndex( + (item) => checkTypeIndex(item) == itemActiveHomeStudent?.id?.trim() + ); + dispatch({ + type: homeType.SELECT_TEACHER_OR_CURRICULUM, + payload: { + type: itemActiveHomeStudent?.type, + id: itemActiveHomeStudent?.id, + scrollTop: 0, + }, + }); + + setCurrentSlideIndex(index); + sliderRef.current.slickGoTo(index); + } else { + setCurrentSlideIndex(0); + sliderRef.current.slickGoTo(0); + } + } + }; + + // rerender for visible change + const handleVisibilityChange = () => { + const currIndex = sliderRef.current.innerSlider.state.currentSlide ?? 0; + setLoading(true); + dispatch({ + type: homeType.SELECT_TEACHER_OR_CURRICULUM, + payload: { + type: dataList[currIndex]?.type_slide, + id: + dataList[currIndex]?.type_slide == "curriculum" + ? dataList[currIndex]?.curriculum_id + : dataList[currIndex]?.id, + scrollTop: 0, + }, + }); + sliderRef.current.slickGoTo(currIndex); + }; + + useEffect(() => { + window.addEventListener("pageshow", handleVisibilityChange); + return () => { + window.removeEventListener("pageshow", handleVisibilityChange); + }; + }, []); + + useEffect(() => { + // Set the current index when itemActiveHomeStudent changes + reRenderSlide(); + }, [ + sliderRef, + itemActiveHomeStudent?.id, + learns.data.list_teacher, + learns.data.list_curriculum, + examSelected, + ]); + + const settings = { + dots: true, + infinite: true, + slidesToShow: 1, + slidesToScroll: 1, + nextArrow: , + prevArrow: , + beforeChange: (oldIndex, newIndex) => { + let currIndex = newIndex ?? 0; + setCurrentSlideIndex(currIndex); + dispatch({ + type: homeType.SELECT_TEACHER_OR_CURRICULUM, + payload: { + type: dataList[currIndex]?.type_slide, + id: + dataList[currIndex]?.type_slide == "curriculum" + ? dataList[currIndex]?.curriculum_id + : dataList[currIndex]?.id, + scrollTop: 0, + }, + }); + setLoading(true); + getExercises( + dataList[currIndex]?.type_slide, + dataList[currIndex]?.type_slide == "curriculum" + ? dataList[currIndex]?.curriculum_id + : dataList[currIndex]?.id + ); + }, + }; + + return ( +
    +
      + + {dataList?.map((data, i) => { + let avatarRes = + data?.type_slide == "curriculum" ? data?.class_avatar : data?.avatar; + + let AVATAR = isEmpty(data?.avatar) + ? data?.type_slide == "teacher" + ? "/assets/images/student/teacher_detail.png" + : data?.type_slide == "parent" + ? `${configConstants.BASE_URL}assets/img_base/parent_male_dfa.jpg` + : `${configConstants.BASE_URL}assets/img_base/class_dfa.jpg` + : configConstants.BASE_URL + avatarRes; + + return ( +
    • +
      +
      + detail2 +
      +
      +
      + {data?.type_slide == "curriculum" + ? "Bài giáo trình" + : data?.type_slide == 'parent' ? 'Bài tập' : "Bài tập về nhà"} +
      + +
      + +
      +
      + {data?.type_slide == "teacher" ? "Giáo viên" : data?.type_slide == "parent" ? "Phụ huynh" : "Lớp"} +
      + +
      + {data?.type_slide == "curriculum" + ? data?.class_name + : data?.fullname} +
      +
      +
      +
      +
    • + ); + })} +
      +
    +
    + ); +} + +export { SliderHomePage }; diff --git a/src/_components/Admin/Student/index.js b/src/_components/Admin/Student/index.js new file mode 100644 index 0000000..e77ff99 --- /dev/null +++ b/src/_components/Admin/Student/index.js @@ -0,0 +1 @@ +export * from './SideBarAssessment'; \ No newline at end of file diff --git a/src/_components/Admin/Teacher/DetailSystemMessage.js b/src/_components/Admin/Teacher/DetailSystemMessage.js new file mode 100644 index 0000000..0be6bcd --- /dev/null +++ b/src/_components/Admin/Teacher/DetailSystemMessage.js @@ -0,0 +1,22 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import moment from "moment"; + +function DetailSystemMessage(props) { + const dataMessage = useSelector(state => state.messages.data_message); + let messageIndex = props.messageIndex; + let dataMess = messageIndex >= 0 ? dataMessage.data[messageIndex] : ''; + return ( +
    + bg_update + {dataMess &&
    +

    Tiêu đề: {dataMess.title}

    +

    Nội dung: {dataMess.msg}

    +

    Gửi lúc: {moment(dataMess.created_at).format('HH:mm:ss, DD-MM-YYYY')}

    +
    } +
    + ); + +} + +export { DetailSystemMessage }; \ No newline at end of file diff --git a/src/_components/Admin/Teacher/EmptyClassBlock.js b/src/_components/Admin/Teacher/EmptyClassBlock.js new file mode 100644 index 0000000..a05ab38 --- /dev/null +++ b/src/_components/Admin/Teacher/EmptyClassBlock.js @@ -0,0 +1,34 @@ +import React, { Fragment } from 'react'; +import { useSelector } from 'react-redux'; +import { userConstants } from '../../../_constants'; + +function EmptyClassBlock({messagEmpty}) { + const authentication = useSelector(state => state.authentication); + + return ( + + { + authentication.role === userConstants.ROLE_TEACHER ? +
    + img_no_class_big + {messagEmpty ?

    + {messagEmpty} +

    : +

    Bạn chưa có lớp học nào, hãy ấn “TẠO LỚP MỚI” để bắt đầu.

    + } +
    + : +
    + img_no_class_big + {messagEmpty ?

    + {messagEmpty} +

    : +

    Bạn chưa có lớp học nào, hãy ấn “Xin vào lớp mới” để bắt đầu.

    + } +
    + } +
    + ); +} + +export { EmptyClassBlock }; \ No newline at end of file diff --git a/src/_components/Admin/Teacher/EmptyClassSlider.js b/src/_components/Admin/Teacher/EmptyClassSlider.js new file mode 100644 index 0000000..e2faea1 --- /dev/null +++ b/src/_components/Admin/Teacher/EmptyClassSlider.js @@ -0,0 +1,78 @@ +import React from "react"; +import { Link } from "react-router-dom"; +import { useSelector } from "react-redux"; + +function EmptyClassSlider() { + const authentication = useSelector((state) => state.authentication); + return ( +
    +
    +
    +
      +
    • +
      +
      + img_no_class +
      +
      +
      +

      + Bạn chưa có lớp học{" "} + online nào. +
      + Để theo dõi báo cáo học tập, hãy tạo lớp! +

      + + ico_add + + + + +
      +
      +
      +
    • +
    +
    + +
      +
    +
    + ); +} + +export { EmptyClassSlider }; diff --git a/src/_components/Admin/Teacher/EmptyStudent.js b/src/_components/Admin/Teacher/EmptyStudent.js new file mode 100644 index 0000000..86c58b7 --- /dev/null +++ b/src/_components/Admin/Teacher/EmptyStudent.js @@ -0,0 +1,14 @@ +import React from 'react'; + +function EmptyStudent() { + return ( +
    + +
    +

    Lớp học hiện tại chưa có thành viên nào.

    +
    +
    + ); +} + +export { EmptyStudent }; \ No newline at end of file diff --git a/src/_components/Admin/Teacher/ListClass.js b/src/_components/Admin/Teacher/ListClass.js new file mode 100644 index 0000000..dda3477 --- /dev/null +++ b/src/_components/Admin/Teacher/ListClass.js @@ -0,0 +1,70 @@ +import React, { useEffect } from "react"; +import { Link } from "react-router-dom"; +import { useSelector } from "react-redux"; +import { userConstants } from "../../../_constants"; +import LazyLoad from "react-lazyload"; + +function ListClass(props) { + let { classes, base_url, handleScroll } = props; + const authentication = useSelector((state) => state.authentication); + + return ( +
    handleScroll(e)} + > + + {classes.map((data, i) => { + let link = + authentication.role === userConstants.ROLE_TEACHER + ? "/" + authentication.role + : "/" + authentication.role + "/more"; + link += + "/class/view/" + + (data?.class_id ? data?.class_id : data?.id) + + (data?.type === "offline" ? "/offline" : ""); + return ( + data && ( +
    +
    + +
    +
    + avatar +
    +
    +

    + {data?.class_name} +

    +
    +
    +

    + {data?.organization_name} +

    + + Lớp{" "} + + {" "} + {data?.type} + + +
    +
    +
    +
    + +
    +
    + ) + ); + })} +
    +
    + ); +} + +export { ListClass }; diff --git a/src/_components/Admin/Teacher/ListClassMessage.js b/src/_components/Admin/Teacher/ListClassMessage.js new file mode 100644 index 0000000..064c744 --- /dev/null +++ b/src/_components/Admin/Teacher/ListClassMessage.js @@ -0,0 +1,118 @@ +import React, { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; +import { useSelector } from "react-redux"; +import { teacherService } from "../../../_services"; +import { userConstants } from "../../../_constants"; + +function ListClassMessage(props) { + let classes = props.classes; + const authentication = useSelector((state) => state.authentication); + const [numberMsg, setNumberMsg] = useState(0); + useEffect(() => { + teacherService.getInboxInfo().then((data) => { + setNumberMsg(data.number_msg_new); + }); + }, []); + + return ( +
    props.onScroll(e)} + className='sunE-class-list uk-container' + > +
    + {classes + .filter((item) => item?.total_student > 0) + .map((data, i) => { + return ( +
    + +
    +
    + +
    +
    +

    + {data.class_name} +

    +

    {data.organization_name}

    + + Lớp{" "} + + {data.type} + + +
    +
    + +
    + +
    + ico_message + {data?.msg_msg_new &&
    + + +
    + ico_ring + {data?.msg_system_new &&
    + +
    + +
    + ); + })} +
    +
    + ); +} + +export { ListClassMessage }; diff --git a/src/_components/Admin/Teacher/ListDetailMessage.js b/src/_components/Admin/Teacher/ListDetailMessage.js new file mode 100644 index 0000000..ca4a0d6 --- /dev/null +++ b/src/_components/Admin/Teacher/ListDetailMessage.js @@ -0,0 +1,75 @@ +import React, { useEffect, useState } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { teacherActions } from '../../../_actions'; +import { useParams } from "react-router-dom"; +import moment from "moment"; + +function ListDetailMessage(props) { + const { id } = useParams(); + let roomId = props.roomId; + + const dispatch = useDispatch(); + const authentication = useSelector(state => state.authentication); + const detailMessage = useSelector(state => state.messages.detail_message); + const [inputs, setInputs] = useState({ + room_id: roomId, + to_user_id: '', + subject: '', + content: '', + reply_for_id: '', + class_id: id + }); + const { content } = inputs; + useEffect(() => { + dispatch(teacherActions.getProfileV2(authentication.id)); + }, []); + + function handleChange(e) { + const { name, value } = e.target; + setInputs(inputs => ({ ...inputs, [name]: value })); + } + + function handleSubmit(e) { + e.preventDefault(); + if (validateParam()) { + dispatch(teacherActions.sendMessage(inputs)); + } + dispatch(teacherActions.getDetailMessage(roomId)); + setInputs(inputs => ({ ...inputs, 'content': '' })); + } + + function validateParam() { + return content ? true : false; + } + + return ( +
    + bg_update + { detailMessage.data.map((data, i) => { + return ( +
    +

    Người gửi: {data.fullname}

    +

    Nội dung: {data.msg}

    +

    Gửi lúc: {moment(data.send_time).format('HH:mm:ss, DD-MM-YYYY')}

    +
    + ) + })} +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + ); +} + +export { ListDetailMessage }; \ No newline at end of file diff --git a/src/_components/Admin/Teacher/ListStudent.js b/src/_components/Admin/Teacher/ListStudent.js new file mode 100644 index 0000000..72d7ab9 --- /dev/null +++ b/src/_components/Admin/Teacher/ListStudent.js @@ -0,0 +1,263 @@ +import React, { Fragment, useEffect, useRef, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { teacherActions } from "./../../../_actions"; +import { teacherService } from "./../../../_services"; +import { PopUpRemoveStudentInClass } from "../../Popup"; +import { Alert } from "./../../../_components/Alert"; +import { + teacherConstants, + configConstants, + userConstants, +} from "././../../../_constants"; +import Pagination from "react-js-pagination"; +import { useParams } from "react-router-dom"; +import { alertActions } from "../../../_actions/alerts"; +import { hasDuplicates } from "../../../_base/Validate"; + +function ListStudent(props) { + const { id } = useParams(); + + const [pagination] = useState({ + limit: configConstants.DEFAULT_LIMIT, + offset: 0, + }); + const [isLoadMore, setLoadMore] = useState(true); + const [isLoading, setLoading] = useState(false); + + const alert = useSelector((state) => state.alert); + const authentication = useSelector((state) => state.authentication); + + const dispatch = useDispatch(); + const [dataStudent, setDataStudent] = useState({ + id: "", + name: "", + member_id: "", + }); + + const [showPopup, setShowPopup] = useState(false); + const [currentPage, setCurrentPage] = useState(1); + + let { students, class_detail } = props; + // console.log(class_detail); + + useEffect(() => { + if ( + alert.message && + alert.screen === teacherConstants.SCREEN_LIST_STUDENT + ) { + setCurrentPage(1); + } + }, [alert]); + + useEffect(() => { + return () => { + dispatch({ + type: teacherConstants.GET_STUDENT_OFF_CLASS, + students: { + data: [], + base_url: "", + }, + }); + }; + }, []); + + function showPopUpRemove(data) { + setShowPopup(true); + setDataStudent(data); + } + + function removeStudent(id) { + setShowPopup(false); + teacherActions + .removeStudent({ + id: props.class_id, + students: id, + }) + .then( + (res) => { + dispatch( + alertActions.success({ + message: "Xoá học sinh thành công", + screen: teacherConstants.SCREEN_LIST_STUDENT, + }) + ); + let list = students.data.filter((item) => item.id !== id); + dispatch({ + type: teacherConstants.GET_STUDENT_OFF_CLASS, + students: { + data: list, + base_url: students.base_url, + }, + }); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_LIST_STUDENT, + }) + ); + } + ); + } + + // console.log(students.data); + + function removeStudentOffline(class_member_id) { + setShowPopup(false); + teacherActions.removeStudentOffline(class_member_id).then( + (res) => { + dispatch( + alertActions.success({ + message: "Xoá học sinh thành công", + screen: teacherConstants.SCREEN_LIST_STUDENT, + }) + ); + let list = students.data.filter( + (item) => item.member_id !== class_member_id + ); + dispatch({ + type: teacherConstants.GET_STUDENT_OFF_CLASS, + students: { + data: list, + base_url: students.base_url, + }, + }); + }, + (error) => { + dispatch( + alertActions.error({ + message: error.toString(), + screen: teacherConstants.SCREEN_LIST_STUDENT, + }) + ); + } + ); + } + + function handlePageChange(pageNumber, isLoadingSide) { + if (currentPage != pageNumber && !isLoading) { + setLoading(true); + teacherService + .getStudentOfClass( + id, + pagination.limit, + pagination.limit * (pageNumber - 1), + isLoadingSide + ) + .then((res) => { + setLoading(false); + if (!hasDuplicates(students.data, res.data)) { + setCurrentPage(pageNumber); + setLoadMore(res.data?.length == configConstants.DEFAULT_LIMIT); + dispatch({ + type: teacherConstants.GET_STUDENT_OFF_CLASS, + students: { + data: [...students.data, ...res.data], + base_url: students.base_url, + }, + }); + } + }); + } + } + + // Handle Scroll + const handleScroll = (e) => { + if ( + e.target.scrollHeight - e.target.scrollTop < e.target.clientHeight + 5 && + isLoadMore && + !isLoading + ) { + // console.log('Scroll to bottom load more data'); + handlePageChange(currentPage + 1, true); + } + }; + + return ( + + {alert.message && + alert.screen === teacherConstants.SCREEN_LIST_STUDENT && ( + + )} + {showPopup && ( + + class_detail.type == "offline" + ? removeStudentOffline(dataStudent.member_id) + : removeStudent(dataStudent.id) + } + onClickNo={() => setShowPopup(false)} + message={dataStudent.name} + /> + )} +
    +

    Danh sách lớp

    +
    +
    handleScroll(e)} + > +
    + {students.data.map((data, i) => { + return ( +
    +
    + {i + 1} +
    + avatar +
    +
    +

    + {data.fullname ? data.fullname : data.username} +

    +
    + {authentication.role === userConstants.ROLE_TEACHER && ( +
    + showPopUpRemove({ + id: data.id, + name: data.fullname, + member_id: data.member_id, + }) + } + > + ico_remove_blue +
    + )} +
    +
    + ); + })} +
    +
    + {/* { + students.total_student > configConstants.DEFAULT_LIMIT_STUDENT && +
    + +
    + } */} +
    +
    +
    + ); +} + +export { ListStudent }; diff --git a/src/_components/Admin/Teacher/SliderClass.js b/src/_components/Admin/Teacher/SliderClass.js new file mode 100644 index 0000000..6ad68f1 --- /dev/null +++ b/src/_components/Admin/Teacher/SliderClass.js @@ -0,0 +1,181 @@ +import React from "react"; +import Slider from "react-slick"; +import { ChartDoughnut } from "./../../Chart"; +import { Link } from "react-router-dom"; +import LazyLoad from "react-lazyload"; + +function SampleNextArrow(props) { + const { className, onClick } = props; + return ( +
    + ico_right_white +
    + ); +} + +function SamplePrevArrow(props) { + const { className, onClick } = props; + return ( +
    + ico_left_white +
    + ); +} + +function SliderClass(props) { + const settings = { + dots: true, + infinite: true, + slidesToShow: 1, + slidesToScroll: 1, + nextArrow: , + prevArrow: , + }; + let { classes, role } = props; + + const renderBodyItemClass = (data) => { + if (parseInt(data.total_student) === 0) { + return ( +
    + Lớp chưa có học sinh, +
    vui lòng thêm học sinh vào lớp.
    +
    + ); + } else { + return ( +
    + + Xem báo cáo học tập + +
    + ); + } + // else if (data.report_data) { + // let total_overview_score = + // data.report_data.overview_score.A + + // data.report_data.overview_score.B + + // data.report_data.overview_score.C + + // data.report_data.overview_score.D; + // let report_data = { + // datasets: [ + // { + // data: [ + // data.report_data.overview_score.A, + // data.report_data.overview_score.B, + // data.report_data.overview_score.C, + // data.report_data.overview_score.D, + // ], + // backgroundColor: ["#00AEEF", "#00CC7E", "#FBB040", "#BE1E2D"], + // }, + // ], + // labels: [ + // "Giỏi: " + + // data.report_data.overview_score.A + + // " (" + + // Number.parseFloat( + // (data.report_data.overview_score.A / total_overview_score) * 100 + // ).toFixed(1) + + // "%)", + // "Khá: " + + // data.report_data.overview_score.B + + // " (" + + // Number.parseFloat( + // (data.report_data.overview_score.B / total_overview_score) * 100 + // ).toFixed(1) + + // "%)", + // "Trung Bình: " + + // data.report_data.overview_score.C + + // " (" + + // Number.parseFloat( + // (data.report_data.overview_score.C / total_overview_score) * 100 + // ).toFixed(1) + + // "%)", + // "Dưới trung bình: " + + // data.report_data.overview_score.D + + // " (" + + // Number.parseFloat( + // (data.report_data.overview_score.D / total_overview_score) * 100 + // ).toFixed(1) + + // "%)", + // ], + // }; + // if (total_overview_score === 0) { + // return ( + //
    + // Báo cáo học tập của lớp đang được cập nhật. + //
    + // ); + // } else { + // return ( + //
    + // + //
    + //
    + //

    + // Điểm Trung bình:{" "} + // + // {parseFloat( + // Number.parseFloat(data.report_data.avg).toFixed(1) + // )} + // {" "} + //

    + //
    + //
    + // ); + // } + // } + }; + + return ( +
    +
      + + {classes.data.map((data, i) => { + return ( +
    • + {/* */} +
      + + detail2 + +
      +
      +

      {data.class_name}

      +
      +
      + {`Sĩ số: ${data?.total_student}`} +
      + + {renderBodyItemClass(data)} + +
      +
      + {/* */} +
    • + ); + })} +
      +
    +
    + ); +} + +export { SliderClass }; diff --git a/src/_components/Admin/Teacher/Wish.js b/src/_components/Admin/Teacher/Wish.js new file mode 100644 index 0000000..fbecc50 --- /dev/null +++ b/src/_components/Admin/Teacher/Wish.js @@ -0,0 +1,57 @@ +import React, { useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { teacherActions } from "../../../_actions"; + +function Wish(props) { + let { lesson_id, wish, onChangeStatus, lesson_type, curriculum_id } = props; + const dispatch = useDispatch(); + const authentication = useSelector((state) => state.authentication); + + const [statusWish, setStatusWish] = useState(wish ? true : false); + + function addWish() { + dispatch( + teacherActions.addWish({ + lesson_id, + user_id: authentication.id, + lesson_type, + curriculum_id: curriculum_id + }) + ); + setStatusWish(true); + } + + function removeWish() { + dispatch( + teacherActions.removeWish({ + exercise_id: lesson_id, + user_wish_id: authentication.id, + }) + ); + setStatusWish(false); + onChangeStatus && onChangeStatus(); + // console.log(onChangeStatus); + } + + return ( +
    +
    + ico_heart removeWish()} + style={{ cursor: "pointer" }} + /> + ico_heart_no addWish()} + style={{ cursor: "pointer" }} + /> +
    + ); +} + +export { Wish }; diff --git a/src/_components/Admin/Teacher/index.js b/src/_components/Admin/Teacher/index.js new file mode 100644 index 0000000..7956c39 --- /dev/null +++ b/src/_components/Admin/Teacher/index.js @@ -0,0 +1,8 @@ +export * from './SliderClass'; +export * from './EmptyClassSlider'; +export * from './EmptyClassBlock'; +export * from './ListClass'; +export * from './ListStudent'; +export * from './EmptyStudent'; +export * from './ListClassMessage'; +export * from './Wish'; \ No newline at end of file diff --git a/src/_components/AdvisementForm/AdvisementForm.jsx b/src/_components/AdvisementForm/AdvisementForm.jsx new file mode 100644 index 0000000..977f238 --- /dev/null +++ b/src/_components/AdvisementForm/AdvisementForm.jsx @@ -0,0 +1,235 @@ +import "./AdvisementForm.style.scss"; +import { advisementLogic } from "./AdvisementForm.logic"; +import InputText from "../Auth/InputText"; +import ButtonNews from "../Button/ButtonNews"; +import InputSelectNews from "../Input/InputSelect"; +import { userConstants } from "../../_constants"; +import ModalSuccessMsg from "../Modal/ModalSuccessMsg/ModalSuccessMsg"; +import LazyLoad from "react-lazyload"; + +const AdvisementForm = (props) => { + let { + dataTimeAdvisement, + timeAdvisement, + gradeSelected, + dataGrades, + changeGradeSelected, + changeTimeAdvisement, + nameUser, + setNameUser, + changeNameUser, + nameUserError, + setNameUserError, + phone, + phoneWarning, + setPhoneWarning, + changePhone, + onBlurField, + addressTeach, + setAddressTeach, + changeAddressTeach, + handleRegistAdvisement, + timeAdvisementError, + setTimeAdvisementError, + addressTeachError, + setAddressTeachError, + gradeError, + setGradeError, + isSuccessRegist, + handleCloseModal, + } = advisementLogic(props); + + return ( +
    + {/* Img Banner */} + +
    +
    +
    + {props.type == userConstants.ROLE_TEACHER ? ( + Titlte Advisement + ) : ( + <> + Titlte Advisement + +
    + Titlte Advisement + Titlte Advisement +
    + + )} +
    +
    +
    +
    +
    + {props.type == userConstants.ROLE_TEACHER + ? "Thầy cô hãy để lại thông tin chính xác để được hỗ trợ sớm nhất có thể nhé!" + : "Ba mẹ hãy để lại thông tin chính xác để được hỗ trợ sớm nhất có thể nhé!"} +
    +
    +
    + renderAuthIcon("name")} + errorText={nameUserError} + setErrorText={setNameUserError} + onFocus={() => setNameUser(nameUser?.trim())} + onBlur={() => { + onBlurField("name"); + }} + errorAbsolute={true} + /> + renderAuthIcon("phone")} + errorText={phoneWarning} + setErrorText={setPhoneWarning} + onBlur={() => { + onBlurField("phone"); + }} + errorAbsolute={true} + /> + + {props.type == userConstants.ROLE_TEACHER ? ( + renderAuthIcon("phone")} + errorText={addressTeachError} + setErrorText={setAddressTeachError} + onFocus={() => setAddressTeach(addressTeach?.trim())} + onBlur={() => { + onBlurField("address"); + }} + errorAbsolute={true} + /> + ) : ( + { + return { + value: item.value, + title: item.title, + }; + })} + errorAbsolute={true} + /> + )} + + { + return { + value: item.value, + title: item.title, + }; + })} + errorAbsolute={true} + /> +
    + handleRegistAdvisement(e)} + border={"1px solid #fff"} + backgroundColor={"#EB5757"} + boxShadow={"1px 1px 5px white, 0 0 1px white"} + maxWidth={"19.5vw"} + maxHeight={"5.5vw"} + > +
    + ĐĂNG KÝ +
    +
    +
    + +
    + +
    + Img Side Advisement +
    +
    +
    + + {isSuccessRegist && ( +
    +
    + +
    +
    + )} +
    +
    + ); +}; + +export default AdvisementForm; diff --git a/src/_components/AdvisementForm/AdvisementForm.logic.js b/src/_components/AdvisementForm/AdvisementForm.logic.js new file mode 100644 index 0000000..71902af --- /dev/null +++ b/src/_components/AdvisementForm/AdvisementForm.logic.js @@ -0,0 +1,458 @@ +import { useState, useEffect } from "react"; +import { apiCaller } from "../../_helpers"; +import { configConstants } from "../../_constants"; +import { validateNumber, validateEmail } from "../../_base/Validate"; +import { userConstants } from "../../_constants"; +import { sendMsgContact } from "../../_services/user"; +import moment from "moment"; + +export const advisementLogic = (props) => { + // Time Advisement + const [timeAdvisement, setTimeAdvisement] = useState({}); + const [timeAdvisementError, setTimeAdvisementError] = useState(); + const changeTimeAdvisement = (newValue) => { + if (timeAdvisementError) { + setTimeAdvisementError(""); + setCompulError(""); + } + setTimeAdvisement(newValue); + }; + + let dataTimeAdvisement = [ + { + id: 0, + title: "Thời gian nhận tư vấn", + value: null, + }, + ]; + + // Render List Time Advisement + for (var i = 1; i < 15; i++) { + let dateValue = new Date(); + dateValue.setHours(i + 7, 0, 0, 0); + + dataTimeAdvisement.push({ + id: i, + title: `${i + 7}h - ${i + 1 + 7}h`, + value: `${i + 7} - ${i + 1 + 7}`, + }); + } + + // Grades + const [gradeSelected, setGradeSelected] = useState(); + const [gradeError, setGradeError] = useState(); + const [dataGrades, setDataGrades] = useState([]); + useEffect(() => { + if (!dataGrades.length) { + apiCaller( + "/api_login/grade", + "GET", + {}, + null, + true, + configConstants.API_URL_SETEST, + false + ).then((res) => { + if (res.status) { + const newListGrade = [ + { + id: 0, + name: "Lớp của con", + value: 0, + }, + ].concat(res.list_grade); + + newListGrade?.map((item) => { + item.title = item.name.replace("Khối", "Lớp"); + item.value = item.id; + }); + setDataGrades(newListGrade); + } + }); + } + }, []); + + // Handle Change Grade for Student + const changeGradeSelected = (newValue) => { + if (gradeError) { + setGradeError(""); + } + setGradeSelected(newValue); + }; + + // Name + const [nameUser, setNameUser] = useState(); + const [nameUserError, setNameUserError] = useState(); + + // Handle Change Name User + const changeNameUser = (value) => { + if (nameUserError) { + setNameUserError(""); + } + setNameUser(value?.capitalize()); + }; + + // Phone Number + const [phone, setPhone] = useState(); + const [phoneWarning, setPhoneWarning] = useState(""); + + // Handle Change Phone + const changePhone = (value) => { + setPhone(validateNumber(value)); + if (phoneWarning) { + setPhoneWarning(""); + if ([10, 11].includes(value?.length) || phone == "") { + setPhoneWarning(""); + } + } + }; + + // Address + const [addressTeach, setAddressTeach] = useState(); + const [addressTeachError, setAddressTeachError] = useState(); + + // Handle Change Address Teach for Teacher + const changeAddressTeach = (newValue) => { + if (addressTeachError) { + setAddressTeachError(""); + } + setAddressTeach(newValue); + }; + + // TEACHER + + // Email + const [email, setEmail] = useState(); + const [emailError, setEmailError] = useState(); + + const [isVisibleTime, setIsVisibleTime] = useState(false); + const [isVisbileTrial, setIsVisibleTrial] = useState(false); + + const [errorAdviseTrial, setErrorAdviseTrial] = useState(""); + + // Variable compulsory advise trial + const [compulError, setCompulError] = useState(false); + + // Validate + const onBlurField = (type) => { + switch (type) { + case "email": { + if (email && !emailError && !validateEmail(email)) { + setEmailError("Định dạng email không đúng"); + } else if (validateEmail(email) || email == "") { + setEmailError(""); + } + + return; + } + case "phone": { + if (phone == "") { + setPhoneWarning(""); + } else if (phone && phone?.length != 10 && phone?.length != 11) { + setPhoneWarning("Số điện thoại hợp lệ gồm 10-11 số!"); + // console.log("123"); + } else if (phone && phone?.length && phone[0] !== "0") { + setPhoneWarning("Định dạng số điện thoại không đúng"); + } + return; + } + case "name": { + setNameUser(nameUser?.trim()); + return; + } + case "address": { + setAddressTeach(addressTeach?.trim()); + return; + } + case "timeAdvise": { + if (!timeAdvisement?.value) { + setIsVisibleTime(false); + } + } + default: + } + }; + + // Variable for open modal success + const [isSuccessRegist, setIsSuccessRegist] = useState(false); + + // Handle Close Modal + const handleCloseModal = () => { + setNameUser(""); + setPhone(""); + setTimeAdvisement({ value: null }); + setGradeSelected({ value: null }); + setAddressTeach(""); + setIsVisiblePolicy(false); + setIsVisibleTrial(false); + setIsVisibleTime(false); + setEmail(""); + setIsSuccessRegist(false); + }; + + // Handle Regist Advisement + const handleRegistAdvisement = async (e) => { + e?.preventDefault(); + if ( + nameUser && + phone && + !nameUserError && + !phoneWarning && + timeAdvisement?.value && + !timeAdvisementError + ) { + if ( + (!addressTeach && props.type == userConstants.ROLE_TEACHER) || + (!gradeSelected?.value && props.type != userConstants.ROLE_TEACHER) + ) { + setAddressTeachError("Vui lòng nhập thông tin."); + setGradeError("Vui lòng nhập thông tin."); + } else { + try { + let [from_time, end_time] = timeAdvisement?.value.split("-"); + + const data = { + user_name: nameUser, + phone, + from_time, + end_time, + grade_id: gradeSelected?.value, + school: addressTeach, + source: "advise", + role: props.type, + }; + + const result = await sendMsgContact(data); + if (result.status) { + // setIsSuccess(true); + setIsSuccessRegist(true); + } + } catch (e) { + // console.log(e); + } + } + } else { + if (!nameUser) { + setNameUserError("Vui lòng nhập thông tin."); + } else { + if (!phone) { + setPhoneWarning("Vui lòng nhập thông tin."); + } else { + if ( + (!addressTeach && props.type == userConstants.ROLE_TEACHER) || + (!gradeSelected?.value && props.type != userConstants.ROLE_TEACHER) + ) { + setAddressTeachError("Vui lòng nhập thông tin."); + setGradeError("Vui lòng nhập thông tin."); + } else if ( + (!addressTeachError || !gradeError) && + !timeAdvisement?.value + ) { + setTimeAdvisementError("Vui lòng nhập thông tin."); + } + } + } + } + }; + + // TEACHER + const changeEmail = (value) => { + setEmailError(""); + if (emailError) { + if (validateEmail(value) || value == "") { + setEmailError(""); + } + } + setEmail(value?.trim()); + }; + + // Variable Boolean check checked box + const [isVisiblePolicy, setIsVisiblePolicy] = useState(false); + const [isAgreePolicy, setIsAgreePolicy] = useState(true); + + // Handle Checked Box Time Advisement + const handleCheckedBoxTime = () => { + setIsVisibleTime(!isVisibleTime); + setErrorAdviseTrial(""); + setTimeAdvisementError(""); + setCompulError(""); + }; + + // Handle Checked Box Trial + const handleCheckedBoxTrial = () => { + if (isVisbileTrial) { + setIsVisiblePolicy(false); + setIsAgreePolicy(true); + } + setTimeAdvisementError(""); + setCompulError(""); + setErrorAdviseTrial(""); + setIsVisibleTrial(!isVisbileTrial); + }; + + // Handle Checked Box Policy + const handleCheckedBoxPolicy = () => { + if (isVisiblePolicy) { + setIsAgreePolicy(false); + } else { + setIsAgreePolicy(true); + } + setIsVisiblePolicy(!isVisiblePolicy); + }; + + // Handle Regist Advisement Teacher + const handleRegistAdvisementTeacher = async (e) => { + e?.preventDefault(); + if ( + nameUser && + !nameUserError && + email && + !emailError && + phone && + !phoneWarning && + addressTeach && + !addressTeachError && + ((isVisbileTrial && !errorAdviseTrial) || + (timeAdvisement?.value && !timeAdvisementError)) + ) { + if (isVisbileTrial && !isVisiblePolicy) { + setIsAgreePolicy(false); + } else { + try { + let from_time = ""; + let end_time = ""; + if (timeAdvisement?.value) { + [from_time, end_time] = timeAdvisement?.value.split("-"); + } + let type_contact = ""; + + const data = { + user_name: nameUser, + phone, + school: addressTeach, + role: props.type, + number_teacher: 1, + number_student: numberStudentAccount, + source: "trial", + number_teacher: 1, + number_student: numberStudentAccount, + from_time, + end_time, + email + }; + + if (timeAdvisement?.value && isVisbileTrial) { + type_contact = "both"; + } else if (timeAdvisement?.value) { + type_contact = "care"; + delete data?.number_teacher; + delete data?.number_student; + } else { + type_contact = "free_trial"; + delete data?.from_time; + delete data?.end_time; + } + + data.type_contact = type_contact; + + const result = await sendMsgContact(data); + if (result.status) { + // setIsSuccess(true); + setIsSuccessRegist(true); + } + } catch (e) { + console.log(e); + } + } + } else { + if (!nameUser) { + setNameUserError("Vui lòng nhập thông tin."); + } else if (!phone) { + setPhoneWarning("Vui lòng nhập thông tin."); + } else if (!email) { + setEmailError("Vui lòng nhập thông tin."); + } else if (!addressTeach) { + setAddressTeachError("Vui lòng nhập thông tin."); + } else { + if (!isVisbileTrial && !isVisibleTime && !timeAdvisement?.value) { + setTimeAdvisementError("Vui lòng chọn tối thiểu 1 thông tin."); + setCompulError(true); + // setErrorAdviseTrial("Vui lòng chọn tối thiểu 1 thông tin."); + } + } + } + }; + + // Variable Number Account + const [numberStudentAccount, setNumberStudentAccount] = useState(25); + + // Handle Change Number Account + const handleChangeNumberAccount = (type) => { + switch (type) { + case "increase": + if (numberStudentAccount + 5 <= 50) { + setNumberStudentAccount(numberStudentAccount + 5); + } + return; + case "decrease": + if (numberStudentAccount - 5 >= 5) { + setNumberStudentAccount(numberStudentAccount - 5); + } + return; + default: + return; + } + }; + + return { + dataTimeAdvisement, + dataGrades, + timeAdvisement, + gradeSelected, + dataGrades, + changeTimeAdvisement, + changeGradeSelected, + nameUser, + setNameUser, + changeNameUser, + nameUserError, + setNameUserError, + phone, + phoneWarning, + setPhoneWarning, + changePhone, + onBlurField, + addressTeach, + setAddressTeach, + changeAddressTeach, + handleRegistAdvisement, + timeAdvisementError, + setTimeAdvisementError, + addressTeachError, + setAddressTeachError, + gradeError, + setGradeError, + isSuccessRegist, + handleCloseModal, + handleCheckedBoxTime, + isVisibleTime, + handleCheckedBoxTrial, + isVisbileTrial, + isVisiblePolicy, + handleCheckedBoxPolicy, + handleRegistAdvisementTeacher, + email, + emailError, + setEmailError, + changeEmail, + handleChangeNumberAccount, + numberStudentAccount, + isAgreePolicy, + errorAdviseTrial, + setErrorAdviseTrial, + compulError, + setCompulError, + setIsVisibleTime, + setIsAgreePolicy, + }; +}; diff --git a/src/_components/AdvisementForm/AdvisementForm.style.scss b/src/_components/AdvisementForm/AdvisementForm.style.scss new file mode 100644 index 0000000..8d0e512 --- /dev/null +++ b/src/_components/AdvisementForm/AdvisementForm.style.scss @@ -0,0 +1,478 @@ +@import "/src/_styles/mixin"; + +.advisement_form { + width: 100%; + padding-top: 0.8rem; + padding-bottom: 0rem; + + @include screen_mobile { + width: 100%; + padding-bottom: 0rem; + } + + .content_advisement_container { + width: 90%; + max-width: 100rem; + min-width: 55rem; + border: 1px dashed #4d4d4d; + border-radius: 2.2rem; + padding: 1rem; + + @include screen_mobile { + min-width: 100%; + border: none; + padding: 0; + border-radius: 0rem; + } + + .title_header { + width: 70%; + max-width: 70%; + + @include screen_mobile { + width: 98%; + max-width: 98%; + margin: 0 auto; + } + } + + .title_header_mobile { + padding: 1rem 0 1rem; + + .title_header_1 { + @include screen_mobile { + width: 50%; + max-width: 50%; + margin: 0 auto; + } + } + + .title_header_2 { + @include screen_mobile { + width: 84%; + max-width: 84%; + margin: 0 auto; + } + } + } + + .content_advisement { + width: 100%; + padding: 2.5rem 0 0 5%; + border-radius: 1.5rem; + + @include screen_mobile { + border-radius: 0; + padding: 1rem 0 0; + } + + .content_left_advisement { + width: 48%; + max-width: 48%; + padding-bottom: 2.5rem; + + @include screen_mobile { + width: 92%; + max-width: 92%; + padding-bottom: 0; + // padding:; + } + } + + .header_advisement { + width: 100%; + padding-bottom: 1.2rem; + + @include screen_mobile { + padding-bottom: 0.5rem; + } + + .title_header_teacher { + width: 48%; + max-width: 48%; + padding: 1rem 0 0.5rem; + + @include screen_mobile { + margin: 0 auto; + width: 90%; + max-width: 90%; + text-align: center; + display: flex; + // justify-content: center; + } + } + + // .title_header { + // position: relative; + // background: transparent; + // z-index: 1; + // font-size: clamp(1.7rem, 3.3vw, 2.78125rem); + + // &::after { + // content: attr(title); + // position: absolute; + // -webkit-text-stroke: 8px white; + // left: 0; + // z-index: -2; + // } + + // &::before { + // content: attr(title); + // position: absolute; + // -webkit-text-stroke: 8px white; /* Chris Coyier's favorite color! */ + // left: 0; + // z-index: -1; + // } + // } + + .detail_header { + width: 100%; + font-size: clamp(1rem, 2vw, 1.5rem); + line-height: 1.8rem; + + @include screen_mobile { + margin: 0 auto; + text-align: center; + width: 90%; + font-size: clamp(0.9rem, 4vw, 1rem); + line-height: 1.225rem; + } + } + } + + .form_input_advisement { + width: 100%; + padding-top: 1.2rem; + + @include screen_mobile { + width: 98%; + padding-top: 1.5rem; + } + + .input_radio_base { + .error_text_absolute { + @include screen_mobile { + bottom: calc(100%) !important; + } + } + + .error_select { + span { + font-size: 17px !important; + + @include screen_mobile { + font-size: 0.82rem !important; + } + } + } + } + + .input_text_base_container { + .error_text_absolute { + @include screen_mobile { + bottom: calc(100%) !important; + } + } + + .error_input { + span { + font-size: 17px !important; + + @include screen_mobile { + font-size: 0.82rem !important; + } + } + } + } + + .input_text_base { + padding: 0 1.2rem !important; + } + + .input_text_base, + .input_select_main_wrapper { + height: clamp(3.2rem, 4vw, 3.375rem) !important; + border: none; + background-color: var(--white-color) !important; + margin-bottom: 2.3rem; + + @include screen_mobile { + margin-bottom: 2rem; + } + + .input_text { + color: var(--text-color); + font-size: clamp(1rem, 1.6vw, 1.25rem); + -webkit-text-fill-color: var(--text-color); + + &::placeholder { + color: var(--text-color); + -webkit-text-fill-color: var(--text-color); + } + } + } + } + + .img_side_advisement { + width: 50%; + max-width: 50%; + + @include screen_mobile { + width: 100%; + max-width: 100%; + } + } + } + } +} + +.btn_container { + padding-top: 2.25rem; + + .btn_custom { + @include screen_mobile { + max-height: 100% !important; + max-width: 100% !important; + width: clamp(9rem, 50vw, 11rem) !important; + height: clamp(2.65rem, 12vw, 2.87rem) !important; + } + + .text_btn { + font-size: clamp(1.2rem, 2vw, 1.5rem); + + @include screen_mobile { + font-size: 1.5rem; + } + } + } +} + +.advisement_form_teacher { + width: 100%; + background-color: #fff; + + .content_advisement_container { + width: 90%; + max-width: 100rem; + min-width: 55rem; + padding: 1rem; + border: 1px dashed #4d4d4d; + border-radius: 3rem; + + @include screen_mobile { + min-width: 100%; + border: none; + padding: 0; + border-radius: 0rem; + } + + .content_advisement { + background-color: #ffea99; + border-radius: 2.5rem; + padding: 2.5rem 4%; + + @include screen_mobile { + border-radius: 0; + } + + .header_advisement { + .title_header_teacher_1_mobile { + @include screen_mobile { + width: 82%; + max-width: 82%; + } + } + + .title_header_teacher_2_mobile { + @include screen_mobile { + width: 94%; + max-width: 94%; + } + } + + .title_header_teacher { + width: 92%; + max-width: 90rem; + } + + .detail_header { + font-size: clamp(1.3rem, 1.8vw, 1.5rem); + padding: 1rem 0 2.5rem; + + @include screen_mobile { + font-size: 1rem; + padding: 0.75rem 0 2rem; + } + } + } + + .form_input_advisement { + .form_input_wrapper { + @include screen_mobile { + flex-direction: column !important; + } + } + + .input_radio_base { + .error_text_absolute { + @include screen_mobile { + bottom: calc(100%) !important; + } + } + + .error_select { + span { + font-size: 16px !important; + + @include screen_mobile { + font-size: 0.82rem !important; + } + } + } + } + + .input_container_left, + .input_container_right { + width: 48%; + max-width: 48%; + + @include screen_mobile { + width: 98%; + max-width: 98%; + } + } + + .text_note_assistant { + font-size: clamp(0.9rem, 1.1vw, 1rem); + margin-top: -0.75rem; + + @include screen_mobile { + font-size: 0.75rem; + margin-top: -1rem; + } + } + + .input_container_right {} + + .input_text_base_container { + .error_text_absolute { + @include screen_mobile { + bottom: calc(100%) !important; + } + } + + .error_input { + span { + font-size: 17px !important; + + @include screen_mobile { + font-size: 0.82rem !important; + } + } + } + } + + .input_text_base { + padding: 0 1.2rem !important; + } + + .input_text_base, + .input_select_main_wrapper { + height: clamp(3.2rem, 4vw, 3.375rem) !important; + border: none; + background-color: var(--white-color) !important; + margin-bottom: 2.3rem; + + @include screen_mobile { + margin-bottom: 2rem; + } + + .input_text { + color: var(--text-color); + font-size: clamp(1rem, 1.6vw, 1.25rem); + -webkit-text-fill-color: var(--text-color); + + &::placeholder { + color: var(--text-color); + -webkit-text-fill-color: var(--text-color); + } + } + } + + .number_account_assistant { + margin-top: -0.75rem; + padding: 0 3.5%; + + @include screen_mobile { + margin-top: 1rem; + } + + .title_account_assistant { + font-size: clamp(1.1rem, 1.3vw, 1.25rem); + + @include screen_mobile { + font-size: clamp(0.75rem, 2.8vw, 0.875rem); + } + } + + .box_number_account { + margin-top: 0.5rem; + background-color: var(--white-color); + border-radius: 1.5rem; + border: 1px solid var(--text-color); + width: 8.8rem; + min-width: 6rem; + padding: 0.35rem 0; + font-size: clamp(1.3rem, 1.7vw, 1.5rem); + + @include screen_mobile { + width: 7.5rem; + min-width: 5.5rem; + + font-size: clamp(1.05rem, 2vw, 1.125rem); + } + + .number_account_text { + font-size: clamp(1.3rem, 1.7vw, 1.5rem); + margin: 0 0.75rem; + min-width: 2rem; + + @include screen_mobile { + margin: 0 0.35rem; + font-size: clamp(1.05rem, 2vw, 1.125rem); + } + } + + svg { + @include screen_mobile { + width: 14px; + height: 11px; + } + } + } + } + + // Text Policy + .text_policy_assistant_account { + font-size: clamp(1.1rem, 1.5vw, 1.25rem); + margin-top: 2.5rem; + + .ico_checkbox_policy { + width: 1.25rem; + height: auto; + margin-right: 0.35rem; + } + + span, + a { + font-size: clamp(1.1rem, 1.5vw, 1.25rem); + + @include screen_mobile { + font-size: clamp(0.75rem, 3vw, 0.875rem); + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/_components/AdvisementForm/AdvisementFormTeacher.jsx b/src/_components/AdvisementForm/AdvisementFormTeacher.jsx new file mode 100644 index 0000000..a9b81be --- /dev/null +++ b/src/_components/AdvisementForm/AdvisementFormTeacher.jsx @@ -0,0 +1,382 @@ +import "./AdvisementForm.style.scss"; +import { advisementLogic } from "./AdvisementForm.logic"; +import InputText from "../Auth/InputText"; +import ButtonNews from "../Button/ButtonNews"; +import InputSelectNews from "../Input/InputSelect"; +import { userConstants } from "../../_constants"; +import ModalSuccessMsg from "../Modal/ModalSuccessMsg/ModalSuccessMsg"; +import LazyLoad from "react-lazyload"; +import { TypeHeaderNewsItem } from "../../_constants/headerNews"; + +const AdvisementFormTeacher = (props) => { + let { + dataTimeAdvisement, + timeAdvisement, + gradeSelected, + dataGrades, + changeGradeSelected, + changeTimeAdvisement, + nameUser, + setNameUser, + changeNameUser, + nameUserError, + setNameUserError, + phone, + phoneWarning, + setPhoneWarning, + changePhone, + onBlurField, + addressTeach, + setAddressTeach, + changeAddressTeach, + handleRegistAdvisement, + timeAdvisementError, + setTimeAdvisementError, + addressTeachError, + setAddressTeachError, + gradeError, + setGradeError, + isSuccessRegist, + handleCloseModal, + handleCheckedBoxTime, + isVisibleTime, + handleCheckedBoxTrial, + isVisbileTrial, + isVisiblePolicy, + handleCheckedBoxPolicy, + handleRegistAdvisementTeacher, + email, + emailError, + setEmailError, + changeEmail, + handleChangeNumberAccount, + numberStudentAccount, + isAgreePolicy, + errorAdviseTrial, + setErrorAdviseTrial, + compulError, + setCompulError, + setIsVisibleTime, + } = advisementLogic(props); + + return ( +
    + {/* Img Banner */} + +
    +
    +
    + Titlte Advisement + +
    + Titlte Advisement + Titlte Advisement +
    + +
    + {props.type == userConstants.ROLE_TEACHER + ? "Thầy cô hãy để lại thông tin chính xác để được hỗ trợ sớm nhất có thể nhé!" + : "Ba mẹ hãy để lại thông tin chính xác để được hỗ trợ sớm nhất có thể nhé!"} +
    +
    +
    +
    +
    + renderAuthIcon("name")} + errorText={nameUserError} + setErrorText={setNameUserError} + onFocus={() => setNameUser(nameUser?.trim())} + onBlur={() => { + onBlurField("name"); + }} + errorAbsolute={true} + /> + renderAuthIcon("phone")} + errorText={phoneWarning} + setErrorText={setPhoneWarning} + onBlur={() => { + onBlurField("phone"); + }} + errorAbsolute={true} + /> + renderAuthIcon("phone")} + errorText={emailError} + setErrorText={setEmailError} + onBlur={() => { + onBlurField("email"); + }} + errorAbsolute={true} + /> + + {/* { + return { + value: item.value, + title: item.title, + }; + })} + errorAbsolute={true} + /> */} + +
    + * Chỉ áp dụng cho Giáo viên. Miễn phí trải nghiệm trong thời + gian 1 tháng. +
    +
    + +
    + renderAuthIcon("phone")} + errorText={addressTeachError} + setErrorText={setAddressTeachError} + onFocus={() => setAddressTeach(addressTeach?.trim())} + onBlur={() => { + onBlurField("address"); + }} + errorAbsolute={true} + /> + { + return { + value: item.value, + title: item.title, + }; + })} + errorAbsolute={true} + handleCheckedBox={handleCheckedBoxTime} + isChecked={isVisibleTime} + onBlur={() => { + onBlurField("timeAdvise"); + }} + typeSearch="checkbox" + setCompulWarning={setCompulError} + setIsVisible={setIsVisibleTime} + /> + renderAuthIcon("phone")} + errorAbsolute={true} + handleCheckedBox={() => handleCheckedBoxTrial()} + isChecked={isVisbileTrial} + readOnly={true} + compulWarning={compulError} + /> + +
    + * Chỉ áp dụng cho Giáo viên. Miễn phí trải nghiệm trong thời + gian 1 tháng. +
    + {isVisbileTrial && ( +
    +
    +
    + Tài khoản giáo viên +
    +
    + 01 +
    +
    +
    +
    + Tài khoản học sinh +
    +
    +
    handleChangeNumberAccount("increase")} + style={{ + width: "1.3rem", + }} + > + + + +
    +
    + {numberStudentAccount} +
    +
    handleChangeNumberAccount("decrease")} + style={{ + width: "1.3rem", + }} + > + + + +
    +
    +
    +
    + )} +
    +
    + + {isVisbileTrial && ( +
    +
    + Ico Checkbox +
    + + Tôi đồng ý với{" "} + + window.open( + `/${TypeHeaderNewsItem.POLICY}/#rule1`, + "_blank" + ) + } + style={{ + lineHeight: "normal", + }} + className="text_underline_offset pointer_cursor" + > + điều khoản, chính sách và dịch vụ + {" "} + của Sunday Teacher + +
    + )} + + {isVisbileTrial && !isAgreePolicy && ( +
    + Vui lòng tích chọn đồng ý điều khoản chính sách và dịch vụ +
    + )} + +
    + handleRegistAdvisementTeacher(e)} + border={"1px solid #fff"} + backgroundColor={"#EB5757"} + boxShadow={"1px 1px 5px white, 0 0 1px white"} + maxWidth={"19.5vw"} + maxHeight={"5.5vw"} + > +
    + ĐĂNG KÝ +
    +
    +
    +
    +
    + + {isSuccessRegist && ( +
    +
    + +
    +
    + )} +
    +
    + ); +}; + +export default AdvisementFormTeacher; diff --git a/src/_components/AdvisementForm/FormTrial/FormTrial.jsx b/src/_components/AdvisementForm/FormTrial/FormTrial.jsx new file mode 100644 index 0000000..f995739 --- /dev/null +++ b/src/_components/AdvisementForm/FormTrial/FormTrial.jsx @@ -0,0 +1,567 @@ +import "./FormTrial.style.scss"; +import "../AdvisementForm.style.scss"; +import InputText from "../../Auth/InputText"; +import ButtonNews from "../../Button/ButtonNews"; +import InputSelectNews from "../../Input/InputSelect"; +import ModalSuccessMsg from "../../Modal/ModalSuccessMsg/ModalSuccessMsg"; +import { formTrialLogic } from "./FormTrial.logic"; +import { advisementLogic } from "../AdvisementForm.logic"; +import InputSelect from "../../Auth/InputSelect"; +import { history } from "../../../_helpers"; +import { sendMsgContact } from "../../../_services/user"; +import "../../../_components/Modal/ModalSuccessMsg/ModalSuccessMsg.style.scss"; + +const FormTrial = (props) => { + // Variable advisement Logic for value and validate + let { + timeAdvisement, + gradeSelected, + nameUser, + setNameUser, + changeNameUser, + nameUserError, + setNameUserError, + phone, + phoneWarning, + setPhoneWarning, + changePhone, + onBlurField, + handleCheckedBoxTrial, + isVisbileTrial, + isVisiblePolicy, + handleCheckedBoxPolicy, + email, + emailError, + setEmailError, + changeEmail, + handleChangeNumberAccount, + numberStudentAccount, + isAgreePolicy, + errorAdviseTrial, + setErrorAdviseTrial, + compulError, + setIsAgreePolicy, + } = advisementLogic(props); + + // Variable form trial Logic for value and validate + let { + provinceList, + provinceSelected, + changeProvince, + errProvince, + setErrProvince, + districtList, + districtSelected, + errDistrict, + setErrDistrict, + changeDistrict, + schoolList, + schoolSelected, + changeSchool, + errSchool, + setErrSchool, + dataPolicyTrial, + isSuccessTrial, + setIsSuccessTrial, + } = formTrialLogic(props); + + // Render Icon Input Select + const renderInputIcon = (type) => { + return ( +
    + Icon Input +
    + ); + }; + + // Register Trial Teacher + const handleRegistTrialTeacher = async (e) => { + e?.preventDefault(); + + if ( + nameUser && + !nameUserError && + email && + !emailError && + phone && + !phoneWarning && + provinceSelected?.value && + !errProvince && + districtSelected?.value && + !errDistrict && + schoolSelected?.value && + !errSchool + ) { + if (!isVisiblePolicy) { + setIsAgreePolicy(false); + } else { + try { + const data = { + user_name: nameUser, + phone, + school: schoolSelected.value, + source: "trial", + role: props.type, + email, + type_contact: "free_trial", + source: "trial", + number_teacher: 1, + number_student: numberStudentAccount, + }; + + const result = await sendMsgContact(data); + if (result.status) { + setIsSuccessTrial(true); + } + } catch (e) { + // console.log(e); + } + } + } else { + if (!nameUser) { + setNameUserError("Vui lòng nhập thông tin."); + } else if (!phone) { + setPhoneWarning("Vui lòng nhập thông tin."); + } else if (!email) { + setEmailError("Vui lòng nhập thông tin."); + } else if (!provinceSelected?.value) { + setErrProvince("Vui lòng chọn tỉnh / thành phố."); + } else if (!districtSelected?.value) { + setErrDistrict("Vui lòng chọn quận/ huyện."); + } else if (!schoolSelected?.value) { + setErrSchool("Vui lòng chọn thông tin trường."); + } else if (!isVisbileTrial) { + setErrorAdviseTrial("Vui lòng chọn thông tin."); + } + } + }; + + // Render Data Policy Trial + const renderListPolicyTrial = (policy) => { + return ( +
    +

    + {policy.title} +

    + +
    + {policy.content_list.map((content) => ( +
    + {content?.content} +
    + ))} +
    +
    + ); + }; + + // Render Success Modal + const SuccessTrialInfo = () => { + return ( +
    + Icon Successful +
    + ĐĂNG KÝ THÀNH CÔNG +
    + +
    + Sunday English sẽ liên hệ lại bạn trong thời gian sớm nhất. Trân trọng + cảm ơn! +
    + +
    + Hotline hỗ trợ:{" "} + + 024 6281 3888 + +
    + +
    { + history.push("/teacher_news"); + }} + className="form_trial_close" + > + Icon Delete +
    +
    + ); + }; + + return ( +
    +
    +
    + {isSuccessTrial ? ( + + ) : ( +
    +
    + Titlte Advisement + +
    + Titlte Advisement + Titlte Advisement +
    +
    + +
    +
    +
    + renderAuthIcon("name")} + errorText={nameUserError} + setErrorText={setNameUserError} + onFocus={() => setNameUser(nameUser?.trim())} + onBlur={() => { + onBlurField("name"); + }} + errorAbsolute={true} + typeErrText={"underAbsolute"} + /> + renderAuthIcon("phone")} + errorText={phoneWarning} + setErrorText={setPhoneWarning} + onBlur={() => { + onBlurField("phone"); + }} + errorAbsolute={true} + typeErrText={"underAbsolute"} + /> + renderAuthIcon("phone")} + errorText={emailError} + setErrorText={setEmailError} + onBlur={() => { + onBlurField("email"); + }} + errorAbsolute={true} + typeErrText={"underAbsolute"} + /> + + {/* { + return { + value: item.value, + title: item.title, + }; + })} + errorAbsolute={true} + handleCheckedBox={handleCheckedBoxTime} + isChecked={isVisibleTime} + onBlur={() => { + onBlurField("timeAdvise"); + }} + typeSearch="checkbox" + setCompulWarning={setCompulError} + setIsVisible={setIsVisibleTime} + typeErrText={"underAbsolute"} + /> */} +
    + +
    +
    + Nơi công tác +
    + { + return { + value: item.province_alias, + title: item.province, + }; + })} + placeholder="Chọn Tỉnh/ Thành phố" + renderLabelIcon={() => renderInputIcon("location")} + errorText={errProvince} + setErrorText={setErrProvince} + mgBottom={"1.5rem"} + typeErrText={"underAbsolute"} + errorAbsolute + > + { + return { + value: item.district_alias, + title: item.district, + }; + })} + placeholder="Quận/ Huyện" + renderLabelIcon={() => renderInputIcon("location")} + disabledClick={!provinceSelected.value} + onClickDisable={() => { + setErrProvince("Vui lòng chọn tỉnh / thành phố."); + }} + errorText={errDistrict} + setErrorText={setErrDistrict} + mgBottom={"1.5rem"} + typeErrText={"underAbsolute"} + errorAbsolute + > + { + return { + value: item.school_name, + title: item.school_name, + id: item.id, + }; + })} + placeholder="Trường" + renderLabelIcon={() => renderInputIcon("school")} + disabledClick={!districtSelected.value} + onClickDisable={() => { + setErrDistrict("Chọn quận/ huyện."); + if (!provinceSelected.value) { + setErrProvince("Vui lòng chọn tỉnh/ thành phố."); + } + }} + errorText={errSchool} + setErrorText={setErrSchool} + typeErrText={"underAbsolute"} + errorAbsolute + > +
    +
    + +
    + renderAuthIcon("phone")} + errorAbsolute={true} + handleCheckedBox={() => handleCheckedBoxTrial()} + isChecked={true} + readOnly={true} + compulWarning={compulError} + typeErrText={"underAbsolute"} + /> + +
    +
    +
    + Tài khoản giáo viên +
    +
    + 01 +
    +
    +
    +
    + Tài khoản học sinh +
    +
    +
    handleChangeNumberAccount("increase")} + style={{ + width: "1.3rem", + }} + > + + + +
    +
    + {numberStudentAccount} +
    +
    handleChangeNumberAccount("decrease")} + style={{ + width: "1.3rem", + }} + > + + + +
    +
    +
    +
    +
    + + {/* Policy Trial */} + +
    +

    + {dataPolicyTrial?.title} +

    + +
    + {dataPolicyTrial?.data?.map((policy) => + renderListPolicyTrial(policy) + )} +
    +
    + +
    +
    +
    + Ico Checkbox +
    + + Tôi đã đọc và đồng ý với Chính sách Trải nghiệm sản phẩm + được nêu trên + +
    + + {!isAgreePolicy && ( +
    + Vui lòng tích chọn đồng ý với Chính sách Trải nghiệm sản + phẩm. +
    + )} +
    + +
    + handleRegistTrialTeacher(e)} + border={"1px solid #fff"} + backgroundColor={"#EB5757"} + boxShadow={"1px 1px 5px white, 0 0 1px white"} + maxWidth={"19.5vw"} + maxHeight={"5.5vw"} + > +
    + ĐĂNG KÝ +
    +
    +
    +
    +
    { + history.push("/teacher_news"); + }} + className="form_trial_close" + > + Icon Delete +
    +
    + )} +
    +
    +
    + ); +}; + +export default FormTrial; diff --git a/src/_components/AdvisementForm/FormTrial/FormTrial.logic.js b/src/_components/AdvisementForm/FormTrial/FormTrial.logic.js new file mode 100644 index 0000000..f43bb23 --- /dev/null +++ b/src/_components/AdvisementForm/FormTrial/FormTrial.logic.js @@ -0,0 +1,191 @@ +import { useEffect, useState } from "react"; +import { apiCaller } from "../../../_helpers"; +import { configConstants } from "../../../_constants"; +import { advisementLogic } from "../AdvisementForm.logic"; + +export const formTrialLogic = (props) => { + // Variable Province + const [provinceList, setProvinceList] = useState([]); + const [provinceSelected, setProvinceSelected] = useState({ + title: "", + value: "", + }); + // Variable District + const [districtList, setDistrictList] = useState([]); + const [districtSelected, setDistrictSelected] = useState({ + title: "", + value: "", + }); + + const [schoolList, setSchoolList] = useState([]); + const [schoolSelected, setSchoolSelected] = useState({ + title: "", + value: "", + }); + + // Text error + const [errProvince, setErrProvince] = useState(""); + const [errDistrict, setErrDistrict] = useState(""); + const [errSchool, setErrSchool] = useState(""); + + // Success Trial + const [isSuccessTrial, setIsSuccessTrial] = useState(false); + + const getProvinceList = () => { + apiCaller( + "/api_category/provinces?country_code=vn", + "GET", + {}, + null, + true, + configConstants.API_URL_SETEST, + false + ).then((res) => { + if (res.status) { + setProvinceList(res.data); + } + }); + }; + + useEffect(() => { + getProvinceList(); + }, []); + + // Fetch district list + const getDistrictList = (provinceAlias) => { + apiCaller( + `/api_category/districts?province_alias=${provinceAlias}`, + "GET", + {}, + null, + true, + configConstants.API_URL_SETEST, + false + ).then((res) => { + if (res.status) { + setDistrictList(res.data); + } + }); + }; + + // Fetch school list + const getSchoolList = (districtAlias) => { + apiCaller( + `/api_category/schools?district_alias=${districtAlias}`, + "GET", + {}, + null, + true, + configConstants.API_URL_SETEST, + false + ).then((res) => { + if (res.status) { + setSchoolList(res.data); + } + }); + }; + + // Handle Change Province + const changeProvince = (newProvince) => { + if (newProvince.value !== provinceSelected.value) { + setDistrictSelected({ + title: "", + value: "", + }); + setSchoolSelected({ + title: "", + value: "", + id: "", + }); + setProvinceSelected(newProvince); + getDistrictList(newProvince.value); + } + }; + + // Handle Change District + const changeDistrict = (newDistrict) => { + if (newDistrict.value !== districtSelected.value) { + setSchoolSelected({ + title: "", + value: "", + id: "", + }); + setDistrictSelected(newDistrict); + getSchoolList(newDistrict.value); + } + }; + + // Handle Change School + const changeSchool = (newSchool) => { + setSchoolSelected(newSchool); + }; + + // Data policy trial + const dataPolicyTrial = { + title: "Chính sách trải nghiệm sản phẩm", + data: [ + { + id: 1, + title: "Quy định", + content_list: [ + { + id: 1, + content: + "Chương trình trải nghiệm giải pháp dạy và học tiếng Anh trực tuyến bao gồm 2 sản phẩm Sunday Teacher và Sunday English chỉ áp dụng cho các Giáo viên dạy tiếng Anh tại các trường THCS công lập và tư thục thuộc hệ thống giáo dục Việt Nam.", + }, + { + id: 2, + content: "Mỗi giáo viên được đăng ký trải nghiệm MỘT lần duy nhất.", + }, + { + id: 3, + content: + "Giáo viên cam kết chỉ sử dụng tài khoản Sunday Teacher/Sunday English để phục vụ và tăng hiệu quả việc giảng dạy, giao bài, hướng dẫn học cho học sinh chính khóa và ngoại khóa của mình.", + }, + { + id: 4, + content: + "Giáo viên cam kết không đăng ký hộ, cho tặng, sang nhượng, chuyển giao hay cho thuê mượn các tài khoản trải nghiệm miễn phí.", + }, + { + id: 5, + content: + "Giáo viên cam kết đồng ý và tuân thủ điều khoản, chính sách và dịch vụ của Sunday Teacher.", + }, + ], + }, + { + id: 2, + title: "Thời gian trải nghiệm", + content_list: [ + { + id: 1, + content: + "Giáo viên được miễn phí trải nghiệm 1 tài khoản giáo viên (Sunday Teacher) và tối đa 50 tài khoản học sinh (Sunday English) trong 1 tháng.", + }, + ], + }, + ], + }; + + return { + provinceList, + provinceSelected, + changeProvince, + errProvince, + setErrProvince, + districtList, + districtSelected, + errDistrict, + setErrDistrict, + changeDistrict, + schoolList, + schoolSelected, + changeSchool, + errSchool, + setErrSchool, + dataPolicyTrial, + isSuccessTrial, + setIsSuccessTrial, + }; +}; diff --git a/src/_components/AdvisementForm/FormTrial/FormTrial.style.scss b/src/_components/AdvisementForm/FormTrial/FormTrial.style.scss new file mode 100644 index 0000000..067a254 --- /dev/null +++ b/src/_components/AdvisementForm/FormTrial/FormTrial.style.scss @@ -0,0 +1,249 @@ +@import "/src/_styles/mixin"; + +.modal_form_trial { + padding-top: 40px !important; + padding-bottom: 40px !important; + + .header_advisement { + .title_header_teacher_1_mobile { + width: 35% !important; + max-width: 35% !important; + } + + .title_header_teacher_2_mobile { + width: 90% !important; + max-width: 90% !important; + } + } + + .form_trial { + width: 80%; + min-width: 50rem; + max-width: 75rem; + border-radius: 1.25rem; + height: 100%; + + @include screen_mobile { + width: 100%; + min-width: 18rem; + border-radius: 1.8rem; + } + + .content_advisement_container { + display: flex; + border: none; + padding: 0; + width: 100%; + height: 100%; + border-radius: 1.25rem; + min-width: 50rem; + max-width: 75rem; + @include screen_mobile { + width: 100%; + min-width: 18rem; + border-radius: 1.8rem; + } + .content_advisement { + width: 100%; + background-color: #fddc6b; + border-radius: 1.25rem; + border: 2px solid var(--white-color); + height: 100%; + overflow-y: auto; + + @include screen_mobile { + border-radius: 1.8rem; + } + + .title_header_teacher { + width: 65%; + max-width: 38rem; + } + .form_input_wrapper { + padding-top: 2.75rem; + + @include screen_mobile { + padding-top: 1.75rem; + } + + .input_container_left, + .input_container_right { + @include screen_mobile { + width: 100%; + max-width: 100%; + } + } + .input_container_right { + .text-address { + position: absolute; + top: -2rem; + left: 1.2rem; + font-size: clamp(0.875rem, 1.5vw, 1.1rem); + + @include screen_mobile { + position: relative; + top: auto; + left: 0.75rem; + padding-bottom: 0.5rem; + } + } + } + + .input_text_base, + .input_select_main_wrapper { + margin-bottom: 2.1rem !important; + + @include screen_mobile { + margin-bottom: 1.9rem !important; + } + + .input_text { + font-size: clamp(0.875rem, 1.6vw, 1.1rem) !important; + } + } + + .input_select_main_wrapper { + padding-left: 10px; + padding-right: 18px; + } + + .input_radio_base { + .drop_down { + max-height: 295px !important; + top: 100%; + } + } + + .input_select_main_wrapper { + .input_select_main { + .icon_label { + margin-right: 5px; + } + } + } + } + + .input_trial_container { + .input_text_base_container { + width: 48%; + max-width: 48%; + margin: 0 auto; + + @include screen_mobile { + width: 100%; + max-width: 100%; + } + .input_text_base { + margin-bottom: 1.25rem !important; + } + } + + .number_account_assistant { + width: 48%; + max-width: 48%; + margin: 0 auto; + padding: 0 1.5%; + @include screen_mobile { + width: 100%; + max-width: 100%; + padding: 0 3.5%; + } + + .title_account_assistant { + font-size: clamp(0.875rem, 1.5vw, 1rem); + } + } + } + + // Policy Trial + .policy-trial-container { + background-color: var(--white-color); + padding: 1rem calc(1.5% + 1rem); + border-radius: 1rem; + margin: 2rem 0; + + .policy-trial-title { + font-size: clamp(1rem, 1.5vw, 1.125rem); + color: var(--primary-green); + padding: 0.25rem 0; + } + + .policy-trial-content { + .policy-item { + .policy-item-title { + padding: 0.25rem 0; + + font-size: clamp(0.875rem, 2vw, 1rem); + } + + .policy-item-content_list { + .policy-item-content { + padding: 0.25rem 0; + font-size: clamp(0.875rem, 2vw, 1rem); + } + } + } + } + } + } + } + + .text_policy_assistant_account { + span, + a { + font-size: clamp(0.75rem, 1.5vw, 0.875rem) !important; + } + } + } + + .form_trial_close { + position: absolute; + top: -0.9rem; + right: -0.9rem; + cursor: pointer; + + @include screen_mobile { + top: 0.45rem; + right: 0.45rem; + } + + img { + border: 1px solid var(--white-color); + width: 2.5rem; + border-radius: 50%; + } + } + + .info-trial-success { + background-color: var(--white-color); + border: none; + width: 100%; + min-width: 50rem; + max-width: 75rem; + padding: 5rem 3%; + border-radius: 1.25rem; + align-self: center; + max-height: 100%; + @include screen_mobile { + width: 100%; + min-width: 18rem; + border-radius: 1.8rem; + } + + .msg-title { + font-size: clamp(1.75rem, 2.3vw, 1.875rem); + } + .msg-detail { + width: 90% !important; + font-size: clamp(1.125rem, 1.7vw, 1.375rem); + } + + .msg-contact { + font-size: clamp(1.125rem, 1.7vw, 1.25rem); + + a { + font-size: clamp(1.25rem, 2.2vw, 1.5rem); + } + } + } +} diff --git a/src/_components/Alert/alert.js b/src/_components/Alert/alert.js new file mode 100644 index 0000000..6460f80 --- /dev/null +++ b/src/_components/Alert/alert.js @@ -0,0 +1,34 @@ +import React from "react"; +import { alertConstants } from "./../../_constants"; +import { AlertError, AlertSuccess } from "./"; + +function Alert(props) { + const { customMessage } = props; + + const onComplete = props.onComplete ? props.onComplete : () => {}; + const notShowComplete = props.notShowComplete ? props.notShowComplete : false; + const notShowError = props.notShowError ? props.notShowError : false; + const isHideIcon = props.isHideIcon ? props.isHideIcon : false; + + return props.alert.type === alertConstants.SUCCESS ? ( + + ) : ( + + ); +} + +export { Alert }; diff --git a/src/_components/Alert/error.js b/src/_components/Alert/error.js new file mode 100644 index 0000000..b656114 --- /dev/null +++ b/src/_components/Alert/error.js @@ -0,0 +1,64 @@ +import React from "react"; +import { useDispatch } from "react-redux"; +import { alertActions } from "../../_actions"; + +function AlertError(props) { + let { changePasswordError, imgErorr, errorHelpClassName, isShowPopup, hasBtnClosePopup, onClosePopup, textComplete, textClose } = props; + const dispatch = useDispatch(); + + // let autoClose = setTimeout(() => { + // isShowPopup && close(); + // }, 2000); + + function complete() { + // clearTimeout(autoClose); + props?.onComplete && props.onComplete(); + dispatch(alertActions.clear()); + } + + const handleClosePopup = () => { + props?.onClosePopup && props.onClosePopup(); + dispatch(alertActions.clear()); + } + + if (props.notShowError) { + return null; + } else if(isShowPopup) { + return ( + + ) + } else { + return ( +
    +
    + {/* {imgErorr && ( +
    + +
    + )} */} +
    + {changePasswordError ? ( +

    + Mật khẩu bạn nhập không trùng khớp. +

    + ) : ( +

    + {props.message} +

    + )} +
    +
    +
    + ); + } +} + +export { AlertError }; diff --git a/src/_components/Alert/index.js b/src/_components/Alert/index.js new file mode 100644 index 0000000..5ced264 --- /dev/null +++ b/src/_components/Alert/index.js @@ -0,0 +1,3 @@ +export * from './error'; +export * from './success'; +export * from './alert'; diff --git a/src/_components/Alert/success.js b/src/_components/Alert/success.js new file mode 100644 index 0000000..29be68c --- /dev/null +++ b/src/_components/Alert/success.js @@ -0,0 +1,36 @@ +import React from 'react'; +import { alertActions } from '../../_actions'; +import { useDispatch } from 'react-redux'; + +function AlertSuccess(props) { + const dispatch = useDispatch(); + + let autoClose = setTimeout(() => { + close(); + }, 2000); + + function close() { + clearTimeout(autoClose); + props.onComplete(); + dispatch(alertActions.clear()); + + } + if (props.notShowComplete) { + return null; + } else { + return ( + + + ); + } + +} + +export { AlertSuccess }; \ No newline at end of file diff --git a/src/_components/Audio/audio.js b/src/_components/Audio/audio.js new file mode 100644 index 0000000..5af05fe --- /dev/null +++ b/src/_components/Audio/audio.js @@ -0,0 +1,96 @@ +import React, { useEffect } from "react"; + +import Play from "./play"; +import Pause from "./pause"; +import Bar from "./bar"; +import "./style.scss"; +import useAudioPlayer from "./useAudioPlayer"; +import { PlayArrow, Pause as PauseIcon } from "@material-ui/icons"; + +function Audio(props) { + const { curTime, duration, playing, setPlaying, setClickedTime } = + useAudioPlayer(); + let { link, type } = props; + + useEffect(() => { + document.getElementById("audio").loop = false; + }, []); + + return ( +
    + {type === "video" ? ( + + ) : ( + + )} +
    + {playing ? ( + setPlaying(false)} /> + ) : ( + setPlaying(true)} /> + )} + setClickedTime(time)} + /> +
    +
    + ); +} + +let timeoutId; +function AudioCustom(props) { + const { curTime, duration, playing, setPlaying, setClickedTime, setCurTime } = + useAudioPlayer(); + let { link, type } = props; + + useEffect(() => { + const audio = document.getElementById("audio"); + const source = document.getElementById("audioSource"); + clearTimeout(timeoutId); + timeoutId = setTimeout(() => { + audio.currentTime = 0; + setClickedTime(0); + setCurTime(0); + setPlaying(false); + source.src = link; + audio.load(); + }, 100); + }, [link]); + + useEffect(() => { + document.getElementById("audio").loop = false; + }, []); + + return ( +
    + +
    + {playing ? ( + + ) : ( + + )} + setClickedTime(time)} + /> +
    +
    + ); +} + +export { Audio, AudioCustom }; diff --git a/src/_components/Audio/bar.js b/src/_components/Audio/bar.js new file mode 100644 index 0000000..d2899ad --- /dev/null +++ b/src/_components/Audio/bar.js @@ -0,0 +1,62 @@ +import React from "react"; +import moment from "moment"; +import momentDurationFormatSetup from "moment-duration-format"; + +export default function Bar(props) { + const { duration, curTime, onTimeUpdate, isHideTime } = props; + + const curPercentage = (curTime / duration) * 100; + + function formatDuration(duration) { + return moment + .duration(duration, "seconds") + .format("mm:ss", { trim: false }); + } + + function calcClickedTime(e) { + const clickPositionInPage = e.pageX; + const bar = document.querySelector(".bar__progress"); + const barStart = bar.getBoundingClientRect().left + window.scrollX; + const barWidth = bar.offsetWidth; + const clickPositionInBar = clickPositionInPage - barStart; + const timePerPixel = duration / barWidth; + return timePerPixel * clickPositionInBar; + } + + function handleTimeDrag(e) { + onTimeUpdate(calcClickedTime(e)); + + const updateTimeOnMove = (eMove) => { + onTimeUpdate(calcClickedTime(eMove)); + }; + + document.addEventListener("mousemove", updateTimeOnMove); + + document.addEventListener("mouseup", () => { + document.removeEventListener("mousemove", updateTimeOnMove); + }); + } + + return ( +
    + {!isHideTime && ( + {formatDuration(curTime)} + )} +
    handleTimeDrag(e)} + > + +
    + {!isHideTime && ( + {formatDuration(duration)} + )} +
    + ); +} diff --git a/src/_components/Audio/index.js b/src/_components/Audio/index.js new file mode 100644 index 0000000..5c678bb --- /dev/null +++ b/src/_components/Audio/index.js @@ -0,0 +1 @@ +export * from './audio'; diff --git a/src/_components/Audio/pause.js b/src/_components/Audio/pause.js new file mode 100644 index 0000000..c78234b --- /dev/null +++ b/src/_components/Audio/pause.js @@ -0,0 +1,12 @@ +import React from "react"; +import { PauseCircleFilled } from "@material-ui/icons"; + +export default function Play(props) { + const { handleClick } = props; + + return ( + + ); +} \ No newline at end of file diff --git a/src/_components/Audio/play.js b/src/_components/Audio/play.js new file mode 100644 index 0000000..bfcf643 --- /dev/null +++ b/src/_components/Audio/play.js @@ -0,0 +1,12 @@ +import React from "react"; +import { PlayCircleFilled } from "@material-ui/icons"; + +export default function Play(props) { + const { handleClick } = props; + + return ( + + ); +} \ No newline at end of file diff --git a/src/_components/Audio/style.scss b/src/_components/Audio/style.scss new file mode 100644 index 0000000..4328a82 --- /dev/null +++ b/src/_components/Audio/style.scss @@ -0,0 +1,200 @@ +.player { + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px 0; + background-color: #fff; + border-radius: 20px; + box-shadow: 1px 2px 4px 0 rgba(21, 27, 38, 0.15); + margin: 0 50px; + + .controls { + flex-grow: 1; + margin: 0 20px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + + .player__button { + width: fit-content; + margin-bottom: 15px; + background-color: transparent; + border: none; + + &:focus { + outline: none; + } + &:hover { + cursor: pointer; + } + + svg { + font-size: 4em; + color: #00b9b7; + } + } + + .bar { + user-select: none; + width: 100%; + display: flex; + align-items: center; + + .bar__time { + color: #000; + font-size: 16px; + } + + .bar__progress { + flex: 1; + border-radius: 5px; + margin: 0 20px; + height: 10px; + display: flex; + align-items: center; + cursor: pointer; + + .bar__progress__knob { + position: relative; + height: 16px; + width: 16px; + border: 1.5px solid white; + border-radius: 50%; + background-color: #f08a01; + } + } + } + + @media screen and (max-width: 800px) { + flex-direction: column; + + .controls { + width: 100%; + margin-top: 20px; + } + + .bar { + width: 90%; + } + } + + @media screen and (max-height: 800px) { + .player { + margin: 0 30px; + } + } + + @media screen and (max-width: 500px) { + .song { + .song__title { + font-size: 2.5em; + } + + .song__artist { + font-size: 0.8em; + } + } + } +} + +.player-exam { + display: flex; + justify-content: space-between; + align-items: center; + background-color: #fff; + border-radius: 20px; + box-shadow: 1px 2px 4px 0 rgba(21, 27, 38, 0.15); + // margin: 0 20px; + background-image: linear-gradient(to left, #00e1a0, #00b9b7); + padding: 0px 24px; + + .controls { + flex-grow: 1; + display: flex; + justify-content: center; + align-items: center; + } + + .player__button { + width: fit-content; + background-color: transparent; + border: none; + + &:focus { + outline: none; + } + &:hover { + cursor: pointer; + } + + svg { + font-size: 4em; + color: #fff; + } + } + + .bar { + user-select: none; + width: 100%; + display: flex; + align-items: center; + + .bar__time { + color: #000; + font-size: 16px; + } + + .bar__progress { + flex: 1; + border-radius: 5px; + margin: 0 20px; + height: 2px; + display: flex; + align-items: center; + background: #fff; + cursor: pointer; + + .bar__progress__knob { + position: relative; + height: 16px; + width: 16px; + border: 1.5px solid white; + border-radius: 50%; + background-color: #f08a01; + } + } + } + + @media screen and (max-width: 800px) { + flex-direction: column; + + .controls { + width: 100%; + margin-top: 20px; + } + + .bar { + width: 90%; + } + } + + @media screen and (max-height: 800px) { + .player { + margin: 0 30px; + } + } + + @media screen and (max-width: 500px) { + .song { + .song__title { + font-size: 2.5em; + } + + .song__artist { + font-size: 0.8em; + } + } + } +} diff --git a/src/_components/Audio/useAudioPlayer.js b/src/_components/Audio/useAudioPlayer.js new file mode 100644 index 0000000..bc10c7d --- /dev/null +++ b/src/_components/Audio/useAudioPlayer.js @@ -0,0 +1,96 @@ +import { useState, useEffect } from "react"; + +let timeoutId = null; +function useAudioPlayer() { + const [duration, setDuration] = useState(0); + const [curTime, setCurTime] = useState(0); + const [playing, setPlaying] = useState(false); + const [clickedTime, setClickedTime] = useState(0); + + let audio = document.getElementById("audio"); + useEffect(() => { + audio = document.getElementById("audio"); + if (parseInt(curTime) == parseInt(duration)) { + audio.currentTime = 0; + setCurTime(0); + } + if (!playing) { + audio.pause(); + audio.removeEventListener("loadeddata", setAudioData); + audio.removeEventListener("timeupdate", setAudioTime); + } else { + audio.play(); + audio.addEventListener("loadeddata", setAudioData); + audio.addEventListener("timeupdate", setAudioTime); + } + }, [playing]); + + useEffect(() => { + if (parseInt(curTime) == parseInt(duration + 3)) { + setPlaying(false); + } + }, [clickedTime, curTime]); + + // state setters wrappers + const setAudioData = () => { + setDuration(audio.duration); + setCurTime(audio.currentTime); + }; + + const setAudioTime = () => { + if (parseInt(curTime) == parseInt(duration)) { + setCurTime(0); + } else { + setCurTime(audio.currentTime); + } + }; + + useEffect(() => { + // DOM listeners: update React state on DOM events + audio.addEventListener("loadeddata", setAudioData); + + audio.addEventListener("timeupdate", setAudioTime); + + // React state listeners: update DOM on React state changes + playing ? audio.play() : audio.pause(); + + if (clickedTime && clickedTime !== curTime) { + audio.currentTime = clickedTime; + setClickedTime(null); + } + + // effect cleanup + return () => { + audio.removeEventListener("loadeddata", setAudioData); + audio.removeEventListener("timeupdate", setAudioTime); + }; + }); + + useEffect(() => { + if (playing) { + let time = + parseInt(duration) + 1 === parseInt(curTime) + ? duration + : duration - curTime; + const audio = document.getElementById("audio"); + clearTimeout(timeoutId); + timeoutId = setTimeout(() => { + audio.pause(); + setPlaying(false); + }, time * 1000); + } else { + // setCurTime(0) + } + }, [playing, curTime]); + + return { + curTime, + duration, + playing, + setPlaying, + setClickedTime, + setCurTime, + }; +} + +export default useAudioPlayer; diff --git a/src/_components/Auth/InputDate/index.js b/src/_components/Auth/InputDate/index.js new file mode 100644 index 0000000..1846b31 --- /dev/null +++ b/src/_components/Auth/InputDate/index.js @@ -0,0 +1,75 @@ +import classNames from "classnames"; +import React, { useRef, useState } from "react"; +// import { SelectDate } from "../../Calendar"; +import "./index.scss"; +import DatePicker, { registerLocale } from "react-datepicker"; +import vi from "date-fns/locale/vi"; +import { isEmpty } from "lodash"; +registerLocale("vi", vi); + +const InputDate = (props) => { + const $inputRef = useRef(null); + const [isFocus, setIsFocus] = useState(false); + + /** + * changeValue: input change value + * @param e event + */ + const changeValue = (date) => { + if (props.isWarning) { + props.setIsWarning && props.setIsWarning(""); + } + props.setValue(date); + }; + + return ( +
    + {props.errorText ? ( +
    + {props.errorText} +
    + ) : null} +
    +
    {props.renderLabelIcon ? props.renderLabelIcon() : null}
    + changeValue(date)} + showMonthDropdown + showYearDropdown + fixedHeight + dropdownMode="select" + dateFormat="P" + locale="vi" + placeholderText={!isEmpty(props?.placeholder) ? `${props?.placeholder}`: `DD/MM/YYYY`} + name={props.name} + popperPlacement="bottom" + popperModifiers={[ + { + name: "flip", + options: { + fallbackPlacements: ["bottom"], + }, + }, + ]} + onKeyDown={(e) => { + e.preventDefault(); + }} + /> +
    +
    + ); +}; + +export default InputDate; diff --git a/src/_components/Auth/InputDate/index.scss b/src/_components/Auth/InputDate/index.scss new file mode 100644 index 0000000..1a786d8 --- /dev/null +++ b/src/_components/Auth/InputDate/index.scss @@ -0,0 +1,103 @@ +@import "/src/_styles/mixin"; + +$red: #e22028; +$border-color: #4a4848; + +.input_date_base_container { + position: relative; + + .error_input { + span { + color: $red; + font-size: 18px; + } + } + + .error_text { + margin-bottom: 9px; + } + + .error_text_absolute { + position: absolute; + bottom: calc(100% + 2px); + } + + .input_date_base { + display: flex; + align-items: center; + height: 65px; + padding: 0px 22px; + border: 1px solid $border-color; + border-radius: 10px; + margin-bottom: 22px; + + @media screen and (max-width: 768px) { + height: 44px; + + svg { + width: 18px; + } + } + + .icon_label { + width: 31px; + margin-right: 26px; + flex: none; + + @include screen_mobile { + margin-right: 0 !important; + } + } + + .react-datepicker-wrapper { + height: 100%; + + .react-datepicker__input-container { + height: 100%; + } + } + + input { + height: 100%; + border: none; + font-size: 18px; + line-height: 21px; + background-color: transparent; + width: 100%; + font-family: "Myriadpro-Regular"; + + &:focus { + outline: none; + } + + @include screen_mobile { + font-size: 0.9rem !important; + } + + &::placeholder { + /* Chrome, Firefox, Opera, Safari 10.1+ */ + font-family: "Myriadpro-Regular"; + color: #8e9298; + opacity: 1; + /* Firefox */ + } + + &:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + font-family: "Myriadpro-Regular"; + color: #8e9298; + } + + &::-ms-input-placeholder { + /* Microsoft Edge */ + font-family: "Myriadpro-Regular"; + color: #8e9298; + } + } + + select { + font-family: "Myriadpro-Regular"; + color: #8e9298; + } + } +} \ No newline at end of file diff --git a/src/_components/Auth/InputSelect/index.js b/src/_components/Auth/InputSelect/index.js new file mode 100644 index 0000000..5a17b2e --- /dev/null +++ b/src/_components/Auth/InputSelect/index.js @@ -0,0 +1,184 @@ +import React, { useEffect, useRef, useState } from "react"; +import classnames from "classnames"; +import "./index.scss"; +import useOutsideClick from "../../../_helpers/customHook/useOutsideClick"; +import { PresentToAllSharp } from "@material-ui/icons"; + +// interface Props { +// value: OptionInputRadio; +// setValue: (..._args: any[]) => void; +// label: string; +// className?: string; +// options: OptionInputRadio[]; +// inputEditable?: boolean; +// placeholder: string; +// isWarning?: boolean; +// setIsWarning?: (..._args: any[]) => void; +// disabledClick?: boolean; +// } + +const InputRadio = (props) => { + const [isOpen, setIsOpen] = useState(false); + const $selectRef = useRef(null); + const isOpenCached = useRef(null); + + useEffect(() => { + isOpenCached.current = isOpen; + }, [isOpen]); + + useOutsideClick($selectRef, () => { + if (isOpenCached.current) { + setIsOpen(false); + } + }); + + // console.log(props.value); + + return ( +
    + {props.errorText && props?.typeErrText != "underAbsolute" ? ( +
    + {props.errorText} +
    + ) : null} +
    { + props.isWarning && props.setIsWarning(false); + props.setErrorText && props.setErrorText(""); + if (!props.disabledClick) { + setIsOpen(!isOpen); + } else { + props.onClickDisable && props.onClickDisable(); + } + }} + > +
    +
    + {props.label ? {props.label} : null} +
    + {props.renderLabelIcon ? props.renderLabelIcon() : null} +
    + { + if (props.inputEditable) { + props.setValue({ + value: e.target?.value, + title: e.target?.value, + }); + } + }} + style={props.inputEditable ? {} : { pointerEvents: "none" }} + > +
    + + + +
    +
    +
    +
    +
    +
    + {props.options.map((option) => { + return ( +
    { + props.setValue(option); + setIsOpen(false); + }} + > + + {option.title} + +
    + ); + })} +
    +
    + {props.errorText && props?.typeErrText == "underAbsolute" ? ( +
    + {props.errorText} +
    + ) : null} +
    + ); +}; + +export default InputRadio; diff --git a/src/_components/Auth/InputSelect/index.scss b/src/_components/Auth/InputSelect/index.scss new file mode 100644 index 0000000..667803b --- /dev/null +++ b/src/_components/Auth/InputSelect/index.scss @@ -0,0 +1,236 @@ +@import "/src/_styles/mixin"; + +$red: #e22028; +$border-color: #4a4848; + +.input_radio_base { + position: relative; + .error_select { + span { + color: $red; + font-size: 18px; + display: flex; + } + } + .error_text { + margin-bottom: 9px; + } + .error_text_absolute { + position: absolute; + bottom: calc(100% + 2px); + } + .error_text_absolute_new { + position: absolute; + top: calc(100% + 2px); + } + .input_select { + cursor: pointer; + } + .input_select_main_wrapper { + display: flex; + align-items: center; + height: 65px; + padding: 0px 22px; + border: 1px solid $border-color; + border-radius: 10px; + margin-bottom: 22px; + .input_select_main { + display: flex; + align-items: center; + flex: 1; + height: 100%; + padding: 1px 0px; + display: flex; + align-items: center; + flex: 1; + height: 100%; + .icon_label { + width: 31px; + margin-right: 26px; + border: 0px solid transparent; + border-bottom-width: 1px; + @include screen_mobile { + margin-right: 1rem !important; + } + } + .input_text { + height: 100%; + border: none; + font-size: 18px; + line-height: 21px; + flex: 1; + background-color: transparent; + opacity: 1; + + &:focus { + outline: none; + } + @include screen_mobile { + font-size: 0.9rem !important; + } + } + } + } + + .drop_down { + position: absolute; + display: none; + top: 65px; + width: 100%; + max-height: 350px; + overflow: auto; + background-color: white; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; + z-index: 1; + /* width */ + &::-webkit-scrollbar { + width: 6px; + } + + /* Handle */ + &::-webkit-scrollbar-thumb { + background: #bbbbbb; + border-radius: 10px; + } + + &::-webkit-scrollbar-track { + margin: 0.5rem 0; + } + + /* Handle on hover */ + &::-webkit-scrollbar-thumb:hover { + background: #8b8b8b; + } + + .option_item { + padding: 12px 30px; + &:hover { + background-color: whitesmoke; + cursor: pointer; + } + span { + font-size: 18px; + font-family: "Myriadpro-Regular"; + color: #707070; + + @include screen_mobile { + font-size: 0.9rem; + } + } + } + &.active { + display: block; + } + } + + .drop_down_news { + top: clamp(2.4rem, 3vw, 2.8rem); + border: 1px solid var(--text-color); + border-radius: 0.5rem; + width: 54%; + right: -20%; + text-align: center; + min-width: 13rem; + + @include screen_mobile { + right: 3%; + min-width: 12.5rem; + } + .option_item { + padding: 12px 20px; + span { + font-size: 18px; + font-family: "AvertaStdCY" !important; + color: #707070; + + @include screen_mobile { + font-size: 0.875rem; + } + } + } + } + + &.focus { + box-shadow: 1px 3px 3px 0px rgba(23, 23, 23, 0.16); + border-top-left-radius: 10px; + border-top-right-radius: 10px; + .input_select_main_wrapper { + border-color: white; + border-radius: 0px; + border-top-left-radius: 10px; + border-top-right-radius: 10px; + background-color: white; + } + .drop_down { + box-shadow: 1px 3px 3px 0px rgba(23, 23, 23, 0.16); + } + .input_select_main { + border: 0px solid #a1afbe; + border-bottom-width: 1px; + } + } + &.warning_select { + .input_select_main_wrapper { + border-color: $red !important; + border-width: 2px !important; + border-style: solid !important; + } + } + .rotate_180 { + transform: rotate(180deg); + } + .cursor_pointer { + cursor: pointer; + } + + input { + font-family: "Myriadpro-Regular"; + &::placeholder { + /* Chrome, Firefox, Opera, Safari 10.1+ */ + font-family: "Myriadpro-Regular"; + color: #8e9298; + opacity: 1; /* Firefox */ + } + + &:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + font-family: "Myriadpro-Regular"; + color: #8e9298; + } + + &::-ms-input-placeholder { + /* Microsoft Edge */ + font-family: "Myriadpro-Regular"; + color: #8e9298; + } + } +} + +.input_radio_base_news { + &.focus { + border-radius: 10px; + .input_select_main_wrapper { + border-radius: 10px; + } + + .input_select_main { + border: none; + } + } + + .input_select_main_wrapper_news { + padding: 0 1.2rem !important; + } + + .input_text { + width: 75% !important; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + @include screen_mobile { + width: 100%; + max-width: 100% !important; + } + } +} diff --git a/src/_components/Auth/InputSelectSearch/index.js b/src/_components/Auth/InputSelectSearch/index.js new file mode 100644 index 0000000..df42fa9 --- /dev/null +++ b/src/_components/Auth/InputSelectSearch/index.js @@ -0,0 +1,158 @@ +import React, { useEffect, useRef, useState } from "react"; +import classnames from "classnames"; +import "./index.scss"; +import useOutsideClick from "../../../_helpers/customHook/useOutsideClick"; +import { PresentToAllSharp } from "@material-ui/icons"; +import ModalSearch from "../../Modal/ModalSearch/ModalSearch"; + +// interface Props { +// value: OptionInputRadio; +// setValue: (..._args: any[]) => void; +// label: string; +// className?: string; +// options: OptionInputRadio[]; +// inputEditable?: boolean; +// placeholder: string; +// isWarning?: boolean; +// setIsWarning?: (..._args: any[]) => void; +// disabledClick?: boolean; +// } + +const InputSelectSearch = (props) => { + const [isOpen, setIsOpen] = useState(false); + const $selectRef = useRef(null); + const isOpenCached = useRef(null); + + useEffect(() => { + isOpenCached.current = isOpen; + }, [isOpen]); + + useOutsideClick($selectRef, () => { + if (isOpenCached.current) { + setIsOpen(false); + } + }); + + // Handle Select Option + const handleSelectOption = (option) => { + props.setValue(option); + setIsOpen(false); + }; + + // console.log(props.value); + + return ( +
    + {props.errorText && !props?.bottomErr ? ( +
    + {props.errorText} +
    + ) : null} +
    { + props.isWarning && props.setIsWarning(false); + props.setErrorText && props.setErrorText(""); + if (!props.disabledClick) { + setIsOpen(!isOpen); + } else { + props.onClickDisable && props.onClickDisable(); + } + }} + > +
    +
    + {props.label ? {props.label} : null} +
    + {props.renderLabelIcon ? props.renderLabelIcon() : null} +
    + { + if (props.inputEditable) { + props.setValue({ + value: e.target?.value, + title: e.target?.value, + }); + } + }} + style={props.inputEditable ? {} : { pointerEvents: "none" }} + > +
    + + + +
    +
    +
    +
    + {props?.bottomErr &&
    + {props.errorText} +
    } + {!!isOpen ? ( + setIsOpen(false)} + handleSelectOption={handleSelectOption} + /> + ) : null} +
    + ); +}; + +export default InputSelectSearch; diff --git a/src/_components/Auth/InputSelectSearch/index.scss b/src/_components/Auth/InputSelectSearch/index.scss new file mode 100644 index 0000000..fe8939a --- /dev/null +++ b/src/_components/Auth/InputSelectSearch/index.scss @@ -0,0 +1,271 @@ +@import "/src/_styles/mixin"; + +$red: #e22028; +$border-color: #4a4848; + +.input_radio_base { + position: relative; + + .error_select { + span { + color: $red; + font-size: 18px; + display: flex; + + @media screen and (max-width: 768px) { + font-size: 14px; + } + } + } + + .error_text { + margin-bottom: 9px; + } + + .error_text_absolute { + position: absolute; + bottom: calc(100% + 2px); + } + + .input_select { + cursor: pointer; + } + + .input_select_main_wrapper { + display: flex; + align-items: center; + height: 65px; + padding: 0px 22px; + border: 1px solid $border-color; + border-radius: 10px; + margin-bottom: 22px; + + @media screen and (max-width: 768px) { + height: 44px; + + svg { + width: 18px; + height: 22px; + } + } + + .input_select_main { + display: flex; + align-items: center; + flex: 1; + height: 100%; + padding: 1px 0px; + display: flex; + align-items: center; + flex: 1; + height: 100%; + + .icon_label { + width: 31px; + margin-right: 26px; + border: 0px solid transparent; + border-bottom-width: 1px; + + @include screen_mobile { + margin-right: 0 !important; + } + } + + .input_text { + height: 100%; + border: none; + font-size: 18px; + line-height: 21px; + flex: 1; + background-color: transparent; + opacity: 1; + + &:focus { + outline: none; + } + + @include screen_mobile { + font-size: 0.9rem !important; + } + } + } + } + + .drop_down { + position: absolute; + display: none; + top: 65px; + width: 100%; + max-height: 350px; + overflow: auto; + background-color: white; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; + z-index: 1; + + /* width */ + &::-webkit-scrollbar { + width: 6px; + } + + /* Handle */ + &::-webkit-scrollbar-thumb { + background: #bbbbbb; + border-radius: 10px; + } + + &::-webkit-scrollbar-track { + margin: 0.5rem 0; + } + + /* Handle on hover */ + &::-webkit-scrollbar-thumb:hover { + background: #8b8b8b; + } + + .option_item { + padding: 12px 30px; + + &:hover { + background-color: whitesmoke; + cursor: pointer; + } + + span { + font-size: 18px; + font-family: "Myriadpro-Regular"; + color: #707070; + + @include screen_mobile { + font-size: 0.9rem; + } + } + } + + &.active { + display: block; + } + } + + .drop_down_news { + top: clamp(2.4rem, 3vw, 2.8rem); + border: 1px solid var(--text-color); + border-radius: 0.5rem; + width: 54%; + right: -20%; + text-align: center; + min-width: 13rem; + + @include screen_mobile { + right: 3%; + min-width: 12.5rem; + } + + .option_item { + padding: 12px 20px; + + span { + font-size: 18px; + font-family: "AvertaStdCY" !important; + color: #707070; + + @include screen_mobile { + font-size: 0.875rem; + } + } + } + } + + &.focus { + box-shadow: 1px 3px 3px 0px rgba(23, 23, 23, 0.16); + border-top-left-radius: 10px; + border-top-right-radius: 10px; + + .input_select_main_wrapper { + border-color: white; + border-radius: 0px; + border-top-left-radius: 10px; + border-top-right-radius: 10px; + background-color: white; + } + + .drop_down { + box-shadow: 1px 3px 3px 0px rgba(23, 23, 23, 0.16); + } + + .input_select_main { + border: 0px solid #a1afbe; + border-bottom-width: 1px; + } + } + + &.warning_select { + .input_select_main_wrapper { + border-color: $red !important; + border-width: 2px !important; + border-style: solid !important; + } + } + + .rotate_180 { + transform: rotate(180deg); + } + + .cursor_pointer { + cursor: pointer; + } + + input { + font-family: "Myriadpro-Regular"; + + &::placeholder { + /* Chrome, Firefox, Opera, Safari 10.1+ */ + font-family: "Myriadpro-Regular"; + color: #8e9298; + opacity: 1; + /* Firefox */ + } + + &:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + font-family: "Myriadpro-Regular"; + color: #8e9298; + } + + &::-ms-input-placeholder { + /* Microsoft Edge */ + font-family: "Myriadpro-Regular"; + color: #8e9298; + } + } +} + +.input_radio_base_news { + &.focus { + border-radius: 10px; + + .input_select_main_wrapper { + border-radius: 10px; + } + + .input_select_main { + border: none; + } + } + + .input_select_main_wrapper_news { + padding: 0 1.2rem !important; + } + + .input_text { + width: 75% !important; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + @include screen_mobile { + width: 100%; + max-width: 100% !important; + } + } +} \ No newline at end of file diff --git a/src/_components/Auth/InputText/index.js b/src/_components/Auth/InputText/index.js new file mode 100644 index 0000000..296889b --- /dev/null +++ b/src/_components/Auth/InputText/index.js @@ -0,0 +1,245 @@ +import React, { useEffect, useRef, useState } from "react"; +import useOutsideClick from "../../../_helpers/customHook/useOutsideClick"; +import "./index.scss"; +import classnames from "classnames"; + +// interface Props { +// value: string | number; +// setValue: (..._args: any[]) => void; +// name: string; +// placeholder?: string; +// required?: boolean; +// type: string; +// className?: string; +// label?: string; +// style?: any; +// isWarning?: boolean; +// setIsWarning?: (..._args: any[]) => void; +// setIcon?: () => any; +// min?: number; +// max?: number; +// isHiddenClear?: boolean; +// } + +const InputText = (props) => { + const $inputRef = useRef(null); + const [isFocus, setIsFocus] = useState(false); + const isFocusState = useRef(false); + const [showPw, setShowPw] = useState(false); + + useEffect(() => { + isFocusState.current = isFocus; + }, [isFocus]); + + useOutsideClick($inputRef, () => { + if (isFocusState.current) { + setIsFocus(false); + } + }); + + /** + * togglePw + */ + const togglePw = () => { + setShowPw(!showPw); + }; + + /** + * renderType: render type input + */ + const renderType = () => { + if (props.type === "password") { + return !showPw ? "password" : "text"; + } + return props.type; + }; + + /** + * changeValue: input change value + * @param e event + */ + const changeValue = (e) => { + // if (e.target.value === " ") { + // return; + // } + // if ( + // e.target.value?.length > 2 && + // e.target.value[e.target.value.length - 2] === " " && + // e.target.value[e.target.value.length - 1] === " " + // ) { + // return; + // } + if (props.removeWarningOnType && props.errorText) { + props.setErrorText && props.setErrorText(""); + } else if (props.errorText && !e.target.value) { + props.setErrorText && props.setErrorText(""); + } + if (props.type === "password") { + // props.setValue(e.target.value?.trim()); + props.setValue(e.target.value); + } else { + props.setValue(e.target.value); + } + }; + + // Handle Reset Value Search + const handleResetValue = () => { + props.handleResetValueSearch("reset"); + }; + + // Handle Checked box + const handleCheckedBoxValue = () => { + props.handleCheckedBox(); + }; + + return ( +
    + {props.errorText && props?.typeErrText != "underAbsolute" ? ( +
    + {props.errorText} +
    + ) : null} +
    +
    + {props.label ? : null} +
    + {props.renderLabelIcon ? props.renderLabelIcon() : null} +
    + { + setIsFocus(true); + props.onFocus && props.onFocus(); + }} + min={props.min ? props.min : ""} + max={props.max ? props.max : ""} + onBlur={props.onBlur} + autoComplete={ + props.autoComplete ? props.autoComplete : "new-password" + } + autoFocus={props?.autoFocus ? props.autoFocus : false} + /> + {props.typeSearch == "search" && props.value ? ( +
    + Icon Delete Menu +
    + ) : null} + {props.typeSearch == "checkbox" && ( +
    + Icon Checked Box +
    + )} +
    + {props.type !== "password" ? null : ( +
    + {showPw ? ( + + + + + ) : ( + + + + + + )} +
    + )} +
    + + {/* Err Text Under */} + {props.errorText && props?.typeErrText == "underAbsolute" ? ( +
    + {props.errorText} +
    + ) : null} +
    + ); +}; + +export default InputText; diff --git a/src/_components/Auth/InputText/index.scss b/src/_components/Auth/InputText/index.scss new file mode 100644 index 0000000..e360809 --- /dev/null +++ b/src/_components/Auth/InputText/index.scss @@ -0,0 +1,145 @@ +@import "/src/_styles/mixin"; + +$red: #e22028; +$border-color: #4a4848; + +.input_text_base_container { + position: relative; + + .error_input { + span { + color: $red; + font-size: 18px; + } + } + + .error_text { + margin-bottom: 9px; + } + + .error_text_absolute { + position: absolute; + bottom: calc(100% + 2px); + } + + .error_text_absolute_new { + position: absolute; + top: calc(100% + 2px); + } + + .input_text_base { + display: flex; + align-items: center; + height: 65px; + padding: 0px 22px; + border: 1px solid $border-color; + border-radius: 10px; + margin-bottom: 22px; + + @media screen and (max-width: 768px) { + height: 44px; + + svg { + width: 18px; + } + } + + &.focus { + border-width: 1px; + + .custom_icon { + display: none; + } + } + + &.warning { + border-color: $red !important; + border-width: 2px !important; + border-style: solid !important; + padding-left: 23px; + padding-right: 23px; + } + + &.success { + border-color: #36ae4a !important; + border-width: 2px !important; + border-style: solid !important; + padding-left: 23px; + padding-right: 23px; + } + + .input_text_base_content { + display: flex; + align-items: center; + flex: 1; + height: 100%; + padding: 1px 0px; + + .icon_label { + width: 31px; + margin-right: 26px; + + @include screen_mobile { + margin-right: 0 !important; + } + } + + .input_text { + height: 100%; + border: none; + font-size: 18px; + line-height: 21px; + flex: 1; + background-color: transparent; + + &:focus { + outline: none; + } + + @include screen_mobile { + font-size: 0.9rem !important; + } + } + } + + .toggle_password { + display: flex; + align-items: center; + cursor: pointer; + } + } + + input[type="password"] { + &::-ms-reveal { + display: none; + } + } + + input { + font-family: "Myriadpro-Regular"; + + &::placeholder { + /* Chrome, Firefox, Opera, Safari 10.1+ */ + font-family: "Myriadpro-Regular"; + color: #8e9298; + opacity: 1; + /* Firefox */ + } + + &:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + font-family: "Myriadpro-Regular"; + color: #8e9298; + } + + &::-ms-input-placeholder { + /* Microsoft Edge */ + font-family: "Myriadpro-Regular"; + color: #8e9298; + } + } +} + +::-ms-reveal { + display: none; +} \ No newline at end of file diff --git a/src/_components/Auth/SocialLogin/index.js b/src/_components/Auth/SocialLogin/index.js new file mode 100644 index 0000000..dc8a394 --- /dev/null +++ b/src/_components/Auth/SocialLogin/index.js @@ -0,0 +1,26 @@ +import PropTypes from "prop-types"; +import React, { Component } from "react"; +import SocialLogin from "react-social-login"; + +class Button extends Component { + static propTypes = { + triggerLogin: PropTypes.func.isRequired, + }; + + render() { + const { triggerLogin, image, ...props } = this.props; + return ( +
    { + props.clickprocessing && props.clickprocessing(); + triggerLogin(e); + }} + > + {props.children} +
    + ); + } +} + +export default SocialLogin(Button); diff --git a/src/_components/BoxTitle/BoxTitle.jsx b/src/_components/BoxTitle/BoxTitle.jsx new file mode 100644 index 0000000..5f61db8 --- /dev/null +++ b/src/_components/BoxTitle/BoxTitle.jsx @@ -0,0 +1,13 @@ +import "./BoxTitle.style.scss"; + +export const BoxTitlte = ({ title, id }) => { + return ( +
    +
    + {title} +
    +
    + ); +}; diff --git a/src/_components/BoxTitle/BoxTitle.style.scss b/src/_components/BoxTitle/BoxTitle.style.scss new file mode 100644 index 0000000..fabcb21 --- /dev/null +++ b/src/_components/BoxTitle/BoxTitle.style.scss @@ -0,0 +1,10 @@ +@import "/src/_styles/mixin"; + +.box_title { + padding: 0.35rem 0.9vw; + border-radius: 3rem; + + @include screen_mobile { + padding: 0.2rem 5vw; + } +} diff --git a/src/_components/Button/ButtomBack.js b/src/_components/Button/ButtomBack.js new file mode 100644 index 0000000..0e9c078 --- /dev/null +++ b/src/_components/Button/ButtomBack.js @@ -0,0 +1,10 @@ +import React from 'react'; + +function ButtonBack() { + + return ( + Quay lại + ); +} + +export { ButtonBack }; \ No newline at end of file diff --git a/src/_components/Button/ButtonNews.js b/src/_components/Button/ButtonNews.js new file mode 100644 index 0000000..e7ccf0a --- /dev/null +++ b/src/_components/Button/ButtonNews.js @@ -0,0 +1,39 @@ +import "./ButtonNews.style.scss"; + +export const ButtonNews = ({ + onClick, + border, + children, + width, + height, + backgroundColor, + boxShadow, + maxWidth, + maxHeight, + disabled, + styleProps, + className, +}) => { + return ( + + ); +}; + +export default ButtonNews; diff --git a/src/_components/Button/ButtonNews.style.scss b/src/_components/Button/ButtonNews.style.scss new file mode 100644 index 0000000..7b8c348 --- /dev/null +++ b/src/_components/Button/ButtonNews.style.scss @@ -0,0 +1,10 @@ +.btn_custom { + border-radius: 0.4rem; + display: flex; + align-items: center; + justify-content: center; + position: relative; + &:hover { + opacity: 0.8; + } +} diff --git a/src/_components/Button/index.js b/src/_components/Button/index.js new file mode 100644 index 0000000..0fd8926 --- /dev/null +++ b/src/_components/Button/index.js @@ -0,0 +1,2 @@ +export * from "./ButtonBack"; +export { default as ButtonNews } from "./ButtonNews"; diff --git a/src/_components/Calendar/CalendaSchedule.js b/src/_components/Calendar/CalendaSchedule.js new file mode 100644 index 0000000..70b6539 --- /dev/null +++ b/src/_components/Calendar/CalendaSchedule.js @@ -0,0 +1,494 @@ +import React, { useCallback, useEffect, useState } from "react"; +import dayjs from "dayjs"; +import range from "lodash-es/range"; +import { scheduleActions } from "./../../_actions"; +import moment from "moment"; +import "./style.scss"; +import { useSelector, useDispatch } from "react-redux"; +import { useParams } from "react-router-dom"; +import { scheduleConstants } from "../../_constants"; +import { isEmpty } from "lodash"; + +const weekDays = ["T2", "T3", "T4", "T5", "T6", "T7", "CN"]; + +const todayObj = dayjs(); + +function CalendaSchedule(props) { + const dispatch = useDispatch(); + const schedules = useSelector((state) => state.schedules); + const status = schedules.status; + const date = new Date(); + let { + changeDateCalendaSchedule, + collapse, + showAll, + showMonth, + role, + student_id, + hideEvent, + class_id, + homePageTeacherCalendaSchedule, + } = props; + + role = role || "teacher"; + const [fullHeight, setFullHeight] = useState(false); + const [dayObj, setDayObj] = useState( + dayjs( + date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + ) + ); + const thisYearSelected = schedules.selectDate + ? parseInt(moment(schedules.selectDate)?.format("YYYY")) + : dayObj.year(); + const thisMonthSelected = schedules.selectDate + ? parseInt(moment(schedules.selectDate)?.format("MM") - 1) + : dayObj.month(); + const thisDateSelected = schedules.selectDate + ? parseInt(moment(schedules.selectDate)?.format("DD")) + : dayObj.date(); + const thisWeekSelected = weekCount( + thisYearSelected, + thisMonthSelected, + thisDateSelected + ); + + const thisYear = dayObj.year(); + const thisMonth = dayObj.month(); + const thisDate = dayObj.date(); + + const thisWeek = weekCount(thisYear, thisMonth, thisDate); + const daysInMonth = dayObj.daysInMonth(); + + const dayObjOf1 = dayjs(`${thisYear}-${thisMonth + 1}-1`); + let weekDayOf1 = dayObjOf1.day() - 1; + + if (weekDayOf1 < 0) { + weekDayOf1 = 6; + } + const dayObjOfLast = dayjs(`${thisYear}-${thisMonth + 1}-${daysInMonth}`); + let weekDayOfLast = dayObjOfLast.day() - 1; + if (weekDayOfLast < 0) { + weekDayOfLast = 6; + } + + const handlePrev = () => { + let dayObjTmp = dayObj.subtract(1, "month"); + dispatch( + scheduleActions.getStatus( + dayObjTmp.month() + 1, + dayObjTmp.year(), + role, + student_id, + class_id + ) + ); + setDayObj(dayObjTmp); + }; + const handleNext = () => { + let dayObjTmp = dayObj.add(1, "month"); + dispatch( + scheduleActions.getStatus( + dayObjTmp.month() + 1, + dayObjTmp.year(), + role, + student_id, + class_id + ) + ); + setDayObj(dayObjTmp); + }; + + const [selectDate, setSelectDate] = useState({ + year: schedules.dateSelectedCalendar + ? parseInt(moment(schedules.dateSelectedCalendar).format("YYYY")) + : localStorage.getItem("date_selected") + ? parseInt( + moment(JSON.parse(localStorage.getItem("date_selected"))).format( + "YYYY" + ) + ) + : thisYear, + month: schedules.dateSelectedCalendar + ? parseInt( + parseInt(moment(schedules.dateSelectedCalendar).format("MM")) - 1 + ) + : localStorage.getItem("date_selected") + ? parseInt( + parseInt( + moment(JSON.parse(localStorage.getItem("date_selected"))).format( + "MM" + ) + ) - 1 + ) + : thisMonth, + day: schedules.dateSelectedCalendar + ? parseInt(moment(schedules.dateSelectedCalendar).format("DD")) + : localStorage.getItem("date_selected") + ? parseInt( + moment(JSON.parse(localStorage.getItem("date_selected"))).format("DD") + ) + : todayObj.date(), + }); + + function selectDay(year, month, day) { + localStorage.setItem( + "date_selected", + JSON.stringify(`${year}-${parseInt(month) + 1}-${day}`) + ); + setSelectDate({ + year, + month, + day, + }); + dispatch({ + type: scheduleConstants.SET_DATE_SELECTED_CALENDAR, + time: `${year}-${parseInt(month) + 1}-${day}`, + }); + changeDateCalendaSchedule({ + year, + month, + day, + }); + } + + useEffect(() => { + let currentDate = new Date(); + dispatch( + scheduleActions.getStatus( + parseInt(currentDate.getMonth()) + 1, + currentDate.getFullYear(), + role, + student_id, + class_id + ) + ); + + return () => { + dispatch({ + type: scheduleConstants.GET_STATUS, + data: { + in_complete: [], + complete: [], + has_log: [], + }, + }); + }; + }, []); + + const renderClass = useCallback( + (day, month, year) => { + if (hideEvent) { + return ""; + } + let date = year + "-" + parseInt(month) + "-" + day; + + if (status.in_complete.indexOf(moment(date).format("YYYY-MM-DD")) != -1) { + return " missing"; + } else if ( + status.complete.indexOf(moment(date).format("YYYY-MM-DD")) != -1 + ) { + return " complete"; + } else if ( + status?.has_log?.length > 0 && + status.has_log?.indexOf(moment(date).format("YYYY-MM-DD")) != -1 + ) { + return " active_date"; + } else { + return ""; + } + }, + [status] + ); + + function showFullHeight() { + setFullHeight(!fullHeight); + } + + function renderClassHideCollapse(day, month, year) { + let dateFormat = + selectDate.year + + "-" + + (parseInt(selectDate.month) + 1) + + "-" + + selectDate.day; + + let dateWeekToday = moment(dateFormat); + let dowDateWeekToday = parseInt(dateWeekToday.day()) + 1; + let listDateShowCollapse = [moment(dateFormat).format("YYYY-MM-DD")]; + if (dowDateWeekToday == 2) { + for (let i = 1; i <= 6; i++) { + listDateShowCollapse.push( + moment(dateFormat, "YYYY-MM-DD").add("days", i).format("YYYY-MM-DD") + ); + } + } else if (dowDateWeekToday == 1) { + for (let i = 1; i <= 6; i++) { + listDateShowCollapse.push( + moment(dateFormat, "YYYY-MM-DD") + .subtract("days", i) + .format("YYYY-MM-DD") + ); + } + } else { + for (let i = 2; i < dowDateWeekToday; i++) { + listDateShowCollapse.push( + moment(dateFormat, "YYYY-MM-DD") + .subtract("days", i - 1) + .format("YYYY-MM-DD") + ); + } + for (let i = 1; i <= 8 - dowDateWeekToday; i++) { + listDateShowCollapse.push( + moment(dateFormat, "YYYY-MM-DD").add("days", i).format("YYYY-MM-DD") + ); + } + } + + let date = year + "-" + month + "-" + day; + if (listDateShowCollapse.indexOf(moment(date).format("YYYY-MM-DD")) == -1) { + // return ' hide_collapse'; + } else { + // return ''; + } + return ""; + } + + function dequyWeek(days, week, total) { + days = parseInt(days) + 7; + week++; + if (total > days) { + return dequyWeek(days, week, total); + } else { + return week; + } + } + + function weekCount(year, month_number, total) { + var firstOfMonth = new Date(year, month_number, 1); + let week = 1; + let days = firstOfMonth.getDay() == 0 ? 1 : 8 - firstOfMonth.getDay(); + if (total > days) { + week = dequyWeek(days, week, total); + } + return week; + } + + const renderClassShot = (date) => { + if (fullHeight || !collapse) { + return ""; + } else { + let className = ""; + if ( + thisMonthSelected == dayObj.month() && + thisYearSelected == dayObj.year() + ) { + let week = weekCount(thisYearSelected, thisMonthSelected, date); + className = " hide-date-custom"; + if (thisWeekSelected == week) { + className = ""; + } + } + return className; + } + }; + + const showWeekDayOf1 = () => { + if (fullHeight || !collapse) { + return true; + } else { + let isHide = true; + if ( + thisMonthSelected == dayObj.month() && + thisYearSelected == dayObj.year() + ) { + var firstOfMonth = new Date(thisYear, thisMonth, 1); + if ( + (firstOfMonth.getDay() == 1 && thisWeekSelected == 1) || + thisWeekSelected != 1 + ) { + isHide = false; + } + } + // console.log('isHide ====', isHide) + return isHide; + } + }; + + return ( +
    +
    +
    + +
    {"Tháng " + dayObj.format("M/YYYY")}
    + +
    +
    + {weekDays.map((d) => ( +
    + {d} +
    + ))} +
    +
    + {showWeekDayOf1() && + range(weekDayOf1).map((i) => ( +
    +
    + {dayObjOf1.subtract(weekDayOf1 - i, "day").date()} +
    +
    + ))} + + {range(daysInMonth).map((i) => ( +
    +
    selectDay(thisYear, thisMonth, i + 1)} + > + {i + 1} + ico_check_calendar + ico_missing_calendar + ico_active_calendar_green +
    +
    + ))} + + {range(6 - weekDayOfLast).map((i) => ( +
    +
    + {dayObjOfLast.add(i + 1, "day").date()} +
    +
    + ))} +
    +
    + {collapse && ( +
    showFullHeight()}> + {fullHeight ? ( + ico_dropup_blue + ) : ( + ico_dropdown_blue + )} +
    + )} +
    + ); +} + +export { CalendaSchedule }; diff --git a/src/_components/Calendar/PickDay.js b/src/_components/Calendar/PickDay.js new file mode 100644 index 0000000..366aaa4 --- /dev/null +++ b/src/_components/Calendar/PickDay.js @@ -0,0 +1,68 @@ +import React, { useState } from 'react'; +import { isEmpty } from 'lodash'; + +function PickDay(props) { + let { time, handleChangeDate, name_time } = props; + const [inputs, setInputs] = useState({ + day: !isEmpty(time) ? time.substr(0, 2) : new Date().getDate(), + month: !isEmpty(time) ? time.substr(3, 2) : new Date().getMonth() + 1, + year: !isEmpty(time) ? time.substr(6, 4) : new Date().getFullYear(), + }); + + function createElementsOption(start, end) { + var elements = []; + for (let i = start; i <= end; i++) { + elements.push(); + } + return elements; + } + + let defaultValueDate = new Date().getDate(); + let defaultValueMonth = new Date().getMonth() + 1; + let defaultValueYear = new Date().getFullYear(); + if (!isEmpty(time)) { + defaultValueDate = time.substr(0, 2); + defaultValueMonth = time.substr(3, 2) + defaultValueYear = time.substr(6, 4) + } + + function handleChange(e) { + try{ + const { name, value } = e.target; + let day = defaultValueDate; + let month = defaultValueMonth; + let year = defaultValueYear; + if(_.isEqual(name, 'day')){ + day = value; + }else if(_.isEqual(name, 'month')){ + month = value; + if ((new Date(defaultValueYear, month, 0)).getDate() < (new Date(defaultValueYear, defaultValueMonth, 0)).getDate() && day > (new Date(defaultValueYear, month, 0)).getDate()){ + day = (new Date(defaultValueYear, month, 0)).getDate() + } + }else if(_.isEqual(name, 'year')){ + year = value; + } + handleChangeDate({ + [name_time]: year + '-' + month + '-' + day, + }) + }catch(e){ + console.log('handleChange', e) + } + } + + return ( +
    + + + +
    + ); +} + +export { PickDay }; \ No newline at end of file diff --git a/src/_components/Calendar/SelectDate.js b/src/_components/Calendar/SelectDate.js new file mode 100644 index 0000000..af7738d --- /dev/null +++ b/src/_components/Calendar/SelectDate.js @@ -0,0 +1,67 @@ +import React, { Fragment, useEffect, useRef } from "react"; +// import DatePicker from "react-datepicker"; +import "react-datepicker/dist/react-datepicker.css"; +import DatePicker, { registerLocale } from "react-datepicker"; +import es from "date-fns/locale/es"; + +const months = [ + "Tháng 1 / ", + "Tháng 2 / ", + "Tháng 3 / ", + "Tháng 4 / ", + "Tháng 5 / ", + "Tháng 6 / ", + "Tháng 7 / ", + "Tháng 8 / ", + "Tháng 9 / ", + "Tháng 10 / ", + "Tháng 11 / ", + "Tháng 12 / ", +]; +const days = ["CN", "T2", "T3", "T4", "T5", "T6", "T7"]; + +registerLocale("es", { + ...es, + options: { ...es.options, weekStartsOn: 1 }, + localize: { + month: (n) => months[n], + day: (n) => days[n], + }, +}); + +function SelectDate(props) { + const { id, name, selected, onChange, dateFormat, disableMouseFocus, minDate } = props; + const showTimeSelect = props.showTimeSelect || false; + const showTimeSelectOnly = props.showTimeSelectOnly || false; + const dateRef = useRef(null); + + useEffect(() => { + let isFirefox = window.navigator.userAgent.indexOf("Firefox") != -1; + if (dateRef.current && disableMouseFocus && !isFirefox) { + dateRef.current?.input?.setAttribute("disabled", true); + } + }, [dateRef, disableMouseFocus]); + + return ( + + e.preventDefault()} + showTimeSelect={showTimeSelect} + showTimeSelectOnly={showTimeSelectOnly} + // timeFormat="HH:mm" + locale="es" + id={id} + timeIntervals={15} + dateFormat={dateFormat} + name={name} + selected={selected} + placeholderText="DD/MM/YYYY" + onChange={(time) => onChange(time)} + ref={dateRef} + /> + + ); +} + +export { SelectDate }; diff --git a/src/_components/Calendar/index.js b/src/_components/Calendar/index.js new file mode 100644 index 0000000..e154a3d --- /dev/null +++ b/src/_components/Calendar/index.js @@ -0,0 +1,3 @@ +export * from './CalendaSchedule'; +export * from './PickDay'; +export * from './SelectDate'; \ No newline at end of file diff --git a/src/_components/Calendar/style.scss b/src/_components/Calendar/style.scss new file mode 100644 index 0000000..1557e9d --- /dev/null +++ b/src/_components/Calendar/style.scss @@ -0,0 +1,203 @@ +@import url('https://fonts.googleapis.com/css?family=Manjari:400,700&display=swap'); + +body { + font-family: Manjari, sans-serif; + font-size: 14px; +} + +.calendar { + width: 350px; + margin: 0 auto; + box-shadow: 0 2px 4px 0 rgba(21, 27, 38, .15); + border-radius: 6px; +} + +.header { + display: flex; + align-items: center; + padding: 12px 12px 0 12px; + border-radius: 6px 6px 0 0; + background-color: #fff; + color: #fff; + border-top-left-radius: 20px; + border-top-right-radius: 20px; +} + +.nav { + border: 1px solid #fff; + border-radius: 25px; + outline: 0; + background-color: transparent; + cursor: pointer; +} + +.datetime { + margin: 0 auto; + font-size: 18px; + font-weight: bold; + color: #00B9B7; +} + +.week-container, +.day-container { + display: flex; + flex-wrap: wrap; +} + +.week-cell{ + font-family: 'Myriadpro-SemiBold'; +} +.week-cell, +.day-cell { + flex: 0 0 calc(100% / 7 - 10px); + display: flex; + justify-content: center; + align-items: center; + height: 40px; + width: 40px; + cursor: pointer; + margin: 5px; +} + +.day-cell.active{ + background: #fff; + border: 2px solid #00A79D!important; + border-radius: 25px!important; + color: #404041!important; +} + +.img-check-calendar{ + display: none; + position: absolute; + top: 0; + right: -4px; +} + +.day-cell.complete .img-check-calendar{ + display: block; + +} + + +.img-missing-calendar{ + display: none; + position: absolute; + top: 9px; + right: 1px; +} + +.day-cell.missing .img-missing-calendar{ + display: block; +} +.day-cell.complete .img-missing-calendar{ + display: none; +} +.day-cell.active_date .img-missing-calendar{ + display: none; +} +.day-cell.today .img-missing-calendar{ + display: none; +} + +.img-active_dot-calendar{ + display: none; + position: absolute; + top: 0px; + right: -5px; +} + +.day-cell.missing .img-active_dot-calendar{ + display: none; +} +.day-cell.complete .img-active_dot-calendar{ + display: none; +} +.day-cell.active_date .img-active_dot-calendar{ + display: block; +} +.day-cell.today .img-active_dot-calendar{ + display: none; +} + +.day-cell.today{ + border: none!important; +} + +.day-cell { + &--faded { + opacity: .4; + } + + &--today { + border-radius: 25px; + background-image: linear-gradient(to right, #00e1a0 , #00b9b7)!important; + color: #fff!important; + border: none; + } +} +.lichngay-teacher .week-cell,.lichngay-teacher .day-cell { + flex-basis: calc(100% / 7 - 36px); + margin: 5px 0px; +} +.hide_collapse{ + display : none; +} +.fullHeight .hide_collapse{ + display : flex; +} +@media screen and (max-height: 800px) { + .img-check-calendar { + top: -4px; + right: -2px; + } + .box-40-40.lichngay-teacher .day-cell { + flex-basis: calc(100% / 7 - 24px); + margin: 5px 0px; + } + .hide_collapse { + display: none; + } +} +@media screen and (max-height: 700px) { + .calendar { + // width: 258px; + margin: 0 auto; + box-shadow: 2px 3px 4px 0 rgba(21, 27, 38, .15); + border-radius: 6px; + } + .week-cell, + .day-cell { + font-size: 14px; + flex: 0 0 calc(100% / 7 - 10px); + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + margin: 5px 0px; + } + .day-cell.missing .img-missing-calendar { + display: block; + width: 7px; + } + .img-missing-calendar { + display: none; + position: absolute; + top: 2px; + right: -3px; + } + .img-check-calendar { + top: -4px; + right: -4px; + } + .box-40-40.lichngay-teacher .day-cell { + flex-basis: calc(100% / 7 - 27px); + margin: 5px 0px; + } + .hide_collapse { + display: none; + } + + .homePageTeacherCalendaSchedule { + margin: 0 !important + } +} \ No newline at end of file diff --git a/src/_components/Chart/Doughnut.js b/src/_components/Chart/Doughnut.js new file mode 100644 index 0000000..a6bb74d --- /dev/null +++ b/src/_components/Chart/Doughnut.js @@ -0,0 +1,34 @@ +import React from 'react'; +import { Doughnut } from 'react-chartjs-2'; + +function ChartDoughnut(props) { + let { report_data, position, display_legend } = props; + if (display_legend === undefined) { + display_legend = true; + } + const options = { + legend: { + display: display_legend, + position: position, + labels: { + fontColor: '#000', + boxWidth: 20, + padding: 10, + }, + onClick: (e) => e.stopPropagation() + }, + responsive: true, + maintainAspectRatio: true, + elements: { + arc: { + borderWidth: 0 + } + }, + }; + + return ( + + ); +} + +export { ChartDoughnut }; \ No newline at end of file diff --git a/src/_components/Chart/index.js b/src/_components/Chart/index.js new file mode 100644 index 0000000..d4b3ef9 --- /dev/null +++ b/src/_components/Chart/index.js @@ -0,0 +1 @@ +export * from './Doughnut'; \ No newline at end of file diff --git a/src/_components/ContentBanner/ContentBanner.jsx b/src/_components/ContentBanner/ContentBanner.jsx new file mode 100644 index 0000000..bd9e686 --- /dev/null +++ b/src/_components/ContentBanner/ContentBanner.jsx @@ -0,0 +1,75 @@ +import "./ContentBanner.style.scss"; +const ContentBanner = (props) => { + let { typeBanner, bgBannerProps, classBgProps, dataImageSlide } = props; + + return ( +
    +
    +
    + Img Phone + +
    + +
    +
    + Icon Sliding Left +
    {" "} +
    + Icon Sliding Center +
    +
    + Icon Sliding Right +
    +
    + +
    + Icon Sliding Center +
    +
    +
    + ); +}; + +export default ContentBanner; diff --git a/src/_components/ContentBanner/ContentBanner.style.scss b/src/_components/ContentBanner/ContentBanner.style.scss new file mode 100644 index 0000000..fc21ee5 --- /dev/null +++ b/src/_components/ContentBanner/ContentBanner.style.scss @@ -0,0 +1,167 @@ +@import "/src/_styles/mixin"; + +.content_banner_container { + width: 100%; + margin: 7rem 0 0; + background-color: var(--bg-light-blue-color); + z-index: 3; + + @include screen_mobile { + background-color: var(--white-color) !important; + } + .content_bg_banner { + margin: 3rem 0 3rem -1rem; + width: 100%; + height: 100%; + // min-height: 60rem; + display: flex; + align-items: center; + justify-content: center; + + @include screen_mobile { + margin-left: 0; + } + + .img_banner_3 { + // max-height: 85%; + // max-width: 30%; + // object-fit: contain; + // // width: 16vw; + // height: 35rem; + // // overflow: hidden; + // width: 17rem; + + // @include screen_mobile { + // // max-width: 60%; + // width: 85vw; + // min-width: 15rem; + // height: 45rem; + // // overflow: hidden; + // } + // margin-left: 1rem; + + .mySwiper { + // width: 98%; + width: 13.9vw; + // margin-top: 0.7vw; + border-radius: 1rem; + min-width: 12.5rem; + // margin-left: 0.2vw; + + @include screen_mobile { + width: 45vw; + min-width: 20rem; + } + } + + .item_slide_banner { + max-height: 32rem; + // margin-bottom: 0.5vw; + width: 100%; + border-radius: 1rem; + padding-left: 0.4vw; + @include screen_mobile { + max-height: 50rem; + height: 42.3rem; + } + } + .img_phone { + position: absolute; + z-index: 1; + // width: 16vw; + height: 35rem; + // overflow: hidden; + width: 17rem; + object-fit: contain; + + @include screen_mobile { + // max-width: 60%; + width: 85vw; + min-width: 15rem; + height: 49rem; + } + } + + // Video + .video_banner_container { + z-index: -1; + // width: 16vw; + height: 33.8rem; + // overflow: hidden; + // margin: 0 1rem; + width: 17rem; + border-radius: 3.3rem; + object-fit: contain; + + @include screen_mobile { + // max-width: 60%; + width: 85vw; + min-width: 15rem; + height: 49rem; + } + } + } + + .icon_left_sliding_container { + position: absolute; + left: 0; + top: 20%; + z-index: -1; + img { + width: 7vw; + min-width: 6rem; + } + } + .icon_center_sliding_container { + position: absolute; + // left: 34.5vw; + // left: 50%; + // right: 50%; + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; + text-align: center; + top: 15%; + z-index: -2; + padding-left: 3%; + img { + width: 33vw; + min-width: 28rem; + } + } + .icon_right_sliding_container { + position: absolute; + right: 5%; + bottom: 5rem; + z-index: -1; + img { + width: 7vw; + min-width: 6rem; + } + } + + // Mobile + .icon_center_sliding_container_mobile { + @include screen_mobile { + position: absolute; + // left: 34.5vw; + // left: 50%; + // right: 50%; + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; + text-align: center; + top: 5%; + z-index: -2; + // padding-left: 3%; + img { + width: 100vw; + // min-width: 28rem; + // height: 30rem; + } + } + } + } +} diff --git a/src/_components/ContentBanner/ContentBanner_Swiper.jsx b/src/_components/ContentBanner/ContentBanner_Swiper.jsx new file mode 100644 index 0000000..1a5f111 --- /dev/null +++ b/src/_components/ContentBanner/ContentBanner_Swiper.jsx @@ -0,0 +1,11 @@ +import "./ContentBanner.style.scss"; + +const ContentBanner = (props) => { + let { typeBanner, bgBannerProps, classBgProps, dataImageSlide } = props; + + return ( +
    + ); +}; + +export default ContentBanner; diff --git a/src/_components/ContentBanner/VideoBanner.jsx b/src/_components/ContentBanner/VideoBanner.jsx new file mode 100644 index 0000000..dee3a09 --- /dev/null +++ b/src/_components/ContentBanner/VideoBanner.jsx @@ -0,0 +1,19 @@ +import "./VideoBanner.style.scss"; + +const VideoBanner = (props) => { + return ( +
    +
    +
    +
    + ); +}; + +export default VideoBanner; diff --git a/src/_components/ContentBanner/VideoBanner.style.scss b/src/_components/ContentBanner/VideoBanner.style.scss new file mode 100644 index 0000000..097d4f0 --- /dev/null +++ b/src/_components/ContentBanner/VideoBanner.style.scss @@ -0,0 +1,71 @@ +@import "/src/_styles/mixin"; + +.video_banner_container { + .video_banner { + width: 13.9vw; + // margin-top: 0.7vw; + min-width: 19.5rem; + @include screen_mobile { + width: 60vw; + min-width: 17rem; + } + } + .icon_left_sliding_container { + position: absolute; + left: 0; + top: 20%; + // z-index: -1; + img { + width: 7vw; + min-width: 11rem; + } + } + .icon_center_sliding_container { + position: absolute; + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; + text-align: center; + top: 15%; + // z-index: -1; + padding-left: 4%; + img { + width: 28vw; + min-width: 32rem; + } + } + .icon_right_sliding_container { + position: absolute; + right: 5%; + bottom: 5rem; + // z-index: -1; + img { + width: 7vw; + min-width: 9rem; + } + } + + // Mobile + .icon_center_sliding_container_mobile { + @include screen_mobile { + position: absolute; + // left: 34.5vw; + // left: 50%; + // right: 50%; + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; + text-align: center; + top: 10%; + // z-index: -1; + // padding-left: 3%; + img { + width: 100vw; + // min-width: 28rem; + // height: 30rem; + } + } + } +} diff --git a/src/_components/CustomBarRange/CustomBarRange.jsx b/src/_components/CustomBarRange/CustomBarRange.jsx new file mode 100644 index 0000000..65b2f89 --- /dev/null +++ b/src/_components/CustomBarRange/CustomBarRange.jsx @@ -0,0 +1,76 @@ +import { customBarLogic } from "./CustomBarRange.logic"; +import { convertTitleAssign, vietsubSkillName } from "../../_base/Validate"; +import "./CustomBarRange.style.scss"; +import { useSelector } from "react-redux"; + +const CustomBarRange = (props) => { + let { study_data_item, setMovePercent, currUnit, totalUnit, levelSkills, isLostRoot } = + props; + let { handleTimeDrag } = customBarLogic(props); + + const exercises = useSelector((state) => state.classes.exercises); + + if(study_data_item && levelSkills) { + + study_data_item.list_skill_en = levelSkills?.filter( + (item) => + item?.level?.toLocaleLowerCase() == + convertTitleAssign(study_data_item?.stand).toLocaleLowerCase() + ); + } + + const curPercentage = (study_data_item?.practice_percent / 100) * 100; + + const renderLevelSkill = (data, index) => { + return ( +
    + {vietsubSkillName(data?.skill?.toLocaleLowerCase())} +
    + ); + }; + + return ( +
    + {!isLostRoot &&
    + Trình độ {convertTitleAssign(study_data_item?.stand)} +
    } + + {Array.isArray(exercises?.students) && + exercises?.students.length == 1 && ( +
    + {study_data_item?.list_skill_en?.map((data, index) => + renderLevelSkill(data, index) + )} +
    + )} +
    handleTimeDrag(e)} + > + +
    + +
    +
    + Ôn luyện {`(${study_data_item?.practice_percent}%)`} +
    + +
    + Kiến thức mới{" "} + {`(${100 - parseInt(study_data_item?.practice_percent)}%)`} +
    +
    +
    + ); +}; + +export default CustomBarRange; diff --git a/src/_components/CustomBarRange/CustomBarRange.logic.js b/src/_components/CustomBarRange/CustomBarRange.logic.js new file mode 100644 index 0000000..f71252e --- /dev/null +++ b/src/_components/CustomBarRange/CustomBarRange.logic.js @@ -0,0 +1,34 @@ +export const customBarLogic = (props) => { + function calcClickedTime(e) { + const clickPositionInPage = e.pageX; + const bar = document.querySelector(".bar__progress"); + const barStart = bar?.getBoundingClientRect().left + window.scrollX; + const barWidth = bar.offsetWidth; + const clickPositionInBar = clickPositionInPage - barStart; + const timePerPixel = 100 / barWidth; + + let draggedPercentage = Math.round(timePerPixel * clickPositionInBar); + + const snappedPercentage = Math.round(draggedPercentage / 10) * 10; + + // Ensure the snapped value is within the 0-100 range + const finalPercentage = Math.max(0, Math.min(100, snappedPercentage)); + + return draggedPercentage; + } + + const handleTimeDrag = (e) => { + if (props.currUnit != props.totalUnit) { + props.setMovePercent(calcClickedTime(e)); + const updateTimeOnMove = (eMove) => { + props.setMovePercent(calcClickedTime(eMove)); + }; + document.addEventListener("mousemove", updateTimeOnMove); + document.addEventListener("mouseup", () => { + document.removeEventListener("mousemove", updateTimeOnMove); + }); + } + }; + + return { handleTimeDrag }; +}; diff --git a/src/_components/CustomBarRange/CustomBarRange.style.scss b/src/_components/CustomBarRange/CustomBarRange.style.scss new file mode 100644 index 0000000..85f23b6 --- /dev/null +++ b/src/_components/CustomBarRange/CustomBarRange.style.scss @@ -0,0 +1,30 @@ +.bar_range { + padding: 1.15rem 0rem 0rem; + + .bar__progress { + // flex: 1; + // margin: 0 20px; + height: 1rem; + display: flex; + align-items: center; + cursor: pointer; + border-radius: 1.5rem; + position: relative; + + .bar__progress__knob { + position: absolute; + height: 1.6875rem; + width: 1.6875rem; + border: 1.5px solid #ffdb5a; + border-radius: 50%; + background-color: var(--white-color); + } + } + + .skill_item { + background-color: #e8e8e8; + border-radius: 1.2rem; + padding: 0.13rem 0.7rem; + margin-right: 1.3%; + } +} diff --git a/src/_components/Divider/Divider.jsx b/src/_components/Divider/Divider.jsx new file mode 100644 index 0000000..6fe401f --- /dev/null +++ b/src/_components/Divider/Divider.jsx @@ -0,0 +1,11 @@ +import "./Divider.style.scss"; + +const Divider = (props) => { + return ( +
    +
    +
    + ); +}; + +export default Divider; diff --git a/src/_components/Divider/Divider.style.scss b/src/_components/Divider/Divider.style.scss new file mode 100644 index 0000000..dc4fc06 --- /dev/null +++ b/src/_components/Divider/Divider.style.scss @@ -0,0 +1,11 @@ +.divider_mobile_container { + width: 100%; + padding: 4rem 0; + + .divider_mobile { + height: 0.6rem; + border-radius: 1rem; + background-color: var(--primary-green); + width: 60%; + } +} diff --git a/src/_components/FooterNews/FooterAuth.jsx b/src/_components/FooterNews/FooterAuth.jsx new file mode 100644 index 0000000..b54e690 --- /dev/null +++ b/src/_components/FooterNews/FooterAuth.jsx @@ -0,0 +1,38 @@ +import { HashLink } from "react-router-hash-link"; +import { TypeHeaderNewsItem } from "../../_constants/headerNews"; +import "./FooterAuth.style.scss"; + +const FooterAuth = () => { + return ( +
    +
    + + Điều khoản và Điều kiện + + + Liên hệ với chúng tôi + +
    + +
    +
    + SUNDAY ENGLISH +
    + +
    + Copyright @ 2007-2023 GK Corp. All Rights Reserved +
    +
    +
    + ); +}; + +export default FooterAuth; diff --git a/src/_components/FooterNews/FooterAuth.style.scss b/src/_components/FooterNews/FooterAuth.style.scss new file mode 100644 index 0000000..1196d44 --- /dev/null +++ b/src/_components/FooterNews/FooterAuth.style.scss @@ -0,0 +1,21 @@ +@import "/src/_styles/mixin"; + +.footer_auth_container { + padding-bottom: 2rem; + @include screen_mobile { + flex-direction: column; + // padding-bottom: 1rem; + padding-top: 7vh; + padding-bottom: 0; + } + + .footer_auth_first { + @include screen_mobile { + width: 100% !important; + display: flex; + flex-direction: column; + align-items: center; + padding-bottom: 0.5rem; + } + } +} diff --git a/src/_components/FooterNews/FooterNews.jsx b/src/_components/FooterNews/FooterNews.jsx new file mode 100644 index 0000000..99f6210 --- /dev/null +++ b/src/_components/FooterNews/FooterNews.jsx @@ -0,0 +1,437 @@ +import "./FooterNews.style.scss"; +import { footerLogic } from "./FooterNews.logic"; +import { Link } from "react-router-dom"; +import { HashLink } from "react-router-hash-link"; +import classNames from "classnames"; +import { TypeHeaderNewsItem } from "../../_constants/headerNews"; +import { FooterSelection } from "../../_constants/footerSelection"; +import { LinkApp } from "../../_constants/linkDownloadApp"; +import { hasDomainStore } from "../../_base/Validate"; +import LazyLoad from "react-lazyload"; +import { handleNavigateCurriculumDownload } from "../../_base/FunctionBase"; +import { Fragment } from "react"; +import { history } from "../../_helpers"; +import {Mydata} from '../../_base/Mydata' + +const FooterNews = (props) => { + let { + dataFooterMobile, + dataSupport, + dataCourses, + dataBuyCoursesTeacher, + dataBuyCourses, + dataPolicy, + dataTariff, + handleNavigateFooter, + handleOpenOption, + isOpen, + dataInforDownload, + handleOpenLinkApp, + } = footerLogic(props); + + const renderFooterItem = (item, type) => { + return ( + + {item.typeStore == "store" && hasDomainStore() ? null : ( + { + if(type === FooterSelection.POLICY) { + window.scrollTo({top: 0, behavior: 'instant'}) + } else { + ele.scrollIntoView({ behavior: "instant" }) + } + }} + elementId={item?.eleId} + key={item.id} + to={`/${item?.href}`} + onClick={() => { + item?.href?.includes("faq") && + localStorage.removeItem("categoryFAQ"); + }} + className={`mg-vertical-0-5 pd-left-4per color_hover color-light-black footer_detail_item fz-08-mobile mg-bottom-0-5 animation_slidein_top ${ + isOpen == type ? "display_flex_mobile" : "display_none_mobile" + } ${type == FooterSelection.POLICY && " mg-bottom-1-mobile"}`} + > + {item.name} + + )} + + ); + }; + const renderFooterItemMobile = (item, type) => { + return ( + ele.scrollIntoView({ behavior: "instant" })} + key={item.id} + to={`/${item?.href + "_mb"}`} + className={`mg-vertical-0-5 pd-left-4per color_hover color-light-black fz-08 mg-bottom-0-5 animation_slidein_top ${ + isOpen == type ? "display_flex_mobile" : "display_none_mobile" + } ${type == FooterSelection.POLICY && " mg-bottom-1-mobile"}`} + > + {item.name} + + ); + }; + + const renderListFooter = (item, type) => { + return ( +
    +
    {item.name}
    + +
    + {item.data.map((item) => renderFooterItem(item, type))} +
    +
    + ); + }; + + // Render Ico Download + const renderInforDownload = (item) => { + return ( +
    +
    + Icon Tick + {item.title} +
    + +
    +
    + handleNavigateCurriculumDownload( + item.type == "teacher" + ? "teacher" + : item.type == "parent" + ? "parent" + : "student" + ) + } + className="icon_qr flex-center" + style={{ + cursor: "pointer", + }} + > + Icon Logo SE +
    + +
    +
    + Icon App Store + handleOpenLinkApp(LinkApp[`${item.type}`].APP_STORE) + } + /> +
    + +
    + Icon GG Play + handleOpenLinkApp(LinkApp[`${item.type}`].GG_PLAY) + } + /> +
    +
    +
    +
    + ); + }; + + return ( +
    +
    +
    +
    + {/*
    +
    handleOpenOption(FooterSelection.INTRODUCTION)} + className={`font_news_bold flex-jus-between-mobile mg-bottom-0-mobile title_footer_container mg-bottom-0-7 ${ + isOpen == FooterSelection.INTRODUCTION + ? " font_news_bold_mobile" + : "font_news_mobile" + }`} + // style={{ + // fontWeight: isOpen == FooterSelection.INTRODUCTION && "700", + // }} + > + ele.scrollIntoView({ behavior: "instant" })} + to={`/${TypeHeaderNewsItem.INTRODUCTION}`} + className={`font_news_bold title_footer ${ + isOpen == FooterSelection.INTRODUCTION + ? " font_news_bold_mobile" + : " font_news_mobile" + }`} + > + Giới thiệu + +
    + + + +
    +
    +
    handleNavigateFooter("introduction/#about")} + > + ele.scrollIntoView({ behavior: "instant" })} + to="/introduction/#about" + > +
    + Về Sunday English +
    +
    +
    + +
    + ele.scrollIntoView({ behavior: "instant" })} + to="/introduction/#our_missions" + > +
    + Sứ mệnh của chúng tôi +
    +
    +
    +
    */} + +
    +
    +
    + {/*
    + Icon Message + +
    + + Gửi tin nhắn + +
    +
    */} +
    + Liên hệ +
    +
    +
    + Icon Phone + +
    + {/*
    + Hotline +
    */} + + 0762 007 298 + +
    +
    +
    +
    +
    + Icon Mail + +
    + {/*
    + Email +
    */} + + support@sundayenglish.com + +
    +
    + +
    + + +
    + + {props?.type != "download" && ( +
    + {dataInforDownload.map((item) => renderInforDownload(item))} +
    + )} +
    +
    +
    + +
    +
    + Công ty Cổ phần Công nghệ Giáo dục GK +
    + {/*
    + MST:00000000 do Sở KH và ĐT TP.Hà Nội cấp ngày 00/00/0000 +
    +
    + Người đại diện: Ông Ngô Viết Tuấn +
    */} +
    + Tầng 5, Tòa nhà 141 Hoàng Quốc Việt, phường Nghĩa Đô, quận Cầu + Giấy, Tp. Hà Nội, Việt Nam. +
    +
    +
    + +
    + + +
    + {dataInforDownload.map((item) => renderInforDownload(item))} +
    + +
    + + Image Bo Cong Thuong + +
    +
    +
    + +
    + Image Bo Cong Thuong +
    +
    + Copyright @ 2007-2023 GK Corp. All Rights Reserved + {/*
    {Mydata.version}
    */} +
    +
    + ); +}; + +export default FooterNews; diff --git a/src/_components/FooterNews/FooterNews.logic.js b/src/_components/FooterNews/FooterNews.logic.js new file mode 100644 index 0000000..df3494e --- /dev/null +++ b/src/_components/FooterNews/FooterNews.logic.js @@ -0,0 +1,275 @@ +import { useState } from "react"; +import { useHistory } from "react-router-dom"; +import { FooterSelection } from "../../_constants/footerSelection"; +import { TypeHeaderNewsItem } from "../../_constants/headerNews"; +import { id } from "date-fns/locale"; + +export const footerLogic = (props) => { + const _history = useHistory(); + const [isOpen, setIsOpen] = useState(""); + + // DATA COURSES + + // const [dataCourses, setDataCourses] = useState([ + // { + // id: 1, + // name: "Mất gốc", + // data: [ + // { + // id: 1, + // name: "Tiếng Anh lớp 6", + // href: `${TypeHeaderNewsItem.COURSES}/#unknown_06`, + // }, + // { + // id: 2, + // name: "Tiếng Anh lớp 7", + // href: `${TypeHeaderNewsItem.COURSES}/#unknown_07`, + // }, + // { + // id: 3, + // name: "Tiếng Anh lớp 8", + // href: `${TypeHeaderNewsItem.COURSES}/#unknown_08`, + // }, + // { + // id: 4, + // name: "Tiếng Anh lớp 9", + // href: `${TypeHeaderNewsItem.COURSES}/#unknown_09`, + // }, + // ], + // }, + // { + // id: 2, + // name: "Cơ bản", + // data: [ + // { + // id: 1, + // name: "Tiếng Anh lớp 6", + // href: `${TypeHeaderNewsItem.COURSES}/#basic_06`, + // }, + // { + // id: 2, + // name: "Tiếng Anh lớp 7", + // href: `${TypeHeaderNewsItem.COURSES}/#basic_07`, + // }, + // { + // id: 3, + // name: "Tiếng Anh lớp 8", + // href: `${TypeHeaderNewsItem.COURSES}/#basic_08`, + // }, + // { + // id: 4, + // name: "Tiếng Anh lớp 9", + // href: `${TypeHeaderNewsItem.COURSES}/#basic_09`, + // }, + // ], + // }, + // ]); + + const [dataFooterMobile] = useState([ + { + id: 1, + name: 'Khóa học', + href: '/courses' + }, + { + id: 2, + name: 'Phụ huynh', + href: '/parent_news' + }, + { + id: 3, + name: 'Giáo viên', + href: '/teacher_news' + }, + { + id: 4, + name: 'Luyện thi', + href: '/mock_test' + } + ]) + + const [dataCourses, setDataCourses] = useState([ + { + id: 1, + name: "Hội nhập", + href: `${TypeHeaderNewsItem.COURSES}/#integrate`, + eleId: "#integrate", + }, + { + id: 2, + name: "Nâng cao năng lực", + href: `${TypeHeaderNewsItem.COURSES}/#advanced`, + eleId: "#advanced", + }, + ]); + + const [dataBuyCourses, setDataBuyCourses] = useState([ + { + id: 1, + name: "Gói Pro", + href: `${TypeHeaderNewsItem.FEE}/#list_packages`, + eleId: "#list_packages", + }, + { + id: 2, + name: "Gói Plus", + href: `${TypeHeaderNewsItem.FEE}/#list_packages`, + eleId: "#list_packages", + }, + { + id: 3, + name: "Gói Premium", + href: `${TypeHeaderNewsItem.FEE}/#list_packages`, + eleId: "#list_packages", + }, + ]); + + const [dataBuyCoursesTeacher, setDataBuyCoursesTeacher] = useState([ + { + id: 1, + name: "Gói Silver", + href: `${TypeHeaderNewsItem.TARIFF}/#list_packages`, + eleId: "#list_packages", + }, + { + id: 2, + name: "Gói Gold", + href: `${TypeHeaderNewsItem.TARIFF}/#list_packages`, + eleId: "#list_packages", + }, + { + id: 3, + name: "Gói Diamond", + href: `${TypeHeaderNewsItem.TARIFF}/#list_packages`, + eleId: "#list_packages", + }, + ]); + + // Data Tariff + const dataTariff = [ + { + id: 1, + name: "Dành cho học sinh", + href: `${TypeHeaderNewsItem.FEE}/#list_packages`, + eleId: "list_packages", + }, + { + id: 2, + name: "Dành cho giáo viên", + href: `${TypeHeaderNewsItem.TARIFF}/#list_packages`, + eleId: "list_packages", + }, + ]; + + // Data Support + + const dataSupport = [ + { + id: 1, + name: "Kích hoạt tài khoản", + href: "account_activation/#", + }, + { + id: 2, + name: "Hỗ trợ khách hàng", + href: `faq/#faq`, + }, + { + id: 3, + name: "Câu hỏi thường gặp", + href: `faq/#faq`, + }, + { + id: 4, + name: "Hướng dẫn thanh toán", + href: `${TypeHeaderNewsItem.FEE}/policy/#policy_payment`, + typeStore: "store", + eleId: "policy_payment", + }, + ]; + + // Data Policy + const dataPolicy = [ + { + id: 1, + name: "Điều khoản sử dụng", + href: `${TypeHeaderNewsItem.POLICY}/#term`, + eleId: "term", + }, + { + id: 2, + name: "Chính sách bảo vệ và xử lý dữ liệu cá nhân", + href: `${TypeHeaderNewsItem.POLICY}/#security`, + eleId: "security", + }, + { + id: 3, + name: "Chính sách về bản quyền và sở hữu trí tuệ", + href: `${TypeHeaderNewsItem.POLICY}/#license`, + eleId: "license", + }, + { + id: 4, + name: "Chính sách thanh toán", + href: `${TypeHeaderNewsItem.POLICY}/#payment`, + eleId: "payment", + }, + ]; + + const handleNavigateFooter = (href) => {}; + + const handleOpenOption = (type) => { + if (isOpen != type) { + // console.log(type); + setIsOpen(type); + } else { + setIsOpen(""); + } + }; + + // Data Infor download + const dataInforDownload = [ + { + id: 1, + title: "Tải app dành cho học sinh", + linkAppStore: "#", + linkGGPlay: "#", + type: "student", + // href: + }, + { + id: 2, + title: "Tải app dành cho giáo viên", + linkAppStore: "#", + linkGGPlay: "#", + type: "teacher", + }, + { + id: 3, + title: "Tải app dành cho phụ huynh", + linkAppStore: "#", + linkGGPlay: "#", + type: "parent", + }, + ]; + + // Handle Click Link App + const handleOpenLinkApp = (link) => { + window.open(link, "_blank"); + }; + + return { + dataFooterMobile, + dataCourses, + dataSupport, + dataBuyCourses, + dataPolicy, + isOpen, + dataInforDownload, + dataBuyCoursesTeacher, + dataTariff, + handleNavigateFooter, + handleOpenOption, + handleOpenLinkApp, + }; +}; diff --git a/src/_components/FooterNews/FooterNews.style.scss b/src/_components/FooterNews/FooterNews.style.scss new file mode 100644 index 0000000..2a4f0b9 --- /dev/null +++ b/src/_components/FooterNews/FooterNews.style.scss @@ -0,0 +1,358 @@ +@import "/src/_styles/mixin"; + +.footer_wrapper { + padding: 3rem 0rem 2rem; + background-color: var(--light-gray-color); + + @include screen_mobile { + background-color: var(--white-color); + padding-top: 0; + } + .footer_container { + display: flex; + padding-bottom: 6.5rem; + width: 100%; + justify-content: space-between; + padding-left: clamp(2%, 4.2vw, 6%); + padding-right: clamp(2%, 4.2vw, 6%); + + @include screen_mobile { + flex-direction: column-reverse; + padding-bottom: 2.5rem; + padding-left: 0; + padding-right: 0; + } + + .footer_left_container { + max-width: 30%; + width: 30%; + } + + .footer_left_container, + .footer_right_container { + @include screen_mobile { + width: 100% !important; + max-width: 100% !important; + margin: 0; + } + } + + .footer_right_container { + width: 70%; + max-width: 100rem; + margin: 0 auto; + // margin-left: clamp(1%, 11vw, 15%); + @include screen_mobile { + flex-direction: column; + margin-left: 0; + } + + .footer_right_item { + // margin-left: 2%; + @include screen_mobile { + width: 100% !important; + max-width: 100% !important; + margin: 0; + } + } + } + + .title_footer_container { + @include screen_mobile { + border-top: 1px solid #e6e6e6; + margin: 0; + padding: 0.7rem 0; + cursor: pointer; + padding-left: 4%; + padding-right: 3%; + } + } + .title_footer { + font-size: clamp(1rem, 1.6vw, 1.4rem); + + @include screen_mobile { + font-size: 0.95rem; + } + } + + .footer_intro_modal { + @include screen_mobile { + animation: slideTopIn linear 0.3s; + } + } + + .margin_horizontal { + margin: 0 1.5rem; + } + + .footer_contact_box { + // border: 1px solid var(--border-color); + padding: 0.23rem 0; + border-radius: 0.4rem; + max-width: 19rem; + width: 100%; + + @include screen_mobile { + max-width: 96%; + width: 96%; + // max-width: 60%; + // justify-content: center; + } + .icon_contact { + width: 1.5rem; + height: auto; + + @include screen_mobile { + width: 1.8rem; + } + } + } + + .footer_email_contact { + @include screen_mobile { + width: auto; + max-width: auto; + } + } + + .footer_social_container { + align-items: flex-end; + justify-content: space-between; + padding: 1.2rem 0; + // padding-right: clamp(0.5rem, 5vw, 1rem); + // padding-left: clamp(2rem, 4.2vw, 5.5rem); + margin-top: 2rem; + // border: 1px solid var(--border-color); + border-radius: 0.5rem; + @include screen_mobile { + // flex-direction: row-reverse; + justify-content: flex-end !important; + align-items: flex-start; + margin: 0 !important; + padding: 0.5rem 0 2rem; + border: none; + padding-top: 1.75rem; + } + + .item_infor_download { + padding-right: clamp(2.3rem, 5.5vw, 7rem); + + &:last-child { + padding-right: 0.5rem; + margin-right: clamp(-3rem, 4.5vw, -6rem); + + @include screen_tablet { + margin-right: clamp(-0.5rem, 20vw, -6rem); + } + + @include screen_mobile { + margin-right: 0; + padding-right: 0; + } + } + @include screen_mobile { + flex-direction: column; + align-items: center; + width: 100%; + // justify-content: space-between !important; + padding-bottom: 1.3rem; + padding-right: 0; + } + + .item_infor_title { + padding-bottom: 1rem; + align-items: flex-start; + + @include screen_mobile { + padding-bottom: 0; + width: 90%; + max-width: 90%; + padding-right: 0.8rem; + align-items: center; + justify-content: center; + margin-bottom: 0.5rem; + } + span { + font-size: clamp(0.75rem, 1.1vw, 0.875rem); + @include screen_mobile { + font-size: clamp(0.7rem, 4vw, 0.875rem); + } + } + + .img_tick_title { + width: 1.2rem; + margin-right: 0.3rem; + margin-top: 0.05rem; + + @include screen_mobile { + width: clamp(0.75rem, 4vw, 0.9375rem); + } + } + } + + .img_download_container { + // padding: 0 1rem 0.8rem; + justify-content: flex-start; + @include screen_mobile { + // width: 60%; + // max-width: 60%; + // padding: 0 0 0.8rem 0; + // max-height: 90%; + margin: 0 0.5rem; + // width: 90%; + // max-width: 90%; + justify-content: center; + } + } + .icon_qr { + // margin-right: 13%; + width: 30%; + height: 100%; + min-height: 100%; + max-width: 10rem; + min-width: 30%; + + @include screen_mobile { + margin-right: 4%; + width: 11.5%; + max-width: 3.3rem; + min-width: 11.5%; + } + + img { + object-fit: contain; + width: 100%; + max-width: 100%; + + @include screen_mobile { + max-width: 3rem; + } + } + } + + .footer_app_download_container { + display: flex; + justify-content: space-between; + flex-direction: column; + // width: 65%; + max-width: 65%; + @include screen_mobile { + flex-direction: row; + align-items: center; + justify-content: space-between; + width: 100%; + max-width: 100%; + } + .img_app_download_container { + max-width: 96%; + @include screen_mobile { + width: 100%; + max-width: 100%; + } + } + .img_app_download { + // height: 1.6rem; + // min-height: 1.6rem; + width: 65%; + max-width: 13rem; + + @include screen_mobile { + margin: 0 !important; + width: 90%; + max-height: 90%; + max-width: 10rem; + } + } + } + } + } + .footer_email_social { + @include screen_mobile { + flex-wrap: wrap; + margin-bottom: 0.5rem !important; + } + } + .icon_social_container { + padding-bottom: 1.5rem; + @include screen_mobile { + min-width: 28%; + justify-content: center; + // max-width: 100%; + // width: 100%; + // padding-right: 3%; + // min-width: 3rem; + margin-bottom: 0.2rem; + padding-bottom: 0; + } + .icon_social { + cursor: pointer; + width: 4.4rem; + height: auto; + -webkit-transition: all ease-out 0.3s; + transition: all ease-out 0.3s; + -webkit-transform: scale(1); + transform: scale(1); + margin-right: 0.5rem; + + @include screen_mobile { + width: 3.2rem; + min-width: 2rem; + margin-right: 0; + } + + &:hover { + -webkit-transition: all ease-out 0.3s; + transition: all ease-out 0.3s; + -webkit-transform: scale(1.3); + transform: scale(1.3); + } + } + } + + .list_option_right { + @include screen_mobile { + min-width: 50%; + margin-bottom: 1rem; + } + } + + .footer_1_tail { + padding-top: 1.1rem; + border-top: 1px solid var(--border-color); + + @include screen_mobile { + border-bottom: 1px solid var(--border-color); + padding-bottom: 1.5rem; + } + } + + .text_title_contact { + font-size: clamp(1rem, 1.6vw, 1.4rem); + } + + .text_phone_number { + font-size: clamp(0.95rem, 1.3vw, 1.125rem) !important; + } + + .text_email { + font-size: clamp(0.95rem, 1.3vw, 1.125rem) !important; + } + + .footer_detail_item { + font-size: clamp(0.8rem, 0.8vw, 0.875rem); + } + } + .img_bct { + @include screen_mobile { + width: clamp(9rem, 45vw, 11rem); + height: auto; + padding-bottom: 2rem; + } + } + + .text_license { + @include screen_mobile { + padding: 0 1rem; + } + } +} diff --git a/src/_components/GlobalStyles/GlobalStyles.scss b/src/_components/GlobalStyles/GlobalStyles.scss new file mode 100644 index 0000000..7185d40 --- /dev/null +++ b/src/_components/GlobalStyles/GlobalStyles.scss @@ -0,0 +1,1644 @@ +@import "/src/_styles/mixin"; + +:root { + --white-color: #fff; + --light-red-color: #eb5757; + --primary-green: #00cc83; + --light-black: rgba(0, 0, 0, 0.7); + --light-gray-color: #f5f5f5; + --border-color: #c4c4c4; + --text-color: #4d4d4d; + --bg-light-blue-color: #e7fbf8; + --text-hover-color: #00b9b7; + --text-hover-color-dark: #039390; + --bg-course-color: #cff6f1; + --black-color: #000; + --light-yellow: #fdcd04; + --title-assign-color: #00beb4; + --gray-color: #bcbec0; + --light-border-color: #d9d9d9; + --linear-color: linear-gradient(270deg, #00e2a0 0%, #00b9b7 100%); +} + +a { + text-decoration: none; + color: black; +} + +img { + user-select: none; +} + +.display_flex { + display: flex; +} + +.flex-between { + display: flex; + justify-content: space-between; +} + +.flex-align-end { + display: flex; + align-items: flex-end; +} + +.flex-align-start { + display: flex; + align-items: flex-start; +} + +.flex-jus-around { + display: flex; + align-items: center; + justify-content: space-around; +} + +.flex-jus-between { + display: flex; + align-items: center; + justify-content: space-between; +} + +.flex-start-jus-between { + display: flex; + align-items: flex-start; + justify-content: space-between; +} + +.flex-just-center { + display: flex; + justify-content: center; +} + +.flex-jus-end-between { + display: flex; + align-items: flex-end; + justify-content: space-between; +} + +.flex-jus-start-between { + display: flex; + justify-content: space-between; +} + +.flex-jus-start-evenly { + display: flex; + align-items: flex-start; + justify-content: space-evenly; +} + +.flex-jus-evenly { + display: flex; + align-items: center; + justify-content: space-evenly; +} + +.flex-jus-end { + display: flex; + justify-content: flex-end; +} + +.flex-align { + display: flex; + align-items: center; +} + +.flex-self-center { + display: flex; + align-self: center; + justify-self: center; +} + +.flex-center { + display: flex; + align-items: center; + justify-content: center; +} + +.flex-center-important { + display: flex !important; + align-items: center; + justify-content: center; +} + +.flex-start { + display: flex; + align-items: center; + justify-content: flex-start; +} + +.flex-all-start { + display: flex; + align-items: flex-start; + justify-content: flex-start; +} + +.flex-end { + display: flex; + align-items: center; + justify-content: flex-end; +} + +.flex-center-column { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; +} + +.flex-align-end-column { + display: flex; + align-items: flex-end; + justify-content: center; + flex-direction: column; +} + +.flex-align-start-column { + display: flex; + align-items: flex-start; + justify-content: center; + flex-direction: column; +} + +.flex-jus-end-column { + display: flex; + align-items: center; + justify-content: flex-end; + flex-direction: column; +} + +.flex-end-column { + display: flex; + align-items: flex-end; + justify-content: flex-end; + flex-direction: column; +} + +.flex-column { + display: flex; + flex-direction: column; + justify-content: flex-start !important; +} + +.flex-column-start { + display: flex; + flex-direction: column; + justify-content: flex-start !important; +} + +.flex-column-between { + display: flex; + flex-direction: column; + justify-content: space-between !important; +} + +.flex-column-center-cross-axis { + display: flex; + flex-direction: column; + justify-content: center; +} + +.flex-column-jus-center { + display: flex; + flex-direction: column; + justify-content: center; +} + +.commondPage div, +.commondPage span, +.commondPage a, +.commondPage p, +.commondPage strong, +.commondPage input, +.commondPage textarea, +.commondPage th, +.commondPage td, +.commondPage h2, +.header_container div, +.footer_container div, +.footer_container span, +.footer_container a { + font-family: "AvertaStdCY"; + color: var(--text-color); +} + +.commondPage * { + scroll-margin-top: 70px; +} + +.commondPage input::placeholder, +.commondPage textarea::placeholder { + font-family: "AvertaStdCY"; +} + +.selection_assign div, +.selection_assign span, +.selection_assign a { + color: var(--text-color); +} + +.footer_container a:hover { + color: var(--text-hover-color) !important; +} + +.footer_1_tail div, +.footer_1_tail a { + color: var(--light-black); + margin-bottom: 0.4rem; + color: var(--text-color); + + @include screen_mobile { + margin-bottom: 0.5rem; + } +} + +// Font Family +.font_news { + font-family: "AvertaStdCY" !important; +} + +.font_news_black { + font-family: "AvertaStdCY-Black" !important; +} + +.font_news_extra_bold { + font-family: "AvertaStdCY-ExtraBold" !important; +} + +.font_news_semi_bold { + font-family: "AvertaStdCY-SemiBold" !important; +} + +.font_news_italic { + font-family: "AvertaStdCY-Italic" !important; +} + +.font_news_bold { + font-family: "AvertaStdCY-Bold" !important; +} + +.font_myriad_bold { + font-family: "Myriadpro-Bold" !important; + line-height: normal; + position: relative; + font-weight: 700; + top: 0.155rem; +} + +.font_myriad_bold_no_top { + font-family: "Myriadpro-Bold" !important; + line-height: normal; + color: var(--black-color); +} + +.font_myriad_semi_bold { + font-family: "Myriadpro-SemiBold" !important; + line-height: normal; + position: relative; + top: 0.075rem; +} + +.font_myriad_semi_bold_normal { + font-family: "Myriadpro-SemiBold" !important; + line-height: normal; + position: relative; +} + +.font_myriad_light { + font-family: "Myriadpro-Light" !important; + line-height: normal; +} + +// COLORS +.color-linear { + background: -webkit-linear-gradient(#00e2a0 0%, #00b9b7 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} + +.color-red { + color: var(--light-red-color) !important; +} + +.color-light-black { + color: var(--light-black) !important; +} + +.color-primary-green { + color: var(--primary-green) !important; +} + +.color-light-text { + color: var(--border-color) !important; +} + +.color-white { + color: var(--white-color) !important; +} + +.color-text { + color: var(--text-color) !important; + -webkit-text-fill-color: var(--text-color); +} + +.color-black { + color: var(--black-color) !important; +} + +.color-light-blue { + color: var(--text-hover-color) !important; +} + +.color-title-assign { + color: var(--title-assign-color) !important; +} + +.color-gray { + color: var(--gray-color) !important; +} + +.stroke_primary_green { + stroke: #00cc83 !important; +} + +// Font Weight +.font-weight-500 { + font-weight: 500; +} + +.font-weight-700 { + font-weight: 700; +} + +// MARGIN +.mg-vertical-0-5 { + margin: 0.5rem 0 !important; +} + +.mg-horizontal-2 { + margin: 0 2rem !important; +} + +.mg-horizontal-1 { + margin: 0 1rem !important; +} + +.mg-bottom-2 { + margin-bottom: 2rem !important; +} + +.mg-bottom-15 { + margin-bottom: 1.5rem !important; +} + +.mg-bottom-12 { + margin-bottom: 1.2rem; +} + +.mg-bottom-1 { + margin-bottom: 1rem; +} + +.mg-bottom-0-3 { + margin-bottom: 0.3rem; +} + +.mg-bottom-0-5 { + margin-bottom: 0.5rem; +} + +.mg-bottom-0-7 { + margin-bottom: 0.7rem; +} + +.mg-bottom-0-9 { + margin-bottom: 0.9rem; + + @include screen_mobile { + margin-bottom: 0.3rem; + } +} + +.mg-bottom-0-8 { + margin-bottom: 0.8rem; + + @include screen_mobile { + margin-bottom: 0.3rem; + } +} + +.mg-left-0-5 { + margin-left: 0.5rem; +} + +.mg-left-1 { + margin-left: 1rem; +} + +.mg-left-15 { + margin-left: 1.5rem; +} + +.mg-right-0-5 { + margin-right: 0.5rem; +} + +.mg-right-0-75 { + margin-right: 0.75rem; +} + +.mg-right-1 { + margin-right: 1rem; +} + +.mg-right-3per { + margin-right: 3%; +} + +.mg-right-2 { + margin-right: 2rem; +} + +.mg-right-25 { + margin-right: 2.5rem; +} + +.mg-right-5 { + margin-right: 5rem; +} + +.mg-left-2 { + margin-left: 2rem; +} + +.mg-top-1 { + margin-top: 1rem; +} + +.mg-top-0-8 { + margin-top: 0.8rem; + + @include screen_mobile { + margin-top: 0.3rem; + } +} + +.mg-top-0-5 { + margin-top: 0.5rem; +} + +.mg-top-0-75 { + margin-top: 0.75rem; +} + +.mg-top-2 { + margin-top: 2rem; +} + +.mg-top-15 { + margin-top: 1.5rem; +} + +.mg-top-25 { + margin-top: 2.5rem; +} + +.mg-top-25 { + margin-top: 2.5rem; +} + +// Padding +.pd-bottom-0-3 { + padding-bottom: 0.3rem; +} + +.pd-bottom-0-5 { + padding-bottom: 0.5rem; +} + +.pd-bottom-0-6 { + padding-bottom: 0.6rem; +} + +.pd-bottom-0-7 { + padding-bottom: 0.7rem; +} + +.pd-bottom-1 { + padding-bottom: 1rem; +} + +.pd-bottom-15 { + padding-bottom: 1.5rem; +} + +.pd-bottom-17-5 { + padding-bottom: 1.75rem; +} + +.pd-bottom-2 { + padding-bottom: 2rem; +} + +.pd-bottom-3 { + padding-bottom: 3rem; +} + +.pd-top-0-5-pc { + padding-top: 0.5rem; +} + +.pd-top-0-75-pc { + padding-top: 0.75rem; +} + +.pd-top-1-pc { + padding-top: 1rem; +} + +.pd-top-12-5-pc { + padding-top: 1.25rem; +} + +.pd-top-15-pc { + padding-top: 1.5rem !important; +} + +.pd-top-2-pc { + padding-top: 2rem; +} + +.pd-top-2-5-pc { + padding-top: 2.5rem; +} + +.pd-top-3-pc { + padding-top: 3rem; +} + +.pd-top-4-pc { + padding-top: 4rem; +} + +.pd-left-05-pc { + padding-left: 0.5rem; +} + +.pd-top-05-pc { + padding-top: 0.5rem; +} + +.pd-left-12-pc { + padding-left: 1.2rem !important; +} + +.pd-left-2per-pc { + padding-left: 2%; +} + +.pd-left-4per-pc { + padding-left: 4%; +} + +.pd-right-32 { + padding-right: 3.2rem; +} + +// COLUMN +.col-20 { + width: 15%; + max-width: 15%; +} + +.col-25 { + width: 25%; + max-width: 25%; +} + +.col-13 { + width: 13%; + max-width: 13%; +} + +.col-23 { + width: 23%; + max-width: 23%; +} + +.col-35 { + max-width: 35%; +} + +.col-40 { + width: 40%; +} + +.col-45 { + width: 45%; +} + +.col-47 { + width: 47%; +} + +.col-55 { + width: 55%; +} + +.col-65 { + max-width: 65%; +} + +.col-50 { + max-width: 50%; +} + +.col-fixed-50 { + width: 50%; +} + +.col-70 { + max-width: 70%; +} + +.col-30 { + max-width: 30%; +} + +.col-fix-30 { + width: 30%; +} + +.col-fix-35 { + width: 35%; +} + +.col-fix-65 { + width: 65%; +} + +.col-15 { + max-width: 15%; + flex: 0 0 15%; +} + +.col-60 { + width: 60%; +} + +.col-80 { + width: 80%; +} + +.col-85 { + width: 85%; +} + +.col-87-5 { + width: 87.5%; +} + +.col-90 { + width: 90%; +} + +.col-100 { + width: 100%; +} + +.col-min-100 { + min-width: 100%; +} + +.width-115px { + width: 115px; +} + +// FLEX +.flex-wrap { + flex-wrap: wrap; +} + +.flex-1 { + flex: 1; +} + +.flex-1-8 { + flex: 1.8 !important; +} + +// FONTSIZE +.fz-08 { + font-size: 0.8rem; +} + +.fz-08-75 { + font-size: 0.875rem; +} + +.fz-09 { + font-size: 0.9rem; +} + +.fz-07-5 { + font-size: 0.75rem; +} + +.fz-14 { + font-size: 1.4rem; +} + +.fz-15 { + font-size: 1.5rem; +} + +.fz-16 { + font-size: 1.6rem; +} + +.fz-16-25 { + font-size: 1.625rem; +} + +.fz-16-875 { + font-size: 1.6875rem; +} + +.fz-18 { + font-size: 1.8rem; +} + +.fz-18-75 { + font-size: 1.875rem; +} + +.fz-19 { + font-size: 1.9rem; +} + +.fz-17 { + font-size: 1.7rem; +} + +.fz-20 { + font-size: 2rem; +} + +.fz-22 { + font-size: 2.2rem; +} + +.fz-12 { + font-size: 1.2rem; +} + +.fz-12-5 { + font-size: 1.25rem; +} + +.fz-13 { + font-size: 1.3rem; +} + +.fz-13-75 { + font-size: 1.375rem; +} + +.fz-11 { + font-size: 1.1rem; +} + +.fz-11-25 { + font-size: 1.125rem; +} + +.fz-11-5 { + font-size: 1.15rem; +} + +.fz-1 { + font-size: 1rem; +} + +.fz-24 { + font-size: 2.4rem; + + @include screen_mobile { + font-size: 1.1rem; + } +} + +.fz-26 { + font-size: 2.6rem; +} + +.fz-25 { + font-size: 2.5rem; + + @include screen_mobile { + font-size: 1.4rem; + } +} + +.fz-28 { + font-size: 2.8rem; +} + +.fz-30 { + font-size: 3rem; +} + +.fz-31 { + font-size: 3.1rem; +} + +.fz-32 { + font-size: 3.2rem; +} + +.fz-35 { + font-size: 3.5rem; +} + +.fz-37 { + font-size: 3.7rem; +} + +// ANIMATION +.icon_scale { + cursor: pointer; + -webkit-transition: all ease-out 0.3s; + transition: all ease-out 0.3s; + -webkit-transform: scale(1); + transform: scale(1); + + &:hover { + -webkit-transition: all ease-out 0.3s; + transition: all ease-out 0.3s; + -webkit-transform: scale(1.3); + transform: scale(1.3); + } +} + +.contain_image { + object-fit: contain; +} + +.cover_image { + object-fit: cover; +} + +// Text align +.text-align-left { + text-align: left; +} + +.text-align-center { + text-align: center; +} + +.text-align-justify { + text-align: justify; +} + +.disabled_user_select { + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} + +.color_hover { + cursor: pointer; + + &:hover { + color: var(--text-hover-color) !important; + } +} + +.color_hover_green { + cursor: pointer; + + &:hover { + color: #009761 !important; + } +} + +// Border +.border-1 { + border: 1px solid var(--text-color); +} + +.border_1_light { + border: 1px solid var(--border-color); +} + +.border_bottom { + border-bottom: 2px solid var(--border-color); +} + +.border_bottom_1 { + border-bottom: 1px solid rgba($color: #000000, $alpha: 0.1); +} + +.border_bottom_1_dark { + border-bottom: 1px solid var(--border-color); +} + +.border_bottom_2_black { + border-bottom: 2px solid var(--black-color); +} + +.border_bottom_1_text { + border-bottom: 1px solid var(--text-color); +} + +.border_dashed { + border-bottom: 1px dashed var(--black-color); +} + +.border-1-light { + border: 1px solid var(--light-border-color); +} + +// LIST STYLE +.list_style { + list-style-type: disc !important; + list-style: disc !important; +} + +.before_dot { + &::before { + content: "\2022"; + position: absolute; + color: black; + // padding-right: 0.3em; + top: 0; + left: 0rem; + font-size: 1.2rem; + } +} + +.before_dot_assign { + &::before { + content: "\2022"; + position: relative; + color: var(--title-assign-color); + // padding-right: 0.3em; + top: 0rem; + left: 0rem; + margin-right: 8%; + margin-left: 4%; + font-size: 1.3rem; + } +} + +.before_asterisk { + &::before { + content: "*"; + position: relative; + color: var(--light-red-color); + // padding-right: 0.3em; + top: 0.2rem; + left: 0rem; + margin-right: 0.4rem; + // margin-left: 4%; + font-size: 1.3rem; + } +} + +.item_dot_lozenge { + &::before { + content: "\25C6"; + position: absolute; + top: 0.3rem; + left: -1.2rem; + color: var(--primary-green); + font-size: 0.9rem; + } +} + +.item_dot_lozenge_black { + &::before { + content: "\25C6"; + position: absolute; + top: 0rem; + left: -1.12rem; + color: var(--black-color); + font-size: 0.88rem; + + @include screen_mobile { + font-size: 0.75rem; + } + } +} + +.item_dot_lozenge_black_top { + &::before { + content: "\25C6"; + position: absolute; + top: 0.7rem; + left: -1.12rem; + color: var(--black-color); + font-size: 0.88rem; + + @include screen_mobile { + font-size: 0.75rem; + } + } +} + +.border_radius_05 { + border-radius: 0.5rem; +} + +.border_radius_1 { + border-radius: 1rem; +} + +.text_underline { + text-decoration: underline !important; +} + +.text_underline_offset { + text-decoration: underline !important; + text-underline-offset: 0.32rem; + + @include screen_mobile { + text-underline-offset: 0.2rem; + } +} + +.text_through { + text-decoration: line-through !important; +} + +.pointer_cursor { + cursor: pointer; + + &:hover { + opacity: 0.9; + } +} + +.input_focus { + &:focus { + border-color: #333 !important; + } +} + +.ultil_price { + &::after { + content: "đ"; + color: var(--light-red-color); + font-size: 1.5rem; + position: absolute; + top: -0.6rem; + right: -1.1rem; + + @include screen_mobile { + top: -0.45rem; + right: -1rem; + font-size: 1.25rem; + } + } +} + +.ultil_price_right { + &::after { + content: "đ"; + color: var(--light-red-color); + font-size: 1.2rem; + position: absolute; + top: 0; + right: -1rem; + } +} + +.ultil_price_smaller { + &::after { + content: "đ"; + font-size: 1.2rem; + position: absolute; + top: -0.2rem; + right: -1rem; + } +} + +.ultil_price_payment { + &::after { + content: "đ"; + font-size: 0.85rem; + position: absolute; + top: -0.4rem; + right: -0.8rem; + } +} + +// POSITION +.pos_rel { + position: relative; +} + +.pos_abs { + position: absolute; +} + +.pos_sticky { + position: sticky; + top: 67px; + z-index: 2; +} + +.header_sticky { + position: sticky; + top: 0; + left: 0; + width: 100%; + // z-index: 99; +} + +.filter_shadow { + filter: drop-shadow(1px 2px 4px rgba(21, 27, 38, 0.4)); +} + +.zIndex999 { + z-index: 999 !important; +} + +.bg_readonly { + background-color: #cdcdcd !important; +} + +.notallowed_cursor { + cursor: not-allowed; +} + +// Animation +@keyframes fadeIn { + 0% { + opacity: 0.1; + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0.1; + } +} + +@keyframes slideIn { + from { + opacity: 0; + transform: translateX(-76vw); + } + + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes slideOut { + from { + opacity: 1; + transform: translateX(0); + } + + to { + opacity: 0; + transform: translateX(-85vw); + } +} + +@keyframes slideTopIn { + from { + opacity: 0.3; + transform: translateY(0); + } + + from { + opacity: 1; + transform: translateY(50%); + } +} + +@keyframes scaleInOut { + 0% { + transform: scale(1); + } + + 50% { + transform: scale(1.15); + } + + 100% { + transform: scale(1); + } +} + +// Other +.img_label_input { + width: 1.5rem; + height: auto; + + @include screen_mobile { + width: 1.2rem; + height: auto; + } +} + +.img_action_input { + width: 1.3rem; + height: auto; + + @include screen_mobile { + width: 1.1rem; + height: auto; + } +} + +.rotate_180 { + transform: rotate(180deg) !important; +} + +.keep_all { + word-break: keep-all; +} + +.break_word_all { + word-break: break-all; +} + +.break_word { + word-break: break-word; +} + +.bg-main:has(> .policyPage) { + background: transparent !important; +} + +.bg_white { + background-color: var(--white-color); +} + +.zIndex1 { + z-index: 1; +} + +.zIndex5 { + z-index: 5; +} + +.pd_4per { + padding: 0 4%; + + @include screen_mobile { + padding: 0 1.1rem; + } +} + +.pd_6per { + padding: 0 6%; + + @include screen_mobile { + padding: 0rem; + } +} + +.pd-hor-11-mobile { + @include screen_mobile { + padding-left: 1.1rem; + padding-right: 1.1rem; + } +} + +.pd-ver-11-mobile { + @include screen_mobile { + padding-top: 1.1rem; + padding-bottom: 1.1rem; + } +} + +.pd_8per { + padding: 0 8%; + + @include screen_mobile { + padding: 0 2rem; + } +} + +.hover_underline { + &:hover { + color: var(--text-hover-color); + text-decoration: underline !important; + } +} + +.hover_border_bottom { + &:hover { + color: var(--text-hover-color) !important; + border-bottom: 2px solid var(--text-hover-color); + } +} + +.border_after { + &::after { + content: ""; + position: absolute; + width: 100%; + height: 3px; + border-radius: 1rem; + background-color: var(--primary-green); + left: 0; + bottom: -0.3rem; + } + + &:hover { + color: var(--primary-green) !important; + } +} + +.border_after_notselected { + &::after { + content: ""; + position: absolute; + width: 0; + height: 3px; + border-radius: 1rem; + background-color: var(--primary-green); + left: 0; + bottom: -0.3rem; + transition: 0.2s; + } + + &:hover { + color: var(--primary-green) !important; + font-family: "AvertaStdCY-SemiBold" !important; + + &::after { + width: 100%; + } + } +} + +// Font Style +.font_style_italic { + font-style: italic; +} + +// Icon Tick +.icon_tick_success { + width: 1rem; + height: auto; +} + +.icon_tick_success_over { + width: 1.375rem; + height: auto; + + @include screen_mobile { + width: 1rem; + margin-top: 0.3rem !important; + } +} + +// List Dot +.list_item_dot { + + li, + .item_dot { + &::before { + content: "\2022"; + color: red; + padding-right: 0.5em; + font-size: 1.7rem; + + @include screen_mobile { + font-size: 1.4rem; + } + } + } +} + +// Line Height +.line_height_14 { + line-height: 1.4rem; +} + +.line_height_18-6-6 { + line-height: 1.86rem; +} + +.line_height_normal { + line-height: normal; +} + +// Uppercase +.text_uppercase { + text-transform: uppercase; +} + +.img_intro_item { + @include screen_mobile { + width: 2.4rem; + height: auto; + } +} + +// Pop up Resent +.uk-modal-dialog-resent { + width: 40% !important; + + @include screen_tablet { + width: 60% !important; + } + + @include screen_mobile { + width: 85% !important; + } + + .btn_text_popup { + width: 65% !important; + min-width: 7rem !important; + vertical-align: middle; + } +} + +// +.modal_success_abs_container { + width: 100%; + height: 100%; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: 0 auto; + text-align: center; + + .modal_success_abs { + width: 65%; + min-width: 30rem; + margin: 0 auto; + position: absolute; + left: 0; + right: 0; + top: 20%; + bottom: 0; + margin: 0 auto; + text-align: center; + + @include screen_mobile { + width: 90%; + min-width: auto; + top: 16%; + } + + .modal_container { + min-height: 45%; + min-width: 35rem; + + @include screen_mobile { + // height: 75%; + min-width: 18rem; + } + } + } +} + +// White Space +.white_space_pre { + white-space: pre; +} + +// Pop up Resent +.uk-modal-dialog-resent { + width: 40% !important; + + @include screen_tablet { + width: 60% !important; + } + + @include screen_mobile { + width: 85% !important; + } + + .btn_text_popup { + width: 65% !important; + min-width: 7rem !important; + vertical-align: middle; + } +} + +.uk-modal-dialog-yesno { + width: 40% !important; + max-width: 32rem !important; + min-width: 30rem; + + @media screen and (max-width: 768px) { + min-width: 22rem; + } + + .btn_text_popup { + width: 65% !important; + min-width: 7rem !important; + vertical-align: middle; + } +} + +// +.modal_success_abs_container { + width: 100%; + height: 100%; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: 0 auto; + text-align: center; + + .modal_success_abs { + width: 65%; + min-width: 30rem; + margin: 0 auto; + position: absolute; + left: 0; + right: 0; + top: 20%; + bottom: 0; + margin: 0 auto; + text-align: center; + + @include screen_mobile { + width: 90%; + min-width: auto; + top: 16%; + } + + .modal_container { + min-height: 45%; + + @include screen_mobile { + // height: 75%; + } + } + } +} + +.flex-evenly { + display: flex; + justify-content: space-evenly; +} + +// Assign +.btn_next_assign { + img { + position: relative; + left: 0.075rem; + } +} + +.btn_prev_assign { + img { + position: relative; + right: 0.075rem; + } +} + +//Btn log out +.customWidthBtn { + max-width: 27rem !important; + min-width: 27rem !important; + padding: 25px !important; +} + +.ico_upgrade { + width: 80%; + // height: 80%; + object-fit: contain; +} + +.btn-action-popup { + max-width: 200px; + width: 155px !important; +} + +.btn-action-popup-smaller { + max-width: 200px; + width: 138px !important; +} + +.filter-shadow { + filter: drop-shadow(1px 2px 4px rgba(21, 27, 38, 0.4)); +} + +.overflow-y-auto { + overflow-y: auto; +} \ No newline at end of file diff --git a/src/_components/GlobalStyles/ResponsiveGlobal.scss b/src/_components/GlobalStyles/ResponsiveGlobal.scss new file mode 100644 index 0000000..519eeba --- /dev/null +++ b/src/_components/GlobalStyles/ResponsiveGlobal.scss @@ -0,0 +1,448 @@ +$screen_tablet: 63.9375em; +$screen_mobile: 48em; + +// Tablet +@media screen and (min-width: 48.01em) and (max-width: $screen_tablet) { +} + +// Mobile +@media screen and (max-width: $screen_mobile) { + // Display + .display_block_mobile { + display: block !important; + } + .display_flex_mobile { + display: flex !important; + } + .display_none_mobile { + display: none !important; + } + .display_inline_mobile { + display: inline !important; + } + .display_inline_block_mobile { + display: inline-block !important; + } + + // MOBILE + + // Flex + .flex-between-mobile { + display: flex; + justify-content: space-between; + } + .flex-align-end-mobile { + display: flex; + align-items: flex-end; + } + + .flex-align-start-mobile { + display: flex; + align-items: flex-start; + } + + .flex-jus-around-mobile { + display: flex; + align-items: center; + justify-content: space-around; + } + + .flex-jus-between-mobile { + display: flex; + align-items: center; + justify-content: space-between; + } + + .flex-just-center-mobile { + display: flex; + justify-content: center; + } + + .flex-jus-end-between-mobile { + display: flex; + align-items: flex-end; + justify-content: space-between; + } + + .flex-jus-start-between-mobile { + display: flex; + justify-content: space-between; + } + + .flex-jus-evenly-mobile { + display: flex; + align-items: center; + justify-content: space-evenly; + } + + .flex-align-mobile { + display: flex; + align-items: center; + } + + .flex-center-mobile { + display: flex; + align-items: center; + justify-content: center; + } + + .flex-start-mobile { + display: flex; + align-items: center; + justify-content: flex-start; + } + + .flex-end-mobile { + display: flex; + align-items: center; + justify-content: flex-end; + flex-direction: row; + } + + .flex-between-row-mobile { + display: flex; + justify-content: space-between; + flex-direction: row; + } + .flex-row-mobile { + display: flex; + flex-direction: row; + } + + .flex-center-column-mobile { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + } + + .flex-column-mobile { + display: flex; + flex-direction: column; + justify-content: flex-start !important; + } + .flex-row-mobile { + display: flex; + flex-direction: row !important; + } + + .flex-row-reverse-mobile { + display: flex; + flex-direction: row-reverse !important; + } + + // Col + .col-max-100-mobile { + max-width: 100% !important; + } + .col-100-mobile { + width: 100% !important; + } + .col-90-mobile { + width: 90% !important; + } + + .col-20-mobile { + width: 20% !important; + } + + .col-25-mobile { + width: 25% !important; + } + .col-75-mobile { + width: 75% !important; + } + .col-80-mobile { + width: 80%; + } + .col-82-5-mobile { + width: 82.5%; + } + .col-50-mobile { + width: 50% !important; + } + .col-40-mobile { + width: 40% !important; + } + .col-45-mobile { + width: 45% !important; + } + + // FontSize + + // Mobile + .fz-07-mobile { + font-size: 0.7rem !important; + } + .fz-07-5-mobile { + font-size: 0.75rem !important; + } + .fz-08-mobile { + font-size: 0.8rem !important; + } + .fz-08-75-mobile { + font-size: 0.875rem !important; + } + .fz-09-mobile { + font-size: 0.9rem !important; + } + .fz-09-375-mobile { + font-size: 0.9375rem !important; + } + + .fz-14-mobile { + font-size: 1.4rem !important; + } + .fz-15-mobile { + font-size: 1.5rem !important; + } + .fz-16-mobile { + font-size: 1.6rem !important; + } + .fz-18-mobile { + font-size: 1.8rem !important; + } + .fz-17-mobile { + font-size: 1.7rem !important; + } + + .fz-20-mobile { + font-size: 2rem !important; + } + .fz-21-mobile { + font-size: 2.1rem !important; + } + .fz-21-5-mobile { + font-size: 2.15rem !important; + line-height: 3rem; + } + + .fz-22-mobile { + font-size: 2.2rem !important; + } + + .fz-12-mobile { + font-size: 1.2rem !important; + } + .fz-12-5-mobile { + font-size: 1.25rem !important; + } + .fz-13-mobile { + font-size: 1.3rem !important; + } + .fz-13-75-mobile { + font-size: 1.375rem; + } + .fz-11-mobile { + font-size: 1.1rem !important; + } + .fz-11-25-mobile { + font-size: 1.125rem !important; + } + .fz-11-5-mobile { + font-size: 1.15rem !important; + } + + .fz-1-mobile { + font-size: 1rem !important; + } + + .fz-24-mobile { + font-size: 2.4rem !important; + } + .fz-25-mobile { + font-size: 2.5rem !important; + } + + .fz-26-mobile { + font-size: 2.6rem !important; + } + + .fz-28-mobile { + font-size: 2.8rem !important; + } + + .fz-30-mobile { + font-size: 3rem !important; + } + + .fz-32-mobile { + font-size: 3.2rem !important; + } + + .fz-35-mobile { + font-size: 3.5rem !important; + } + + // Border + .border-1-mobile { + border: 1px solid var(--text-color); + } + + .border-bottom-1-mobile { + border-bottom: 1px solid var(--text-color); + } + .border-bottom-1-black-mobile { + border-bottom: 1px solid var(--black-color); + } + .border-bottom-2-black-mobile { + border-bottom: 2px solid var(--black-color); + } + + .border-bottom-2-mobile { + border-bottom: 2px solid var(--text-color); + } + + .border-bottom-light-1-mobile { + border-bottom: 1px solid var(--border-color); + } + .border-top-light-1-mobile { + border-top: 1px solid #e6e6e6; + } + + // Margin-Padding + .pd-top-2 { + padding-top: 2rem; + } + .pd-top-0-mobile { + padding-top: 0rem !important; + } + + .pd-vertical-0-3-mobile { + padding-top: 0.3rem !important; + padding-bottom: 0.3rem !important; + } + .pd-top-0-5 { + padding-top: 0.5rem; + } + .pd-top-1 { + padding-top: 1rem; + } + .pd-top-15 { + padding-top: 1.5rem; + } + .pd-top-17-5 { + padding-top: 1.75rem; + } + .pd-bottom-0-mobile { + padding-bottom: 0rem !important; + } + .pd-bottom-1-mobile { + padding-bottom: 1rem !important; + } + .pd-bottom-15-mobile { + padding-bottom: 1.5rem !important; + } + + .pd-right-4per { + padding-right: 4%; + } + .pd-left-4per { + padding-left: 4%; + } + + // Margin + .mg-bottom-2-mobile { + margin-bottom: 2rem !important; + } + .mg-bottom-15-mobile { + margin-bottom: 1.5rem !important; + } + .mg-bottom-12-mobile { + margin-bottom: 1.2rem; + } + .mg-bottom-0-mobile { + margin-bottom: 0 !important; + } + .mg-bottom-1-mobile { + margin-bottom: 1rem !important; + } + .mg-bottom-0-5-mobile { + margin-bottom: 0.5rem !important; + } + .mg-bottom-0-7-mobile { + margin-bottom: 0.7rem; + } + .mg-bottom-0-9-mobile { + margin-bottom: 0.9rem; + } + + .mg-top-2-mobile { + margin-top: 2rem !important; + } + .mg-top-1-mobile { + margin-top: 1rem; + } + .mg-top-15-mobile { + margin-top: 1.5rem; + } + .mg-top-0-5-mobile { + margin-top: 0.5rem; + } + + .mg-right-0-mobile { + margin-right: 0rem !important; + } + + // Form Input + .form_input_mobile { + .input_text_base, + .input_date_base, + .input_select_main_wrapper { + padding: 0 2vw !important; + } + .drop_down { + top: 3.3rem !important; + } + .icon_dropdown { + width: 1.2rem !important; + height: auto; + } + } + + // Color + .black-color-mobile { + color: var(--black-color) !important; + } + + .animation_slidein_top { + animation: slideTopIn linear 0.3s; + } + + // Color + .color-text-mobile { + color: var(--text-color) !important; + } + + .color-light-text-mobile { + color: #6e6e6e !important; + } + + .text-align-center-mobile { + text-align: center; + } + + // Font + .font_news_semi_bold_mobile { + font-family: "AvertaStdCY-SemiBold" !important; + } + .font_news_bold_mobile { + font-family: "AvertaStdCY-Bold" !important; + } + .font_news_extra_bold_mobile { + font-family: "AvertaStdCY-ExtraBold" !important; + } + + .font_news_black_mobile { + font-family: "AvertaStdCY-Black" !important; + } + + .font_news_mobile { + font-family: "AvertaStdCY" !important; + } + + // Position + .pos_rel_mobile { + position: relative !important; + } +} diff --git a/src/_components/GlobalStyles/index.js b/src/_components/GlobalStyles/index.js new file mode 100644 index 0000000..8658e7f --- /dev/null +++ b/src/_components/GlobalStyles/index.js @@ -0,0 +1,8 @@ +import "./GlobalStyles.scss"; +import "./ResponsiveGlobal.scss"; + +function GlobalStyles({ children }) { + return children; +} + +export default GlobalStyles; diff --git a/src/_components/GradeSelection/GradeSelection.jsx b/src/_components/GradeSelection/GradeSelection.jsx new file mode 100644 index 0000000..b0ab17a --- /dev/null +++ b/src/_components/GradeSelection/GradeSelection.jsx @@ -0,0 +1,42 @@ +import "./GradeSelection.style.scss"; + +const GradeSelection = (props) => { + let { dataGrades, gradeSelected, handleClickGrade, type } = props; + + const renderNumberGrade = (item) => { + return ( +
    +
    handleClickGrade(item)} + className={`pointer_cursor flex-center item_grade ${ + type == "teacher" + ? "font_news item_grade_teacher" + : " font_news_bold" + }`} + style={{ + backgroundColor: + (gradeSelected?.value || gradeSelected) == item.value + ? "#00CC83" + : "#FFF", + color: + (gradeSelected?.value || gradeSelected) == item.value + ? "#FFF" + : "#C4C4C4", + fontSize: type == "teacher" && "1.125rem", + width: type == "teacher" && "7vw", + }} + > + {item.value} +
    +
    + ); + }; + + return ( +
    + {dataGrades?.map((item) => renderNumberGrade(item))} +
    + ); +}; + +export default GradeSelection; diff --git a/src/_components/GradeSelection/GradeSelection.style.scss b/src/_components/GradeSelection/GradeSelection.style.scss new file mode 100644 index 0000000..e3e6aee --- /dev/null +++ b/src/_components/GradeSelection/GradeSelection.style.scss @@ -0,0 +1,45 @@ +@import "/src/_styles/mixin"; + +.list_grades { + width: 55%; + padding-left: 5%; + + @include screen_mobile { + max-width: 55% !important; + } + .item_grade_container { + margin: 0 3%; + .item_grade { + border: 1px solid#cdcdcd; + font-size: 2.4rem; + border-radius: 0.3rem; + // padding: 0 3%; + height: 4.5vw; + width: 4.5vw; + min-height: 3.5rem; + min-height: 3.5rem; + text-align: center; + + &:hover { + background-color: #00cc85 !important; + color: var(--white-color) !important; + } + + @include screen_mobile { + font-size: 1.4rem !important; + height: 10.8vw !important; + width: 10.8vw !important; + min-height: 3rem; + min-width: 3rem; + } + } + + .item_grade_teacher { + @include screen_mobile { + font-size: 0.9rem !important; + height: 15vw !important; + width: 15vw !important; + } + } + } +} diff --git a/src/_components/Header/HeaderCloud.js b/src/_components/Header/HeaderCloud.js new file mode 100644 index 0000000..65ada63 --- /dev/null +++ b/src/_components/Header/HeaderCloud.js @@ -0,0 +1,16 @@ +import React from "react"; +import { Link } from "react-router-dom"; +import { useSelector } from "react-redux"; + +function HeaderCloud() { + const authentication = useSelector((state) => state.authentication); + return ( +
    + + {"Logo"} + +
    + ); +} + +export { HeaderCloud }; diff --git a/src/_components/Header/HeaderCurve.js b/src/_components/Header/HeaderCurve.js new file mode 100644 index 0000000..5f78afa --- /dev/null +++ b/src/_components/Header/HeaderCurve.js @@ -0,0 +1,16 @@ +import React from "react"; +import { Link } from "react-router-dom"; +import { useSelector } from "react-redux"; + +function HeaderCurve() { + const authentication = useSelector((state) => state.authentication); + return ( +
    + + {"Logo"} + +
    + ); +} + +export { HeaderCurve }; diff --git a/src/_components/Header/HeaderNews/HeaderNews.jsx b/src/_components/Header/HeaderNews/HeaderNews.jsx new file mode 100644 index 0000000..342539a --- /dev/null +++ b/src/_components/Header/HeaderNews/HeaderNews.jsx @@ -0,0 +1,310 @@ +import "./HeaderNews.style.scss"; +import { headerNewsLogic } from "./HeaderNews.logic"; +import { Link, useParams } from "react-router-dom"; +import { TypeHeaderNewsItem } from "../../../_constants/headerNews"; +import { useDispatch, useSelector } from "react-redux"; +import { PopUpYesNo } from "../../Popup"; +import { HashLink } from "react-router-hash-link"; +import ButtonNews from "../../Button/ButtonNews"; +import { history } from "../../../_helpers"; +import { hasDomainStore } from "../../../_base/Validate"; +import classNames from "classnames"; + +const HeaderNews = (props) => { + let { + wrapperRef, + isVisibleTaiff, + listHeader, + visibleModal, + typeIcon, + isOpenModalNav, + dataUser, + dataSelectTariff, + setVisibleModal, + handleChangeModalHeader, + handleLogout, + handleOpenSubTariff, + setWrapperRefFind, + handleSelectOptionTariff, + handleNavigateCurriculum, + } = headerNewsLogic(props); + let { type } = props; + const authentication = useSelector((state) => state.authentication); + const dataProfile = useSelector((state) => state.profile.user_info.data); + + const renderFooterItem = (item) => { + return ( +
    handleSelectOptionTariff(item.type)} + > + {item.name} +
    + ); + }; + + // Render Data Select + const renderDataSelect = (data, index) => ( +
    handleSelectOptionTariff(data.type)} + > + {data.name} +
    + ); + + // Render Header Item + const renderHeaderItem = (item, typeOS) => { + return [TypeHeaderNewsItem.FEE, TypeHeaderNewsItem.TARIFF]?.includes( + item.type + ) && hasDomainStore() ? null : ( +
    + {![TypeHeaderNewsItem.FEE, TypeHeaderNewsItem.TARIFF]?.includes( + item.type + ) ? ( + ele.scrollIntoView({ behavior: "instant" })} + to={`/${item?.type}`} + className="link_header_mobile link_header_item pos_rel" + ref={(e) => + [TypeHeaderNewsItem.FEE, TypeHeaderNewsItem.TARIFF]?.includes( + item.type + ) && setWrapperRefFind(e) + } + > +
    +
    + {item?.name} +
    + + {item?.type == TypeHeaderNewsItem.MOCK_TEST && ( +
    FREE
    + )} + + {[TypeHeaderNewsItem.FEE, TypeHeaderNewsItem.TARIFF]?.includes( + item.type + ) && ( +
    + + + +
    + )} +
    + {typeOS != "mobile" && + [TypeHeaderNewsItem.FEE, TypeHeaderNewsItem.TARIFF]?.includes( + item.type + ) && ( +
    + {dataSelectTariff?.map((data, index) => + renderDataSelect(data, index) + )} +
    + )} + + {typeOS == "mobile" && + [TypeHeaderNewsItem.FEE, TypeHeaderNewsItem.TARIFF]?.includes( + item.type + ) && ( +
    + {dataSelectTariff.map((data) => renderFooterItem(data))} +
    + )} +
    + ) : ( +
    {} + } + > +
    +
    + {item?.name} +
    + + {item?.type == TypeHeaderNewsItem.MOCK_TEST && ( +
    FREE
    + )} + + {[TypeHeaderNewsItem.FEE, TypeHeaderNewsItem.TARIFF]?.includes( + item.type + ) && ( +
    + + + +
    + )} +
    + {typeOS != "mobile" && + [TypeHeaderNewsItem.FEE, TypeHeaderNewsItem.TARIFF]?.includes( + item.type + ) && ( +
    + {dataSelectTariff?.map((data, index) => + renderDataSelect(data, index) + )} +
    + )} + + {typeOS == "mobile" && + [TypeHeaderNewsItem.FEE, TypeHeaderNewsItem.TARIFF]?.includes( + item.type + ) && ( +
    + {dataSelectTariff.map((data) => renderFooterItem(data))} +
    + )} +
    + )} +
    + ); + }; + + return ( + + ); +}; + +export default HeaderNews; diff --git a/src/_components/Header/HeaderNews/HeaderNews.logic.js b/src/_components/Header/HeaderNews/HeaderNews.logic.js new file mode 100644 index 0000000..0b4ca5f --- /dev/null +++ b/src/_components/Header/HeaderNews/HeaderNews.logic.js @@ -0,0 +1,227 @@ +import { TypeHeaderNewsItem } from "../../../_constants/headerNews"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { userConstants } from "../../../_constants"; +import { history } from "../../../_helpers"; +import { teacherActions } from "../../../_actions"; +import { getMobileOperatingSystem } from "../../../_base/Validate"; +import { LinkApp } from "../../../_constants/linkDownloadApp"; +import { persistor } from "../../../index"; +import { convertNameHeaderItem } from "../../../_base/Validate"; + +export const headerNewsLogic = (props) => { + let { type } = props; + + const _dispatch = useDispatch(); + const authentication = useSelector((state) => state.authentication); + const dataProfile = useSelector((state) => state.profile.user_info.data); + + // useEffect(() => { + // _dispatch(teacherActions.getProfile(authentication.id)); + // }, []); + + const [isVisibleTaiff, setIsVisibleTariff] = useState(false); + + const [dataUser, setDataUser] = useState({ + fullname: + JSON.parse(localStorage.getItem("info_header_user"))?.fullname || + dataProfile?.fullname, + avatar: + JSON.parse(localStorage.getItem("info_header_user"))?.avatar || + dataProfile?.avatar, + }); + + useEffect(() => { + setDataUser({ + fullname: + JSON.parse(localStorage.getItem("info_header_user"))?.fullname || + dataProfile?.fullname, + avatar: + JSON.parse(localStorage.getItem("info_header_user"))?.avatar || + dataProfile?.avatar, + }); + }, [dataProfile]); + + const listHeader = [ + { + id: 1, + name: "HỌC SINH", + type: TypeHeaderNewsItem.HOME, + }, + { + id: 2, + name: "GIÁO VIÊN", + type: TypeHeaderNewsItem.TEACHER, + }, + { + id: 3, + name: "PHỤ HUYNH", + type: TypeHeaderNewsItem.PARENT, + }, + ]; + + const [visibleModal, setVisibleModal] = useState(false); + const [typeIcon, setTypeIcon] = useState("menu"); + const [isOpenModalNav, setIsOpenModalNav] = useState(false); + + const handleLogout = () => { + setVisibleModal(false); + _dispatch({ + type: userConstants.LOGOUT, + }); + _dispatch({ + type: userConstants.RESET_ALL_STATE, + }); + persistor.purge(); + // localStorage.clear(); + localStorage.removeItem("authentication"); + localStorage.removeItem("access_token"); + localStorage.removeItem("info_header_user"); + localStorage.removeItem("date_selected"); + localStorage.removeItem("curriculum_id_Selected"); + + // localStorage.removeItem("device_id_commond"); + // window.location.href = "/"; + history.push("/"); + }; + + const handleChangeModalHeader = () => { + if (typeIcon == "menu") { + setTypeIcon("close_menu"); + setIsOpenModalNav(true); + } else { + setTypeIcon("menu"); + setIsOpenModalNav(false); + setIsVisibleTariff(false); + } + }; + + useEffect(() => { + if (window.location.href.includes("/fee/policy")) { + document.title = convertNameHeaderItem("fee_policy"); + } else if (window.location.href.includes("/policy")) { + document.title = convertNameHeaderItem("policy"); + } else if (window.location.href.includes("/faq")) { + document.title = convertNameHeaderItem("faq"); + } else if (window.location.href.includes("/account_activation")) { + document.title = convertNameHeaderItem("account_activation"); + } else { + document.title = convertNameHeaderItem(type); + } + }, []); + + // Handle Tariff Open Sub Nav + const handleOpenSubTariff = () => { + setIsVisibleTariff(!isVisibleTaiff); + }; + + let wrapperRef = null; + + useEffect(() => { + document.addEventListener("mousedown", clickOutside); + return () => { + document.removeEventListener("mousedown", clickOutside); + }; + }, []); + + function clickOutside(event) { + if (wrapperRef && !wrapperRef.contains(event.target)) { + setIsVisibleTariff(false); + } + } + + const setWrapperRefFind = (node) => { + if (!wrapperRef) { + wrapperRef = node; + } + }; + + // Data Tariff Select + const dataSelectTariff = [ + { + id: 1, + name: "Dành cho học sinh", + type: TypeHeaderNewsItem.FEE, + }, + { + id: 2, + name: "Dành cho giáo viên", + type: TypeHeaderNewsItem.TARIFF, + }, + ]; + + // Func Handle Select Option Tariff + const handleSelectOptionTariff = (type) => { + setTypeIcon("menu"); + setIsOpenModalNav(false); + window.location.href = `/${type}`; + }; + + // Sticky Header + useEffect(() => { + var menu = document.querySelectorAll("div#header"); + var menu = menu[0]; + + //Truy xuất div menu + var trangthai = "duoi0.1"; + window.addEventListener("scroll", function () { + var x = pageYOffset; + if (x > 0.1) { + if (trangthai == "duoi0.1") { + trangthai = "tren20"; + menu.classList.add("header_sticky"); + menu.classList.add("box-shadow"); + } + } else { + if (trangthai == "tren20") { + menu.classList.remove("header_sticky"); + menu.classList.remove("box-shadow"); + trangthai = "duoi0.1"; + } + } + }); + }, []); + + // Handle Navigate Curriculum + const handleNavigateCurriculum = (type) => { + const osMobile = getMobileOperatingSystem(); + if (osMobile == "Android") { + window.open(LinkApp[`${type}`].GG_PLAY, "_blank"); + } else if (osMobile == "iOS") { + window.open(LinkApp[`${type}`].APP_STORE, "_blank"); + } else { + if (type === 'parent') { + history.push('/download_page/parent') + return; + } + if (authentication.isLogin) { + history.push(`/${authentication.role}/curriculum`); + } else { + localStorage.setItem( + "purposeLogin", + JSON.stringify({ + purpose: "curriculum", + }) + ); + history.push(`/login`); + } + } + }; + + return { + isVisibleTaiff, + listHeader, + visibleModal, + typeIcon, + isOpenModalNav, + dataUser, + dataSelectTariff, + setVisibleModal, + handleLogout, + handleChangeModalHeader, + handleOpenSubTariff, + setWrapperRefFind, + handleSelectOptionTariff, + handleNavigateCurriculum, + }; +}; diff --git a/src/_components/Header/HeaderNews/HeaderNews.style.scss b/src/_components/Header/HeaderNews/HeaderNews.style.scss new file mode 100644 index 0000000..fa4de14 --- /dev/null +++ b/src/_components/Header/HeaderNews/HeaderNews.style.scss @@ -0,0 +1,367 @@ +@import "/src/_styles/mixin"; + +.header_container { + background-color: var(--white-color); + padding: 0.1rem 0; + z-index: 9990; + transition: all ease-in 0.3s; + + border-top: 1px solid #f5f5f5; + border-bottom: 1px solid #f5f5f5; + position: sticky; + top: 0; + // height: 75px; + + .header_content { + margin: 0 auto; + max-width: 88vw; + display: flex; + align-items: center; + justify-content: space-around; + z-index: 9990; + + @include screen_tablet { + max-width: 95vw; + justify-content: space-between; + } + + @include screen_mobile { + max-width: 95vw; + justify-content: space-between; + margin-left: 3%; + margin-right: 3%; + } + + .img_logo { + height: 4rem; + width: auto; + } + + .header_menu_icon_container { + padding: 0.5rem; + padding-left: 0.2rem; + + .header_menu_icon { + width: 1.5rem; + height: 1.5rem; + animation: fadeIn linear 0.3s; + + @include screen_mobile { + width: 1.3rem; + height: 1.3rem; + } + } + } + + .logo_header { + @include screen_mobile { + // margin: 0 auto; + // padding-left: 12%; + } + } + + .header_list { + display: flex; + align-items: center; + flex: 1; + margin-left: 32px; + // justify-content: center; + } + + .header_login { + // font-size: 0.9rem; + // @include screen_tablet { + // font-size: 0.85rem !important; + // } + + // @include screen_mobile { + // font-size: 0.85rem !important; + // } + + font-size: clamp(0.75rem, 1vw, 0.9rem); + } + + .btn_custom { + width: clamp(5.5rem, 12vw, 7rem) !important; + height: clamp(2rem, 4vw, 2.3rem) !important; + // animation: scaleInOut linear 1.5s; + // animation-iteration-count: infinite; + } + + .name_user { + padding-right: 1rem; + max-width: 11vw; + text-align: right; + overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: 2; + /* number of lines to show */ + line-clamp: 2; + -webkit-box-orient: vertical; + + // font-size: 0.9rem; + // @include screen_tablet { + // font-size: 0.9rem; + // } + + font-size: clamp(0.7rem, 1.3vw, 0.9rem); + } + + .img_avt_user { + width: 3rem; + min-width: 3rem; + height: 3rem; + + @include screen_tablet { + width: 2.6rem; + min-width: 2.6rem; + height: 2.6rem; + } + + border-radius: 50%; + } + + .img_logout_container { + margin-left: 2.5rem; + + @include screen_tablet { + margin-left: 1rem; + } + + @include screen_mobile { + margin-left: 1.3rem; + } + + .img_logout { + min-width: 1.6rem; + height: 1.6rem; + + @include screen_tablet { + min-width: 1.2rem; + height: 1.2rem; + } + } + } + } + + .header_item { + margin: 0 calc(2% + 0.2rem); + position: relative; + display: flex; + align-items: center; + // @include screen_tablet { + // font-size: 0.8rem; + // }padding: 0.8rem 0; + + &:hover .ico_drop_tariff svg { + transform: rotate(180deg); + + @include screen_mobile { + transform: rotate(0); + } + } + + &:hover .ico_drop_tariff svg path, + &:hover .header_item_text { + stroke: var(--text-hover-color); + color: var(--text-hover-color); + } + + &::after { + content: ""; + height: 60%; + width: 125%; + position: absolute; + bottom: -30%; + right: -5%; + + @include screen_mobile { + display: none !important; + } + } + + &:hover .list_option_custom { + display: flex !important; + background-color: var(--white-color) !important; + } + + .link_header_item { + .list_option_custom { + position: absolute; + top: 3.3rem; + right: 0; + left: -75%; + max-height: 20rem; + min-height: 5rem; + overflow: auto; + margin: 0 auto; + background-color: var(--white-color) !important; + border-bottom-left-radius: 0.6rem; + border-bottom-right-radius: 0.6rem; + border-radius: 0.6rem; + padding: 0 0.5rem; + z-index: 99; + width: 250%; + min-width: 10rem; + max-width: clamp(11.5rem, 13vw, 12.5rem); + // border-top: 0; + + &::-webkit-scrollbar { + width: 6px; + } + + /* Handle */ + &::-webkit-scrollbar-thumb { + background: #bbbbbb; + border-radius: 10px; + } + + &::-webkit-scrollbar-track { + margin: 0.4rem 0; + } + + /* Handle on hover */ + &::-webkit-scrollbar-thumb:hover { + background: #8b8b8b; + } + + .option_item_custom { + color: var(--text-color); + padding: 0.75rem 0; + background: white !important; + z-index: 2; + cursor: pointer; + + font-size: clamp(0.875rem, 1.15vw, 1.125rem); + + &:hover { + font-family: "AvertaStdCY-Bold" !important; + background: white !important; + } + } + } + } + + .item_bonus { + display: inline-flex; + background-color: var(--light-red-color); + color: var(--white-color); + border-radius: 0.9rem; + padding: 0.05rem 0.4rem; + font-size: 0.5rem; + margin: 0 0 0.8rem 0.3rem; + // animation: fadeIn linear 3s; + animation-iteration-count: infinite; + animation-direction: alternate; + } + + .header_item_text_container { + padding: 0.8rem 0; + + .ico_drop_tariff { + margin-left: 0.33rem; + + svg { + width: clamp(10px, 1.25vw, 13px); + + @include screen_mobile { + width: 12px; + } + } + } + + &:hover .header_item_text { + cursor: pointer; + color: var(--text-hover-color); + } + } + + .header_item_text { + // font-size: 0.9rem; + font-weight: 500; + font-size: clamp(0.5rem, 1vw, 0.9rem); + } + } + + .modal_header_container { + background-color: rgba(0, 0, 0, 0.6); + width: 100%; + + .modal_header { + background-color: var(--white-color); + position: absolute; + left: 0; + top: 4.2rem; + width: 75vw; + // min-height: 92vh; + max-height: calc(100vh - 68px); + overflow-x: auto; + z-index: 9999; + animation: slideIn linear 0.25s; + display: flex; + flex-direction: column; + + .header_item_mobile { + width: 100%; + border-bottom: 1px solid var(--border-color); + padding: 0 0 0 4%; + margin: 0; + animation: slideIn linear 0.3s; + + &:last-child { + border-bottom: none; + } + + @include screen_mobile { + &:hover .header_item_text { + color: var(--text-hover-color); + // border-bottom: 2px solid var(--text-hover-color); + } + } + + .option_item_mobile { + font-size: clamp(0.75rem, 3.2vw, 0.875rem); + + &:hover { + font-family: "AvertaStdCY-Bold" !important; + } + } + + .link_header_mobile { + width: 100%; + padding: 1rem 0; + + // &:hover .header_item_text { + // color: var(--text-hover-color); + // text-decoration: underline !important; + // } + } + + .item_bonus { + display: inline-flex; + background-color: var(--light-red-color); + color: var(--white-color); + border-radius: 0.9rem; + padding: 0.05rem 0.4rem; + font-size: 0.65rem; + margin: 0 0 0.8rem 0.3rem; + // animation: fadeIn linear 3.5s; + animation-iteration-count: infinite; + animation-direction: alternate; + } + + .header_item_text { + font-size: clamp(0.75rem, 3.2vw, 0.875rem); + height: 100%; + } + } + } + } +} + +.title_news_container { + padding: 1rem 0 1rem 4%; + border-top: 1px solid #f5f5f5; + border-bottom: 1px solid #f5f5f5; + background-color: var(--white-color); +} \ No newline at end of file diff --git a/src/_components/Header/HeaderNews/TitleNews.jsx b/src/_components/Header/HeaderNews/TitleNews.jsx new file mode 100644 index 0000000..b478f3b --- /dev/null +++ b/src/_components/Header/HeaderNews/TitleNews.jsx @@ -0,0 +1,11 @@ +import "./HeaderNews.style.scss"; + +const TitleNews = (props) => { + return ( +
    + {props.title} +
    + ); +}; + +export default TitleNews; diff --git a/src/_components/Header/HeaderSquare.js b/src/_components/Header/HeaderSquare.js new file mode 100644 index 0000000..b9d115c --- /dev/null +++ b/src/_components/Header/HeaderSquare.js @@ -0,0 +1,12 @@ +import React from 'react'; + +function HeaderSquare() { + + return ( +
    +

    HeaderSquare

    +
    + ); +} + +export { HeaderSquare }; \ No newline at end of file diff --git a/src/_components/Header/HeaderTS/HeaderTS.js b/src/_components/Header/HeaderTS/HeaderTS.js new file mode 100644 index 0000000..5422e05 --- /dev/null +++ b/src/_components/Header/HeaderTS/HeaderTS.js @@ -0,0 +1,21 @@ +import React from "react"; +import { Link } from "react-router-dom"; +import { useSelector } from "react-redux"; +import './headerTS.style.scss' + +function HeaderTS() { + const authentication = useSelector((state) => state.authentication); + return ( +
    + + {"Logo"} + Cô Đặng Thu Hiền + +
    + ); +} + +export { HeaderTS }; diff --git a/src/_components/Header/HeaderTS/headerTS.style.scss b/src/_components/Header/HeaderTS/headerTS.style.scss new file mode 100644 index 0000000..a8f04b9 --- /dev/null +++ b/src/_components/Header/HeaderTS/headerTS.style.scss @@ -0,0 +1,43 @@ +.header-ts { + display: flex; + align-items: center; + padding-top: 16px; + + @media screen and (max-width: 768px) { + padding-top: 12px; + } + + a { + display: flex; + flex-direction: column; + align-items: center; + margin-left: 32px; + + @media screen and (max-width: 768px) { + margin-left: 16px; + } + } + + img { + width: 90px; + height: auto; + margin-top: 0 !important; + + @media screen and (max-width: 768px) { + width: 50px; + } + } + + span { + font-size: 20px; + font-weight: 700; + margin-top: 4px; + color: #14375F; + font-family: 'Barlow-Bold'; + + @media screen and (max-width: 768px) { + font-size: 12px; + } + + } +} \ No newline at end of file diff --git a/src/_components/Header/index.js b/src/_components/Header/index.js new file mode 100644 index 0000000..493a046 --- /dev/null +++ b/src/_components/Header/index.js @@ -0,0 +1,5 @@ +export * from "./HeaderCloud"; +export * from "./HeaderCurve"; +export * from "./HeaderSquare"; +export * from "./HeaderTS/HeaderTS"; +export { default as HeaderNews } from "./HeaderNews/HeaderNews"; diff --git a/src/_components/Input/InputNews.jsx b/src/_components/Input/InputNews.jsx new file mode 100644 index 0000000..22b04a9 --- /dev/null +++ b/src/_components/Input/InputNews.jsx @@ -0,0 +1,29 @@ +const InputNews = (props) => { + let { value, typeInput, placeholder, onChange, width, height, pattern } = + props; + + return ( +
    + onChange(e.target.value)} + pattern={pattern} + style={{ + width: width, + height: height, + backgroundColor: "white", + border: "1px solid #c4c4c4", + borderRadius: "0.3rem", + outline: "none", + color: "#4D4D4D", + paddingLeft: "1.2rem", + }} + className="fz-11 input_focus input_news" + /> +
    + ); +}; + +export default InputNews; diff --git a/src/_components/Input/InputSelect.jsx b/src/_components/Input/InputSelect.jsx new file mode 100644 index 0000000..7bcd3b2 --- /dev/null +++ b/src/_components/Input/InputSelect.jsx @@ -0,0 +1,187 @@ +import React, { useEffect, useRef, useState } from "react"; +import classnames from "classnames"; +import "../Auth/InputSelect/index.scss"; +import { PresentToAllSharp } from "@material-ui/icons"; +import useOutsideClick from "../../_helpers/customHook/useOutsideClick"; + +const InputSelectNews = (props) => { + let { placeholder } = props; + const [isOpen, setIsOpen] = useState(false); + const $selectRef = useRef(null); + const isOpenCached = useRef(null); + + useEffect(() => { + isOpenCached.current = isOpen; + }, [isOpen]); + + useOutsideClick($selectRef, () => { + if (isOpenCached.current) { + setIsOpen(false); + props?.setIsVisible && props?.setIsVisible(false); + } + }); + + // Handle Checked box + const handleCheckedBoxValue = () => { + props.handleCheckedBox(); + }; + + return ( +
    + {props.errorText && props?.typeErrText != "underAbsolute" ? ( +
    + {props.errorText} +
    + ) : null} +
    { + props.isWarning && props.setIsWarning(false); + if (props.setErrorText) { + props.setErrorText(""); + props?.setCompulWarning && props?.setCompulWarning(""); + } + if (!props.disabledClick) { + setIsOpen(!isOpen); + props?.setIsVisible && props?.setIsVisible(!isOpen); + } else { + props.onClickDisable && props.onClickDisable(); + } + }} + > +
    +
    + {props.renderLabelIcon ? ( +
    {props.renderLabelIcon()}
    + ) : null} + { + if (props.inputEditable) { + props.setValue({ + value: e.target?.value, + title: e.target?.value, + }); + } + }} + style={props.inputEditable ? {} : { pointerEvents: "none" }} + > + {props.typeSearch == "checkbox" && ( +
    + Icon Checked Box +
    + )} +
    + {props.typeSearch != "checkbox" && ( + + + + )} +
    +
    +
    +
    +
    +
    + {props.options?.map((option) => { + return ( +
    { + props.setValue(option); + setIsOpen(false); + props?.setIsVisible && props.setIsVisible(false); + }} + > + + {option.title} + +
    + ); + })} +
    +
    + {props.errorText && props?.typeErrText == "underAbsolute" ? ( +
    + {props.errorText} +
    + ) : null} +
    + ); +}; + +export default InputSelectNews; diff --git a/src/_components/Input/TextAreaNews.jsx b/src/_components/Input/TextAreaNews.jsx new file mode 100644 index 0000000..0ed49b4 --- /dev/null +++ b/src/_components/Input/TextAreaNews.jsx @@ -0,0 +1,32 @@ +const TextAreaNews = (props) => { + let { placeholder, onChange, width, height, value } = props; + + return ( +
    + + {isShowCheckBox &&
    + setIsChecked(e.target.checked)} /> + +
    } +
    + + +
    +
    + + + ); +} + +export { PopUpAddCommentRollUp }; \ No newline at end of file diff --git a/src/_components/Popup/PopUpAddFile.js b/src/_components/Popup/PopUpAddFile.js new file mode 100644 index 0000000..7918a61 --- /dev/null +++ b/src/_components/Popup/PopUpAddFile.js @@ -0,0 +1,186 @@ +import React, { useEffect, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import "./style.css"; +import { SelectAsDiv } from "./../../_components/Select"; +import { studentActions, teacherActions } from "./../../_actions"; +import { alertActions } from "./../../_actions/alerts"; +import { teacherConstants } from "./../../_constants"; +import $ from "jquery"; + + +function PopUpAddFile(props) { + let { onClickNo, width, param, messageErr } = props; + const [acceptFile] = useState({ + accept_file: 'audio/*, video/*, image/*, .pdf, .doc, .docx, .txt, .pptx, .xlsx, .xls, .ppt', + type: ['audio', 'video', 'image'], + name: ['pdf', 'doc', 'docx', 'txt', 'pptx', 'ppt', 'xls', 'xlsx'] + }) + const [errFile, setErrFile] = useState('') + + const dispatch = useDispatch(); + + const grades = useSelector((state) => state.grades); + const [inputs, setInputs] = useState({ + file: "", + title: "", + grade_id: "", + skill: "", + }); + let { file, title, grade_id, skill } = inputs; + + function handleChangeFile(event) { + const typeFile = event?.target?.files?.[0]?.type + if(!!typeFile) { + const nameFile = event?.target?.files?.[0]?.name + const typeFileName = nameFile?.slice(nameFile?.lastIndexOf('.') + 1) + + const isValidFile = + acceptFile.type.includes(typeFile?.slice(0, typeFile?.indexOf('/'))) + || acceptFile.name.includes(typeFileName) + + if(!isValidFile) { + setErrFile(`Định dạng file ${typeFileName} không được hỗ trợ!`) + return; + } + + setErrFile('') + dispatch(alertActions.error({ message: "", screen: "" })); + setInputs((inputs) => ({ + ...inputs, + file: event.target.files[0], + })); + const input = document.getElementById("files"); + input.style.setProperty("--after-content", '"' + 123 + '"'); + } + } + + useEffect(() => { + dispatch(studentActions.getAllGrade()); + }, []); + + const [avalableSubmit, setAvalableSubmit] = useState(true); + + function handleSubmit() { + if (validateParam() && avalableSubmit) { + if (validateParam()) { + setAvalableSubmit(false); + var dataAddFile = new FormData(); + dataAddFile.append("title", title); + dataAddFile.append("grade_id", grade_id); + dataAddFile.append("skill", skill); + dataAddFile.append("file", file); + dispatch(teacherActions.addFileResource(dataAddFile, param)); + setTimeout(function () { + setAvalableSubmit(true); + }, 3000); + props?.onSubmit && props.onSubmit(); + } + } + } + + function validateParam() { + return file && title?.trim() !== "" && grade_id && skill ? true : false; + } + + return ( + + ); +} + +export { PopUpAddFile }; diff --git a/src/_components/Popup/PopUpAddRollUp.js b/src/_components/Popup/PopUpAddRollUp.js new file mode 100644 index 0000000..2ab0876 --- /dev/null +++ b/src/_components/Popup/PopUpAddRollUp.js @@ -0,0 +1,76 @@ +import React, { useState } from "react"; +import "./style.css"; +import { SelectDate } from "./../../_components/Calendar"; +import { useSelector, useDispatch } from "react-redux"; +import moment from "moment"; +import { teacherConstants } from "./../../_constants"; +import { useHistory } from "react-router-dom"; +import { useParams } from "react-router-dom"; + +function PopUpAddRollUp(props) { + const { id } = useParams(); + let { width } = props; + const history = useHistory(); + let { onClickNo } = props; + const [inputs, setInputs] = useState({ + date: new Date(), + }); + let { date } = inputs; + const dispatch = useDispatch(); + const authentication = useSelector((state) => state.authentication); + + function addRollUp() { + dispatch({ + type: teacherConstants.ADD_TIME_ADD_ROLL_UP, + date: date, + }); + history.push( + "/" + authentication.role + "/class/view/" + id + "/roll_up/add" + ); + } + + return ( + + ); +} + +export { PopUpAddRollUp }; diff --git a/src/_components/Popup/PopUpAddSchedule.js b/src/_components/Popup/PopUpAddSchedule.js new file mode 100644 index 0000000..e69de29 diff --git a/src/_components/Popup/PopUpAddStudent.js b/src/_components/Popup/PopUpAddStudent.js new file mode 100644 index 0000000..68b2ad0 --- /dev/null +++ b/src/_components/Popup/PopUpAddStudent.js @@ -0,0 +1,60 @@ +import React from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { teacherActions, studentActions } from './../../_actions'; +import { useParams } from "react-router-dom"; +import { configConstants, popupConstants } from './../../_constants'; +import { userConstants } from '../../_constants'; +import moment from 'moment' + +import './style.css'; + +function PopUpAddStudent(props) { + let { width } = props; + const { id } = useParams(); + const dispatch = useDispatch(); + const student = useSelector(state => state.classes.addStudent); + const authentication = useSelector(state => state.authentication); + + function handleSubmit() { + if(authentication.role === userConstants.ROLE_TEACHER){ + dispatch(teacherActions.addStudent({ class_id: id, user_code: student.user_data.user_code })); + }else{ + dispatch(studentActions.addParent({user_code: student.user_data.user_code })); + } + } + function close() { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + } + + return ( + + + ); +} + +export { PopUpAddStudent }; \ No newline at end of file diff --git a/src/_components/Popup/PopUpAddTimeTable.js b/src/_components/Popup/PopUpAddTimeTable.js new file mode 100644 index 0000000..99a22c9 --- /dev/null +++ b/src/_components/Popup/PopUpAddTimeTable.js @@ -0,0 +1,300 @@ +import React, { useEffect, useState } from "react"; +import moment from "moment"; +// import DatePicker from "react-datepicker"; +// import "react-datepicker/dist/react-datepicker.css"; +import { alertActions, scheduleActions } from "./../../_actions"; +import { Alert } from "./../../_components/Alert"; +import { useSelector, useDispatch } from "react-redux"; +import { userConstants, scheduleConstants } from "./../../_constants"; +import { SelectDate } from "./../../_components/Calendar"; +import { SelectAsDiv } from "./../../_components/Select"; +import "./style.css"; + +function PopUpAddTimeTable(props) { + const dispatch = useDispatch(); + let { + onClickCancel, + titleButtonDone, + titleButtonCancel, + width, + dataEditTimeTable, + } = props; + const alert = useSelector((state) => state.alert); + + const authentication = useSelector((state) => state.authentication); + + const [alertState, setAlert] = useState({}); + const isRemind = + dataEditTimeTable.action === "add" + ? dataEditTimeTable.checkRemind + : parseInt(dataEditTimeTable.remind) === 1; + const [checkRemind, setcheckRemind] = useState(isRemind); + const [inputs, setInputs] = useState({ + ...dataEditTimeTable, + // fix example for library datepicker can working + start_time: new Date("2021/01/01 " + dataEditTimeTable.start_time), + end_time: new Date("2021/01/01 " + dataEditTimeTable.end_time), + }); + + useEffect(() => { + dispatch(alertActions.error({})); + }, []); + + useEffect(() => { + setAlert(alert); + }, [alert]); + + function handleChange(e) { + const { name } = e.target; + if (name === "remind_time") { + let val = e.target.value === "" ? "" : e.target.value.replace(/\D/, ""); + if (val > 60 && val < 70) { + val = 60; + setInputs((inputs) => ({ ...inputs, [name]: val })); + } else if (val <= 60) { + setInputs((inputs) => ({ ...inputs, [name]: val })); + } + } else { + let value = e.target.value; + setInputs((inputs) => ({ ...inputs, [name]: value })); + } + dispatch(alertActions.error({})); + } + + function handleBlurInputText(e) { + const { name, value } = e.target; + setInputs((inputs) => ({ ...inputs, [name]: value.trim() })); + } + + function handleOnBlur() { + if (!inputs.remind_time) { + setInputs((inputs) => ({ ...inputs, ["remind_time"]: 0 })); + } + if (Number(inputs.remind_time) > 60) { + setInputs((inputs) => ({ ...inputs, ["remind_time"]: 60 })); + } + } + const [submitted, setSubmitted] = useState(false); + + function handleSubmit(e) { + if (inputs.class_name.length > 30) { + dispatch( + alertActions.error({ + message: + (authentication.role === userConstants.ROLE_TEACHER + ? "Tên lớp học" + : "Tên môn học") + " không được quá 30 ký tự.", + screen: scheduleConstants.SCREEN_ADD_TIME_TABLE, + }) + ); + } else { + // console.log(inputs.class_name.length) + e.preventDefault(); + setSubmitted(true); + if (validateParam()) { + if (!checkRemind) { + // inputs.remind_time = null; + inputs.remind = 0; + inputs.is_remind = 0; + setInputs({ + ...inputs, + remind: 0, + // 'remind_time': null, + }); + } else { + inputs.remind = 1; + inputs.is_remind = 1; + if (!inputs.remind_time || inputs.remind_time <= 0) { + // return false; + } + } + if (dataEditTimeTable.action === "add") { + dispatch( + scheduleActions.addTimeTable({ + ...inputs, + remind_time: inputs.remind_time || 10, + start_time: moment(inputs.start_time).format("HH:mm"), + end_time: moment(inputs.end_time).format("HH:mm"), + }) + ); + } else { + dispatch( + scheduleActions.editTimeTable({ + ...inputs, + remind_time: inputs.remind_time || 10, + start_time: moment(inputs.start_time).format("HH:mm"), + end_time: moment(inputs.end_time).format("HH:mm"), + }) + ); + } + } + } + } + + function validateParam() { + if (checkRemind) { + if (!inputs.remind_time || inputs.remind_time <= 0) { + // return false; + } + } + return inputs.class_name.trim() && inputs.start_time <= inputs.end_time + ? true + : false; + } + + // console.log(inputs); + return ( + + ); +} + +export { PopUpAddTimeTable }; diff --git a/src/_components/Popup/PopUpApplyClass.js b/src/_components/Popup/PopUpApplyClass.js new file mode 100644 index 0000000..da66603 --- /dev/null +++ b/src/_components/Popup/PopUpApplyClass.js @@ -0,0 +1,117 @@ +import React from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { studentActions } from "./../../_actions"; +import moment from "moment"; +import { popupConstants } from "./../../_constants"; +import { userConstants } from "../../_constants"; + +import "./style.css"; + +function PopUpApplyClass(props) { + let { width } = props; + const dispatch = useDispatch(); + const classDetail = useSelector((state) => state.classes.detail); + + const authentication = useSelector((state) => state.authentication); + + function handleSubmit() { + if (authentication.role === userConstants.ROLE_STUDENT) { + dispatch( + studentActions.applyForClass({ + class_code: classDetail.class_data.class_code, + }) + ); + } + } + function close() { + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + } + return ( + + ); +} + +export { PopUpApplyClass }; diff --git a/src/_components/Popup/PopUpEditHomeWork.js b/src/_components/Popup/PopUpEditHomeWork.js new file mode 100644 index 0000000..b0817f0 --- /dev/null +++ b/src/_components/Popup/PopUpEditHomeWork.js @@ -0,0 +1,250 @@ +import React, { useEffect, useState, Fragment } from "react"; +import "./style.css"; + +function PopUpEditHomeWork(props) { + let { + onClickNo, + onClickYes, + width, + currentDataErr, + currentDataFix, + cachesList, + type, + } = props; + + let [dataError, setDataError] = useState({ + ...currentDataErr, + }); + + // console.log("currentDataErr ====", currentDataErr); + // console.log("currentDataFix ====", currentDataFix); + + let [dataFix, setDataFix] = useState({ ...currentDataFix }); + + function handleSubmit() { + if (validateParam()) { + dataFix.ai = false; + dataFix.idErr = dataError.start + "_" + dataError.end; + + let startFix = 0; + let endFix = 0; + + let startError = 0; + let endError = 0; + // let cachesList = cachesList; + if (type == "update") { + if (currentDataFix?.type == 1) { + dataError.start = dataError.start - currentDataFix.fixed.length; + dataError.end = dataError.end - currentDataFix.fixed.length; + dataError.id = dataError.start + "_" + dataError.end; + setDataError({ ...dataError }); + } + + cachesList = + cachesList.substring(0, currentDataFix?.start) + + cachesList.substring(currentDataFix?.end, cachesList?.length); + } + if (!dataFix.fixed.toString()) { + dataFix.start = dataError.start; + dataFix.end = dataError.start; + dataFix.id = dataError.start + "_" + dataError.start; + dataFix.idErr = dataError.start + "_" + dataError.end; + dataError.id = dataError.start + "_" + dataError.end; + cachesList = + cachesList.substring(0, dataError.start) + + cachesList.substring(dataError.start, dataError.end) + + cachesList.substring(dataError.end, dataError.length); + } else { + if (dataFix.type) { + // console.log("vao day roiii ====", dataFix.type); + startFix = dataError.start; + endFix = dataError.start + dataFix.fixed.length; + startError = dataError.start + dataFix.fixed.length; + endError = dataError.end + dataFix.fixed.length; + cachesList = + cachesList.substring(0, dataError.start) + + dataFix.fixed + + cachesList.substring(dataError.start, dataError.length); + + // console.log("startError ===", startError); + // console.log("endError ===", endError); + } else { + startFix = dataError.end; + endFix = dataError.end + dataFix.fixed.length; + startError = dataError.start; + endError = dataError.end; + cachesList = + cachesList.substring(0, dataError.end) + + dataFix.fixed + + cachesList.substring(dataError.end, dataError.length); + } + dataFix.start = startFix; + dataFix.end = endFix; + dataFix.id = startFix + "_" + endFix; + dataFix.idErr = startError + "_" + endError; + + dataError.id = startError + "_" + endError; + dataError.start = startError; + dataError.end = endError; + } + + dataError.ai = false; + dataError.type = dataFix.type; + + let addNumberToId = parseInt( + dataFix.fixed.length - currentDataFix.fixed.length + ); + + onClickYes({ + dataError, + dataFix, + cachesList, + type, + addNumberToId, + }); + } + } + + function back() { + let addNumberToId = parseInt(0 - currentDataFix.fixed.length); + cachesList = + cachesList.substring(0, currentDataFix.start) + + cachesList.substring(currentDataFix.end, cachesList.length); + onClickYes({ + dataError, + dataFix, + cachesList, + type: "delete", + addNumberToId, + }); + } + + function validateParam() { + return dataError.isHide || dataFix.fixed ? true : false; + } + + return ( + + ); +} + +export { PopUpEditHomeWork }; diff --git a/src/_components/Popup/PopUpEditScheduleYear.js b/src/_components/Popup/PopUpEditScheduleYear.js new file mode 100644 index 0000000..11eaf5a --- /dev/null +++ b/src/_components/Popup/PopUpEditScheduleYear.js @@ -0,0 +1,70 @@ +import React, { useState } from 'react'; +import './style.css'; +import { useSelector, useDispatch } from 'react-redux'; +import { scheduleConstants, popupConstants } from './../../_constants'; +import { scheduleActions } from './../../_actions'; +import { Alert } from './../../_components/Alert'; + + +function PopUpEditScheduleYear(props) { + const alert = useSelector(state => state.alert); + const dispatch = useDispatch(); + const schedules = useSelector(state => state.schedules.dataAddScheduleYear); + const [inputs, setInputs] = useState({ + content: schedules.content + }); + const [submitted, setSubmitted] = useState(false); + let { width } = props; + + + function close() { + dispatch({ + 'type': popupConstants.CLEAR_ALL_POPUP, + }) + } + + function hanldeForm() { + setSubmitted(true); + if (validateParam()) { + if (schedules.action === 'add') { + dispatch(scheduleActions.addScheduleYear({ + ...schedules, + content: inputs.content + })); + } else { + dispatch(scheduleActions.editScheduleYear({ + ...schedules, + content: inputs.content + })); + } + } + + } + + function handleChange(e) { + const { name, value } = e.target; + setInputs(inputs => ({ ...inputs, [name]: value })); + } + + function validateParam() { + return (inputs.content.trim()) ? true : false; + } + + return ( + + + ); +} + +export { PopUpEditScheduleYear }; \ No newline at end of file diff --git a/src/_components/Popup/PopUpFilter.js b/src/_components/Popup/PopUpFilter.js new file mode 100644 index 0000000..ec87a9a --- /dev/null +++ b/src/_components/Popup/PopUpFilter.js @@ -0,0 +1,842 @@ +import React, { Fragment, useEffect, useState } from "react"; +import "./style.css"; +import { useSelector, useDispatch } from "react-redux"; +import { studentActions, teacherActions } from "../../_actions"; +import { configConstants, curriculumConstants } from "../../_constants"; +import { useParams } from "react-router-dom"; +import { SelectDate } from "../../_components/Calendar"; + +import moment from "moment"; +import { filter, isEmpty } from "lodash"; +import { history } from "../../_helpers"; + +function PopUpFilter(props) { + const { id } = useParams(); + + const paramFilter = useSelector((state) => state.curriculums.filters.param); + const fromPageRedux = useSelector((state) => state.curriculums.fromPage); + const search = history?.location?.search; + const params = new URLSearchParams(search); + const assign = params?.get("assign"); + const user_id = params?.get("user_id"); + + let { + width, + onClickNo, + filter_files, + actionResetFilter, + filter_curriculum, + filter_exercise, + filter_level, + filter_exercise_more, + class_name, + filter_exercise_without_class, + isHideRangeDate, + type, + setExerciseHistory, + listExerciseHistory, + setOffset, + setLoadMore, + setOffsetOrigin, + fromPage, + } = props; + + const [filters, setFilters] = useState(paramFilter); + const dispatch = useDispatch(); + + useEffect(() => { + switch (fromPage) { + case "morepage": { + dispatch({ + type: curriculumConstants.FROM_PAGE_STATUS, + data: "morepage", + }); + break; + } + case "curriculum": + dispatch({ + type: curriculumConstants.FROM_PAGE_STATUS, + data: "curriculum", + }); + break; + case "classmanager": + dispatch({ + type: curriculumConstants.FROM_PAGE_STATUS, + data: "classmanager", + }); + break; + default: + ""; + } + }, []); + + useEffect(() => { + dispatch(studentActions.getAllGrade()); + }, []); + + const grades = useSelector((state) => state.grades); + + function handleChange(e, type) { + if (type) { + // console.log(type); + } + const { name, value } = e.target; + let filterParam = filters; + let tempValue = filters[name]; + const index = tempValue.indexOf(value); + if (value === 'Test') { + if(tempValue?.includes('mini_test') && tempValue?.includes('exam')) { + tempValue = tempValue?.map((item) => { + if (item === 'mini_test' || item === 'exam') + return null; + return item; + })?.filter(item => !!item); + } else { + const index = tempValue.indexOf('Test'); + if (index === -1) { + tempValue = [...tempValue, 'Test']; + } else { + tempValue = tempValue.filter((item) => item !== 'Test'); + } + } + } else { + if (index === -1) { + tempValue = [...tempValue, value]; + } else { + tempValue = tempValue.filter((item) => item !== value); + } + } + switch (name) { + case "grade_id": + setFilters((filters) => ({ ...filters, grade_id: tempValue })); + break; + case "level": + setFilters((filters) => ({ ...filters, level: tempValue })); + break; + case "skill": + setFilters((filters) => ({ ...filters, skill: tempValue })); + break; + case "type": + setFilters((filters) => ({ ...filters, type: tempValue })); + break; + } + } + + function handleChangeTopic(e) { + const { value } = e.target; + setFilters((filters) => ({ ...filters, topic: value })); + } + + function handleSubmit(e) { + e.preventDefault(); + let filterFile = filters; + let skills = filters.skill; + if (filters.skill.indexOf("Test") !== -1) { + skills = skills.filter((skill) => skill !== "Test"); + // skills = [...skills, "mini_test", "exam"] + skills = [...skills, "mini_test", "exam"]; + } + let paramsFilter = { ...filters, skill: skills }; + onClickNo && onClickNo(); + // console.log(paramsFilter) + if (filter_files) { + dispatch(teacherActions.getFileExercise(filterFile)); + } + if (filter_curriculum) { + let assignAndUserID = { + assign: assign, + user_id: user_id, + }; + dispatch( + teacherActions.filterSkill( + paramsFilter, + null, + null, + null, + null, + null, + fromPageRedux, + !isEmpty(assign && user_id) ? assignAndUserID : "" + ) + ); + } + if (filter_exercise && !filter_exercise_without_class) { + setLoadMore(true); + setOffset(0); + _.isEmpty(paramsFilter.level) && + _.isEmpty(paramsFilter.skill) && + _.isEmpty(paramsFilter.end_time) && + _.isEmpty(paramsFilter.start_time) + ? type == "class_mark" + ? dispatch( + teacherActions.getListHomeWork( + id, + "class_mark", + configConstants.DEFAULT_LIMIT, + 0, + listExerciseHistory + ) + ).then((res) => { + setExerciseHistory(res.data); + }) + : dispatch( + teacherActions.getHistoryExercise( + id, + paramsFilter, + "class", + configConstants.DEFAULT_LIMIT, + 0, + listExerciseHistory + ) + ).then((res) => { + setExerciseHistory(res.data); + setLoadMore(res.data?.length == configConstants.DEFAULT_LIMIT); + }) + : type == "class_mark" + ? dispatch( + teacherActions.getHistoryExercise( + id, + paramsFilter, + "class_mark", + configConstants.DEFAULT_LIMIT, + 0, + listExerciseHistory + ) + ).then((res) => { + setExerciseHistory(res.data); + setLoadMore(res.data?.length == configConstants.DEFAULT_LIMIT); + }) + : dispatch( + teacherActions.getHistoryExercise( + id, + paramsFilter, + "class", + configConstants.DEFAULT_LIMIT, + 0, + listExerciseHistory + ) + ).then((res) => { + setExerciseHistory(res.data); + }); + } + if (filter_exercise_more || filter_exercise_without_class) { + dispatch( + teacherActions.getHistoryExerciseWithoutClass(paramsFilter, true) + ); + } + dispatch({ + type: curriculumConstants.ADD_PARAM_FILTER_CURRICULUM, + param: filters, + }); + if ( + isEmpty(paramsFilter.level) && + isEmpty(paramsFilter.skill) && + isEmpty(paramsFilter.grade_id) + ) { + setOffset && setOffset(0); + setOffsetOrigin && setOffsetOrigin(0); + } + } + + function resetFilter() { + // dispatch({ + // type: curriculumConstants.CLEAR_PARAM_FILTER_CURRICULUM + // }); + setOffset && setOffset(0); + setOffsetOrigin && setOffsetOrigin(0); + let newFilters = { + topic: "", + skill: [], + level: [], + grade_id: [], + type: [], + start_time: "", + end_time: "", + }; + setFilters(newFilters); + // dispatch({ + // type: curriculumConstants.ADD_PARAM_FILTER_CURRICULUM, + // param: newFilters + // }); + if (actionResetFilter) { + actionResetFilter(newFilters); + } + } + + function validateParam() { + if (filters.start_time && filters.end_time) { + return true; + } else if (filter_files) { + return filters.skill.length || + filters.type.length || + filters.grade_id.length + ? true + : false; + } else { + if ( + (filter_exercise_more || + filter_exercise || + filter_exercise_without_class) && + filters.start_time > filters.end_time + ) { + return false; + } else { + return filters.topic || + filters.skill.length || + filters.level.length || + filters.grade_id.length + ? true + : false; + } + } + } + + function isDisableSubmit() { + if ( + filters.start_time && + filters.end_time && + filters.start_time > filters.end_time + ) { + return true; + } + return false; + } + + let isEndTimeLessThanFromTime = + filters.start_time && + filters.end_time && + filters.start_time > filters.end_time; + + return ( + + ); +} + +export { PopUpFilter }; diff --git a/src/_components/Popup/PopUpHelp.js b/src/_components/Popup/PopUpHelp.js new file mode 100644 index 0000000..f25d6ff --- /dev/null +++ b/src/_components/Popup/PopUpHelp.js @@ -0,0 +1,21 @@ +import React, { Fragment } from 'react'; +import './style.css'; + +function PopUpHelp(props) { + let { onClickNo, width} = props; + return ( + + + ); +} + +export { PopUpHelp }; \ No newline at end of file diff --git a/src/_components/Popup/PopUpOnlyOneButton.js b/src/_components/Popup/PopUpOnlyOneButton.js new file mode 100644 index 0000000..5dff88c --- /dev/null +++ b/src/_components/Popup/PopUpOnlyOneButton.js @@ -0,0 +1,30 @@ +import React, { Fragment } from 'react'; +import './style.css'; + +function PopUpOnlyOneButton(props) { + let { message, onClickNo, labelNo, width } = props; + return ( + + + ); +} + +export { PopUpOnlyOneButton }; \ No newline at end of file diff --git a/src/_components/Popup/PopUpRadio.js b/src/_components/Popup/PopUpRadio.js new file mode 100644 index 0000000..d959025 --- /dev/null +++ b/src/_components/Popup/PopUpRadio.js @@ -0,0 +1,131 @@ +import React, { useState } from "react"; +import "./style.css"; +import { useSelector, useDispatch } from "react-redux"; +import { scheduleConstants, userConstants } from "./../../_constants"; +import { scheduleActions } from "./../../_actions"; +import { Alert } from "./../../_components/Alert"; + +function PopUpRadio({ selectedDate, student }) { + const alert = useSelector((state) => state.alert); + const schedules = useSelector((state) => state.schedules.delete_schedule); + const authentication = useSelector((state) => state.authentication); + const dispatch = useDispatch(); + const [updateAll, setupdateAll] = useState(schedules.updateAll); + function close() { + dispatch({ + type: scheduleConstants.RESET_DELETE_SCHEDULE_DAY, + }); + } + + function deleteSchedule() { + dispatch({ + type: scheduleConstants.SET_DATE_SELECTED_CALENDAR, + time: schedules.dateSelectedCalendar + ? schedules?.dateSelectedCalendar + : schedules?.selectDate, + }); + if (schedules.repeatType == "no_repeat") { + dispatch( + scheduleActions.deleteSchedule( + { + id: schedules.id, + user_id: authentication.id, + update_all: 0, + selectedDate, + }, + schedules.dateSelectedCalendar + ? schedules?.dateSelectedCalendar + : schedules?.selectDate, + authentication.role === userConstants.ROLE_STUDENT + ) + ); + } else { + dispatch( + scheduleActions.deleteSchedule( + { + id: schedules.id, + user_id: authentication.id, + update_all: updateAll, + selectedDate, + }, + schedules.dateSelectedCalendar + ? schedules?.dateSelectedCalendar + : schedules?.selectDate, + authentication.role === userConstants.ROLE_STUDENT + ) + ); + } + + dispatch( + scheduleActions.getScheduleToday( + authentication.id, + schedules.dateSelectedCalendar + ? schedules?.dateSelectedCalendar + : schedules?.selectDate + ) + ); + } + + if (schedules.showForm) { + return ( + + ); + } else { + return null; + } +} + +export { PopUpRadio }; diff --git a/src/_components/Popup/PopUpRemind.js b/src/_components/Popup/PopUpRemind.js new file mode 100644 index 0000000..574076c --- /dev/null +++ b/src/_components/Popup/PopUpRemind.js @@ -0,0 +1,68 @@ +import React, { useState } from 'react'; +import './style.css'; +import { useSelector, useDispatch } from 'react-redux'; +import { teacherConstants, popupConstants } from './../../_constants'; +import { teacherActions } from './../../_actions'; +import { Alert } from './../../_components/Alert'; + + + +function PopUpRemind(props) { + + const alert = useSelector(state => state.alert); + const dispatch = useDispatch(); + const [submitted, setSubmitted] = useState(false); + let { width } = props; + + const [inputs, setInputs] = useState({ + content: '' + }); + + + function validateParam() { + return (inputs.content) ? true : false; + } + + function close() { + dispatch({ + 'type': popupConstants.CLEAR_ALL_POPUP, + }) + } + + function handleChange(e) { + const { name, value } = e.target; + setInputs(inputs => ({ ...inputs, [name]: value })); + } + + function hanldeForm() { + setSubmitted(true); + if (validateParam()) { + let list_user_exercise_id = props.listStudentIdAll; + let dataRemind = { + list_user_exercise_id, + msg: inputs.content, + exercise_id: props.exercise_id, + class_id: props.class_id, + } + dispatch(teacherActions.remindStudent(dataRemind)); + } + } + + return ( + + + ); +} + +export { PopUpRemind }; \ No newline at end of file diff --git a/src/_components/Popup/PopUpRemoveStudentInClass.js b/src/_components/Popup/PopUpRemoveStudentInClass.js new file mode 100644 index 0000000..f83221d --- /dev/null +++ b/src/_components/Popup/PopUpRemoveStudentInClass.js @@ -0,0 +1,20 @@ +import React from 'react'; +import './style.css'; + +function PopUpRemoveStudentInClass(props) { + let { message, onClickYes, onClickNo , width} = props; + return ( + + + ); +} + +export { PopUpRemoveStudentInClass }; \ No newline at end of file diff --git a/src/_components/Popup/PopUpResentEmail.js b/src/_components/Popup/PopUpResentEmail.js new file mode 100644 index 0000000..3abcca9 --- /dev/null +++ b/src/_components/Popup/PopUpResentEmail.js @@ -0,0 +1,58 @@ +import React, { Fragment } from "react"; +import "./style.css"; + +function PopUpResentEmail(props) { + let { + message, + onClickNo, + labelNo, + width, + hideButtonNo, + styleGroupBtn, + title, + msgResentEmail, + handleResentEmail, + } = props; + return ( + + ); +} + +export { PopUpResentEmail }; diff --git a/src/_components/Popup/PopUpResetTimeTable.js b/src/_components/Popup/PopUpResetTimeTable.js new file mode 100644 index 0000000..f77aa7a --- /dev/null +++ b/src/_components/Popup/PopUpResetTimeTable.js @@ -0,0 +1,35 @@ +import React from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { scheduleActions } from './../../_actions'; +import { Alert } from './../../_components/Alert'; +import { scheduleConstants } from './../../_constants'; + +import './style.css'; + +function PopUpResetTimeTable(props) { + let { onClose, width } = props; + const dispatch = useDispatch(); + const alert = useSelector(state => state.alert); + + function resetTimeTable() { + onClose() + dispatch(scheduleActions.resetTimeTable()); + } + + return ( + + + ); +} + +export { PopUpResetTimeTable }; \ No newline at end of file diff --git a/src/_components/Popup/PopUpSelectObjectRollUp.js b/src/_components/Popup/PopUpSelectObjectRollUp.js new file mode 100644 index 0000000..f9abe31 --- /dev/null +++ b/src/_components/Popup/PopUpSelectObjectRollUp.js @@ -0,0 +1,36 @@ + import React, { useState } from 'react'; +function PopUpSelectObjectRollUp(props) { + let { onClickNo, onClickYes, title } = props; + const [inputs, setInputs] = useState({ + send_content: 'student' + }); + + + function handleSubmit() { + onClickYes(inputs.send_content); + onClickNo(); + } + + return ( + + + ); +} + +export { PopUpSelectObjectRollUp }; \ No newline at end of file diff --git a/src/_components/Popup/PopUpSetCriteria.js b/src/_components/Popup/PopUpSetCriteria.js new file mode 100644 index 0000000..12f71bb --- /dev/null +++ b/src/_components/Popup/PopUpSetCriteria.js @@ -0,0 +1,246 @@ +import React, { useState, Fragment, useEffect } from "react"; +import "./style.css"; +import { isEmpty, forEach, result } from "lodash"; +import { validateNumber } from "../../_base/Validate"; + +function PopUpSetCriteria(props) { + let { + onClickYes, + onClickNo, + criteria, + exercise_id, + width, + exercise_selected, + } = props; + + let [dataCriteria, setDataCriteria] = useState([]); + const [changeProportion, setChangeProportion] = useState("-1"); + + useEffect(() => { + let list = []; + criteria.forEach((item) => { + list.push({ + proportion: item.proportion, + text: item.text, + }); + }); + setDataCriteria(list); + }, [criteria]); + + function remove(key) { + setChangeProportion("-1"); + let list = dataCriteria.filter((item, index) => index != key); + setDataCriteria(list); + } + + function add() { + let item = { + proportion: 0, + text: "", + }; + setDataCriteria([...dataCriteria, item]); + } + + function validateParam() { + let count = countTotalPercent(); + forEach(dataCriteria, function (value) { + if (isEmpty(value.text)) { + return false; + } + }); + if (count !== 100) { + return false; + } + return true; + } + + function countTotalPercent() { + let count = 0; + forEach(dataCriteria, function (value) { + count += parseInt(value.proportion); + }); + return count; + } + + function handleChange(e, key) { + const { name, value } = e.target; + let criterias = []; + dataCriteria.forEach((item, index) => { + if (index === key) { + let data = { + proportion: item.proportion, + text: item.text, + score: item.score, + }; + if (name === "text") { + data.text = value; + } else { + data.proportion = validateNumber(value); + } + criterias.push(data); + } else { + criterias.push(item); + } + }); + // dataCriteria[key][name] = value; + setDataCriteria(criterias); + } + + const handleChangeProportion = (e, key) => { + const { value } = e.target; + let criterias = []; + dataCriteria.forEach((item, index) => { + if (index == key) { + let data = { + proportion: item.proportion, + text: item.text, + score: item.score, + }; + const regex = /^[0-9]+$/; + setChangeProportion(key); + if (regex.test(value)) { + data.proportion = value == "%" ? 0 : validateNumber(value); + data.proportion = value == "" ? 0 : validateNumber(value); + criterias.push(data); + } else { + data.proportion = 0; + criterias.push(data); + } + } else { + criterias.push(item); + } + }); + // dataCriteria[key][name] = value; + setDataCriteria(criterias); + }; + + let [DataExerciseId, setDataExerciseId] = useState(exercise_selected); + + // Handle Blur Proportion + const handleBlurProportion = (e, key) => { + setChangeProportion("-1"); + }; + + return ( + + ); +} + +export { PopUpSetCriteria }; diff --git a/src/_components/Popup/PopUpShowTimeTable.js b/src/_components/Popup/PopUpShowTimeTable.js new file mode 100644 index 0000000..2c5a2d2 --- /dev/null +++ b/src/_components/Popup/PopUpShowTimeTable.js @@ -0,0 +1,47 @@ +import React from 'react'; +import { useDispatch } from 'react-redux'; +import { scheduleActions } from './../../_actions'; +import './style.css'; +import $ from "jquery"; + +function PopUpShowTimeTable(props) { + let { onClickClose, onClickEdit, onClickDelete, titleButtonDone, titleButtonCancel, width, dataEditTimeTable } = props; + const dispatch = useDispatch(); + + function deleteTimeTable() { + onClickDelete(); + $(".loading").removeClass("hide"); + dispatch(scheduleActions.deleteTimeTable(dataEditTimeTable.id)); + } + + return ( + + + ); +} + +export { PopUpShowTimeTable }; \ No newline at end of file diff --git a/src/_components/Popup/PopUpSusscess.js b/src/_components/Popup/PopUpSusscess.js new file mode 100644 index 0000000..65860d4 --- /dev/null +++ b/src/_components/Popup/PopUpSusscess.js @@ -0,0 +1,20 @@ +import React from 'react'; +import { alertActions } from '../../_actions'; +import { useDispatch } from 'react-redux'; + +function PopUpSuccess(props) { + if(props?.visible) { + return ( + ) + } + return null +} + +export { PopUpSuccess }; \ No newline at end of file diff --git a/src/_components/Popup/PopUpVovabularyDetail.js b/src/_components/Popup/PopUpVovabularyDetail.js new file mode 100644 index 0000000..c4a467c --- /dev/null +++ b/src/_components/Popup/PopUpVovabularyDetail.js @@ -0,0 +1,113 @@ +import React, { useRef, useEffect } from 'react'; + +var audioElement; +function PopUpVocabularyDetail(props) { + let { width, data, img_url, close } = props; + + const [tab, set_tab] = React.useState(false) + const ref = useRef(); + + useOnClickOutside(ref, () => close(false)); + + // console.log(data) + + function getImage(imageJson) { + const myObject = JSON.parse(imageJson); + myObject.forEach(element => { + const index = element.search('300x200'); + if (index >= 0) { + return element; + } + }); + return myObject[0]; + } + + function handleClickItem(e, $url) { + e.preventDefault(); + if (audioElement) { + audioElement.pause(); + } + audioElement = new Audio($url); + const playPromise = audioElement.play(); + + if (playPromise !== undefined) { + playPromise + .then(_ => { + // Automatic playback started! + // Show playing UI. + console.log("audio played auto"); + }) + .catch(error => { + // Auto-play was prevented + // Show paused UI. + console.log("playback prevented"); + }); + } + } + + function useOnClickOutside(ref, handler) { + useEffect( + () => { + const listener = (event) => { + // Do nothing if clicking ref's element or descendent elements + if (!ref.current || ref.current.contains(event.target)) { + return; + } + handler(event); + }; + document.addEventListener("mousedown", listener); + document.addEventListener("touchstart", listener); + return () => { + document.removeEventListener("mousedown", listener); + document.removeEventListener("touchstart", listener); + }; + }, + [ref, handler] + ); + } + + return ( + + ) +} + +export { PopUpVocabularyDetail }; \ No newline at end of file diff --git a/src/_components/Popup/PopUpYesNo.js b/src/_components/Popup/PopUpYesNo.js new file mode 100644 index 0000000..b61cd6e --- /dev/null +++ b/src/_components/Popup/PopUpYesNo.js @@ -0,0 +1,82 @@ +import React, { Fragment } from "react"; +import "./style.css"; + +function PopUpYesNo(props) { + let { + message, + onClickYes, + onClickNo, + labelYes, + labelNo, + width, + btnCloseBlue, + hideButtonNo, + hideButtonYes, + styleGroupBtn, + title, + customWidthBtn, + } = props; + return ( + + ); +} + +export { PopUpYesNo }; diff --git a/src/_components/Popup/PopUpZoomImage.js b/src/_components/Popup/PopUpZoomImage.js new file mode 100644 index 0000000..51af169 --- /dev/null +++ b/src/_components/Popup/PopUpZoomImage.js @@ -0,0 +1,34 @@ +import React from "react"; +import "./style.css"; + +function PopUpZoomImage(props) { + let { onClickNo, src, width } = props; + return ( + + ); +} + +export { PopUpZoomImage }; diff --git a/src/_components/Popup/PopUpZoomImageV2.js b/src/_components/Popup/PopUpZoomImageV2.js new file mode 100644 index 0000000..98430bc --- /dev/null +++ b/src/_components/Popup/PopUpZoomImageV2.js @@ -0,0 +1,66 @@ +import React from "react"; +import { useState } from "react"; +import "./style.css"; + +function PopUpZoomImageV2(props) { + let { onClickNo, src, width, height } = props; + + const [valueRotated, setValueRotated] = useState(90); + + const rotateImage = () => { + document.querySelector( + ".image_zoom" + ).style.transform = `rotate(${valueRotated}deg)`; + setValueRotated(valueRotated + 90); + }; + + return ( + + ); +} + +export { PopUpZoomImageV2 }; diff --git a/src/_components/Popup/PopupFilterV2.js b/src/_components/Popup/PopupFilterV2.js new file mode 100644 index 0000000..82a3251 --- /dev/null +++ b/src/_components/Popup/PopupFilterV2.js @@ -0,0 +1,601 @@ +import React, { Fragment, useEffect, useState } from "react"; +import "./style.css"; +import { useSelector, useDispatch } from "react-redux"; +import { studentActions, teacherActions } from "../../_actions"; +import { curriculumConstants } from "../../_constants"; +import { useParams } from "react-router-dom"; +import { SelectDate } from "../../_components/Calendar"; + +import moment from "moment"; + +function PopUpFilterV2(props) { + let { + width, + onClickNo, + isFilterByKeyWord, + isFilterByRangeDate, + isFilterBySkill, + isFilterByGrade, + isFilterByLevel, + isFilterByFormat, + onSubmitFilter, + paramFilter, + } = props; + + const [filters, setFilters] = useState(paramFilter); + const grades = useSelector((state) => state.grades); + + const dispatch = useDispatch(); + + useEffect(() => { + if (isFilterByGrade) { + dispatch(studentActions.getAllGrade()); + } + }, [isFilterByGrade]); + + function handleChange(e) { + const { name, value } = e.target; + let tempValue = filters[name]; + const index = tempValue.indexOf(value); + if (index === -1) { + tempValue = [...tempValue, value]; + } else { + tempValue = tempValue.filter((item) => item !== value); + } + switch (name) { + case "grade_id": + setFilters((filters) => ({ ...filters, grade_id: tempValue })); + break; + case "level": + setFilters((filters) => ({ ...filters, level: tempValue })); + break; + case "skill": + setFilters((filters) => ({ ...filters, skill: tempValue })); + break; + case "type": + setFilters((filters) => ({ ...filters, type: tempValue })); + break; + } + } + + function handleChangeTopic(e) { + const { value } = e.target; + setFilters((filters) => ({ ...filters, topic: value })); + } + + function handleSubmit(e) { + e.preventDefault(); + onSubmitFilter(filters); + onClickNo && onClickNo(); + } + + function resetFilter() { + let newFilters = { + topic: "", + skill: [], + level: [], + grade_id: [], + type: [], + start_time: "", + end_time: "", + }; + setFilters(newFilters); + } + + function validateParam() { + if (isFilterByKeyWord && filters.topic) { + return true; + } else if (isFilterByRangeDate && filters.start_time && filters.end_time) { + return true; + } else if (isFilterBySkill && filters.skill.length) { + return true; + } else if (isFilterByLevel && filters.level.length) { + return true; + } else if (isFilterByGrade && filters.grade_id.length) { + return true; + } else if (isFilterByFormat && filters.type.length) { + return true; + } + return false; + } + + function isDisableSubmit() { + if ( + filters.start_time && + filters.end_time && + filters.start_time > filters.end_time + ) { + return true; + } + return false; + } + + let isEndTimeLessThanFromTime = + filters.start_time && + filters.end_time && + filters.start_time > filters.end_time; + + return ( + + ); +} + +export { PopUpFilterV2 }; diff --git a/src/_components/Popup/index.js b/src/_components/Popup/index.js new file mode 100644 index 0000000..2027d39 --- /dev/null +++ b/src/_components/Popup/index.js @@ -0,0 +1,25 @@ +export * from "./PopUpYesNo"; +export * from "./PopUpRadio"; +export * from "./PopUpEditScheduleYear"; +export * from "./PopUpAddTimeTable"; +export * from "./PopUpShowTimeTable"; +export * from "./PopUpResetTimeTable"; +export * from "./PopUpRemoveStudentInClass"; +export * from "./PopUpFilter"; +export * from "./PopUpAddStudent"; +export * from "./PopUpAddRollUp"; +export * from "./PopUpAddCommentRollUp"; +export * from "./PopUpSelectObjectRollUp"; +export * from "./PopUpAddFile"; +export * from "./PopUpAddSchedule"; +export * from "./PopUpOnlyOneButton"; +export * from "./PopUpApplyClass"; +export * from "./PopUpZoomImage"; +export * from "./PopUpEditHomeWork"; +export * from "./PopUpSetCriteria"; +export * from "./PopUpHelp"; +export * from "./PopUpRemind"; +export * from "./PopUpVovabularyDetail"; +// export * from './PopupStudyGuild'; +export * from "./PopupFilterV2"; +export * from "./PopUpResentEmail"; diff --git a/src/_components/Popup/style.css b/src/_components/Popup/style.css new file mode 100644 index 0000000..39529eb --- /dev/null +++ b/src/_components/Popup/style.css @@ -0,0 +1,876 @@ +.uk-modal-body { + border-radius: 20px; + box-shadow: 0 1px 6px 0 rgba(21, 27, 38, 0.15); +} + +.uk-modal-dialog { + width: auto; + width: 340px; +} + +.btn-default { + padding: 0 35px; + height: 40px; + line-height: 37px; + border-radius: 20px; + border: 2px solid #00a69c; + font-size: 16px; + color: #00a69c; + /* transition: 0.8s; */ + background: #fff; + font-family: "Myriadpro-SemiBold"; + box-sizing: border-box; + width: 130px; +} + +.btn-bg-blue { + background-image: linear-gradient(to right, #00e1a0, #00b9b7); + color: #fff; + border: none; +} + +.btn-popup-gr { + margin: 20px 0 0; +} + +.popup-title { + font-size: 18px; + padding: 0 0 20px; +} + +.uk-modal-body p { + font-size: 16px; +} + +.radio-gr input { + margin: -2px 8px 0 0; +} + +.radio-body { + padding: 0 20px; + display: flex; + justify-content: center; +} + +.btn-popup-gr button:nth-child(1) { + margin-right: 10px; +} + +.btn-popup-gr button:nth-child(2) { + margin-left: 10px; +} + +.message-body textarea { + width: 100%; + outline: none; + resize: none; + background: #ececec; + color: #000; + border: none; + border-radius: 20px; + padding: 20px; + box-sizing: border-box; + font-family: "Myriadpro-SemiBold"; + font-size: 16px; +} + +.message-body textarea::-webkit-input-placeholder { + /* Edge */ + color: #000; +} + +.message-body textarea:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + color: #000; +} + +.message-body textarea::placeholder { + color: #000; +} + +.title-span { + font-family: "Myriadpro-Bold"; + font-size: 16px; + display: block; + padding: 0 0 5px; +} + +.time-start-end-gr { + background: #b2eee7; + border-radius: 20px; + border: none; + margin: 0 0 4px; +} + +.time-start-end-gr .start, +.time-start-end-gr .end { + padding: 15px 0; + border-radius: 20px; + border: none; + box-sizing: border-box; + width: 150px; +} + +.time-start-end-gr .start input, +.time-start-end-gr .end input { + box-sizing: border-box; + width: 150px; +} + +.time-start-end-gr .active { + background-image: linear-gradient(to right, #00e2a0, #00b9b7); +} + +.time-start-end-gr p { + text-align: center; + font-size: 18px; + line-height: 20px; + box-sizing: border-box; +} + +.time-start-end-gr input { + background: none; + border: none; + box-shadow: none; + text-align-last: center; + font-family: "Myriadpro-Bold"; + font-size: 16px; + outline: none; +} + +.showtime-gr { + margin: 0 0 15px; +} + +.showtime-gr p { + font-size: 14px; + text-align: center; + line-height: 24px; +} + +.showtime-gr .day { + position: absolute; + left: 0; + top: 0; + font-size: 24px; + line-height: 24px; + font-family: "Myriadpro-Bold"; + color: #00a79d; +} + +.filter-popup-title { + margin: 0 0 20px; +} + +.filter-popup-title h2 { + font-size: 24px; + line-height: 24px; + font-family: "Myriadpro-Bold"; + color: #00a79d; + padding-left: 5px; +} + +.ico_filter_blue { + height: 17px; + margin-top: 3px; +} + +.title-sp { + font-size: 18px; + line-height: 20px; + font-family: "Myriadpro-Bold"; + padding: 0 0 0 20px; + margin: 0 0 10px; + color: #01283a; + display: block; +} + +.title-sp.pad-00 { + padding: 0; +} + +.popup-filter-option { + overflow: auto; +} + +.popup-filter-option .pad-020 .title-sp { + padding: 0; +} + +.input-search { + height: 50px; + width: 100%; + border-radius: 25px; + box-sizing: border-box; + background: #eeeeee; + color: #000; + font-family: "Myriadpro-Regular"; + border: none; + outline: none; + padding-left: 20px; + font-size: 16px; + margin: 0 0 25px; +} + +.input-search::placeholder { + /* Chrome, Firefox, Opera, Safari 10.1+ */ + color: #000; + opacity: 0.5; + /* opacity: 1; Firefox */ + font-family: "Myriadpro-Regular"; +} + +.input-search:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + color: #000; + font-family: "Myriadpro-Regular"; +} + +.input-search::-ms-input-placeholder { + /* Microsoft Edge */ + color: #000; + font-family: "Myriadpro-Regular"; +} + +.pad-020 { + padding: 0 20px; +} + +.box-input { + margin: 0 0 15px; +} + +.chk-gr { + margin: 0 0 5px; +} + +.chk-gr input { + width: 20px; + height: 20px; + margin: -2px 5px 0 0; +} + +.chk-gr label { + color: #000; + font-family: "Myriadpro-Regular"; + font-size: 18px; +} + +.ico_close_popup { + cursor: pointer; +} + +.close-popup-ab { + position: absolute; + right: 12px; + top: 12px; + width: 22px; + height: 22px; + cursor: pointer; +} + +.pad0 { + padding: 0; +} + +.avt-pop { + width: 117px; + height: 117px; + border-radius: 50%; + background: #ccc; + position: absolute; + top: -65px; + left: calc(50% - 58px); + overflow: hidden; + border: 3px solid #e9af38; +} + +.avt-pop img { + width: 100%; + height: 100%; +} + +.title-student-pop { + padding: 0; + margin: 15px 0 20px; + font-size: 24px; + line-height: 28px; + max-height: 76px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +.title-student-pop.cutom-mg { + margin: 25px 0 0; +} + +.title24 { + font-size: 24px; + margin: 0; + padding: 0 0 10px; +} + +.title18 { + font-size: 18px; + margin: 0; + padding: 0 0 20px; +} + +.date-dd .react-datepicker-wrapper input { + background: rgb(0 203 173 / 30%); + outline: none; + border: none; + border-radius: 28px; + height: 56px; + width: 100%; + color: #231f20; + font-size: 18px; + text-align: center; +} + +.ico-calender-ab { + position: absolute; + top: 15px; + left: 20px; + cursor: pointer; +} + +.btn-create { + margin: 0 auto; +} + +.custom-area { + width: 100%; + height: 120px; + padding: 20px; + border: none; + border-radius: 20px; + resize: none; + box-sizing: border-box; + outline: none; + background: #ececec; + color: #000; + font-size: 18px; + font-family: "Myriadpro-Regular"; +} + +.custom-area::-webkit-input-placeholder { + /* Edge */ + color: #000; +} + +.custom-area:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + color: #000; +} + +.custom-area::placeholder { + color: #000; +} + +.text-center.form-sunE-button { + margin: 20px 0 0; +} + +.form-gr { + margin: 0 0 10px; +} + +.form-gr span { + display: block; + color: #231f20; + font-size: 18px; + padding: 0 0 5px 10px; + font-family: "Myriadpro-Regular"; +} + +.form-gr input:not([type="file"]) { + width: 100%; + line-height: 40px; + border-radius: 20px; + border: 1px solid #231f20; + outline: none; + box-sizing: border-box; + padding: 0 20px; + color: #231f20; + font-size: 18px; + font-family: "Myriadpro-Regular"; +} + +.input_files { + width: 100%; + height: 40px; + border-radius: 20px; + border: 1px solid #231f20; + border: 1px solid #231f20; + outline: none; + box-sizing: border-box; + padding: 0 20px; + color: #231f20; + font-size: 18px; + font-family: "Myriadpro-Regular"; +} + +.form-gr .input_files input[type="file"] { + color: transparent; + font-size: 1.1rem; + /* flex: 1; */ + min-width: 40%; + width: 40%; +} +/* .form-gr input[type="file"]::after { + position: relative; + content: "Chưa chọn tệp"; + color: #8e8e8e; + text-align: center; + left: -2rem; + font-size: 1rem; +} */ + +.form-gr input::-webkit-input-placeholder { + /* Edge */ + font-family: "Myriadpro-Regular"; +} + +.form-gr input:-ms-input-placeholder { + /* Internet Explorer 10-11 */ + font-family: "Myriadpro-Regular"; +} + +.form-gr input::placeholder { + font-family: "Myriadpro-Regular"; +} + +.khoi { + z-index: 10; +} + +.khoi .select-options { + z-index: 9; + max-height: 300px; +} + +.ky-nang { + z-index: 8; +} + +.ky-nang .select-options { + z-index: 7; + max-height: 200px; +} + +.uk-modal .uk-modal-body.showImg { + padding: 0; + border-radius: 0; +} + +.showImg { + height: calc(100vh - 200px); +} + +.zoomImg { + width: 100%; + height: 100%; +} + +.zoomImg img { + height: 100%; +} + +.btn-dkvl { + width: 164px; + padding: 0 20px; +} + +.title-sp-gray { + color: #686868; + font-size: 16px; + line-height: 135%; + font-family: "Myriadpro-Bold"; +} + +.uk-modal-body p.text-edit { + color: #00a69c; + font-size: 24px; + line-height: 135%; + font-family: "Myriadpro-Bold"; + margin: 0 0 15px; +} + +.input-text-gr input { + width: 100%; + height: 44px; + border-radius: 22px; + box-sizing: border-box; + outline: none; + border: 1px solid #7f7f7f; + padding: 0 15px; + font-size: 16px; + line-height: 44px; + font-family: "Myriadpro-Light"; + margin: 10px 0; +} + +.input-text-gr input::-webkit-input-placeholder { + /* Edge */ + font-family: "Myriadpro-Regular"; +} + +.input-text-gr input::-ms-input-placeholder { + /* Internet Explorer 10-11 */ + font-family: "Myriadpro-Regular"; +} + +.input-text-gr input::placeholder { + font-family: "Myriadpro-Regular"; +} + +.radio-gr-add-content { + margin: 0 0 10px; +} + +.radio-gr-add-content input { + margin-right: 10px; +} + +.mb-20 { + margin-bottom: 20px; +} + +.mb-10 { + margin-bottom: 10px; +} + +.set-180.class-slect-time .slect-time .react-datepicker__input-container input { + width: 170px; +} + +.break-all { + word-break: break-all; +} + +.t-title-w { + background: #00a69c; + padding: 8px 20px; + border-radius: 17px; +} + +.t-title-w p { + font-family: "Myriadpro-Bold"; + font-size: 16px; + color: #fff; +} + +.r-80 { + width: 80px; +} + +.r-100 { + width: 100px; +} + +.rm-20 { + width: 20px; +} + +.tc-list { + padding-right: 20px; +} + +.tc-content { + padding: 15px 10px 5px; + background: #e6e7e8; + border-radius: 20px; + margin: 10px 0; +} + +.tc-content.tc-sum { + padding: 10px; + margin-right: 20px; +} + +.tc-content.tc-sum p { + font-family: "Myriadpro-Bold"; + color: #000; +} + +.title-regular-black { + font-family: "Myriadpro-Regular"; + color: #000; + font-size: 16px; + margin: 0 0 10px; +} + +.tc-item { + padding: 5px 0; + border-bottom: 1px solid #787878; +} + +.tc-item:last-child { + border-bottom: none; +} + +.tc-item input { + color: #787878; + font-family: "Myriadpro-Regular"; + font-size: 16px; + border: none; + outline: none; + width: 100%; + box-sizing: border-box; + background: #e6e7e8; +} + +.tc-item .r-100 input { + text-align: center; + padding-right: 20px; +} + +.rm-btn { + position: absolute; + right: -35px; + top: 4px; + cursor: pointer; +} + +.btn-add-tc { + padding: 10px 0; +} + +.title-regular-black input[type="radio" i] { + margin: -2px 5px 0 0; +} + +.wd-c { + width: 130px; +} + +.chambai.writing .uk-modal-dialog { + width: auto; +} + +.help-popup h2 { + font-family: "Myriadpro-Regular"; + font-size: 24px; + color: #000; + margin: 0 0 20px; +} + +.help-popup p { + font-family: "Myriadpro-Regular"; + font-size: 16px; + color: #686868; + margin: 0 0 30px; +} + +@media screen and (max-height: 800px) { + .uk-modal-body .wh20.chk-custom-gr input:checked + label:after { + top: -8px; + } + + .set-180.class-slect-time + .slect-time + .react-datepicker__input-container + input { + width: 135px; + } + + .input-text-gr input { + height: 32px; + border-radius: 16px; + font-size: 16px; + line-height: 32px; + } + + .title-sp-gray { + font-size: 16px; + } +} + +@media screen and (max-height: 700px) { + .btn-default { + padding: 0 25px; + height: 32px; + line-height: 29px; + border-radius: 16px; + font-size: 13px; + width: 80px; + } + + .wd-c { + width: 100px; + } + + .uk-modal-body p { + font-size: 13px; + } + + .uk-modal-dialog { + width: auto; + width: 300px; + } + + .title24 { + font-size: 18px; + } + + .date-dd .react-datepicker-wrapper input { + border-radius: 20px; + height: 40px; + width: 100%; + font-size: 14px; + } + + .ico-calender-ab { + top: 8px; + left: 16px; + } + + .close-popup-ab { + position: absolute; + right: 12px; + top: 12px; + width: 18px; + height: 18px; + cursor: pointer; + } + + .lichngay-teacher .week-cell, + .lichngay-teacher .day-cell { + flex-basis: calc(100% / 7 - 24px); + margin: 5px 12px; + } + + .form-gr input { + height: 32px; + line-height: 32px; + border-radius: 16px; + padding-left: 16px; + font-size: 14px; + } + + .title-sp { + font-size: 14px; + line-height: 16px; + padding: 0 0 0 16px; + } + + .chk-gr label { + font-size: 14px; + } + + .custom-width { + width: 380px !important; + } + + .ico_close_popup { + width: 20px; + height: 20px; + } +} + +.__img-detail { + width: auto; + height: 200px; + border-radius: 20px; +} + +.__img-detail img { + width: 100%; + height: 100%; +} + +.__vocabulary span { + color: #00bbb5; + font-size: 18px; +} + +.__vi_mean { + font-family: "MyriadPro-SemiBold"; +} + +.justify-content-between { + justify-content: space-between; +} + +.title-modal { + font-family: "MyriadPro-SemiBold"; + margin-bottom: 20px; + justify-content: left; +} + +.title-modal .thumb2 { + left: 10px; +} + +.content-modal { + padding: 10px; + border: 1px solid #d3d3d3; + border-radius: 10px; + min-height: 150px; + overflow-y: auto; + overflow-x: hidden; + max-height: 250px; +} + +.btn-flash-popup-vocabulary { + border: none; + background: none; + position: absolute; + left: 45%; + bottom: -15px; +} + +.img-flash-popup-vocabulary { + width: 35px; + height: 35px; + background: #fff; + padding: 5px; + border-radius: 35%; +} + +/* Zoom in Image */ +.icon_image_container { + top: 0.5rem; + right: 1rem; +} + +.ico_image { + width: 2.2rem; + margin: 0.8rem; + cursor: pointer; +} + +.rotated-image { + -webkit-transform: rotate(45deg); + transform: rotate(45deg); +} + + +/* Popup Edit Homework */ + +.img_close_popup { + top: 10px; + right: 10px; + width: 1.8rem; + height: 1.8rem; + cursor: pointer; +} + +.info-container { + margin-top: 16px; + padding-left: 40px; +} + +.info-row-box { + display: flex; + width: 100%; + padding: 0 32px; +} + +.label-info-left { + width: 32%; +} \ No newline at end of file diff --git a/src/_components/Process/CricleProcess.js b/src/_components/Process/CricleProcess.js new file mode 100644 index 0000000..28d84cd --- /dev/null +++ b/src/_components/Process/CricleProcess.js @@ -0,0 +1,131 @@ +import React, { Fragment } from "react"; + +function CricleProcess(percent, size = 'small') { + return ( +
    + {(() => { + if (percent >= 0 && percent < 10) { + return ( + + process + {percent}% + + ); + } else if (percent >= 10 && percent < 20) { + return ( + + process + {percent}% + + ); + } else if (percent >= 20 && percent < 30) { + return ( + + process + {percent}% + + ); + } else if (percent >= 30 && percent < 40) { + return ( + + process + {percent}% + + ); + } else if (percent >= 40 && percent < 50) { + return ( + + process + {percent}% + + ); + } else if (percent >= 50 && percent < 60) { + return ( + + process + {percent}% + + ); + } else if (percent >= 60 && percent < 70) { + return ( + + process + {percent}% + + ); + } else if (percent >= 70 && percent < 80) { + return ( + + process + {percent}% + + ); + } else if (percent >= 80 && percent < 90) { + return ( + + process + {percent}% + + ); + } else if (percent >= 90 && percent < 100) { + return ( + + process + {percent}% + + ); + }else if (percent >= 100) { + return ( + + process + + ); + } else { + return ( + + process + + ); + } + })()} +
    + ); +} + +export { CricleProcess }; diff --git a/src/_components/Process/index.js b/src/_components/Process/index.js new file mode 100644 index 0000000..4005b98 --- /dev/null +++ b/src/_components/Process/index.js @@ -0,0 +1 @@ +export * from './CricleProcess'; \ No newline at end of file diff --git a/src/_components/Router/RouteRedirectToAdmin.js b/src/_components/Router/RouteRedirectToAdmin.js new file mode 100644 index 0000000..244f704 --- /dev/null +++ b/src/_components/Router/RouteRedirectToAdmin.js @@ -0,0 +1,30 @@ +import React from "react"; +import { Route, Redirect } from "react-router-dom"; +import PropTypes from "prop-types"; +import { TypeHeaderNewsItem } from "../../_constants/headerNews"; +import { HomePage } from "../../_screens"; + +export const RouteRedirectToAdmin = ({ + component: Component, + additionalProps, + ...rest +}) => { + return ( + { + return ( +
    + +
    + ); + }} + /> + ); +}; + +RouteRedirectToAdmin.propTypes = { + location: PropTypes.any, + component: PropTypes.any, +}; diff --git a/src/_components/Router/RouteRedirectToLogin.js b/src/_components/Router/RouteRedirectToLogin.js new file mode 100644 index 0000000..13693d8 --- /dev/null +++ b/src/_components/Router/RouteRedirectToLogin.js @@ -0,0 +1,42 @@ +import React, { Fragment } from 'react'; +import { Route, Redirect } from 'react-router-dom'; +import PropTypes from 'prop-types'; +import { SideBar } from './../Admin/SideBar'; +import { useSelector } from 'react-redux'; + +export const RouteRedirectToLogin = ({ component: Component, noSideBar: noSideBar, containerClassName ,...rest }) => { + const sideBarRootLessness = useSelector(state => state.rootlessness.sideBarRootLessness) + return ( + { + if (rest.authentication.isLogin) { + if (rest.authentication.role === rest.prefix) { + if(containerClassName) { + return ( +
    + {noSideBar && sideBarRootLessness ? null : } + +
    + ) + } + return ( + + {noSideBar && sideBarRootLessness ? null : } + + + + ) + } else { + return + } + + } else { + return + } + }} /> + ); +}; + +RouteRedirectToLogin.propTypes = { + location: PropTypes.any, + component: PropTypes.any, +}; diff --git a/src/_components/Router/index.js b/src/_components/Router/index.js new file mode 100644 index 0000000..26f5407 --- /dev/null +++ b/src/_components/Router/index.js @@ -0,0 +1,2 @@ +export * from './RouteRedirectToAdmin'; +export * from './RouteRedirectToLogin'; \ No newline at end of file diff --git a/src/_components/ScrollFixed/ScrollFixed.jsx b/src/_components/ScrollFixed/ScrollFixed.jsx new file mode 100644 index 0000000..0355e35 --- /dev/null +++ b/src/_components/ScrollFixed/ScrollFixed.jsx @@ -0,0 +1,47 @@ +import "./ScrollFixed.style.scss"; +import { scrollFixedLogic } from "./ScrollFixed.logic"; +import { TypeHeaderNewsItem } from "../../_constants/headerNews"; + +const ScrollFixed = () => { + let { handleScrollTop, handleNavigate } = scrollFixedLogic(); + + return ( + <> +
    +
    handleNavigate('/'+TypeHeaderNewsItem.HOME)}> + Icon phu huynh +
    +
    + Icon Scroll Up +
    +
    +
    +
    +
    handleNavigate('/'+TypeHeaderNewsItem.PARENT)}> + Icon phu huynh +
    +
    handleNavigate('/'+TypeHeaderNewsItem.TEACHER)}> + Icon giao vien +
    +
    +
    + + ); +}; +export default ScrollFixed; diff --git a/src/_components/ScrollFixed/ScrollFixed.logic.js b/src/_components/ScrollFixed/ScrollFixed.logic.js new file mode 100644 index 0000000..987e495 --- /dev/null +++ b/src/_components/ScrollFixed/ScrollFixed.logic.js @@ -0,0 +1,17 @@ +import { history } from "../../_helpers"; + +export const scrollFixedLogic = () => { + const handleScrollTop = () => { + window.scrollTo({ top: 0, behavior: "instant" }); + }; + + const handleNavigate = (href) => { + history.push(href) + window.scrollTo({ top: 0, behavior: "instant" }); + } + + return { + handleScrollTop, + handleNavigate + }; +}; diff --git a/src/_components/ScrollFixed/ScrollFixed.style.scss b/src/_components/ScrollFixed/ScrollFixed.style.scss new file mode 100644 index 0000000..506e99c --- /dev/null +++ b/src/_components/ScrollFixed/ScrollFixed.style.scss @@ -0,0 +1,72 @@ +@import "/src/_styles/mixin"; + +.box_fixed { + position: fixed; + bottom: 2%; + right: 2%; + align-items: center; + display: flex; + flex-direction: column; + z-index: 9998; + + @include screen_mobile { + flex-direction: row-reverse !important; + right: 0; + width: 100%; + justify-content: space-between !important; + align-items: center; + padding: 0 2%; + } + + .icon_scroll_fixed { + width: 2.6rem; + height: 2.6rem; + + @include screen_mobile { + margin-bottom: 0 !important; + } + } +} + +.box-left_fixed { + position: fixed; + bottom: 2%; + left: 2%; + align-items: center; + display: flex; + flex-direction: column; + z-index: 9998; + + @include screen_mobile { + left: 0; + padding: 0 2%; + } + + .icon_scroll_fixed { + width: 3rem; + height: 3rem; + + @include screen_mobile { + margin-bottom: 0 !important; + } + } +} + +.box-right_fixed { + position: fixed; + bottom: 2%; + right: 2%; + align-items: center; + display: flex; + flex-direction: column; + z-index: 9998; + + .icon_scroll_fixed { + width: 3rem; + height: 3rem; + + @include screen_mobile { + margin-bottom: 0 !important; + } + } +} \ No newline at end of file diff --git a/src/_components/Select/SelectAsDiv.js b/src/_components/Select/SelectAsDiv.js new file mode 100644 index 0000000..9a70b90 --- /dev/null +++ b/src/_components/Select/SelectAsDiv.js @@ -0,0 +1,105 @@ +import React, { useEffect, useState } from "react"; + +function SelectAsDiv(props) { + let { + textDefault, + data, + onChangeSelect, + keySelected, + ico_url, + list_style, + id, + className, + hzLine, + ico_filter, + position, + disabled, + fix_text_cut_chart, + styleOption, + styleBox, + styleItem + } = props; + + if (!id) { + id = "id"; + } + let wrapperRef = null; + let keyName = props.keyName ? props.keyName : "name"; + const [show, setShow] = useState(false); + + useEffect(() => { + document.addEventListener("mousedown", _click_outside); + return () => { + document.removeEventListener("mousedown", _click_outside); + }; + }, []); + + function _click_outside(event) { + if (wrapperRef && !wrapperRef.contains(event.target)) { + setShow(false); + } + } + + const _set_wrapper_ref_find = (node) => { + if (!wrapperRef) { + wrapperRef = node; + } + }; + + function closeAndSetValue(key) { + setShow(false); + onChangeSelect(key); + } + + if (keySelected) { + if (data.find((item) => item[id] === keySelected)) { + textDefault = data.find((item) => item[id] === keySelected)[keyName]; + } + } + + return ( +
    _set_wrapper_ref_find(e)} + > +
    setShow(!show)} + id={keySelected} + > + {textDefault} {hzLine && |} +
    +
      + {data?.map((item, i) => { + return ( +
    • closeAndSetValue(item[id])} style={styleItem}> + {list_style && } + {item[keyName]} +
    • + ); + })} +
    + {ico_url && ( + {"ico_icon_select"} + )} + {ico_filter && ( + {"ico_filter"} + )} +
    + ); +} + +export { SelectAsDiv }; diff --git a/src/_components/Select/SelectCurriculum/SelectCurriculum.jsx b/src/_components/Select/SelectCurriculum/SelectCurriculum.jsx new file mode 100644 index 0000000..6e2e4be --- /dev/null +++ b/src/_components/Select/SelectCurriculum/SelectCurriculum.jsx @@ -0,0 +1,132 @@ +import React, { useEffect, useState } from "react"; +import { classesConstants } from "../../../_constants/classes"; + +export default function SelectCurriculum(props) { + let { + textDefault, + data, + onChangeSelect, + keySelected, + list_style, + id, + className, + hzLine, + position, + disabled, + fix_text_cut_chart, + styleOption, + typeCurriculum, + } = props; + + if (!id) { + id = "id"; + } + let wrapperRef = null; + let keyName = props.keyName ? props.keyName : "name"; + let typeName = props.typeName ? props.typeName : "type"; + const [show, setShow] = useState(false); + + useEffect(() => { + document.addEventListener("mousedown", _click_outside); + return () => { + document.removeEventListener("mousedown", _click_outside); + }; + }, []); + + function _click_outside(event) { + if (wrapperRef && !wrapperRef.contains(event.target)) { + setShow(false); + } + } + + const _set_wrapper_ref_find = (node) => { + if (!wrapperRef) { + wrapperRef = node; + } + }; + + function closeAndSetValue(key) { + setShow(false); + onChangeSelect(key); + } + + if (keySelected) { + if (data.find((item) => item[id] === keySelected)) { + const itemSelected = data.find((item) => item[id] === keySelected); + textDefault = itemSelected[keyName]; + typeCurriculum = itemSelected[typeName]; + } + } + const isSundayFree = + typeCurriculum === classesConstants.SUNDAY || + typeCurriculum === classesConstants.SUNDAY_FREE; + return ( +
    _set_wrapper_ref_find(e)} + > +
    setShow(!show)} + id={keySelected} + > + {typeCurriculum && ( +
    + {textDefault} +
    + )} + {textDefault} {hzLine && |} +
    +
      + {data?.map((item, i) => { + return ( +
    • closeAndSetValue(item[id])}> +
      + {item[keyName]} +
      + {list_style && } + {item[keyName]} +
    • + ); + })} +
    +
    + ); +} diff --git a/src/_components/Select/SelectCustom/SelectCustom.jsx b/src/_components/Select/SelectCustom/SelectCustom.jsx new file mode 100644 index 0000000..288657e --- /dev/null +++ b/src/_components/Select/SelectCustom/SelectCustom.jsx @@ -0,0 +1,63 @@ +import "./SelectCustom.style.scss"; +import { selectCustomLogic } from "./SelectCustom.logic"; +import classNames from "classnames"; + +const SelectCustom = (props) => { + let { isVisible, handleOpenSelection, setWrapperRefFind } = + selectCustomLogic(props); + + const renderDataSelect = (data, index) => ( +
    props.handleClickOption(data, props.typeSelect)} + className={`col-80 ${ + props?.dataSelect.length - 1 != index && " border_bottom_1_dark" + } option_item_custom flex-center-column pointer_cursor `} + > + {data?.address || data?.title || data?.name} +
    + ); + + return ( +
    setWrapperRefFind(e)} + > +
    + {props.titleSelected?.name || + props.titleSelected?.title || + props?.titleSelected?.address || + props?.defaultTitle} +
    + + + +
    +
    +
    + {props?.dataSelect?.map((data, index) => renderDataSelect(data, index))} +
    +
    + ); +}; + +export default SelectCustom; diff --git a/src/_components/Select/SelectCustom/SelectCustom.logic.js b/src/_components/Select/SelectCustom/SelectCustom.logic.js new file mode 100644 index 0000000..861d0cc --- /dev/null +++ b/src/_components/Select/SelectCustom/SelectCustom.logic.js @@ -0,0 +1,37 @@ +import { useState, useEffect } from "react"; + +export const selectCustomLogic = (props) => { + const [isVisible, setIsVisible] = useState(false); + + const handleOpenSelection = () => { + setIsVisible(!isVisible); + }; + + let wrapperRef = null; + + useEffect(() => { + document.addEventListener("mousedown", clickOutside); + return () => { + document.removeEventListener("mousedown", clickOutside); + }; + }, []); + + function clickOutside(event) { + if (wrapperRef && !wrapperRef.contains(event.target)) { + setIsVisible(false); + } + } + + const setWrapperRefFind = (node) => { + if (!wrapperRef) { + wrapperRef = node; + } + }; + + return { + wrapperRef, + isVisible, + handleOpenSelection, + setWrapperRefFind, + }; +}; diff --git a/src/_components/Select/SelectCustom/SelectCustom.style.scss b/src/_components/Select/SelectCustom/SelectCustom.style.scss new file mode 100644 index 0000000..b71ee8c --- /dev/null +++ b/src/_components/Select/SelectCustom/SelectCustom.style.scss @@ -0,0 +1,56 @@ +.select_container { + position: relative; + min-width: 15%; + max-width: 18%; + width: 18%; + margin-right: 2%; + cursor: pointer; + position: relative; + .select_title { + font-size: clamp(0.9rem, 1.5vw, 1.1rem); + .icon_drop_custom { + margin-left: 0.5rem; + } + } + + .list_option_custom { + position: absolute; + top: 2rem; + right: 0; + left: 0; + max-height: 20rem; + min-height: 10rem; + overflow: auto; + background-color: var(--white-color); + border-bottom-left-radius: 0.6rem; + border-bottom-right-radius: 0.6rem; + border-radius: 0.6rem; + z-index: 99; + border: 1px solid var(--text-color); + // border-top: 0; + + &::-webkit-scrollbar { + width: 6px; + } + + /* Handle */ + &::-webkit-scrollbar-thumb { + background: #bbbbbb; + border-radius: 10px; + } + &::-webkit-scrollbar-track { + margin: 0.4rem 0; + } + /* Handle on hover */ + &::-webkit-scrollbar-thumb:hover { + background: #8b8b8b; + } + + .option_item_custom { + color: var(--text-color); + padding: 1rem 0; + + font-size: clamp(0.9rem, 1.5vw, 1rem); + } + } +} diff --git a/src/_components/Select/SelectCustomDouble/SelectCustomDouble.jsx b/src/_components/Select/SelectCustomDouble/SelectCustomDouble.jsx new file mode 100644 index 0000000..44ea89b --- /dev/null +++ b/src/_components/Select/SelectCustomDouble/SelectCustomDouble.jsx @@ -0,0 +1,70 @@ +import "./SelectCustomDouble.style.scss"; +import { selectCustomDoubleLogic } from "./SelectCustomDouble.logic"; +import classNames from "classnames"; + +const SelectCustomDouble = (props) => { + let { isVisible, handleOpenSelection, setWrapperRefFind } = + selectCustomDoubleLogic(props); + + const renderDataSelect = (data, index) => ( +
    props.handleClickOption(data, props.typeSelect)} + className={`col-80 ${ + props?.dataSelect.length - 1 != index && " border_bottom_1_dark" + } option_item_custom flex-center-column pointer_cursor `} + > + {data?.address || data?.title || data?.name} +
    + ); + + return ( +
    setWrapperRefFind(e)} + > +
    +
    +
    + {props?.title} +
    +
    + {props.titleSelected?.name || + props.titleSelected?.title || + props?.titleSelected?.address || + "Tất cả"} +
    +
    +
    + + + +
    +
    +
    + {props?.dataSelect?.map((data, index) => renderDataSelect(data, index))} +
    +
    + ); +}; + +export default SelectCustomDouble; diff --git a/src/_components/Select/SelectCustomDouble/SelectCustomDouble.logic.js b/src/_components/Select/SelectCustomDouble/SelectCustomDouble.logic.js new file mode 100644 index 0000000..60accb8 --- /dev/null +++ b/src/_components/Select/SelectCustomDouble/SelectCustomDouble.logic.js @@ -0,0 +1,37 @@ +import { useState, useEffect } from "react"; + +export const selectCustomDoubleLogic = (props) => { + const [isVisible, setIsVisible] = useState(false); + + const handleOpenSelection = () => { + setIsVisible(!isVisible); + }; + + let wrapperRef = null; + + useEffect(() => { + document.addEventListener("mousedown", clickOutside); + return () => { + document.removeEventListener("mousedown", clickOutside); + }; + }, []); + + function clickOutside(event) { + if (wrapperRef && !wrapperRef.contains(event.target)) { + setIsVisible(false); + } + } + + const setWrapperRefFind = (node) => { + if (!wrapperRef) { + wrapperRef = node; + } + }; + + return { + wrapperRef, + isVisible, + handleOpenSelection, + setWrapperRefFind, + }; +}; diff --git a/src/_components/Select/SelectCustomDouble/SelectCustomDouble.style.scss b/src/_components/Select/SelectCustomDouble/SelectCustomDouble.style.scss new file mode 100644 index 0000000..0f92a95 --- /dev/null +++ b/src/_components/Select/SelectCustomDouble/SelectCustomDouble.style.scss @@ -0,0 +1,58 @@ +.select_double_container { + position: relative; + // min-width: 15%; + // max-width: 18%; + // width: 18%; + // margin-right: 2%; + width: 100%; + cursor: pointer; + position: relative; + padding: 0 3.5%; + .select_title { + margin: 0.5rem 0; + padding: 1.2rem 0; + border-bottom: 1px solid var(--border-color); + .select_title_main { + margin-bottom: 0.2rem; + } + .icon_drop_custom { + margin-left: 0.5rem; + } + } + + .list_option_custom { + width: 70%; + position: absolute; + top: 80%; + right: 4%; + max-height: 20rem; + min-height: 10rem; + overflow: auto; + background-color: var(--white-color); + border-radius: 0.6rem; + border-radius: 0.6rem; + z-index: 99; + border: 1px solid var(--border-color); + border-top: 0; + + &::-webkit-scrollbar { + width: 6px; + } + + /* Handle */ + &::-webkit-scrollbar-thumb { + background: #bbbbbb; + border-radius: 10px; + } + + /* Handle on hover */ + &::-webkit-scrollbar-thumb:hover { + background: #8b8b8b; + } + + .option_item_custom { + color: var(--text-color); + padding: 1rem 0; + } + } +} diff --git a/src/_components/Select/SelectQuestion/SelectQuestion.jsx b/src/_components/Select/SelectQuestion/SelectQuestion.jsx new file mode 100644 index 0000000..e725556 --- /dev/null +++ b/src/_components/Select/SelectQuestion/SelectQuestion.jsx @@ -0,0 +1,55 @@ +import "./SelectQuestion.style.scss"; +import { renderDataQuestion1 } from "../../../_base/DetailListNews"; +import { selectQuestionLogic } from "./SelectQuestion.logic"; + +const SelectQuestion = (props) => { + let { + title, + title_2, + data, + titleSelected, + typeQuestion, + handleSelectQuestion, + } = props; + + // let { isSelected, handleSelectQuestion } = selectQuestionLogic(props); + + const isSelected = titleSelected == title; + + return ( +
    +
    handleSelectQuestion(title)} + > +
    + {title}{" "} + {!!title_2 ? ( +
    + {title_2} +
    + ) : null} +
    +
    + Icon Dropdown +
    + + {isSelected ?
    : null} +
    + + {isSelected ? renderDataQuestion1(data) : null} +
    + ); +}; + +export default SelectQuestion; diff --git a/src/_components/Select/SelectQuestion/SelectQuestion.logic.js b/src/_components/Select/SelectQuestion/SelectQuestion.logic.js new file mode 100644 index 0000000..bc6c0dd --- /dev/null +++ b/src/_components/Select/SelectQuestion/SelectQuestion.logic.js @@ -0,0 +1,22 @@ +import { useState } from "react"; + +export const selectQuestionLogic = (props) => { + const [isSelected, setIsSelected] = useState(false); + + // Handle Select Title Question + const handleSelectQuestion = (title) => { + setIsSelected(!isSelected); + const element = document.getElementById(title); + // console.log(element); + element?.scrollIntoView({ + behavior: "smooth", + block: "center", // or 'center' or 'end' + inline: "nearest", // or 'start' or 'end' + }); + }; + + return { + isSelected, + handleSelectQuestion, + }; +}; diff --git a/src/_components/Select/SelectQuestion/SelectQuestion.style.scss b/src/_components/Select/SelectQuestion/SelectQuestion.style.scss new file mode 100644 index 0000000..3688f1e --- /dev/null +++ b/src/_components/Select/SelectQuestion/SelectQuestion.style.scss @@ -0,0 +1,119 @@ +@import "/src/_styles/mixin"; + +.select-question-container { + border-radius: 0.9rem; + padding: 0.35rem 1.25rem 0.35rem; + margin-top: 1rem; + + @include screen_mobile { + padding: 0 1rem 0.35rem; + } + + .question_header { + padding: 1rem 0; + + @include screen_mobile { + padding: 0.85rem 0 0.65rem; + } + .question_name { + font-size: clamp(1.125rem, 1.8vw, 1.375rem); + margin-right: 0.5rem; + + @include screen_mobile { + font-size: clamp(0.875rem, 5vw, 1.125rem); + } + } + + .img_dropdown { + min-width: clamp(2rem, 2.75vw, 2.4rem); + min-height: clamp(2rem, 2.75vw, 2.4rem); + width: clamp(2rem, 2.75vw, 2.4rem); + height: clamp(2rem, 2.75vw, 2.4rem); + } + + .question_divider_header { + position: absolute; + bottom: 0; + left: 0; + width: 40%; + height: 2px; + background-color: var(--primary-green); + } + } + + .question_data { + padding: 1rem 0rem; + .question_content_left { + margin-right: 6%; + + @include screen_mobile { + margin-right: 0; + } + } + .question_content_text { + font-size: clamp(1rem, 1.6vw, 1.25rem); + + @include screen_mobile { + font-size: clamp(0.875rem, 4.5vw, 1rem); + } + } + + .question_content_list { + .img_app_download { + width: 8rem; + min-width: 4rem; + @include screen_mobile { + width: 7rem; + min-width: 4rem; + } + } + } + + .question_content_image { + width: 25%; + max-width: 25%; + min-width: 25%; + + @include screen_mobile { + width: 62%; + max-width: 62%; + max-width: 28rem; + min-width: 7.5rem; + padding-top: 1.25rem; + } + + img { + width: 100%; + min-width: 100%; + max-width: 100%; + } + } + + .question_content_list_images { + .question_content_image_smaller { + width: auto; + max-width: 25%; + + &:not(:last-child) { + margin-right: 2.5%; + } + + @include screen_mobile { + margin-right: 0; + width: 62%; + max-width: 28rem; + min-width: 7.5rem; + padding-top: 1rem; + &:first-child { + padding-top: 1.25rem; + } + + img { + width: 100%; + min-width: 100%; + } + } + } + } + } +} diff --git a/src/_components/Select/index.js b/src/_components/Select/index.js new file mode 100644 index 0000000..2fa77d2 --- /dev/null +++ b/src/_components/Select/index.js @@ -0,0 +1 @@ +export * from './SelectAsDiv'; \ No newline at end of file diff --git a/src/_components/SkillsAssign/SkillsAssign.jsx b/src/_components/SkillsAssign/SkillsAssign.jsx new file mode 100644 index 0000000..76e50b9 --- /dev/null +++ b/src/_components/SkillsAssign/SkillsAssign.jsx @@ -0,0 +1,175 @@ +import "./SkillsAssign.style.scss"; +import { skillsAssignLogic } from "./SkillsAssign.logic"; + +const SkillsAssign = (props) => { + let { dataSkills, typeModal } = props; +console.log(dataSkills) + let { + handleChangeLevel, + dataSkillsSide, + handleChangeCountExercise, + handleChecked, + } = skillsAssignLogic(props); + + // Render List Skills + const renderListSkills = (data) => { + return ( +
    +
    +
    + {data?.skill.capitalize()} +
    + + handleChecked(e, data)} + checked={data.sum > 0} + /> + + +
    + +
    + {!["pronunciation", "vocabulary"].includes( + data?.skill?.toLowerCase() + ) && ( +
    handleChangeLevel(data, "prev")} + > + img icon left +
    + )} + + {data?.level.capitalize()} + + {!["pronunciation", "vocabulary"].includes( + data?.skill?.toLowerCase() + ) && ( +
    handleChangeLevel(data, "next")} + > + img icon right +
    + )} +
    + +
    + + +
    {data?.sum} bài
    + + +
    +
    + ); + }; + + return ( +
    +
    + {dataSkillsSide?.slice(0, 3)?.map((data) => renderListSkills(data))} +
    +
    + {dataSkillsSide?.slice(3)?.map((data) => renderListSkills(data))} +
    + + {!dataSkills?.is_lost_root &&
    +
    + Bài tập Easy phù hợp với trình độ Junior +
    +
    + Bài tập Medium phù hợp với trình độ Middle +
    +
    + Bài tập Hard phù hợp với trình độ Senior +
    +
    } +
    + ); +}; + +export default SkillsAssign; diff --git a/src/_components/SkillsAssign/SkillsAssign.logic.js b/src/_components/SkillsAssign/SkillsAssign.logic.js new file mode 100644 index 0000000..24a55eb --- /dev/null +++ b/src/_components/SkillsAssign/SkillsAssign.logic.js @@ -0,0 +1,124 @@ +import { useState, useEffect } from "react"; + +export const skillsAssignLogic = (props) => { + let { dataSkills, setDataSkills } = props; + + const [dataSkillsSide, setDataSkillsSide] = useState( + dataSkills.lesson_list_propose + ); + + const dataLevels = ["easy", "medium", "hard"]; + + // Handle Checked + // Handle Checked Box + const handleChecked = (e, data) => { + const newDataAssign = dataSkillsSide; + if (e.target.checked) { + newDataAssign?.forEach((item) => { + if (item.skill == data.skill) { + item.sum = 1; + } + }); + + setDataSkillsSide(newDataAssign); + setDataSkills((prev) => ({ + ...prev, + lesson_list_propose: newDataAssign, + })); + } else { + newDataAssign?.forEach((item) => { + if (item.skill == data.skill) { + item.sum = 0; + } + }); + + setDataSkillsSide(newDataAssign); + setDataSkills((prev) => ({ + ...prev, + lesson_list_propose: newDataAssign, + })); + } + }; + + // Handle Change Level + const handleChangeLevel = (data, type) => { + const newDataAssign = dataSkillsSide; + switch (type) { + case "prev": + newDataAssign?.forEach((item) => { + if (item.skill == data.skill) { + const indexLevel = dataLevels.indexOf(data.level); + if (indexLevel - 1 >= 0) { + item.level = dataLevels[indexLevel - 1]; + } + } + }); + + setDataSkills((prev) => ({ + ...prev, + lesson_list_propose: newDataAssign, + })); + setDataSkillsSide(newDataAssign); + break; + case "next": + newDataAssign?.forEach((item) => { + if (item.skill == data.skill) { + const indexLevel = dataLevels.indexOf(data.level); + if (indexLevel + 1 < dataLevels.length) { + item.level = dataLevels[indexLevel + 1]; + } + } + }); + setDataSkills((prev) => ({ + ...prev, + lesson_list_propose: newDataAssign, + })); + setDataSkillsSide(newDataAssign); + break; + default: + } + }; + + // Handle Change Count Exercise + const handleChangeCountExercise = (data, type) => { + const newDataAssign = dataSkillsSide; + switch (type) { + case "prev": + newDataAssign?.forEach((item) => { + if (item.skill == data.skill) { + item.sum -= 1; + } + }); + + setDataSkills((prev) => ({ + ...prev, + lesson_list_propose: newDataAssign, + })); + setDataSkillsSide(newDataAssign); + break; + case "next": + newDataAssign?.forEach((item) => { + if (item.skill == data.skill) { + if (item.skill == data.skill) { + item.sum += 1; + } + } + }); + + setDataSkills((prev) => ({ + ...prev, + lesson_list_propose: newDataAssign, + })); + setDataSkillsSide(newDataAssign); + break; + default: + } + }; + + return { + dataSkillsSide, + handleChangeLevel, + handleChangeCountExercise, + handleChecked, + }; +}; diff --git a/src/_components/SkillsAssign/SkillsAssign.style.scss b/src/_components/SkillsAssign/SkillsAssign.style.scss new file mode 100644 index 0000000..fb06fef --- /dev/null +++ b/src/_components/SkillsAssign/SkillsAssign.style.scss @@ -0,0 +1,61 @@ +.skills_assign { + .skill_assign_box { + background-color: var(--white-color); + border-radius: 0.8rem; + padding: 0.6rem 0.7rem; + margin-right: 1rem; + width: 23%; + max-width: 23%; + min-width: 23%; + + .skill_assign_level { + height: 1.75rem; + width: 65%; + border-radius: 1rem; + padding: 0 3%; + + .btn_level { + height: 70%; + + img { + height: 100%; + } + } + } + + .btn_count_exercises { + border: 1px solid #e5e5e5; + border-radius: 2rem; + padding: 0.15rem; + + .btn { + border-radius: 50%; + background-color: #00e2a0; + border: none; + outline: none; + width: 1.8rem; + height: 1.8rem; + + img { + height: 70%; + } + } + } + } + + .skill_assign_box:last-child { + margin-right: 0rem; + } + + .skill_assign_box_lost_root { + width: 200px; + max-width: unset; + min-width: unset; + } +} + +.skills_assigns_proposal { + padding-top: 3%; + padding-bottom: 1.5%; + // min-height: 15rem; +} \ No newline at end of file diff --git a/src/_components/Slogan/Slogan.jsx b/src/_components/Slogan/Slogan.jsx new file mode 100644 index 0000000..978e334 --- /dev/null +++ b/src/_components/Slogan/Slogan.jsx @@ -0,0 +1,78 @@ +import ButtonNews from "../Button/ButtonNews"; +import "./Slogan.style.scss"; +import { sloganLogic } from "./Slogan.logic"; +import { TypeHeaderNewsItem } from "../../_constants/headerNews"; +import { useSelector } from "react-redux"; +import { hasDomainStore } from "../../_base/Validate"; +import LazyLoad from "react-lazyload"; + +const Slogan = (props) => { + let { handleNavigate, handleNavigateRegister } = sloganLogic(); + const authentication = useSelector((state) => state.authentication); + + return ( +
    +
    + + Slogan Image + Slogan Image + {/* {props.type != "teacher" && !hasDomainStore() && ( +
    + + handleNavigate(`/${TypeHeaderNewsItem.FEE}/#list_packages`) + } + border={"1px solid #fff"} + backgroundColor={"#EB5757"} + boxShadow={"1px 1px 5px white, 0 0 1px white"} + maxWidth={"19.5vw"} + maxHeight={"5.5vw"} + > +
    + MUA NGAY +
    +
    +
    + )} */} +
    +
    + {/*
    + handleNavigate("/advisement")} + border={"1px solid #00cc83"} + backgroundColor={"#00cc83"} + > +
    + NHẬN TƯ VẤN MIỄN PHÍ +
    +
    +
    */} +
    + ); +}; + +export default Slogan; diff --git a/src/_components/Slogan/Slogan.logic.js b/src/_components/Slogan/Slogan.logic.js new file mode 100644 index 0000000..9ecac96 --- /dev/null +++ b/src/_components/Slogan/Slogan.logic.js @@ -0,0 +1,26 @@ +import { history } from "../../_helpers"; +import { TypeHeaderNewsItem } from "../../_constants/headerNews"; +import { useSelector } from "react-redux"; + +export const sloganLogic = (props) => { + const authentication = useSelector((state) => state.authentication); + + // Handle Navigate + const handleNavigate = (type) => { + history.push(type); + }; + + // Handle navigate register + const handleNavigateRegister = () => { + if (authentication.isLogin) { + history.push(`/${authentication.role}`); + } else { + history.push("/register_news"); + } + }; + + return { + handleNavigate, + handleNavigateRegister, + }; +}; diff --git a/src/_components/Slogan/Slogan.style.scss b/src/_components/Slogan/Slogan.style.scss new file mode 100644 index 0000000..72ae351 --- /dev/null +++ b/src/_components/Slogan/Slogan.style.scss @@ -0,0 +1,69 @@ +@import "/src/_styles/mixin"; + +.slogan_container { + width: 100%; + // background-color: var(--white-color); + + // @include screen_mobile { + // padding: 0 3%; + // } + .slogan_content { + width: 100%; + position: relative; + // margin-bottom: 2.5rem; + + .slogan_img { + width: 100%; + object-fit: contain; + } + + .btn_buy_container { + position: absolute; + right: 2%; + bottom: 10%; + max-width: 50%; + + @include screen_mobile { + display: flex; + align-items: center; + justify-content: center; + margin-top: 1rem; + width: 100%; + bottom: 2%; + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; + text-align: center; + } + + .btn_custom { + @include screen_mobile { + width: 12rem !important; + // height: 2.8rem !important; + height: 13vw !important; + max-width: 100% !important; + max-height: 2.87rem !important; + } + } + + .text_btn_buy { + font-size: clamp(1.3rem, 2vw, 1.5rem); + } + } + } + + .btn_container { + .btn_custom { + @include screen_mobile { + width: 65% !important; + min-width: 10rem; + } + } + + .btn_text { + color: var(--white-color); + font-size: 1.75rem; + } + } +} \ No newline at end of file diff --git a/src/_components/SocialLogin/index.js b/src/_components/SocialLogin/index.js new file mode 100644 index 0000000..4c1cbad --- /dev/null +++ b/src/_components/SocialLogin/index.js @@ -0,0 +1,16 @@ +import PropTypes from "prop-types"; +import React, { Component } from "react"; +import SocialLogin from "react-social-login"; + +class Button extends Component { + static propTypes = { + triggerLogin: PropTypes.func.isRequired, + }; + + render() { + const { triggerLogin, image, ...props } = this.props; + return {"icon_login_fb"}; + } +} + +export default SocialLogin(Button); diff --git a/src/_components/dropdown/index.js b/src/_components/dropdown/index.js new file mode 100644 index 0000000..240d754 --- /dev/null +++ b/src/_components/dropdown/index.js @@ -0,0 +1,54 @@ +import React, { useEffect, useState } from "react"; +import './styles.scss' + +export const DropDownCustom = (props) => { + + const { listOptions, itemSelected, onChangeValue, classItem} = props; + + const [isExpand, setExpand] = useState(false); + let wrapperRef = null; + + useEffect(() => { + document.addEventListener('mousedown', clickOutside); + return () => { + document.removeEventListener('mousedown', clickOutside); + } + }, []) + + function clickOutside(event) { + if (wrapperRef && !wrapperRef.contains(event.target)) { + setExpand(false) + } + } + + const setWrapperRefFind = (node) => { + if (!wrapperRef) { + wrapperRef = node + } + } + + const onChange = (item) => { + onChangeValue && onChangeValue(item) + setExpand(false) + } + + return ( +
    setWrapperRefFind(e)}> +
    setExpand(!isExpand)}> + {props.children ? props.children : ( +
    + + {itemSelected && itemSelected.title} +
    + )} +
    + {isExpand &&
    + {listOptions && listOptions.map(item => ( +
    onChange(item)}> + {item.title} +
    + ))} +
    } +
    + ) +} diff --git a/src/_components/dropdown/styles.scss b/src/_components/dropdown/styles.scss new file mode 100644 index 0000000..6146eba --- /dev/null +++ b/src/_components/dropdown/styles.scss @@ -0,0 +1,61 @@ +.c-dropdown-custom { + display: flex; + flex-direction: column; + position: relative; + margin: 0px 6px; + + .item-selected { + z-index: 10; + cursor: pointer; + } + + .item-default { + border: 1px solid #ccc; + padding: 8px 16px; + border-radius: 20px; + min-width: 120px; + display: flex; + justify-content: space-between; + background-image: linear-gradient(to right, #00b9b7, #00e1a0); + + img { + object-fit: contain; + } + + img.reverse { + transform: rotate(180deg); + } + + span { + margin-left: 6px; + border-left: 3px solid #fff; + padding-left: 6px; + color: #fff; + flex: 1; + } + } + + .list-options { + position: absolute; + top: 15px; + max-height: 500px; + background-color: #fff; + padding: 30px 16px 16px; + right: 0; + left: 0; + border-radius: 0px 0px 20px 20px; + box-shadow: 0px 0px 2px inset #707070; + z-index: 9; + overflow: auto; + + .option { + padding: 8px 0px; + cursor: pointer; + border-bottom: 1px solid #ccc; + } + + .option:last-child { + border-bottom: none; + } + } +} \ No newline at end of file diff --git a/src/_components/exam-test/CheckBoxCustom.js b/src/_components/exam-test/CheckBoxCustom.js new file mode 100644 index 0000000..b4b8d8f --- /dev/null +++ b/src/_components/exam-test/CheckBoxCustom.js @@ -0,0 +1,56 @@ +import React from "react"; +import "./styles.scss"; + +export const CheckBoxCustom = (props) => { + const { label, status, onChange } = props; + + const renderBox = () => { + switch (status) { + case "checked": + return ; + case "fail": + return ; + default: + return ; + } + }; + + const renderColor = () => { + switch (status) { + case "checked": + return "#009444"; + case "fail": + return "#BE1E2D"; + default: + return null; + } + }; + + return ( +
    + {renderBox()} + +
    + ); +}; + +export const renderStatusCheckBox = ( + isMatch, + isTrueAnswer, + isReview = false +) => { + let status = "unchecked"; + if (isReview) { + if (isTrueAnswer) { + status = "checked"; + } else if (isMatch) { + status = "fail"; + } + } else { + status = isMatch ? "checked" : "unchecked"; + } + return status; +}; diff --git a/src/_components/exam-test/CheckBoxSquare.js b/src/_components/exam-test/CheckBoxSquare.js new file mode 100644 index 0000000..f0408da --- /dev/null +++ b/src/_components/exam-test/CheckBoxSquare.js @@ -0,0 +1,44 @@ +const CheckBoxSquare = (props) => { + const { label, status, onChange } = props; + + const renderBox = () => { + switch (status) { + case true: + return ( + Img CheckedBox + ); + case false: + return ( + Img UnCheckedBox + ); + default: + return ( + Img UnCheckedBox + ); + } + }; + + return ( +
    + {renderBox()} + +
    + ); +}; + +export default CheckBoxSquare; diff --git a/src/_components/exam-test/ExamListening.js b/src/_components/exam-test/ExamListening.js new file mode 100644 index 0000000..b9149cd --- /dev/null +++ b/src/_components/exam-test/ExamListening.js @@ -0,0 +1,268 @@ +import { isEmpty } from "lodash"; +import React, { useEffect } from "react"; +import { renderFormAnswer, renderTextAnswerReview } from "."; +import { configConstants } from "../../_constants"; +import { AudioCustom } from "../Audio"; +import { CheckBoxCustom, renderStatusCheckBox } from "./CheckBoxCustom"; +import "./styles.scss"; +import ReviewLaterBox from "./ReviewLaterBox"; + +export const ExamListening = (props) => { + const { + type, + category, + indexQuestion, + resultExam = [], + onChangeResult, + isReview, + listReview = [], + onCheckReview, + isDoing = false + } = props; + + const renderQuestionsListening1 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText?.trim() || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let matchOptionText = question?.list_option[0].match_option_text?.map( + (text) => text + ); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    +

    + {index + indexQuestion}. {question.question_content} +

    + {isReview ? ( + renderTextAnswerReview(answer, matchOptionText) + ) : ( + + onChangeResult(question?.question_id, e.target.value) + } + /> + )} +
    + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + }); + }; + + const renderQuestionsListening3 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText?.trim() || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    + + {index + indexQuestion}. {question.question_content}. + +
    + {question?.list_option?.map((option) => { + let isOptionTrue = parseInt(option?.score) !== 0; + let isAnswerTrue = + answer === option?.match_option_text.join(""); + return ( +
    + {isReview && isOptionTrue && !isAnswerTrue && ( + + )} + + onChangeResult( + question.question_id, + option?.match_option_text.join("") + ) + } + label={option?.match_option_text?.join("")} + /> +
    + ); + })} +
    +
    + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + }); + }; + + const renderQuestionsListening5 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText?.trim() || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let optionTextTrue = question?.list_option[0]?.match_option_text.join(""); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    + + {index + indexQuestion}. {question.question_content} + +
    +
    + {isReview && optionTextTrue === "T" && answer !== "T" && ( + + )} + onChangeResult(question.question_id, "T")} + label="True" + /> +
    +
    + {isReview && optionTextTrue === "F" && answer !== "F" && ( + + )} + onChangeResult(question.question_id, "F")} + label="False" + /> +
    + {/* {question?.list_option?.map(option => ( +
    + onChangeResult(question.question_id, option?.match_option_text.join(''))} + label={option?.match_option_text?.join('')}/> +
    + ))} */} +
    +
    + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + }); + }; + + const renderQuestionsListening9 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let textAnswer = props?.userAnswerText?.trim() || (answer + ? answer.find((item) => item.type === "input")?.value?.trim() + : ""); + let matchOptionText = question?.list_option[0].match_option_text?.map( + (text) => text + ); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    + + {renderFormAnswer( + question?.list_option, + answer, + !isReview, + (value) => onChangeResult(question.question_id, value) + )} +
    + {isReview && renderTextAnswerReview(textAnswer, matchOptionText)} + {isReview && !isEmpty(question?.option_explain) && ( +
    + +
    + {question?.option_explain} +
    +
    + )} +
    + ); + }); + }; + + const renderListQuestions = () => { + switch (type) { + case "listening1": + return renderQuestionsListening1(); + case "listening2": + return renderQuestionsListening1(); + case "listening3": + return renderQuestionsListening3(); + case "listening5": + return renderQuestionsListening5(); + case "listening9": + return renderQuestionsListening9(); + } + }; + + return ( +
    +
    +

    {category?.group_content}

    +
    + +
    + {renderListQuestions()} +
    +
    + ); +}; diff --git a/src/_components/exam-test/ExamWriting.js b/src/_components/exam-test/ExamWriting.js new file mode 100644 index 0000000..7f9e73a --- /dev/null +++ b/src/_components/exam-test/ExamWriting.js @@ -0,0 +1,287 @@ +import React from "react"; +import "./styles.scss"; +import { CheckBoxCustom, renderStatusCheckBox } from "./CheckBoxCustom"; +import { isEmpty } from "lodash"; +import { renderTextAnswerReview } from "."; +import ReviewLaterBox from "./ReviewLaterBox"; + +export const ExamWriting = (props) => { + const { + type, + title, + category, + indexQuestion, + resultExam = [], + onChangeResult, + isReview, + listReview = [], + onCheckReview, + isDoing = false, + } = props; + + const renderQuestionsWriting2 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText?.trim() || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + if (isReview) { + answer = answer?.trim(); + } + let matchOptionText = [ + question?.list_option[0].question_content?.replaceAll("/", "")?.trim(), + ]; + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    +

    + {index + indexQuestion}. {question?.question_content} +

    + {isReview ? ( + renderTextAnswerReview(answer, matchOptionText) + ) : ( + + onChangeResult(question?.question_id, e.target.value) + } + /> + )} +
    + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + }); + }; + + const renderQuestionsWriting3 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText?.trim() || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let matchOptionText = question?.list_option[0].match_option_text?.map( + (text) => text + ); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    +

    + {index + indexQuestion}. {question?.question_content} +

    + {isReview ? ( + renderTextAnswerReview(answer, matchOptionText) + ) : ( + + onChangeResult(question?.question_id, e.target.value) + } + /> + )} +
    + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + }); + }; + + const renderQuestionsWriting4 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText?.trim() || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let matchOptionText = question?.list_option[0].match_option_text?.map( + (text) => text + ); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    +

    + {index + indexQuestion}. {question?.question_content} +

    +
    +

    {question?.hint}

    + {isReview ? ( + ________ + ) : ( + + onChangeResult(question?.question_id, e.target.value) + } + /> + )} +
    + {isReview && renderTextAnswerReview(answer, matchOptionText)} +
    + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + }); + }; + + const renderQuestionsWriting5 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText?.trim() || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let matchOptionText = question?.list_option[0].match_option_text?.map( + (text) => text + ); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    +

    + {index + indexQuestion}. {question?.question_content} +

    + {isReview ? ( + renderTextAnswerReview(answer, matchOptionText) + ) : ( + + onChangeResult(question?.question_id, e.target.value) + } + /> + )} +
    + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + }); + }; + + const renderQuestionsWriting8 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText?.trim() || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    + + {index + indexQuestion}. {question?.question_content} + +
    + {question?.list_option?.map((option) => { + let isOptionTrue = parseInt(option?.score) !== 0; + let isAnswerTrue = + answer === option?.match_option_text.join(""); + return ( +
    + {isReview && isOptionTrue && !isAnswerTrue && ( + + )} + + onChangeResult( + question?.question_id, + option?.match_option_text.join("") + ) + } + label={option?.match_option_text?.join("")} + /> +
    + ); + })} +
    +
    + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + }); + }; + + const renderListQuestions = () => { + switch (type) { + case "writing2": + return renderQuestionsWriting2(); + case "writing3": + return renderQuestionsWriting3(); + case "writing4": + return renderQuestionsWriting4(); + case "writing5": + return renderQuestionsWriting5(); + case "writing8": + return renderQuestionsWriting8(); + } + }; + + return ( +
    + +
    {renderListQuestions()}
    +
    + ); +}; diff --git a/src/_components/exam-test/ReviewLaterBox.js b/src/_components/exam-test/ReviewLaterBox.js new file mode 100644 index 0000000..96d24d3 --- /dev/null +++ b/src/_components/exam-test/ReviewLaterBox.js @@ -0,0 +1,19 @@ +import { useState } from "react" +import "./styles.scss"; + +export default function ReviewLaterBox({isActive, ...props}) { + const [isHover, setIsHover] = useState(false) + + return ( +
    setIsHover(true)} onMouseLeave={() => setIsHover(false)} {...props}> + rv-later + {isHover && !isActive &&
    + Xem lại sau +
    } +
    + ) +} \ No newline at end of file diff --git a/src/_components/exam-test/index.js b/src/_components/exam-test/index.js new file mode 100644 index 0000000..8f0e6fc --- /dev/null +++ b/src/_components/exam-test/index.js @@ -0,0 +1,971 @@ +import React, { useState } from "react"; +import "./styles.scss"; +import { CheckBoxCustom, renderStatusCheckBox } from "./CheckBoxCustom"; +import { isEmpty } from "lodash"; +import ReviewLaterBox from "./ReviewLaterBox"; + +export const renderTextAnswerReview = (text, answer) => { + let answers = answer?.map((textItem) => textItem.toLowerCase()); + if ( + answers?.includes( + text + ?.toLowerCase() + ?.trim() + ?.replace(/[^A-Za-z0-9]+$/, "") + ?.replace(/\s+/g, " ") + ) || + answers?.includes( + text + ?.toLowerCase() + ?.trim() + ?.replace(/[^A-Za-z0-9]+$/, "") + ?.replace(/\s+/g, " ") + ?.concat(".") + ) || + answers?.includes( + text + ?.toLowerCase() + ?.trim() + ?.replace(/[^A-Za-z0-9]+$/, "") + ?.replace(/\s+/g, " ") + ?.concat("?") + ) + ) { + return ( +
    + {text} + {/* {answer.join('/ ')} */} +
    + ); + } else { + return ( +
    + {text} +
    + + {answer[0]} +
    +
    + ); + } +}; + + + +export const ExamPro1 = (props) => { + const { category, indexQuestion, resultExam = [], onChangeResult, isReview, listReview = [], onCheckReview, isDoing } = + props; + + return ( +
    + + {category?.question_content} + {category?.group_content} + + {category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText?.trim() || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    + +
    + {question?.list_option?.map((option) => { + let isOptionTrue = parseInt(option?.score) !== 0; + let isAnswerTrue = + answer === option?.match_option_text.join(""); + return ( +
    + {isReview && isOptionTrue && !isAnswerTrue && ( + + )} + + onChangeResult( + question.question_id, + option?.match_option_text.join("") + ) + } + label={option?.match_option_text + ?.join("") + .replace("[", "") + .replace("]", "")} + /> +
    + ); + })} +
    +
    + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + })} +
    + ); +}; + +const convertObjectToString = (arr = [], index, newValue) => { + arr[index] = { ...arr[index], value: newValue }; + return arr; +}; + +export const renderFormAnswer = ( + options = {}, + answer, + isEnter = true, + onChange = () => {} +) => { + let question = ""; + for (let option of options) { + question = option.question_content; + } + let textsMatch = getFromBetween.get(question, "{", "}"); + for (let text of textsMatch) { + question = question.replace(`{${text}}`, "{}"); + } + let arrQuestion = question.split("{}"); + let arrQuestionResult = []; + arrQuestion.forEach((item, index) => { + if (index !== 0 || item.length === 0) { + arrQuestionResult.push({ + type: "input", + value: answer ? answer[arrQuestionResult.length]?.value || "" : "", + }); + } + arrQuestionResult.push({ + type: "text", + value: item, + }); + }); + + return ( +
    + {arrQuestionResult.map((item, index) => { + if (item?.type === "text") { + return ( + + {item?.value} + + ); + } else { + if (isEnter) { + return ( + + onChange( + convertObjectToString( + arrQuestionResult, + index, + e.target.value + ) + ) + } + key={"enter-key-" + index} + /> + ); + } else { + return ( + + ________ + + ); + } + } + })} +
    + ); +}; + +export const ExamGrammar1 = (props) => { + const { category, indexQuestion, resultExam = [], onChangeResult, isReview, listReview = [], onCheckReview, isDoing = false } = + props; + + return ( +
    + + {category?.listQuestions?.map((question, index) => { + let answer = resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let textAnswer = props?.userAnswerText?.trim() || (answer + ? answer.find((item) => item.type === "input")?.value?.trim() + : ""); + let matchOptionText = question?.list_option[0].match_option_text?.map( + (text) => text + ); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    + + {renderFormAnswer( + question?.list_option, + answer, + !isReview, + (value) => onChangeResult(question.question_id, value) + )} +
    + {isReview && renderTextAnswerReview(textAnswer, matchOptionText)} + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + })} +
    + ); +}; + +var getFromBetween = { + results: [], + string: "", + getFromBetween: function (sub1, sub2) { + if (this.string.indexOf(sub1) < 0 || this.string.indexOf(sub2) < 0) + return false; + var SP = this.string.indexOf(sub1) + sub1.length; + var string1 = this.string.substr(0, SP); + var string2 = this.string.substr(SP); + var TP = string1.length + string2.indexOf(sub2); + return this.string.substring(SP, TP); + }, + removeFromBetween: function (sub1, sub2) { + if (this.string.indexOf(sub1) < 0 || this.string.indexOf(sub2) < 0) + return false; + var removal = sub1 + this.getFromBetween(sub1, sub2) + sub2; + this.string = this.string.replace(removal, ""); + }, + getAllResults: function (sub1, sub2) { + // first check to see if we do have both substrings + if (this.string.indexOf(sub1) < 0 || this.string.indexOf(sub2) < 0) return; + + // find one result + var result = this.getFromBetween(sub1, sub2); + // push it to the results array + this.results.push(result); + // remove the most recently found one from the string + this.removeFromBetween(sub1, sub2); + + // if there's more substrings + if (this.string.indexOf(sub1) > -1 && this.string.indexOf(sub2) > -1) { + this.getAllResults(sub1, sub2); + } else return; + }, + get: function (string, sub1, sub2) { + this.results = []; + this.string = string; + this.getAllResults(sub1, sub2); + return this.results; + }, +}; + +export const ExamGrammar9 = (props) => { + const { category, indexQuestion, resultExam = [], onChangeResult, isReview, listReview = [], onCheckReview, isDoing = false } = + props; + return ( +
    + + {category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let options = getFromBetween.get(question?.question_content, "[", "]"); + let matchOptionText = question?.list_option[0].match_option_text?.map( + (text) => text.toLowerCase() + ); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    + ") + .replaceAll("]", ""), + }} + > +
    + {category.question_type === "11" + ? options.map((option) => { + let isOptionTrue = + matchOptionText.join("") === option?.toLowerCase(); + let isAnswerTrue = answer === option; + return ( +
    + {isReview && isOptionTrue && !isAnswerTrue && ( + + )} + + onChangeResult(question.question_id, option) + } + label={option} + /> +
    + ); + }) + : question?.list_option?.map((option) => { + let isOptionTrue = parseInt(option?.score) !== 0; + let isAnswerTrue = + answer === option?.match_option_text.join(""); + return ( +
    + {isReview && isOptionTrue && !isAnswerTrue && ( + + )} + + onChangeResult( + question.question_id, + option?.match_option_text.join("") + ) + } + label={option?.match_option_text?.join("")} + /> +
    + ); + })} +
    +
    + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + })} +
    + ); +}; + +export const ExamReading1 = (props) => { + const { + type, + title, + category, + indexQuestion, + resultExam = [], + onChangeResult, + isReview, + listReview = [], + onCheckReview, + isDoing = false, + } = props; + + const renderQuestionsReading1 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText || props?.userAnswerText || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    + + {index + indexQuestion}. {question.question_content} + +
    + {question?.list_option.map((option) => { + let isOptionTrue = parseInt(option?.score) !== 0; + let isAnswerTrue = + answer === option?.match_option_text.join(""); + return ( +
    + {isReview && isOptionTrue && !isAnswerTrue && ( + + )} + + onChangeResult( + question?.question_id, + option?.match_option_text.join("") + ) + } + label={option?.match_option_text?.join("")} + /> +
    + ); + })} +
    +
    + + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + }); + }; + + const renderQuestionsReading2 = () => { + return category?.listQuestions?.map((question, index) => { + let answer =props?.userAnswerText?.trim() || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let matchOptionText = question?.list_option[0].match_option_text?.map( + (text) => text + ); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    + + {isReview ? ( + renderTextAnswerReview(answer, matchOptionText) + ) : ( + + onChangeResult(question?.question_id, e.target.value) + } + /> + )} +
    + {isReview && !isEmpty(question?.option_explain) && ( +
    + +
    + {question?.option_explain} +
    +
    + )} +
    + ); + }); + }; + + const renderQuestionsReading3 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText?.trim() || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let matchOptionText = question?.list_option[0].match_option_text?.map( + (text) => text + ); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    + {question?.list_option?.map((option) => ( +
    + + {isReview ? ( + renderTextAnswerReview(answer, matchOptionText) + ) : ( + + onChangeResult(question?.question_id, e.target.value) + } + /> + )} +
    + ))} +
    + {isReview && !isEmpty(question?.option_explain) && ( +
    + +
    + {question?.option_explain} +
    +
    + )} +
    + ); + }); + }; + + // Reading 4 + const renderQuestionsReading4 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText?.trim() || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let matchOptionText = question?.list_option[0].match_option_text?.map( + (text) => text + ); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    + {question?.list_option?.map((option) => ( +
    + + {isReview ? ( + renderTextAnswerReview(answer, matchOptionText) + ) : ( + + onChangeResult(question?.question_id, e.target.value) + } + /> + )} +
    + ))} +
    + {isReview && !isEmpty(question?.option_explain) && ( +
    + +
    + {question?.option_explain} +
    +
    + )} +
    + ); + }); + }; + + const renderQuestionsReading6 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    + + {index + indexQuestion}. {question.question_content} + +
    + {question?.list_option?.map((option) => { + let isOptionTrue = parseInt(option?.score) !== 0; + let isAnswerTrue = + answer === option?.match_option_text.join(""); + return ( +
    +
    + {isReview && isOptionTrue && !isAnswerTrue && ( + + )} + + onChangeResult( + question?.question_id, + option?.match_option_text.join("") + ) + } + label={option.match_option_text.join("")} + /> +
    +
    + ); + })} +
    + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    +
    + ); + }); + }; + + const renderQuestionsReading11 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let matchOptionText = question?.list_option[0].match_option_text?.map( + (text) => text + ); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    +

    + {index + indexQuestion}. {question.question_content} +

    + {isReview ? ( + renderTextAnswerReview(answer, matchOptionText) + ) : ( + + onChangeResult(question?.question_id, e.target.value) + } + /> + )} +
    + + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + }); + }; + + const renderQuestionsReading12 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = props?.userAnswerText?.trim() || resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let optionTextTrue = question?.list_option[0]?.match_option_text.join(""); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    +
    + + {index + indexQuestion}. {question.question_content} + +
    +
    + {isReview && optionTextTrue === "T" && answer !== "T" && ( + + )} + onChangeResult(question?.question_id, "T")} + /> +
    +
    + {isReview && optionTextTrue === "F" && answer !== "F" && ( + + )} + onChangeResult(question?.question_id, "F")} + /> +
    +
    +
    +
    + {isReview && + !isEmpty(question?.explain_parse?.content_question_text) && ( +
    + +
    + {question?.explain_parse?.content_question_text} +
    +
    + )} +
    + ); + }); + }; + + const renderQuestionsReading14 = () => { + return category?.listQuestions?.map((question, index) => { + let answer = resultExam.filter( + (result) => result.questionId === question.question_id + )[0]?.answer; + let textAnswer = props?.userAnswerText?.trim() || (answer + ? answer.find((item) => item.type === "input")?.value?.trim() + : ""); + let matchOptionText = question?.list_option[0].match_option_text?.map( + (text) => text + ); + const isActiveReview = listReview?.find(item => item?.question_id === question?.question_id)?.checked + return ( +
    + {isDoing && onCheckReview(question?.question_id)}/>} +
    + + {renderFormAnswer( + question?.list_option, + answer, + !isReview, + (value) => onChangeResult(question.question_id, value) + )} +
    + {isReview && renderTextAnswerReview(textAnswer, matchOptionText)} + {isReview && !isEmpty(question?.option_explain) && ( +
    + +
    + {question?.option_explain} +
    +
    + )} +
    + ); + }); + }; + + const renderListQuestions = () => { + switch (type) { + case "reading1": + return renderQuestionsReading1(); + case "reading2": + return renderQuestionsReading2(); + case "reading3": + return renderQuestionsReading3(); + case "reading4": + return renderQuestionsReading4(); + case "reading6": + return renderQuestionsReading6(); + case "reading11": + return renderQuestionsReading11(); + case "reading12": + return renderQuestionsReading12(); + case "reading14": + return renderQuestionsReading14(); + } + }; + + // console.log(category); + + const renderContent = (group_script) => { + console.log('group_script: ', group_script) + let content = group_script; + if (type === "reading3") { + category?.jamming_answer_parse?.forEach((text) => { + if (content.includes(`{${text}}`)) { + category?.listQuestions?.forEach((question, index) => { + if (!content.includes(`(${indexQuestion + index})`)) { + content = content.replace( + `{${text}}`, + `______(${indexQuestion + index})` + ); + } + }); + } + }); + } else if (type === "reading4") { + // console.log(category?.match_option_text); + category?.match_option_text.forEach((text) => { + if (content.includes(`{${text}}`)) { + category?.listQuestions?.forEach((question, index) => { + if (!content.includes(`(${indexQuestion + index})`)) { + content = content.replace( + `{${text}}`, + `______(${indexQuestion + index})` + ); + } + }); + } + }); + } else if (type === "reading2") { + category?.match_option_text.forEach((text) => { + if (content.includes(`{${text}}`)) { + category?.listQuestions?.forEach((question, index) => { + if (!content.includes(`(${indexQuestion + index})`)) { + content = content.replace( + `{${text}}`, + `______(${indexQuestion + index})` + ); + } + }); + } + }); + } else if (type === "reading6") { + content = content.replaceAll("{", "(").replaceAll("}", ")______"); + } + return content; + }; + + return ( +
    + + +
    + {category?.group_title ? category?.group_title : ""} +
    + {type === "reading3" && ( +
    + {category?.jamming_answer_parse?.map((item) => ( + {item} + ))} +
    + )} +
    +

    {title}

    + + {type === "reading2" && ( +
    + {renderContent(category?.content)} +
    + )} + {type === "reading4" && ( +
    + {renderContent(category?.content)} +
    + )} +
    +
    {renderListQuestions()}
    +
    + ); +}; diff --git a/src/_components/exam-test/styles.scss b/src/_components/exam-test/styles.scss new file mode 100644 index 0000000..288c75f --- /dev/null +++ b/src/_components/exam-test/styles.scss @@ -0,0 +1,259 @@ +.item-checkbox { + display: flex; + align-items: center; + margin: 3px; + cursor: pointer; + + label { + font-size: 18px; + margin-left: 8px; + margin-top: -3px; + } +} + +.item-grammar1 { + display: flex; + margin: 12px 3px; + + .order { + font-size: 18px; + } + + .begin-text { + font-size: 18px; + } + + .end-text { + font-size: 18px; + } + + input { + margin: 2px 6px; + padding: 6px; + font-size: 16px; + border-radius: 6px; + border: 1px solid #707070; + + &:focus { + outline: none; + } + + &::placeholder { + font-size: 13px; + } + } +} + +.item-pronunuciation { + width: 100%; + + u { + text-decoration: none; + border-bottom: 1.5px solid #454545; + } +} + +.item-grammar9 { + margin-top: 16px; + margin-bottom: 8px; + + u { + text-decoration: none; + border-bottom: 1.5px solid #454545; + } +} + +.label { + font-size: 18px; +} + +.title-question { + display: block; + font-size: 18px; + font-family: "Myriadpro-SemiBold"; +} + +.title_question_width { + width: 100%; +} + +.underline { + text-decoration: underline; +} + +.item-reading1, +.item-writing, +.exam-listening { + margin: 8px 3px; + width: 100%; + + .key-word-sugguest { + display: flex; + width: 75%; + align-items: center; + flex-wrap: wrap; + padding: 16px; + border: 1.5px solid #70707070; + border-radius: 16px; + margin: 24px; + text-align: center; + margin-left: auto; + margin-right: auto; + + span { + width: 25%; + margin: 8px 0px; + font-size: 18px; + // font-family: 'Myriadpro-SemiBold'; + } + } + + .content-document { + .title-content { + font-size: 18px; + text-align: center; + } + + span { + font-size: 18px; + white-space: break-spaces; + display: inline-block !important; + padding-bottom: 0.6rem !important; + } + } + + .content-audio { + margin: 30px 0px 40px; + // width: 50%; + width: 540px; + } + + .item-writing .content-question { + width: 100%; + } + + .content-question { + margin-top: 16px; + width: 80%; + + .item-question { + margin: 8px; + } + + .order { + font-size: 18px; + font-family: "Myriadpro-SemiBold"; + } + + .begin-text { + font-size: 18px; + } + + .end-text { + font-size: 18px; + } + + input { + margin: 0px 6px; + padding: 8px; + font-size: 16px; + border-radius: 6px; + border: 1px solid #707070; + + &:focus { + outline: none; + } + + &::placeholder { + font-size: 13px; + } + } + + .full-width { + width: 100%; + margin: 6px; + } + + .width-50-percent { + width: 50%; + margin: 6px; + } + + .d-flex { + display: flex; + align-items: center; + margin: 6px; + } + } + + .content-question-review { + width: 100%; + } +} + +.text-explain-exam { + margin-top: 16px; + margin-left: 16px; + + label { + font-weight: bold; + font-size: 18px; + } + + div { + font-size: 18px; + } +} + +.item-exam-result-text { + display: flex; + flex-direction: column; + margin-left: 16px; + + .text-answer-false { + color: #be1e2d; + font-size: 18px; + } + + .text-answer-true { + color: #009444; + font-size: 18px; + } +} + +//Check box square css +.img_checkBox { + width: 1.7rem; + height: auto; +} + +.review-later-box { + position: absolute; + left: -34px; + top: 4px; + width: 20px; + height: 20px; + cursor: pointer; +} + +.review-later-img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.review-later-tool { + position: absolute; + top: -20px; + right: 20px; + background-color: #fff; + border: 1px solid #F7931E; + border-top-left-radius: 10px; + border-top-right-radius: 10px; + border-bottom-left-radius: 10px; + display: inline-block; + width: max-content; + padding: 0 8px; + font-size: smaller; + cursor: default; +} \ No newline at end of file diff --git a/src/_config/ReduxPersist.js b/src/_config/ReduxPersist.js new file mode 100644 index 0000000..647f7ca --- /dev/null +++ b/src/_config/ReduxPersist.js @@ -0,0 +1,12 @@ +import localStorage from "redux-persist/es/storage"; + +const ReduxPersist = { + active: true, + reducerVersion: "0.7", + storeConfig: { + key: "primary", + storage: localStorage, + }, +}; + +export default ReduxPersist; diff --git a/src/_constants/alerts.js b/src/_constants/alerts.js new file mode 100644 index 0000000..215242e --- /dev/null +++ b/src/_constants/alerts.js @@ -0,0 +1,6 @@ +export const alertConstants = { + SUCCESS: "ALERT_SUCCESS", + ERROR: "ALERT_ERROR", + CLEAR: "ALERT_CLEAR", + MSG_ERROR: "Không được nhập quá 50 ký tự.", +}; diff --git a/src/_constants/auth.js b/src/_constants/auth.js new file mode 100644 index 0000000..aede9bb --- /dev/null +++ b/src/_constants/auth.js @@ -0,0 +1,6 @@ +export const stepAuthConstants = { + STEP_CREATE_ACCOUNT: "STEP_CREATE_ACCOUNT", + STEP_UPDATE_ACCOUNT: "STEP_UPDATE_ACCOUNT", + STEP_ADD_CLASS_NAME: "STEP_ADD_CLASS_NAME", + STEP_ACCOUNT_TYPE: "STEP_ACCOUNT_TYPE", +}; diff --git a/src/_constants/classes.js b/src/_constants/classes.js new file mode 100644 index 0000000..89c1bc8 --- /dev/null +++ b/src/_constants/classes.js @@ -0,0 +1,4 @@ +export const classesConstants = { + SUNDAY_FREE: "sunday_free", + SUNDAY: "sunday", +}; diff --git a/src/_constants/config.example.js b/src/_constants/config.example.js new file mode 100644 index 0000000..a014536 --- /dev/null +++ b/src/_constants/config.example.js @@ -0,0 +1,17 @@ +export const configConstants = { + API_URL: "", + API_KEY: "", + AUTH_BASIC_USER_NAME: "", + AUTH_BASIC_PASSWORD: "", + APP_ID_GOOGLE: "", + SCOPE_LOGIN_GOOGLE: "", + APP_ID_FACEBOOK: "", + BASE_URL: "", + API_URL_SETEST: "", + API_TIMEOUT: 12000, + LOGIN_VIA_GOOLE: "LOGIN_VIA_GOOLE", + LOGIN_VIA_FACEBOOK: "LOGIN_VIA_FACEBOOK", + LOGIN_VIA_APPLE: "LOGIN_VIA_APPLE", + APP_ID_APPLE: "", + APPLE_REDIRECT_URL: "", +}; diff --git a/src/_constants/configConstants.js b/src/_constants/configConstants.js new file mode 100644 index 0000000..a014536 --- /dev/null +++ b/src/_constants/configConstants.js @@ -0,0 +1,17 @@ +export const configConstants = { + API_URL: "", + API_KEY: "", + AUTH_BASIC_USER_NAME: "", + AUTH_BASIC_PASSWORD: "", + APP_ID_GOOGLE: "", + SCOPE_LOGIN_GOOGLE: "", + APP_ID_FACEBOOK: "", + BASE_URL: "", + API_URL_SETEST: "", + API_TIMEOUT: 12000, + LOGIN_VIA_GOOLE: "LOGIN_VIA_GOOLE", + LOGIN_VIA_FACEBOOK: "LOGIN_VIA_FACEBOOK", + LOGIN_VIA_APPLE: "LOGIN_VIA_APPLE", + APP_ID_APPLE: "", + APPLE_REDIRECT_URL: "", +}; diff --git a/src/_constants/configs.example.js b/src/_constants/configs.example.js new file mode 100644 index 0000000..7238607 --- /dev/null +++ b/src/_constants/configs.example.js @@ -0,0 +1,21 @@ +import { configConstants } from "./config"; + +export const configConstants = { + API_URL: "", + API_KEY: "8c3a30506d9633a8b202cb5a91873efa", + AUTH_BASIC_USER_NAME: "gek_admin", + AUTH_BASIC_PASSWORD: "gek_admin_password", + APP_ID_GOOGLE: + "906644438510-eid5lsm4ndgtu0qh2lbrk31tl8r7rrt6.apps.googleusercontent.com", + SCOPE_LOGIN_GOOGLE: "https://www.googleapis.com/auth/user.gender.read", + APP_ID_FACEBOOK: "660393674829980", + BASE_URL: configConstants.BASE_URL, + EXCERCISE_URL: configConstants.EXCERCISE_URL, + API_URL_SETEST: configConstants.API_URL_SETEST, + API_TIMEOUT: "60000", + LOGIN_VIA_GOOLE: "GOOGLE", + LOGIN_VIA_FACEBOOK: "FACEBOOK", + LOGIN_VIA_APPLE: "LOGIN_VIA_APPLE", + APP_ID_APPLE: "gk.app.sunday", + DEFAULT_LIMIT: 10, +}; diff --git a/src/_constants/curriculums.js b/src/_constants/curriculums.js new file mode 100644 index 0000000..0c98a19 --- /dev/null +++ b/src/_constants/curriculums.js @@ -0,0 +1,26 @@ +export const curriculumConstants = { + GET_LIST_CURRICULUM_FAVORITE_START: "GET_LIST_CURRICULUM_FAVORITE_START", + GET_LIST_CURRICULUM: "GET_LIST_CURRICULUM", + ADD_CURRICULUM: "ADD_CURRICULUM", + GET_DETAIL_CURRICULUM_CLASS: "GET_DETAIL_CURRICULUM_CLASS", + GET_DETAIL_CURRICULUM: "GET_DETAIL_CURRICULUM", + SCREEN_DETAIL_CURRICULUM: "SCREEN_DETAIL_CURRICULUM", + CLEAR_DETAIL_CURRICULUM: "CLEAR_DETAIL_CURRICULUM", + CLEAR_DETAIL_CURRICULUM_CLASS: "CLEAR_DETAIL_CURRICULUM_CLASS", + GET_LIST_CURRICULUM_FAVORITE: "GET_LIST_CURRICULUM_FAVORITE", + GET_FILTER_CURRICULUM: "GET_FILTER_CURRICULUM", + ADD_PARAM_FILTER_CURRICULUM: "ADD_PARAM_FILTER_CURRICULUM", + CLEAR_PARAM_FILTER_CURRICULUM: "CLEAR_PARAM_FILTER_CURRICULUM", + CHANGE_VIEW: "CHANGE_VIEW", + GET_LIST_CURRICULUM_EXERCISE: "GET_LIST_CURRICULUM_EXERCISE", + GET_DATA_MAP_CURRICULUM_STUDENT_START: + "GET_DATA_MAP_CURRICULUM_STUDENT_START", + GET_DATA_MAP_CURRICULUM_STUDENT: "GET_DATA_MAP_CURRICULUM_STUDENT", + GET_DATA_GRID_CURRICULUM_STUDENT: "GET_DATA_GRID_CURRICULUM_STUDENT", + GET_LESSON_CURRICULUM_STUDENT: "GET_LESSON_CURRICULUM_STUDENT", + RESET_DETAIL: "RESET_DETAIL", + FROM_PAGE_STATUS: "FROM_PAGE_STATUS", + CLEAR_FROM_PAGE: "CLEAR_FROM_PAGE", + LESSON_BY_SKILL_TEACHER: "LESSON_BY_SKILL_TEACHER", + GET_LESSON_IN_SKILL: "GET_LESSON_IN_SKILL", +}; diff --git a/src/_constants/footerSelection.js b/src/_constants/footerSelection.js new file mode 100644 index 0000000..a1e8114 --- /dev/null +++ b/src/_constants/footerSelection.js @@ -0,0 +1,7 @@ +export const FooterSelection = { + INTRODUCTION: "intro", + COURSES: "courses", + BUY_COURSES: "buy_courses", + POLICY: "policy", + SUPPORT: "support", +}; diff --git a/src/_constants/headerNews.js b/src/_constants/headerNews.js new file mode 100644 index 0000000..184cf84 --- /dev/null +++ b/src/_constants/headerNews.js @@ -0,0 +1,23 @@ +export const TypeHeaderNewsItem = { + HOME: "", + INTRODUCTION: "introduction", + COURSES: "courses", + FEE: "fee", + MOCK_TEST: "mock_test", + TEACHER: "teacher", + PARENT: "parent", + LOGIN: "login_news", + POLICY: "policy", + TARIFF: "tariff", +}; + +export const NameTitleNewsItem = { + HOME: "Trang chủ", + INTRODUCTION: "Giới thiệu", + COURSES: "Khóa học", + FEE: "Học phí", + MOCK_TEST: "Luyện thi", + CONTACT: "Liên hệ", + PROFILE: "Hồ sơ", + // LOGIN: "login_news", +}; diff --git a/src/_constants/home_type.js b/src/_constants/home_type.js new file mode 100644 index 0000000..2ead453 --- /dev/null +++ b/src/_constants/home_type.js @@ -0,0 +1,3 @@ +export const homeType = { + SELECT_TEACHER_OR_CURRICULUM: "SELECT_TEACHER_OR_CURRICULUM" +}; \ No newline at end of file diff --git a/src/_constants/homepageNews.js b/src/_constants/homepageNews.js new file mode 100644 index 0000000..84d398a --- /dev/null +++ b/src/_constants/homepageNews.js @@ -0,0 +1,5 @@ +export const TypeHomePage = { + BENEFIT_STUDENT: "benefit_student", + BENEFIT_TEACHER: "benefit_teacher", + BENEFIT_PARENT: "benefit_parent", +}; diff --git a/src/_constants/index.js b/src/_constants/index.js new file mode 100644 index 0000000..334e364 --- /dev/null +++ b/src/_constants/index.js @@ -0,0 +1,11 @@ +export * from './config'; +export * from './configConstants'; +export * from './users'; +export * from './alerts'; +export * from './students'; +export * from './licenses'; +export * from './teachers'; +export * from './schedules'; +export * from './curriculums'; +export * from './popups'; +export * from './home_type'; diff --git a/src/_constants/licenses.js b/src/_constants/licenses.js new file mode 100644 index 0000000..405015d --- /dev/null +++ b/src/_constants/licenses.js @@ -0,0 +1,8 @@ +export const licenseConstants = { + GET_CURRENT_LICENSE: 'GET_CURRENT_LICENSE', + MESSAGE_LICENSE_ADD_CODE_COMPLETE: 'MESSAGE_LICENSE_ADD_CODE_COMPLETE', + SCREEN_LICENSE_ADD_CODE: 'SCREEN_LICENSE_ADD_CODE', + GET_HISTORY_LICENSE: 'GET_HISTORY_LICENSE', + SCREEN_GET_CURREN_LICENSE: 'SCREEN_GET_CURREN_LICENSE', + SCREEN_GET_HISTORY_LICENSE: 'SCREEN_GET_HISTORY_LICENSE', +}; \ No newline at end of file diff --git a/src/_constants/linkDownloadApp.js b/src/_constants/linkDownloadApp.js new file mode 100644 index 0000000..7915464 --- /dev/null +++ b/src/_constants/linkDownloadApp.js @@ -0,0 +1,17 @@ +export const LinkApp = { + student: { + APP_STORE: "https://apps.apple.com/vn/app/sunday-english/id1536078421", + GG_PLAY: + "https://play.google.com/store/apps/details?id=gk.app.sunday&pcampaignid=web_share", + }, + teacher: { + APP_STORE: "https://apps.apple.com/in/app/sunday-teacher/id6473355553", + GG_PLAY: + "https://play.google.com/store/apps/details?id=gk.app.sundayteacher", + }, + parent: { + APP_STORE: "https://apps.apple.com/vn/app/sunday-parent/id6479732371", + GG_PLAY: + "https://play.google.com/store/apps/details?id=gk.app.sundayparent", + }, +}; diff --git a/src/_constants/linkingParent.js b/src/_constants/linkingParent.js new file mode 100644 index 0000000..5c42324 --- /dev/null +++ b/src/_constants/linkingParent.js @@ -0,0 +1,3 @@ +export const linkingParentConstants = { + SCREEN_MANAGE_LINKING: 'SCREEN_MANAGE_LINKING', +} \ No newline at end of file diff --git a/src/_constants/policy.js b/src/_constants/policy.js new file mode 100644 index 0000000..6fb9724 --- /dev/null +++ b/src/_constants/policy.js @@ -0,0 +1,865 @@ +export const policy = { + term: { + id: 'term', + name: "ĐIỀU KHOẢN SỬ DỤNG", + data: [ + { + id: 1, + title: "1. Chấp nhận các điều khoản thỏa thuận", + contents: [ + { + id: 1, + content: + "Chào mừng các bạn đến với Sunday English - Giải pháp nâng cao năng lực Tiếng Anh học sinh THCS. Chúng tôi cung cấp dịch vụ (như được mô tả dưới đây) cho bạn, dựa trên các Điều khoản Sử dụng Dịch vụ sau đây, chúng tôi toàn quyền thay đổi nội dung các điều khoản theo quyết định của mình mà không cần báo trước. Khi sử dụng, có nghĩa rằng bạn đã chấp nhận và đồng ý tuân thủ theo thoả thuận.", + }, + { + id: 2, + content: + "Tất cả các chỉ dẫn hoặc quy định theo từng trang riêng biệt cũng là những phần không thể tách rời với Điều khoản dịch vụ này.", + } + ] + }, + { + id: 2, + title: "2. Mô tả dịch vụ", + contents: [ + { + id: 0, + content: + "Dịch vụ Sunday English cung cấp cho bạn bao gồm, nhưng không giới hạn, những dịch vụ hiện có sau đây:", + }, + { + id: 1, + content: + "- Ứng dụng Sunday English - Nền tảng học tiếng Anh trực tuyến thông minh, cung cấp cho bạn các khóa học tiếng Anh online uy tín và chất lượng.", + }, + { + id: 2, + content: + "- Ứng dụng Sunday Teacher - Giải pháp ưu việt giúp thầy cô giảng dạy tiếng Anh hiệu quả.", + }, + { + id: 3, + content: + "- Ứng dụng Sunday Parent - Ứng dụng tích hợp công nghệ AI giúp phụ huynh dễ dàng kèm cặp con học giỏi tiếng Anh.", + }, + { + id: 4, + content: "- Website: sundayenglish.com", + }, + ], + }, + { + id: 3, + title: "3. Trách nhiệm của bạn trong việc đăng ký", + contents: [ + { + id: 0, + content: + "Khi xem xét việc bạn sử dụng Dịch vụ, bạn cam kết rằng mình có đủ tuổi luật định để xác lập một hợp đồng có tính ràng buộc và không phải là người bị hạn chế nhận các dịch vụ theo pháp luật hoặc bởi việc thực thi các phán quyết khác. Bạn cũng đồng ý rằng: ", + }, + { + id: 1, + content: + "(a) Cung cấp các thông tin mới nhất, đầy đủ, trung thực và chính xác về bản thân bạn theo hướng dẫn trong mẫu đăng ký sử dụng Dịch vụ; ", + }, + { + id: 2, + content: + "(b) Duy trì và cập nhật kịp thời Dữ liệu đăng ký để bảo đảm rằng dữ liệu này là mới nhất, đầy đủ, trung thực và chính xác. Nếu bạn cung cấp bất kỳ thông tin nào không phải là thông tin mới nhất, không đầy đủ, không trung thực hoặc không chính xác, hoặc nếu Sunday English có căn cứ hợp lý để nghi ngờ rằng thông tin đó không phải là thông tin mới nhất, không đầy đủ, không trung thực hoặc không chính xác, Sunday English có quyền đình chỉ hoặc chấm dứt tài khoản của bạn và từ chối bất kỳ và toàn bộ việc sử dụng Dịch vụ (hoặc bất kỳ phần nào của Dịch vụ) tại thời điểm hiện tại hoặc sau này.", + }, + { + id: 3, + content: + "Sunday English quan tâm tới sự an toàn và sự riêng tư của tất cả những người sử dụng dịch vụ của mình, đặc biệt là trẻ em. Tuy nhiên, xin nhớ rằng Dịch vụ này được thiết kế để thu hút đông đảo người sử dụng. Vì vậy, nếu bạn là cha mẹ hoặc người giám hộ hợp pháp, bạn có trách nhiệm xác định xem bất kỳ các Dịch vụ và/hoặc Nội dung nào có thích hợp cho con của bạn hay không. Tương tự, nếu bạn là trẻ em, xin hãy hỏi ý kiến cha mẹ hoặc người giám hộ hợp pháp của bạn để xem liệu Dịch vụ và/hoặc Nội dung có phù hợp với bạn hay không. ", + }, + { + id: 4, + content: + "Mặc dù có quy định như đã nêu ở trên, chúng tôi có thể cho phép bạn sử dụng một số phần của Dịch vụ mà bạn không cần phải đăng ký sử dụng. Trong trường hợp đó, danh tính của bạn sẽ được dựa trên các phương tiện nhận dạng khác mà chúng tôi cho là thích hợp. Trong các trường hợp thích hợp, việc nhận dạng có thể được tiến hành dựa trên dữ liệu nhận dạng máy điện thoại di động hoặc việc đăng ký thuê bao sử dụng dịch vụ liên lạc của bạn do người điều hành mạng của bạn cung cấp. Bạn đồng ý rằng thông tin đó có thể được thu thập và tiết lộ cho chúng tôi và có thể được sử dụng theo quy định của bản Điều khoản dịch vụ này.", + } + ], + }, + { + id: 4, + title: "4. Tài khoản thành viên, mật khẩu và sự bảo mật", + contents: [ + { + id: 1, + content: + "Bạn có trách nhiệm giữ kín mật khẩu và tài khoản, và hoàn toàn chịu trách nhiệm đối với tất cả các hoạt động diễn ra thông qua việc sử dụng mật khẩu hoặc tài khoản của bạn. Bạn đồng ý thông báo ngay cho Sunday English về bất kỳ trường hợp nào sử dụng trái phép mật khẩu hoặc tài khoản của bạn hoặc bất kỳ trường hợp nào khác vi phạm sự bảo mật. Sunday English không thể và sẽ không chịu trách nhiệm đối với bất kỳ tổn thất hoặc thiệt hại nào phát sinh do bạn không tuân thủ quy định tại mục này.", + }, + { + id: 2, + content: + "Mỗi tài khoản được đăng nhập tối đa trên 2 thiết bị, danh sách thiết bị có thể được thay đổi ở phần quản lý thiết bị. Người dùng chỉ được sử dụng 1 tài khoản trên 1 thiết bị tại 1 thời điểm.", + } + ] + }, + { + id: 5, + title: "5. Nội dung của bạn", + contents: [ + { + id: 1, + titleDot: "Tổng quan", + content: + "Hiện tại, hoặc trong tương lai, chúng tôi có thể cho phép gửi và đăng hoặc liên kết đến tác phẩm của tác giả, tác phẩm sáng tác, đồ họa, hình ảnh, video, âm thanh, văn bản và các tương tác (“Nội dung”) do bạn gửi, bao gồm nhưng không giới hạn mục đích tương tác với các tính năng hiện có của ứng dụng hoặc đăng tải, lưu trữ và tạo mới nội dung để phục vụ cho việc dạy và học trên nền tảng ứng dụng (gọi chung là “Nội dung của bạn”). Bạn chịu trách nhiệm pháp lý về Nội dung của bạn được gửi tới Dịch vụ. Chúng tôi không có nghĩa vụ kiểm duyệt toàn bộ Nội dung của bạn nhưng chúng tôi có thể sử dụng các hệ thống tự động phân tích Nội dung của bạn để giúp phát hiện hành vi vi phạm và lạm dụng, chẳng hạn như thư rác, phần mềm độc hại và nội dung bất hợp pháp.", + }, + { + id: 2, + titleDot: "Trao quyền", + content: + "Chúng tôi có thể sử dụng Nội dung của bạn theo nhiều cách khác nhau, bao gồm hiển thị công khai, định dạng lại, sử dụng công nghệ để cải thiện công nghệ, tạo các tác phẩm phái sinh từ nó, phân phối và cho phép bên khác quyền sử dụng tương tự trên trang web và nền tảng truyền thông của họ. Để làm rõ, bạn giữ lại tất cả các quyền sở hữu của mình đối với Nội Dung của bạn. Tuy nhiên, bằng việc gửi Nội dung của bạn đến Dịch vụ, bạn thông qua đây cấp cho chúng tôi quyền toàn cầu, không độc quyền, miễn phí bản quyền, có thể cấp quyền thứ cấp và có thể chuyển giao để sử dụng, sao chép, truyền đạt, tạo lập các tác phẩm phái sinh, trình bày, và thực hiện Nội dung của bạn liên quan đến Dịch vụ và hoạt động kinh doanh của chúng tôi (và của các bên kế thừa và các công ty liên kết của chúng tôi), bao gồm nhưng không giới hạn cho việc quảng bá và truyền đạt lại một phần hoặc toàn bộ Dịch vụ (và các tác phẩm phái sinh của Dịch vụ) trong bất kỳ định dạng truyền thông đại chúng nào và thông qua bất kỳ các kênh truyền thông đại chúng nào. Bạn cũng thông qua đây cấp cho từng người dùng Dịch vụ quyền không độc quyền để truy cập Nội dung của bạn thông qua Dịch vụ, và để sử dụng, sao chép, truyền đạt, trình bày và thực hiện Nội dung của bạn theo như được cho phép thông qua chức năng của Dịch vụ và theo các Điều khoản này.", + }, + { + id: 3, + titleDot: "Đại diện và bảo đảm về nội dung của bạn", + contents: [ + { + id: 0, + content: "Bạn đại diện và đảm bảo rằng: ", + }, + { + id: 1, + content: + "(a) Bạn sở hữu Nội dung của bạn hoặc bạn có quyền sử dụng và cấp cho chúng tôi quyền và giấy phép như được cung cấp trong các Điều khoản này;", + }, + { + id: 2, + content: + "(b) Việc chia sẻ Nội dung của bạn trên hoặc thông qua Dịch vụ không vi phạm quyền riêng tư, quyền công khai, bản quyền, quyền hợp đồng hoặc bất kỳ quyền nào khác của bất kỳ người nào.", + }, + ], + }, + { + id: 4, + titleDot: "Điều khoản cấm về Nội Dung chia sẻ", + contents: [ + { + id: 0, + content: + "Khi gửi Nội dung hoặc sử dụng Dịch vụ, bạn cam kết sẽ không gửi tài liệu:", + }, + { + id: 1, + content: + "a) Gửi hoặc chuyển các thông tin đe doạ, lạm dụng, bôi nhọ, nói xấu, khiêu dâm, phi thẩm mỹ, xúc phạm hoặc bất kỳ loại thông tin không đứng đắn nào, bao gồm nhưng không hạn chế việc truyền bá tin tức góp phần hay khuyến khích hành vi phạm tội, gây ra trách nhiệm pháp lý dân sự hoặc vi phạm pháp luật địa phương, liên bang, quốc gia hoặc quốc tế;", + }, + { + id: 2, + content: + "b) Chống Nhà nước Cộng hoà xã hội chủ nghĩa Việt Nam, phá hoại khối đoàn kết toàn dân, tuyên truyền, xuyên tạc, kích động hoặc cung cấp thông chống phá Nhà nước Việt Nam; ", + }, + { + id: 3, + content: + "c) Kích động bạo lực, tuyên truyền chiến tranh xâm lược, gây hận thù giữa các dân tộc và nhân dân các nước, kích động dâm ô, đồi trụy, tội ác, tệ nạn xã hội, mê tín dị đoan, phá hoại thuần phong mỹ tục của dân tộc; ", + }, + + { + id: 4, + content: + "d) Tiết lộ bí mật nhà nước, bí mật quân sự, an ninh, kinh tế, đối ngoại và những bí mật khác đã được pháp luật quy định; ", + }, + + { + id: 5, + content: + "e) Xuyên tạc, vu khống, xúc phạm uy tín của tổ chức, danh dự, nhân phẩm, uy tín của công dân;", + }, + { + id: 6, + content: + "f) Quảng cáo, tuyên truyền hàng hoá, dịch vụ thuộc danh mục cấm đã được pháp luật quy định; ", + }, + { + id: 7, + content: "g) Đề cập đến các vấn đề chính trị và tôn giáo; ", + }, + { + id: 8, + content: + "h) Sử dụng các từ ngữ vô văn hóa vi phạm truyền thống đạo đức của Việt Nam; ", + }, + { + id: 9, + content: + "i) Hạn chế hoặc ngăn cản người sử dụng khác sử dụng và hưởng các tính năng tương tác; ", + }, + { + id: 10, + content: + "j) Gửi hay chuyển các thông tin, phần mềm, hoặc các tài liệu khác bất kỳ, vi phạm hoặc xâm phạm các quyền của những người khác, trong đó bao gồm cả tài liệu xâm phạm đến quyền riêng tư hoặc công khai, hoặc tài liệu được bảo vệ bản quyền, tên thương mại hoặc quyền sở hữu khác, hoặc các sản phẩm phái sinh mà không được sự cho phép của người chủ sở hữu hoặc người có quyền hợp pháp;", + }, + ], + }, + { + id: 5, + titleDot: "Quyền xử lý Nội dung", + content: + "Chúng tôi có quyền theo dõi, chỉnh sửa và loại bỏ nội dung. Chúng tôi không có nghĩa vụ giám sát việc bạn sử dụng Dịch vụ hoặc xem xét, kiểm duyệt bất kỳ Nội dung của bạn nhưng chúng tôi có quyền giám sát, xóa, chỉnh sửa và chặn Nội dung hoặc tài khoản chứa Nội dung mang tính chất vi phạm và lạm dụng, nhằm đảm bảo sự tuân thủ của bạn với các Điều khoản này; hoặc tuân thủ pháp luật hiện hành; lệnh hoặc yêu cầu của tòa án, cơ quan thẩm quyền khác. Bất kỳ lúc nào và không cần thông báo trước, chúng tôi sẽ bảo lưu quyền xóa hoặc vô hiệu hóa quyền truy cập vào bất kỳ Nội dung nào mà chúng tôi xem xét và nhận thấy có hành vi vi phạm các Điều khoản này hoặc có hại cho Dịch vụ.", + }, + ], + }, + { + id: 6, + title: "6. Quyền sở hữu của Sunday English đối với Nội dung Dịch vụ", + contents: [ + { + id: 1, + content: + "Tất cả nội dung có sẵn thông qua Dịch vụ, bao gồm thiết kế, văn bản, đồ họa, hình ảnh, thông tin, phần mềm, âm thanh và các tệp khác cũng như sự lựa chọn và sắp xếp của chúng tôi (“Nội dung Dịch vụ”), là tài sản độc quyền của Sunday English hoặc người cấp phép của Sunday English. Không có Nội dung dịch vụ nào có thể được sửa đổi, sao chép, phân phối, đóng khung, sao chép, tái xuất bản, tải xuống, hiển thị, đăng, truyền hoặc bán dưới bất kỳ hình thức nào hoặc bằng bất kỳ phương tiện nào, toàn bộ hoặc một phần, ngoài những điều được cho phép rõ ràng trong các Điều khoản sử dụng này. Bạn không được sử dụng bất kỳ phương pháp khai thác dữ liệu, rô bốt, công nghệ AI hoặc thu thập hoặc trích xuất dữ liệu tương tự nào để lấy Nội dung dịch vụ.", + } + ] + }, + { + id: 7, + title: "7. Quy định về Hạn chế", + contents: [ + { + id: 0, + content: "Bạn đồng ý không:" + }, + { + id: 1, + content: + "(a) Can thiệp, làm hỏng, làm suy yếu hoặc vô hiệu hóa hoạt động của Dịch vụ, bằng bất kỳ phương tiện nào (kể cả thông qua phương tiện tự động hoặc cách khác), bao gồm tải lên hoặc phổ biến virus, worm, phần mềm gián điệp, phần mềm quảng cáo hoặc mã độc hại khác; ", + }, + { + id: 2, + content: + "(b) Đưa ra các đề nghị, quảng cáo, đề xuất hoặc gửi thư rác hoặc thư rác không mong muốn cho Người dùng khác hoặc sử dụng Dịch vụ vì mục đích thương mại; ", + }, + { + id: 3, + content: + "(c) Sử dụng bất kỳ “rô bốt”, “spider”, “thiết bị đọc ngoại tuyến” hoặc các phương tiện tự động khác để truy cập Dịch vụ cho bất kỳ mục đích nào mà không có sự đồng ý rõ ràng của chúng tôi hoặc bỏ qua các tiêu đề loại trừ “rô bốt” hoặc các biện pháp tương tự; ", + }, + { + id: 4, + content: + "(d) Xóa, phá vỡ, vô hiệu hóa, làm hỏng hoặc can thiệp vào các tính năng liên quan đến bảo mật của Dịch vụ, các tính năng ngăn chặn hoặc hạn chế việc sử dụng hoặc sao chép bất kỳ phần nào của Dịch vụ hoặc các tính năng thực thi Hạn chế dịch vụ; ", + }, + { + id: 5, + content: + "(e) Cố gắng truy cập trái phép vào Dịch vụ, các tài khoản Người dùng khác, hệ thống máy tính hoặc mạng được kết nối với Dịch vụ thông qua hoạt động truy cập trái phép, khai thác mật khẩu hoặc bất kỳ phương tiện nào khác; ", + }, + { + id: 6, + content: + "(f) Liên kết worm tới Dịch vụ và bạn đồng ý rằng bạn sẽ nhanh chóng xóa mọi liên kết mà Công ty thấy có thể bị phản đối theo quyết định riêng của mình; ", + }, + { + id: 7, + content: + "(g) Gửi email hàng loạt, khảo sát hoặc thông điệp hàng loạt khác, dù là thương mại hay phi thương mại; ", + }, + { + id: 8, + content: + "(h) Gạ gẫm lấy thông tin cá nhân từ trẻ em, hoặc gửi hoặc truyền tải nội dung khiêu dâm; ", + }, + { + id: 9, + content: + "(i) Định dạng lại hoặc tái cấu trúc bất kỳ phần nào của Dịch vụ; ", + }, + { + id: 10, + content: + "(k) Thực hiện bất kỳ hành động nào để áp đặt, hoặc mang tính áp đặt, theo quyết định riêng của chúng tôi, một lượng tải lớn không hợp lý hoặc không cân xứng trên cơ sở hạ tầng công nghệ của chúng tôi hoặc tạo ra nhu cầu lưu lượng quá mức của Dịch vụ; ", + }, + { + id: 11, + content: + "(l) Mạo danh một người khác hoặc đại diện cho chính mình như là liên kết với chúng tôi, nhân viên của chúng tôi hoặc các chuyên gia trong ngành khác; ", + }, + { + id: 12, + content: + "(m) Thu thập mật khẩu hoặc thông tin tài khoản khác của Người dùng; ", + }, + { + id: 13, + content: + "(n) Thu thập Tên người dùng, địa chỉ hoặc địa chỉ email cho bất kỳ mục đích nào.", + }, + { + id: 14, + content: + "(o) Cho tặng, sang nhượng, chuyển giao, cho thuê mượn những tài khoản đã kích hoạt.", + }, + ], + }, + { + id: 8, + title: "8. Sửa đổi đối với Dịch vụ", + contents: [ + { + id: 1, + content: + "Sunday English giữ quyền, tại bất kỳ thời điểm nào và tại từng thời điểm, sửa đổi hoặc ngừng tạm thời hoặc vĩnh viễn, Dịch vụ (hoặc bất kỳ phần nào của Dịch vụ) cho dù có hoặc không có thông báo, vì bất kỳ lý do nào, cho dù áp dụng chung đối với tất cả mọi người hoặc chỉ giới hạn đối với bạn. Bạn đồng ý rằng Sunday English không có nghĩa vụ dưới bất kỳ hình thức nào đối với bạn hoặc bất kỳ bên thứ ba nào về việc điều chỉnh, tạm ngừng hoặc ngừng cung cấp Dịch vụ.", + } + ] + }, + { + id: 9, + title: "9. Chấm dứt", + contents: [ + { + id: 1, + content: + "Bạn đồng ý rằng Sunday English có thể, tùy theo các trường hợp cụ thể và không cần thông báo trước, chấm dứt ngay lập tức việc sử dụng dịch vụ và truy cập vào tài khoản Sunday English đã được cấp cho bạn, bao gồm nhưng không giới hạn bởi các trường hợp sau:", + contents: [ + { + id: 1, + content: + "(a) Bạn có hành vi truy cập vào các hệ thống Sunday English với mục đích phá hoại sự hoạt động của hệ thống; truy xuất và thu thập dữ liệu trái phép; hoặc các hành vi sai phạm khác như được đề cập ở mục I.7 mà chúng tôi cho rằng chúng ảnh hưởng đến lợi ích của hệ thống và của cả cộng đồng người học khác.", + }, + { + id: 2, + content: + "(b) Theo yêu cầu của các cơ quan pháp luật có thẩm quyền.", + }, + { + id: 3, + content: "(c) Theo yêu cầu của bạn.", + }, + ] + }, + { + id: 2, + content: "Việc chấm dứt sử dụng tài khoản Sunday English của bạn bao gồm:", + contents: [ + { + id: 1, + content: + "(a) Xóa bỏ việc truy cập vào tất cả các Nội dung trong phạm vi ứng dụng và dịch vụ Sunday English.", + }, + { + id: 2, + content: + "(b) Xóa bỏ mật khẩu và tất cả các thông tin, tập tin liên quan và các nội dung gắn kết hoặc nằm trong tài khoản của bạn (hoặc bất cứ phần nào của tài khoản).", + }, + { + id: 3, + content: + "(c) Ngăn cản việc tiếp tục sử dụng ứng dụng và dịch vụ Sunday English.", + }, + ] + } + ], + }, + ], + }, + security: { + id: 'security', + name: "CHÍNH SÁCH BẢO VỆ VÀ XỬ LÝ DỮ LIỆU CÁ NHÂN", + contents: [ + { + id: 1, + content: "Khách hàng đồng ý áp dụng, phối hợp và cam kết tuân thủ Điều khoản và điều kiện chung về bảo vệ và xử lý dữ liệu cá nhân của Sunday English thuộc Công ty Cổ phần Công nghệ Giáo dục GK (GK Corp).", + } + ], + data: [ + { + id: 1, + title: "1. Những quy định chung", + contents: [ + { + id: 1, + contents: [ + { + id: 1, + content: + "A. Điều khoản và điều kiện chung về bảo vệ dữ liệu cá nhân (gọi chung là “Điều khoản và điều kiện chung về BVDLCN”), là một phần không thể tách rời của các thỏa thuận, điều khoản và điều kiện chi phối mối quan hệ giữa Khách hàng với Sunday English.", + }, + { + id: 2, + content: + "B. Sunday English đề cao và tôn trọng quyền riêng tư, bảo mật và an toàn thông tin cá nhân. Đồng thời, Sunday English luôn nỗ lực bảo vệ thông tin cá nhân, quyền riêng tư của Khách hàng và tuân thủ quy định pháp luật Việt Nam thông qua những biện pháp bảo vệ dữ liệu cá nhân đáp ứng và phù hợp với các tiêu chuẩn quốc tế.", + }, + { + id: 3, + content: + "C. Sunday English chỉ thu thập, xử lý và lưu trữ dữ liệu cá nhân của Khách hàng phù hợp với quy định của pháp luật và trong phạm vi (các) thỏa thuận giữa Sunday English và Khách hàng.", + }, + { + id: 4, + content: + "D. Bằng việc cung cấp dữ liệu cá nhân của một bên thứ ba (bao gồm nhưng không giới hạn bởi: thông tin của người phụ thuộc, người có liên quan theo quy định pháp luật, vợ/chồng, con cái và/hoặc cha mẹ và/hoặc người giám hộ, bạn bè, người tham chiếu, bên thụ hưởng, người được ủy quyền, đối tác, người liên hệ trong các trường hợp khẩn cấp hoặc cá nhân khác của Khách hàng) cho Sunday English, Khách hàng cam đoan, bảo đảm và chịu trách nhiệm rằng Khách hàng đã có được sự đồng ý hợp pháp của bên thứ ba đó cho việc xử lý và thông tin về việc Sunday English là chủ thể xử lý các thông tin cá nhân cho các mục đích được nêu tại Điều khoản và điều kiện chung về BVDLCN.", + }, + { + id: 5, + content: + "E. Điều khoản và điều kiện chung về BVDLCN sẽ được ưu tiên áp dụng trong trường hợp có bất kỳ xung đột hoặc mâu thuẫn nào với các thỏa thuận, điều khoản và điều kiện chi phối mối quan hệ của Khách hàng với Sunday English, cho dù được ký kết trước, vào ngày hoặc sau ngày Khách hàng chấp thuận Điều khoản và điều kiện chung về BVDLCN này.", + }, + ] + }, + { + id: 2, + content: + "Tất cả các quyền và nghĩa vụ của Sunday English và Khách hàng tại Điều khoản và điều kiện chung về BVDLCN này sẽ không thay thế, chấm dứt hoặc thay đổi, nhưng sẽ là cộng dồn vào các quyền mà Sunday English và Khách hàng đang có ở bất kỳ văn bản nào và không một điều khoản nào trong Điều khoản và điều kiện chung về BVDLCN này hàm ý hạn chế hoặc xóa bỏ bất kỳ quyền nào trong số các quyền của Sunday English.", + } + ], + }, + { + id: 2, + title: "2. Các hoạt động xử lý dữ liệu cá nhân", + contents: [ + { + id: 1, + title: "2.1. Thu thập dữ liệu cá nhân", + contents: [ + { + id: 1, + content: + "- Để Sunday English có thể cung cấp các sản phẩm, dịch vụ cho Khách hàng và/hoặc xử lý các yêu cầu của Khách hàng, Sunday English có thể cần phải và/hoặc được yêu cầu phải thu thập dữ liệu cá nhân có liên quan đến Khách hàng và các cá nhân có liên quan của Khách hàng. ", + }, + { + id: 2, + content: + "- Sunday English có thể thu thập trực tiếp hoặc gián tiếp những dữ liệu cá nhân này từ Khách hàng khi Khách hàng yêu cầu, hoặc trong quá trình Sunday English cung cấp bất kỳ sản phẩm, dịch vụ nào cho Khách hàng.", + }, + { + id: 3, + content: + "Việc thu thập dữ liệu chủ yếu trên Sunday English bao gồm: email, điện thoại, tên đăng nhập, mật khẩu đăng nhập, địa chỉ khách hàng (thành viên). Đây là các thông tin mà Sunday English cần thành viên cung cấp bắt buộc khi đăng ký sử dụng dịch vụ và để Sunday English liên hệ xác nhận khi khách hàng đăng ký sử dụng dịch vụ trên website nhằm đảm bảo quyền lợi cho cho người tiêu dùng. Các thành viên sẽ tự chịu trách nhiệm về bảo mật và lưu giữ mọi hoạt động sử dụng dịch vụ dưới tên đăng ký, mật khẩu và hộp thư điện tử của mình. Ngoài ra, thành viên có trách nhiệm thông báo kịp thời cho Sunday English về những hành vi sử dụng trái phép, lạm dụng, vi phạm bảo mật, lưu giữ tên đăng ký và mật khẩu của bên thứ ba để có biện pháp giải quyết phù hợp.", + }, + ], + }, + { + id: 2, + title: "2.2. Phạm vi sử dụng thông tin", + contents: [ + { + id: 1, + title: + "A. Sunday English có thể xử lý dữ liệu cá nhân cho một hoặc nhiều mục đích sau đây:", + contents: [ + { + id: 1, + contentDot: + "Xác minh tính chính xác, đầy đủ của các thông tin được Khách hàng cung cấp; xác định hoặc xác thực danh tính của Khách hàng và thực hiện quy trình xác thực khách hàng;", + }, + { + id: 2, + contentDot: + "Xử lý việc đăng ký của Khách hàng đối với bất kỳ sản phẩm và dịch vụ nào do Sunday English đề xuất hoặc cung cấp;", + }, + { + id: 3, + contentDot: + "Liên hệ với Khách hàng nhằm trao đổi thông tin, giao các hóa đơn, các sao kê, các báo cáo hoặc các tài liệu khác có liên quan;", + }, + { + id: 4, + contentDot: + "Thông báo cho Khách hàng các thông tin về quyền lợi, thay đổi các tính năng của sản phẩm, dịch vụ;", + }, + { + id: 5, + contentDot: + "Quản lý và đánh giá các hoạt động kinh doanh bao gồm thiết kế, cải tiến và nâng cao chất lượng các các sản phẩm, dịch vụ của Sunday English hoặc thực hiện các hoạt động truyền thông tiếp thị;", + }, + { + id: 6, + contentDot: + "Lập các báo cáo tài chính, báo cáo hoạt động hoặc các loại báo cáo liên quan khác theo quy định pháp luật;", + }, + { + id: 7, + contentDot: + "Thực hiện nghiên cứu thị trường, khảo sát và phân tích dữ liệu liên quan đến bất kỳ các sản phẩm, dịch vụ nào do Sunday English cung cấp (dù được thực hiện bởi Sunday English hay một bên thứ ba khác mà Sunday English hợp tác) mà có thể liên quan đến Khách hàng;", + }, + { + id: 8, + contentDot: + "Bảo vệ lợi ích hợp pháp của Sunday English và tuân thủ các quy định pháp luật liên quan;", + }, + { + id: 9, + contentDot: + "Ngăn chặn hoặc giảm thiểu mối đe dọa đối với tính mạng, sức khỏe của người khác và lợi ích công cộng;", + }, + { + id: 10, + contentDot: + "Để đáp ứng, tuân thủ các chính sách nội bộ của Sunday English, các thủ tục và bất kỳ quy tắc, quy định, hướng dẫn, chỉ thị hoặc yêu cầu được ban hành bởi Cơ quan nhà nước có thẩm quyền theo quy định pháp luật;", + }, + { + id: 11, + contentDot: + "Cho bất kỳ mục đích nào khác được yêu cầu hoặc cho phép bởi bất kỳ luật, quy định, hướng dẫn và/hoặc các Cơ quan nhà nước có thẩm quyền;", + }, + { + id: 12, + contentDot: + "Để thực hiện các hoạt động khác có liên quan đến việc cung cấp, vận hành, xử lý và quản lý của Sunday English đối với các sản phẩm, dịch vụ cho Khách hàng;", + }, + { + id: 13, + contentDot: + "Để phục vụ các mục đích khác có liên quan đến hoạt động kinh doanh của Sunday English mà Sunday English cho là phù hợp tại từng thời điểm; ", + }, + { + id: 14, + contentDot: + "Các mục đích hợp lý khác có liên quan đến những mục đích được nêu trên.", + }, + ], + }, + { + id: 2, + title: "B. Việc chuyển giao và tiết lộ dữ liệu cá nhân:", + contents: [ + { + id: 1, + contentDot: + "Các cơ quan nhà nước có thẩm quyền tại Việt Nam hoặc bất kỳ cá nhân, cơ quan có thẩm quyền hoặc cơ quan quản lý hoặc bên thứ ba mà Sunday English được phép hoặc bắt buộc phải tiết lộ theo quy định pháp luật của bất kỳ quốc gia, hoặc theo bất kỳ hợp đồng/thỏa thuận hoặc cam kết nào khác giữa bên thứ ba và Sunday English;", + }, + { + id: 2, + contentDot: + "Các bên thứ ba mà Khách hàng đồng ý hoặc Sunday English có cơ sở pháp lý để chia sẻ dữ liệu cá nhân của Khách hàng.", + }, + { + id: 3, + contentDot: + "Mặt khác, Sunday English sẽ xem dữ liệu cá nhân của Khách hàng là riêng tư và bí mật. Ngoài các bên đã nêu ở trên, Sunday English sẽ không tiết lộ dữ liệu của Khách hàng cho bất kỳ bên nào khác, trừ các trường hợp:", + contents: [ + { + id: 1, + content: "a. Khi có sự đồng ý của Khách hàng;", + }, + { + id: 2, + content: + "b. Khi Sunday English được yêu cầu hoặc được phép tiết lộ theo quy định pháp luật; hoặc theo quyết định của cơ quan nhà nước có thẩm quyền;", + }, + { + id: 3, + content: + "c. Khi Sunday English chuyển giao quyền và nghĩa vụ theo (các) thỏa thuận giữa Khách hàng và Sunday English.", + }, + ], + }, + ], + }, + ], + }, + ], + }, + { + id: 3, + title: "3. Thời gian lưu trữ thông tin", + contents: [ + { + id: 1, + content: + "Dữ liệu cá nhân của Thành viên sẽ được lưu trữ cho đến khi có yêu cầu hủy bỏ theo yêu cầu hoặc cho phép bởi các quy định pháp luật hiện hành hoặc tự thành viên đăng nhập và thực hiện hủy bỏ. Còn lại trong mọi trường hợp thông tin cá nhân thành viên sẽ được bảo mật trên máy chủ của Sunday English trong khoảng thời gian cần thiết để hoàn thành các mục đích theo Điều khoản và điều kiện chung về BVDLCN.", + } + ] + }, + { + id: 4, + title: "4. Biện pháp Bảo mật dữ liệu cá nhân", + contents: [ + { + id: 1, + content: + "- Sunday English xem các dữ liệu cá nhân của Khách hàng như là tài sản quan trọng nhất của Sunday English và Sunday English đảm bảo tính bảo mật, an toàn, tuân thủ pháp luật, hạn chế các hậu quả, thiệt hại không mong muốn có khả năng xảy ra (bao gồm nhưng không giới hạn: rò rỉ dữ liệu hoặc xử lý dữ liệu không phù hợp gây tổn hại đến quyền và lợi ích hợp pháp của Khách hàng). Trách nhiệm bảo mật dữ liệu cá nhân của Khách hàng là yêu cầu bắt buộc Sunday English đặt ra cho toàn thể nhân viên. ", + }, + { + id: 2, + content: + "- Sunday English thực hiện trách nhiệm bảo vệ dữ liệu cá nhân theo quy định của pháp luật hiện hành với các phương pháp bảo mật tốt nhất theo tiêu chuẩn quốc tế và thường xuyên xem xét và cập nhật các biện pháp quản lý và kỹ thuật khi xử lý dữ liệu cá nhân của Khách hàng (nếu có).", + }, + ], + }, + { + id: 5, + title: "5. Chính sách bảo mật thông tin thanh toán", + contents: [ + { + id: 1, + content: + "Sunday English luôn coi trọng việc bảo mật thông tin và sử dụng các biện pháp tốt nhất để bảo vệ thông tin cá nhân của Khách hàng (người dùng dịch vụ) trong quá trình thanh toán. Khách hàng không được sử dụng bất kỳ chương trình, công cụ hay hình thức nào để can thiệp vào hệ thống làm thay đổi cấu trúc dữ liệu.", + }, + { + id: 2, + content: + "Cá nhân hay tổ chức có hành vi can thiệp, phá hoại hay xâm nhập vào dữ liệu của hệ thống sẽ bị tước bỏ mọi quyền lợi cũng như bị truy tố trước pháp luật nếu cần thiết.", + }, + { + id: 3, + content: 'Tất cả thông tin giao dịch đều được bảo mật trừ trường hợp phải thực hiện theo yêu cầu của cơ quan Nhà nước có thẩm quyền.' + }, + { + id: 4, + title: '5.1. Mục đích áp dụng', + contents: [ + { + id: 1, + content: '- Hệ thống thanh toán thẻ trên website: https://sundayenglish.com/ (sau đây gọi là Sunday English) được cung cấp bởi đối tác cổng thanh toán OnePay đã được cấp phép hoạt động hợp pháp tại Việt Nam (“Đối Tác Cổng Thanh Toán”). Theo đó, các tiêu chuẩn bảo mật thanh toán thẻ của Sunday English đảm bảo tuân thủ theo các tiêu chuẩn bảo mật của Đối Tác Cổng Thanh Toán.' + }, + { + id: 2, + content: '- Ngoài ra, Sunday English còn có các tiêu chuẩn bảo mật giao dịch thanh toán riêng, đảm bảo an toàn các thông tin thanh toán của khách hàng.' + } + ] + }, + { + id: 5, + title: '5.2. Quy định cụ thể', + contents: [ + { + id: 1, + content: '- Chính sách giao dịch thanh toán bằng thẻ nội địa và thẻ quốc tế đảm bảo tuân thủ các tiêu chuẩn bảo mật của các Đối Tác Cổng Thanh Toán gồm:', + contents: [ + { + id: 1, + content: '+ Thông tin tài chính của khách hàng được bảo vệ bằng giao thức SSL (Secure Sockets Layer). Giao thức SSL sẽ mã hóa thông tin khách hàng cung cấp trong suốt quá trình giao dịch.' + }, + { + id: 2, + content: '+ Hệ thống thanh toán đáp ứng chuẩn bảo mật thông tin của PCI Security Standards Council.' + }, + { + id: 3, + content: '+ Các nguyên tắc và quy định bảo mật thông tin trong ngành tài chính ngân hàng theo quy định của Ngân hàng Nhà nước Việt Nam.' + } + ] + }, + { + id: 2, + content: '- Chính sách bảo mật giao dịch trong thanh toán của Sunday English áp dụng với khách hàng: Sunday English cung cấp tiện ích lưu giữ thông tin thẻ để sử dụng cho các lần thanh toán sau trên Sunday English với nguyên tắc Sunday English chỉ lưu khóa thông tin thẻ thanh toán đã được các Đối Tác Cổng Thanh Toán mã hóa. Vì vậy:', + contents: [ + { + id: 1, + content: '+ Khách hàng lựa chọn sử dụng tiện ích: trong trường hợp phát sinh vấn đề liên quan đến việc bảo mật thông tin thẻ thanh toán, khách hàng liên hệ với Đối Tác Cổng Thanh Toán để được giải quyết.' + }, + { + id: 2, + content: '+ Khách hàng không lựa chọn sử dụng tiện ích: thông tin thẻ thanh toán của khách hàng không lưu trên hệ thống của Sunday English mà được lưu giữ và bảo mật theo tiêu chuẩn quốc tế PCI DSS trên Đối Tác Cổng Thanh Toán.' + }, + { + id: 3, + content: '+ Khách hàng truy cập vào website thông qua giao thức HTTPS - HyperText Transfer Protocol Secure (giao thức truyền tải siêu văn bản bảo mật).' + } + ] + } + ] + } + ], + }, + { + id: 6, + title: "6. Sửa đổi", + contents: [ + { + id: 1, + content: + "- Thành viên có quyền tự kiểm tra, cập nhật, điều chỉnh hoặc hủy bỏ thông tin cá nhân của mình bằng cách đăng nhập vào tài khoản và chỉnh sửa thông tin cá nhân hoặc yêu cầu Sunday English thực hiện việc này.", + }, + { + id: 2, + content: + "- Sunday English có thể sửa đổi, cập nhật hoặc điều chỉnh các điều khoản của Điều khoản và điều kiện chung về BVDLCN này tùy từng thời điểm. Thông báo về bất kỳ sự sửa đổi, cập nhật hoặc điều chỉnh nào sẽ được cập nhật, đăng tải trên trang điện tử của Sunday English: sundayenglish.com và/ hoặc thông báo đến Khách hàng thông qua các phương tiện liên lạc khác mà Sunday English cho là phù hợp. ", + }, + ], + }, + { + id: 7, + title: "7. Cơ chế tiếp nhận và giải quyết khiếu nại của Khách hàng", + contents: [ + { + id: 1, + content: + "Chúng tôi có trách nhiệm tiếp nhận khiếu nại và hỗ trợ Khách hàng liên quan đến giao dịch tại hệ thống Sunday English. Khi phát sinh tranh chấp, chúng tôi đề cao giải pháp thương lượng, hòa giải giữa các bên nhằm duy trì sự tin cậy của Khách hàng vào chất lượng dịch vụ của chúng tôi và thực hiện theo các bước sau:", + }, + { + id: 2, + content: + "Bước 1: Khách Hàng gửi khiếu nại về dịch vụ của hệ thống Sunday English qua email: support@sundayenglish.com, Hoặc Khách hàng có thể phản ánh trực tiếp qua Hotline: 024 6281 3888", + }, + { + id: 3, + content: 'Bước 2: Bộ phận Chăm Sóc Khách Hàng của chúng tôi sẽ tiếp nhận các khiếu nại của Khách Hàng, tùy theo tính chất và mức độ của khiếu nại thì chúng tôi sẽ có những biện pháp cụ thể hỗ trợ Khách hàng để giải quyết tranh chấp đó. Bộ phận này chủ động giải quyết nhanh chóng và trả lời ngay kết quả giải quyết các khiếu nại trên cơ sở các Chính sách mà chúng tôi đã công bố trong thời hạn 7 ngày làm việc.' + }, + { + id: 4, + content: 'Bước 3: Trong trường hợp nằm ngoài khả năng và thẩm quyền của chúng tôi thì chúng tôi sẽ yêu cầu Khách hàng đưa vụ việc này ra cơ quan nhà nước có thẩm quyền giải quyết theo đúng quy định của pháp luật.' + }, + { + id: 5, + content: 'Chúng tôi luôn tôn trọng và nghiêm túc thực hiện các quy định của pháp luật về bảo vệ quyền lợi của Khách hàng (người dùng dịch vụ).' + }, + { + id: 6, + content: 'Nếu thông qua hình thức thỏa thuận mà vẫn không thể giải quyết được mâu thuẫn phát sinh từ giao dịch giữa 02 (hai) bên, thì một trong 02 (hai) bên Khách hàng hay Sunday English sẽ có quyền nhờ đến cơ quan pháp luật có thẩm quyền can thiệp nhằm đảm bảo lợi ích hợp pháp của các bên.' + } + ], + }, + ] + }, + license: { + id: 'license', + name: 'CHÍNH SÁCH VỀ BẢN QUYỀN & SỞ HỮU TRÍ TUỆ', + data: [ + { + id: 1, + title: + "1. Quy định về việc sử dụng nội dung trên hệ thống website và ứng dụng của dịch vụ Sunday English", + contents: [ + { + id: 1, + content: + "- Sunday English cho phép bạn xem và sử dụng thông tin của website cho mục đích học tập cá nhân, không phải cho mục đích thương mại, vì thế bạn cần phải giữ lại tất cả tuyên bố bản quyền và quyền sở hữu khác trong thông tin gốc trên tất cả bản sao của những thông tin này.", + }, + { + id: 2, + content: + "- Không được sửa thông tin của website dưới bất cứ hình thức nào, hoặc sao chép hoặc công khai trình bày, thực hiện, tuyên truyền, hoặc dùng cho mục đích thương mại. Nghiêm cấm sử dụng thông tin website cho bất cứ mục đích nào ở website khác hoặc môi trường máy tính mạng dưới bất cứ hình thức nào. Thông tin trên website đều có bản quyền, sử dụng thông tin website trái phép sẽ vi phạm luật bản quyền, luật thương hiệu và các luật khác. Thông tin, giới thiệu chương trình, ý tưởng, tài liệu, dịch vụ, và tất cả phần mềm tải xuống của website đều là sản phẩm có bản quyền của Công ty Cổ phần Công nghệ Giáo dục GK, nghiêm cấm sao chép hoặc chuyển tiếp phần mềm.", + }, + { + id: 3, + content: + "- Chúng tôi có toàn quyền khoá tài khoản và cấm truy cập vĩnh viễn đối với những Thành viên không tôn trọng hay có hành vi xâm phạm Bản quyền và Quyền sở hữu trí tuệ theo quy định của pháp luật nước CHXHCN Việt Nam.", + }, + { + id: 4, + content: + "- Nếu Bạn cho rằng nội dung mà Bạn sở hữu bị sử dụng trái phép trên Trang Web, có dấu hiệu vi phạm Bản quyền hay Quyền sở hữu Trí tuệ, xin vui lòng báo ngay cho Chúng tôi với các thông tin sau để kịp thời xử lý:", + contents: [ + { + id: 1, + content: "+ Mô tả nội dung Bạn sở hữu bị vi phạm Bản quyền.", + }, + { + id: 2, + content: + "+ Mô tả vị trí, nội dung, cách thức mà nội dung của Bạn bị vi phạm Bản quyền trên Trang Web của chúng tôi, để Chúng tôi có thể xác định đúng chi tiết nội dung để xử lý.", + }, + { + id: 3, + content: "+ Thông tin liên hệ, địa chỉ, số điện thoại, email.", + }, + { + id: 4, + content: + "+ Lời xác thực bởi chính Bạn, rằng những thông tin bạn cung cấp là chính xác và yêu cầu xử lý đối với nội dung vi phạm Bản quyền.", + }, + { + id: 5, + content: + "+ Bạn có thể liên hệ với chúng tôi về các vấn đề bản quyền theo email …", + }, + ], + }, + ], + }, + { + id: 2, + title: "2. Liên kết website", + contents: [ + { + id: 1, + content: + "Sau khi được Công ty Cổ phần Công nghệ Giáo dục GK chấp thuận, quý khách có thể liên kết với website, nhưng không được sao chép nội dung trên wesbite của Sunday English. Không được dùng nội dung trên website của Sunday English để xây dựng trình duyệt và môi trường mạng. Không được ám chỉ Sunday English công nhận website này hoặc sản phẩm dịch vụ của nó. Không được xuyên tạc quan hệ giữa website này với Sunday English. Không được sử dụng logo liên quan đến Sunday English khi chưa được sự cho phép của Công ty Cổ phần Công nghệ Giáo dục GK.", + } + ] + }, + ] + }, + payment: { + id: 'payment', + name: 'CHÍNH SÁCH THANH TOÁN', + data: [ + { + id: 1, + title: "1. Chính sách Vận chuyển và Giao nhận", + contents: [ + { + id: 1, + content: + "Hiện nay, Sunday English hiện chỉ hỗ trợ hình thức giao mã kích hoạt gói học thông qua email được gửi về địa chỉ email do khách hàng đăng ký khi tiến hành thanh toán trực tuyến.", + }, + { + id: 2, + content: '- Đối với hình thức thanh toán trực tuyến: Khi khách hàng thanh toán qua cổng thanh toán trực tuyến của Sunday English thành công, khách hàng sẽ nhận được email thông báo mã kích hoạt gói học và xác nhận thanh toán thành công.' + }, + { + id: 3, + content: '- Đối với hình thức thanh toán trong ứng dụng bằng thẻ tín dụng đăng ký với Apple/ Google (In-app purchase): Với hình thức giao nhận này, khách hàng thực hiện được qua app Sunday English và Sunday Teacher. Khách hàng sẽ nhận được email thông báo mã kích hoạt gói học và xác nhận thanh toán thành công.' + }, + { + id: 4, + content: 'Khách hàng được quyền yêu cầu xuất hóa đơn điện tử cho mỗi đơn hàng mua gói học thành công bằng cách gửi yêu cầu đến địa chỉ email: support@sundayenglish.com.' + } + ], + }, + { + id: 2, + title: "2. Chính sách Kiểm hàng", + contents: [ + { + id: 1, + content: + "Hiện nay, Sunday English hiện chỉ hỗ trợ hình thức giao mã kích hoạt gói học thông qua email trực tuyến. Sau khi khách hàng nhận và nhập mã kích hoạt gói học, nếu có yêu cầu hoặc thắc mắc liên quan đến việc sử dụng ứng dụng, khách hàng có thể liên hệ tổng đài chăm sóc khách hàng 024 6281 3888 để được hỗ trợ từ 8h00-18h00 các ngày trong tuần.", + } + ] + }, + { + id: 3, + title: "3. Chính sách Đổi hàng", + contents: [ + { + id: 1, + content: + "Khách hàng được chuyển đổi sang các gói học có giá trị lớn hơn gói học đã mua theo giá niêm yết trên website tại thời điểm xác nhận yêu cầu chuyển đổi. Mỗi tài khoản chỉ được hỗ trợ chuyển đổi 1 lần.", + }, + { + id: 2, + content: "Phương thức thực hiện", + contents: [ + { + id: 1, + content: + "- Khi có nhu cầu chuyển đổi sang gói học có giá trị cao hơn gói học đã mua, quý khách sẽ được nhân viên chăm sóc khách hàng hỗ trợ chuyển đổi ngay tại thời điểm nhận yêu cầu chuyển đổi.", + }, + { + id: 2, + content: + "- Khi chuyển đổi sang gói học có giá trị lớn hơn gói học đã mua, quý khách vui lòng thanh toán phí chênh lệch.", + }, + ], + }, + { + id: 3, + content: + "LƯU Ý: Trong thời gian 24 giờ kể từ khi Sunday English xác nhận yêu cầu chuyển đổi sang gói học có giá trị cao hơn từ quý khách (Không tính thứ 7, Chủ Nhật và các ngày nghỉ lễ), nếu quý khách không thực hiện thanh toán chênh lệch, yêu cầu chuyển đổi của quý khách sẽ tự động bị HỦY", + }, + ], + }, + { + id: 4, + title: "4. Chính sách Trả hàng và Hoàn tiền", + contents: [ + { + id: 1, + content: + "Khi khách hàng đăng ký mua một khóa học tiếng Anh bất kỳ trên hệ thống Sunday English, có nghĩa rằng khách hàng đã tìm hiểu kỹ lưỡng về toàn bộ sản phẩm trước khi mua và sử dụng. Sunday English chịu trách nhiệm đảm bảo các cam kết dịch vụ đã nêu ra và sẽ làm hết khả năng để khắc phục trong những trường hợp bất khả kháng.", + }, + { + id: 2, + content: + "Sunday English không có trách nhiệm hoàn trả học phí mà khách hàng đã đăng ký.", + } + ] + }, + ] + } +} \ No newline at end of file diff --git a/src/_constants/popups.js b/src/_constants/popups.js new file mode 100644 index 0000000..d2a0456 --- /dev/null +++ b/src/_constants/popups.js @@ -0,0 +1,4 @@ +export const popupConstants = { + CLEAR_ALL_POPUP: 'CLEAR_ALL_POPUP', + SHOW_FORM_POPUP: 'SHOW_FORM_POPUP', +}; \ No newline at end of file diff --git a/src/_constants/schedules.js b/src/_constants/schedules.js new file mode 100644 index 0000000..40dda6b --- /dev/null +++ b/src/_constants/schedules.js @@ -0,0 +1,60 @@ +export const scheduleConstants = { + GET_SCHEDULE_TODAY: 'GET_SCHEDULE_TODAY', + GET_TIME_TABLE: 'GET_TIME_TABLE', + SCREEN_GET_TIME_TABLE: 'SCREEN_GET_TIME_TABLE', + SCREEN_GET_SCHEDULE_TODAY: 'SCREEN_GET_SCHEDULE_TODAY', + SCREEN_ADD_SCHEDULE: 'SCREEN_ADD_SCHEDULE', + SCREEN_ADD_TIME_TABLE: 'SCREEN_ADD_TIME_TABLE', + SCREEN_RESET_TIME_TABLE: 'SCREEN_RESET_TIME_TABLE', + ADD_DETAIL_SCHEDULE_DAY: 'ADD_DETAIL_SCHEDULE_DAY', + REMOVE_DETAIL_SCHEDULE_DAY: 'REMOVE_DETAIL_SCHEDULE_DAY', + ADD_DELETE_SCHEDULE_DAY: 'ADD_DELETE_SCHEDULE_DAY', + RESET_DELETE_SCHEDULE_DAY: 'RESET_DELETE_SCHEDULE_DAY', + SCREEN_DELETE_SCHEDULE: 'SCREEN_DELETE_SCHEDULE', + GET_SCHEDULE_YEAR: 'GET_SCHEDULE_YEAR', + ADD_DATA_SCHEDULE_YEAR: 'ADD_DATA_SCHEDULE_YEAR', + SCREEN_ADD_SCHEDULE_YEAR: 'SCREEN_ADD_SCHEDULE_YEAR', + SET_SELECT_DATE: 'SET_SELECT_DATE', + SET_DATE_SELECTED_CALENDAR: 'SET_DATE_SELECTED_CALENDAR', + SCREEN_UPDATE_TIME_TIME_TABLE: 'SCREEN_UPDATE_TIME_TIME_TABLE', + GET_STATUS: 'GET_STATUS', + TEXT_ICON_SCHEDULE_STATUS: { + 'upcoming': { + 'title': 'Sắp diễn ra', + 'icon': 'ico_dangdienra.png', + 'class': 'orange' + }, + 'done': { + 'title': 'Đã hoàn thành', + 'icon': 'ico_succes_small.png', + 'class': 'success-text' + }, + 'over_time': { + 'title': 'Đã quá giờ', + 'icon': 'ico_quagio.png', + 'class': 'red' + }, + }, + TEXT_TYPE_SCHEDULE: [ + { + 'id': 'personal', + 'name': 'Cá nhân' + }, + // { + // 'id': 'teaching_work', + // 'name': 'Công tác giảng dạy' + // }, + { + 'id': 'professional_activities', + 'name': 'Sinh hoạt chuyên môn' + }, + { + 'id': 'test_evaluation', + 'name': 'Kiểm tra đánh giá' + }, + { + 'id': 'other', + 'name': 'Khác' + } + ], +}; \ No newline at end of file diff --git a/src/_constants/students.js b/src/_constants/students.js new file mode 100644 index 0000000..0e96ff9 --- /dev/null +++ b/src/_constants/students.js @@ -0,0 +1,42 @@ +export const studentConstants = { + GET_ALL_GRADE: 'GET_ALL_GRADE', + GET_LIST_DATA_LEARN: 'GET_LIST_DATA_LEARN', + GET_LIST_EXERCISE_STUDENT: 'GET_LIST_EXERCISE_STUDENT', + ADD_PARENT_COMPLETE: 'Bạn đã gửi liên kết thành công. Hãy chờ phụ huynh xác nhận.', + SCREEN_ADD_PARENT: 'SCREEN_ADD_PARENT', + SCREEN_APPLY_CLASS: 'SCREEN_APPLY_CLASS', + GET_ASSESSMENT_ONLINE: 'GET_ASSESSMENT_ONLINE', + GET_LOG_LEARNING_BY_DATE: 'GET_LOG_LEARNING_BY_DATE', + GET_LIST_LOG_LEARNING: 'GET_LIST_LOG_LEARNING', + APPLY_FOR_CLASS_COMPLETE: 'Xin vào lớp thành công', + ASSESSMENT_RANK: 'rank', + ASSESSMENT_OFFLINE: 'offline', + POINT_A: 'A', + POINT_B: 'B', + POINT_C: 'C', + POINT_D: 'D', + POINT_E: 'E', + RANK_UP: 'up', + RANK_DOWN: 'down', + TEXT_LIST_FILTER_DAY: [{ + 'name': 'Lọc theo ngày', + 'id': 'day' + }, + { + 'name': 'Lọc theo tuần', + 'id': 'week' + }, + { + 'name': 'Lọc theo tháng', + 'id': 'month' + }, + + ], + LIST_CLASS_FILTER: "LIST_CLASS_FILTER", + LIST_ADDRESS_FILTER: "LIST_ADDRESS_FILTER", + GET_REDIRECT_URL: "GET_REDIRECT_URL", + STATUS_HOMEWORK: "STATUS_HOMEWORK", + CLEAR_STATUS_HOMEWORK: "CLEAR_STATUS_HOMEWORK", + SCREEN_LESSSON_SKILL: 'SCREEN_LESSSON_SKILL', + HOMEWORK_SELECTED: 'HOMEWORK_SELECTED', +}; \ No newline at end of file diff --git a/src/_constants/teachers.js b/src/_constants/teachers.js new file mode 100644 index 0000000..be51581 --- /dev/null +++ b/src/_constants/teachers.js @@ -0,0 +1,144 @@ +export const teacherConstants = { + SCREEN_HOME_PAGE: "SCREEN_HOME_PAGE", + GET_LIST_CLASS: "GET_LIST_CLASS", + SCREEN_GET_LIST_CLASS: "SCREEN_GET_LIST_CLASS", + GET_DETAIL_CLASS: "GET_DETAIL_CLASS", + MESSAGE_ADD_CLASS_COMPLETE: "Thêm lớp thành công", + SCREEN_ADD_CLASS: "SCREEN_ADD_CLASS", + GET_STUDENT_OFF_CLASS: "GET_STUDENT_OFF_CLASS", + SCREEN_ADD_STUDENT: "SCREEN_ADD_STUDENT", + ADD_STUDENT_COMPLETE: "Thêm học sinh thành công", + GET_STUDENT_REQUEST: "GET_STUDENT_REQUEST", + SCREEN_LIST_STUDENT: "SCREEN_LIST_STUDENT", + SCREEN_REVIEW_STUDENT: "SCREEN_REVIEW_STUDENT", + DELETE_STUDENT: "DELETE_STUDENT", + REMOVE_REQUEST_STUDENT: "REMOVE_REQUEST_STUDENT", + SCREEN_ADD_SCHEDULE: "SCREEN_ADD_SCHEDULE", + SCREEN_ADD_CURRICULUM: "SCREEN_ADD_CURRICULUM", + ADD_STUDENT: "ADD_STUDENT", + ADD_DATA_EXERCISE: "ADD_DATA_EXERCISE", + RESET_DATA_EXERCISE: "RESET_DATA_EXERCISE", + GET_LIST_HISTORY_EXERCISE: "GET_LIST_HISTORY_EXERCISE", + GET_DETAIL_HISTORY_EXERCISE: "GET_DETAIL_HISTORY_EXERCISE", + SCREEN_ADD_STUDENT_EXERCISE: "SCREEN_ADD_STUDENT_EXERCISE", + ADD_DATA_FILE: "ADD_DATA_FILE", + SCREEN_ADD_EXERCISE: "SCREEN_ADD_EXERCISE", + GET_LIST_HOMEWORK: "GET_LIST_HOMEWORK", + GET_DETAIL_HOMEWORK: "GET_DETAIL_HOMEWORK", + GET_DETAIL_HOMEWORK_EXERCISE: "GET_DETAIL_HOMEWORK_EXERCISE", + SCREEN_EDIT_HOME_WORK: "SCREEN_EDIT_HOME_WORK", + GET_LIST_CLASS_OFFLINE: "GET_LIST_CLASS_OFFLINE", + CALL_AI_HOMEWORK: "CALL_AI_HOMEWORK", + GET_STUDENT_RANKING: "GET_STUDENT_RANKING", + GET_CLASS_RANKING: "GET_CLASS_RANKING", + GET_DETAIL_CLASS_OFFLINE: "GET_DETAIL_CLASS_OFFLINE", + ADD_TIME_ADD_ROLL_UP: "ADD_TIME_ADD_ROLL_UP", + SCREEN_ADD_ROLL_UP: "SCREEN_ADD_ROLL_UP", + GET_EXAM_CARD: "GET_EXAM_CARD", + SCREEN_ADD_EXAM_CARD: "SCREEN_ADD_EXAM_CARD", + SCREEN_LIST_FILE: "SCREEN_LIST_FILE", + GET_LIST_REPORT_CLASS: "GET_LIST_REPORT_CLASS", + GET_REPORT_BY_STUDENT_ID: "GET_REPORT_BY_STUDENT_ID", + GET_LOG_LEARNING_BY_STUDENT_ID: "GET_LOG_LEARNING_BY_STUDENT_ID", + TEXT_LIST_ROLL_UP_STATUS: [ + { + status: "Đúng giờ", + id: "intime", + }, + { + status: "Đi muộn", + id: "late", + }, + { + status: "Nghỉ KP", + id: "absence_not_allowed", + }, + { + status: "Nghỉ CP", + id: "absence_allowed", + }, + ], + TEXT_LIST_SEMESTER: [ + { + name: "Học kỳ I", + id: "1", + }, + { + name: "Học kỳ II", + id: "2", + }, + ], + TEXT_LIST_SKILL: [ + { + name: "Pronunciation", + id: "pronunciation", + }, + { + name: "Listening", + id: "listening", + }, + { + name: "Vocabulary", + id: "vocabulary", + }, + { + name: "Speaking", + id: "speaking", + }, + { + name: "Grammar", + id: "grammar", + }, + { + name: "Writing", + id: "writing", + }, + { + name: "Reading", + id: "reading", + }, + { + name: "Test", + id: "test", + }, + { + name: "Project", + id: "project", + }, + ], + GET_LIST_CRITERIA: "GET_INFO_CONTACT", + TEXT_LIST_FILTER_TYPE_MESSAGE: [ + { + name: "Tất cả", + id: "all", + }, + { + name: "Phụ huynh", + id: "parent", + }, + { + name: "Học sinh", + id: "student", + }, + ], + GET_LIST_CRITERIA: "GET_LIST_CRITERIA", + EDIT_EXERCISE: "EDIT_EXERCISE", + SOURCE_PAGE_ADD_EXCERCISE: "SOURCE_PAGE_ADD_EXCERCISE", + SCREEN_REMIND_STUDENT: "SCREEN_REMIND_STUDENT", + ADD_WISH: "ADD_WISH", + GET_LOG_LEARNING_BY_DATE: "GET_LOG_LEARNING_BY_DATE", + ADD_FILE_ATTACH_ORIGIN: "ADD_FILE_ATTACH_ORIGIN", + GET_DATA_SETTING_ASSIGN: "GET_DATA_SETTING_ASSIGN", + CLEAR_DATA_EXERCISES: "CLEAR_DATA_EXERCISES", + GET_DATA_ASSIGN_SPECIFIC: "GET_DATA_ASSIGN_SPECIFIC", + ADD_TIME_TO_CHOOSE_FILE_SCREEN: "ADD_TIME_TO_CHOOSE_FILE_SCREEN", + CLEAR_DATA_LESSONS: "CLEAR_DATA_LESSONS", + ADD_DATA_LESSONS: "ADD_DATA_LESSONS", + SCREEN_ASSIGN_HOME_WORK: "SCREEN_ASSIGN_HOME_WORK", + ON_STATUS_ATTACH_FILE: "ON_STATUS_ATTACH_FILE", + OFF_STATUS_ATTACH_FILE: "OFF_STATUS_ATTACH_FILE", + SAVE_DATE_ADD_STUDENT_EXERCISE: "SAVE_DATE_ADD_STUDENT_EXERCISE", + GET_SERVICE_TEACHER: "GET_SERVICE_TEACHER", + CLEAR_ONLY_DATA_EXERCISES: "CLEAR_ONLY_DATA_EXERCISES", + SCREEN_ASSIGN_SETTING: 'SCREEN_ASSIGN_SETTING', +}; diff --git a/src/_constants/typeAssignExercise.js b/src/_constants/typeAssignExercise.js new file mode 100644 index 0000000..aae68dc --- /dev/null +++ b/src/_constants/typeAssignExercise.js @@ -0,0 +1,5 @@ +export const TypeAssignExercise = { + FREEDOM: "freedom", + DEMAND: "demand", + CAPACITY: "capacity", +}; diff --git a/src/_constants/users.js b/src/_constants/users.js new file mode 100644 index 0000000..468ecb7 --- /dev/null +++ b/src/_constants/users.js @@ -0,0 +1,122 @@ +export const userConstants = { + LOGIN: "LOGIN", + LOGOUT: "LOGOUT", + DELETE_ACCOUNT: "DELETE_ACCOUNT", + SCREEN_LOGIN: "SCREEN_LOGIN", + SCREEN_UPDATE_INFOMATION: "SCREEN_UPDATE_INFOMATION", + SCREEN_FORGOT_PASSWORD: "SCREEN_FORGOT_PASSWORD", + SCREEN_RESET_PASSWORD: "SCREEN_RESET_PASSWORD", + ADD_DATA_REGISTER: "ADD_DATA_REGISTER", + CHANGE_LOGIN_TYPE: "CHANGE_LOGIN_TYPE", + RESET_LOGIN_TYPE: "RESET_LOGIN_TYPE", + LOGIN_TYPE_DEFAULT: "default", + LOGIN_TYPE_SOCIAL: "social", + SCREEN_REGISTER: "SCREEN_REGISTER", + SCREEN_COMPLETE_DATA_REGISTER: "SCREEN_COMPLETE_DATA_REGISTER", + SCREEN_UPDATE_PROFILE: "SCREEN_UPDATE_PROFILE", + ROLE_STUDENT: "student", + ROLE_TEACHER: "teacher", + ROLE_PARENT: "parent", + GET_PROFILE: "GET_PROFILE", + GET_PROFILE_NEWS: "GET_PROFILE_NEWS", + EDIT_PROFILE: "EDIT_PROFILE", + MESSAGE_REQUEST_CHANGE_PASSWORD_COMPLETE: + "Email cài đặt lại mật khẩu đã được gửi đến bạn. Bạn hãy truy cập email để đặt lại mật khẩu", + MESSAGE_CHANGE_PASSWORD_COMPLETE: "Đổi mật khẩu thành công", + MESSAGE_REGISTER_COMPLETE: "Đăng ký thành công", + MESSAGE_UPDATE_PROFILE_COMPLETE: "Cập nhật thông tin thành công", + MESSAGE_UPDATE_AVATAR_COMPLETE: "Cập nhật avatar thành công", + TEXT_SELECT_ROLE_DEFAULT: "Loại tài khoản", + GET_ROOM_CHAT: "GET_ROOM_CHAT", + GET_CLASS_MESSAGE: "GET_CLASS_MESSAGE", + GET_CLASS_NOTIFICATION: "GET_CLASS_NOTIFICATION", + GET_DETAIL_MESSAGE: "GET_DETAIL_MESSAGE", + SEND_MESSAGE: "SEND_MESSAGE", + GET_CONTACT_INFO: "GET_INFO_CONTACT", + GET_SETTING_DETAIL: "GET_SETTING_DETAIL", + GET_TOTAL_MESSAGE: "GET_TOTAL_MESSAGE", + RESET_CLASS_MESSAGE: "RESET_CLASS_MESSAGE", + TEXT_SELECT_ROLE: [ + { + id: "student", + name: "Tài khoản Học sinh", + }, + { + id: "teacher", + name: "Tài khoản Giáo viên", + }, + { + id: "parent", + name: "Tài khoản Phụ huynh", + }, + ], + TEXT_LIST_DAY: [ + { + id: "Monday", + name: "Thứ 2", + }, + { + id: "Tuesday", + name: "Thứ 3", + }, + { + id: "Wednesday", + name: "Thứ 4", + }, + { + id: "Thursday", + name: "Thứ 5", + }, + { + id: "Friday", + name: "Thứ 6", + }, + { + id: "Saturday", + name: "Thứ 7", + }, + { + id: "Sunday", + name: "Chủ nhật", + }, + ], + LANG_CONFIG: [ + { + name: "Tiếng Việt", + id: "vi", + }, + { + name: "Tiếng Anh", + id: "en", + }, + ], + + SCHOOL_TYPE_PUBLIC: "public", + SCHOOL_TYPE_PRIVATE: "private", + SCHOOL_TYPE_FREE: "free", + RESET_ALL_STATE: "RESET_ALL_STATE", + ON_ROOTLESSNESS: "ON_ROOTLESSNESS", + OFF_ROOTLESSNESS: "OFF_ROOTLESSNESS", + ON_PLACEMENT_TEST: "ON_PLACEMENT_TEST", + OFF_PLACEMENT_TEST: "OFF_PLACEMENT_TEST", + SHOW_SIDEBAR_ROOTLESSNESS: "SHOW_SIDEBAR_ROOTLESSNESS", + HIDE_SIDEBAR_ROOTLESSNESS: "HIDE_SIDEBAR_ROOTLESSNESS", + ON_PROPOSED_CURRICULUM: "ON_PROPOSED_CURRICULUM", + OFF_PROPOSED_CURRICULUM: "OFF_PROPOSED_CURRICULUM", + ON_CHOOSE_LIST_CURRICULUM: "ON_CHOOSE_LIST_CURRICULUM", + OFF_CHOOSE_LIST_CURRICULUM: "OFF_CHOOSE_LIST_CURRICULUM", + SET_PRIORITY_CURRICULUM: "SET_PRIORITY_CURRICULUM", + RESULT_PLACEMENT_TEST: "RESULT_PLACEMENT_TEST", + RESET_RESULT_PLACEMENT_TEST: "RESET_RESULT_PLACEMENT_TEST", + CODE_SENT_ON: "CODE_SENT_ON", + CODE_SENT_OFF: "CODE_SENT_OFF", + TIMEREMAINING:"TIMEREMAINING", + REGISTER_STATUS: "REGISTER_STATUS", + RESET_REGISTER_STATUS: "RESET_REGISTER_STATUS", + SAVE_DATA_REGISTER: "SAVE_DATA_REGISTER", + RESET_ALL_PLACEMENT_TEST: "RESET_ALL_PLACEMENT_TEST", + REGISTER_WITH_OTHER_ZALO: "REGISTER_WITH_OTHER_ZALO", + LOGIN_WHEN_NOT_VERIFY: "LOGIN_WHEN_NOT_VERIFY", + RESET_LOGIN_WHEN_NOT_VERIFY: "RESET_LOGIN_WHEN_NOT_VERIFY", + +}; diff --git a/src/_containers/AddInformationPage/AddInformationPage.js b/src/_containers/AddInformationPage/AddInformationPage.js new file mode 100644 index 0000000..d757a82 --- /dev/null +++ b/src/_containers/AddInformationPage/AddInformationPage.js @@ -0,0 +1,133 @@ +import React, { Fragment, useState, useEffect } from 'react'; +import _ from 'lodash'; +import { HeaderCloud } from '../../_components/Header'; +import { useSelector, useDispatch } from 'react-redux'; +import { userConstants } from '../../_constants'; +import { Alert } from '../../_components/Alert'; +import { userActions, studentActions } from '../../_actions'; +import { LinkBack } from '../../_components/Link'; +import InputForm from '../../_components/Input'; +import { useHistory } from 'react-router-dom'; +import { SelectAsDiv } from '../../_components/Select'; +import { SelectDate } from '../../_components/Calendar'; + +function AddInformationPage() { + const alert = useSelector(state => state.alert); + const dispatch = useDispatch(); + const dataRegister = useSelector(state => state.register); + const grades = useSelector(state => state.grades); + const history = useHistory(); + + + useEffect(() => { + dispatch(studentActions.getAllGrade()); + }, []); + + const [inputs, setInputs] = useState({ + fullname: '', + class_number: '', + birthday: new Date(), + school: '', + grade_id: '', + phone: '', + gender: '', + }); + + const [submitted, setSubmitted] = useState(false); + const { fullname, class_number, birthday, grade_id, school, phone, gender } = inputs; + + function handleChange(e) { + const { name, value } = e.target; + setInputs(inputs => ({ ...inputs, [name]: value })); + + } + + function handleSubmit(e) { + e.preventDefault(); + setSubmitted(true); + if (validateParam()) { + dispatch(userActions.register(_.pickBy({ ...inputs, ...dataRegister, birthday: birthday.toISOString().slice(0, 10), class: class_number }))); + } + } + + + function validateParam() { + if (fullname && birthday && gender) { + if ((dataRegister.role === userConstants.ROLE_STUDENT && (!inputs.class_number || !school)) || (dataRegister.role === userConstants.ROLE_TEACHER && !school) || ((dataRegister.role === userConstants.ROLE_TEACHER || dataRegister.role === userConstants.ROLE_PARENT) && !phone)) { + return false; + } + return true; + } + return false; + } + + + function changeGender(gender) { + setInputs({ + ...inputs, + gender: gender + }); + } + + + + return ( +
    + +
    +
    + +

    {dataRegister.role === userConstants.ROLE_STUDENT ? 'Vui lòng điền đầy đủ thông tin dưới đây để chúng tôi có thể giúp bạn học tiếng anh theo cách tốt' : 'Vui lòng điền đầy đủ thông tin dưới đây để chúng tôi có thể hỗ trợ bạn tốt nhất' }

    + + {alert.message && alert.screen === userConstants.SCREEN_COMPLETE_DATA_REGISTER && history.push('/login')} />} +
    + +
    +
    + birthday + setInputs({ ...inputs, birthday })} /> +
    +
    +
    changeGender('male')}> + {"ico_male"} + {"ico_male_2"} +
    +
    changeGender('female')}> + {"ico_female"} + {"ico_female_2"} +
    +
    +
    + {dataRegister.role === userConstants.ROLE_STUDENT && + + +
    + setInputs({ ...inputs, grade_id })} ico_url={'/assets/images/icon/ico_khoi.png'} /> +
    + +
    + } + {dataRegister.role === userConstants.ROLE_TEACHER && + + + + } + {(dataRegister.role === userConstants.ROLE_PARENT || dataRegister.role === userConstants.ROLE_TEACHER) && + + + + } +
    + +
    +
    + +
    + +
    +
    +
    + ); +} + +export { AddInformationPage }; \ No newline at end of file diff --git a/src/_containers/AddInformationPage/index.js b/src/_containers/AddInformationPage/index.js new file mode 100644 index 0000000..7aa4f48 --- /dev/null +++ b/src/_containers/AddInformationPage/index.js @@ -0,0 +1 @@ +export * from './AddInformationPage'; \ No newline at end of file diff --git a/src/_containers/ForgotPasswordPage/ForgotPasswordPage.js b/src/_containers/ForgotPasswordPage/ForgotPasswordPage.js new file mode 100644 index 0000000..e163bde --- /dev/null +++ b/src/_containers/ForgotPasswordPage/ForgotPasswordPage.js @@ -0,0 +1,223 @@ +import React, { useEffect, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { alertConstants, userConstants } from "./../../_constants"; + +import { HeaderCloud } from "../../_components/Header"; +import { alertActions, userActions } from "../../_actions"; +import { Alert } from "../../_components/Alert"; +import { LinkBack } from "../../_components/Link"; +import { isEmail } from "../../_helpers/validateEmail"; +import InputText from "../../_components/Auth/InputText"; +import { Link } from "react-router-dom"; + +function ForgotPasswordPage() { + const alert = useSelector((state) => state.alert); + const dispatch = useDispatch(); + const [email, setEmail] = useState(""); + const [emailError, setEmailError] = useState(""); + const [submitted, setSubmitted] = useState(false); + const [resetSuccess, setResetSuccess] = useState(false); + + useEffect(() => { + if (alert.type === alertConstants.SUCCESS) { + setResetSuccess(true); + } + }, [alert]); + + function handleSubmit(e) { + e.preventDefault(); + setSubmitted(true); + if (validateParam()) { + dispatch(userActions.forgotPassword(email)); + } + } + + function validateParam() { + return isEmail(email); + } + + const changeEmail = (value) => { + if ( + alert.message && + alert.screen === userConstants.SCREEN_FORGOT_PASSWORD + ) { + dispatch(alertActions.clear()); + } + if (emailError) { + if (isEmail(value)) { + setEmailError(""); + } + } + setEmail(value.trim()); + }; + + const onBlurEmail = () => { + if (email && !emailError && !isEmail(email)) { + setEmailError("Định dạng email không đúng"); + } + }; + + const renderEmailIcon = () => { + return ( + + + + ); + }; + + return ( +
    + +
    + {!resetSuccess ? ( + <> +
    +

    ĐẶT LẠI MẬT KHẨU

    +

    + Bạn vui lòng điền Email sử dụng khi tạo tài khoản để lấy lại mật + khẩu +

    + {alert.message && + alert.screen === userConstants.SCREEN_FORGOT_PASSWORD && ( + + )} +
    + +
    + +
    +
    +
    +
    + +
    + + ) : ( + <> +
    +

    + ĐẶT LẠI MẬT KHẨU +

    +
    + + + + + + + +
    +
    +

    + Đường dẫn đặt lại mật khẩu đã được gửi đến địa chỉ email{" "} + + {email} + + . Bạn vui lòng kiểm tra hộp thư và làm theo hướng dẫn nhé! +

    +
    +
    +
    + + + +
    + + )} +
    +
    + ); +} + +export { ForgotPasswordPage }; diff --git a/src/_containers/ForgotPasswordPage/index.js b/src/_containers/ForgotPasswordPage/index.js new file mode 100644 index 0000000..f55d3fd --- /dev/null +++ b/src/_containers/ForgotPasswordPage/index.js @@ -0,0 +1 @@ +export * from './ForgotPasswordPage'; \ No newline at end of file diff --git a/src/_containers/LoginPage/LoginPage.js b/src/_containers/LoginPage/LoginPage.js new file mode 100644 index 0000000..f4543a7 --- /dev/null +++ b/src/_containers/LoginPage/LoginPage.js @@ -0,0 +1,334 @@ +import React, { useEffect, useState } from "react"; +import Login from "./components/Login"; +import { HeaderCurve } from "../../_components/Header"; +import { userActions } from "../../_actions"; +import { useDispatch, useSelector } from "react-redux"; +import { isEmail } from "../../_helpers/validateEmail"; +import { configConstants, userConstants } from "../../_constants"; +import classNames from "classnames"; +import AccountType from "../RegisterPage/components/AccountType"; +import { stepAuthConstants } from "../../_constants/auth"; +import UpdateInformation from "../RegisterPage/components/UpdateInformation"; +import UpdateEmailFb from "./components/UpdateEmailFb"; +import {Mydata} from '../../_base/Mydata' + +function LoginPage() { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [emailError, setEmailError] = useState(""); + const [pwError, setPwError] = useState(""); + const dispatch = useDispatch(); + const [loginType, setLoginType] = useState({ + type: "default", + step: "normal_login", + }); + const authentication = useSelector((state) => state.authentication); + const [dataStepEmail, setDataStepEmail] = useState({ + email: "", + }); + const [dataStepRole, setDataStepRole] = useState({ + role: "", + grade: "", + schoolType: "", + }); + const [dataUpdateInfo, setDataUpdateInfo] = useState({ + fullname: "", + birthday: "", + gender: "", + phone: "", + province: "", + district: "", + school: "", + onRegister: false, + }); + const getDevice = () => { + let currentBrowser = "Unknown"; + if (window.navigator.userAgent.indexOf("Chrome") !== -1) { + currentBrowser = "Google_Chrome"; + } else if (window.navigator.userAgent.indexOf("Firefox") !== -1) { + currentBrowser = "Mozilla_Firefox"; + } else if (window.navigator.userAgent.indexOf("MSIE") !== -1) { + currentBrowser = "Internet_Exployer"; + } else if (window.navigator.userAgent.indexOf("Edge") !== -1) { + currentBrowser = "Edge"; + } else if (window.navigator.userAgent.indexOf("Safari") !== -1) { + currentBrowser = "Safari"; + } else if (window.navigator.userAgent.indexOf("Opera") !== -1) { + currentBrowser = "Opera"; + } else if (window.navigator.userAgent.indexOf("Opera") !== -1) { + currentBrowser = "YaBrowser"; + } else { + return currentBrowser; + } + return currentBrowser; + }; + const makeToken = () => { + let ID = ""; + let characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + for (var i = 0; i < 12; i++) { + ID += characters.charAt(Math.floor(Math.random() * 36)); + } + return ID; + }; + const [inputs, _setInputs] = useState({ + device_id: makeToken(), + device_name: getDevice(), + fcm_token: makeToken(), + }); + const [submitted, setSubmitted] = useState(false); + const [cacheTokenSocial, setCacheTokenSocial] = useState({}); + + // method--------------------------------------------- + + useEffect(() => { + if ( + authentication.loginType === configConstants.LOGIN_VIA_FACEBOOK || + authentication.loginType === configConstants.LOGIN_VIA_GOOLE + ) { + if (authentication.is_new_acc) { + setLoginType({ + type: authentication.loginType, + step: + authentication.loginType === configConstants.LOGIN_VIA_FACEBOOK + ? stepAuthConstants.STEP_CREATE_ACCOUNT + : + stepAuthConstants.STEP_ACCOUNT_TYPE, + }); + dispatch({ + type: userConstants.LOGOUT, + }); + } + } + }, [authentication]); + + useEffect(() => { + if (dataUpdateInfo.onRegister) { + onLoginBySocial(); + } + }, [dataUpdateInfo]); + + useEffect(() => { + if (loginType.type === "default") { + resetStateLoginSocial(); + } + }, [loginType]); + + const onLoginBySocial = () => { + const data = { + email: dataStepEmail.email, + user_role: dataStepRole.role, + class: dataStepRole.grade, + school_type: dataStepRole.schoolType, + grade_id: dataStepRole.grade, + school: dataUpdateInfo.school, + birthday: dataUpdateInfo.birthday, + fullname: dataUpdateInfo.fullname, + gender: dataUpdateInfo.gender, + province_alias: dataUpdateInfo.province, + district_alias: dataUpdateInfo.district, + phone: dataUpdateInfo.phone, + }; + + dispatch( + userActions.login( + { + ...cacheTokenSocial, + ...data, + }, + loginType.type + ) + ); + }; + + function handleSubmit(e) { + e.preventDefault(); + setSubmitted(true); + if (validateParam()) { + const dataLogin = { + ...inputs, + username: email, + password: password, + }; + dispatch( + userActions.login(dataLogin, configConstants.LOGIN_TYPE_DEFAULT) + ); + } + } + + // function onLoginFacebookSuccess(user) { + // console.log(user); + // if (user && user._token) { + // const data = { + // access_token: user._token.accessToken, + // organization_id: 1, + // }; + // setCacheTokenSocial(data); + // dispatch(userActions.login(data, configConstants.LOGIN_VIA_FACEBOOK)); + // } + // } + + function onLoginGoogleSuccess(user) { + // console.log(user); + // alert("Waiting Api"); + setDataStepEmail({ + email: user.profileObj?.email ?? "", + }); + setDataUpdateInfo({ + ...dataUpdateInfo, + fullname: user.profileObj?.name ?? "", + }); + const data = { + id_token: user.tokenId, + access_token: user.accessToken, + organization_id: 1, + }; + setCacheTokenSocial(data); + dispatch(userActions.login(data, configConstants.LOGIN_VIA_GOOLE)); + dispatch(userConstants.REGISTER_WITH_OTHER_ZALO) + } + + function onLoginAppleSuccess(response) { + setDataStepEmail({ + email: response.user?.email ?? "", + }); + setDataUpdateInfo({ + ...dataUpdateInfo, + fullname: + response.user?.name?.firstName ?? + "" + response.user?.name?.lastName ?? + "", + }); + const data = { + identityToken: user.authorization.id_token, + organization_id: 1, + }; + setCacheTokenSocial(data); + dispatch(userActions.login(data, configConstants.LOGIN_VIA_APPLE)); + } + + function validateParam() { + return isEmail(email) && password.length >= 6 && password.trim() !== "" + ? true + : false; + } + + const changeStepLoginSocial = (step) => { + setLoginType({ + ...loginType, + step: step, + }); + }; + + const backStepFromAccountType = () => { + if (loginType.type === configConstants.LOGIN_VIA_GOOLE) { + setLoginType({ + type: "default", + step: "normal_login", + }); + } + // else if (loginType.type === configConstants.LOGIN_VIA_FACEBOOK) { + // setLoginType({ + // ...loginType, + // step: stepAuthConstants.STEP_CREATE_ACCOUNT, + // }); + // } + }; + + const resetStateLoginSocial = () => { + setDataStepEmail({ + email: "", + }); + setDataStepRole({ + role: "", + grade: "", + schoolType: "", + }); + setDataUpdateInfo({ + fullname: "", + birthday: "", + gender: "", + phone: "", + province: "", + district: "", + school: "", + onRegister: false, + }); + }; + + return ( +
    + + {loginType.step === "normal_login" ? ( + <> +
    + +
    +
    {Mydata.version}
    + + ) : null} + +
    + +
    +
    + +
    +
    + +
    +
    + ); +} + +export { LoginPage }; diff --git a/src/_containers/LoginPage/components/Login.js b/src/_containers/LoginPage/components/Login.js new file mode 100644 index 0000000..e9993ed --- /dev/null +++ b/src/_containers/LoginPage/components/Login.js @@ -0,0 +1,516 @@ +import React, { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; +import { useSelector, useDispatch } from "react-redux"; +import { + userConstants, + configConstants, + alertConstants, +} from "../../../_constants"; +import { alertActions } from "../../../_actions"; +// import SocialLogin from "../../../_components/SocialLogin"; +import { Alert } from "../../../_components/Alert"; +// import from "../../../_components/Input"; +import "./Login.scss"; +import InputText from "../../../_components/Auth/InputText"; +import { isEmail } from "../../../_helpers/validateEmail"; +import GoogleLogin from "react-google-login"; +// import FacebookLogin from "react-facebook-login/dist/facebook-login-render-props"; +import AppleLogin from "react-apple-login"; +import { apiCaller, history } from "../../../_helpers"; +import classNames from "classnames"; +import SocialLogin from "../../../_components/Auth/SocialLogin"; +import { PopUpYesNo } from "../../../_components/Popup"; + +function Login(props) { + const alert = useSelector((state) => state.alert); + const dispatch = useDispatch(); + const [dataResetEmail, setDataResetEmail] = useState({ + loading: false, + msg: "Gửi lại email kích hoạt khác", + }); + const [savePassword, setSavePassword] = useState( + localStorage.getItem("save_pw") === "true" + ); + // fb + const [isProcessingFb, setIsProcessingFb] = useState(false); + + const registerStatus = useSelector( + (state) => state.authenticationTeacherZalo.registerStatus + ); + + const { + email, + setEmail, + password, + setPassword, + emailError, + setEmailError, + pwError, + setPwError, + handleSubmit, + // onLoginFacebookSuccess, + onLoginGoogleSuccess, + onLoginAppleSuccess, + validateParam, + } = props; + + useEffect(() => { + dispatch({ type: userConstants.RESET_REGISTER_STATUS }); + dispatch({ type: userConstants.RESET_LOGIN_WHEN_NOT_VERIFY }); + }, []); + + const changeEmail = (value) => { + if (alert.message && alert.screen === userConstants.SCREEN_LOGIN) { + dispatch(alertActions.clear()); + } + if (emailError) { + if (isEmail(value)) { + setEmailError(""); + } + } + setEmail(value.trim()); + }; + + const changePassword = (value) => { + setPwError(""); + if (alert.message && alert.screen === userConstants.SCREEN_LOGIN) { + dispatch(alertActions.clear()); + } + if (pwError) { + if (value.length >= 6) { + setPwError(""); + } + } + setPassword(value); + }; + + const onBlurField = (type) => { + switch (type) { + case "email": { + if (email && !emailError && !isEmail(email)) { + setEmailError("Định dạng email không đúng"); + } + return; + } + default: { + if (password.trim() === "" && !pwError) { + setPwError( + "Mật khẩu cần tối thiểu 6 kí tự và không gồm toàn dấu cách" + ); + } + if (password && !pwError && password.length < 6) { + setPwError("Mật khẩu phải có từ 6 ký tự trở lên"); + } + return; + } + } + }; + + const renderEmailIcon = () => { + return ( + + + + ); + }; + + const renderPasswordIcon = () => { + return ( + + + + ); + }; + + const resentEmail = () => { + if (!dataResetEmail.loading) { + setDataResetEmail({ + loading: true, + msg: "Đang gửi...", + }); + apiCaller(`/api_register/resend_active_email?email=${email}`) + .then((res) => { + if (res.status) { + setDataResetEmail({ + loading: true, + msg: "Gửi email xác nhận thành công", + }); + setTimeout(() => { + dispatch(alertActions.clear()); + setDataResetEmail({ + loading: false, + msg: "Gửi lại email kích hoạt khác", + }); + }, 5000); + } else { + setDataResetEmail({ + loading: true, + msg: "Gửi email xác nhận thất bại", + }); + setTimeout(() => { + setDataResetEmail({ + loading: false, + msg: "Gửi lại email kích hoạt khác", + }); + }, 3000); + } + }) + .catch((e) => { + setDataResetEmail({ + loading: true, + msg: "Gửi email xác nhận thất bại", + }); + setTimeout(() => { + setDataResetEmail({ + loading: false, + msg: "Gửi lại email kích hoạt khác", + }); + }, 3000); + }); + } + }; + + const rememberPassword = (e) => { + const checked = e.target.checked; + setSavePassword(checked); + localStorage.setItem("save_pw", checked); + }; + + function setNodeRef(provider, node) { + if (node) { + // nodes[provider] = node; + } + } + + const handleToVerify = () => { + const data = { + phone: "", + email: email, + }; + dispatch({ type: userConstants.LOGIN_WHEN_NOT_VERIFY }); + history.push(`/register/authentication`, { data: data }); + dispatch({ type: userConstants.RESET_REGISTER_STATUS }); + }; + + return ( +
    + {registerStatus && ( + + )} +
    +

    Đăng nhập

    + {alert.message && + !registerStatus && + alert.message !== + "Tài khoản chưa được kích hoạt, vui lòng kiểm tra email và kích hoạt tài khoản trước khi sử dụng." && + alert.screen === userConstants.SCREEN_LOGIN && ( + + )} +
    + {alert.message && + alert.screen === userConstants.SCREEN_LOGIN && + alert.message === + "Tài khoản chưa được kích hoạt, vui lòng kiểm tra email và kích hoạt tài khoản trước khi sử dụng." ? ( +
    +

    {alert.message}

    +
    + {dataResetEmail.msg} +
    +
    + ) : null} + { + onBlurField("email"); + }} + setErrorText={setEmailError} + autoComplete={savePassword ? "on" : "new-password"} + autoFocus={true} + > + { + onBlurField("password"); + }} + onFocus={() => setPassword(password.trim())} + autoComplete={savePassword ? "on" : "new-password"} + > +
    + {/*
    + + +
    */} +
    + Quên mật khẩu? +
    +
    +
    + +
    +
    +
    +
    + hoặc +
    +
    + {/*
    + ( +
    { + if (!renderProps.isProcessing) { + renderProps.onClick(data); + } + }} + > + {renderProps.isProcessing ? ( +
    +
    +
    +
    +
    +
    +
    + ) : ( + <> + + + +
    + Facebook +
    + + )} +
    + )} + /> +
    { + if (isReady) { + FBInstance.getLoginStatus((response) => { + onLoginFacebookSuccess(response); + }); + } + }} + > + + + +
    + Facebook +
    +
    +
    */} + {/* { + onLoginFacebookSuccess(res); + setIsProcessingFb(false); + }} + key={"facebook"} + onLoginFailure={(e) => { + if (e !== "Fetching user") { + setIsProcessingFb(false); + } + return true; + }} + clickprocessing={() => { + setIsProcessingFb(true); + }} + > +
    + {isProcessingFb ? ( +
    +
    +
    +
    +
    +
    +
    + ) : ( + <> + + + +
    + Facebook +
    + + )} +
    +
    */} + {/* { + return true; + }} + > +
    + + + +
    + Facebook +
    +
    +
    */} +
    + ( +
    { + if (!renderProps.disabled) { + renderProps.onClick(); + } + }} + > + + + +
    + Google +
    +
    + )} + /> +
    + {/*
    + ( +
    + + + + Apple +
    + )} + /> +
    */} +
    +
    +
    +
    +
    +

    + Đăng ký tài khoản +

    +
    +
    + ); +} + +export default Login; diff --git a/src/_containers/LoginPage/components/Login.scss b/src/_containers/LoginPage/components/Login.scss new file mode 100644 index 0000000..fd8293b --- /dev/null +++ b/src/_containers/LoginPage/components/Login.scss @@ -0,0 +1,307 @@ +$green: #00b9b7; +$bg-color: #f3ffff; +$bg-fb: #1b75bb; +$bg-gg: #be1e2d; +$bg-apple: #000000; +$loading-color: #f8f8f8; + +.login-form-container { + input[type="checkbox"] { + -moz-appearance: initial; // Hack for Firefox Browsers + } + + &_content { + margin: 0 auto; + margin-top: 50px; + max-width: 450px; + + @media screen and (max-height: 800px) { + margin-top: -145px; + } + + .title { + font-size: 32px; + text-transform: uppercase; + margin-bottom: 22px; + } + + .password_options { + align-items: center; + + label, + a { + font-size: 18px; + } + + label { + position: relative; + top: 2px; + } + + .save_password { + &_checkbox { + position: relative; + margin: -5px 17px 0 2px; + width: 16px; + height: 16px; + border: 1px solid $green; + border-radius: 4px; + cursor: pointer; + + &:before { + content: ""; + display: block; + position: absolute; + width: 20px; + height: 20px; + top: -2px; + left: -2px; + border: 1px solid $green; + border-radius: 5px; + background-color: white; + } + + &:checked:before { + background-color: $green; + } + + &:checked:after { + content: ""; + display: block; + width: 5px; + height: 10px; + border: solid white; + border-width: 0 2px 2px 0; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); + position: absolute; + top: 1px; + left: 6px; + } + } + } + } + + .button_submit { + margin-top: 26px; + margin-bottom: 40px; + text-align: center; + + button { + height: 50px; + width: 210px; + border-radius: 25px; + font-size: 18px; + line-height: unset; + } + } + + .line_or { + overflow: visible; + text-align: inherit; + margin: 0 0 20px 0; + border: 0; + border-top: 1px solid #777777; + position: relative; + + span { + width: 70px; + background: #f3ffff; + position: absolute; + display: block; + top: -12px; + left: calc(50% - 40px); + text-align: center; + font-size: 18px; + } + } + + .social_login { + display: flex; + margin-top: 32px; + + &_item { + flex: 1; + margin-right: 15px; + cursor: pointer; + + &:last-child { + margin-right: 0px; + } + } + + &_container { + display: flex; + align-items: center; + justify-content: center; + padding: 0px 16px; + height: 50px; + border-radius: 10px; + + // &.facebook { + // background-color: $bg-fb; + // } + &.google { + background-color: $bg-gg; + } + + &.apple { + background-color: $bg-apple; + } + + .icon { + margin-right: 9px; + } + + span { + color: white; + font-size: 18px; + } + } + } + } + + .register_text { + margin-top: 25px; + + p, + a { + font-size: 18px; + color: $green; + font-weight: 600; + } + } + + .resend_email { + margin-top: 5px; + + span { + color: #b02343; + text-decoration: underline; + font-size: 18px; + cursor: pointer; + font-weight: 600; + } + } + + form { + position: relative; + + .login_error_server { + // position: absolute; + // bottom: calc(100% + 18px); + background-color: #fdf4f4; + padding: 26px 34px; + margin-bottom: 30px; + width: 100%; + border-radius: 10px; + + p { + font-size: 18px; + color: #b02343; + } + } + } + + .fb_disabled { + cursor: no-drop; + + .loading_fb { + width: 100%; + display: flex; + justify-content: center; + + .dot-pulse { + position: relative; + left: -9999px; + width: 10px; + height: 10px; + border-radius: 5px; + background-color: $loading-color; + color: $loading-color; + box-shadow: 9999px 0 0 -5px $loading-color; + animation: dotPulse 1.5s infinite linear; + animation-delay: 0.25s; + } + + .dot-pulse::before, + .dot-pulse::after { + content: ""; + display: inline-block; + position: absolute; + top: 0; + width: 10px; + height: 10px; + border-radius: 5px; + background-color: $loading-color; + color: $loading-color; + } + + .dot-pulse::before { + box-shadow: 9984px 0 0 -5px $loading-color; + animation: dotPulseBefore 1.5s infinite linear; + animation-delay: 0s; + } + + .dot-pulse::after { + box-shadow: 10014px 0 0 -5px $loading-color; + animation: dotPulseAfter 1.5s infinite linear; + animation-delay: 0.5s; + } + + @keyframes dotPulseBefore { + 0% { + box-shadow: 9984px 0 0 -5px $loading-color; + } + + 30% { + box-shadow: 9984px 0 0 2px $loading-color; + } + + 60%, + 100% { + box-shadow: 9984px 0 0 -5px $loading-color; + } + } + + @keyframes dotPulse { + 0% { + box-shadow: 9999px 0 0 -5px $loading-color; + } + + 30% { + box-shadow: 9999px 0 0 2px $loading-color; + } + + 60%, + 100% { + box-shadow: 9999px 0 0 -5px $loading-color; + } + } + + @keyframes dotPulseAfter { + 0% { + box-shadow: 10014px 0 0 -5px $loading-color; + } + + 30% { + box-shadow: 10014px 0 0 2px $loading-color; + } + + 60%, + 100% { + box-shadow: 10014px 0 0 -5px $loading-color; + } + } + } + } + + .login_social_wrapper { + margin: 0px 120px; + } +} + +.hide_step_login { + display: none; +} \ No newline at end of file diff --git a/src/_containers/LoginPage/components/UpdateEmailFb/index.js b/src/_containers/LoginPage/components/UpdateEmailFb/index.js new file mode 100644 index 0000000..0afc782 --- /dev/null +++ b/src/_containers/LoginPage/components/UpdateEmailFb/index.js @@ -0,0 +1,149 @@ +import React, { useEffect, useState } from "react"; +import InputText from "../../../../_components/Auth/InputText"; +import "./index.scss"; +import { isEmail } from "../../../../_helpers/validateEmail"; +import { apiCaller } from "../../../../_helpers"; +import { stepAuthConstants } from "../../../../_constants/auth"; + +const UpdateEmailFb = (props) => { + const [email, setEmail] = useState(""); + const [emailError, setEmailError] = useState(""); + const [cacheEmailPass, setCacheEmailPass] = useState([]); + const [cacheEmailFail, setCacheEmailFail] = useState([]); + + useEffect(() => { + setEmail(props.data.email); + }, [props.data]); + + async function handleSubmit(e) { + // setSubmitted(true); + // if (validateParam()) { + // dispatch(userActions.udpateInformation(inputs)); + // } + e.preventDefault(); + if (isEmail(email)) { + if (cacheEmailPass.includes(email)) { + nextStep(); + } else if (cacheEmailFail.includes(email)) { + setEmailError("Bạn đã đăng ký tài khoản với email này trước đó. Hãy kích hoạt email và sử dụng!"); + } else { + await apiCaller("/api_register/check_email", "POST", { + email, + }) + .then((res) => { + if (res.status) { + setCacheEmailPass([...cacheEmailPass, email]); + nextStep(); + } + }) + .catch((e) => { + setCacheEmailFail([...cacheEmailFail, email]); + setEmailError(e); + }); + } + return; + } + checkEmail(); + } + + const nextStep = () => { + props.setData({ + email, + }); + props.setStep(stepAuthConstants.STEP_ACCOUNT_TYPE); + }; + + const checkEmail = () => { + if (!isEmail(email)) { + setEmailError("Định dạng email không đúng"); + } + }; + + const changeEmail = (value) => { + if (emailError) { + if (isEmail(value)) { + setEmailError(""); + } + } + setEmail(value); + }; + + const onBlurField = (type) => { + switch (type) { + case "email": { + if (email && !emailError) { + checkEmail(); + } + return; + } + default: { + return; + } + } + }; + + function validateParam() { + return isEmail(email); + } + + const renderEmailIcon = () => { + return ( + + + + ); + }; + + function logout() { + // revoke app permissions to logout completely because FB.logout() doesn't remove FB cookie + if (window.FB) { + window.FB.api("/me/permissions", "delete", null, () => window.FB.logout()); + window.location.href = "/"; + } + } + + return ( +
    +
    +

    ĐĂNG KÝ TÀI KHOẢN

    +

    1. Thêm địa chỉ email

    +

    Hãy nhập địa chỉ email hợp lệ của bạn để có thể kích hoạt và khôi phục tài khoản trong tương lai.

    +
    + <> + { + onBlurField("email"); + }} + > + +
    + +
    +
    +

    { + logout(); + }} + > + Quay lại +

    +
    +
    +
    +
    + ); +}; + +export default UpdateEmailFb; diff --git a/src/_containers/LoginPage/components/UpdateEmailFb/index.scss b/src/_containers/LoginPage/components/UpdateEmailFb/index.scss new file mode 100644 index 0000000..5e73f70 --- /dev/null +++ b/src/_containers/LoginPage/components/UpdateEmailFb/index.scss @@ -0,0 +1,10 @@ +.login_fb_update_email { + .step_desc { + margin-bottom: 44px; + font-size: 18px; + } + .button_submit { + margin-top: 110px; + margin-bottom: 24px; + } +} diff --git a/src/_containers/LoginPage/index.js b/src/_containers/LoginPage/index.js new file mode 100644 index 0000000..52a0ddd --- /dev/null +++ b/src/_containers/LoginPage/index.js @@ -0,0 +1 @@ +export * from './LoginPage'; \ No newline at end of file diff --git a/src/_containers/More/HomePageMore.js b/src/_containers/More/HomePageMore.js new file mode 100644 index 0000000..0af1b5b --- /dev/null +++ b/src/_containers/More/HomePageMore.js @@ -0,0 +1,190 @@ +import React, { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; +import { useSelector, useDispatch } from "react-redux"; +import { useHistory } from "react-router-dom"; +import { scheduleConstants, userConstants } from "./../../_constants"; +import { PopUpYesNo } from "../../_components/Popup"; +import { persistor } from "../../index"; +import LazyLoad from "react-lazyload"; +import { apiRequestLogout } from "../../_helpers"; +import API from "../../_apis/APIConstants"; + +function HomePageMore() { + const authentication = useSelector((state) => state.authentication); + const [visibleModalLogout, setVisibleModalLogout] = useState(false); + const history = useHistory(); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch({ + type: scheduleConstants.SET_SELECT_DATE, + time: null, + }); + }, []); + + function logout() { + apiRequestLogout(`${API.logout_account_service}`); + apiRequestLogout(`${API.logout_account_exercise}`); + window.location.href = "/login"; + dispatch({ + type: userConstants.RESET_ALL_STATE, + }); + dispatch({ + type: userConstants.LOGOUT, + }); + persistor.purge(); + // localStorage.clear(); + localStorage.removeItem("authentication"); + localStorage.removeItem("access_token"); + localStorage.removeItem("info_header_user"); + localStorage.removeItem("purposeLogin"); + localStorage.removeItem("date_selected"); + localStorage.removeItem("curriculum_info"); + localStorage.removeItem("curriculum_id_Selected"); + + // localStorage.removeItem("device_id_commond"); + // history.push("/login"); + } + return ( +
    +
    + +

    Thêm

    +
    +
    +
    + {authentication.role === userConstants.ROLE_STUDENT && ( + + + ico_class +

    Lớp học

    +
    + + )} + + + ico_hoso +

    Hồ sơ

    +
    + + {authentication.role === userConstants.ROLE_STUDENT && ( + + + ico_tinnhan +

    Tin nhắn

    +
    + + )} + {authentication.role === userConstants.ROLE_TEACHER && ( + + + ico_lichlamviec +

    Lịch làm việc

    +
    + + )} + {authentication.role === userConstants.ROLE_TEACHER && ( + + + ico_huongdan +

    Hướng dẫn học tập

    +
    + + )} + {authentication.role === userConstants.ROLE_TEACHER && ( + + + ico_quanly +

    Quản lý bài đã giao

    +
    + + )} + {authentication.role === userConstants.ROLE_STUDENT && ( + + + ico_kehoachhoctap +

    + Kế hoạch +
    + học tập +

    +
    + + )} + + + ico_upgrade +

    Kích hoạt tài khoản

    +
    + + + + ico_caidat +

    Cài đặt

    +
    + + {/* {authentication.role === userConstants.ROLE_TEACHER && ( + +
    + ico_nangcap +

    Nâng cấp tài khoản

    +
    + + )} */} +
    +
    + {/*
    setVisibleModalLogout(true)} + > + +
    */} + {visibleModalLogout && ( + logout()} + onClickNo={() => setVisibleModalLogout(false)} + labelNo={"Không"} + message={["Bạn có muốn đăng xuất tài khoản không?"]} + customWidthBtn={"customWidthBtn"} + /> + )} +
    + ); +} + +export { HomePageMore }; diff --git a/src/_containers/More/License/AddLicense.js b/src/_containers/More/License/AddLicense.js new file mode 100644 index 0000000..458d25a --- /dev/null +++ b/src/_containers/More/License/AddLicense.js @@ -0,0 +1,104 @@ +import React, { useEffect } from "react"; +import Slider from "react-slick"; +import { SideBar } from "../../../_components/Admin/More/License"; +import { Header } from "../../../_components/Admin/Header"; +import { SliderItem } from "./SliderItem"; +import { useSelector, useDispatch } from "react-redux"; +import { SelectAsDiv } from "../../../_components/Select"; +import { feePageLogic } from "../../../_screens/FeePage/FeePage.logic"; +import { renderListPackages } from "../../../_screens/FeePage/FeePage"; +import { renderListPackagesTeacher } from "../../../_screens/TariffPage/TariffPage"; +import { tariffPageLogic } from "../../../_screens/TariffPage/TariffPage.logic"; +import LazyLoad from "react-lazyload"; +import { userConstants } from "../../../_constants"; + +function SampleNextArrow(props) { + const { className, onClick } = props; + return ( +
    + dropdown right +
    + ); +} + +function SamplePrevArrow(props) { + const { className, onClick } = props; + return ( +
    + ico_left_white +
    + ); +} + +function AddLicense() { + let { listPackages, handleNavigatePayment } = feePageLogic(); + + const authentication = useSelector((state) => state.authentication); + + let { + listPackagesTeacher, + accountNumber, + currPriceSpecific, + openPopUpAccount, + handleNavigatePaymentTeacher, + handleChangeAccountNumber, + handleActionAccount, + setOpenPopUpAccount, + handleResetAccount, + } = tariffPageLogic(); + + return ( +
    +
    + +
    +
    + +
    + {authentication.role == userConstants.ROLE_STUDENT + ? listPackages.map((item, index) => + renderListPackages(item, handleNavigatePayment, index) + ) + : listPackagesTeacher.map((item) => + renderListPackagesTeacher( + item, + handleChangeAccountNumber, + handleActionAccount, + handleNavigatePaymentTeacher, + accountNumber, + currPriceSpecific, + openPopUpAccount + ) + )} +
    +
    +
    +
    + + {openPopUpAccount == "popup" && ( + handleResetAccount()} + labelYes="Đóng" + message="Bạn cần mua tối thiểu 10 tài khoản học sinh." + /> + )} +
    + ); +} + +export { AddLicense }; diff --git a/src/_containers/More/License/EnterCodeLicense.js b/src/_containers/More/License/EnterCodeLicense.js new file mode 100644 index 0000000..66a9f52 --- /dev/null +++ b/src/_containers/More/License/EnterCodeLicense.js @@ -0,0 +1,59 @@ +import React, { useState } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { Link } from 'react-router-dom'; +import { licenseActions } from '../../../_actions'; +import { SideBar } from '../../../_components/Admin/More/License'; +import { licenseConstants } from '../../../_constants'; +import { Alert } from './../../../_components/Alert'; +import { Header } from '../../../_components/Admin/Header'; + + +function EnterCodeLicense() { + + const alert = useSelector(state => state.alert); + const [inputs, setInputs] = useState({ + code: '', + }); + const authentication = useSelector(state => state.authentication); + const dispatch = useDispatch(); + + const [submitted, setSubmitted] = useState(false); + const { code } = inputs; + // console.log(submitted); + function handleChange(e) { + const { name, value } = e.target; + setInputs(inputs => ({ ...inputs, [name]: value })); + } + + function handleSubmit(e) { + e.preventDefault(); + setSubmitted(true); + if (code) { + dispatch(licenseActions.forgotPassword({ code })); + } + } + + + return ( +
    +
    +
    + +
    + {alert.message && alert.screen === licenseConstants.SCREEN_LICENSE_ADD_CODE && } +
    +
    + + {/*

    Nếu chưa có mã vui lòng Click vào đây

    */} +
    +
    +
    + +
    +
    +
    +
    + ); +} + +export { EnterCodeLicense }; \ No newline at end of file diff --git a/src/_containers/More/License/HistoryLicense.js b/src/_containers/More/License/HistoryLicense.js new file mode 100644 index 0000000..1ddd66a --- /dev/null +++ b/src/_containers/More/License/HistoryLicense.js @@ -0,0 +1,188 @@ +import React, { useEffect, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { licenseActions } from "../../../_actions"; +import { SideBar } from "../../../_components/Admin/More/License"; +import { Header } from "../../../_components/Admin/Header"; +import "./style.scss"; +import { isEmpty } from "lodash"; +import moment from "moment"; +import $ from "jquery"; + +function HistoryLicense() { + const dispatch = useDispatch(); + const licenses = useSelector((state) => state.licenses); + const authentication = useSelector((state) => state.authentication); + const [isLoading, setLoading] = useState(false); + + // Function convert data History month + const convertHistoryTime = (packagesHistory) => { + let dataConvert = []; + let prevYear = 0; + let prevMonth = 0; + + if (!isEmpty(packagesHistory) && packagesHistory.length > 0) { + packagesHistory?.forEach((packageItem) => { + let month = moment(packageItem?.date, "DD-MM-YYYY").get("month"); + let year = moment(packageItem?.date, "DD-MM-YYYY").get("year"); + + if (prevYear != year || prevMonth != month) { + packageItem.month = month + 1; + packageItem.year = year; + prevYear = year; + prevMonth = month; + } + }); + dataConvert = dataConvert.concat(packagesHistory); + } + return dataConvert; + }; + + // Init Packages History + const packagesHistory = convertHistoryTime( + licenses?.listHistoryLicenses?.package_list + ); + + useEffect(() => { + dispatch(licenseActions.getHistoryLicense()); + }, []); + + useEffect(() => { + let isLoading = !$(".loading").hasClass("hide"); + setLoading(isLoading); + }, [licenses]); + + const showImgStatus = (action, is_success) => { + switch (action?.toLowerCase()) { + case "buy": + return is_success ? "ico_package_gan" : "ico_package_failed"; + case "assign": + return "ico_package_gan"; + case "activated": + return "ico_package_actived"; + case "expired": + return "ico_package_failed"; + case "deposed": + return "ico_package_failed"; + case "refund": + return "ico_package_failed"; + default: + break; + } + }; + + // Render Title Package + const showTitlePackage = (action, name) => { + switch (action?.toLowerCase()) { + case "buy": + return "Mua " + name; + case "assign": + return "Gán " + name; + case "activated": + return "Kích hoạt " + name; + case "expired": + return name + " hết hạn"; + case "deposed": + return "Hủy " + name; + case "refund": + return "Hoàn tiền " + name; + default: + break; + } + }; + + // Render History Payment + const renderHistoryPayment = (license, index) => { + return ( +
    + {!!license?.year ? ( +
    +
    {`Tháng ${license?.month}/${license?.year}`}
    +
    + ) : null} +
    +
    +
    + Icon Action +
    + +
    +
    + {showTitlePackage(license?.action, license?.package_name)} +
    + +
    {license?.date}
    +
    +
    + +
    + {license?.detail} +
    +
    +
    + ); + }; + + return ( +
    +
    +
    + {/* */} + {!isLoading ? ( +
    + {!isEmpty(packagesHistory) && packagesHistory.length > 0 ? ( +
    + {packagesHistory?.map((license, index) => + renderHistoryPayment(license, index) + )} +
    + ) : ( +
    + Img Empty +
    + Bạn chưa có lịch sử mua hàng! +
    + {/*
    + Hãy click vào "Mua gói mới" để trải nghiệm. +
    */} +
    + )} +
    + ) : null} +
    +
    + ); +} + +export { HistoryLicense }; diff --git a/src/_containers/More/License/HomePageLicense.js b/src/_containers/More/License/HomePageLicense.js new file mode 100644 index 0000000..49cdf54 --- /dev/null +++ b/src/_containers/More/License/HomePageLicense.js @@ -0,0 +1,291 @@ +import React, { useEffect, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { Link } from "react-router-dom"; +import { licenseActions } from "../../../_actions"; +import { SideBar } from "../../../_components/Admin/More/License"; +import { Header } from "../../../_components/Admin/Header"; +import ButtonNews from "../../../_components/Button/ButtonNews"; +import { history } from "../../../_helpers"; +import { PopUpYesNo } from "../../../_components/Popup"; +import "./style.scss"; +import { isEmpty } from "lodash"; +import APIBase from "../../../_base/APIBase"; +import API from "../../../_apis/APIConstants"; +import { alertActions } from "../../../_actions/alerts"; +import { licenseConstants } from "../../../_constants"; +import { Alert } from "../../../_components/Alert"; +import $ from "jquery"; +import { Fragment } from "react"; + +function HomePageLicense() { + const dispatch = useDispatch(); + const licenses = useSelector((state) => state.licenses); + const authentication = useSelector((state) => state.authentication); + const packages_available = licenses.listCurentLicenses?.package_list; + const [packageSelected, setPackageSelected] = useState({ id: "" }); + const [isLoading, setLoading] = useState(false); + + const alert = useSelector((state) => state.alert); + + useEffect(() => { + dispatch(licenseActions.getCurrentLicense()); + }, []); + + const isStudent = authentication.role == "student"; + + useEffect(() => { + let isLoading = !$(".loading").hasClass("hide"); + setLoading(isLoading); + }, [licenses]); + + // Handle Action Package + const handleActionPackage = (packageItem) => { + switch (packageItem.status) { + case "active": + case "expired": + history.push(`/${authentication.role}/more/license/add`); + break; + case "bought": + setPackageSelected(packageItem); + break; + default: + break; + } + }; + + // Render Packages Available + const renderPackagesAvailable = (packageItem) => { + let packageItemStatus = ""; + let packageItemBtn = ""; + let colorTextStatus = ""; + + switch (packageItem?.status.toLowerCase()) { + case "active": + packageItemStatus = "Đang sử dụng"; + packageItemBtn = !packageItem.isForever ? "Mua thêm" : ""; + colorTextStatus = "#00CC83"; + break; + case "bought": + packageItemStatus = "Chưa kích hoạt"; + packageItemBtn = isStudent ? "Kích hoạt" : "Gán"; + colorTextStatus = "#008ae6"; + break; + case "expired": + packageItemStatus = "Đã hết hạn"; + packageItemBtn = isStudent ? "Gia hạn" : "Gia hạn"; + colorTextStatus = "#BE1D2E"; + break; + default: + break; + } + + return ( +
    +
    + Img Package +
    + +
    +
    + {packageItem?.package_name}{" "} + {`(${packageItemStatus})`} +
    + +
    + {packageItem.status != "expired" ? ( + +
    + {packageItem.status == "active" + ? "Ngày kích hoạt: " + packageItem?.activated_date + : "Ngày mua: " + packageItem?.bought_date} +
    + +
    -
    +
    + ) : null} +
    + {(packageItem.status == "active" || + packageItem.status == "expired" + ? "Ngày hết hạn: " + : "Thời hạn: ") + + (packageItem?.isForever + ? "Vĩnh viễn" + : packageItem.status == "active" || + packageItem.status == "expired" + ? packageItem?.end_date + : packageItem?.duration_expired)} +
    +
    + +
    + {!!packageItemBtn ? ( + + ) : null} +
    +
    +
    + ); + }; + + // Navigate to history package page + const historyPackageComponent = () => { + return ( + + + + ); + }; + + // Handle upgrade Package + const handleUpgradePackage = async () => { + let urlApi = `${API.baseURL}${API.post_package_active}`; + try { + const result = await APIBase.apiBaseCaller("POST", urlApi, { + id: packageSelected?.payment_id, + }); + + if (result?.status) { + dispatch(licenseActions.getCurrentLicense()); + } else { + dispatch( + alertActions.success({ + message: result.msg.toString(), + screen: licenseConstants.SCREEN_LICENSE_ADD_CODE, + }) + ); + } + } catch (error) { + dispatch( + alertActions.success({ + message: error.toString(), + screen: licenseConstants.SCREEN_LICENSE_ADD_CODE, + }) + ); + } finally { + setPackageSelected({ id: "" }); + } + }; + + return ( +
    +
    +
    + {/* */} + {alert.message && + alert.screen == licenseConstants.SCREEN_LICENSE_ADD_CODE && ( + + )} + {!isLoading ? ( +
    + {!isEmpty(packages_available) && packages_available?.length > 0 ? ( +
    + {packages_available?.map((packageItem) => + renderPackagesAvailable(packageItem) + )} +
    + ) : ( +
    + ico_remove_blue +
    + Bạn chưa mua gói nào! +
    +
    + Hãy click vào "Mua gói mới" để trải nghiệm. +
    +
    + )} +
    + ) : null} +
    +
    + { + history.push(`/${authentication.role}/more/license/add`); + }} + > +
    + Icon Cart +
    + +
    + Mua gói mới +
    +
    + + { + history.push( + `/${authentication.role}/more/upgrade-account?from=license` + ); + }} + > +
    + Icon New Package +
    + +
    + Nhập gói đã mua +
    +
    +
    + + {!isEmpty(packageSelected) && !!packageSelected?.id ? ( + { + handleUpgradePackage(); + }} + onClickNo={() => { + setPackageSelected({ id: "" }); + }} + > + ) : null} +
    + ); +} + +export { HomePageLicense }; diff --git a/src/_containers/More/License/SliderItem.js b/src/_containers/More/License/SliderItem.js new file mode 100644 index 0000000..b8349b9 --- /dev/null +++ b/src/_containers/More/License/SliderItem.js @@ -0,0 +1,96 @@ +import React, { useState } from 'react'; + + +function SliderItem() { + const [showDesc, setShowDesc] = useState(false); + + function showDescFunc() { + setShowDesc(true); + } + + function hideDescFunc() { + setShowDesc(false); + } + + return ( +
  • +
    +
    +
    +

    Tiếng Anh lớp 8 - PRO 1

    +
    + details +
    +

    1.200.000đ

    +
    +
    +
    +
    +

    Thời hạn:

    +
    +
    + 3 tháng +
    +
    +
    +
    +

    Tặng thêm:

    +
    +
    + + 2 tháng +
    +
    +
    +
    + dropdown +
    +
    +
    +
    +

    Tiếng Anh lớp 8 - PRO 1

    +
    +
    +

    Mua gói VIP 1 để sở hữu gói học tập 5 tháng bao gồm:

    +
    +
    + checked +
    +
    +

    Toàn bộ 60 video bài giảng và hơn 300 bài tập thuộc tất cả các kỹ năng.

    +
    +
    +
    +
    + checked +
    +
    +

    Thi thử online với ngân hàng đề thi lên tới 5.500 câu.

    +
    +
    +
    +
    + checked +
    +
    +

    Chế độ học tập “IMaster” – cải thiện điểm yếu và ôn tập những kiến thức đã học

    +
    +
    +
    +
    + checked +
    +
    +

    Học theo lộ trình học tập cá nhân

    +
    +
    +
    +
    + dropdown +
    +
    +
    +
  • + ); +} + +export { SliderItem }; \ No newline at end of file diff --git a/src/_containers/More/License/index.js b/src/_containers/More/License/index.js new file mode 100644 index 0000000..bd3c876 --- /dev/null +++ b/src/_containers/More/License/index.js @@ -0,0 +1,4 @@ +export * from './HomePageLicense'; +export * from './AddLicense'; +export * from './HistoryLicense'; +export * from './EnterCodeLicense'; \ No newline at end of file diff --git a/src/_containers/More/License/style.scss b/src/_containers/More/License/style.scss new file mode 100644 index 0000000..e9db608 --- /dev/null +++ b/src/_containers/More/License/style.scss @@ -0,0 +1,321 @@ +.license-page { + .sunE-content-box { + padding-left: 0; + } + .license-content { + flex: 1; + overflow-y: auto; + max-height: 60rem; + align-items: flex-start; + + .img-license-empty { + width: 40%; + min-width: 20rem; + } + + .license-text-empty { + font-size: clamp(1.5rem, 2vw, 1.625rem); + } + + .license-text-instruct { + padding-top: 0.5rem; + font-size: clamp(1.125rem, 2vw, 1.25rem); + } + } + + .license-btn { + padding-bottom: 3vh; + padding-top: 2vh; + + button { + padding: 0.25rem 0.75rem; + } + + .btn-line-blue { + &:hover { + background: #00c0b4 !important; + } + } + + .btn__icon { + height: 80%; + + img { + height: 100%; + } + } + + .btn__icon-package { + height: 90%; + } + } + + .package-list { + align-items: flex-start; + justify-content: flex-start; + padding-top: calc(2vh + 0.5rem); + .package-item { + background-color: var(--white-color); + padding: 0.65rem 0.75rem; + width: 82%; + align-self: center; + border-radius: 1rem; + margin: 0.75rem 0; + + .package-img { + padding-right: calc(3% + 0.5rem); + img { + width: 8.75rem; + height: 8.75rem; + } + } + + .package-infor { + justify-content: flex-start; + align-items: flex-start; + height: 100%; + padding-right: 2rem; + + .package-infor_name { + font-size: clamp(1.125rem, 1.8vw, 1.25rem); + span { + font-weight: 500; + font-style: italic; + font-size: clamp(0.875rem, 1.5vw, 1rem); + } + } + + .package-infor_date { + div { + font-size: clamp(1rem, 1.5vw, 1.125rem); + } + } + + .package-infor_btn { + button { + height: 2.5rem; + padding-left: 2.5rem; + padding-right: 2.5rem; + border-radius: 1.25rem; + } + } + } + } + } + + .list-buy-history { + flex: 1; + overflow-y: auto; + max-height: 50rem; + align-items: flex-start; + } + .history-list { + .history-item { + width: 82%; + align-self: center; + + .history-infor { + padding: 1rem 1.5rem 1rem 1.25rem; + + .history-icon { + margin-right: calc(2% + 0.5rem); + img { + width: 3.5rem; + height: 3.5rem; + } + } + } + } + + .history-header { + background-color: #60d6d0; + height: 3.75rem; + padding: 0.5rem 1.5rem 0.5rem 2.25rem; + border: 1px solid #60d6d0; + margin-bottom: 2.5px; + position: relative; + + div { + font-size: clamp(1.8rem, 1.8vw, 1.875rem); + line-height: normal; + } + } + + .history-package_title { + font-size: clamp(1rem, 1.75vw, 1.125rem); + } + + .history-package_detail { + font-size: 0.875rem; + } + } +} + +.history-page { + padding-bottom: 0; +} + +// Add License +.add-license { + flex: 1; + overflow-y: auto; + max-height: 62rem; + align-items: flex-start; + + div, + span { + font-family: "Myriadpro-Regular" !important; + line-height: normal; + } + + .content { + .content_bg { + .list_packages { + padding: 0; + + .package_item { + margin-top: 1rem; + + min-width: 16.75rem; + + .package_item_header { + padding: 0.75rem 0 !important; + + .ico_white_star { + width: 0.875rem; + } + } + + .item_detail_fee { + font-size: clamp(0.75rem, 1.75vw, 0.875rem) !important; + margin-right: 1rem; + margin-left: 1rem; + width: 88.5%; + } + + .package_item_title { + font-size: clamp(1rem, 1.75vw, 1.125rem); + font-family: "Myriadpro-Bold" !important; + position: relative; + top: 0.155rem; + } + + .package_item_content { + padding: 0 5% !important; + } + + .ico_tick_detail { + width: 0.875rem; + top: 0.75rem; + } + + .ico_tick_detail_1 { + width: 0.875rem; + top: 0.75rem; + } + + .item_detail_fee_side { + margin-left: 0 !important; + } + + .package_item_price { + padding-top: 1rem !important; + margin-bottom: 0.75rem !important; + .original_price_item { + font-size: clamp(0.75rem, 1.75vw, 0.875rem) !important; + } + .original_price_item_unit { + font-size: clamp(0.65rem, 1.75vw, 0.75rem) !important; + } + } + .current_price_item { + font-size: clamp(1.5rem, 2.5vw, 1.75rem); + font-family: "Myriadpro-Bold" !important; + position: relative; + top: 0.155rem; + } + + .current_price_item_unit { + font-size: clamp(1.125rem, 2.5vw, 1.3rem) !important; + font-family: "Myriadpro-Bold" !important; + bottom: 0.15rem; + } + + .btn_custom { + background-image: var(--linear-color); + border-radius: 2rem; + width: 82% !important; + max-width: 90% !important; + height: 2.5rem !important; + div { + color: var(--white-color); + font-family: "Myriadpro-Regular" !important; + text-transform: initial !important; + font-size: clamp(0.875rem, 2.5vw, 1.05rem); + } + } + } + + .package_item_tariff { + width: 45%; + + min-width: 20.75rem; + min-height: 60rem !important; + margin-top: 0.75rem; + + .package_item_title { + font-size: clamp(1.25rem, 2vw, 1.42rem); + } + + .pdElement { + padding-top: 0.6rem !important; + padding-bottom: 0.6rem !important; + } + + .noPdElement_side { + padding-left: 1rem !important; + } + + .package_item_price_tariff { + padding-top: 0.15rem !important; + margin-bottom: 0.25rem !important; + line-height: normal; + } + + .tariff_item_accounts { + min-height: 6rem; + padding-bottom: 1.25rem !important; + padding-top: 1rem !important; + } + + .item_detail_fee, + .text_desc_diamond { + font-size: clamp(0.875rem, 2vw, 1rem) !important; + margin-right: 0.75rem !important; + } + + .btn_custom { + width: 75% !important; + max-width: 82% !important; + div { + font-size: clamp(1rem, 3.2vw, 1.135rem); + } + } + + .current_price_item { + font-size: clamp(2.25rem, 3.2vw, 2.5rem); + font-family: "Myriadpro-Bold" !important; + position: relative; + top: 0.155rem; + } + + .current_price_item_unit { + font-size: clamp(1.8rem, 3.2vw, 1.875rem) !important; + font-family: "Myriadpro-Bold" !important; + bottom: 0.15rem; + } + } + } + } + } +} diff --git a/src/_containers/More/Messages/DetailPageMessage.js b/src/_containers/More/Messages/DetailPageMessage.js new file mode 100644 index 0000000..d1907f9 --- /dev/null +++ b/src/_containers/More/Messages/DetailPageMessage.js @@ -0,0 +1,663 @@ +import React, { useEffect, useState, useRef } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { userActions } from "../../../_actions"; +import { useParams, Link, useHistory } from "react-router-dom"; +import { Header } from "../../../_components/Admin/Header"; +import { userConstants } from "../../../_constants"; +import { scheduleService, teacherService } from "../../../_services"; +import { isEmpty } from "lodash"; +import moment from "moment"; +import { history } from "../../../_helpers"; + +var intervalIdRefreshData = null; +var TIME_REQUEST = 60 * 1000; // 60s = 1 minutes +function DetailPageMessage() { + const { id } = useParams(); + const search = history.location.search; + const params = new URLSearchParams(search); + const tab = params.get("active"); + const page = params.get("page"); + const dispatch = useDispatch(); + const [activeTab, setActiveTab] = useState(tab); + + // console.log(page) + + // const dataMessage = useSelector(state => state.messages.data_message); + const [dataMessage, setDataMessage] = useState({}); + useEffect(() => { + if (activeTab === "personal") { + teacherService.getInboxInfo(id).then((data) => { + setDataMessage(data); + }); + } else { + teacherService.getSystemNotification(id).then((data) => { + setDataMessage(data); + }); + } + }, [activeTab]); + const authentication = useSelector((state) => state.authentication); + + const [detailMessage, setDetailMessage] = useState({}); + + const totalMsg = useSelector((state) => state.messages.total_msg); + + const [typeMessage, setTypeMessage] = useState(tab); + const [messIndex, setMessIndex] = useState(""); + const [roomId, setRoomId] = useState(""); + const [activeIndex, setActiveIndex] = useState("0"); + const [numberMsg, setNumberMsg] = useState({ + number_msg_new: "0", + number_system_new: "0", + }); + + const dataMess = + !isEmpty(dataMessage) && messIndex >= 0 ? dataMessage.data[messIndex] : ""; + + useEffect(() => { + dispatch(userActions.getPrivateMessages()); + }, []); + + useEffect(() => { + clearInterval(intervalIdRefreshData); + intervalIdRefreshData = setInterval(() => { + refreshDataMessage(); + }, TIME_REQUEST); + + return () => { + clearInterval(intervalIdRefreshData); + }; + }, [typeMessage, roomId]); + + function refreshDataMessage() { + if (roomId > 0) { + teacherService.getDetailInbox(roomId).then((data) => { + setDetailMessage(data); + executeScroll(); + }); + } + + teacherService.getInboxInfo(id).then((data) => { + if (typeMessage === "personal") { + setDataMessage(data); + } + setNumberMsg({ + number_msg_new: data.number_msg_new, + number_system_new: data.number_system_new, + }); + }); + + if (typeMessage === "system") { + teacherService.getSystemNotification(id).then((data) => { + setDataMessage(data); + }); + } + } + + useEffect(() => { + if (roomId > 0) { + teacherService.getDetailInbox(roomId).then((data) => { + setDetailMessage(data); + executeScroll(); + }); + } + }, [roomId]); + + useEffect(() => { + teacherService.getInboxInfo(id).then((data) => { + setNumberMsg({ + number_msg_new: data.number_msg_new, + number_system_new: data.number_system_new, + }); + }); + }, [typeMessage]); + + const [inputs, setInputs] = useState({ + room_id: roomId, + to_user_id: "", + subject: "", + content: "", + reply_for_id: "", + class_id: id, + }); + + const { content } = inputs; + + function changeType(type) { + setActiveIndex(); + dispatch({ + type: userConstants.RESET_CLASS_MESSAGE, + }); + setTypeMessage(type); + if (type === "personal") { + history.push({ + pathname: history.location.pathname, + search: `?active=personal&page=${page}`, + }); + setActiveTab("personal"); + setDataMessage({}); + teacherService.getInboxInfo(id).then((data) => { + setDataMessage(data); + }); + setMessIndex(""); + } else { + setActiveTab("system"); + history.push({ + pathname: history.location.pathname, + search: `?active=system&page=${page}`, + }); + setDataMessage({}); + teacherService.getSystemNotification(id).then((data) => { + setDataMessage(data); + }); + setRoomId(""); + } + setDetailMessage({}); + } + + // Handle Click Personal + function handleClickPersonal( + e, + room_id, + latest_msg_id, + index, + latest_msg_status + ) { + e.preventDefault(); + setRoomId(room_id); + setActiveIndex(room_id); + setInputs((inputs) => ({ ...inputs, room_id: room_id })); + + dispatch( + userActions.getDetailMessage(room_id, latest_msg_id, latest_msg_status) + ); + teacherService.getInboxInfo(id).then((data) => { + setDataMessage(data); + setNumberMsg({ + number_msg_new: data.number_msg_new, + number_system_new: data.number_system_new, + }); + }); + if (roomId > 0) { + setDetailMessage(""); + teacherService.getDetailInbox(room_id).then((data) => { + setDetailMessage(data); + executeScroll(); + }); + } + } + + function handleClickSystem(e, mess_id, message) { + e.preventDefault(); + setMessIndex(mess_id); + setActiveIndex(mess_id); + dispatch(userActions.getSystemNotification(id)); + teacherService.getSystemNotification(id).then((data) => { + setDataMessage(data); + }); + scheduleService.markSystemSeen(message.msg_id).then((res) => { + teacherService.getInboxInfo(id).then((data) => { + setNumberMsg({ + number_msg_new: data.number_msg_new, + number_system_new: data.number_system_new, + }); + }); + }); + } + function handleChange(e) { + const { name, value } = e.target; + setInputs((inputs) => ({ ...inputs, [name]: value })); + } + + function handleSubmit(e) { + e.preventDefault(); + + if (validateParam()) { + dispatch(userActions.sendMessage(inputs, roomId)); + } + dispatch(userActions.getDetailMessage(roomId)); + setInputs((inputs) => ({ ...inputs, content: "" })); + + teacherService.getDetailInbox(roomId).then((data) => { + setDetailMessage(data); + executeScroll(); + if (typeMessage === "personal") { + teacherService.getInboxInfo(id).then((data) => { + setDataMessage(data); + }); + } + }); + } + + function validateParam() { + return content ? true : false; + } + + function diffTime(startTimeString) { + const start = moment(startTimeString).toDate().getTime(); + const end = moment().toDate().getTime(); + const timespan = end - start; + const duration = moment(timespan); + return millisToMinutesAndSeconds(duration); + } + function millisToMinutesAndSeconds(millis) { + const minutes = Math.floor(millis / 60000); + // var seconds = ((millis % 60000) / 1000).toFixed(0); + return minutes; + } + + function handleKeyPress(event) { + if (event.which === 13 || event.keyCode === 13 || event.key === "Enter") { + handleSubmit(event); + } + } + + const myRef = useRef(null); + + const executeScroll = () => myRef.current?.scrollIntoView(); + + const goBackPageListChat = () => { + let path = ""; + if (page === "homepage") { + path = + authentication.role === userConstants.ROLE_TEACHER + ? "/teacher" + : "/student"; + } else { + path = + authentication.role === userConstants.ROLE_TEACHER + ? "/teacher/message" + : "/student/more"; + } + + history.push(path); + }; + + const renderUserNameSendLastMessage = (data) => { + if (data.last_user_send_id && !data.last_user_send_name) { + return "Người dùng đã bị xóa: "; + } else if (data.last_user_send_id === 0) { + return "Tin nhắn hệ thống"; + } else if (data.last_user_send_id === null) { + return null; + } else if ( + data.user_send_id !== authentication.id && + data.last_user_send_id !== authentication.id + ) { + return data.last_user_send_name + ": "; + } else if ( + data.user_send_id === authentication.id || + data.last_user_send_id === authentication.id + ) { + return "Bạn: "; + } + }; + + return ( +
    +
    +
    +
    + ico_add + +
    + + } + isBack + clickBack={goBackPageListChat} + /> +
    +
    +
    +
    +
    changeType("personal")} + > +
    + ico_message + {numberMsg.number_msg_new > 0 && isEmpty(totalMsg) && ( + + )} + {!isEmpty(totalMsg) && totalMsg.number_msg_new > 0 && ( + + )} +
    +

    CÁ NHÂN

    +
    +
    changeType("system")} + > +
    + ico_ring + {numberMsg.number_system_new > 0 && isEmpty(totalMsg) && ( + + )} + {!isEmpty(totalMsg) && numberMsg.number_system_new > 0 && ( + + )} +
    +

    HỆ THỐNG

    +
    +
    +
    + {!isEmpty(dataMessage.data) && + dataMessage.data.map((data, i) => { + if (typeMessage === "personal") { + let className = ""; + if ( + activeIndex === (data.id || data.room_id) && + data.seen_latest_msg_status === "1" + ) { + className = "msg-active msg-seen"; + } else if (data.seen_latest_msg_status === "1") { + className = "msg-seen"; + } else if (activeIndex === (data.id || data.room_id)) { + className = "msg-active msg-seen"; + } + if (!isEmpty(data.room_name)) { + return ( +
    + handleClickPersonal( + e, + data.id || data.room_id, + data.latest_msg_id, + i, + data.seen_latest_msg_status + ) + } + > +
    + student +
    +
    + {(data?.user_role === userConstants.ROLE_PARENT && !!data?.list_child_name?.length) ? ( +

    +

    {data?.room_name || ''}

    +

    {`Phụ huynh: ` + data?.list_child_name?.join(', ') }

    + + ) : ( +

    {data?.room_name || ''}

    + )} +
    + + {data.latest_msg_time + ? moment(data.latest_msg_time).format( + "HH:mm, DD/MM/YYYY" + ) + : "Chưa có tin nhắn nào"} + +
    +
    +
    + { +

    + {renderUserNameSendLastMessage(data) + + data.latest_msg_content || ""} +

    + } +
    + ); + } else { + return false; + } + } else { + let className = ""; + if ( + activeIndex === i && + data.seen_latest_msg_status === "1" + ) { + className = "msg-active msg-seen"; + } else if (data.seen_latest_msg_status === "1") { + className = "msg-seen"; + } else if (activeIndex === i) { + className = "msg-active"; + } + return ( +
    handleClickSystem(e, i, data)} + > +
    + student +
    +
    +

    + {data.title || ""} +

    + + {moment(data.send_time).format( + "HH:mm, DD/MM/YYYY" + ) || ""} + +
    +

    {data.msg || ""}.

    +
    + ); + } + })} +
    +
    + {!isEmpty(dataMessage) && dataMessage.data.length === 0 && ( +
    + + {typeMessage === "personal" ? ( +
    + Bạn chưa có tin nhắn mới nào +
    + Ấn{" "} + + "Gửi tin nhắn" + {" "} + để tạo tin nhắn mới. +
    + ) : ( +
    + Bạn chưa có thông báo mới nào. +
    + )} +
    + )} + {!isEmpty(detailMessage) && ( +
    + {!isEmpty(detailMessage) && ( +
    + bg_message +
    + )} + {!isEmpty(detailMessage) && ( +
    +
    + {!isEmpty(detailMessage) && + detailMessage.data.map((data, i) => { + return ( +
    + + {data.user_send_id === authentication.id + ? "" + : data.fullname} + + {data.user_send_id !== authentication.id && ( +
    + avatar +
    + )} +

    {data.msg}

    + {diffTime(data.send_time) === 0 && ( + Vừa xong + )} + {diffTime(data.send_time) > 59 && ( + + {moment(data.send_time).format( + "HH:mm, DD/MM/YYYY" + )} + + )} + {diffTime(data.send_time) > 0 && + diffTime(data.send_time) <= 59 && ( + + {diffTime(data.send_time) + " phút trước"} + + )} +
    + ); + })} +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + )} +
    + )} + + {isEmpty(detailMessage) && ( +
    +
    + bg_message +
    + {dataMess && ( +
    + {isEmpty(dataMess.file_link) && ( + bg_update + )} + {isEmpty(dataMess.file_link) && ( +
    +

    {dataMess.title}

    +

    {dataMess.msg}

    +
    + )} + + {dataMess.file_link && ( +
    +

    {dataMess.title}

    +

    {dataMess.msg}

    +
    + +
    +
    + )} +
    + )} +
    + )} +
    +
    +
    +
    + ); +} + +export { DetailPageMessage }; diff --git a/src/_containers/More/Messages/HomePageMessages.js b/src/_containers/More/Messages/HomePageMessages.js new file mode 100644 index 0000000..bdafd28 --- /dev/null +++ b/src/_containers/More/Messages/HomePageMessages.js @@ -0,0 +1,130 @@ +import React, { useEffect, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { teacherActions } from "../../../_actions"; +import { Header } from "../../../_components/Admin/Header"; +import { isEmpty } from "lodash"; +import { + EmptyClassBlock, + ListClassMessage, +} from "../../../_components/Admin/Teacher"; +import $ from "jquery"; +import { teacherService } from "../../../_services"; + +function HomePageMessages() { + const dispatch = useDispatch(); + // const classes = useSelector((state) => state.classes); + const [isLoading, setLoading] = useState(false); + const [classes, setClasses] = useState([]); + const [limitOnline] = useState(10); + const [offsetOnline, setOffsetOnline] = useState(0); + const [isEndOnlineClasses, setIsEndOnlineClasses] = useState(false); + const [baseUrl, setBaseUrl] = useState(""); + const [isLoadMoreOnline, setLoadMoreOnline] = useState(true); + const [isFirstLoading, setIsFirstLoading] = useState(true); + + useEffect(() => { + if (isLoading) { + $(".loading").removeClass("hide"); + } else { + $(".loading").addClass("hide"); + } + }, [isLoading]); + + useEffect(() => { + getListClass(); + }, []); + + const getListClass = async () => { + setLoading(true); + try { + let resOnline = await teacherService.getListClassOnlineAsyncLimit( + limitOnline, + offsetOnline, + 3 + ); + setLoading(false); + setBaseUrl(resOnline?.base_url); + setClasses(resOnline?.data); + isFirstLoading && setIsFirstLoading(false); + if (resOnline.data?.length < limitOnline) setIsEndOnlineClasses(true); + } catch (e) { + } finally { + setLoading(false); + } + }; + + const handleScroll = (e) => { + if ( + e.target.scrollHeight - e.target.scrollTop < e.target.clientHeight + 5 && + isLoadMoreOnline && + !isLoading + ) { + onLoadMoreClasses(); + } + }; + + // Load More Classes for Teacher + const onLoadMoreClasses = async () => { + let offsetOnlineMore = offsetOnline + limitOnline; + let concatListSide = []; + setLoading(true); + try { + if (!isEndOnlineClasses) { + let resOnline = await teacherService.getListClassOnlineAsyncLimit( + limitOnline, + offsetOnlineMore, + 3 + ); + concatListSide = resOnline?.data; + setOffsetOnline(offsetOnline + limitOnline); + if (resOnline?.data?.length < limitOnline) { + setLoadMoreOnline(false); + if (resOnline?.data?.length == 0) setLoadMoreOnline(false); + setIsEndOnlineClasses(true); + } + } else { + setIsEndOnlineClasses(true); + } + + let listClassSide = classes; + setClasses(listClassSide?.concat(concatListSide)); + } catch (e) { + } finally { + setLoading(false); + } + }; + + let componentClass = + isEmpty(classes) && isEmpty(classes.dataOffline) ? ( + + ) : classes.every((data) => data.count_student <= 0) ? ( + + ) : ( + + ); + + return ( +
    +
    +
    +
    + {!isFirstLoading && componentClass} +
    +
    +
    + ); +} + +export { HomePageMessages }; diff --git a/src/_containers/More/Messages/SendMessage.js b/src/_containers/More/Messages/SendMessage.js new file mode 100644 index 0000000..3372261 --- /dev/null +++ b/src/_containers/More/Messages/SendMessage.js @@ -0,0 +1,495 @@ +import React, { useEffect, useState, useRef } from "react"; +import { useSelector } from "react-redux"; +import { teacherConstants, userConstants } from "./../../../_constants"; +import { useParams } from "react-router-dom"; +import { Header } from "../../../_components/Admin/Header"; +import { isEmpty } from "lodash"; +import moment from "moment"; +import _ from "lodash"; +import { teacherService } from "../../../_services"; +import { SelectAsDiv } from "../../../_components/Select"; + +function SendMessage() { + const { id } = useParams(); + const [statusForm, setStatusForm] = useState(false); + const [textSearch, setTextSearch] = useState(""); + const [detailMessage, setDetailMessage] = useState({}); + const [dataContact, setDataContact] = useState({}); + const [activeIndex, setActiveIndex] = useState("0"); + + const [inputs, setInputs] = useState({ + room_id: "", + to_user_id: "", + subject: "", + content: "", + reply_for_id: "", + class_id: id, + type_filter: "all", + }); + const { content, type_filter } = inputs; + const authentication = useSelector((state) => state.authentication); + const classes = dataContact ? dataContact.data_contact : ""; + const baseUrl = dataContact ? dataContact.base_url : ""; + const [dataFilter, setdataFilter] = useState([]); + let [stt, setStt] = useState(false); + const [roomChat, setRoomChat] = useState("0"); + const [isLoading, setLoading] = useState(false); + const [isFocusSearch, setFocusSearch] = useState(false) + + useEffect(() => { + if (classes) { + setdataFilter(classes); + } + }, [classes]); + + useEffect(() => { + if (roomChat > 0) { + teacherService.getDetailInbox(roomChat).then((data) => { + setDetailMessage(data); + }); + } + }, [roomChat]); + + useEffect(() => { + setLoading(true); + teacherService.getDetailContact(id, authentication.role).then((data) => { + setDataContact(data); + setLoading(false); + }); + }, []); + + function handleChange(e) { + const { name, value } = e.target; + setInputs((inputs) => ({ ...inputs, [name]: value })); + } + + function handleChangeOption(type_filter) { + setInputs({ + ...inputs, + type_filter, + }); + if (type_filter === "all") { + if (_.isEmpty(textSearch)) { + setdataFilter([...classes]); + } else { + setdataFilter([ + ..._.filter( + classes, + (data) => + data.fullname !== null && + replaceTextSearch(data.fullname).includes( + replaceTextSearch(textSearch) + ) + ), + ]); + } + } else if (type_filter === "parent") { + setdataFilter([ + ..._.filter( + classes, + (data) => + data.user_role === type_filter && + data.child_name !== null && + replaceTextSearch(data.child_name).includes( + replaceTextSearch(textSearch) + ) + ), + ]); + } else { + setdataFilter([ + ..._.filter( + classes, + (data) => + data.user_role === type_filter && + data.fullname !== null && + replaceTextSearch(data.fullname).includes( + replaceTextSearch(textSearch) + ) + ), + ]); + } + + setStatusForm(false); + } + + function replaceTextSearch(textSearch) { + return textSearch + .toLowerCase() + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, ""); + } + + function handleInputChange(e) { + setTextSearch(replaceTextSearch(e.target.value)); + setStt(true); + if (!e.target.value) { + if (type_filter === "all") { + setdataFilter([...classes]); + } else { + setdataFilter([ + ..._.filter(classes, (data) => data.user_role === type_filter), + ]); + } + } else { + if (type_filter === "all") { + setdataFilter([ + ..._.filter( + classes, + (data) => + data.fullname !== null && + replaceTextSearch(data.fullname).includes( + replaceTextSearch(e.target.value) + ) + ), + ]); + } else if (type_filter === "parent") { + setdataFilter([ + ..._.filter( + classes, + (data) => + data.user_role === type_filter && + data.child_name !== null && + replaceTextSearch(data.child_name).includes( + replaceTextSearch(e.target.value) + ) + ), + ]); + } else { + setdataFilter([ + ..._.filter( + classes, + (data) => + data.user_role === type_filter && + data.fullname !== null && + replaceTextSearch(data.fullname).includes( + replaceTextSearch(e.target.value) + ) + ), + ]); + } + } + setStatusForm(false); + } + + function handleSubmit(e) { + e.preventDefault(); + if (validateParam()) { + teacherService.sendMessage(inputs).then(() => { + teacherService.getDetailInbox(roomChat).then((data) => { + setDetailMessage(data); + executeScroll(); + }); + }); + } + setInputs((inputs) => ({ ...inputs, content: "" })); + } + + function handleClickPersonal(e, user_id, index) { + e.preventDefault(); + setActiveIndex(index); + setInputs((inputs) => ({ ...inputs, to_user_id: user_id })); + setStatusForm(true); + + teacherService.getRoomChat(user_id).then((dataRoom) => { + setRoomChat(dataRoom.room_id); + teacherService.getDetailInbox(dataRoom.room_id).then((data) => { + setDetailMessage(data); + executeScroll(); + }); + }); + } + + function validateParam() { + return content ? true : false; + } + + function diffTime(startTimeString) { + const start = moment(startTimeString).toDate().getTime(); + const end = moment().toDate().getTime(); + const timespan = end - start; + const duration = moment(timespan); + return millisToMinutesAndSeconds(duration); + } + function millisToMinutesAndSeconds(millis) { + var minutes = Math.floor(millis / 60000); + // var seconds = ((millis % 60000) / 1000).toFixed(0); + return minutes; + } + + function handleKeyPress(event) { + if (event.which === 13 || event.keyCode === 13 || event.key === "Enter") { + handleSubmit(event); + } + } + + const myRef = useRef(null); + + const executeScroll = () => myRef.current.scrollIntoView(); + + return ( +
    +
    +
    +
    +
    + {authentication.role === userConstants.ROLE_TEACHER && ( + handleChangeOption(type)} + className="select-message" + styleBox={{ + justifyContent: "center", + paddingRight: '16px' + }} + styleItem={{ + justifyContent: 'center', + textIdent: 'unset' + }} + /> + )} + + {authentication.role === userConstants.ROLE_TEACHER && ( +
    + +
    + )} +
    + setFocusSearch(true)} + onBlur={() => setFocusSearch(false)} + /> + ico_search +
    +
    +
    + +
    +
    + {!isEmpty(classes) ? ( +
    +
    +
    + {/* {textSearch === "" && + dataFilter?.length > 0 && + dataFilter + .filter((it) => it.user_role === "student") + ?.map((data, i) => { + let className = ""; + if (activeIndex === i) { + className = "msg-active"; + } + return ( +
    + handleClickPersonal( + e, + data.id || data.user_id, + i + ) + } + > + {i + 1} +
    + student +
    +
    + {type_filter === "parent" && + data.child_name && ( +

    + {"Phụ huynh: " + data.child_name || ""} +

    + )} + {type_filter !== "parent" && ( +

    + {data.fullname || ""} +

    + )} +
    +
    + ); + })} */} + {dataFilter?.length > 0 && + dataFilter + .filter((it) => (it.user_role === type_filter || type_filter === "all")) + .map((data, i) => { + let className = ""; + if (activeIndex === i) { + className = "msg-active"; + } + return ( +
    + handleClickPersonal( + e, + data.id || data.user_id, + i + ) + } + > + {i + 1} +
    + student +
    +
    +

    + {(data?.user_role === userConstants.ROLE_PARENT && !!data?.list_child_name?.length) ? ( +

    +
    {data?.fullname || ''}
    +
    {`Phụ huynh: ` + data?.list_child_name?.join(', ') }
    +
    + ) : ( + <> + {data?.fullname || ""} + + )} +

    +
    +
    + ); + })} + + {!isLoading && (isEmpty(dataFilter) || dataFilter.length === 0) && ( +
    +

    Không tìm thấy kết quả

    +
    + )} +
    +
    +
    + ) : (!isLoading && ( +
    + Không có dữ liệu. +
    + ))} + {statusForm && ( +
    +
    +
    + {!isEmpty(detailMessage) && + detailMessage.data.map((data, i) => { + return ( +
    + + {data.user_send_id === authentication.id + ? "" + : data.fullname} + + {data.user_send_id !== authentication.id && ( +
    + avatar +
    + )} +

    {data.msg}

    + {diffTime(data.send_time) > 59 && ( + + {moment(data.send_time).format( + "HH:mm, DD/MM/YYYY" + )} + + )} + {diffTime(data.send_time) <= 59 && ( + + {diffTime(data.send_time) <= 1 + ? "Vừa xong" + : diffTime(data.send_time) + " phút trước"} + + )} +
    + ); + })} +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + )} +
    +
    +
    +
    + ); +} + +export { SendMessage }; diff --git a/src/_containers/More/Messages/index.js b/src/_containers/More/Messages/index.js new file mode 100644 index 0000000..9f57a80 --- /dev/null +++ b/src/_containers/More/Messages/index.js @@ -0,0 +1,3 @@ +export * from './HomePageMessages'; +export * from './DetailPageMessage'; +export * from './SendMessage'; \ No newline at end of file diff --git a/src/_containers/More/Profile/EditProfile.js b/src/_containers/More/Profile/EditProfile.js new file mode 100644 index 0000000..ccf3e59 --- /dev/null +++ b/src/_containers/More/Profile/EditProfile.js @@ -0,0 +1,763 @@ +import React, { useEffect, useState } from "react"; +import { useHistory } from "react-router-dom"; +import { useSelector, useDispatch } from "react-redux"; +import { Alert } from "../../../_components/Alert"; +import { teacherActions, userActions } from "../../../_actions"; +import { userConstants } from "./../../../_constants"; +import { SelectDate } from "../../../_components/Calendar"; +import { Header } from "./../../../_components/Admin/Header"; +import $ from "jquery"; +import { SelectAsDiv } from "./../../../_components/Select"; +import styled from "styled-components"; +import moment from "moment"; +import { isEmpty } from "lodash"; +import InputDate from "../../../_components/Auth/InputDate"; +import dayjs from "dayjs"; +import InputSelectSearch from "../../../_components/Auth/InputSelectSearch"; +import { apiCaller } from "../../../_helpers"; + +const ProfileImage = styled.img` + object-fit: cover; +`; + +const CustomSelect = styled(SelectAsDiv)` + background-image: unset; + .select-styled { + height: 44px; + line-height: 36px; + font-size: 14px; + padding-left: 20px; + border-radius: 18px; + outline: none; + border: 1px solid #fff; + box-shadow: 0 1px 8px 0 rgb(21 27 38 / 15%); + display: flex; + align-items: center; + justify-content: center; + + &::after { + top: 7px; + } + } + img { + display: none; + } + ul li { + height: 40px; + } +`; + +const GRADE_OPTIONS = [ + // { id: "1", name: "1" }, + // { id: "2", name: "2" }, + // { id: "3", name: "3" }, + // { id: "4", name: "4" }, + // { id: "5", name: "5" }, + { id: "Khối 6", name: "Khối 6" }, + { id: "Khối 7", name: "Khối 7" }, + { id: "Khối 8", name: "Khối 8" }, + { id: "Khối 9", name: "Khối 9" }, + // { id: "10", name: "10" }, + // { id: "11", name: "11" }, + // { id: "12", name: "12" }, +]; + +function EditProfile() { + const dispatch = useDispatch(); + const authentication = useSelector((state) => state.authentication); + const dataProfile = useSelector((state) => state.profile.user_info.data); + const alert = useSelector((state) => state.alert); + + // console.log(dataProfile); + + const [inputs, setInputs] = useState({ + fullname: dataProfile.fullname, + gender: dataProfile.gender, + birthday: + dataProfile?.birthday && moment(dataProfile.birthday).isValid() + ? new Date(dataProfile.birthday.replaceAll("-", "/")) + : new Date(), + email: dataProfile.email, + phone: dataProfile.phone, + school: dataProfile.school, + }); + + const history = useHistory(); + const baseUrl = useSelector((state) => state.profile.base_url); + + const [submitted, setSubmitted] = useState(false); + const [changeAvatar, setChangeAvatar] = useState(true); + const [availableEdit, setAilableEdit] = useState(false); + const [feildInputInValid, setFeildInputInvalid] = useState(""); + const [provinceList, setProvinceList] = useState([]); + const [province, setProvince] = useState({ + title: "", + value: "", + }); + const [districtList, setDistrictList] = useState([]); + const [district, setDistrict] = useState({ + title: "", + value: "", + }); + const [schoolList, setSchoolList] = useState([]); + const [school, setSchool] = useState({ + title: dataProfile?.school, + value: dataProfile?.school, + id: dataProfile?.school, + }); + const [errProvince, setErrProvince] = useState(""); + const [errDistrict, setErrDistrict] = useState(""); + + const { fullname, gender, birthday, email, phone } = inputs; + + useEffect(() => { + setInputs({ + fullname: dataProfile.fullname, + gender: dataProfile.gender, + birthday: + dataProfile?.birthday && moment(dataProfile.birthday).isValid() + ? new Date(dataProfile.birthday.replaceAll("-", "/")) + : new Date(), + email: dataProfile.email, + phone: dataProfile.phone, + school: dataProfile.school, + }); + }, [dataProfile]); + + useEffect(() => { + if (!!province.value) { + getDistrictList(province.value) + } + }, [province.value]) + + useEffect(() => { + if (!!district.value) { + getSchoolList(district.value) + } + }, [district.value]) + + useEffect(() => { + dispatch(teacherActions.getProfileV2(authentication.id)); + getProvinceList(); + $(document).ready(function ($) { + $("#avatar").change(function () { + readURL(this, "#preview-avatar"); + }); + + function readURL(input, element) { + if (input.files && input.files[0]) { + var reader = new FileReader(); + reader.onload = function (e) { + $(element).attr("src", e.target.result); + }; + reader.readAsDataURL(input.files[0]); + } + } + }); + }, []); + + const getProvinceList = () => { + apiCaller("/api_category/provinces?country_code=vn").then((res) => { + if (res.status) { + if(dataProfile?.province_alias) { + const province = res?.data?.find(item => item?.province_alias === dataProfile?.province_alias) + if(province) { + setProvince({ + value: province?.province_alias, + title: province?.province + }) + } + } + setProvinceList(res.data); + } + }); + }; + + const getDistrictList = (provinceAlias) => { + apiCaller(`/api_category/districts?province_alias=${provinceAlias}`).then( + (res) => { + if (res.status) { + if(dataProfile?.district_alias) { + const district = res?.data?.find(item => item?.district_alias === dataProfile?.district_alias) + if(district) { + setDistrict({ + value: district?.district_alias, + title: district?.district + }) + } + } + setDistrictList(res.data); + } + } + ); + }; + + const getSchoolList = (districtAlias) => { + apiCaller(`/api_category/schools?district_alias=${districtAlias}`).then( + (res) => { + if (res.status) { + setSchoolList(res.data); + } + } + ); + }; + + const changeProvice = (newProvince) => { + if (newProvince.value !== province.value) { + setAilableEdit(true); + setDistrict({ + title: "", + value: "", + }); + setSchool({ + title: "", + value: "", + }); + setProvince(newProvince); + getDistrictList(newProvince.value); + } + }; + + const changeDistrict = (newDistrict) => { + if (newDistrict.value !== district.value) { + setAilableEdit(true); + setSchool({ + title: "", + value: "", + }); + setDistrict(newDistrict); + getSchoolList(newDistrict.value); + } + }; + + const changeSchool = (school) => { + setAilableEdit(true); + setSchool(school); + }; + + function handleChange(e) { + setAilableEdit(true); + const { name, value } = e.target; + if (name === "phone") { + let numberPhone = e.target.value.replace(/\D/, ""); + setInputs((inputs) => ({ ...inputs, [name]: numberPhone })); + setFeildInputInvalid(""); + } else { + setInputs((inputs) => ({ ...inputs, [name]: value })); + } + } + + const changeBirthday = (birthday) => { + const today = new Date(); + setAilableEdit(true); + if (dayjs(birthday).isBefore(dayjs(today))) { + setInputs((inputs) => ({ ...inputs, ["birthday"]: birthday })); + } else { + setInputs((inputs) => ({ ...inputs, ["birthday"]: today })); + } + }; + + function handleOnBlur(e) { + const { name } = e.target; + let value = e.target.value.trim(); + if (name === "phone") { + let numberPhone = e.target.value.replace(/\D/, "").trim(); + if ([10, 11].includes(numberPhone.length)) { + setInputs((inputs) => ({ ...inputs, [name]: numberPhone })); + setFeildInputInvalid(""); + } else { + setFeildInputInvalid(name); + } + } else { + setInputs((inputs) => ({ ...inputs, [name]: value })); + } + } + + function handleChangeFile(event) { + setInputs((inputs) => ({ + ...inputs, + avatar: event.target.files[0], + })); + setChangeAvatar(true); + setAilableEdit(true); + } + + function openSelectFile(e) { + setChangeAvatar(false); + e.preventDefault(); + $("#avatar").trigger("click"); + } + + async function handleSubmit(e) { + e.preventDefault(); + setSubmitted(true); + if (changeAvatar && inputs["avatar"]) { + var uploadAvatar = new FormData(); + uploadAvatar.append("file", inputs["avatar"]); + // dispatch(userActions.uploadAvatar(uploadAvatar)); + await apiCaller("/api_user/update_avatar", "POST", uploadAvatar, null, false) + } + if (validateParam()) { + const params = { + ...inputs, + class: inputs.grade_name, + grade_id: + inputs.grade_name == "Khối 6" + ? 2 + : inputs.grade_name == "Khối 7" + ? 4 + : inputs.grade_name == "Khối 8" + ? 3 + : inputs.grade_name == "Khối 9" + ? 6 + : "", + birthday: + inputs.birthday.getFullYear() + + "-" + + (inputs.birthday.getMonth() + 1) + + "-" + + inputs.birthday.getDate(), + province_alias: province.value, + district_alias: district.value, + school: school.value, + }; + // delete params.grade_name; + + dispatch(teacherActions.updateProfile(params)); + } + } + + function changeGender(gender) { + setAilableEdit(true); + setInputs({ + ...inputs, + gender: gender, + }); + } + + function validateParam() { + if ( + fullname?.trim() && + gender && + birthday && + email && + phone + ) { + if (changeAvatar && availableEdit) { + return true; + } else if (availableEdit) { + return true; + } else { + return false; + } + } + // return (changeAvatar && availableEdit && fullname && gender && birthday && email && phone && school) ? true : false; + } + + const renderLocationIcon = () => { + return ( + + + + + + ); + }; + + const renderSchoolIcon = () => { + return ( + + + + + + + ); + }; + + return ( +
    +
    +
    +
    +
    + {authentication.role === userConstants.ROLE_STUDENT && ( + bg_edit_student_profile + )} +
    + + +
    + ico_edit_avt +
    +
    +
    +
    +
    + + +
    +
    + + {/* + console.log(birthday) + + setInputs({ ...inputs, birthday }) + setAilableEdit(true) + } + /> */} + +
    +
    + + +
    + {/* {authentication.role === userConstants.ROLE_STUDENT && ( +
    + + +
    + )} */} +
    +
    +
    + +
    +
    +
    changeGender("male")} + > + {"ico_male"} + {"ico_male_2"} + Nam +
    +
    +
    +
    changeGender("female")} + > + {"ico_female"} + {"ico_female_2"} + Nữ +
    +
    +
    +
    +
    + + +
    + {/* {authentication.role === userConstants.ROLE_TEACHER && ( +
    + + +
    + )} */} + {authentication.role === userConstants.ROLE_STUDENT && ( +
    + + {/* */} + { + setAilableEdit(true); + setInputs({ ...inputs, grade_name }); + }} + /> +
    + )} +
    +
    +
    +
    + +
    +
    + { + return { + value: item.province_alias, + title: item.province, + }; + })} + placeholder="Tỉnh/Thành phố" + titleHeader="Chọn Tỉnh/Thành phố" + renderLabelIcon={renderLocationIcon} + bottomErr={true} + errorText={errProvince} + setErrorText={setErrProvince} + styleInputSelectWrapper={{ + height: '44px', + marginBottom: 0, + backgroundColor: '#FFFFFF', + padding: '0 16px' + }} + className='profile-input-select' + /> + { + return { + value: item.district_alias, + title: item.district, + }; + })} + placeholder="Quận/Huyện" + titleHeader="Chọn Quận/Huyện" + renderLabelIcon={renderLocationIcon} + disabledClick={!province.value} + onClickDisable={() => { + setErrProvince("Vui lòng chọn tỉnh / thành phố"); + }} + errorText={errDistrict} + setErrorText={setErrDistrict} + bottomErr={true} + styleInputSelectWrapper={{ + height: '44px', + marginBottom: 0, + backgroundColor: '#FFFFFF', + padding: '0 16px' + }} + className={"profile-input-select ml-20"} + /> + { + return { + value: item.school_name, + title: item.school_name, + id: item?.id, + }; + })} + placeholder="Trường" + titleHeader="Chọn Trường" + renderLabelIcon={renderSchoolIcon} + disabledClick={!district.value} + onClickDisable={() => { + setErrDistrict("Vui lòng chọn quận / huyện"); + if (!province.value) { + setErrProvince("Vui lòng chọn tỉnh / thành phố"); + } + }} + bottomErr={true} + styleInputSelectWrapper={{ + height: '44px', + marginBottom: 0, + backgroundColor: '#FFFFFF', + padding: '0 16px' + }} + className={"profile-input-select ml-20"} + /> +
    +
    + + +
    + + {alert.message && + alert.screen === userConstants.SCREEN_UPDATE_PROFILE && ( + + history.push("/" + authentication.role + "/more/profile") + } + /> + )} + +
    + +
    + +
    +
    + ); +} + +export { EditProfile }; diff --git a/src/_containers/More/Profile/HomePageProfile.js b/src/_containers/More/Profile/HomePageProfile.js new file mode 100644 index 0000000..e6450e7 --- /dev/null +++ b/src/_containers/More/Profile/HomePageProfile.js @@ -0,0 +1,332 @@ +import React, { useEffect, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { Link } from "react-router-dom"; +import { teacherActions } from "../../../_actions"; +import { Header } from "./../../../_components/Admin/Header"; +import { useHistory } from "react-router-dom"; +import { userConstants } from "./../../../_constants"; +import moment from "moment"; +import { isEmpty } from "lodash"; +import styled from "styled-components"; +import $ from "jquery"; +import LazyLoad from "react-lazyload"; +import { apiCaller } from "../../../_helpers"; +import DoTestExam from "../../StudentPage/exam-test/DoTestExam"; + +const ProfileImage = styled.img` + object-fit: cover; +`; + +function HomePageProfile() { + const history = useHistory(); + const [isLoading, setLoading] = useState(false); + const [dataEntranceScoreStudent, setDataEntranceScoreStudent] = useState() + const [isTest, setIsTest] = useState(false); + + const dispatch = useDispatch(); + const authentication = useSelector((state) => state.authentication); + const dataProfile = useSelector((state) => state.profile.user_info.data); + const baseUrl = useSelector((state) => state.profile.base_url); + + const getEntranceScoreStudent = () => { + const url = '/api_user/entrance_test?' + 'user_id=' + authentication?.id + apiCaller(url, 'get', {}, null, true).then((res) => { + setDataEntranceScoreStudent(res?.data) + }).catch(err => { + alert(err) + }) + } + + const handleClickEntrance = () => { + if(dataEntranceScoreStudent?.test_done) { + history.push("/" + authentication.role + "/more/profile/entrance-score") + dispatch({ type: userConstants.SHOW_SIDEBAR_ROOTLESSNESS }) + } else { + setIsTest(true) + } + } + + useEffect(() => { + setLoading(true); + dispatch(teacherActions.getProfileV2(authentication.id)); + authentication.role === userConstants.ROLE_STUDENT && getEntranceScoreStudent() + }, []); + + + useEffect(() => { + let isLoading = !$(".loading").hasClass("hide"); + setLoading(isLoading); + }, [dataProfile]); + + const dateHere = String(dataProfile.birthday).split(" "); + const days = String(dateHere[0]).split("-"); + const formatDays = days[2] + "/" + days[1] + "/" + days[0]; + + function editProfile() { + return ( + <> + { authentication.role === userConstants.ROLE_STUDENT && dataEntranceScoreStudent &&
    + +
    } +
    + + + + {authentication.role === userConstants.ROLE_STUDENT && ( + ico_edit_profile + )} +
    + + ); + } + + // console.log(dataProfile); + return ( +
    +
    +
    history.push("/" + authentication.role + "/more")} + /> + {!isLoading && ( +
    +
    + {authentication.role === userConstants.ROLE_STUDENT && ( + bg_hoso_detail_student + )} + {authentication.role === userConstants.ROLE_TEACHER && ( + bg_hoso_detail + )} +
    +
    +
    + + + +

    {dataProfile.fullname}

    +
    + {/*
    {dataProfile.email}
    +
    */} +
    +
    + ico_gender +
    + + {dataProfile.gender === "female" ? "Nữ" : "Nam"} + +
    +
    +
    + ico_birthday +
    + {formatDays} +
    +
    +
    + ico_phone +
    + {dataProfile.phone} +
    +
    +
    + ico_email +
    + {dataProfile.email} +
    + {authentication.role === userConstants.ROLE_STUDENT && ( +
    +
    +
    + ico_class +
    + + {dataProfile.grade_name} + +
    +
    +
    + ico_school +
    + + {dataProfile.school} + +
    +
    + )} + {authentication.role === userConstants.ROLE_TEACHER && ( +
    +
    + ico_shcool +
    + {dataProfile.school} +
    + )} +
    +
    + Tài khoản: +
    +
    +

    + {dataProfile?.package?.package_type} +

    +
    +
    + {authentication.role !== userConstants.ROLE_PARENT && ( + + + Nâng cấp + + + )} +
    +
    +
    +
    + {authentication.role === userConstants.ROLE_STUDENT && ( +
    + + + Quản lý liên kết + + +
    + )} + {/* {authentication.role === userConstants.ROLE_TEACHER && ( +
    +
    +

    {dataProfile.class_number}

    + Lớp +
    +
    +

    + {dataProfile.student_number} +

    + Học sinh +
    +
    +

    + {dataProfile.curriculum_number} +

    + Giáo trình +
    +
    + )} */} + {/* {authentication.role === userConstants.ROLE_STUDENT && ( +
    +
    + + Phụ huynh{" "} + + {isEmpty(dataProfile.parent_info) && ( + +
    + ico_add_ph + Thêm liên kết +
    + + )} +
    +
    + {!isEmpty(dataProfile.parent_info) && ( +
    +
    + ico_add_ph +
    +
    +

    {dataProfile.parent_info?.parent_fullname}

    */} + {/* + Đã liên kết từ{" "} + {dataProfile.parent_info?.date_connected ? moment( + dataProfile.parent_info?.date_connected + ).format("DD/MM/YYYY") : ''} + */} + {/*
    +
    + )} +
    + )} */} +
    +
    + )} + {isTest && setIsTest(false)} isBackGuide/>} +
    +
    + ); +} + +export { HomePageProfile }; diff --git a/src/_containers/More/Profile/index.js b/src/_containers/More/Profile/index.js new file mode 100644 index 0000000..9148726 --- /dev/null +++ b/src/_containers/More/Profile/index.js @@ -0,0 +1,2 @@ +export * from './HomePageProfile'; +export * from './EditProfile'; \ No newline at end of file diff --git a/src/_containers/More/Resource/HomePageResource.js b/src/_containers/More/Resource/HomePageResource.js new file mode 100644 index 0000000..504c7d8 --- /dev/null +++ b/src/_containers/More/Resource/HomePageResource.js @@ -0,0 +1,423 @@ +import React, { useEffect, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { alertActions, teacherActions } from "../../../_actions"; +import { Header } from "./../../../_components/Admin/Header"; +import { + curriculumConstants, + popupConstants, + teacherConstants, +} from "../../../_constants"; +import moment from "moment"; +import { + PopUpFilter, + PopUpYesNo, + PopUpAddFile, +} from "../../../_components/Popup"; +import { Alert } from "./../../../_components/Alert"; +import { isEmpty } from "lodash"; +import $ from "jquery"; +import { configConstants } from "../../../_constants"; +import { PopUpZoomImageV2 } from "../../../_components/Popup/PopUpZoomImageV2"; +import LazyLoad from "react-lazyload"; +import { history } from "../../../_helpers"; + +function HomePageResource() { + const dispatch = useDispatch(); + const curriculums = useSelector((state) => state.curriculums); + const exercises = useSelector((state) => state.classes.exercises); + const Popup = useSelector((state) => state.Popup); + const alert = useSelector((state) => state.alert); + const [visibleModalUpdateSoon, setVisibleModalUpdateSoon] = useState(false); + const [isLoading, setLoading] = useState(false); + const [fileActive, setFileActive] = useState({}); + const [showHideDisplay, setShowHideDisplay] = useState(false); + const [htmlWritingContent, setHtmlWritingContent] = useState([]); + const [openZoomImage, setOpenZoomImage] = useState(false); + + useEffect(() => { + let isLoading = !$(".loading").hasClass("hide"); + setLoading(isLoading); + }, [exercises]); + + useEffect(() => { + setLoading(true); + dispatch(teacherActions.getFileExercise(curriculums.filters.param)); + return () => { + dispatch({ + type: curriculumConstants.CLEAR_PARAM_FILTER_CURRICULUM, + }); + }; + }, []); + + function setshowFilter() { + dispatch({ + type: popupConstants.SHOW_FORM_POPUP, + data: { + showFilterCurriculum: true, + }, + }); + } + + function setclosePopup() { + dispatch(alertActions.error({ message: "", screen: "" })); + dispatch({ + type: popupConstants.CLEAR_ALL_POPUP, + }); + } + + function componentFilter() { + let isEmptyData = + isEmpty(curriculums.filters.param.grade_id) && + isEmpty(curriculums.filters.param.skill) && + isEmpty(curriculums.filters.param.type); + + if (exercises.files && exercises.files.data.length || !isEmptyData) { + return ( + + ); + } + } + + const [idRmove, setIdRemove] = useState(0); + const [showFormRemove, setShowFormRemove] = useState(false); + + function setShowRemove(id) { + setShowFormRemove(true); + setIdRemove(id); + } + + function revemoFile(id) { + setShowFormRemove(false); + setIdRemove(0); + dispatch( + teacherActions.deleteFileExercise({ + id: idRmove, + param: curriculums.filters.param, + }) + ); + } + + function setshowAddFile() { + dispatch({ + type: popupConstants.SHOW_FORM_POPUP, + data: { + showAddFile: true, + }, + }); + } + + const setIsBack = () => { + if (showHideDisplay) { + setShowHideDisplay(false); + setFileActive({}); + } else { + history.go(-1); + } + }; + + function renderIcoFile(data) { + if (data.type === "document") { + let arr = data.path.split("."); + let fileFormat = arr[arr.length - 1]; + if (["doc", "docx"].includes(fileFormat)) { + return ( + {data.type} + ); + } else if (["xlsx", "xls", "xlsm", "xlsb"].includes(fileFormat)) { + return ( + {data.type} + ); + } else if (["ppt", "pptx", "pps", "ppsx", "pptm"].includes(fileFormat)) { + return ( + {data.type} + ); + } else if (fileFormat === "pdf") { + return ( + {data.type} + ); + } else { + return ( + {data.type} + ); + } + } else { + return ( + {data.type} + ); + } + } + + const openWindow = (file) => { + setFileActive(file); + if (["video", "writing", "audio", "img"].includes(file.type)) { + setShowHideDisplay(true); + } else { + window.open(file?.path, "_blank"); + } + }; + + const detailImage = () => { + // window.open(fileActive?.path); + setOpenZoomImage(true); + }; + + let isNotUseFilter = + isEmpty(curriculums.filters.param.grade_id) && + isEmpty(curriculums.filters.param.level) && + isEmpty(curriculums.filters.param.skill) && + isEmpty(curriculums.filters.param.type); + + function capitalizeFirstLetter(string) { + return string.charAt(0).toUpperCase() + string.slice(1); + } + + useEffect(() => { + if (fileActive.type == "writing") { + const htmlFileContent = fileActive?.content?.split("\n"); + // console.log(htmlFileContent); + setHtmlWritingContent(htmlFileContent); + } + }, [fileActive.type]); + + return ( +
    + {Popup.showAddFile && ( + setclosePopup()} + width={400} + messageErr={ + alert.screen === teacherConstants.SCREEN_LIST_FILE + ? alert.message + : "" + } + class_name={"custom-width"} + onSubmit={() => setShowHideDisplay(false)} + /> + )} + {alert?.message && + alert?.screen === teacherConstants.SCREEN_LIST_FILE && + + } + {Popup.showFilterCurriculum && ( + setclosePopup()} + width={460} + filter_files={true} + class_name={"custom-width"} + /> + )} + {showFormRemove && ( + revemoFile()} + onClickNo={() => setShowFormRemove(false)} + labelNo={"Không"} + message={[ + "Bạn có chắc chắn muốn xoá", + "Hướng dẫn học tập này", + "ra khỏi danh sách ?", + ]} + /> + )} + {/* {Popup.addFileCompleteResource && setclosePopup()} width={320} labelNo={'Không'} onClickNo={() => setclosePopup(false)} message={['Tạo hướng dẫn thành công !', 'Bạn có muốn thêm hướng dẫn', 'vào bài tập không ?']} />} */} + {/* {alert.message && alert.screen === teacherConstants.SCREEN_LIST_FILE && } */} +
    +
    + {!isLoading && ( + + {!showHideDisplay && + exercises.files && + exercises.files.data.map((data, i) => { + return ( +
    +
    openWindow(data)} + > +
    {renderIcoFile(data)}
    +
    +

    + {data.title} +

    + + Ngày tạo:{" "} + {moment(data.created_at).format("DD/MM/yyyy")} + + + {data?.grade_name} {" >> "}{" "} + {capitalizeFirstLetter(data?.skill)} + +
    +
    +
    setShowRemove(data.id)} + > + ico_remove_blue +
    +
    + ); + })} + {!showHideDisplay && + exercises.files && + exercises.files.data.length === 0 && + (isNotUseFilter ? ( +
    + +
    + Bạn chưa tạo nội dung hướng dẫn học tập nào. +
    Chọn + "Tạo mới" + {" "} + để tạo hướng dẫn. +
    + ) : ( + + Không tìm thấy kết quả phù hợp. + + ))} + {showHideDisplay && ( +
    +
    +
    +
    {renderIcoFile(fileActive)}
    +
    +

    + {fileActive?.title} +

    +
    +
    +
    + {fileActive?.type === "writing" && ( +
    + {htmlWritingContent.map((item, index) => ( +
    {item}
    + ))} +
    + )} + {fileActive?.type === "video" && ( + + + + )} + {fileActive?.type === "audio" && ( +
    + +
    + )} + {fileActive?.type === "img" && ( +
    + + {fileActive?.type} + Icon Zoom out + +
    + )} +
    + )} +
    + )} +
    +
    setshowAddFile()} + > + +
    + + {visibleModalUpdateSoon && ( + removeCurriculum(curriculum.id)} + onClickNo={() => setVisibleModalUpdateSoon(false)} + message={ + "Tính năng xem chi tiết hướng dẫn học tập đang cập nhật. Vui lòng đăng nhập app để sử dụng." + } + labelNo={"Đóng"} + styleGroupBtn={{ paddingLeft: 30, paddingRight: 30 }} + width={"278px"} + hideButtonYes={true} + /> + )} + + {openZoomImage && ( + setOpenZoomImage(false)} + /> + )} +
    + ); +} + +export { HomePageResource }; diff --git a/src/_containers/More/Resource/index.js b/src/_containers/More/Resource/index.js new file mode 100644 index 0000000..4dfec12 --- /dev/null +++ b/src/_containers/More/Resource/index.js @@ -0,0 +1 @@ +export * from './HomePageResource'; \ No newline at end of file diff --git a/src/_containers/More/Schedule/AddSchedule.js b/src/_containers/More/Schedule/AddSchedule.js new file mode 100644 index 0000000..54e8d63 --- /dev/null +++ b/src/_containers/More/Schedule/AddSchedule.js @@ -0,0 +1,730 @@ +import React, { useState, useMemo, useCallback } from "react"; +import _, { update } from "lodash"; +import moment from "moment"; +import { useSelector, useDispatch } from "react-redux"; +import { scheduleActions } from "./../../../_actions"; +import { userConstants } from "./../../../_constants"; +import { Header } from "./../../../_components/Admin/Header"; +import { Alert } from "./../../../_components/Alert"; +import { teacherConstants, scheduleConstants } from "./../../../_constants"; +import { useHistory } from "react-router-dom"; +import { SelectAsDiv } from "./../../../_components/Select"; +import { SelectDate } from "./../../../_components/Calendar"; +import $ from "jquery"; +import { useParams } from "react-router-dom"; +import { parse } from "query-string"; +import { alertActions } from "./../../../_actions"; +import { alertConstants } from "./../../../_constants"; +import { FastfoodOutlined } from "@material-ui/icons"; + +function AddSchedule() { + const { page } = useParams(); + const history = useHistory(); + const dispatch = useDispatch(); + const alert = useSelector((state) => state.alert); + const schedules = useSelector((state) => state.schedules); + const [isShowSwitchEdit, showSwitchEdit] = useState(false); + const [typeUpdateWithLoop, setTypeUpdateWithLoop] = useState(0); + + const [isDisabledBtn, setIsDisabledBtn] = useState(false); + + const pageParams = useMemo(() => { + return history?.location?.search ? parse(history.location.search) : null; + }, [history.location.search]); + + const setEndTimeSchedules = useMemo(() => { + if (schedules.detail_today.action === "add") { + return { + ...schedules.detail_today, + start_time: pageParams?.date + ? new Date( + new Date(pageParams.date).getFullYear(), + new Date(pageParams.date).getMonth(), + new Date(pageParams.date).getDate(), + new Date().getHours(), + new Date().getMinutes() + ) + : schedules?.detail_today.start_time, + end_time: new Date( + moment( + pageParams?.date + ? new Date( + new Date(pageParams.date).getFullYear(), + new Date(pageParams.date).getMonth(), + new Date(pageParams.date).getDate(), + new Date().getHours(), + new Date().getMinutes() + ) + : schedules?.detail_today.start_time + ).add(7, "days") + ), + valid_to: new Date( + moment( + pageParams?.date + ? new Date( + new Date(pageParams.date).getFullYear(), + new Date(pageParams.date).getMonth(), + new Date(pageParams.date).getDate(), + new Date().getHours(), + new Date().getMinutes() + ) + : schedules?.detail_today.start_time + ).add(7, "days") + ), + }; + } else { + return { + ...schedules?.detail_today, + start_time: new Date(moment(schedules?.detail_today?.start_time)), + end_time: new Date(moment(schedules?.detail_today?.valid_to)), + valid_to: new Date(moment(schedules?.detail_today?.valid_to)), + }; + } + }, [schedules?.detail_today]); + + const authentication = useSelector((state) => state.authentication); + const [inputs, setInputs] = useState(setEndTimeSchedules); + const [submitted, setSubmitted] = useState(false); + let { + title, + start_time, + end_time, + type, + content, + remind_time, + repeat_type, + action, + valid_to, + } = inputs; + + const [checkRemind, setcheckRemind] = useState( + parseInt(inputs.remind || 1) === 1 ? true : false + ); + + function handleChange(e) { + const { name, value } = e.target; + if (name === "remind_time") { + let val = e.target.value === "" ? "" : e.target.value.replace(/\D/, ""); + if (val > 60 && val < 70) { + val = 60; + setInputs((inputs) => ({ ...inputs, [name]: val })); + } else if (val <= 60) { + setInputs((inputs) => ({ ...inputs, [name]: val })); + } + } else { + setInputs((inputs) => ({ ...inputs, [name]: value })); + } + + if (name == "title") { + if (e.target.value.length <= 50) { + setIsDisabledBtn(false); + dispatch( + alertActions.error({ + message: "", + screen: scheduleConstants.SCREEN_ADD_SCHEDULE, + }) + ); + } else { + setIsDisabledBtn(true); + dispatch( + alertActions.error({ + message: alertConstants.MSG_ERROR, + screen: scheduleConstants.SCREEN_ADD_SCHEDULE, + }) + ); + } + } + } + + function handleBlurInputText(e) { + const { name, value } = e.target; + setInputs((inputs) => ({ ...inputs, [name]: value.trim() })); + } + + function handleBlur() { + if (inputs["remind_time"] === "") { + setInputs((inputs) => ({ ...inputs, ["remind_time"]: 0 })); + } + if (Number(inputs["remind_time"]) > 60) { + setInputs((inputs) => ({ ...inputs, ["remind_time"]: 60 })); + } + } + + function changeRepeatType(repeat_type) { + if (inputs) { + const startTime = pageParams?.date + ? new Date( + new Date(pageParams.date).getFullYear(), + new Date(pageParams.date).getMonth(), + new Date(pageParams.date).getDate(), + new Date().getHours(), + new Date().getMinutes() + ) + : schedules?.detail_today?.start_time; + + switch (repeat_type) { + case "no_repeat": + setInputs({ + ...inputs, + repeat_type, + }); + return; + case "day": + setInputs({ + ...inputs, + end_time: !isNaN(inputs?.end_time?.getTime()) ? inputs?.end_time : new Date(moment(startTime).add(7, "days")), + valid_to: !isNaN(inputs?.valid_to?.getTime()) ? inputs?.valid_to : new Date(moment(startTime).add(7, "days")), + repeat_type: repeat_type, + }); + return; + case "week": + setInputs({ + ...inputs, + // end_time: new Date(moment(startTime).add(1, "month")), + // valid_to: new Date(moment(startTime).add(1, "month")), + end_time: !isNaN(inputs?.end_time?.getTime()) ? inputs?.end_time : new Date(moment(startTime).add(7, "days")), + valid_to: !isNaN(inputs?.valid_to?.getTime()) ? inputs?.valid_to : new Date(moment(startTime).add(7, "days")), + repeat_type: repeat_type, + }); + return; + case "month": + setInputs({ + ...inputs, + // end_time: new Date(moment(startTime).add(1, "year")), + // valid_to: new Date(moment(startTime).add(1, "year")), + end_time: !isNaN(inputs?.end_time?.getTime()) ? inputs?.end_time : new Date(moment(startTime).add(7, "days")), + valid_to: !isNaN(inputs?.valid_to?.getTime()) ? inputs?.valid_to : new Date(moment(startTime).add(7, "days")), + repeat_type: repeat_type, + }); + return; + default: + } + } + } + + function handleSubmit(e) { + e.preventDefault(); + setSubmitted(true); + if (validateParam()) { + if (!checkRemind) { + inputs.remind_time = null; + inputs.remind = 0; + inputs.is_remind = 0; + setInputs({ + ...inputs, + remind_time: "", + }); + } else { + inputs.remind = 1; + inputs.is_remind = 1; + if (!inputs.remind_time) { + return false; + } + } + // dispatch({ + // type: scheduleConstants.SET_SELECT_DATE, + // time: moment(inputs?.start_time).format("yyyy-MM-DD"), + // }); + + // dispatch({ + // type: scheduleConstants.SET_DATE_SELECTED_CALENDAR, + // time: moment(inputs?.start_time).format("yyyy-MM-DD"), + // }); + + if (action == "add") { + dispatch( + scheduleActions.addSchedule({ + title: inputs.title.trim(), + content: inputs.content.trim(), + remind: checkRemind ? 1 : 0, + remind_time: inputs.remind_time || remind_time, + start_time: moment(inputs.start_time).format("HH:mm"), + end_time: moment(inputs.repeat_type == 'no_repeat' ? inputs.start_time : inputs?.end_time).format("HH:mm"), + valid_from: moment(inputs.start_time).format("yyyy-MM-DD"), + valid_to: moment(inputs?.end_time).format("yyyy-MM-DD"), + type: inputs.type, + repeat_type: inputs.repeat_type, + }) + ); + + localStorage.setItem( + "date_selected", + JSON.stringify(moment(inputs.start_time).format("yyyy-MM-DD")) + ); + } else { + if (setEndTimeSchedules.repeat_type === "") { + handleUpdateSchedule(0); + } else { + if (inputs.repeat_type == "no_repeat") { + showSwitchEdit(false); + let dateNow = new Date(); + let status = + moment(start_time).toDate() > dateNow + ? "no_status" + : inputs.status; + dispatch( + scheduleActions.editSchedule( + _.pickBy({ + id: inputs.id, + title: inputs.title.trim(), + content: inputs.content.trim(), + remind_time: inputs.remind_time || remind_time, + remind: checkRemind ? "1" : "0", + start_time: moment(inputs.start_time).format( + "yyyy-MM-DD HH:mm:ss" + ), + valid_from: moment(inputs.start_time).format("yyyy-MM-DD"), + valid_to: moment(inputs.valid_to).format("yyyy-MM-DD"), + update_all: "0", + type: inputs.type, + repeat_type: + inputs.repeat_type == "no_repeat" + ? null + : inputs.repeat_type, + }) + ) + ); + localStorage.setItem( + "date_selected", + JSON.stringify(moment(inputs.start_time).format("yyyy-MM-DD")) + ); + } else { + showSwitchEdit(true); + } + } + } + } + } + + const handleUpdateSchedule = (updateAll) => { + showSwitchEdit(false); + let dateNow = new Date(); + let status = + moment(start_time).toDate() > dateNow ? "no_status" : inputs.status; + dispatch( + scheduleActions.editSchedule( + _.pickBy({ + id: inputs.id, + title: inputs.title.trim(), + content: inputs.content.trim(), + remind_time: inputs.remind_time || remind_time, + remind: checkRemind ? "1" : "0", + start_time: moment(inputs?.start_time).format("yyyy-MM-DD HH:mm:ss"), + end_time: moment(inputs?.end_time).format("yyyy-MM-DD HH:mm"), + valid_from: moment(inputs?.start_time).format("yyyy-MM-DD"), + valid_to: moment(inputs?.end_time).format("yyyy-MM-DD"), + update_all: `${updateAll ? updateAll : parseInt(0)}`, + status, + type: inputs.type, + repeat_type: inputs.repeat_type, + }) + ) + ); + dispatch({ + type: scheduleConstants.SET_DATE_SELECTED_CALENDAR, + time: moment(inputs?.start_time).format("yyyy-MM-DD"), + }); + }; + + function validateParam() { + return start_time && end_time && type && title.trim() + ? // && tart_time <= end_time + true + : false; + } + + function onCompleteAddSchedule(page) { + if (authentication.role === userConstants.ROLE_TEACHER) { + page === "homepage" + ? history.push( + "/" + + authentication.role + + `?date=${moment(start_time).format("YYYY-MM-DD")}` + ) + : history.push("/" + authentication.role + "/more/schedule/day"); + } else { + history.push("/" + authentication.role + "/more/schedule"); + } + } + + const onChangeDateTimeSelect = (start_time) => { + // if (inputs?.repeat_type == "no_repeat") { + // setInputs({ ...inputs, start_time }); + // } else { + // let validTo = ""; + // switch (inputs?.repeat_type) { + // case "day": + // validTo = new Date(moment(start_time).add(7, "days")); + // break; + // case "week": + // validTo = new Date(moment(start_time).add(1, "month")); + // break; + // case "month": + // validTo = new Date(moment(start_time).add(1, "year")); + // break; + // default: + // break; + // } + // setInputs({ ...inputs, start_time, valid_to: validTo }); + setInputs({ ...inputs, start_time }); + // } + // if (start_time.getTime() > dateNow.getTime() - 24 * 60 * 60 * 1000) { + // if (repeat_type === "no_repeat") { + // setInputs({ ...inputs, start_time, end_time: start_time }); + // } else { + // setInputs({ ...inputs, start_time }); + // } + // } else { + // console.log("Date is not selected!"); + // } + }; + + const onChangeDateEndTime = (end_time) => { + let dateNow = new Date(); + end_time = new Date( + end_time.getFullYear(), + end_time.getMonth(), + end_time.getDate(), + 23, + 59, + 59 + ); + if (end_time.getTime() > dateNow.getTime() + // && end_time.getTime() > inputs?.start_time?.getTime() + ) { + // console.log("end_time", end_time); + setInputs({ ...inputs, end_time: end_time, valid_to: end_time }); + } + // else { + // dispatch( + // alertActions.error({ + // message: "Vui lòng chọn đúng khoản thời gian áp dụng", + // screen: scheduleConstants.SCREEN_ADD_SCHEDULE, + // isShowPopup: true + // }) + // ); + // } + }; + + const gotoBackPage = useCallback(() => { + if (pageParams?.redirectUrl) { + history.push( + `${pageParams?.redirectUrl}?date=${ + pageParams?.date + ? moment(pageParams?.date).format("YYYY-MM-DD") + : moment(new Date()).format("YYYY-MM-DD") + }` + ); + } else { + history.go(-1); + } + }, [pageParams, history, authentication, inputs]); + + return ( +
    +
    + {alert.message && + alert.screen === teacherConstants.SCREEN_ADD_SCHEDULE && ( + onCompleteAddSchedule(page)} /> + )} +
    +
    +
    + + +
    +
    +
    end_time) + ? " err" + : "") + } + > + + onChangeDateTimeSelect(start_time)} + /> +
    + {authentication.role === userConstants.ROLE_TEACHER && ( +
    + + setInputs({ ...inputs, type })} + list_style + styleBox={{ + display: 'flex', + justifyContent: 'center', + }} + styleItem={{ + display: 'flex', + alignItems: 'center' + }} + /> +
    + )} +
    +
    + + +
    + Nhắc trước + + Ngày hết hạn +
    + {(new Date(inputs.end_time) - new Date(inputs.start_time)) / + (1000 * 60 * 60 * 24) < + parseInt(inputs.remind_before) && ( +
    +
    + warning +
    +
    +

    + Số ngày nhắc trước không được quá tổng thời gian kể + từ ngày bắt đầu giao bài cho đến ngày hết hạn. +

    +
    +
    + )} +
    +
    + )} +
    + + changeBeforeStart()} + id='beforestart' + checked={inputs.before_start_time ? true : false} + /> + + + +
    +
    +
    +
    + +
    +
    +
    + + ); +} + +export { AddStudentExercise }; diff --git a/src/_containers/TeacherPage/Class/AssignExercise/AssignExerciseSelection/AssignExerciseSelection.jsx b/src/_containers/TeacherPage/Class/AssignExercise/AssignExerciseSelection/AssignExerciseSelection.jsx new file mode 100644 index 0000000..84c48b3 --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/AssignExerciseSelection/AssignExerciseSelection.jsx @@ -0,0 +1,101 @@ +import React from "react"; +import _ from "lodash"; +import { Header } from "../../../../../_components/Admin/Header"; +import { assignSelectionLogic } from "./AssignExerciseSelection.logic"; +import "./AssignExerciseSelection.style.scss"; + +const AssignExerciseSelection = () => { + const { + typeSelected, + dataSelection, + navigateToSourcePage, + handleSubmit, + handleChecked, + } = assignSelectionLogic(); + + const renderListAssignSelection = (data) => { + return ( +
    handleChecked(data)} + > +
    +
    + Icon Item Selection +
    + {data.title} +
    +
    + +
    + + handleChecked(data)} + checked={typeSelected == data.type} + /> + + +
    +
    + +
    + {data.content} +
    +
    + ); + }; + + return ( +
    +
    navigateToSourcePage()} + /> + {/* {alert.message && + alert.screen === teacherConstants.SCREEN_ADD_STUDENT_EXERCISE && ( + + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/" + + exercise_id + ) + } + /> + )} */} +
    +
    + {dataSelection.map((data) => renderListAssignSelection(data))} +
    +
    + +
    + +
    +
    + ); +}; + +export default AssignExerciseSelection; diff --git a/src/_containers/TeacherPage/Class/AssignExercise/AssignExerciseSelection/AssignExerciseSelection.logic.js b/src/_containers/TeacherPage/Class/AssignExercise/AssignExerciseSelection/AssignExerciseSelection.logic.js new file mode 100644 index 0000000..32f9032 --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/AssignExerciseSelection/AssignExerciseSelection.logic.js @@ -0,0 +1,113 @@ +import React, { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { teacherActions } from "../../../../../_actions"; +import { useParams } from "react-router-dom"; +import { useHistory } from "react-router-dom"; +import { isEmpty, findIndex } from "lodash"; +import { TypeAssignExercise } from "../../../../../_constants/typeAssignExercise"; +import { teacherConstants } from "../../../../../_constants"; + +export const assignSelectionLogic = (props) => { + const history = useHistory(); + const _dispatch = useDispatch(); + const { id } = useParams(); + const authentication = useSelector((state) => state.authentication); + + const [typeSelected, setTypeSelected] = useState( + JSON.parse(localStorage.getItem("type_assign")) ?? "" + ); + + // Data Selection + const dataSelection = [ + { + id: 1, + title: "Giao bài theo năng lực", + content: + "Chỉ cần chọn thời lượng bài tập, Sunday English sẽ tự đề xuất những bài tập phù hợp nhất với năng lực từng học sinh của bạn ", + type: TypeAssignExercise.CAPACITY, + }, + { + id: 2, + title: "Giao bài theo yêu cầu", + content: + "Chọn kỹ năng, độ khó và số lượng bài tập cần giao và Sunday English sẽ tự động đề xuất bài tập thích hợp cho học sinh của bạn", + type: TypeAssignExercise.DEMAND, + }, + { + id: 3, + title: "Giao bài tự do", + content: + "Tự chọn những bài tập mong muốn giao cho học sinh trong các giáo trình của Sunday English và giáo trình cá nhân", + type: TypeAssignExercise.FREEDOM, + }, + ]; + + // Handle Navigate Back + const navigateToSourcePage = () => { + _dispatch({ + type: teacherConstants.CLEAR_ONLY_DATA_EXERCISES, + }); + history.push( + "/" + authentication.role + "/class/view/" + id + "/exercise/student" + ); + _dispatch({ + type: teacherConstants.GET_DATA_SETTING_ASSIGN, + setting: [], + }); + localStorage.removeItem("type_assign"); + }; + + // Handle Submit Continue + const handleSubmit = () => { + if (typeSelected) { + localStorage.setItem("type_assign", JSON.stringify(typeSelected)); + switch (typeSelected) { + case TypeAssignExercise.FREEDOM: + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/curriculum?assign=assign_freedom&page=classmanager" + + `&classId=${id}` + ); + break; + case TypeAssignExercise.DEMAND: + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/student/" + + TypeAssignExercise.DEMAND + ); + break; + case TypeAssignExercise.CAPACITY: + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/student/" + + TypeAssignExercise.CAPACITY + + "?page=capacity" + ); + break; + default: + } + } + }; + + // Handle Checked + const handleChecked = (data) => { + setTypeSelected(data?.type); + }; + + return { + dataSelection, + navigateToSourcePage, + handleSubmit, + typeSelected, + handleChecked, + }; +}; diff --git a/src/_containers/TeacherPage/Class/AssignExercise/AssignExerciseSelection/AssignExerciseSelection.style.scss b/src/_containers/TeacherPage/Class/AssignExercise/AssignExerciseSelection/AssignExerciseSelection.style.scss new file mode 100644 index 0000000..208e794 --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/AssignExerciseSelection/AssignExerciseSelection.style.scss @@ -0,0 +1,52 @@ +.selection_assign { + overflow: hidden; + .content_selection { + width: 100%; + // height: 82%; + max-height: 60rem; + overflow: auto; + padding-top: 1.5rem; + flex: 1; + .list_assign_selection { + width: 100%; + justify-content: space-evenly; + .item_assign_selection { + width: 42%; + max-width: 42%; + margin-bottom: 1.2rem; + background-color: var(--white-color); + border: 1px solid #e5e5e5; + padding: 1.2rem 1.3rem; + border-radius: 1rem; + min-height: 13.3rem; + .item_selection_header { + margin-bottom: 1.25rem; + .item_selection_header_left { + .icon_assign { + width: 1.6rem; + } + } + .item_selection_header_right { + .chk-custom-gr { + label { + &::before { + margin-right: 0 !important; + } + } + } + } + } + } + } + } + + .btn_continue_selection { + // right: 1.25rem; + // bottom: 1.5rem; + margin: 0.8rem 0 5px !important; + .btn-default { + width: 120px !important; + padding: 0 !important; + } + } +} diff --git a/src/_containers/TeacherPage/Class/AssignExercise/AssignSkills/AssignSkills.jsx b/src/_containers/TeacherPage/Class/AssignExercise/AssignSkills/AssignSkills.jsx new file mode 100644 index 0000000..32b0013 --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/AssignSkills/AssignSkills.jsx @@ -0,0 +1,86 @@ +import React from "react"; +import _ from "lodash"; +import { Header } from "../../../../../_components/Admin/Header"; +import "./AssignSkills.style.scss"; +import "../AssignExerciseSelection/AssignExerciseSelection.style.scss"; +import { Redirect, useParams } from "react-router-dom"; +import { TypeAssignExercise } from "../../../../../_constants/typeAssignExercise"; +import { useSelector } from "react-redux"; +import SkillsAssign from "../../../../../_components/SkillsAssign/SkillsAssign"; +import { assignSkillsLogic } from "./AssignSkills.logic"; + +const AssignSkills = () => { + let { + handleGoBack, + dataAssignSpecific, + setDataAssignSpecific, + handleSubmitSkills, + } = assignSkillsLogic(); + + const { id, type } = useParams(); + const authentication = useSelector((state) => state.authentication); + + // Redirect for not allow router + if (type != TypeAssignExercise.DEMAND) { + return ( + + ); + } + + return ( +
    +
    handleGoBack()} + /> +
    + {dataAssignSpecific?.lesson_list_propose && ( + + )} +
    + +
    + +
    +
    + ); +}; + +export default AssignSkills; diff --git a/src/_containers/TeacherPage/Class/AssignExercise/AssignSkills/AssignSkills.logic.js b/src/_containers/TeacherPage/Class/AssignExercise/AssignSkills/AssignSkills.logic.js new file mode 100644 index 0000000..a5da6ce --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/AssignSkills/AssignSkills.logic.js @@ -0,0 +1,132 @@ +import { history } from "../../../../../_helpers"; +import { useDispatch, useSelector } from "react-redux"; +import { useParams } from "react-router-dom"; +import { useEffect, useState } from "react"; +import { apiCaller } from "../../../../../_helpers"; +import { TypeAssignExercise } from "../../../../../_constants/typeAssignExercise"; +import { teacherService } from "../../../../../_services"; +import { teacherConstants } from "../../../../../_constants"; +import { floatObjectToArray } from "../../../../../_base/Validate"; +import { cloneDeep } from "lodash"; + +export const assignSkillsLogic = () => { + const { id, type } = useParams(); + const _dispatch = useDispatch(); + const authentication = useSelector((state) => state.authentication); + const exercises = useSelector((state) => state.classes.exercises); + + const dataReduxAssign = useSelector((state) => state.classes.setting_assign); + + // Variable Data Assign Specific for Assign Demand + const [dataAssignSpecific, setDataAssignSpecific] = useState( + cloneDeep(dataReduxAssign) + ); + + // Get Data Proposal + const getDataProposalDemand = async () => { + var body = new FormData(); + + body.append("list_student", JSON.stringify(exercises.students)); + body.append("id_class", id.toString()); + body.append("unit_learning_id", dataAssignSpecific.cur_unit.toString()); + body.append( + "setting_student", + JSON.stringify( + dataAssignSpecific.study_data.map( + ({ + practice_percent: practice_per, + study_percent: study_per, + ...rest + }) => ({ + practice_per, + study_per, + ...rest, + }) + ) + ) + ); + body.append( + "ingredient", + JSON.stringify(dataAssignSpecific?.lesson_list_propose) + ); + + const res = await teacherService.getDataAssignProposal("request", body); + + return res.data; + }; + + // Handle Go Back + const handleGoBack = () => { + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/student/" + + TypeAssignExercise.DEMAND + ); + }; + + // Handle Submit Skills + const handleSubmitSkills = async () => { + _dispatch({ + type: teacherConstants.GET_DATA_SETTING_ASSIGN, + setting: dataAssignSpecific, + }); + + const responseData = await getDataProposalDemand(); + + if (responseData) { + responseData.map( + (item) => + (item.exercise_suggest = floatObjectToArray(item.exercise_suggest)) + ); + _dispatch({ + type: teacherConstants.GET_DATA_ASSIGN_SPECIFIC, + proposal: responseData.map((item) => ({ + ...item, + exercise_suggest: item.exercise_suggest.map((exercise) => ({ + ...exercise, + user_id: item.user_id, + list_guide_id: [], + })), + })), + }); + + const dataExercise = responseData.reduce(function (accumulator, obj) { + return accumulator.concat( + obj.exercise_suggest.map((exercise) => ({ + ...exercise, + user_id: obj.user_id, + list_guide_id: [], + })) + ); + }, []); + + _dispatch({ + type: teacherConstants.ADD_DATA_EXERCISE, + data: { + ...exercises, + data_exercise: dataExercise, + }, + }); + } + + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/student/" + + type + + "/list_proposals" + ); + }; + + return { + dataAssignSpecific, + handleGoBack, + setDataAssignSpecific, + handleSubmitSkills, + }; +}; diff --git a/src/_containers/TeacherPage/Class/AssignExercise/AssignSkills/AssignSkills.style.scss b/src/_containers/TeacherPage/Class/AssignExercise/AssignSkills/AssignSkills.style.scss new file mode 100644 index 0000000..a5bb389 --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/AssignSkills/AssignSkills.style.scss @@ -0,0 +1,19 @@ +.skills_assign_container { + .content_selection { + width: 100%; + padding-top: 6.5vh; + padding-right: 0; + position: relative; + + .wh20.chk-custom-gr label:before { + padding: 10px; + } + .chk-custom-gr { + label { + &::before { + margin-right: 0 !important; + } + } + } + } +} diff --git a/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecific/AssignSpecific.jsx b/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecific/AssignSpecific.jsx new file mode 100644 index 0000000..f516388 --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecific/AssignSpecific.jsx @@ -0,0 +1,263 @@ +import React, { useEffect } from "react"; +import _ from "lodash"; +import { Header } from "../../../../../_components/Admin/Header"; +import { assignSpecificLogic } from "./AssignSpecific.logic"; +import "./AssignSpecific.style.scss"; +import "../AssignExerciseSelection/AssignExerciseSelection.style.scss"; +import { Redirect, useParams } from "react-router-dom"; +import { TypeAssignExercise } from "../../../../../_constants/typeAssignExercise"; +import CustomBarRange from "../../../../../_components/CustomBarRange/CustomBarRange"; +import { convertTitleAssign } from "../../../../../_base/Validate"; +import { useSelector } from "react-redux"; +import { Alert } from "../../../../../_components/Alert"; +import { teacherConstants } from "../../../../../_constants"; + +const AssignSpecific = () => { + const { + isLoading, + exercises, + handleSubmitAssignDemand, + handleGoBack, + dataAssignSpecific, + handleChangeUnit, + currUnit, + cantChangeUnit, + handleChangePercent, + cantChangeTime, + handleChangeTime, + currTimeMinute, + isLostRoot + } = assignSpecificLogic(); + + const { id, type } = useParams(); + const authentication = useSelector((state) => state.authentication); + const alert = useSelector((state) => state.alert); + + const renderListRangeStudy = (data) => { + return ( + handleChangePercent(data, value)} + levelSkills={dataAssignSpecific?.level_skill} + isLostRoot={isLostRoot} + /> + ); + }; + + const renderListStandardSkill = (data, index, dataParent) => { + const lengthParent = dataParent.length; + return ( +
    +
    + {data.skill.capitalize()} +
    +
    + {convertTitleAssign(data.level)} +
    +
    + ); + }; + + if ( + ![TypeAssignExercise.DEMAND, TypeAssignExercise.CAPACITY].includes(type) + ) { + return ( + + ); + } + + return ( +
    +
    handleGoBack()} + /> + {alert.message && + alert.screen == teacherConstants.SCREEN_ASSIGN_SETTING && ( + + )} + {dataAssignSpecific?.cur_unit && !isLoading ? ( +
    +
    +
    Unit đang học
    +
    + + +
    + Unit {currUnit} +
    + + +
    +
    + {type == TypeAssignExercise.CAPACITY && ( +
    +
    + Thời lượng mong muốn +
    +
    + + +
    + {currTimeMinute} phút +
    + + +
    +
    + )} + +
    +
    Tỷ lệ kiến thức
    + +
    + * Kéo thanh gạt để chọn tỷ lệ ôn luyện kiến thức đã học và kiến + thức mới theo trình độ của từng kỹ năng. +
    + +
    +
    + {isLostRoot ? renderListRangeStudy(dataAssignSpecific?.study_data?.[0]) : dataAssignSpecific?.study_data?.map((data) => + renderListRangeStudy(data) + )} +
    + + {/* {Array.isArray(exercises?.students) && + exercises?.students.length == 1 && ( +
    +
    +
    +
    + Kỹ năng +
    +
    + Trình độ +
    +
    +
    + {Array.isArray(dataAssignSpecific?.level_skill) && + dataAssignSpecific?.level_skill?.map((data, index) => + renderListStandardSkill( + data, + index, + dataAssignSpecific?.level_skill + ) + )} +
    +
    +
    + )} */} +
    +
    +
    + ) : ( +
    + )} + +
    + +
    +
    + ); +}; + +export default AssignSpecific; diff --git a/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecific/AssignSpecific.logic.js b/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecific/AssignSpecific.logic.js new file mode 100644 index 0000000..ad78265 --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecific/AssignSpecific.logic.js @@ -0,0 +1,384 @@ +import { history } from "../../../../../_helpers"; +import { useDispatch, useSelector } from "react-redux"; +import { useParams } from "react-router-dom"; +import { useEffect, useState } from "react"; +import { apiCaller } from "../../../../../_helpers"; +import { TypeAssignExercise } from "../../../../../_constants/typeAssignExercise"; +import { teacherService } from "../../../../../_services"; +import { teacherConstants } from "../../../../../_constants"; +import { floatObjectToArray } from "../../../../../_base/Validate"; +import { alertActions } from "../../../../../_actions"; + +export const assignSpecificLogic = (props) => { + const { id, type } = useParams(); + + const _dispatch = useDispatch(); + const authentication = useSelector((state) => state.authentication); + const exercises = useSelector((state) => state.classes.exercises); + + // Variable Data Assign Specific for Assign Demand + const [dataAssignSpecific, setDataAssignSpecific] = useState( + useSelector((state) => state.classes.setting_assign) + ); + + const [studySetting, setStudySetting] = useState( + dataAssignSpecific?.study_data || [] + ) + + const [isLoading, setLoading] = useState(false); + + // Data Setting for assign + const [currUnit, setCurrUnit] = useState( + parseInt(dataAssignSpecific?.cur_unit) || 1 + ); + + const [totalUnit, setTotalUnit] = useState( + dataAssignSpecific?.total_unit || 12 + ); + + const [currTimeMinute, setCurrTimeMinute] = useState( + dataAssignSpecific?.expected_time || 30 + ); + + const [cantChangeUnit, setCantChangeUnit] = useState( + currUnit == 1 ? "prev" : currUnit == totalUnit ? "next" : "" + ); + + // Capacity + const [cantChangeTime, setCantChangeTime] = useState( + currTimeMinute == 10 ? "prev" : currTimeMinute == 180 ? "next" : "" + ); + + // check GTHN + const [isLostRoot, setIsLostRoot] = useState(!!dataAssignSpecific?.is_lost_root || false) + + // GET Data Setting for assign + const getDataSetting = async () => { + setLoading(true); + const res = await teacherService.getDataAssignSetting( + id, + JSON.stringify(exercises.students) + ); + if (res?.status) { + const data = res.data; + data["expected_time"] = currTimeMinute; + let transformData = {} + + const newStudyData = swapPositionArr(data?.study_data, 0, 2)?.map(item => { + if(!!data?.is_lost_root) { + return { + ...item, + practice_percent: 100, + study_percent: 0, + } + } + return item + }); + + if(!!data?.is_lost_root) { + transformData = { + ...data, + study_data: newStudyData, + lesson_list_propose: data?.lesson_list_propose?.map(item => { + if(item?.skill === "vocabulary" || item?.skill === "grammar") { + return item + } + return null + }).filter(item => !!item), + level_skill: [] + } + } else { + transformData = { + ...data, + study_data: newStudyData, + }; + } + + _dispatch({ + type: teacherConstants.GET_DATA_SETTING_ASSIGN, + setting: transformData, + }); + + setIsLostRoot(!!data?.is_lost_root) + setLoading(false); + setStudySetting(newStudyData) + setDataAssignSpecific(transformData); + setCurrUnit(parseInt(data.cur_unit)); + setTotalUnit(parseInt(data.total_unit)); + setCantChangeUnit( + parseInt(data.cur_unit) == 1 + ? "prev" + : parseInt(data.cur_unit) == parseInt(data.total_unit) + ? "next" + : "" + ); + } else { + _dispatch( + alertActions.error({ + message: res, + screen: teacherConstants.SCREEN_ASSIGN_SETTING, + }) + ); + } + }; + + useEffect(() => { + !dataAssignSpecific?.cur_unit && getDataSetting(); + }, []); + + useEffect(() => { + if (currUnit == totalUnit) { + setDataAssignSpecific((data) => ({ + ...data, + cur_unit: currUnit, + study_data: dataAssignSpecific.study_data.map((ele) => { + return { + ...ele, + practice_percent: 100, + study_percent: 0, + }; + }), + })) + } else { + setDataAssignSpecific((data) => ({ + ...data, + cur_unit: currUnit, + study_data: studySetting, + })) + } + }, [currUnit]) + + // Get Data Proposal + const getDataProposalCapacity = async () => { + var body = new FormData(); + const studyData = swapPositionArr(dataAssignSpecific?.study_data, 0, 2); + + body.append("list_student", JSON.stringify(exercises.students)); + body.append("id_class", id.toString()); + body.append("unit_learning_id", dataAssignSpecific.cur_unit.toString()); + body.append("setting_student", JSON.stringify(studyData)); + body.append( + "desired_time", + JSON.stringify(dataAssignSpecific.expected_time) + ); + + const res = await teacherService.getDataAssignProposal("capacity", body); + + return res.data; + }; + + // Handle Go Back + const handleGoBack = () => { + _dispatch({ + type: teacherConstants.CLEAR_ONLY_DATA_EXERCISES, + }); + localStorage.setItem("typeCurrExercise", "sunday"); + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/student/selection_assign" + ); + }; + + // Handle Submit Assign Demand + const handleSubmitAssignDemand = async () => { + _dispatch({ + type: teacherConstants.GET_DATA_SETTING_ASSIGN, + setting: dataAssignSpecific, + }); + + if (type == TypeAssignExercise.DEMAND) { + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/student/" + + type + + "/skills" + ); + } else if (type == TypeAssignExercise.CAPACITY) { + const responseData = await getDataProposalCapacity(); + if (responseData) { + responseData.map( + (item) => + (item.exercise_suggest = floatObjectToArray(item.exercise_suggest)) + ); + + _dispatch({ + type: teacherConstants.GET_DATA_ASSIGN_SPECIFIC, + proposal: responseData.map((item) => ({ + ...item, + exercise_suggest: item.exercise_suggest.map((exercise) => ({ + ...exercise, + user_id: item.user_id, + list_guide_id: [], + })), + isRoot: true + })), + }); + + const dataExercise = responseData.reduce(function (accumulator, obj) { + return accumulator.concat( + obj.exercise_suggest.map((exercise) => ({ + ...exercise, + user_id: obj.user_id, + list_guide_id: [], + })) + ); + }, []); + + _dispatch({ + type: teacherConstants.ADD_DATA_EXERCISE, + data: { + ...exercises, + data_exercise: dataExercise, + }, + }); + } + + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/student/" + + type + + "/list_proposals" + ); + } + }; + + // Handle Change Unit + const handleChangeUnit = (type) => { + switch (type) { + case "prev": + if (currUnit > 1) { + setCurrUnit(currUnit - 1); + setDataAssignSpecific((data) => ({ + ...data, + cur_unit: currUnit - 1, + })); + } + if (currUnit - 1 <= 1) { + setCantChangeUnit("prev"); + } else { + setCantChangeUnit(""); + } + break; + case "next": + if (currUnit < totalUnit) { + setCurrUnit(currUnit + 1); + if (currUnit + 1 == totalUnit) { + setDataAssignSpecific((data) => ({ + ...data, + cur_unit: currUnit + 1, + study_data: dataAssignSpecific.study_data.map((ele) => { + return { + ...ele, + practice_percent: 100, + study_percent: 0, + }; + }), + })); + } else { + setDataAssignSpecific((data) => ({ + ...data, + cur_unit: currUnit + 1, + })); + } + } + if (currUnit + 1 >= totalUnit) { + setCantChangeUnit("next"); + } else { + setCantChangeUnit(""); + } + break; + default: + } + }; + + // Handle Change Time + const handleChangeTime = (type) => { + switch (type) { + case "prev": + if (currTimeMinute > 10) { + setCurrTimeMinute(currTimeMinute - 10); + setDataAssignSpecific((data) => ({ + ...data, + expected_time: currTimeMinute - 10, + })); + } + if (currTimeMinute - 10 <= 10) { + setCantChangeTime("prev"); + } else { + setCantChangeTime(""); + } + break; + case "next": + if (currTimeMinute < 180) { + setCurrTimeMinute(currTimeMinute + 10); + setDataAssignSpecific((data) => ({ + ...data, + expected_time: currTimeMinute + 10, + })); + } + if (currTimeMinute + 10 >= 180) { + setCantChangeTime("next"); + } else { + setCantChangeTime(""); + } + break; + default: + } + }; + + // Handle Change Percent + const handleChangePercent = (data, value) => { + if (value <= 100 && value >= 0) { + let newStudyData = dataAssignSpecific.study_data; + if(isLostRoot) { + newStudyData.forEach((item) => { + item.practice_percent = value; + item.study_percent = 100 - value; + }); + } else { + newStudyData.forEach((item) => { + if (item.stand == data.stand) { + item.practice_percent = value; + item.study_percent = 100 - value; + } + }); + } + setDataAssignSpecific((data) => ({ ...data, study_data: newStudyData })); + setStudySetting(newStudyData) + } + }; + + return { + isLoading, + exercises, + cantChangeTime, + currUnit, + cantChangeUnit, + dataAssignSpecific, + currTimeMinute, + handleSubmitAssignDemand, + setDataAssignSpecific, + handleChangeUnit, + handleChangePercent, + handleGoBack, + handleChangeTime, + isLostRoot + }; +}; + +const swapPositionArr = (arr, indexA, indexB) => { + const newArr = [...arr]; + var temp = newArr[indexA]; + newArr[indexA] = newArr[indexB]; + newArr[indexB] = temp; + return newArr; +}; diff --git a/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecific/AssignSpecific.style.scss b/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecific/AssignSpecific.style.scss new file mode 100644 index 0000000..1083099 --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecific/AssignSpecific.style.scss @@ -0,0 +1,94 @@ +.assign_specific_container { + // height: 100%; + overflow: auto; + overflow-x: hidden; + .content_selection { + width: 100%; + margin: 0 auto; + padding-top: 3vh; + padding-left: 1rem; + overflow: auto; + padding-right: 6%; + margin-right: -0.7rem; + flex: 1; + + .content_unit { + padding: 0.9rem 0; + + .text_unit { + min-width: 8rem; + text-align: center; + } + } + + .btn_unit_container { + .btn { + border-radius: 50%; + background-color: #00e2a0; + border: none; + outline: none; + width: 2rem; + height: 2rem; + + img { + height: 70%; + } + } + } + + .content_rate { + padding: 1.2rem 0 0; + + .content_rate_desc { + font-style: italic; + margin: 0.6rem 0rem 0; + } + + .list_range_study { + width: 68%; + max-width: 68%; + padding-right: 0.8rem; + } + + .list_standard_skill { + width: 52%; + max-width: 52%; + height: 100%; + + .standard_skill_container { + width: 84%; + max-width: 84%; + background-color: var(--white-color); + border-radius: 0.8rem; + padding: 0.9rem 1.5rem 0.6rem; + min-height: 75%; + margin-bottom: 0.3rem; + + .standard_skill_item { + padding: 0.2rem 0 0.4rem; + + div { + line-height: normal; + } + } + + .title_standard { + background-color: var(--light-red-color); + margin-right: 3%; + border-radius: 0.5rem; + padding: 0.4rem 0; + } + + .title_standard_right { + margin-right: 0; + margin-left: 3%; + } + } + } + } + } + + .content_selection_capacity { + padding-top: 1.7vh; + } +} diff --git a/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecificProposal/AssignSpecificProposal.jsx b/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecificProposal/AssignSpecificProposal.jsx new file mode 100644 index 0000000..a68bdcb --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecificProposal/AssignSpecificProposal.jsx @@ -0,0 +1,420 @@ +import React from "react"; +import _, { isEmpty } from "lodash"; +import { Header } from "../../../../../_components/Admin/Header"; +import "./AssignSpecificProposal.style.scss"; +import "../AssignExerciseSelection/AssignExerciseSelection.style.scss"; +import { Link, Redirect, useParams } from "react-router-dom"; +import { TypeAssignExercise } from "../../../../../_constants/typeAssignExercise"; +import { useSelector } from "react-redux"; +import SkillsAssign from "../../../../../_components/SkillsAssign/SkillsAssign"; +import { assignProposalLogic } from "./AssignSpecificProposal.logic"; +import { PopUpYesNo } from "../../../../../_components/Popup"; +import classnames from "classnames"; +import { configConstants, teacherConstants } from "../../../../../_constants"; +import { history } from "../../../../../_helpers"; +import { Alert } from "../../../../../_components/Alert"; +import { userConstants } from "../../../../../_constants"; +import { useDispatch } from "react-redux"; +import { cloneDeep } from "lodash"; + +const AssignSpecificStudents = (props) => { + const { id, type } = useParams(); + const authentication = useSelector((state) => state.authentication); + const alert = useSelector((state) => state.alert); + const _dispatch = useDispatch(); + + let { + dataReduxAssign, + isScrollable, + checkScroll, + dataProposal, + dataAssignSpecific, + setDataAssignSpecific, + handleGoBack, + handleOpenModalSkill, + handleConfirmApply, + studentSelected, + handleSelectStudent, + handleDeleteLesson, + openModalSide, + setOpenModalSide, + handleCheckDelete, + handleCheckEmptyExercise, + handleAssignHomework, + } = assignProposalLogic(props); + + // Function to calculate the total time for a user + const calculateTotalTime = (user) => { + return user?.exercise_suggest.reduce( + (total, exercise) => total + Number.parseFloat(exercise?.total_time), + 0 + ); + }; + + const EditComponent = () => { + return ( +
    + +
    + ); + }; + + // Render List Lesson assign + const renderListLesson = (item) => { + return ( +
    + + + {item.level ? item.level == "normal" ? "Medium" : item?.level?.capitalize() : ''} + +
    } +
    + {item?.topic || item?.lesson_topic} +
    + + +
    + {item?.lesson_name} +
    +
    + {item?.curriculum_name} +
    + +
    +
    + ico_file +
    + + {isEmpty(item?.list_guide_id) ? ( +
    + Chưa có file hướng dẫn +
    + ) : ( +
    + Đã có file hướng dẫn +
    + )} +
    + + +
    handleCheckDelete(item)} + > + Icon Delete +
    + + ); + }; + + // Render List Proposal students + const renderListProposal = (data) => { + return ( +
    +
    handleSelectStudent(data)} + > +
    +
    + Img Avt +
    + +
    +
    + {data.fullname} ( + {Math.round(data?.isRoot ? data?.minute_finish : Number.parseFloat(calculateTotalTime(data)))} phút) +
    +
    {data.email}
    +
    +
    + +
    + + + +
    +
    + {studentSelected == data.user_id && ( + <> +
    + {data?.exercise_suggest?.map((item) => renderListLesson(item))} +
    + +
    + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/curriculum?assign=" + + type + + "&user_id=" + + data.user_id + // + + // "&page=classmanager" + ) + } + > +
    +
    + Icon Edit +
    +
    + Thêm bài tập +
    +
    +
    + + )} +
    + ); + }; + + return ( +
    +
    } + clickBack={() => handleGoBack()} + /> +
    + {dataProposal && dataProposal?.map((data) => renderListProposal(data))} +
    + +
    + +
    + + {(openModalSide == "modalSkills" || openModalSide == "modalApply") && ( + + )} + + {openModalSide == "modalApply" && ( + handleConfirmApply()} + onClickNo={() => setOpenModalSide("modalSkills")} + labelNo={"Hủy"} + labelYes={"Đồng ý"} + message={ + "Hệ thống sẽ đề xuất danh sách bài tập mới, những thay đổi trước đó của bạn sẽ không được giữ lại." + } + /> + )} + + {openModalSide == "modalDelete" && ( + handleDeleteLesson()} + onClickNo={() => setOpenModalSide("")} + labelNo={"Hủy"} + labelYes={"Xóa"} + message={"Bạn có chắc chắn muốn xóa bài tập này ra khỏi danh sách?"} + /> + )} + + {alert.message && + alert.screen === teacherConstants.SCREEN_ASSIGN_HOME_WORK && ( + { + history.push( + "/" + authentication.role + "/class/view/" + id + "/exercise" + ); + _dispatch({ + type: teacherConstants.RESET_DATA_EXERCISE, + }); + _dispatch({ + type: teacherConstants.CLEAR_DATA_EXERCISES, + }); + }} + /> + )} +
    + ); +}; + +export default AssignSpecificStudents; diff --git a/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecificProposal/AssignSpecificProposal.logic.js b/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecificProposal/AssignSpecificProposal.logic.js new file mode 100644 index 0000000..2667027 --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecificProposal/AssignSpecificProposal.logic.js @@ -0,0 +1,371 @@ +import { history } from "../../../../../_helpers"; +import { useDispatch, useSelector } from "react-redux"; +import { useParams } from "react-router-dom"; +import { useEffect, useState, useRef } from "react"; +import { TypeAssignExercise } from "../../../../../_constants/typeAssignExercise"; +import { teacherService } from "../../../../../_services"; +import { teacherConstants } from "../../../../../_constants"; +import { floatObjectToArray } from "../../../../../_base/Validate"; +import { useLocation } from "react-router-dom"; +import { alertActions } from "../../../../../_actions"; +import { cloneDeep } from "lodash"; + +export const assignProposalLogic = (props) => { + const _location = useLocation(); + const { id, type } = useParams(); + const _dispatch = useDispatch(); + const authentication = useSelector((state) => state.authentication); + const exercises = useSelector((state) => state.classes.exercises); + + // Variable Date Add Student Exercise from start choose students + const dateAddStudentExercise = useSelector( + (state) => state.classes.dateAddStudentExercise + ); + + const userIDSelected = _location?.state?.userIDSelected; + + // Data Assign Proposal + const dataAssignProposal = useSelector( + (state) => state.classes.data_assign_proposal + ); + + const resultDataProposal = dataAssignProposal?.map((data) => { + const exercise_suggest = data?.exercise_suggest?.map( + (item) => { + if (item?.total_time) { + return { + ...item, + lesson_id: item?.lesson_id || item?.exam_id + }; + } + const exercise = exercises?.data_exercise?.find( + (ex) => ex?.lesson_id == item?.lesson_id + ); + if (exercise) { + return { + ...item, + lesson_id: item?.lesson_id || item?.exam_id, + total_time: exercise?.total_time + }; + } + return { + ...item, + lesson_id: item?.lesson_id || item?.exam_id + }; + } + ); + return { + ...data, + exercise_suggest, + } + }); + const [dataProposal, setDataProposal] = useState(resultDataProposal); + + const dataReduxAssign = useSelector((state) => state.classes.setting_assign); + + const [dataAssignSpecific, setDataAssignSpecific] = useState( + cloneDeep(dataReduxAssign) + ); + + // Selected Student + const [studentSelected, setStudentSelected] = useState(userIDSelected); + + // Lesson Selected + const [lessonSelected, setLessonSelected] = useState(); + + // Get Data Proposal + const getDataProposal = async () => { + var body = new FormData(); + + body.append("list_student", JSON.stringify(exercises.students)); + body.append("id_class", id.toString()); + body.append("unit_learning_id", dataAssignSpecific.cur_unit.toString()); + + type == TypeAssignExercise.DEMAND + ? body.append( + "setting_student", + JSON.stringify( + dataAssignSpecific.study_data.map( + ({ + practice_percent: practice_per, + study_percent: study_per, + ...rest + }) => ({ + practice_per, + study_per, + ...rest, + }) + ) + ) + ) + : body.append( + "setting_student", + JSON.stringify(dataAssignSpecific.study_data) + ); + + type == TypeAssignExercise.DEMAND + ? body.append( + "ingredient", + JSON.stringify(dataAssignSpecific?.lesson_list_propose) + ) + : body.append( + "desired_time", + JSON.stringify(dataAssignSpecific.expected_time) + ); + + const res = await teacherService.getDataAssignProposal( + type == TypeAssignExercise.DEMAND ? "request" : "capacity", + body + ); + + return res.data; + }; + + // Handle Open Modal Skill + const handleOpenModalSkill = () => { + setOpenModalSide("modalSkills"); + }; + + // Handle Go Back + const handleGoBack = () => { + if (type == TypeAssignExercise.DEMAND) { + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/student/" + + type + + "/skills" + ); + } else if (type == TypeAssignExercise.CAPACITY) { + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/student/" + + type + ); + } + }; + + // Variable Open Popup + const [openModalSide, setOpenModalSide] = useState(""); + + // Handle Confirm Apply + const handleConfirmApply = async () => { + setOpenModalSide(""); + const responseData = await getDataProposal(); + + if (responseData) { + responseData.map( + (item) => + (item.exercise_suggest = floatObjectToArray(item.exercise_suggest)) + ); + _dispatch({ + type: teacherConstants.GET_DATA_ASSIGN_SPECIFIC, + proposal: responseData.map((item) => ({ + ...item, + exercise_suggest: item.exercise_suggest.map((exercise) => ({ + ...exercise, + user_id: item.user_id, + list_guide_id: [], + })), + })), + }); + const resultDataProposal = responseData?.map((data) => { + const exercise_suggest = data?.exercise_suggest?.map( + (item) => { + if (item?.total_time) { + return item; + } + const exercise = exercises?.data_exercise?.find( + (ex) => ex?.lesson_id == item?.lesson_id + ); + if (exercise) { + const newItem = { ...item }; + newItem.total_time = exercise?.total_time; + return newItem; + } + return item; + } + ); + return { + ...data, + exercise_suggest, + } + }); + setDataProposal(resultDataProposal); + } + }; + + // Handle Select Student + const handleSelectStudent = (data) => { + data.user_id == studentSelected + ? setStudentSelected("") + : setStudentSelected(data.user_id); + }; + + // Handle Check Delete + const handleCheckDelete = (item) => { + setLessonSelected(item); + setOpenModalSide("modalDelete"); + }; + + // Handle Delete Lesson + const handleDeleteLesson = async () => { + setOpenModalSide(""); + const studentLessonDelete = dataProposal.filter( + (item) => item.user_id == studentSelected + ); + + const [objStudentLessonDelete] = studentLessonDelete; + + const newObjStudentLess = objStudentLessonDelete.exercise_suggest.filter( + (item) => item.lesson_id != lessonSelected.lesson_id + ); + + objStudentLessonDelete["exercise_suggest"] = newObjStudentLess; + objStudentLessonDelete["isRoot"] = false; + + const newDataProposal = dataProposal; + newDataProposal.forEach((item, index, dataOriginal) => { + if (item.user_id == objStudentLessonDelete.user_id) { + dataOriginal[index] = objStudentLessonDelete; + } + }); + + setDataProposal(newDataProposal); + + // const dataExercise = newDataProposal.reduce(function (accumulator, obj) { + // return accumulator.concat(obj.exercise_suggest); + // }, []); + + // Create data exercise side + const dataExercise = exercises.data_exercise; + + const newDataExercise = dataExercise.filter( + (item_filter) => item_filter.lesson_id != lessonSelected.lesson_id + ); + + const dataLessonSelected = exercises.data_lessons_selected; + + const newDataLessonSelected = dataLessonSelected.filter( + (item_filter) => item_filter?.lesson_id != lessonSelected?.lesson_id + ); + + _dispatch({ + type: teacherConstants.ADD_DATA_EXERCISE, + data: { + ...exercises, + start_time: dateAddStudentExercise.start_time, + end_time: dateAddStudentExercise.end_time, + data_exercise: newDataExercise, + data_lessons_selected: newDataLessonSelected, + }, + }); + + _dispatch({ + type: teacherConstants.GET_DATA_ASSIGN_SPECIFIC, + proposal: newDataProposal, + }); + }; + + // Handle check empty exercise + const handleCheckEmptyExercise = () => { + return dataAssignProposal?.every( + (item) => item.exercise_suggest.length <= 0 + ); + }; + + // Handle Submit Assign + const handleAssignHomework = async () => { + const exercise_per_hs = dataProposal.map((data, index) => ({ + user_id: data?.user_id, + exercise_suggest: data?.exercise_suggest.map((item) => ({ + exercise_id: item?.lesson_id, + exercise_type: item?.lesson_type, + start_time: item?.start_time || dateAddStudentExercise?.start_time, + end_time: item?.end_time || dateAddStudentExercise?.end_time, + curriculum_id: item?.curriculum_id, + unit_id: item?.unit_id, + list_guide_id: JSON.stringify(item.list_guide_id), + })), + })); + + const bodyAssign = { + class_id: id.toString(), + students: exercises.students, + start_time: dateAddStudentExercise?.start_time, + end_time: dateAddStudentExercise?.end_time, + remind_before: exercises.remind_before, + note: exercises.note, + before_start_time: exercises.before_start_time, + exercise_per_hs: exercise_per_hs, + }; + + const res = await teacherService.postAssignSpecific(bodyAssign); + + if (res.status) { + _dispatch( + alertActions.success({ + message: res.msg.toString(), + screen: teacherConstants.SCREEN_ASSIGN_HOME_WORK, + }) + ); + } else { + _dispatch( + alertActions.error({ + message: res.msg.toString(), + screen: teacherConstants.SCREEN_ASSIGN_HOME_WORK, + }) + ); + } + }; + + const [isScrollable, setIsScrollable] = useState(false); + const checkScroll = useRef(null); + + // check scroll ability and change state + useEffect(() => { + const checkScrollAbility = () => { + if (checkScroll.current) { + const div = checkScroll.current; + if (div.scrollHeight > div.clientHeight) { + setIsScrollable(true); + } else { + setIsScrollable(false); + } + } + }; + + window.addEventListener("resize", checkScrollAbility); + + setTimeout(checkScrollAbility, 500); + + return () => { + window.removeEventListener("resize", checkScrollAbility); + }; + }, []); + + return { + dataReduxAssign, + isScrollable, + checkScroll, + dataProposal, + dataAssignSpecific, + setDataAssignSpecific, + handleGoBack, + handleOpenModalSkill, + handleConfirmApply, + studentSelected, + handleSelectStudent, + handleDeleteLesson, + openModalSide, + setOpenModalSide, + handleCheckDelete, + handleCheckEmptyExercise, + handleAssignHomework, + }; +}; diff --git a/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecificProposal/AssignSpecificProposal.style.scss b/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecificProposal/AssignSpecificProposal.style.scss new file mode 100644 index 0000000..88a4745 --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/AssignSpecificProposal/AssignSpecificProposal.style.scss @@ -0,0 +1,164 @@ +.skills_assign_container { + .content_selection { + padding-top: 0; + margin-top: 4vh; + padding-right: 4.8%; + margin-right: -14px; + + .proposal_item { + background-color: var(--white-color); + + .proposal_header { + border: 1px solid #cccccc; + background-color: var(--white-color); + width: 100%; + padding: 0.8rem 0.9rem; + padding-right: 1.2rem; + + .img_avt_container { + border-radius: 50%; + background-color: var(--white-color); + width: 4.2rem; + height: 4.2rem; + + img { + border-radius: 50%; + // padding: 0.28rem; + object-fit: cover; + width: 100%; + height: 100%; + border: 0.25rem solid var(--white-color); + } + } + } + + .lesson_item { + padding: 1.1rem 0.9rem; + padding-right: 0; + background-color: #f3ffff; + border-bottom: 1px solid #e5e5e5; + border-left: 1px solid #e5e5e5; + border-right: 1px solid #e5e5e5; + + .lesson_content { + width: 100%; + max-width: 100%; + + .lesson_content_text { + width: 85%; + max-width: 85%; + } + } + + .img_lesson { + img { + width: 3.4rem; + height: 3.4rem; + min-width: 3.4rem; + border-radius: 0.5rem; + } + } + + .title_level { + min-width: 3.9rem; + height: 1.25rem; + border-radius: 1rem; + top: 0; + margin-right: 0.55rem; + } + + .title_lesson { + color: #00a69c; + top: 0.12rem; + } + + .lesson_name { + color: #00a69c; + } + + .ico_delete_lesson { + bottom: 1rem; + right: 1rem; + z-index: 9; + + img { + width: 1.35rem; + z-index: 9; + } + } + } + + .add_lesson_container { + margin: 0; + padding: 1.1rem 0; + background-image: linear-gradient(to right, #00b9b7, #00e1a0); + cursor: pointer; + + &:hover { + background: #00c0b4; + color: #ffffff; + } + + .btn_add_lesson { + background-color: transparent; + border: none; + + .img_add_container { + width: 1.25rem; + } + } + } + } + } + + .edit_container { + margin-right: 0.75rem; + + .img_edit_container { + position: relative; + top: -0.15rem; + margin-right: 0.4rem; + + img { + width: 1.45rem; + } + } + } + + .modal_skills_container { + width: 72%; + min-width: 50rem; + max-width: 100rem; + // min-height: 40rem; + height: 98%; + max-height: 46rem; + background-color: var(--white-color); + border-radius: 1rem; + padding: 0 0.75% 1.5% 4.6%; + justify-content: space-between; + flex-direction: column; + + .btn_action_container { + margin: 0; + text-align: center; + padding-top: 2%; + + .btn_action { + text-align: center; + width: 9rem; + min-width: 9rem; + margin: 0 4%; + } + } + } + + .modal_skills_container_lost_root { + width: unset; + min-width: unset; + max-width: unset; + // min-height: 40rem; + height: unset; + max-height: unset; + padding: 30px 20px 50px; + } +} \ No newline at end of file diff --git a/src/_containers/TeacherPage/Class/AssignExercise/DetailSkilAssign/DetailSkillAssign.jsx b/src/_containers/TeacherPage/Class/AssignExercise/DetailSkilAssign/DetailSkillAssign.jsx new file mode 100644 index 0000000..331f4e0 --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/DetailSkilAssign/DetailSkillAssign.jsx @@ -0,0 +1,221 @@ +import React, { useEffect, useLayoutEffect, useRef, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { useParams, Link, useLocation } from "react-router-dom"; +import { Header } from "../../../../../_components/Admin/Header"; +import { teacherConstants } from "../../../../../_constants"; +import { useHistory } from "react-router-dom"; +import moment from "moment"; +import { SelectDate } from "../../../../../_components/Calendar"; +import { detailSkillAssignLogic } from "./DetailSkillAssign.logic"; + +function DetailSkillAssign() { + const exercises = useSelector((state) => state.classes.exercises); + + let { + skill_key, + isEdit, + inputs, + originListFileId, + deletedItem, + stateReceived, + getPrevTime, + originAttachFile, + skill, + listFileId, + listFileIdCopy, + setIsEdit, + setInputs, + handleBack, + validateParam, + handleSubmit, + handleChangeDate, + removeFile, + dispatch, + handleGoListSupport + } = detailSkillAssignLogic(); + + const history = useHistory(); + + const authentication = useSelector((state) => state.authentication); + const { id, type, lesson_id } = useParams(); + + const search = history?.location?.search; + const params = new URLSearchParams(search); + const userID = params.get("user_id"); + + return ( +
    +
    +
    +
    +
    +

    + {skill?.detail?.lesson_name || skill?.lesson_name} +

    +

    + {skill?.detail?.lesson_topic || skill?.topic} +

    +

    + {skill?.curriculum_name} >> {skill?.unit_name} >>{" "} + {skill?.exercise_type?.capitalize() || + skill?.lesson_type?.capitalize()}{" "} +

    +
    +
    +

    Thời gian làm bài

    +
    +
    +
    + +
    inputs.end_time ? " err" : "") + } + > + { + if ( + new Date(start_time) <= new Date(inputs.end_time) && + new Date(start_time) >= moment(new Date()).startOf("day") + ) { + setIsEdit(true); + setInputs((inputs) => ({ + ...inputs, + start_time: + moment(start_time).format("YYYY-MM-DD") || + inputs.start_time, + })); + dispatch({ + type: teacherConstants.ADD_TIME_TO_CHOOSE_FILE_SCREEN, + data: { + start_time: moment(start_time).format("YYYY-MM-DD"), + end_time: inputs.end_time, + }, + }); + } + }} + /> +
    +
    +
    +
    +
    + +
    inputs.end_time ? " err" : "") + } + > + { + if (new Date(inputs.start_time) <= new Date(end_time)) { + setIsEdit(true); + setInputs((inputs) => ({ + ...inputs, + end_time: + moment(end_time).format("YYYY-MM-DD") || + inputs.end_time, + })); + dispatch({ + type: teacherConstants.ADD_TIME_TO_CHOOSE_FILE_SCREEN, + data: { + start_time: inputs.start_time, + end_time: moment(end_time).format("YYYY-MM-DD"), + }, + }); + } + }} + /> +
    +
    +
    +
    +
    +
    +

    File Hướng dẫn

    +
    + +

    Thêm hướng dẫn

    +
    + +
    +
    + {(listFileId || []).map((data, i) => { + return ( +
    +
    +
    +
    + ico_file +
    +
    + {data.title} +
    +
    +
    +
    + ico_remove_blue removeFile(i)} + /> +
    +
    + ); + })} +
    +
    +
    + +
    + + ); +} + +export default DetailSkillAssign; diff --git a/src/_containers/TeacherPage/Class/AssignExercise/DetailSkilAssign/DetailSkillAssign.logic.js b/src/_containers/TeacherPage/Class/AssignExercise/DetailSkilAssign/DetailSkillAssign.logic.js new file mode 100644 index 0000000..32a476c --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/DetailSkilAssign/DetailSkillAssign.logic.js @@ -0,0 +1,282 @@ +import { useState, useEffect } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { teacherConstants } from "../../../../../_constants"; +import { useHistory, useLocation, useParams } from "react-router-dom"; + +export const detailSkillAssignLogic = (props) => { + const dispatch = useDispatch(); + const history = useHistory(); + const search = history?.location?.search; + const params = new URLSearchParams(search); + const userID = params.get("user_id"); + const authentication = useSelector((state) => state.authentication); + + const dataProposal = useSelector( + (state) => state.classes.data_assign_proposal + ); + + const { id, type, lesson_id } = useParams(); + const exercises = useSelector((state) => state.classes.exercises); + let temp_exercises_data_exercise = exercises.data_exercise; + const skillArray = exercises.data_exercise.filter( + (item) => item.lesson_id == lesson_id && item.user_id == userID + ); + + // Data Add student in exercise + const dateAddStudentExercise = useSelector( + (state) => state.classes.dateAddStudentExercise + ); + const [skill] = skillArray; + const skill_key = exercises.data_exercise.indexOf(skill) + 1; + const skillKeyOfList = exercises.data_exercise[skill_key - 1]; + + // console.log("skillKeyOfList ====", skillKeyOfList); + // console.log("dateAddStudentExercise ====", skillKeyOfList); + + const [inputs, setInputs] = useState({ + detail: skillKeyOfList?.detail, + exercise_type: skillKeyOfList?.exercise_type, + list_guide_id: skillKeyOfList?.list_guide_id, + parent: skillKeyOfList?.parent, + start_time: + skillKeyOfList?.start_time ?? + dateAddStudentExercise.start_time ?? + moment().format("YYYY-MM-DD"), + end_time: + skillKeyOfList?.end_time ?? + dateAddStudentExercise.end_time ?? + moment().add(2, "days").format("YYYY-MM-DD"), + }); + + let { start_time, end_time } = inputs; + + const location = useLocation(); + const stateReceived = location.state?.stateSaveTimePrev; + const getPrevTime = useSelector((state) => state.classes.originTime); + + const originAttachFile = useSelector( + (state) => state.classes.originAttachFile + ); + const statusAttachFile = useSelector( + (state) => state.classes.statusAttachFile + ); + + const [isEdit, setIsEdit] = useState(exercises?.isNew ?? false); + + useEffect(() => { + if (!statusAttachFile) { + dispatch({ + type: teacherConstants.ADD_FILE_ATTACH_ORIGIN, + data: exercises.data_exercise[skill_key - 1]?.list_guide_id, + }); + } else { + setInputs((inputs) => ({ + ...inputs, + start_time: getPrevTime.start_time ?? exercises.start_time, + end_time: getPrevTime.end_time ?? exercises.end_time, + })); + } + // dispatch({ type: teacherConstants.ON_STATUS_ATTACH_FILE }); + }, []); + + // Handle Change Data + function handleChangeDate(date) { + setIsEdit(true); + if (date.start_time) { + if ( + moment(date.start_time).toDate() <= + moment(inputs.end_time, "DD-MM-YYYY").toDate() + ) { + setInputs((inputs) => ({ + ...inputs, + start_time: + moment(date.start_time).format("DD-MM-YYYY") || inputs.start_time, + })); + dispatch({ + type: teacherConstants.ADD_DATA_EXERCISE, + data: { + ...exercises, + start_time: + moment(date.start_time).format("DD-MM-YYYY") || inputs.start_time, + }, + }); + } + } else if (date.end_time) { + if ( + moment(date.end_time).toDate() >= + moment(inputs.start_time, "DD-MM-YYYY").toDate() + ) { + setInputs((inputs) => ({ + ...inputs, + end_time: + moment(date.end_time).format("DD-MM-YYYY") || inputs.end_time, + })); + dispatch({ + type: teacherConstants.ADD_DATA_EXERCISE, + data: { + ...exercises, + end_time: + moment(date.end_time).format("DD-MM-YYYY") || inputs.end_time, + }, + }); + } + } + // setInputs(inputs => ({ + // ...inputs, + // start_time: date.start_time ? moment(date.start_time).format("DD-MM-YYYY") : inputs.start_time, + // end_time: date.end_time ? moment(date.end_time).format("DD-MM-YYYY") : inputs.end_time, + // })); + } + + const [listFileId, setListFileId] = useState( + exercises?.data_exercise[skill_key - 1]?.list_guide_id + ); + + // Handle Remove File + function removeFile(key) { + setIsEdit(true); + const newArrayDeleted = listFileId.filter((_, index) => index !== key); + // listFileId.splice(key, 1); + setListFileId([...newArrayDeleted]); + exercises.data_exercise[skill_key - 1].list_guide_id = newArrayDeleted; + exercises.isNew = true; + dispatch({ + type: teacherConstants.ADD_DATA_EXERCISE, + data: exercises, + }); + } + + // Handle Submit File Support and Time Assign + function handleSubmit() { + temp_exercises_data_exercise[skill_key - 1].start_time = start_time; + temp_exercises_data_exercise[skill_key - 1].end_time = end_time; + + // Get DATA of Selected Student + const [objStudentLessonAdd] = dataProposal.filter( + (item) => item.user_id == userID + ); + + const [objLesson] = objStudentLessonAdd?.exercise_suggest.filter( + (item) => item.lesson_id == lesson_id + ); + + objLesson.list_guide_id = + temp_exercises_data_exercise[skill_key - 1].list_guide_id; + objLesson.start_time = inputs.start_time; + objLesson.end_time = inputs.end_time; + + const updatedObjects = objStudentLessonAdd?.exercise_suggest.map((obj) => { + if (obj.lesson_id === lesson_id) { + return { ...obj, ...objLesson }; + } + return obj; + }); + + objStudentLessonAdd["exercise_suggest"] = updatedObjects; + + const newDataProposal = dataProposal; + newDataProposal.forEach((item, index, dataOriginal) => { + if (item.user_id == objStudentLessonAdd.user_id) { + dataOriginal[index] = objStudentLessonAdd; + } + }); + + dispatch({ + type: teacherConstants.GET_DATA_ASSIGN_SPECIFIC, + proposal: newDataProposal, + }); + + dispatch({ + type: teacherConstants.ADD_DATA_EXERCISE, + data: { + ...exercises, + data_exercise: temp_exercises_data_exercise, + start_time: inputs.start_time, + end_time: inputs.end_time, + isNew: false, + }, + }); + dispatch({ type: teacherConstants.OFF_STATUS_ATTACH_FILE }); + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/student/" + + type + + "/list_proposals", + { + userIDSelected: userID, + } + ); + } + + // Validate Param Date + function validateParam() { + return new Date(inputs.start_time) > new Date(inputs.end_time) + ? false + : true; + } + + // Handle Back + const handleBack = () => { + exercises.data_exercise[skill_key - 1].list_guide_id = originAttachFile; + dispatch({ + type: teacherConstants.ADD_DATA_EXERCISE, + data: { + ...exercises, + data_exercise: temp_exercises_data_exercise, + start_time: getPrevTime.startTime, + end_time: getPrevTime.endTime, + isNew: false, + }, + }); + dispatch({ type: teacherConstants.OFF_STATUS_ATTACH_FILE }); + + history.replace( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/student/" + + type + + "/list_proposals", + { + userIDSelected: userID, + } + ); + }; + + // Handle Go List Support + const handleGoListSupport = () => { + dispatch({ type: teacherConstants.ON_STATUS_ATTACH_FILE }); + dispatch({ + type: teacherConstants.ADD_TIME_TO_CHOOSE_FILE_SCREEN, + data: { + start_time: inputs.start_time, + end_time: inputs.end_time, + }, + }); + }; + + return { + skill_key, + isEdit, + inputs, + stateReceived, + getPrevTime, + originAttachFile, + skill, + temp_exercises_data_exercise, + listFileId, + setInputs, + setIsEdit, + handleBack, + validateParam, + handleSubmit, + handleChangeDate, + removeFile, + dispatch, + handleGoListSupport, + }; +}; diff --git a/src/_containers/TeacherPage/Class/AssignExercise/index.js b/src/_containers/TeacherPage/Class/AssignExercise/index.js new file mode 100644 index 0000000..ea6d1d1 --- /dev/null +++ b/src/_containers/TeacherPage/Class/AssignExercise/index.js @@ -0,0 +1,5 @@ +export { default as AssignExerciseSelection } from "./AssignExerciseSelection/AssignExerciseSelection"; +export { default as AssignSpecific } from "./AssignSpecific/AssignSpecific"; +export { default as AssignSkills } from "./AssignSkills/AssignSkills"; +export { default as AssignSpecificStudents } from "./AssignSpecificProposal/AssignSpecificProposal"; +export { default as DetailSkillAssign } from "./DetailSkilAssign/DetailSkillAssign"; diff --git a/src/_containers/TeacherPage/Class/DetailSkillExercise.js b/src/_containers/TeacherPage/Class/DetailSkillExercise.js new file mode 100644 index 0000000..51b8270 --- /dev/null +++ b/src/_containers/TeacherPage/Class/DetailSkillExercise.js @@ -0,0 +1,360 @@ +import React, { useEffect, useLayoutEffect, useRef, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { useParams, Link, useLocation } from "react-router-dom"; +import { Header } from "../../../_components/Admin/Header"; +import { teacherConstants } from "../../../_constants"; +import { useHistory } from "react-router-dom"; +import moment from "moment"; +import { SelectDate } from "../../../_components/Calendar"; +import { isEmpty } from "lodash"; + +function DetailSkillExercise() { + const exercises = useSelector((state) => state.classes.exercises); + const originAttachFile = useSelector( + (state) => state.classes.originAttachFile + ); + const authentication = useSelector((state) => state.authentication); + const { id, skill_key } = useParams(); + const skill = exercises.data_exercise[skill_key - 1]; + const dateAddStudentExercise = useSelector( + (state) => state.classes.dateAddStudentExercise + ); + let temp_exercises_data_exercise = exercises.data_exercise; + const [inputs, setInputs] = useState({ + detail: skill?.detail, + exercise_type: skill?.exercise_type, + list_guide_id: skill?.list_guide_id, + parent: skill?.parent, + start_time: skill?.start_time ?? dateAddStudentExercise.start_time, + end_time: skill?.end_time ?? dateAddStudentExercise.end_time, + }); + + const dispatch = useDispatch(); + const history = useHistory(); + let { start_time, end_time } = inputs; + const getPrevTime = useSelector((state) => state.classes.originTime); + const statusAttachFile = useSelector( + (state) => state.classes.statusAttachFile + ); + const search = history.location.search; + const params = new URLSearchParams(search); + const fromPage = params.get("page"); + + const [isEdit, setIsEdit] = useState(exercises?.isNew ?? false); + + useEffect(() => { + if (!statusAttachFile) { + dispatch({ + type: teacherConstants.ADD_FILE_ATTACH_ORIGIN, + data: exercises.data_exercise[skill_key - 1]?.list_guide_id, + }); + } else { + setInputs((inputs) => ({ + ...inputs, + start_time: getPrevTime.start_time ?? exercises.start_time, + end_time: getPrevTime.end_time ?? exercises.end_time, + })); + } + // dispatch({ type: teacherConstants.ON_STATUS_ATTACH_FILE }); + }, []); + + function handleChangeDate(date) { + setIsEdit(true); + if (date.start_time) { + if ( + moment(date.start_time).toDate() <= + moment(inputs.end_time, "DD-MM-YYYY").toDate() + ) { + setInputs((inputs) => ({ + ...inputs, + start_time: + moment(date.start_time).format("DD-MM-YYYY") || inputs.start_time, + })); + dispatch({ + type: teacherConstants.ADD_DATA_EXERCISE, + data: { + ...exercises, + start_time: + moment(date.start_time).format("DD-MM-YYYY") || inputs.start_time, + }, + }); + } + } else if (date.end_time) { + if ( + moment(date.end_time).toDate() >= + moment(inputs.start_time, "DD-MM-YYYY").toDate() + ) { + setInputs((inputs) => ({ + ...inputs, + end_time: + moment(date.end_time).format("DD-MM-YYYY") || inputs.end_time, + })); + dispatch({ + type: teacherConstants.ADD_DATA_EXERCISE, + data: { + ...exercises, + end_time: + moment(date.end_time).format("DD-MM-YYYY") || inputs.end_time, + }, + }); + } + } + // setInputs(inputs => ({ + // ...inputs, + // start_time: date.start_time ? moment(date.start_time).format("DD-MM-YYYY") : inputs.start_time, + // end_time: date.end_time ? moment(date.end_time).format("DD-MM-YYYY") : inputs.end_time, + // })); + } + + const [listFileId, setListFileId] = useState( + exercises?.data_exercise[skill_key - 1]?.list_guide_id + ); + + function removeFile(key) { + setIsEdit(true); + let newArrayDeleted = listFileId?.filter((_, index) => index !== key); + setListFileId([...newArrayDeleted]); + if (!!exercises.data_exercise[skill_key - 1].list_guide_id) + exercises.data_exercise[skill_key - 1].list_guide_id = newArrayDeleted; + exercises.isNew = true; + dispatch({ + type: teacherConstants.ADD_DATA_EXERCISE, + data: exercises, + }); + } + + function handleSubmit() { + if (validateParam()) { + temp_exercises_data_exercise[skill_key - 1].start_time = start_time; + temp_exercises_data_exercise[skill_key - 1].end_time = end_time; + dispatch({ + type: teacherConstants.ADD_DATA_EXERCISE, + data: { + ...exercises, + data_exercise: temp_exercises_data_exercise, + start_time: inputs.start_time, + end_time: inputs.end_time, + isNew: false, + }, + }); + + dispatch({ type: teacherConstants.OFF_STATUS_ATTACH_FILE }); + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/review" + + (!isEmpty(fromPage) ? `?page=${fromPage}` : "") + ); + } + } + + function validateParam() { + return new Date(inputs.start_time) > new Date(inputs.end_time) + ? false + : true; + } + + const handleBack = () => { + if (!!exercises.data_exercise[skill_key - 1].list_guide_id) + exercises.data_exercise[skill_key - 1].list_guide_id = originAttachFile; + dispatch({ + type: teacherConstants.ADD_DATA_EXERCISE, + data: { + ...exercises, + data_exercise: temp_exercises_data_exercise, + start_time: getPrevTime.startTime, + end_time: getPrevTime.endTime, + isNew: false, + }, + }); + dispatch({ type: teacherConstants.OFF_STATUS_ATTACH_FILE }); + history.replace( + "/" + + authentication.role + + "/class/view/" + + id + + "/exercise/review" + + (!isEmpty(fromPage) ? `?page=${fromPage}` : "") + ); + }; + + // Handle Go List Support + const handleGoListSupport = () => { + dispatch({ type: teacherConstants.ON_STATUS_ATTACH_FILE }); + // dispatch({ + // type: teacherConstants.ADD_TIME_TO_CHOOSE_FILE_SCREEN, + // data: { + // start_time: inputs.start_time, + // end_time: inputs.end_time, + // }, + // }); + }; + + return ( +
    +
    +
    +
    +
    +

    {skill?.detail?.lesson_name}

    +

    {skill?.detail?.lesson_topic}

    +

    + {skill?.parent[0]} >> {skill?.parent[1]} >>{" "} + {skill?.exercise_type?.capitalize()}{" "} +

    +
    +
    +

    Thời gian làm bài

    +
    +
    +
    + +
    inputs.end_time ? " err" : "") + } + > + { + if ( + new Date(start_time) <= new Date(inputs.end_time) && + new Date(start_time) >= moment(new Date()).startOf("day") + ) { + setIsEdit(true); + setInputs((inputs) => ({ + ...inputs, + start_time: + moment(start_time).format("YYYY-MM-DD") || + inputs.start_time, + })); + // dispatch({ + // type: teacherConstants.ADD_TIME_TO_CHOOSE_FILE_SCREEN, + // data: { + // start_time: moment(start_time).format("YYYY-MM-DD"), + // end_time: inputs.end_time, + // }, + // }); + } + }} + /> +
    +
    +
    +
    +
    + +
    inputs.end_time ? " err" : "") + } + > + { + if (new Date(inputs.start_time) <= new Date(end_time)) { + setIsEdit(true); + setInputs((inputs) => ({ + ...inputs, + end_time: + moment(end_time).format("YYYY-MM-DD") || + inputs.end_time, + })); + // dispatch({ + // type: teacherConstants.ADD_TIME_TO_CHOOSE_FILE_SCREEN, + // data: { + // start_time: inputs.start_time, + // end_time: moment(end_time).format("YYYY-MM-DD"), + // }, + // }); + } + }} + /> +
    +
    +
    +
    +
    +
    +

    File Hướng dẫn

    +
    + handleGoListSupport()} + > +
    +

    Thêm hướng dẫn

    +
    + +
    +
    + {(listFileId || []).map((data, i) => { + return ( +
    +
    +
    +
    + ico_file +
    +
    + {data.title} +
    +
    +
    +
    + ico_remove_blue removeFile(i)} + /> +
    +
    + ); + })} +
    +
    +
    + +
    +
    + ); +} + +export { DetailSkillExercise }; diff --git a/src/_containers/TeacherPage/Class/EditHomeWork.css b/src/_containers/TeacherPage/Class/EditHomeWork.css new file mode 100644 index 0000000..d991023 --- /dev/null +++ b/src/_containers/TeacherPage/Class/EditHomeWork.css @@ -0,0 +1,3 @@ +.rel{ + position: inherit !important; +} \ No newline at end of file diff --git a/src/_containers/TeacherPage/Class/EditHomeWork.js b/src/_containers/TeacherPage/Class/EditHomeWork.js new file mode 100644 index 0000000..a5d82bb --- /dev/null +++ b/src/_containers/TeacherPage/Class/EditHomeWork.js @@ -0,0 +1,1496 @@ +import React, { useEffect, useState, Fragment } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { useParams } from "react-router-dom"; +import { teacherActions } from "../../../_actions"; +import { Header } from "../../../_components/Admin/Header"; +import { Alert } from "../../../_components/Alert"; +import { teacherConstants, userConstants } from "./../../../_constants"; +import { teacherService } from "./../../../_services"; +import { + PopUpYesNo, + PopUpZoomImage, + PopUpEditHomeWork, + PopUpSetCriteria, + PopUpHelp, +} from "./../../../_components/Popup"; +import { useHistory } from "react-router-dom"; +import { Audio } from "./../../../_components/Audio"; +import $ from "jquery"; +import Parser from "html-react-parser"; +import HTMLReactParser from "html-react-parser"; +import { + forEach, + findIndex, + isEmpty, + sortBy, + isNaN, + isEqual, + cloneDeep, +} from "lodash"; +import { + validateDecimal2Number, + checkPositiveFloat, +} from "../../../_base/Validate"; + +// import './EditHomeWork.css' +function EditHomeWork() { + const history = useHistory(); + const authentication = useSelector((state) => state.authentication); + const tabSelected = new URLSearchParams(window.location.search).get("type"); + const topic = new URLSearchParams(window.location.search).get("topic"); + const lesson_name = new URLSearchParams(window.location.search).get( + "lesson_name" + ); + const parentId = new URLSearchParams(window.location.search).get("parent_id"); + + let { + id, + exercise_id, + exercise_type, + user_exercise_id, + library, + type, + unit_id, + skill, + lesson_id, + } = useParams(); + + const [criteriaNormal, setCriteriaNormal] = useState(null); + const [exerciseId, setExcerciseId] = useState(exercise_id); + const [studentInfo, setStudentInfo] = useState({}); + let dispatch = useDispatch(); + let homeworks = useSelector((state) => state.classes.homeworks); + let criteria = useSelector((state) => state.classes.criteria); + let alert = useSelector((state) => state.alert); + const [isEdit, setIsEdit] = useState(false); + const [saveResult, setSaveResult] = useState({}); + const [popupDetailResult, setPopupDetailResult] = useState(false); + const [isAIEditing, setIsAIEditing] = useState(false); + const [cachesList, setCachesList] = useState( + homeworks.exercises.resource_data?.content + ); + + let criteriaScoreDefault = + isEmpty(homeworks?.exercises?.old_result) || + isEmpty(homeworks?.exercises?.old_result?.json_criteria_score) + ? criteriaNormal || criteria + : JSON.parse(homeworks?.exercises?.old_result?.json_criteria_score); + + const [criteriaScore, setCriteriaScore] = useState(criteriaScoreDefault); + + let [dataEdit, setdataEdit] = useState({ + errList: [], + fixList: [], + }); + + const [dataEditPrev, setDataEditPrev] = useState({ + errList: [], + fixList: [], + }); + + let [inputs, setInputs] = useState({ + score: "", + comment: "", + user_exercise_id: user_exercise_id, + library: library, + exercise_type: exercise_type, + json_criteria_score: [], + json_writing_check: [], + }); + + let [zoom, setZoom] = useState(false); + + const [availableSubmit, setAvailableSubmit] = useState( + authentication.role == userConstants.ROLE_TEACHER + ); + const [statusHomework, setStausHomeWork] = useState(0); + let [contentEditAI, setContentEditAI] = useState(); + + useEffect(() => { + if (!isEmpty(criteriaScoreDefault) && exercise_type == "writing") { + setCriteriaScore(criteriaScoreDefault); + } + }, [user_exercise_id, homeworks?.exercises?.old_result]); + + useEffect(() => { + const newHomeWorks = cloneDeep(homeworks); + if (newHomeWorks.detail?.data?.length > 0) { + let student = + authentication.role == userConstants.ROLE_TEACHER + ? newHomeWorks?.detail?.data?.find( + (user) => user.id == user_exercise_id + ) || {} + : newHomeWorks.exercises.exercise_data || {}; + dispatch({ + type: teacherConstants.GET_DETAIL_HOMEWORK, + homeworks: newHomeWorks?.detail, + }); + setStudentInfo(cloneDeep(student)); + } + }, [homeworks.detail?.data?.length]); + + useEffect(() => { + teacherService + .getDetailHomeWorkExercise(user_exercise_id, library, exercise_type) + .then((exercises) => { + setIsAIEditing( + type != "0" && !!exercises.old_result.ai_mark + ? !!exercises.old_result.ai_mark + : false + ); + dispatch({ + type: teacherConstants.GET_DETAIL_HOMEWORK_EXERCISE, + exercises: exercises, + }); + setSaveResult(exercises); + if (exercise_type == "writing") { + setInputs({ + ...inputs, + score: exercises.old_result.final_score, + comment: exercises.old_result.comment, + }); + setContentEdit(exercises.resource_data.content); + setCachesList(exercises.resource_data.content); + setFulltext(exercises.resource_data.content); + // console.log(exercises.old_result.json_writing_check) + exercises?.old_result?.json_writing_check && + convertDataHomeWordWriting( + JSON.parse(exercises?.old_result?.json_writing_check) + ); + } else { + setInputs({ + ...inputs, + score: parseInt(type) == 0 ? "" : exercises.exercise_data.score, + comment: + exercise_type == "speaking" + ? exercises.old_result.comment || + exercises.exercise_data.comment + : exercises.exercise_data.comment || + exercises.old_result.comment, + }); + } + + // setAvailableSubmit(parseInt(exercises.exercise_data.status) == 1 ? false : true); + setStausHomeWork(parseInt(exercises.exercise_data.status)); + }); + + // get Criteria normal apply all excercise + teacherService.getCriteriaWorkExercise(null).then((criteria2) => { + setCriteriaNormal( + isEmpty(criteria2.data_criteria) ? null : criteria2.data_criteria + ); + dispatch({ + type: teacherConstants.GET_LIST_CRITERIA, + criteria: criteria2?.data_criteria, + }); + }); + + $(document).on("click", function (e) { + if ($(e.target).closest("#content-box-edit").length == 0) { + $("span.popup-tag-edit").css("display", "none"); + } + }); + }, []); + + // Func get character selected + function getSelectionCharacterOffsetWithin(element) { + var start = 0; + var end = 0; + var doc = element.ownerDocument || element.document; + var win = doc.defaultView || doc.parentWindow; + var sel; + + if (typeof win.getSelection != "undefined") { + sel = win.getSelection(); + if (sel.rangeCount > 0) { + var range = win.getSelection().getRangeAt(0); + var preCaretRange = range.cloneRange(); + preCaretRange.selectNodeContents(element); + preCaretRange.setEnd(range.startContainer, range.startOffset); + start = preCaretRange.toString().length; + preCaretRange.setEnd(range.endContainer, range.endOffset); + end = preCaretRange.toString().length; + } + } else if (sel == doc.selection && sel.type != "Control") { + var textRange = sel.createRange(); + var preCaretTextRange = doc.body.createTextRange(); + preCaretTextRange.moveToElementText(element); + preCaretTextRange.setEndPoint("EndToStart", textRange); + start = preCaretTextRange.text.length; + preCaretTextRange.setEndPoint("EndToEnd", textRange); + end = preCaretTextRange.text.length; + } + return { start: start, end: end }; + } + + // Func select text hightlight + function selectText(event) { + var selOffsets = getSelectionCharacterOffsetWithin( + document.getElementById("content-box-edit") + ); + let start = selOffsets.start; + let end = selOffsets.end; + // console.log(start, end) + if (start != end) { + let locationMousex = locationMouse.x; + let locationMousey = locationMouse.y; + if ((locationMousey = event.clientY)) { + locationMousex += Math.abs((event.clientX - locationMousex) / 2); + } + + let showPopUp = true; + + if ( + findIndex(dataEdit.errList, function (o) { + return o.start <= start && o.end >= start; + }) != -1 || + findIndex(dataEdit.errList, function (o) { + return o.start <= end && o.end >= end; + }) != -1 || + findIndex(dataEdit.fixList, function (o) { + return o.start <= start && o.end >= start; + }) != -1 || + findIndex(dataEdit.fixList, function (o) { + return o.start <= end && o.end >= end; + }) != -1 + ) { + showPopUp = false; + } + // console.log('cachesList', cachesList, cachesList?.substring(start, end)) + + // console.log("startt =====", selOffsets.start + "_" + selOffsets.end); + + if (showPopUp) { + $("span.popup-tag-edit").css("display", "flex"); + $("span.popup-tag-edit").css("left", locationMousex); + if (start >= 0 && end >= 0) { + setTypeEdit("add"); + setcurrentDataErr({ + ...currentDataErr, + start, + end, + text: window.getSelection().toString(), + }); + setcurrentDataFix(defaultCurrentDataFix); + } + } + } + } + + let [locationMouse, setLocationMouse] = useState({ + x: 0, + y: 0, + }); + + const defaultCurrentDataErr = { + end: 0, + isHide: false, + start: 0, + text: "", + isHide: true, + numberIncre: 0, + }; + let [currentDataErr, setcurrentDataErr] = useState(defaultCurrentDataErr); + + const defaultCurrentDataFix = { + type: 1, + explain: "", + fixed: "", + ai: false, + numberIncre: 0, + }; + + let [currentDataFix, setcurrentDataFix] = useState(defaultCurrentDataFix); + + function clickonMouseDown(event) { + setLocationMouse({ + x: event.clientX, + y: event.clientY, + }); + if ( + event.target.className.includes("delete") || + event.target.className.includes("fix") || + event.target.className.includes("error") || + event.target.className.includes("err") + ) { + let { errList, fixList } = dataEdit; + + // $("span.popup-tag-edit").css("display", "block"); + // $("span.popup-tag-edit").css("left", event.clientX); + let indexError = findIndex(errList, { + id: event.target.getAttribute("id_error"), + }); + + let indexFix = findIndex(fixList, { + id: event.target.getAttribute("id_fix"), + }); + if (indexError != -1 || indexFix != -1) { + setcurrentDataErr(errList[indexError]); + setcurrentDataFix(fixList[indexFix]); + } + setTypeEdit("update"); + setDataUpdateWriting({ + indexError, + indexFix, + }); + if (authentication.role == userConstants.ROLE_TEACHER) { + setOpenPopUpEditHomeWork(true); + } else if ( + authentication.role == userConstants.ROLE_STUDENT && + !isEmpty(fixList[indexFix]?.explain) + ) { + setPopupDetailResult(true); + } + } else { + $("span.popup-tag-edit").css("display", "none"); + } + } + + function validateParam() { + if (exercise_type === 'writing') { + if ( Number(inputs.score) > 10 || Number(inputs.score) < 0) { + return false; + } + if (criteriaScore?.every(item => Number(item?.score) >= 0)) { + return true + } + return false + } + if (["speaking", "project"]?.includes(exercise_type)) { + if(inputs.score !== '' && Number(inputs.score) <=10 && Number(inputs.score) >= 0) return true; + return false + } + return true; + } + + function handleChange(e) { + const { name, value } = e.target; + if (name == "comment") { + setInputs((inputs) => ({ ...inputs, [name]: value })); + setIsEdit(true); + } else { + if (value <= 10 && value.toString().length <= 4) { + setInputs((inputs) => ({ ...inputs, [name]: value })); + setIsEdit(true); + } + } + } + + // Handle Submit + function handleSubmit() { + if (validateParam()) { + let message = + statusHomework == 1 ? "Cập nhật bài thành công" : "Chấm bài thành công"; + dispatch( + teacherActions.updatelHomeWorkExercise( + { + ...inputs, + json_criteria_score: criteriaScore, + comment: inputs.comment || "", + json_writing_check: { ...dataEdit, cachesList: cachesList }, + }, + message + ) + ); + } + } + + const [askAI, setAskAI] = useState(false); + const [askHELP, setAskHELP] = useState(false); + const [OpenPopUpEditHomeWork, setOpenPopUpEditHomeWork] = useState(false); + + function callAI() { + setIsEdit(true); + setAskAI(false); + dispatch( + teacherActions.callAIHomeWork( + homeworks.exercises.resource_data.content, + studentInfo?.user_received_id, + library, + user_exercise_id, + id + ) + ); + } + + function showZoom() { + setZoom(true); + } + + // Convert Date Home Work Writing + const convertDataHomeWordWriting = (data) => { + let errList = data.errList; + let fixList = data.fixList; + let cachesList = data.cachesList || ""; + // console.log("cachesList1 ========", cachesList); + + if (data.type == "add") { + errList.push(data.dataError); + fixList.push(data.dataFix); + } else if (data.type == "update") { + if (dataUpdateWriting.indexError != -1) { + errList[dataUpdateWriting.indexError] = data.dataError; + fixList[dataUpdateWriting.indexError] = data.dataFix; + } + } else if (data.type == "delete") { + errList.splice(dataUpdateWriting.indexError, 1); + fixList.splice(dataUpdateWriting.indexError, 1); + } + errList = sortBy(errList, "start"); + fixList = sortBy(fixList, "start"); + let tempFixList = []; + let tempErrorList = []; + if (data.type == "add") { + dataUpdateWriting.indexError = 0; + forEach(errList, function (value, key) { + if (data.dataError.start >= value.end) { + dataUpdateWriting.indexError = key + 1; + return true; + } + }); + } + + forEach(fixList, function (value, key) { + if ( + ((data.type == "update" || data.type == "add") && + key > dataUpdateWriting.indexError) || + (data.type == "delete" && key >= dataUpdateWriting.indexError) + ) { + let idError = value.idErr.split("_"); + tempFixList.push({ + ...value, + start: parseInt(value.start) + parseInt(data.addNumberToId), + end: parseInt(value.end) + parseInt(data.addNumberToId), + id: + parseInt(value.start) + + parseInt(data.addNumberToId) + + "_" + + parseInt(parseInt(value.end) + parseInt(data.addNumberToId)), + idErr: + parseInt(idError[0]) + + parseInt(data.addNumberToId) + + "_" + + parseInt(parseInt(idError[1]) + parseInt(data.addNumberToId)), + }); + } else { + tempFixList.push(value); + } + }); + + forEach(errList, function (value, key) { + if ( + ((data.type == "update" || data.type == "add") && + key > dataUpdateWriting.indexError) || + (data.type == "delete" && key >= dataUpdateWriting.indexError) + ) { + tempErrorList.push({ + ...value, + start: parseInt(value.start) + parseInt(data.addNumberToId), + end: parseInt(value.end) + parseInt(data.addNumberToId), + id: + parseInt(value.start) + + parseInt(data.addNumberToId) + + "_" + + parseInt(parseInt(value.end) + parseInt(data.addNumberToId)), + }); + } else { + tempErrorList.push(value); + } + }); + + fixList = tempFixList; + errList = tempErrorList; + setdataEdit({ + errList, + fixList, + }); + setCachesList(cachesList); + + // console.log("cachesList2 ========", cachesList); + + let curentCursor = 0; + if (!isEmpty(fixList)) { + contentEdit = ""; + forEach(fixList, function (value, key) { + let indexOfError = findIndex(errList, { id: value.idErr }); + let dataError = value.idErr.split("_"); + // console.log('dataError ====', dataError) + let class_explain = value.explain ? " have-explain" : ""; + if (value.start == value.end) { + contentEdit += + cachesList?.substring(curentCursor, dataError[0]) + + ' + {OpenPopUpEditHomeWork && ( + saveDataWriting(data)} + onClickNo={() => setOpenPopUpEditHomeWork(false)} + width={340} + /> + )} + {popupDetailResult && ( + setPopupDetailResult(false)} + /> + )} + {alert.message && + alert.screen == teacherConstants.SCREEN_EDIT_HOME_WORK && ( + + history.push( + "/" + + authentication.role + + "/class/view/" + + id + + "/homework/" + + exercise_id + + "/" + + library + + "/" + + type + ) + } + /> + )} + {openSetCriteria && ( + SetOpenSetCriteria(false)} + onClickYes={(data, exercise_id) => saveCriteria(data, exercise_id)} + width={420} + /> + )} + + {(exercise_type == "speaking" || exercise_type == "project") && ( +
    +
    + + {studentInfo?.lesson_name || + lesson_name || + saveResult?.exercise_data?.lesson_name || + saveResult?.resource_data?.title} + +

    + Topic:{" "} + {studentInfo?.topic || + topic || + saveResult?.resource_data?.topic || + saveResult?.exercise_data?.topic} +

    +
    +
    + {homeworks.exercises.resource_data.file_type == "img" && ( + img showZoom()} + /> + )} + {homeworks.exercises.resource_data.file_type == "video" && ( + + )} + {homeworks.exercises.resource_data.file_type == "audio" && ( +
    +
    +
    +
    +

    Điểm

    + e.target.blur()} + name="score" + onChange={handleChangeScoreDecimal} + max={10} + min={0} + value={ + inputs.score && + (Number.isInteger(Number.parseFloat(inputs.score)) + ? inputs.score + : Number.parseFloat(inputs.score)) + } + disabled={!availableSubmit} + /> +
    +
    +

    Nhận xét

    +