commit 496cc47ca2aff2917279488c32526850f205beec Author: HOANGLAOTA Date: Thu Jul 11 15:04:15 2024 +0700 first 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..933d0a4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# 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 + +/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..7b401e0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM node:16 + +# 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..71a2dc7 --- /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.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/config.js b/config.js new file mode 100644 index 0000000..429908d --- /dev/null +++ b/config.js @@ -0,0 +1,22 @@ +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: "http://45.119.84.189:10809/", + BASE_URL: "https://service.dev.sundayenglish.com/", + EXCERCISE_URL: "https://exercise.dev.sundayenglish.com/", + // API_URL_SETEST: "http://45.119.84.189:10809/api", + API_URL_SETEST: "https://service.dev.sundayenglish.com/api", + AUTH_URL: "https://oauth2.dev.sundayenglish.com/", + 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/docker-compose.yml.example b/docker-compose.yml.example new file mode 100644 index 0000000..02345b5 --- /dev/null +++ b/docker-compose.yml.example @@ -0,0 +1,35 @@ +version: '3.5' +services: + #Nginx Service + register-teacher-nginx: + image: nginx:alpine + container_name: register-teacher-nginx + restart: unless-stopped + tty: true + ports: + - "19992:80" + - "19923:443" + volumes: + - ./:/var/www + - ./nginx/conf.d:/etc/nginx/conf.d + networks: + - app-network + #Node Service + register-teacher-web: + image: node:16 + container_name: register-teacher-web + build: + context: . + dockerfile: ./Dockerfile + restart: unless-stopped + tty: true + working_dir: /var/www + volumes: + - ./:/var/www + networks: + - app-network +#Docker Networks +networks: + app-network: + name: gk.internal + external: true diff --git a/nginx/conf.d.prod/vhost.conf b/nginx/conf.d.prod/vhost.conf new file mode 100644 index 0000000..00f61a5 --- /dev/null +++ b/nginx/conf.d.prod/vhost.conf @@ -0,0 +1,68 @@ +server { + listen 80; + server_name dev.giaovien.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; +} +server { + listen 443 default_server ssl http2; + listen [::]:443 ssl http2; + server_name dev.giaovien.sundayenglish.com; + index index.php index.html; + error_log /var/log/nginx/error.log; + access_log /var/log/nginx/access.log; + root /var/www/main; + add_header Access-Control-Allow-Origin *; + ssl_certificate /etc/nginx/ssl/live/dev.giaovien.sundayenglish.com/fullchain.pem; + ssl_certificate_key /etc/nginx/ssl/live/dev.giaovien.sundayenglish.com/privkey.pem; + + location / { + try_files $uri /index.html; + } + + location ~* \.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$ { + expires 1h; + add_header Cache-Control "public, no-transform"; + gzip on; + gzip_disable "msie6"; + + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_min_length 256; + gzip_types + application/atom+xml + application/geo+json + application/javascript + application/x-javascript + application/json + application/ld+json + application/manifest+json + application/rdf+xml + application/rss+xml + application/xhtml+xml + application/xml + font/eot + font/otf + font/ttf + image/svg+xml + text/css + text/javascript + text/plain + text/xml + image/jpeg; + } + + client_max_body_size 1024m; +} 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..faaddbf --- /dev/null +++ b/public/assets/css/all.css @@ -0,0 +1,11165 @@ +/*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: #fff; +} + +.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-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; +} + +.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: #1071d8 !important; + text-decoration: underline; +} + +.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; +} \ 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..9027b99 --- /dev/null +++ b/public/assets/css/login.css @@ -0,0 +1,190 @@ +.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; + background-color: #fff; +} +.bg-login .version-app { + position: absolute; + bottom: 10px; + right: 10px; +} +.bg-register { + background-image: url("./../images/BG_ND.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/BG_ND.png b/public/assets/images/BG_ND.png new file mode 100644 index 0000000..387515a Binary files /dev/null and b/public/assets/images/BG_ND.png 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/Logo_ND.png b/public/assets/images/Logo_ND.png new file mode 100644 index 0000000..e8f9b2c Binary files /dev/null and b/public/assets/images/Logo_ND.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/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..4f5e682 Binary files /dev/null and b/public/assets/images/coursesNews/bg_content_1.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/img_courses_tree.png b/public/assets/images/coursesNews/img_courses_tree.png new file mode 100644 index 0000000..66b4922 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/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/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/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..d2abf39 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..61759f4 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_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/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/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..d5c6b08 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..979df17 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_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..2417479 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_GV.png b/public/assets/images/logo_GV.png new file mode 100644 index 0000000..5a15c83 Binary files /dev/null and b/public/assets/images/logo_GV.png differ diff --git a/public/assets/images/logo_PY1.png b/public/assets/images/logo_PY1.png new file mode 100644 index 0000000..1a817c6 Binary files /dev/null and b/public/assets/images/logo_PY1.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..0cc6945 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..6868a0c --- /dev/null +++ b/public/index.html @@ -0,0 +1,79 @@ + + + + + + + + + + + + + Sunday English - Nâng cao điểm số Tiếng Anh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + 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..96d1a32 --- /dev/null +++ b/src/App.js @@ -0,0 +1,61 @@ +import React, { useEffect, useState, useLayoutEffect } from "react"; +import { Router, Route, Switch, Redirect } from "react-router-dom"; +import { + RouteRedirectToAdmin, + RouteRedirectToLogin, +} from "./_components/Router"; +import { alertActions } from "./_actions"; +import { history } from "./_helpers"; +import { useDispatch, useSelector } from "react-redux"; +import {LoginPage} from './_containers/LoginPage/index' +import { ForgotPasswordPage } from "./_containers/ForgotPasswordPage"; +import RegisterPage from "./_containers/RegisterPage"; +import HomePage from "./_containers/HomePage"; + +function App() { + const dispatch = useDispatch(); + const authentication = useSelector((state) => state.authentication); + + useEffect(() => { + history.listen(() => { + dispatch(alertActions?.clear()); + }); + }, []); + + 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..840a790 --- /dev/null +++ b/src/_actions/schedules.js @@ -0,0 +1,575 @@ +import { apiCaller } from "./../_helpers"; +import { alertActions } from "./"; +import { scheduleConstants, popupConstants } 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 + ).then(() => { + dispatch(getTimetable()); + }); + }; +} + +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", + urlencoded, + 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..c6f348a --- /dev/null +++ b/src/_actions/users.js @@ -0,0 +1,552 @@ +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 = "/login"; + let method = "POST"; + return apiCaller(url_call_api, method, data, null, false).then( + async (data) => { + 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"); + + 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); + } + history.push("/"); + }, + (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..7918337 --- /dev/null +++ b/src/_base/DetailListNews.js @@ -0,0 +1,722 @@ +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?.content} + {item?.tail_content} + {item?.list_detail?.map((item) => + renderItemListDetailCourse(item, courseID) + )} + + {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} +
    + ); +}; + +export { + renderListContent1, + renderListDetail, + renderListDot, + renderListPage1, + renderListPage2, + renderListContent3, + renderContentPolicyPayment, + renderContentPolicyPayment2, + renderListDetailCourse, + renderCourseItem, + renderListDetailCourseMobile, + renderDataQuestion1, + renderListContentFAQ, +}; 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..c5ccd78 --- /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..412322b --- /dev/null +++ b/src/_base/Mydata.js @@ -0,0 +1,3 @@ +export const Mydata = { + version: 'v1.0.6' +} \ 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..b8d82c0 --- /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 = { + id, + 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..d57f882 --- /dev/null +++ b/src/_components/AdvisementForm/AdvisementForm.style.scss @@ -0,0 +1,452 @@ +@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%; + .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); + } + } + } + } + } + } +} 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..d70b2cb --- /dev/null +++ b/src/_components/Auth/InputSelectSearch/index.scss @@ -0,0 +1,272 @@ +@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; + margin-top: 1%; + } + } + } + } + + .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..3273a59 --- /dev/null +++ b/src/_components/Auth/InputText/index.js @@ -0,0 +1,246 @@ +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} + onKeyDown={props?.onKeyDown} + /> + {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..ab89c6d --- /dev/null +++ b/src/_components/Auth/InputText/index.scss @@ -0,0 +1,146 @@ +@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; + margin-top: 1%; + } + } + } + + .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..a4f276d --- /dev/null +++ b/src/_components/FooterNews/FooterNews.jsx @@ -0,0 +1,676 @@ +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 : ( + 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 +
    */} + + 024 6281 3888 + +
    +
    +
    +
    +
    + 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. +
    +
    + +
    + + Image Bo Cong Thuong + +
    +
    + +
    +
    +
    +
    +
    handleOpenOption(FooterSelection.INTRODUCTION)} + className={`font_news_bold flex-jus-between-mobile mg-bottom-0-mobile title_footer mg-bottom-0-7 ${ + isOpen == FooterSelection.INTRODUCTION + ? " font_news_bold_mobile" + : "font_news_mobile" + }`} + > + + Giới thiệu + +
    +
    + + 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 +
    +
    +
    +
    + + {/*only mobile */} +
    + {dataFooterMobile.map(item => ( +
    { + history.push(item?.href) + window.scrollTo({ top: 0, behavior: "instant" }) + }} + className={"flex-jus-between-mobile title_footer_container font_news_bold mg-bottom-0-3 font_news_mobile"} + > + + {item?.name} + +
    + + ))} +
    + + {/* Fee */} + {!hasDomainStore() && ( +
    +
    + handleOpenOption(FooterSelection.BUY_COURSES) + } + className={`flex-jus-between-mobile title_footer_container font_news_bold mg-bottom-0-3 ${ + isOpen == FooterSelection.BUY_COURSES + ? " font_news_bold_mobile" + : " font_news_mobile" + }`} + > + + {/* {[ + TypeHeaderNewsItem.TARIFF, + TypeHeaderNewsItem.TEACHER, + ].includes(props?.typeFee) + ? "Bảng giá" + : "Học phí"} */} + Bảng giá + +
    + + + +
    +
    +
    + {dataTariff.map((data) => + renderFooterItem(data, FooterSelection.BUY_COURSES) + )} +
    +
    + )} +
    + + {/* Support */} +
    +
    handleOpenOption(FooterSelection.SUPPORT)} + className={`flex-jus-between-mobile title_footer_container font_news_bold mg-bottom-0-3 ${ + isOpen == FooterSelection.SUPPORT + ? " font_news_bold_mobile" + : " font_news_mobile" + }`} + // style={{ + // fontWeight: isOpen == FooterSelection.COURSES && "700", + // }} + > + + Hỗ trợ + +
    + + + +
    +
    +
    + {dataSupport.map((data) => + renderFooterItem(data, FooterSelection.SUPPORT) + )} +
    + {/*
    + {dataSupport.map((data) => + renderFooterItemMobile(data, FooterSelection.SUPPORT) + )} +
    */} +
    + +
    +
    handleOpenOption(FooterSelection.POLICY)} + className={`flex-jus-between-mobile title_footer_container font_news_bold mg-bottom-0-5 ${ + isOpen == FooterSelection.POLICY + ? " font_news_bold_mobile" + : " font_news_mobile" + }`} + > + + Điều khoản và chính sách dịch vụ + +
    + + + +
    +
    + {dataPolicy.map((data) => + renderFooterItem(data, FooterSelection.POLICY) + )} +
    +
    + + {props?.type != "download" && ( +
    + {dataInforDownload.map((item) => renderInforDownload(item))} +
    + )} +
    +
    + +
    + 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..4560fa5 --- /dev/null +++ b/src/_components/FooterNews/FooterNews.logic.js @@ -0,0 +1,276 @@ +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}/#rule1`, + eleId: "rule1", + }, + { + id: 2, + name: "Chính sách bảo vệ và xử lý dữ liệu cá nhân", + href: `${TypeHeaderNewsItem.POLICY}/#content2/#rule2`, + eleId: "rule2", + }, + { + id: 3, + name: "Chính sách về bản quyền và sở hữu trí tuệ", + href: `${TypeHeaderNewsItem.POLICY}/#content3/#rule3`, + eleId: "rule3", + }, + { + id: 4, + name: "Chính sách thanh toán", + href: `${TypeHeaderNewsItem.POLICY}/#content3/#rule4`, + typeStore: "store", + eleId: "rule4", + }, + ]; + + 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..1d1b3c3 --- /dev/null +++ b/src/_components/GlobalStyles/GlobalStyles.scss @@ -0,0 +1,1618 @@ +@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-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; +} + +.fz-26 { + font-size: 2.6rem; +} + +.fz-25 { + font-size: 2.5rem; +} + +.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_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/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/HeaderLogoRegister/HeaderLogoRegister.js b/src/_components/Header/HeaderLogoRegister/HeaderLogoRegister.js new file mode 100644 index 0000000..d3ed2fa --- /dev/null +++ b/src/_components/Header/HeaderLogoRegister/HeaderLogoRegister.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 HeaderLogoRegister({srcImg, name, color, path}) { + return ( +
    + + {"Logo"} + {name.split('\n').map((str, index) => {str})} + + +
    + ); +} + +export { HeaderLogoRegister }; diff --git a/src/_components/Header/HeaderLogoRegister/headerTS.style.scss b/src/_components/Header/HeaderLogoRegister/headerTS.style.scss new file mode 100644 index 0000000..98c6ab6 --- /dev/null +++ b/src/_components/Header/HeaderLogoRegister/headerTS.style.scss @@ -0,0 +1,53 @@ +.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: 56px; + margin-top: 8px; + cursor: default; + + @media screen and (max-height: 800px) { + margin-left: 46px; + margin-top: -2px; + } + + @media screen and (max-width: 768px) { + margin-left: 16px; + } + } + + img { + width: 120px; + height: auto; + margin-top: 0 !important; + + @media screen and (max-width: 768px) { + width: 74px; + } + } + + span { + font-size: 16px; + font-weight: 700; + margin-top: 4px; + font-family: 'Barlow-Bold'; + + @media screen and (max-height: 800px) { + font-size: 14px; + } + + @media screen and (max-width: 768px) { + font-size: 12px; + } + + } +} \ No newline at end of file diff --git a/src/_components/Header/HeaderMain/HeaderMain.style.scss b/src/_components/Header/HeaderMain/HeaderMain.style.scss new file mode 100644 index 0000000..9ec0fb3 --- /dev/null +++ b/src/_components/Header/HeaderMain/HeaderMain.style.scss @@ -0,0 +1,56 @@ +@import "/src/_styles/mixin"; + +.header-main-container { + box-shadow: 1px 2px 4px 0 rgba(21, 27, 38, 0.4); + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 99999; + background-color: #fff; + + @include screen_mobile { + padding-right: 16px; + } + + .logo { + img { + width: 120px; + margin: 0; + padding: 0; + } + } + + .header-main-content { + display: flex; + justify-content: space-between; + align-items: center; + height: 80px; + + .btn-logout { + border-radius: 50%; + border: 2px solid #00B9B7; + padding: 6px; + cursor: pointer; + position: relative; + width: 36px; + height: 36px; + display: flex; + + .btn-logout-text { + font-size: 14px; + color: #000; + position: absolute; + display: inline block; + text-wrap: nowrap; + bottom: -30px; + right: 50%; + transform: translateX(50%); + background-color: #fff; + box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px; + padding: 2px 8px; + border-radius: 24px; + } + } + } +} \ No newline at end of file diff --git a/src/_components/Header/HeaderMain/index.js b/src/_components/Header/HeaderMain/index.js new file mode 100644 index 0000000..6bc47be --- /dev/null +++ b/src/_components/Header/HeaderMain/index.js @@ -0,0 +1,29 @@ +import { Link } from "react-router-dom"; +import './HeaderMain.style.scss' +import { useState } from "react"; +import {history} from '../../../_helpers/history' +export default function HeaderMain() { + const [isHoverLogout, setIsHoverLogout] = useState(false) + + const handleLogout = () => { + history.replace('/login') + } + + return ( +
    +
    +
    +
    + + {"Logo"} + +
    +
    setIsHoverLogout(true)} onMouseOut={() => setIsHoverLogout(false)} onClick={handleLogout}> + + {isHoverLogout && Đăng xuất} +
    +
    +
    +
    + ); +} \ No newline at end of file diff --git a/src/_components/Header/HeaderNews/HeaderNews.jsx b/src/_components/Header/HeaderNews/HeaderNews.jsx new file mode 100644 index 0000000..492038b --- /dev/null +++ b/src/_components/Header/HeaderNews/HeaderNews.jsx @@ -0,0 +1,406 @@ +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..7f22e33 --- /dev/null +++ b/src/_components/Header/HeaderNews/HeaderNews.logic.js @@ -0,0 +1,250 @@ +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: "TRANG CHỦ", + type: TypeHeaderNewsItem.HOME, + }, + { + id: 2, + name: "GIỚI THIỆU", + type: TypeHeaderNewsItem.INTRODUCTION, + }, + { + id: 3, + name: "KHÓA HỌC", + type: TypeHeaderNewsItem.COURSES, + }, + { + id: 4, + name: "BẢNG GIÁ", + type: + type == TypeHeaderNewsItem.TEACHER || type == TypeHeaderNewsItem.TARIFF + ? TypeHeaderNewsItem.TARIFF + : TypeHeaderNewsItem.FEE, + }, + { + id: 5, + name: "PHỤ HUYNH", + type: TypeHeaderNewsItem.PARENT, + }, + { + id: 6, + name: "GIÁO VIÊN", + type: TypeHeaderNewsItem.TEACHER, + }, + { + id: 7, + name: "LUYỆN THI", + type: TypeHeaderNewsItem.MOCK_TEST, + }, + ]; + + 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..81de998 --- /dev/null +++ b/src/_components/Header/HeaderNews/HeaderNews.style.scss @@ -0,0 +1,341 @@ +@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; + 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); +} 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/index.js b/src/_components/Header/index.js new file mode 100644 index 0000000..79d95de --- /dev/null +++ b/src/_components/Header/index.js @@ -0,0 +1,3 @@ +export * from "./HeaderCurve"; +export * from "./HeaderLogoRegister/HeaderLogoRegister"; +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 ( +
    + +
    + + +
    +
    + + + ); +} + +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..b3a530f --- /dev/null +++ b/src/_components/Popup/PopUpAddFile.js @@ -0,0 +1,161 @@ +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 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) { + 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); + } + } + } + + 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..967da26 --- /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..b5787e1 --- /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..cc15334 --- /dev/null +++ b/src/_components/Popup/PopUpFilter.js @@ -0,0 +1,826 @@ +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 (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..48781c0 --- /dev/null +++ b/src/_components/Popup/PopUpRadio.js @@ -0,0 +1,133 @@ +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, + }); + } + + // console.log(schedules.repeatType); + + 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..551b122 --- /dev/null +++ b/src/_components/Popup/PopUpShowTimeTable.js @@ -0,0 +1,45 @@ +import React from 'react'; +import { useDispatch } from 'react-redux'; +import { scheduleActions } from './../../_actions'; +import './style.css'; + +function PopUpShowTimeTable(props) { + let { onClickClose, onClickEdit, onClickDelete, titleButtonDone, titleButtonCancel, width, dataEditTimeTable } = props; + const dispatch = useDispatch(); + + function deleteTimeTable() { + onClickDelete(); + 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..e12fb37 --- /dev/null +++ b/src/_components/Router/RouteRedirectToAdmin.js @@ -0,0 +1,28 @@ +import React from "react"; +import { Route, Redirect } from "react-router-dom"; +import PropTypes from "prop-types"; + +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..03a0825 --- /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..c009176 --- /dev/null +++ b/src/_components/ScrollFixed/ScrollFixed.jsx @@ -0,0 +1,46 @@ +import "./ScrollFixed.style.scss"; +import { scrollFixedLogic } from "./ScrollFixed.logic"; + +const ScrollFixed = () => { + let { handleScrollTop, handleNavigate } = scrollFixedLogic(); + + return ( + <> +
    +
    + Icon Scroll Up +
    + {/*
    + Icon Box Chat +
    */} +
    +
    +
    +
    handleNavigate('/parent_news')}> + Icon phu huynh +
    +
    handleNavigate('/teacher_news')}> + 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..1af45d4 --- /dev/null +++ b/src/_components/ScrollFixed/ScrollFixed.style.scss @@ -0,0 +1,53 @@ +@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; + } + } +} \ 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..e30712a --- /dev/null +++ b/src/_components/Slogan/Slogan.style.scss @@ -0,0 +1,67 @@ +@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; + } + } +} 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..89af178 --- /dev/null +++ b/src/_components/exam-test/index.js @@ -0,0 +1,970 @@ +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..784fd0f --- /dev/null +++ b/src/_constants/auth.js @@ -0,0 +1,7 @@ +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", + STEP_ADDRESS_STUDYING: "STEP_ADDRESS_STUDYING", +}; 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/config.js b/src/_constants/config.js new file mode 100644 index 0000000..af374ab --- /dev/null +++ b/src/_constants/config.js @@ -0,0 +1,22 @@ +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: "http://45.119.84.189:10809/", + BASE_URL: "https://dev.daisu.sundayenglish.com/", + EXCERCISE_URL: "https://exercise.dev.sundayenglish.com/", + // API_URL_SETEST: "http://45.119.84.189:10809/api", + API_URL_SETEST: "https://dev.daisu.sundayenglish.com/api", + AUTH_URL: "https://oauth2.dev.sundayenglish.com/", + 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/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..113a8f1 --- /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_news", + PARENT: "parent_news", + 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..0b7cf04 --- /dev/null +++ b/src/_constants/home_type.js @@ -0,0 +1,4 @@ +export const homeType = { + LANDING: 'LANDING', + REGISTER: 'REGISTER', +}; \ 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/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/register.js b/src/_constants/register.js new file mode 100644 index 0000000..5eed3e1 --- /dev/null +++ b/src/_constants/register.js @@ -0,0 +1,4 @@ +export const STEP_REGISTER = { + CREATE_ACCOUNT: 'CREATE_ACCOUNT', + CREATE_INFORMATION: 'CREATE_INFORMATION', +} \ 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/ForgotPasswordPage/ForgotPasswordPage.js b/src/_containers/ForgotPasswordPage/ForgotPasswordPage.js new file mode 100644 index 0000000..af4ce9d --- /dev/null +++ b/src/_containers/ForgotPasswordPage/ForgotPasswordPage.js @@ -0,0 +1,212 @@ +import React, { useEffect, useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import { alertConstants, userConstants } from "./../../_constants"; + +import { HeaderCloud, HeaderCurve } 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 username 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/HomePage/HomePage.style.scss b/src/_containers/HomePage/HomePage.style.scss new file mode 100644 index 0000000..2d388aa --- /dev/null +++ b/src/_containers/HomePage/HomePage.style.scss @@ -0,0 +1,138 @@ +@import "/src/_styles/mixin"; + +.body-home-container { + margin-top: 80px; + padding: 32px 0; +} + +.home-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 32px; + + @include screen_mobile { + padding: 0 16px; + } + + .box-info { + border: 1px solid #333; + border-radius: 16px; + padding: 24px; + width: 50%; + display: flex; + flex-direction: column; + + @include screen_mobile { + width: 100%; + } + } + + + .box-info-agency { + + .main-info-agency {} + + .avatar-agency { + margin-right: 16px; + + img { + object-fit: cover; + width: 60px; + height: 60px; + border-radius: 50%; + } + } + + .name-agency { + font-size: 28px; + font-weight: 700; + padding-top: 10px; + + @include screen_mobile { + padding-top: 0; + } + } + + .sub-info-agency { + display: flex; + flex-direction: column; + gap: 16px; + margin-top: 24px; + padding-left: 16px; + + .info-agency-item { + display: flex; + gap: 8px; + } + + } + } + + .box-link { + .title-box-link { + font-size: 24px; + font-weight: 700; + margin-bottom: 16px; + } + + .container-link-text { + background-color: #ededed; + padding: 4px 8px; + width: 100%; + display: flex; + align-items: center; + } + + .link-text { + line-break: anywhere; + } + + .btn-copy-link { + background-color: #fff; + border: 1px solid #bfbdbd; + position: relative; + padding: 6px; + + @include screen_mobile { + display: none; + } + } + + .copy-text { + background-color: #121111; + color: #fff; + font-size: 14px; + padding: 4px 8px; + position: absolute; + bottom: -30px; + right: 50%; + transform: translateX(50%); + text-wrap: nowrap; + } + + .btn-copy-link-mobile { + background-color: #fff; + border: 1px solid #bfbdbd; + padding: 6px; + align-self: center; + margin-top: 8px; + width: 120px; + display: none; + align-items: center; + justify-content: center; + border-color: #00B9B7; + color: #00B9B7; + + svg { + width: 24px; + height: 24px; + margin-right: 6px; + } + + @include screen_mobile { + display: flex; + } + } + } +} \ No newline at end of file diff --git a/src/_containers/HomePage/index.js b/src/_containers/HomePage/index.js new file mode 100644 index 0000000..2b44678 --- /dev/null +++ b/src/_containers/HomePage/index.js @@ -0,0 +1,107 @@ +import { useState } from "react"; +import HeaderMain from "../../_components/Header/HeaderMain"; +import './HomePage.style.scss' +import { homeType } from "../../_constants/home_type"; + +export default function HomePage() { + const [typeCopy, setTypeCopy] = useState('') + const [isCopied, setIsCopied] = useState({ + [homeType.LANDING]: false, + [homeType.REGISTER]: false, + }) + + + const handleCopy = (type, value) => { + navigator.clipboard.writeText(value) + if (!!isCopied?.[type]) { + return; + } + setIsCopied(prev => ({ + ...prev, + [type]: true + })); + setTimeout(() => { + setIsCopied(prev => ({ + ...prev, + [type]: false + })); + }, 3000) + } + + const IconCopy = () => { + return ( + + ) + } + + const IconTick = () => { + return ( + + ) + } + + const renderInfoAgencyItem = (text) => { + return ( +
    + + + + {text} +
    + ) + } + + const renderBoxLink = (title,link, type) => { + return ( +
    +

    {title}

    +
    + + +
    + +
    + ) + } + + return ( +
    + +
    +
    +
    +
    +
    + Logo Sun-E +
    +
    +

    + Tên đại lý +

    +
    + {renderInfoAgencyItem('05/02/2000')} + {renderInfoAgencyItem('0397225122')} + {renderInfoAgencyItem('hoangmt@gmail.com')} +
    +
    +
    + {renderBoxLink('Link Đăng ký tuyến dưới', 'https://docs.google.com', homeType.REGISTER)} + {renderBoxLink('Link Landing page cho khách hàng', 'https://docs.google.com/document/d/1hYRL9Su-zTbNXXFGb8AC8-u1NWtCIi4tZKTsRrrqSOg/edit', homeType.LANDING)} +
    +
    +
    +
    + ) +} \ 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..5d7f028 --- /dev/null +++ b/src/_containers/LoginPage/LoginPage.js @@ -0,0 +1,284 @@ +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 { stepAuthConstants } from "../../_constants/auth"; +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, userConstants.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..e6c047e --- /dev/null +++ b/src/_containers/LoginPage/components/Login.js @@ -0,0 +1,505 @@ +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/RegisterPage/CreateAccount/index.js b/src/_containers/RegisterPage/CreateAccount/index.js new file mode 100644 index 0000000..da101ac --- /dev/null +++ b/src/_containers/RegisterPage/CreateAccount/index.js @@ -0,0 +1,382 @@ +import React, { useEffect, useState } from "react"; +import InputText from "../../../_components/Auth/InputText"; +import "./index.scss"; +import { apiCaller } from "../../../_helpers"; +import { stepAuthConstants } from "../../../_constants/auth"; +import {history} from '../../../_helpers/history' + +const CreateAccount = () => { + const [email, setEmail] = useState(""); + const [phone, setPhone] = useState(""); + + const [phoneWarning, setPhoneWarning] = useState(""); + const [password, setPassword] = useState(""); + const [rePassword, setRePassword] = useState(""); + const [emailError, setEmailError] = useState(""); + const [pwError, setPwError] = useState(""); + const [rePwError, setRePwError] = useState(""); + const [cacheEmailPass, setCacheEmailPass] = useState([]); + const [cacheEmailFail, setCacheEmailFail] = useState([]); + const [disabledBtn, setDisabledBtn] = useState(false); + + async function handleSubmit(e) { + e.preventDefault(); + if (!!email && password.length >= 6 && password === rePassword) { + if (cacheEmailPass.includes(email)) { + nextStep(); + return; + } else if (cacheEmailFail.includes(email)) { + setDisabledBtn(true); + setEmailError( + "Email đã tồn tại trên hệ thống. Vui lòng quay lại đăng nhập!" + ); + return; + } else { + await apiCaller("/api_register/check_email", "POST", { + email, + }) + .then((res) => { + if (res.status) { + setCacheEmailPass([...cacheEmailPass, email]); + nextStep(); + setEmailError(""); + setPwError(""); + setRePwError(""); + } + }) + .catch((e) => { + setCacheEmailFail([...cacheEmailFail, email]); + if (e === "Email đã tồn tại trên hệ thống.") { + setDisabledBtn(true); + setEmailError( + "Email đã tồn tại trên hệ thống. Vui lòng quay lại đăng nhập!" + ); + } else { + setEmailError(e); + } + return; + }); + } + return; + } + // checkEmail(); + checkPw(); + checkRePw(); + } + + const nextStep = () => { + }; + + const checkEmail = () => { + // if (!isEmail(email)) { + // setEmailError("Định dạng email không đúng"); + // } + }; + + const checkPw = () => { + if (password.length < 6 || password.trim() === "") { + 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"); + } + }; + + const checkRePw = () => { + if (password !== rePassword) { + setRePwError("Mật khẩu không khớp"); + } + }; + + const changeEmail = (value) => { + setDisabledBtn(false); + if (emailError) { + if (!!value) { + setEmailError(""); + } + } + setEmail(value.trim()); + }; + + + const changePhone = (value) => { + const validatedValue = value.replace(/[^0-9]/g, ""); + setPhone(validatedValue); + if (phoneWarning) { + if (value.length === 10 || value.length === 11) { + setPhoneWarning(""); + } + } + }; + + const changePassword = (value) => { + if (pwError) { + if (value.length >= 6) { + setPwError(""); + } + } + if (value == rePassword && !!rePwError) { + setRePwError(""); + } + setPassword(value); + }; + + const changeRePassword = (value) => { + if (rePwError) { + if (value === password) { + setRePwError(""); + } + } + setRePassword(value); + }; + + const onBlurField = (type) => { + switch (type) { + case "email": { + // if (email && !emailError) { + // checkEmail(); + // } + return; + } + case "password": { + if (password && !pwError) { + checkPw(); + } + return; + } + case "phoneNumber": { + if (phone && !phoneWarning) { + if (phone.length !== 10 && phone.length !== 11) { + setPhoneWarning("Số điện thoại hợp lệ có từ 10-11"); + } + if (phone && phone.length && phone[0] !== "0") { + setPhoneWarning("Định dạng số điện thoại không đúng"); + } + } + return; + } + default: { + if (rePassword && !rePwError) { + checkRePw(); + } + return; + } + } + }; + + const handleBack = () => { + history.push('/login') + } + + function validateParam() { + if ( + !!email && + password.length >= 6 && + rePassword === password && + password.trim() !== "" && + !disabledBtn + ) { + if (emailError) { + return false + } + return true; + } + return false; + } + + const renderEmailIcon = () => { + return ( + + + + ); + }; + + const renderPhoneIcon = () => { + return ( + + + + ); + }; + + const renderPasswordIcon = () => { + return ( + + + + ); + }; + + return ( +
    +
    +
    +
    +
    + { + onBlurField("email"); + }} + autoFocus = {true} + > + { + onBlurField("phone"); + }} + errorAbsolute={true} + > + { + onBlurField("password"); + }} + > + { + onBlurField("rePassword"); + }} + > +
    +
    + { + onBlurField("email"); + }} + autoFocus = {true} + > + { + onBlurField("phone"); + }} + errorAbsolute={true} + > + { + onBlurField("password"); + }} + > + { + onBlurField("rePassword"); + }} + > +
    +
    +
    + +
    +
    +

    + Đăng nhập +

    +
    +
    +
    +
    + ); +}; + +export default CreateAccount; diff --git a/src/_containers/RegisterPage/CreateAccount/index.scss b/src/_containers/RegisterPage/CreateAccount/index.scss new file mode 100644 index 0000000..9fee53c --- /dev/null +++ b/src/_containers/RegisterPage/CreateAccount/index.scss @@ -0,0 +1,66 @@ +.register_step { + .title_register { + margin-bottom: 18px; + + @media screen and (max-width: 768px) { + margin-bottom: 14px; + } + } + + .step_register_name { + font-size: 24px; + line-height: 28px; + + @media screen and (max-width: 768px) { + font-size: 18px; + } + } + + .login_text { + cursor: pointer; + + p, + a { + font-size: 18px; + } + + &:hover { + + p, + a { + color: #35b5c3; + } + } + } +} + +.register_create_account { + .step_register_name { + font-size: 24px; + line-height: 28px; + margin-bottom: 36px; + } +} + +.register-form-container_content { + max-width: 70%; + margin: 0 auto; + margin-top: 50px; + + .title { + font-size: 32px; + text-transform: uppercase; + margin-bottom: 22px; + } + + .button_submit { + display: flex; + justify-content: center; + margin: 24px 0; + } + +} + +.register-side { + flex: 1; +} \ No newline at end of file diff --git a/src/_containers/RegisterPage/index.js b/src/_containers/RegisterPage/index.js new file mode 100644 index 0000000..a9c94c8 --- /dev/null +++ b/src/_containers/RegisterPage/index.js @@ -0,0 +1,24 @@ +import { Link } from "react-router-dom"; +import { HeaderCurve } from "../../_components/Header"; +import { useState } from "react"; +import { STEP_REGISTER } from "../../_constants/register"; +import CreateAccount from "./CreateAccount"; + +export default function RegisterPage() { + + return ( +
    + +
    +
    +
    +

    Đăng ký đại lý

    +
    + +
    +
    +
    +
    +
    + ) +} \ No newline at end of file diff --git a/src/_helpers/apiCaller.js b/src/_helpers/apiCaller.js new file mode 100644 index 0000000..dee98a8 --- /dev/null +++ b/src/_helpers/apiCaller.js @@ -0,0 +1,149 @@ +import axios from "axios"; +import { configConstants } from "../_constants"; +import { history } from "./../_helpers"; +import $ from "jquery"; + +const authDefault = { + username: configConstants.AUTH_BASIC_USER_NAME, + password: configConstants.AUTH_BASIC_PASSWORD, +}; + +export function apiCaller( + endpoint, + method = "GET", + body = {}, + headers = null, + clearToken = true, + basUrl = configConstants.API_URL_SETEST, + isLoading = true, + isFullResponse = false, +) { + 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; + } + } else { + if (localStorage.getItem("authentication")) { + let authentication = JSON.parse(localStorage.getItem("authentication")); + headers["jwt_token"] = authentication.jwt_token; + } + headers = { + "X-API-KEY": configConstants.API_KEY, + ...headers, + } + } + if (isLoading) { + $(".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((res) => handleResponse(res, isLoading, isFullResponse)) + .catch((error) => { + if (isLoading) { + $(".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"); +} + +export function handleResponse(response, isLoading, isFullResponse) { + if (isLoading) { + $(".loading").addClass("hide"); + } + if(isFullResponse) { + return response.data; + } + if (!response.data.status) { + let msg = response.data.msg ? response.data.msg : response.data.error; + return Promise.reject(msg); + } else { + return response.data; + } +} + +export async function apiRequest(url = "/", data = {}) { + try { + let headers = { + "X-API-KEY": configConstants.API_KEY, + }; + if (localStorage.getItem("authentication")) { + let authentication = JSON.parse(localStorage.getItem("authentication")); + headers["jwt_token"] = authentication.jwt_token; + } + + const response = await axios({ + url: `${configConstants.API_URL_SETEST}${url}`, + auth: authDefault, + headers: headers, + ...data, + }); + + return response; + } catch (error) { + return { + status: false, + message: "Đã xảy ra lỗi vui lòng thử lại sau!", + }; + } +} + +export async function apiRequestLogout(url = "/", data = {}) { + try { + let headers = { + "X-API-KEY": configConstants.API_KEY, + }; + if (localStorage.getItem("authentication")) { + let authentication = JSON.parse(localStorage.getItem("authentication")); + headers["jwt_token"] = authentication.jwt_token; + } + + await axios({ + url: `${url}`, + method: "POST", + auth: authDefault, + headers: headers, + ...data, + }); + + } catch (error) { + + } +} diff --git a/src/_helpers/customHook/useOutsideClick.js b/src/_helpers/customHook/useOutsideClick.js new file mode 100644 index 0000000..2891eb6 --- /dev/null +++ b/src/_helpers/customHook/useOutsideClick.js @@ -0,0 +1,23 @@ +import { useEffect } from "react"; + +/** + * useOutsideClick: hàm để bắt sự kiện outside click + * @param ref dom cần check + * @param onOutSideClick function handle + */ +const useOutsideClick = (ref, onOutSideClick) => { + useEffect(() => { + function handleClickOutside(event) { + if (ref.current && !ref.current.contains(event.target)) { + onOutSideClick(); + } + } + document.addEventListener("mousedown", handleClickOutside); + + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, [ref]); +}; + +export default useOutsideClick; diff --git a/src/_helpers/history.js b/src/_helpers/history.js new file mode 100644 index 0000000..3e5753f --- /dev/null +++ b/src/_helpers/history.js @@ -0,0 +1,2 @@ +import { createBrowserHistory } from 'history'; +export const history = createBrowserHistory({ }); \ No newline at end of file diff --git a/src/_helpers/index.js b/src/_helpers/index.js new file mode 100644 index 0000000..135ddf3 --- /dev/null +++ b/src/_helpers/index.js @@ -0,0 +1,2 @@ +export * from './history'; +export * from './apiCaller'; \ No newline at end of file diff --git a/src/_helpers/validateEmail.js b/src/_helpers/validateEmail.js new file mode 100644 index 0000000..2dc196e --- /dev/null +++ b/src/_helpers/validateEmail.js @@ -0,0 +1,5 @@ +export function isEmail(email) { + return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test( + email + ); +} diff --git a/src/_reducers/Alert/index.js b/src/_reducers/Alert/index.js new file mode 100644 index 0000000..43c854f --- /dev/null +++ b/src/_reducers/Alert/index.js @@ -0,0 +1,28 @@ +import { alertConstants } from "./../../_constants"; +import { isEmpty } from "lodash"; +import { userConstants } from "./../../_constants"; + +export function alert(state = {}, action) { + switch (action.type) { + case alertConstants.SUCCESS: + return { + type: alertConstants.SUCCESS, + screen: !isEmpty(action.alert.screen) ? action.alert.screen : "", + message: action.alert.message, + }; + case alertConstants.ERROR: + return { + type: alertConstants.ERROR, + screen: !isEmpty(action.alert.screen) ? action.alert.screen : "", + message: action.alert.message, + ...action.alert + }; + case alertConstants.CLEAR: + return {}; + + case userConstants.RESET_ALL_STATE: + return {}; + default: + return state; + } +} diff --git a/src/_reducers/Authentication/authentiacionTeacherZalo.js b/src/_reducers/Authentication/authentiacionTeacherZalo.js new file mode 100644 index 0000000..0a36a20 --- /dev/null +++ b/src/_reducers/Authentication/authentiacionTeacherZalo.js @@ -0,0 +1,68 @@ +import { userConstants } from "./../../_constants"; +var initialState = { + codeSent: false, + timeRemaining: 30, + registerStatus: false, + dataAccountRegister: {}, + registerWithOtherZalo: true, + loginWhenNotVerify: false, +}; + +export const setTimeRemaining = (time) => ({ + type: userConstants.TIMEREMAINING, + payload: time, +}); + +const authenticationTeacherZalo = (state = initialState, action) => { + switch (action.type) { + case userConstants.CODE_SENT_ON: + return { + ...state, + codeSent: true + } + case userConstants.CODE_SENT_OFF: + return { + ...state, + codeSent: false + } + case userConstants.TIMEREMAINING: + return { + ...state, + timeRemaining: action.payload + } + case userConstants.REGISTER_STATUS: + return { + ...state, + registerStatus: true + } + case userConstants.RESET_REGISTER_STATUS: + return { + ...state, + registerStatus: false + } + case userConstants.SAVE_DATA_REGISTER: + return { + ...state, + dataAccountRegister: action.payload + } + case userConstants.REGISTER_WITH_OTHER_ZALO: + return { + ...state, + registerWithOtherZalo: false + } + case userConstants.LOGIN_WHEN_NOT_VERIFY: + return { + ...state, + loginWhenNotVerify: true + } + case userConstants.RESET_LOGIN_WHEN_NOT_VERIFY: + return { + ...state, + loginWhenNotVerify: false + } + default: + return state; + } +}; + +export { authenticationTeacherZalo }; diff --git a/src/_reducers/Authentication/index.js b/src/_reducers/Authentication/index.js new file mode 100644 index 0000000..ffa2120 --- /dev/null +++ b/src/_reducers/Authentication/index.js @@ -0,0 +1,23 @@ +import { userConstants } from "./../../_constants"; +var initialState = { + isLogin: false, +}; +if (localStorage.getItem("authentication")) { + initialState = JSON.parse(localStorage.getItem("authentication")); +} +const authentication = (state = initialState, action) => { + switch (action.type) { + case userConstants.LOGIN: + return action.user; + case userConstants.LOGOUT: + return { + isLogin: false, + }; + case userConstants.RESET_ALL_STATE: + return initialState; + default: + return state; + } +}; + +export { authentication }; diff --git a/src/_reducers/More/index.js b/src/_reducers/More/index.js new file mode 100644 index 0000000..f5be69b --- /dev/null +++ b/src/_reducers/More/index.js @@ -0,0 +1,5 @@ +export * from './licenses'; +export * from './schedules'; +export * from './profile'; +export * from './messages'; +export * from './setting'; diff --git a/src/_reducers/More/licenses.js b/src/_reducers/More/licenses.js new file mode 100644 index 0000000..a9ec5fe --- /dev/null +++ b/src/_reducers/More/licenses.js @@ -0,0 +1,23 @@ +import { licenseConstants } from './../../_constants'; +var initialState = { + listCurentLicenses: [], + listHistoryLicenses: [], +}; + +const licenses = (state = initialState, action) => { + switch (action.type) { + case licenseConstants.GET_CURRENT_LICENSE: + return { + ...state, + listCurentLicenses: action.listCurentLicenses + }; + case licenseConstants.GET_HISTORY_LICENSE: + return { + ...state, + listHistoryLicenses: action.listHistoryLicenses + }; + default: return state; + } +}; + +export { licenses }; \ No newline at end of file diff --git a/src/_reducers/More/messages.js b/src/_reducers/More/messages.js new file mode 100644 index 0000000..3aa9424 --- /dev/null +++ b/src/_reducers/More/messages.js @@ -0,0 +1,82 @@ +import { userConstants } from "../../_constants"; +var initialState = { + content_message: { + room_id: "", + to_user_id: "", + subject: "", + content: "", + reply_for_id: "", + class_id: "", + }, + data_message: { + data: [], + }, + detail_message: { + data: [], + }, + contact_info: { + data: [], + base_url: "", + }, + room_chat: "", + total_msg: { + number_msg_new: "", + number_system_new: "", + }, +}; + +const messages = (state = initialState, action) => { + switch (action.type) { + case userConstants.GET_CLASS_MESSAGE: + return { + data_message: action.data_message, + }; + case userConstants.RESET_CLASS_MESSAGE: + return { + data_message: {}, + }; + case userConstants.GET_CLASS_NOTIFICATION: + return { + data_message: { + data: action.data, + }, + }; + case userConstants.GET_DETAIL_MESSAGE: + return { + ...state, + detail_message: { + data: action.data, + }, + }; + case userConstants.SEND_MESSAGE: + return { + ...state, + content_message: action.data, + }; + case userConstants.GET_CONTACT_INFO: + return { + ...state, + contact_info: { + data: action.data, + base_url: action.base_url, + }, + }; + case userConstants.GET_ROOM_CHAT: + return { + ...state, + room_chat: action.data, + }; + case userConstants.GET_TOTAL_MESSAGE: + return { + ...state, + total_msg: { + number_msg_new: action.number_msg_new, + number_system_new: action.number_system_new, + }, + }; + default: + return state; + } +}; + +export { messages }; diff --git a/src/_reducers/More/profile.js b/src/_reducers/More/profile.js new file mode 100644 index 0000000..4975fa7 --- /dev/null +++ b/src/_reducers/More/profile.js @@ -0,0 +1,43 @@ +import { userConstants } from "./../../_constants"; +var initialState = { + fullname: "", + gender: "", + birthday: "", + email: "", + phone: "", + school: "", + base_url: "", + user_info: { + data: [], + }, + user_info_news: { + data: [], + }, +}; + +const profile = (state = initialState, action) => { + switch (action.type) { + case userConstants.GET_PROFILE: + return { + ...state, + base_url: action.base_url, + user_info: { + data: action.data, + }, + }; + case userConstants.GET_PROFILE_NEWS: + return { + ...state, + base_url: action.base_url, + user_info_news: { + data: action.data, + }, + }; + case userConstants.RESET_ALL_STATE: + return initialState; + default: + return state; + } +}; + +export { profile }; diff --git a/src/_reducers/More/schedules.js b/src/_reducers/More/schedules.js new file mode 100644 index 0000000..b92f649 --- /dev/null +++ b/src/_reducers/More/schedules.js @@ -0,0 +1,100 @@ +import { scheduleConstants } from "../../_constants"; +var initialState = { + moth: [], + today: [], + year: [], + timeTable: { + data: [], + valid_to: false, + }, + detail_today: { + title: "", + start_time: new Date(), + end_time: new Date(), + type: "personal", + content: "", + remind_time: 10, + repeat_type: "no_repeat", + checkRemind: true, + action: "add", + valid_to: new Date(), + }, + delete_schedule: { + showForm: false, + id: "", + updateAll: 0, + }, + dataAddScheduleYear: { + showForm: false, + }, + selectDate: "", + dateSelectedCalendar: "", + status: { + in_complete: [], + complete: [], + }, +}; + +const schedules = (state = initialState, action) => { + switch (action.type) { + case scheduleConstants.GET_SCHEDULE_TODAY: + return { + ...state, + today: action.today, + }; + case scheduleConstants.GET_TIME_TABLE: + return { + ...state, + timeTable: action.timeTable, + }; + case scheduleConstants.ADD_DETAIL_SCHEDULE_DAY: + return { + ...state, + detail_today: action.data, + }; + case scheduleConstants.REMOVE_DETAIL_SCHEDULE_DAY: + return { + ...state, + detail_today: initialState.detail_today, + }; + case scheduleConstants.ADD_DELETE_SCHEDULE_DAY: + return { + ...state, + delete_schedule: action.data, + }; + case scheduleConstants.RESET_DELETE_SCHEDULE_DAY: + return { + ...state, + delete_schedule: initialState.delete_schedule, + }; + case scheduleConstants.GET_SCHEDULE_YEAR: + return { + ...state, + year: action.year, + }; + case scheduleConstants.ADD_DATA_SCHEDULE_YEAR: + return { + ...state, + dataAddScheduleYear: action.dataAddScheduleYear, + }; + case scheduleConstants.SET_SELECT_DATE: + return { + ...state, + selectDate: action.time, + }; + case scheduleConstants.SET_DATE_SELECTED_CALENDAR: + return { + ...state, + dateSelectedCalendar: action.time, + }; + case scheduleConstants.GET_STATUS: + return { + ...state, + status: action.data, + }; + default: + return state; + } +}; + +export { schedules }; diff --git a/src/_reducers/More/setting.js b/src/_reducers/More/setting.js new file mode 100644 index 0000000..7d2581a --- /dev/null +++ b/src/_reducers/More/setting.js @@ -0,0 +1,27 @@ +import { userConstants } from '../../_constants'; +var initialState = { + 'data_setting': { + 'data': [] + }, + 'app_info': { + 'data': [] + } +}; + +const setting = (state = initialState, action) => { + switch (action.type) { + case userConstants.GET_SETTING_DETAIL: + return { + ...state, + data_setting: { + data: action.data.user_setting, + }, + app_info: { + data: action.data.app_info, + } + }; + default: return state; + } +}; + +export { setting }; \ No newline at end of file diff --git a/src/_reducers/Popup/index.js b/src/_reducers/Popup/index.js new file mode 100644 index 0000000..2cec809 --- /dev/null +++ b/src/_reducers/Popup/index.js @@ -0,0 +1,31 @@ +import { popupConstants } from '../../_constants'; +var initialState = { + 'showFormResetTimeTable': false, + 'showFormAddTimeTable': false, + 'showFormDetailTimeTable': false, + 'showFormAddScheduleYear': false, + 'showFormAddStudent': false, + 'showFormApplyClass': false, + 'showFilterCurriculum': false, + 'showAddFile': false, + 'addFileCompleteResource': false, + 'showFormAddTimeSchedule': false, + 'showFormRemind': false, +}; + +const Popup = (state = initialState, action) => { + switch (action.type) { + case popupConstants.CLEAR_ALL_POPUP: + return { + ...state, + ...initialState + }; + case popupConstants.SHOW_FORM_POPUP: + return { + ...action.data + }; + default: return state; + } +}; + +export { Popup }; \ No newline at end of file diff --git a/src/_reducers/Register/index.js b/src/_reducers/Register/index.js new file mode 100644 index 0000000..c1408e1 --- /dev/null +++ b/src/_reducers/Register/index.js @@ -0,0 +1,34 @@ +import { userConstants } from "./../../_constants"; +var initialState = { + email: "", + password: "", + re_password: "", + role: "", + username: "", + login_type: userConstants.LOGIN_TYPE_DEFAULT, +}; + +const register = (state = initialState, action) => { + switch (action.type) { + case userConstants.ADD_DATA_REGISTER: + return action.data; + case userConstants.CHANGE_LOGIN_TYPE: + return { + ...state, + login_type: userConstants.LOGIN_TYPE_SOCIAL, + email: action.data.email, + }; + case userConstants.RESET_LOGIN_TYPE: + return { + ...state, + login_type: userConstants.LOGIN_TYPE_DEFAULT, + email: "", + }; + case userConstants.RESET_ALL_STATE: + return initialState; + default: + return state; + } +}; + +export { register }; diff --git a/src/_reducers/Student/assessments.js b/src/_reducers/Student/assessments.js new file mode 100644 index 0000000..79bd973 --- /dev/null +++ b/src/_reducers/Student/assessments.js @@ -0,0 +1,58 @@ +import { studentConstants } from "../../_constants"; +import { userConstants } from "../../_constants"; +var initialState = { + online: { + number_vocab: "", + number_medal: "", + list_medal: [], + data_assessment: { + grammar_score: 0, + reading_score: 0, + speaking_score: 0, + listening_score: 0, + writing_score: 0, + test_score: 0, + grammar_score_change: 0, + reading_score_change: 0, + speaking_score_change: 0, + listening_score_change: 0, + writing_score_change: 0, + test_score_change: 0, + total_diamond: 0, + }, + }, + learning_by_date: { + data: [], + }, + logLearnings: { + data: { + recent_activity: [], + }, + }, +}; + +const assessments = (state = initialState, action) => { + switch (action.type) { + case studentConstants.GET_ASSESSMENT_ONLINE: + return { + ...state, + online: action.assessments, + }; + case studentConstants.GET_LOG_LEARNING_BY_DATE: + return { + ...state, + learning_by_date: action.learnings, + }; + case studentConstants.GET_LIST_LOG_LEARNING: + return { + ...state, + logLearnings: action.learnings, + }; + case userConstants.RESET_ALL_STATE: + return initialState; + default: + return state; + } +}; + +export { assessments }; diff --git a/src/_reducers/Student/curriculums.js b/src/_reducers/Student/curriculums.js new file mode 100644 index 0000000..5652c6a --- /dev/null +++ b/src/_reducers/Student/curriculums.js @@ -0,0 +1,59 @@ +import { curriculumConstants } from "../../_constants"; +import { userConstants } from "../../_constants"; +var initialState = { + data_map: { + data_lesson: { + unit_name: [], + }, + }, + data_grid: { + data: { + lesson_data: { + unit_name: [], + data: [], + }, + }, + }, + view: "map", + lessons: { + data: [], + }, + loading: true, +}; + +const curriculumStudent = (state = initialState, action) => { + switch (action.type) { + case curriculumConstants.GET_DATA_MAP_CURRICULUM_STUDENT_START: + return { + ...state, + loading: true, + }; + case curriculumConstants.GET_DATA_MAP_CURRICULUM_STUDENT: + return { + ...state, + loading: false, + data_map: action.data_map, + }; + case curriculumConstants.GET_DATA_GRID_CURRICULUM_STUDENT: + return { + ...state, + data_grid: action.data_grid, + }; + case curriculumConstants.CHANGE_VIEW: + return { + ...state, + view: action.view, + }; + case curriculumConstants.GET_LESSON_CURRICULUM_STUDENT: + return { + ...state, + lessons: action.lessons, + }; + case userConstants.RESET_ALL_STATE: + return initialState; + default: + return state; + } +}; + +export { curriculumStudent }; diff --git a/src/_reducers/Student/grades.js b/src/_reducers/Student/grades.js new file mode 100644 index 0000000..73c7094 --- /dev/null +++ b/src/_reducers/Student/grades.js @@ -0,0 +1,20 @@ +import { studentConstants } from "../../_constants"; +import { userConstants } from "../../_constants"; +var initialState = []; + +const grades = (state = initialState, action) => { + switch (action.type) { + case studentConstants.GET_ALL_GRADE: + return action.grade; + case studentConstants.LIST_CLASS_FILTER: + return { ...state, listGrade: action.payload }; + case studentConstants.LIST_ADDRESS_FILTER: + return { ...state, listAddress: action.payload }; + case userConstants.RESET_ALL_STATE: + return initialState; + default: + return state; + } +}; + +export { grades }; diff --git a/src/_reducers/Student/index.js b/src/_reducers/Student/index.js new file mode 100644 index 0000000..b2171b6 --- /dev/null +++ b/src/_reducers/Student/index.js @@ -0,0 +1,5 @@ +export * from './grades'; +export * from './learns'; +export * from './curriculums'; +export * from './assessments'; +export * from './rootlessness'; diff --git a/src/_reducers/Student/learns.js b/src/_reducers/Student/learns.js new file mode 100644 index 0000000..b524e42 --- /dev/null +++ b/src/_reducers/Student/learns.js @@ -0,0 +1,70 @@ +import { studentConstants } from "../../_constants"; +import { userConstants } from "../../_constants"; +var initialState = { + base_url: "", + data: { + latest_lesson_data: [], + list_teacher: [], + list_curriculum: [], + list_home_work: [], + list_exercise: [], + list_exercise_by_parent: [], + list_parent: [] + }, + exercises: { + list_home_work: [], + }, + homework_by_teacher: { + list_home_work_new: [], + list_home_work_complete: [], + }, + startLearning: { + redirect_url: "", + message: "", + status: false, + }, + statusHomeWork: "list_home_work_new", + homeworkSelected: undefined, +}; + +const learns = (state = initialState, action) => { + switch (action.type) { + case studentConstants.GET_LIST_DATA_LEARN: + return { + ...state, + data: action.learns.data, + base_url: action.learns.base_url, + }; + case studentConstants.GET_LIST_EXERCISE_STUDENT: + return { + ...state, + exercises: action.exercises, + }; + case studentConstants.GET_REDIRECT_URL: + return { + ...state, + startLearning: action.data, + }; + case studentConstants.STATUS_HOMEWORK: + return { + ...state, + statusHomeWork: action.data, + } + case studentConstants.CLEAR_STATUS_HOMEWORK: + return { + ...state, + statusHomeWork: "list_home_work_new" + } + case studentConstants.HOMEWORK_SELECTED: + return { + ...state, + homeworkSelected: action.data + } + case userConstants.RESET_ALL_STATE: + return initialState; + default: + return state; + } +}; + +export { learns }; diff --git a/src/_reducers/Student/rootlessness.js b/src/_reducers/Student/rootlessness.js new file mode 100644 index 0000000..336ef4b --- /dev/null +++ b/src/_reducers/Student/rootlessness.js @@ -0,0 +1,87 @@ +import { userConstants } from '../../_constants'; + +var initialState = { + isRootlessness: false, + isPlacementTest: false, + proposedCurriculum: false, + resultPlacementTest: {}, + chooseListCurriculum: false, + sideBarRootLessness: false, +}; + +const rootlessness = (state = initialState, action) => { + switch (action.type) { + case userConstants.SHOW_SIDEBAR_ROOTLESSNESS: + return { + ...state, + sideBarRootLessness: true, + }; + case userConstants.HIDE_SIDEBAR_ROOTLESSNESS: + return { + ...state, + sideBarRootLessness: false, + }; + case userConstants.ON_ROOTLESSNESS: + return { + ...state, + isRootlessness: true, + }; + case userConstants.OFF_ROOTLESSNESS: + return { + ...state, + isRootlessness: false, + } + case userConstants.ON_PLACEMENT_TEST: + return { + ...state, + isPlacementTest: true + } + case userConstants.OFF_PLACEMENT_TEST: + return { + ...state, + isPlacementTest: false + } + case userConstants.ON_PROPOSED_CURRICULUM: { + return { + ...state, + proposedCurriculum: true + } + } + case userConstants.OFF_PROPOSED_CURRICULUM: { + return { + ...state, + proposedCurriculum: false + } + } + case userConstants.ON_CHOOSE_LIST_CURRICULUM: { + return { + ...state, + chooseListCurriculum: true + } + } + case userConstants.OFF_CHOOSE_LIST_CURRICULUM: { + return { + ...state, + chooseListCurriculum: false + } + } + case userConstants.RESULT_PLACEMENT_TEST: { + return { + ...state, + resultPlacementTest: action.data + } + } + case userConstants.RESET_RESULT_PLACEMENT_TEST: { + return { + ...state, + resultPlacementTest: {} + } + } + case userConstants.RESET_ALL_PLACEMENT_TEST: { + return initialState + } + default: return state; + } +}; + +export { rootlessness }; \ No newline at end of file diff --git a/src/_reducers/Teacher/classes.js b/src/_reducers/Teacher/classes.js new file mode 100644 index 0000000..f442d76 --- /dev/null +++ b/src/_reducers/Teacher/classes.js @@ -0,0 +1,451 @@ +import { teacherConstants, userConstants } from "../../_constants"; +var initialState = { + base_url: "", + data: [], + roll_up: [], + exam_card: { + data: [], + list_score_percent: [], + list_exam_type: [], + }, + add_roll_up: { + date: new Date(), + }, + dataOffline: [], + detail: {}, + students: { + base_url: "", + data: [], + }, + requests: { + list_request: [], + }, + addStudent: { + user_data: { + avatar: "", + email: "", + fullname: "", + }, + }, + exercises: { + data_exercise: [], + data_lessons_selected: [], + students: [], + histories: { + data: [], + detail: { + data: { + incomplete: [], + completed: [], + list_class_detail: [], + }, + }, + }, + files: { + param: { + skill: [], + level: [], + grade_id: [], + }, + data: [], + }, + }, + originAttachFile: [], + originTime: { + startTime: new Date(), + endTime: new Date(), + }, + dateAddStudentExercise: { + start_time: new Date(), + end_time: new Date(), + }, + statusAttachFile: { + status: false, + }, + dataServiceTeacher: {}, + edit_exercises: {}, + homeworks: { + data: [], + detail: { + data: [], + avg_score: "", + min_score: "", + max_score: "", + exercise_name: "", + }, + exercises: { + exercise_data: { + to_fullname: "", + lesson_name: "", + status: "", + }, + resource_data: { + type: "", + path: "", + content: "", + }, + AI: { + result_content: [], + }, + edit_content: [], + }, + }, + student_ranking: { + data: [], + base_url: "", + }, + class_ranking: { + data: [], + }, + reports: { + total_student: "", + avg: 0, + overview_score: {}, + overview_exercise: {}, + students: { + student_data: { + base_url: "", + avatar: "", + }, + }, + log_learning: { + data: { + recent_activity: [], + }, + }, + learning_by_date: { + data: [], + }, + }, + criteria: [], + setting_assign: [], + data_assign_proposal: [], +}; + +const classes = (state = initialState, action) => { + switch (action.type) { + case teacherConstants.GET_LIST_CLASS: + return { + ...state, + base_url: action.classes.base_url, + data: action.classes.data, + }; + case teacherConstants.GET_LIST_CLASS_OFFLINE: + return { + ...state, + dataOffline: action.classes.data, + }; + case teacherConstants.GET_DETAIL_CLASS: + return { + ...state, + detail: action.class, + }; + case teacherConstants.GET_DETAIL_CLASS_OFFLINE: + return { + ...state, + detail: action.class?.class_info?.class_info, + roll_up: action.class.data_roll_up, + }; + case teacherConstants.GET_STUDENT_OFF_CLASS: + return { + ...state, + students: action.students, + }; + case teacherConstants.GET_STUDENT_REQUEST: + return { + ...state, + requests: action.requests, + }; + case teacherConstants.DELETE_STUDENT: + return { + ...state, + students: { + data: state.students.data.filter( + (student) => !action.students.includes(student.id) + ), + }, + }; + case teacherConstants.REMOVE_REQUEST_STUDENT: + return { + ...state, + requests: state.requests.filter( + (request) => !action.list_request_id.includes(request.id) + ), + }; + case teacherConstants.ADD_STUDENT: + return { + ...state, + addStudent: action.data, + }; + case teacherConstants.ADD_DATA_EXERCISE: + return { + ...state, + exercises: action.data, + }; + case teacherConstants.RESET_DATA_EXERCISE: + return { + ...state, + exercises: { + ...initialState.exercises, + data_exercise: [], + data_lessons_selected: [], + }, + edit_exercises: {}, + }; + case teacherConstants.GET_LIST_HISTORY_EXERCISE: + return { + ...state, + edit_exercises: {}, + exercises: { + ...state.exercises, + students: [], + histories: { + ...state.exercises.histories, + data: action.histories, + }, + }, + }; + + case teacherConstants.GET_DETAIL_HISTORY_EXERCISE: + return { + ...state, + exercises: { + ...state.exercises, + histories: { + ...state.exercises.histories, + detail: action.histories, + }, + }, + }; + case teacherConstants.ADD_DATA_FILE: + return { + ...state, + exercises: { + ...state.exercises, + files: { + ...state.files, + data: action.data, + }, + }, + }; + case teacherConstants.ADD_FILE_ATTACH_ORIGIN: + return { + ...state, + originAttachFile: action.data, + }; + case teacherConstants.ADD_TIME_TO_CHOOSE_FILE_SCREEN: + return { + ...state, + originTime: action.data, + }; + case teacherConstants.SAVE_DATE_ADD_STUDENT_EXERCISE: + return { + ...state, + dateAddStudentExercise: action.data, + }; + case teacherConstants.GET_LIST_HOMEWORK: + return { + ...state, + homeworks: { + ...state.homeworks, + data: action.homeworks, + }, + }; + case teacherConstants.GET_DETAIL_HOMEWORK: + return { + ...state, + homeworks: { + ...state.homeworks, + detail: action.homeworks, + }, + }; + case teacherConstants.GET_DETAIL_HOMEWORK_EXERCISE: + return { + ...state, + homeworks: { + ...state.homeworks, + exercises: action.exercises, + }, + }; + case teacherConstants.CALL_AI_HOMEWORK: + return { + ...state, + homeworks: { + ...state.homeworks, + exercises: { + ...state.homeworks.exercises, + AI: action.data, + edit_content: action.data.result_content, + }, + }, + }; + case teacherConstants.GET_STUDENT_RANKING: + return { + ...state, + student_ranking: { + data: action.data, + base_url: action.base_url, + }, + }; + case teacherConstants.GET_CLASS_RANKING: + return { + ...state, + class_ranking: { + data: action.data, + }, + }; + case teacherConstants.ADD_TIME_ADD_ROLL_UP: + return { + ...state, + add_roll_up: { + date: action.date, + }, + }; + case teacherConstants.GET_EXAM_CARD: + return { + ...state, + exam_card: action.exam_card, + }; + case teacherConstants.GET_LIST_REPORT_CLASS: + return { + ...state, + reports: { + ...state.reports, + base_url: action.reports.base_url, + overview_exercise: action.reports.overview_exercise, + overview_score: action.reports.overview_score, + total_score: action.reports.total_score, + total_student: action.reports.total_student, + avg: action.reports.avg, + total_exercise: action?.reports?.total_exercise, + }, + }; + case teacherConstants.GET_REPORT_BY_STUDENT_ID: + return { + ...state, + reports: { + ...state.reports, + students: action.students, + }, + }; + case teacherConstants.GET_LOG_LEARNING_BY_STUDENT_ID: + return { + ...state, + reports: { + ...state.reports, + log_learning: action.log_learning, + }, + }; + case teacherConstants.GET_LIST_CRITERIA: + return { + ...state, + criteria: action.criteria, + }; + case teacherConstants.EDIT_EXERCISE: + return { + ...state, + edit_exercises: action.exercises, + }; + case teacherConstants.SOURCE_PAGE_ADD_EXCERCISE: + return { + ...state, + sourcePageAddExcercise: action.sourcePageAddExcercise, + }; + case teacherConstants.GET_LOG_LEARNING_BY_DATE: + return { + ...state, + reports: { + ...state.reports, + learning_by_date: action.learnings, + }, + }; + case teacherConstants.GET_DATA_SETTING_ASSIGN: + return { + ...state, + setting_assign: action.setting, + }; + case teacherConstants.GET_DATA_ASSIGN_SPECIFIC: + return { + ...state, + data_assign_proposal: action.proposal, + }; + case teacherConstants.CLEAR_DATA_EXERCISES: + return { + ...state, + exercises: { + data_exercise: [], + data_lessons_selected: [], + students: [], + histories: { + data: [], + detail: { + data: { + incomplete: [], + completed: [], + list_class_detail: [], + }, + }, + }, + files: { + param: { + skill: [], + level: [], + grade_id: [], + }, + data: [], + }, + }, + data_assign_proposal: [], + setting_assign: [], + }; + case teacherConstants.CLEAR_ONLY_DATA_EXERCISES: + return { + ...state, + exercises: { + ...state.exercises, + data_exercise: [], + data_lessons_selected: [], + }, + data_assign_proposal: [], + setting_assign: [], + }; + case teacherConstants.ON_STATUS_ATTACH_FILE: + return { + ...state, + statusAttachFile: true, + }; + case teacherConstants.OFF_STATUS_ATTACH_FILE: + return { + ...state, + statusAttachFile: false, + }; + case teacherConstants.GET_SERVICE_TEACHER: + return { + ...state, + dataServiceTeacher: action.data, + }; + case teacherConstants.CLEAR_DATA_LESSONS: + return { + ...state, + exercises: { + ...state.exercises, + data_exercise: [], + data_lessons_selected: [], + files: { + param: { + skill: [], + level: [], + grade_id: [], + }, + data: [], + }, + }, + }; + case userConstants.RESET_ALL_STATE: + return initialState; + default: + return state; + } +}; + +export { classes }; diff --git a/src/_reducers/Teacher/curriculums.js b/src/_reducers/Teacher/curriculums.js new file mode 100644 index 0000000..55c6762 --- /dev/null +++ b/src/_reducers/Teacher/curriculums.js @@ -0,0 +1,127 @@ +import { curriculumConstants } from "../../_constants"; +import { userConstants } from "../../_constants"; +var initialState = { + data: [], + detail_class: { + id: "", + curriculum_data: {}, + }, + detail: { + data_lesson: { + unit_name: [], + }, + }, + lesson_skill: {}, + filters: { + param: { + topic: "", + skill: [], + level: [], + grade_id: [], + type: [], + start_time: "", + end_time: "", + }, + data: [], + }, + fromPage: null, + view: "map", + loading: false, + lessonInSkill: [], +}; + +const curriculums = (state = initialState, action) => { + switch (action.type) { + case curriculumConstants.GET_LIST_CURRICULUM: + return { + ...state, + data: action.curriculums, + }; + case curriculumConstants.GET_LIST_CURRICULUM_EXERCISE: + return { + ...state, + data: action.curriculums, + detail: state.detail, + }; + case curriculumConstants.GET_LIST_CURRICULUM_FAVORITE_START: + return { + ...state, + loading: true, + }; + case curriculumConstants.GET_LIST_CURRICULUM_FAVORITE: + return { + ...state, + data: action.curriculums.data, + loading: false, + }; + case curriculumConstants.GET_DETAIL_CURRICULUM_CLASS: + return { + ...state, + detail_class: action.curriculum, + }; + case curriculumConstants.CLEAR_DETAIL_CURRICULUM_CLASS: + return { + ...state, + detail_class: initialState.detail_class, + }; + + case curriculumConstants.GET_DETAIL_CURRICULUM: + return { + ...state, + detail: action.curriculum, + loading: false, + }; + case curriculumConstants.LESSON_BY_SKILL_TEACHER: + return { + ...state, + lesson_skill: action.lesson_skill, + loading: false, + }; + case curriculumConstants.GET_FILTER_CURRICULUM: + return { + ...state, + filters: { ...state.filters, data: action.data }, + }; + case curriculumConstants.ADD_PARAM_FILTER_CURRICULUM: + return { + ...state, + filters: { ...state.filters, param: action.param }, + }; + case curriculumConstants.CLEAR_PARAM_FILTER_CURRICULUM: + return { + ...state, + filters: { ...state.filters, param: initialState.filters.param }, + }; + case curriculumConstants.CHANGE_VIEW: + return { + ...state, + view: action.view, + }; + case curriculumConstants.RESET_DETAIL: + return { + ...state, + detail: initialState.detail, + }; + case curriculumConstants.FROM_PAGE_STATUS: + return { + ...state, + fromPage: action.data, + }; + case curriculumConstants.CLEAR_FROM_PAGE: + return { + ...state, + fromPage: null, + }; + case curriculumConstants.GET_LESSON_IN_SKILL: + return { + ...state, + lessonInSkill: action.payload, + }; + case userConstants.RESET_ALL_STATE: + return initialState; + default: + return state; + } +}; + +export { curriculums }; diff --git a/src/_reducers/Teacher/index.js b/src/_reducers/Teacher/index.js new file mode 100644 index 0000000..c75adf5 --- /dev/null +++ b/src/_reducers/Teacher/index.js @@ -0,0 +1,2 @@ +export * from './classes'; +export * from './curriculums'; diff --git a/src/_reducers/home_reducer/index.js b/src/_reducers/home_reducer/index.js new file mode 100644 index 0000000..7bec90d --- /dev/null +++ b/src/_reducers/home_reducer/index.js @@ -0,0 +1,14 @@ +import { homeType } from "./../../_constants"; +import { userConstants } from "./../../_constants"; +import { isEmpty } from "lodash"; + +export function home_page_reducer(state = {}, action) { + switch (action.type) { + case homeType.SELECT_TEACHER_OR_CURRICULUM: + return { ...state, itemActiveHomeStudent: action.payload }; + case userConstants.RESET_ALL_STATE: + return {}; + default: + return state; + } +} diff --git a/src/_reducers/index.js b/src/_reducers/index.js new file mode 100644 index 0000000..1604fb8 --- /dev/null +++ b/src/_reducers/index.js @@ -0,0 +1,33 @@ +import { combineReducers } from 'redux'; +import { authentication } from './Authentication'; +import { register } from './Register'; +import { alert } from './Alert'; +import { grades, learns, curriculumStudent,assessments, rootlessness } from './Student'; +import { classes, curriculums } from './Teacher'; +import { licenses, schedules, profile, messages, setting } from './More'; +import { home_page_reducer } from "./home_reducer" +import { Popup } from './Popup'; +import { authenticationTeacherZalo } from './Authentication/authentiacionTeacherZalo' + +const appReducers = combineReducers({ + authentication, + register, + alert, + grades, + licenses, + classes, + schedules, + curriculums, + Popup, + profile, + messages, + learns, + setting, + curriculumStudent, + assessments, + home_page_reducer, + rootlessness, + authenticationTeacherZalo +}); + +export default appReducers; \ No newline at end of file diff --git a/src/_services/index.js b/src/_services/index.js new file mode 100644 index 0000000..ca06fc5 --- /dev/null +++ b/src/_services/index.js @@ -0,0 +1,3 @@ +export * from './teachers'; +export * from './students'; +export * from './schedules'; \ No newline at end of file diff --git a/src/_services/schedules.js b/src/_services/schedules.js new file mode 100644 index 0000000..8dc9465 --- /dev/null +++ b/src/_services/schedules.js @@ -0,0 +1,23 @@ +import { apiCaller } from "./../_helpers"; + +export const scheduleService = { + getScheduleStatus, + markSystemSeen, +}; + +function getScheduleStatus(month, year) { + return apiCaller( + "/API_schedule/schedule_status?month=" + month + "&year=" + year, + "GET", + {}, + null, + true + ); +} + +function markSystemSeen(msgId) { + let body = new URLSearchParams({ + msg_id: msgId, + }); + return apiCaller("/api_inbox/mark_system_seen", "PUT", body, null, true); +} diff --git a/src/_services/students.js b/src/_services/students.js new file mode 100644 index 0000000..7818212 --- /dev/null +++ b/src/_services/students.js @@ -0,0 +1,518 @@ +import { configConstants } from "../_constants"; +import { apiCaller, apiRequest } from "./../_helpers"; + +export const studentService = { + getListDataLearn, + getHomeWorkByTeacher, + getListCurriculum, + getExercise, + getOfflineAssessment, + getRankAssessment, + getLarningHistory, + getVocabulary, + getListDataLearnV2, + getStudentLesson, + getListCurriculumHistory, + startDoMasterUnit, + saveResultMasterUnit, + getListCurriculumHistoryMasterUnit, + getListCurriculumMasterUnit, + getLessonMasterUnit, + learn_exam, + getDetailStudyGuild, + getExamTestService, + getExamTestHistoryService, + getDetailExamTestHistoryService, + startDoExamService, + saveExamService, + getDetailExamResult, + getDetailMockTest, + getExamTestServiceNews, + getListCurriculumFirstStep, + postCurriculumFirstStep, + getCalenderList, + postStudySchedule, + getPlacementTest, + getResultPlacementTest, + getVocabularyByClass, + getVocabularyDetail, + getMyClassesV2, + getDetailHomeWorkExercise, + getInfoStudent, + loadCurriculumRootLessness, + cancelEntranceExam, + getListClassStudentOnline, + getHomeWorkByParent, + getListMyParent, + getListInvitation, + removeParent, + acceptInvitationParent, + checkParent +}; + +function checkParent(email) { + return apiCaller( + `/api_relationship/check_parent?email=${email}`, + "GET", + {}, + null, + true, + configConstants.API_URL_SETEST, + true, + true + ); +} + +function acceptInvitationParent(data) { + return apiCaller( + `/api_relationship/confirm_relationship`, + "POST", + data, + null, + true + ); +} + +function removeParent(parent_id, type) { + return apiCaller( + `/api_relationship/invitation_delete?parent_id=${parent_id}&type=${type}`, + "GET", + {}, + null, + true + ); +} + +function getListMyParent() { + return apiCaller( + "/api_relationship/my_parent", + "GET", + {}, + null, + true + ); +} + +function getListInvitation() { + return apiCaller( + "/api_relationship/invitation_list", + "GET", + {}, + null, + true + ); +} + +function getListDataLearn() { + return apiCaller("/api_student/data_learn_screen", "GET", {}, null, true); +} + +function getHomeWorkByTeacher(teacher_id) { + return apiCaller( + "/api_student/homework_by_teacher?teacher_id=" + teacher_id, + "GET", + {}, + null, + true + ); +} + +function getHomeWorkByParent(parent_id) { + return apiCaller( + "/api_student/homework_by_parent?parent_id=" + parent_id, + "GET", + {}, + null, + true + ); +} + +function getListCurriculum() { + return apiCaller( + "/student/api_student_curriculum/courses_name_follow_class_v2", + "GET", + {}, + null, + true + ); +} + +function getExercise( + teacher_id, + class_id = null, + limit = configConstants.DEFAULT_LIMIT, + offset = 0 +) { + return apiCaller( + "/api_user_exercise/my_homework?teacher=" + + JSON.stringify([teacher_id]) + + (class_id ? "&class_id=" + class_id : "") + + `&limit=${limit}&offset=${offset}`, + "GET", + {}, + null, + true + ); +} + +function getOfflineAssessment() { + return apiCaller("/api_class_offline/achievements", "GET", {}, null, true); +} + +function getRankAssessment(limit, offset) { + return apiCaller( + `/api_student/ranking?limit=${limit}&offset=${offset}&type=total`, + "GET", + {}, + null, + true + ); +} + +function getLarningHistory(student_id, from_time, to_time) { + return apiCaller( + "/api_student/learning_history?student_id=" + + student_id + + "&from_time=" + + from_time + + "&to_time=" + + to_time, + "GET", + {}, + null, + false + ); +} + +function getVocabulary() { + return apiCaller("/api_student/student_vocab", "GET", {}, null, true); +} + +function getVocabularyByClass(class_id) { + return apiCaller( + "/api_student/student_vocab_by_class?class_id=" + class_id, + "GET", + {}, + null, + true + ); +} + +function getVocabularyDetail(grade_id, student_id) { + return apiCaller( + `/api_student/student_vocab_detail?grade_id=${grade_id}&student_id=${student_id}`, + "GET", + {}, + null, + true + ); +} + +function getMyClassesV2() { + return apiCaller(`/api_class/my_classes_v2`, "GET", {}, null, true); +} + +function getListDataLearnV2() { + return apiCaller( + "/api_student/data_learn_screen_v2", + "GET", + {}, + null, + true, + configConstants.API_URL_SETEST, + false + ); +} + +function getStudentLesson(lesson_id) { + return apiCaller( + "/api_lesson/launch_lesson?lesson_id=" + lesson_id, + "GET", + {}, + null, + true + ); + // return apiCaller(`/student/api_student_lesson/launch_homework?lesson_id=${lesson_id}&lesson_type=${lesson_type}&question_type=${question_type}`, 'GET', {}, null, true) +} + +function getListCurriculumHistory(id, type, class_id) { + return apiCaller( + `/student/api_student_lesson/lesson_history?lesson_id=${id}&lesson_type=${type}&class_id=${class_id}`, + "GET", + {}, + null, + true + ); +} + +// Master Unit + +function startDoMasterUnit(looking_back_id, type_lesson) { + let params = `id=${looking_back_id}&type=${type_lesson}`; + return apiCaller( + `/student/api_student_lesson/looking_back_detail?${params}`, + "GET", + {}, + null, + true + ); +} + +function saveResultMasterUnit(data) { + return apiCaller( + `/api_log_learning/learning_improvement`, + "POST", + data, + null, + true + ); +} + +function getListCurriculumHistoryMasterUnit(id, type) { + return apiCaller( + `/api_log_learning/master_unit_utilize?id=${id}&type=${type}`, + "GET", + {}, + null, + true + ); +} + +function getListCurriculumMasterUnit(id, status, limit, offset) { + return apiCaller( + `/student/api_student_lesson/looking_back?class_id=${id}&status=${status}&limit=${limit}&offset=${offset}`, + "GET", + {}, + null, + true + ); +} + +function getLessonMasterUnit(id) { + return apiCaller( + `/student/api_student_lesson/lesson_url?id=${id}`, + "GET", + {}, + null, + true + ); +} + +// Exam +function learn_exam(id, type) { + return apiCaller( + `/student/api_exam/exam_url?id=${id}&type=${type}`, + "GET", + {}, + null, + true + ); +} + +function getDetailMockTest(id) { + return apiCaller( + `/student/api_exam/mock_test_info?mock_test_id=${id}`, + "GET", + {}, + null, + true + ); +} + +function getDetailStudyGuild(id) { + return apiCaller( + `/api_lesson/homework?user_exercise_id=${id}`, + "GET", + {}, + null, + true + ); +} + +function getExamTestService(param) { + let params = `purpose=${param.purpose}&limit=${param.limit}&offset=${param.offset}`; + if (param.gradeId) { + params = params + `&grade_id=${param.gradeId}`; + } + if (param.addressId) { + params = params + `&address_id=${param.addressId}`; + } + return apiCaller( + `/student/api_exam/mock_test?${params}`, + "GET", + {}, + null, + true + ); +} + +function getExamTestServiceNews(param) { + let params = `limit=${param.limit}&offset=${param.offset}`; + if (param.gradeId) { + params = params + `&grade_id=${param.gradeId}`; + } + if (param.addressId) { + params = params + `&address_id=${param.addressId}`; + } + + if (param.purpose) { + params = params + `&purpose=${param.purpose}`; + } + if (param.key_search) { + params = params + `&key_search=${param.key_search}`; + } + return apiCaller( + `/web_advertise/api_lecture/mock_test?${params}`, + "GET", + {}, + null, + true + ); +} + +function getExamTestHistoryService(gradeId, addressId) { + let params = ""; + if (gradeId) { + params = `grade_id=${gradeId}`; + } + if (addressId) { + params = + params.length === 0 + ? `address_id=${addressId}` + : params + `&address_id=${addressId}`; + } + return apiCaller( + `/student/api_exam/mock_test_history?${params}`, + "GET", + {}, + null, + true + ); // ?grade_id=${gradeId}&address_id=${addressId} +} + +function getDetailExamTestHistoryService(id) { + return apiCaller( + `/student/api_exam/mock_test_history_detail?user_exam_result_id=${id}`, + "GET", + {}, + null, + true + ); // ?grade_id=${gradeId}&address_id=${addressId} +} + +function startDoExamService( + testId, + typeExam, + classId, + unitId, + isHomeWork, + curriculumId +) { + let params = `id=${testId}&type=${typeExam}&is_homework=${ + isHomeWork ? 1 : 0 + }`; + if (classId) { + params = params + `&class_id=${classId}`; + } + if (unitId) { + params = params + `&unit_id=${unitId}`; + } + if (curriculumId) { + params = params + `&curriculum_id=${curriculumId}`; + } + + return apiCaller( + `/student/api_exam/exam_v2?${params}`, + "GET", + {}, + null, + true + ); +} + +function saveExamService(data) { + return apiCaller(`/api_log_learning/save_exam_v2`, "POST", data, null, true); +} + +function getDetailExamResult(examId) { + return apiCaller( + `/student/api_student_lesson/load_exam_result?id=${examId}`, + "GET", + {}, + null, + true + ); +} + +function getListCurriculumFirstStep() { + return apiCaller("/student/rl_005", "GET", {}, null, true); +} + +function postCurriculumFirstStep(data) { + return apiCaller("/student/rl_006", "POST", data, null, true); +} + +function getCalenderList() { + return apiCaller("/student/rl_001", "GET", {}, null, true); +} + +function postStudySchedule(data) { + return apiCaller("/student/rl_002", "POST", data, null, true); +} + +function cancelEntranceExam() { + return apiCaller("/student/rl_009", "GET", {}, null, true); +} + +function getPlacementTest() { + return apiCaller( + "/student/api_rootlessness/placement_test_check", + "GET", + {}, + null, + true + ); +} + +function getResultPlacementTest() { + return apiCaller("/student/rl_003", "GET", {}, null, true); +} + +function getDetailHomeWorkExercise(user_exercise_id, library, exercise_type) { + return apiCaller( + "/student/api_homework/homework_detail?user_exercise_id=" + + user_exercise_id + + "&library=" + + library + + "&exercise_type=" + + exercise_type, + "GET", + {}, + null, + true + ); +} + +function getInfoStudent(id) { + return apiCaller(`/api_user/user?id=${id}`, "GET", {}, null, true); +} + +function loadCurriculumRootLessness() { + return apiCaller("/student/rl_007", "GET", {}, null, true); +} + +async function getListClassStudentOnline(limit, offset, at_class) { + let params = `limit=${limit}&offset=${offset}${ + at_class ? "&at_class=" + at_class : "" + }`; + try { + let data = { + method: "GET", + }; + let res = await apiRequest(`/api_student/my_classes/?${params}`, data); + if (res.status === 200) { + return res.data; + } + return []; + } catch (err) {} +} diff --git a/src/_services/teachers.js b/src/_services/teachers.js new file mode 100644 index 0000000..e67e82f --- /dev/null +++ b/src/_services/teachers.js @@ -0,0 +1,389 @@ +import { configConstants } from "../_constants"; +import { apiCaller, apiRequest } from "./../_helpers"; + +export const teacherService = { + getDetailHomeWorkExercise, + getCriteriaWorkExercise, + getStudentOfClass, + getSettingDetail, + learn, + getInboxInfo, + getDetailInbox, + getDetailContact, + getRoomChat, + sendMessage, + getSystemNotification, + getExamCardDetail, + getListClassOnlineAsync, + getListClassOfflineAsync, + getDetailClass, + getListClass, + getCurriculum, + getCurriculumFavorite, + getDetailCurriculumById, + getDetailHomeWork, + getHistoryExerciseWithoutClass, + deleteRollUp, + getDataAssignSetting, + getDataAssignProposal, + postAssignSpecific, + getListClassOnlineAsyncLimit, + getListClassOfflineAsyncLimit, + getDetailCurriculumByIdNew, + deleteScoreBr, + getLessonBySkillTeacher, +}; + +function getDetailHomeWorkExercise(user_exercise_id, library, exercise_type) { + return apiCaller( + "/student/api_homework/homework_detail?user_exercise_id=" + + user_exercise_id + + "&library=" + + library + + "&exercise_type=" + + exercise_type, + "GET", + {}, + null, + true + ); +} + +function getCriteriaWorkExercise(exercise_id) { + return apiCaller( + "/api_class/load_exercise_criteria?exercise_id=" + exercise_id, + "GET", + {}, + null, + true + ); +} + +function getStudentOfClass(id, limit, offset, isLoading) { + return apiCaller( + "/api_class/students?limit=" + + limit + + "&offset=" + + offset + + "&class_id=" + + id, + "GET", + {}, + null, + true, + configConstants.API_URL_SETEST, + isLoading + ); +} + +function getSettingDetail(device_id, type) { + return apiCaller( + "/api_user/load_setting_app?device_id=" + device_id + "&type=" + type, + "GET", + {}, + null, + true + ); +} + +function learn(lesson_id) { + return apiCaller( + "/api_lesson/launch_lesson?lesson_id=" + lesson_id, + "GET", + {}, + null, + true + ); +} + +function getInboxInfo(classId) { + let url = "/api_inbox/inbox" + (classId ? "?class_id=" + classId : ""); + return apiCaller( + url, + "GET", + {}, + null, + true, + configConstants.API_URL_SETEST, + false + ); +} + +function getDetailInbox(id) { + return apiCaller("/api_inbox/inbox_detail?id=" + id, "GET", {}, null, true); +} + +function getDetailContact(class_id, role) { + const url = class_id ? "&class_id=" + class_id : ""; + return apiCaller( + "/api_inbox/list_contact?user_role=" + role + url, + "GET", + {}, + null, + true + ); +} + +function getRoomChat(id) { + return apiCaller( + "/api_inbox/check_room?to_user_id=" + id, + "GET", + {}, + null, + true + ); +} + +function sendMessage(data) { + return apiCaller("/api_inbox/send", "POST", data, null, false); +} + +function getSystemNotification(class_id) { + const url = class_id ? "?class_id=" + class_id : ""; + return apiCaller("/api_inbox/inbox_system" + url, "GET", {}, null, true); +} + +function getExamCardDetail(cartId) { + return apiCaller( + "/api_class_offline/exam_card_detail?card_id=" + cartId, + "GET", + {}, + null, + true + ); +} + +async function getListClassOnlineAsync() { + try { + let data = { + method: "GET", + }; + let res = await apiRequest("/api_class/my_classes", data); + if (res.status === 200) { + return res.data; + } + return []; + } catch (err) {} +} + +async function getListClassOnlineAsyncLimit(limit, offset, screen) { + let params = `limit=${limit}&offset=${offset}&screen=${screen}`; + try { + let data = { + method: "GET", + }; + let res = await apiRequest(`/api_teacher/my_classes/?${params}`, data); + if (res.status === 200) { + return res.data; + } + return []; + } catch (err) {} +} + +async function getListClassOfflineAsync() { + try { + let data = { + method: "GET", + }; + let res = await apiRequest("/api_class_offline/my_classes", data); + if (res.status === 200) { + return res.data; + } + return []; + } catch (err) {} +} +async function getListClassOfflineAsyncLimit(limit, offset) { + let params = `limit=${limit}&offset=${offset}`; + try { + let data = { + method: "GET", + }; + let res = await apiRequest(`/api_class_offline/my_classes?${params}`, data); + if (res.status === 200) { + return res.data; + } + return []; + } catch (err) {} +} + +async function getDetailClass(id) { + try { + let data = { + method: "GET", + }; + let res = await apiRequest("/api_class/class?id=" + id, data); + if (res.status === 200) { + return res.data; + } + return []; + } catch (err) {} +} + +function getListClass() { + return apiCaller("/api_class/my_classes", "GET", {}, null, true); +} + +function getCurriculum(type) { + return apiCaller( + "/api_curriculum/courses_name?type=" + type, + "GET", + {}, + null, + true + ); +} + +function getCurriculumFavorite(user_id) { + return apiCaller( + "/api_wish_list/my_wish_list?user_id=" + user_id, + "GET", + {}, + null, + true + ); +} + +function getDetailCurriculumById(id) { + return apiCaller("/api_curriculum/course?id=" + id, "GET", {}, null, true); +} + +function getDetailCurriculumByIdNew(id) { + return apiCaller( + "/api_curriculum/course_bycurriculumid?id=" + id, + "GET", + {}, + null, + true + ); +} + +function getLessonBySkillTeacher(id) { + return apiCaller( + "/api_curriculum/lessons_by_skill?unit_id=" + id, + "GET", + {}, + null, + true + ); +} + +function getDetailHomeWork(class_id, exercise_id, library, type) { + return apiCaller( + "/api_class/home_work_detail?class_id=" + + class_id + + "&exercise_id=" + + exercise_id + + "&library=" + + library, + "GET", + {}, + null, + true + ); +} + +function getHistoryExerciseWithoutClass( + param = { skill: [] }, + filter_time = false, + offset = 0, + pageSize = 30 +) { + let uri = `/api_class/class_homework_v2?type=all&limit=${pageSize}&offset=${offset}`; + param.skill.forEach((skill) => { + uri += "&skill[]=" + skill.toLocaleLowerCase(); + }); + if (filter_time) { + uri += "&from_date=" + param.start_time + "&to_date=" + param.end_time; + } + return apiCaller(uri, "GET", {}, null, true); +} + +// Update Class Offline + +// Roll Up +async function deleteRollUp(id) { + var urlencoded = new URLSearchParams(); + urlencoded.append("id", id); + try { + const res = await apiCaller( + `/api_class_offline/roll_up`, + "DELETE", + urlencoded, + null, + true + ); + return res; + } catch (e) {} +} + +// Roll Up +async function deleteScoreBr(id) { + var body = { + card_id: id, + }; + try { + const res = await apiCaller( + `/api_class_offline/class_exam_card`, + "PUT", + body, + null, + true + ); + return res; + } catch (e) {} +} + +// Assign Specific +async function getDataAssignSetting(class_id, student_list) { + try { + const res = await apiCaller( + "/api_assignment/setting_default?id_class=" + + class_id + + "&student_list=" + + student_list, + "GET", + {}, + null, + true + ); + return res; + } catch (e) { + return e?.toString(); + } +} + +async function getDataAssignProposal(type, body) { + try { + const res = await apiCaller( + "/api_assignment/" + type, + "POST", + body, + null, + true + ); + return res; + } catch (e) {} +} + +async function postAssignSpecific(data) { + var urlencoded = new URLSearchParams(); + urlencoded.append("students", JSON.stringify(data.students)); + urlencoded.append("exercise_per_hs", JSON.stringify(data.exercise_per_hs)); + urlencoded.append("before_start_time", data.before_start_time); + urlencoded.append("end_time", data?.end_time); + urlencoded.append("start_time", data?.start_time); + urlencoded.append("class_id", data.class_id); + urlencoded.append("note", data.note); + urlencoded.append("remind_before", data.remind_before); + + try { + const res = await apiCaller( + "/api_assignment/assign_homework", + "POST", + urlencoded, + null, + true + ); + return res; + } catch (e) {} +} diff --git a/src/_services/user.js b/src/_services/user.js new file mode 100644 index 0000000..aa9b0a6 --- /dev/null +++ b/src/_services/user.js @@ -0,0 +1,71 @@ +import { apiCaller, apiRequest } from "../_helpers"; + +export async function logoutAuth(deviceId) { + try { + let data = { + method: "POST", + }; + + const res = await apiRequest("/api_user/logout", data); + + // console.log("logoutAuth", res); + } catch (e) {} +} + +export async function getLocationService() { + try { + let data = { + method: "GET", + }; + const res = await apiRequest("/web_advertise/api_lecture/list_address", data); + return res; + } catch (e) {} +} + +export async function getListClassService() { + try { + const res = await apiRequest("/api_login/grade", "GET", {}, null, false); + return res; + } catch (e) {} +} + +export async function deleteAccount() { + try { + let data = { + method: "PUT", + }; + const res = await apiRequest("/api_user/delete", data); + return res; + } catch (e) {} +} + +// Send Msg +export function sendMsgContact(data) { + return apiCaller( + `/web_advertise/api_contact/send_contact`, + "POST", + data, + null, + true + ); +} + +export const getProvinces = () => { + return apiCaller( + '/api_category/provinces?country_code=vn', + "GET", + {}, + null, + true, + ); +} + +export const getDistricts = (provinceAlias) => { + return apiCaller( + `/api_category/districts?province_alias=${provinceAlias}`, + "GET", + {}, + null, + true, + ); +} \ No newline at end of file diff --git a/src/_styles/_mixin.scss b/src/_styles/_mixin.scss new file mode 100644 index 0000000..a5fd6d1 --- /dev/null +++ b/src/_styles/_mixin.scss @@ -0,0 +1,25 @@ +$screen_tablet: 63.9375em; +$screen_mobile: 48em; + +@mixin screen_pc { + @media screen and (min-width: 64em) { + @content; + } +} + +@mixin screen_xl { + @media screen and (min-width: 64em) and (max-width: 75em) { + @content; + } +} +@mixin screen_tablet { + @media screen and (min-width: 48.01em) and (max-width: $screen_tablet) { + @content; + } +} + +@mixin screen_mobile { + @media screen and (max-width: $screen_mobile) { + @content; + } +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..bdc359e --- /dev/null +++ b/src/index.js @@ -0,0 +1,41 @@ +import React from "react"; +import ReactDOM from "react-dom"; +import App from "./App"; +import registerServiceWorker from "./registerServiceWorker"; +import { createStore, applyMiddleware, compose } from "redux"; +import appReducers from "./_reducers"; +import { Provider } from "react-redux"; +import reduxThunk from "redux-thunk"; +import GlobalStyles from "./_components/GlobalStyles"; +import { persistStore, persistReducer } from "redux-persist"; +import ReduxPersist from "./_config/ReduxPersist"; +import { PersistGate } from "redux-persist/integration/react"; + +const middleware = [reduxThunk]; + +const persistedReducer = persistReducer(ReduxPersist.storeConfig, appReducers); + +const store = createStore( + persistedReducer, + compose( + applyMiddleware(...middleware), + typeof window.__REDUX_DEVTOOLS_EXTENSION__ === "undefined" + ? (a) => a + : window.__REDUX_DEVTOOLS_EXTENSION__ && + window.__REDUX_DEVTOOLS_EXTENSION__() + ) +); + +export const persistor = persistStore(store); + +ReactDOM.render( + + + + + + + , + document.getElementById("root") +); +registerServiceWorker(); diff --git a/src/registerServiceWorker.js b/src/registerServiceWorker.js new file mode 100644 index 0000000..00f563a --- /dev/null +++ b/src/registerServiceWorker.js @@ -0,0 +1,108 @@ +// In production, we register a service worker to serve assets from local cache. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on the "N+1" visit to a page, since previously +// cached resources are updated in the background. + +// To learn more about the benefits of this model, read https://goo.gl/KwvDNy. +// This link also includes instructions on opting out of this behavior. + +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.1/8 is considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) + ); + + export default function register() { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL(process.env.PUBLIC_URL, window.location); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 + return; + } + + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + + if (!isLocalhost) { + // Is not local host. Just register service worker + registerValidSW(swUrl); + } else { + // This is running on localhost. Lets check if a service worker still exists or not. + checkValidServiceWorker(swUrl); + } + }); + } + } + + function registerValidSW(swUrl) { + navigator.serviceWorker + .register(swUrl) + .then(registration => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the old content will have been purged and + // the fresh content will have been added to the cache. + // It's the perfect time to display a "New content is + // available; please refresh." message in your web app. + console.log('New content is available; please refresh.'); + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.'); + } + } + }; + }; + }) + .catch(error => { + // console.error('Error during service worker registration:', error); + }); + } + + function checkValidServiceWorker(swUrl) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl) + .then(response => { + // Ensure service worker exists, and that we really are getting a JS file. + if ( + response.status === 404 || + response.headers.get('content-type').indexOf('javascript') === -1 + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then(registration => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl); + } + }) + .catch(() => { + console.log( + 'No internet connection found. App is running in offline mode.' + ); + }); + } + + export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready.then(registration => { + registration.unregister(); + }); + } + } diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js new file mode 100644 index 0000000..5253d3a --- /dev/null +++ b/src/reportWebVitals.js @@ -0,0 +1,13 @@ +const reportWebVitals = onPerfEntry => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals;