From 4c85d722b4036288083050309c6684df485fc770 Mon Sep 17 00:00:00 2001 From: Janderson Souza Matias Date: Tue, 21 Nov 2023 23:56:28 -0300 Subject: [PATCH] add nepali lang --- .github/workflows/nepal.yml | 38 +++++ .../workflows/{main.yml => sierra-leone.yml} | 8 +- Dockerfile | 21 --- docker-compose.yml | 13 -- nginx.conf | 8 - package.json | 1 + src/components/HeaderPage/index.tsx | 48 ++---- .../Layouts/ProtectedLayout/index.tsx | 2 +- src/components/Navbar/common.ts | 14 +- src/components/UserCard/index.tsx | 78 ++------- src/i18n/index.ts | 18 ++- src/i18n/langs/en.ts | 5 +- src/i18n/langs/np.ts | 150 ++++++++++++++++++ src/main.tsx | 27 ++-- src/pages/Dashboard/index.tsx | 2 +- src/pages/Settings/ChangeLanguage/index.tsx | 58 +++++++ src/pages/Settings/ChangePassword/index.tsx | 14 +- src/pages/Settings/EditUser/index.tsx | 12 +- src/pages/Settings/Logs/index.tsx | 7 +- src/pages/Settings/Users/index.tsx | 4 +- src/pages/Settings/index.tsx | 8 +- src/routes/index.tsx | 6 +- src/styles/index.css | 11 +- vite.config.ts | 39 +++-- yarn.lock | 5 + 25 files changed, 376 insertions(+), 221 deletions(-) create mode 100644 .github/workflows/nepal.yml rename .github/workflows/{main.yml => sierra-leone.yml} (87%) delete mode 100644 Dockerfile delete mode 100644 docker-compose.yml delete mode 100644 nginx.conf create mode 100644 src/i18n/langs/np.ts create mode 100644 src/pages/Settings/ChangeLanguage/index.tsx diff --git a/.github/workflows/nepal.yml b/.github/workflows/nepal.yml new file mode 100644 index 0000000..e0a05ed --- /dev/null +++ b/.github/workflows/nepal.yml @@ -0,0 +1,38 @@ +name: Deploy + +on: + push: + branches: + - main + +jobs: + build: + name: Deploy to server + runs-on: ubuntu-latest + env: + VITE_API_URL: https://coachdigital.org/np/api/ + VITE_COUNTRY: np + steps: + - name: ЁЯЫОя╕П Checkout + uses: actions/checkout@v3 + + - name: ЁЯЫая╕П Use Node.js 18.x + uses: actions/setup-node@v3 + with: + node-version: 18.x + + - name: ЁЯЫая╕П Install dependencies + run: npm install + + - name: ЁЯЪА Build + run: npm run build + + - name: ЁЯХ╡ЁЯП╗ Copy file via ssh key + uses: appleboy/scp-action@master + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + source: 'dist' + target: '/usr/share/nginx/html/np/admin' + strip_components: 1 diff --git a/.github/workflows/main.yml b/.github/workflows/sierra-leone.yml similarity index 87% rename from .github/workflows/main.yml rename to .github/workflows/sierra-leone.yml index 337bd59..80bcfb2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/sierra-leone.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest env: VITE_API_URL: https://coachdigital.org/sl/api/ - BASE_URL: /sl/admin/ + VITE_COUNTRY: sl steps: - name: ЁЯЫОя╕П Checkout uses: actions/checkout@v3 @@ -23,7 +23,7 @@ jobs: - name: ЁЯЫая╕П Install dependencies run: npm install - + - name: ЁЯЪА Build run: npm run build @@ -33,6 +33,6 @@ jobs: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.KEY }} - source: "dist" - target: "/usr/share/nginx/html/sl/admin" + source: 'dist' + target: '/usr/share/nginx/html/sl/admin' strip_components: 1 diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 7b745a1..0000000 --- a/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -FROM node:alpine as build - -WORKDIR /home/app - -COPY package.json ./ - -COPY . /home/app - -RUN npm install - -RUN npm run build - -FROM nginx:alpine - -RUN rm /etc/nginx/conf.d/default.conf - -COPY nginx.conf /etc/nginx/conf.d/ - -COPY --from=build /home/app/dist /usr/share/nginx/html - -EXPOSE 80 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 8adf771..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,13 +0,0 @@ -version: "3.3" - -networks: - web: - external: true - internal: - external: false - -services: - coach-admin-sl: - ports: - - "4001:80" - image: coachsl-admin diff --git a/nginx.conf b/nginx.conf deleted file mode 100644 index 7aca579..0000000 --- a/nginx.conf +++ /dev/null @@ -1,8 +0,0 @@ -server { - listen 80; - - location / { - root /usr/share/nginx/html; - try_files $uri /index.html; - } -} \ No newline at end of file diff --git a/package.json b/package.json index 01ac65b..025467a 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@chakra-ui/react": "^2.5.1", "@emotion/react": "^11.10.6", "@emotion/styled": "^11.10.6", + "@fontsource/noto-sans": "^5.0.17", "@hookform/resolvers": "^3.1.1", "@superset-ui/embedded-sdk": "^0.1.0-alpha.9", "@types/styled-system": "^5.1.16", diff --git a/src/components/HeaderPage/index.tsx b/src/components/HeaderPage/index.tsx index ee9b8cd..c55964b 100644 --- a/src/components/HeaderPage/index.tsx +++ b/src/components/HeaderPage/index.tsx @@ -1,7 +1,7 @@ -import React from "react"; -import { Button, HStack, Text, VStack } from "@chakra-ui/react"; -import Icon from "../Base/Icon"; -import { useTranslation } from "react-i18next"; +import React from 'react'; +import { Button, HStack, Text, VStack } from '@chakra-ui/react'; +import Icon from '../Base/Icon'; +import { useTranslation } from 'react-i18next'; type Props = { title: string; @@ -11,56 +11,28 @@ type Props = { onClickDownload?: () => void; }; -const HeaderPage: React.FC = ({ - title, - subtitle, - newButtonValue, - onClickNew, - onClickDownload, -}) => { +const HeaderPage: React.FC = ({ title, subtitle, newButtonValue, onClickNew, onClickDownload }) => { const { t } = useTranslation(); return ( - + {subtitle} - + {title} {onClickDownload && ( - )} {newButtonValue && onClickNew && ( - )} diff --git a/src/components/Layouts/ProtectedLayout/index.tsx b/src/components/Layouts/ProtectedLayout/index.tsx index 542678a..6120336 100644 --- a/src/components/Layouts/ProtectedLayout/index.tsx +++ b/src/components/Layouts/ProtectedLayout/index.tsx @@ -10,7 +10,7 @@ export const ProtectedLayout = () => { const navigate = useNavigate(); useEffect(() => { - if (!user) navigate('/sl/admin/login'); + if (!user) navigate(`/${import.meta.env.VITE_COUNTRY}/admin/login`); }, [user, navigate]); const flexDir = useBreakpointValue({ base: 'column', md: 'row' }) as 'column' | 'row'; diff --git a/src/components/Navbar/common.ts b/src/components/Navbar/common.ts index beba7e9..b11a299 100644 --- a/src/components/Navbar/common.ts +++ b/src/components/Navbar/common.ts @@ -2,7 +2,7 @@ export const MenuItems = [ { icon: 'chart-line', label: 'dashboard', - route: '/sl/admin/', + route: `/${import.meta.env.VITE_COUNTRY}/admin/`, }, { label: 'questionnaire', @@ -10,12 +10,12 @@ export const MenuItems = [ { icon: 'document-layout-right', label: 'teaching-practices', - route: '/sl/admin/teaching-practices', + route: `/${import.meta.env.VITE_COUNTRY}/admin/teaching-practices`, }, { icon: 'clipboard-notes', label: 'coaching-sessions', - route: '/sl/admin/coaching-sessions', + route: `/${import.meta.env.VITE_COUNTRY}/admin/coaching-sessions`, }, ], }, @@ -25,22 +25,22 @@ export const MenuItems = [ { icon: 'university', label: 'schools', - route: '/sl/admin/schools', + route: `/${import.meta.env.VITE_COUNTRY}/admin/schools`, }, { icon: 'calender', label: 'coaches-over-time', - route: '/sl/admin/coach-over-time', + route: `/${import.meta.env.VITE_COUNTRY}/admin/coach-over-time`, }, { icon: 'folder', label: 'session-data', - route: '/sl/admin/session-data', + route: `/${import.meta.env.VITE_COUNTRY}/admin/session-data`, }, { icon: 'sync', label: 'syncs', - route: '/sl/admin/syncs', + route: `/${import.meta.env.VITE_COUNTRY}/admin/syncs`, }, ], }, diff --git a/src/components/UserCard/index.tsx b/src/components/UserCard/index.tsx index 5015e35..bd15e6f 100644 --- a/src/components/UserCard/index.tsx +++ b/src/components/UserCard/index.tsx @@ -1,17 +1,8 @@ -import React, { useMemo } from "react"; -import { - Menu, - MenuButton, - MenuList, - MenuItem, - Center, - HStack, - VStack, - Text, -} from "@chakra-ui/react"; -import { useNavigate } from "react-router-dom"; -import Icon from "../Base/Icon"; -import { useTranslation } from "react-i18next"; +import React, { useMemo } from 'react'; +import { Menu, MenuButton, MenuList, MenuItem, Center, HStack, VStack, Text } from '@chakra-ui/react'; +import { useNavigate } from 'react-router-dom'; +import Icon from '../Base/Icon'; +import { useTranslation } from 'react-i18next'; type Props = { name: string; email: string; logout: () => void }; @@ -19,25 +10,18 @@ const UserCard: React.FC = ({ name, email, logout }) => { const { t } = useTranslation(); const navigate = useNavigate(); const initials = useMemo(() => { - const splinted = name.split(" "); - return splinted.length > 1 - ? `${splinted[0][0]}${splinted[1][0]}` - : `${splinted[0][0]}${splinted[0][1]}`; + const splinted = name.split(' '); + return splinted.length > 1 ? `${splinted[0][0]}${splinted[1][0]}` : `${splinted[0][0]}${splinted[0][1]}`; }, [name]); const handleSettings = () => { - navigate("/sl/admin/settings"); + navigate(`/${import.meta.env.VITE_COUNTRY}/admin/settings`); }; return ( - +
= ({ name, email, logout }) => { bg="#EBF1FF" color="#264673" fontWeight={700} - fontSize={"16px"} + fontSize={'16px'} textTransform="uppercase" > {initials}
- - + + {name} - + {email} @@ -81,23 +47,13 @@ const UserCard: React.FC = ({ name, email, logout }) => {
- + - {t("Navbar.settings")} + {t('Navbar.settings')} - + - {t("Navbar.logout")} + {t('Navbar.logout')}
diff --git a/src/i18n/index.ts b/src/i18n/index.ts index aa45558..452148b 100644 --- a/src/i18n/index.ts +++ b/src/i18n/index.ts @@ -1,19 +1,21 @@ -import i18n from "i18next"; -import { initReactI18next } from "react-i18next"; -import enTranslation from "./langs/en"; -import kriTranslation from "./langs/kri"; +import i18n from 'i18next'; +import { initReactI18next } from 'react-i18next'; +import enTranslation from './langs/en'; +import kriTranslation from './langs/kri'; +import npTranslation from './langs/np'; export const resources: { [lang: string]: { translation: any; label: string }; } = { - en: { translation: enTranslation, label: "English" }, - kri: { translation: kriTranslation, label: "Krio" }, + en: { translation: enTranslation, label: 'English' }, + np: { translation: npTranslation, label: 'Nepali' }, + kri: { translation: kriTranslation, label: 'Krio' }, }; i18n.use(initReactI18next).init({ - compatibilityJSON: "v3", + compatibilityJSON: 'v3', resources, - fallbackLng: "en", + fallbackLng: 'en', interpolation: { escapeValue: false, }, diff --git a/src/i18n/langs/en.ts b/src/i18n/langs/en.ts index a908ad6..dae8d7e 100644 --- a/src/i18n/langs/en.ts +++ b/src/i18n/langs/en.ts @@ -9,7 +9,7 @@ const enTranslation = { generateQRCode: 'Generate QRCode', cancel: 'Cancel', download: 'Download data', - 'items-per-page': 'Items per page' + 'items-per-page': 'Items per page', }, Navbar: { @@ -149,6 +149,9 @@ const enTranslation = { date: 'Date', }, }, + language: { + title: 'Change language', + }, }, }, }; diff --git a/src/i18n/langs/np.ts b/src/i18n/langs/np.ts new file mode 100644 index 0000000..42c137b --- /dev/null +++ b/src/i18n/langs/np.ts @@ -0,0 +1,150 @@ +const npTranslation = { + common: { + edit: 'рд╕рдореНрдкрд╛рджрди рдЧрд░реНрдиреБрд╣реЛрд╕реН', + view: 'рд╣реЗрд░реНрдиреБрд╣реЛрд╕реН', + delete: 'рд╣рдЯрд╛рдЙрдиреБрд╣реЛрд╕реН', + 'items-per-page': 'рдкреГрд╖реНрда рд╕реВрдЪреАрдорд╛ рдХреБрд▓', + activate: 'рд╕рдХреНрд░рд┐рдп рдЧрд░реНрдиреБрд╣реЛрд╕реН', + deactivate: 'рдирд┐рд╖реНрдХреНрд░рд┐рдп рдкрд╛рд░реНрдиреБрд╣реЛрд╕реН', + generateQRCode: 'QR рдХреЛрдб рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН', + cancel: 'рд░рджреНрдж рдЧрд░реНрдиреБрд╣реЛрд╕реН', + download: 'рдбрд╛рдЯрд╛ рдбрд╛рдЙрдирд▓реЛрдб рдЧрд░реНрдиреБрд╣реЛрд╕реН', + actions: 'рдХрд╛рд░реНрдпрд╣рд░реВ', + }, + Navbar: { + dashboard: 'рдореБрдЦреНрдп рдкреГрд╖реНрда', + questionnaire: 'рдкреНрд░рд╢реНрдирд╛рд╡рд▓реА', + 'teaching-practices': 'рд╢рд┐рдХреНрд╖рдг рдЕрднреНрдпрд╛рд╕рд╣рд░реВ', + data: 'рдбрд╛рдЯрд╛', + syncs: 'рдЕрдкрд▓реЛрдб рд░ рдбрд╛рдЙрдирд▓реЛрдб', + logout: 'рдПрдкрдмрд╛рдЯ рд▓рдЧрдЖрдЙрдЯ рдЧрд░реНрдиреБрд╣реЛрд╕реН', + settings: 'рдПрдк рд╕реЗрдЯрд┐рдЩ', + 'coaching-sessions': 'рдХреЛрдЪрд┐рдЩ рд╕рддреНрд░рд╣рд░реВ', + 'session-data': 'рд╕рддреНрд░ рдорд╛ рдбрд╛рдЯрд╛', + 'coaches-over-time': 'рдХреЛрдЪрд┐рдЩ рдЕрд╡рдзрд┐', + schools: 'рд╡рд┐рджреНрдпрд╛рд▓рдпрд╣рд░реВ', + }, + dashboard: { + engagement: { + title: 'рд╕рдВрд▓рдЧреНрдирддрд╛', + 'coaching-sessions': 'рдХреЛрдЪрд┐рдЩ рд╕рддреНрд░рд╣рд░реВ', + 'completed-a-second-coach-session': 'рджреЛрд╕реНрд░реЛ рдХреЛрдЪ рд╕рддреНрд░ рдкреВрд░рд╛ рдЧрд░реЗрдХреЛ рдЫ', + 'teachers-coached': 'рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рд╢рд┐рдХреНрд╖рдХрд╣рд░реВрдХреЛ рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛', + 'active-coaches': 'рд╕рдХреНрд░рд┐рдп рдкреНрд░рд╢рд┐рдХреНрд╖рдХрд╣рд░реВ', + 'coaching-sessions-per-teacher-over-last-three-months': 'рдкрдЫрд┐рд▓реНрд▓реЛ рддреАрди рдорд╣рд┐рдирд╛рдорд╛ рдкреНрд░рддрд┐ рд╢рд┐рдХреНрд╖рдХ рдХреЛрдЪрд┐рдЩ рд╕рддреНрд░рд╣рд░реВ', + description: 'рдЪрдпрди рдЧрд░рд┐рдПрдХреЛ рдЕрд╡рдзрд┐рдорд╛ рдХреЛрдЪ рдкреНрд▓реЗрдЯрдлрд░реНрдо рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдХреЛрдЪ рд╕рдВрд▓рдЧреНрдирддрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдЧрд░реНрдиреЗ рд╕рдВрдЦреНрдпрд╛рд╣рд░реВред', + }, + 'targeted-improvement-areas': { + title: 'рд▓рдХреНрд╖рд┐рдд рд╕реБрдзрд╛рд░ рдХреНрд╖реЗрддреНрд░рд╣рд░реВ', + description: 'рд╢рд┐рдХреНрд╖рдг рдЕрднреНрдпрд╛рд╕рд╣рд░реВ рдЬрд╕рдХреЛ рд▓рд╛рдЧрд┐ рд╢рд┐рдХреНрд╖рдХ рд░ рдкреНрд░рд╢рд┐рдХреНрд╖рдХрд╣рд░реВ рдХреЛрдЪрд┐рдЩ рд╕рддреНрд░рд╣рд░реВ рдмреАрдЪрдорд╛ рдХрд╛рдо рдЧрд░реНрди рд╕рд╣рдордд рднрдП', + }, + 'select-teaching-practices-to-show': 'рддрдкрд╛рдИрдВрд▓реЗ рд╣реЗрд░реНрди рдЪрд╛рд╣рдиреБрднрдПрдХреЛ рд╢рд┐рдХреНрд╖рдг рдЕрднреНрдпрд╛рд╕рд╣рд░реВ рдЪрдпрди рдЧрд░реНрдиреБрд╣реЛрд╕реН', + 'supportive-learning-environment': 'рд╕рд╣рдпреЛрдЧреА рд╕рд┐рдХрд╛рдЗ рд╡рд╛рддрд╛рд╡рд░рдг', + }, + 'teacher-practices': { + new: 'рд╢рд┐рдХреНрд╖рдг рдЕрднреНрдпрд╛рд╕ рдердкреНрдиреБрд╣реЛрд╕реН', + table: { + name: 'рдирд╛рдо', + 'number-of-questions': 'рдкреНрд░рд╢реНрди рд╕рдВрдЦреНрдпрд╛', + 'publish-state': 'рдбрд╛рдЯрд╛ рдкреНрд░рдХрд╛рд╢рд┐рдд рд╕реНрдерд┐рддрд┐', + Actions: 'рдХрд╛рд░реНрдпрд╣рд░реВ', + }, + form: { + name: 'рд╢рд┐рдХреНрд╖рдг рдЕрднреНрдпрд╛рд╕ рдирд╛рдо', + 'question-title': 'рд╢реАрд░реНрд╖рдХ', + 'question-description': 'рд╡рд┐рд╡рд░рдг', + 'save-question': 'рдкреНрд░рд╢реНрди рд╕реБрд░рдХреНрд╖рдг', + }, + }, + 'coaching-sessions': { + table: { + school: 'рд╡рд┐рджреНрдпрд╛рд▓рдп', + coach: 'рдкреНрд░рд╢рд┐рдХреНрд╖рдХ', + teacher: 'рд╢рд┐рдХреНрд╖рдХ', + feedback: 'рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛', + actions: 'рдХрд╛рд░реНрдпрд╣рд░реВ', + subject: 'рд╡рд┐рд╖рдп', + }, + }, + school: { + table: { + actions: 'рдХрд╛рд░реНрдпрд╣рд░реВ', + name: 'рдирд╛рдо', + 'teachers-count': 'рдХреБрд▓ рд╢рд┐рдХреНрд╖рдХ рд╕рдВрдЦреНрдпрд╛', + 'coaches-count': 'рдХреЛрдЪ рдХреЛ рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛', + }, + 'new-school': 'рдирдпрд╛рдБ рд╡рд┐рджреНрдпрд╛рд▓рдп', + filter: 'рд╡рд┐рджреНрдпрд╛рд▓рдпрдХреЛ рдирд╛рдо', + }, + 'coach-over-time': { + filters: { + school: 'рд╡рд┐рджреНрдпрд╛рд▓рдп', + 'with-no-data': 'рдбрд╛рдЯрд╛ рдирднрдПрдХрд╛ рд╡рд┐рджреНрдпрд╛рд▓рдпрд╣рд░реВ рд╕рдорд╛рд╡реЗрд╢ рдЧрд░реНрдиреБрд╣реЛрд╕реН', + region: 'рдХреНрд╖реЗреЗрддреНрд░', + }, + table: { + School: 'рд╡рд┐рджреНрдпрд╛рд▓рдп', + 'Number of coaches': 'рдХреЛрдЪ рд╕рдВрдЦреНрдпрд╛', + 'Feedback sessions': 'рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рддреНрд░', + 'Teachers coached (30-60 days)': 'рдХреБрд▓ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рд╢рд┐рдХреНрд╖рдХ (рейреж-ремреж рджрд┐рди)', + 'Teachers coached (60-90 days)': 'рдХреБрд▓ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рд╢рд┐рдХреНрд╖рдХ (6реж-9реж рджрд┐рди)', + 'Number of teachers coached': 'рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рд╢рд┐рдХреНрд╖рдХрд╣рд░реВрдХреЛ рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛', + 'Teachers coached (90+ days)': 'рдХреБрд▓ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рд╢рд┐рдХреНрд╖рдХ (90+ рджрд┐рди)', + 'Teachers coached (last 30 days)': 'рдХреБрд▓ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рд╢рд┐рдХреНрд╖рдХ (рдкрдЫрд┐рд▓реНрд▓реЛ 30 рджрд┐рди)', + }, + }, + 'session-data': { + filters: { + period: 'рдЕрд╡рдзрд┐', + region: 'рдХреНрд╖реЗрддреНрд░', + school: 'рд╡рд┐рджреНрдпрд╛рд▓рдп', + 'with-no-data': 'рдбрд╛рдЯрд╛ рдирднрдПрдХрд╛ рд╡рд┐рджреНрдпрд╛рд▓рдпрд╣рд░реВ рд╕рдорд╛рд╡реЗрд╢ рдЧрд░реНрдиреБрд╣реЛрд╕реН', + }, + table: { + school: 'рд╡рд┐рджреНрдпрд╛рд▓рдп', + 'feedback-sessions': 'рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рддреНрд░', + 'effective-teaching': 'рдкреНрд░рднрд╛рд╡рдХрд╛рд░реА рд╢рд┐рдХреНрд╖рдг', + 'number-of-coaches': 'рдХреЛрдЪ рд╕рдВрдЦреНрдпрд╛', + 'time-on-learning': 'рд╕рд┐рдХреНрдиреЗ рд╕рдордп', + 'positive-behavioral-expectations': 'рд╕рдХрд╛рд░рд╛рддреНрдордХ рд╡реНрдпрд╡рд╣рд╛рд░ рдЕрдкреЗрдХреНрд╖рд╛рд╣рд░реВ', + 'number-of-teachers-coached': 'рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рдХреБрд▓ рд╢рд┐рдХреНрд╖рдХ', + 'critical-thinking': 'рдЖрд▓реЛрдЪрдирд╛рддреНрдордХ рд╡рд┐рдЪрд╛рд░', + 'supportive-learning Environment': 'рд╕рд╣рдпреЛрдЧреА рд╕рд┐рдХрд╛рдЗ рд╡рд╛рддрд╛рд╡рд░рдг', + }, + }, + settings: { + title: 'рд╕реЗрдЯрд┐рдЩ', + tabs: { + user: { + title: 'рд╕рд╛рдзрд╛рд░рдг', + name: 'рдирд╛рдо', + description: 'рдЖрдлреНрдиреЛ рдЬрд╛рдирдХрд╛рд░реА рдЕрдкрдбреЗрдЯ рдЧрд░реНрдиреБрд╣реЛрд╕реНред', + email: 'рдЗрдореЗрд▓', + }, + users: { + title: 'рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛рд╣рд░реВ', + new: 'рдирдпрд╛рдБ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛рд╣рд░реВ', + }, + logs: { + table: { + title: 'рджреИрдирд┐рдХреА', + user: 'рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛', + action: 'рдХрд╛рд░реНрдпрд╣рд░реВ', + date: 'рдорд┐рддрд┐', + }, + }, + 'change-password': { + 'current-password': 'рд╡рд░реНрддрдорд╛рди рдкрд╛рд╕рд╡рд░реНрдб', + 'new-password': 'рдирдпрд╛ рдкрд╛рд╕рд╡рд░реНрдб', + 'confirm-password': 'рдкрд╛рд╕рд╡рд░реНрдб рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдЧрд░реНрдиреБрд╣реЛрд╕', + description: 'рдЖрдлреНрдиреЛ рдкрд╛рд╕рд╡рд░реНрдб рдЕрдкрдбреЗрдЯ рдЧрд░реНрдиреБрд╣реЛрд╕реН', + title: 'рдкрд╛рд╕рд╡рд░реНрдб рдкрд░рд┐рд╡рд░реНрддрди рдЧрд░реНрдиреБрд╣реЛрд╕реН', + }, + language: { + title: 'рднрд╛рд╖рд╛ рдкрд░рд┐рд╡рд░реНрддрди рдЧрд░реНрдиреБрд╣реЛрд╕реН', + }, + }, + }, +}; + +export default npTranslation; diff --git a/src/main.tsx b/src/main.tsx index 6318a10..b6f16c7 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,16 +1,17 @@ -import { ChakraProvider, Text } from "@chakra-ui/react"; -import { lightTheme } from "./styles/themes/light"; -import { ToastContainer } from "react-toastify"; -import "react-toastify/dist/ReactToastify.css"; -import UserContextProvider from "./contexts/UserContext"; -import ReactDOM from "react-dom/client"; -import { Router } from "./routes"; -import "./styles/index.css"; -import React from "react"; -import "./i18n"; -import { BrowserRouter } from "react-router-dom"; +import { ChakraProvider } from '@chakra-ui/react'; +import { lightTheme } from './styles/themes/light'; +import { ToastContainer } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; +import UserContextProvider from './contexts/UserContext'; +import ReactDOM from 'react-dom/client'; +import { Router } from './routes'; +import './styles/index.css'; +import React from 'react'; +import './i18n'; +import { BrowserRouter } from 'react-router-dom'; +import '@fontsource/noto-sans'; -ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( +ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( @@ -30,5 +31,5 @@ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - + , ); diff --git a/src/pages/Dashboard/index.tsx b/src/pages/Dashboard/index.tsx index b45dcd3..49d75a8 100644 --- a/src/pages/Dashboard/index.tsx +++ b/src/pages/Dashboard/index.tsx @@ -38,7 +38,7 @@ const DashboardPage: React.FC = () => { setSchoolList(schools); } setDashboard(dash); - setSelected(dash.teachingPractices[0]); + setSelected(dash?.teachingPractices[0]); setLoading(false); }); } diff --git a/src/pages/Settings/ChangeLanguage/index.tsx b/src/pages/Settings/ChangeLanguage/index.tsx new file mode 100644 index 0000000..b23fec2 --- /dev/null +++ b/src/pages/Settings/ChangeLanguage/index.tsx @@ -0,0 +1,58 @@ +import React, { useContext, useState } from 'react'; +import Loader from '@/components/Base/Loader'; +import { UserContext } from '@/contexts/UserContext'; +import { IUser } from '@/types'; +import { Button, Center, FormControl, FormLabel, HStack, Input, Radio, Text, VStack } from '@chakra-ui/react'; +import { useForm } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; +import * as yup from 'yup'; +import { useTranslation } from 'react-i18next'; +import Icon from '@/components/Base/Icon'; + +const ChangeLanguage = () => { + const { t, i18n } = useTranslation(); + + const changeLanguage = (lang: string) => { + i18n.changeLanguage(lang); + }; + + return ( + + + {t('settings.tabs.language.title')} + + + + changeLanguage('en')} + > + {'ЁЯЗ║ЁЯЗ╕ English (US)'} + + + + changeLanguage('np')} + > + {'ЁЯЗ│ЁЯЗ╡ Nepali'} + + + + + ); +}; + +export default ChangeLanguage; diff --git a/src/pages/Settings/ChangePassword/index.tsx b/src/pages/Settings/ChangePassword/index.tsx index 396eadb..0021c67 100644 --- a/src/pages/Settings/ChangePassword/index.tsx +++ b/src/pages/Settings/ChangePassword/index.tsx @@ -7,8 +7,10 @@ import React, { useContext, useState } from 'react'; import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; import * as yup from 'yup'; +import { useTranslation } from 'react-i18next'; const ChangePassword = () => { + const { t } = useTranslation(); const { handleUpdateUser } = useContext(UserContext); const [isLoading, setIsLoading] = useState(false); @@ -44,10 +46,10 @@ const ChangePassword = () => { ) : ( - Change password + {t('settings.tabs.change-password.title')} - Update your access password. + {t('settings.tabs.change-password.description')}
{ style={{ width: '100%', display: 'flex', flexDirection: 'column', marginTop: '40px' }} > - Current password + {t('settings.tabs.change-password.current-password')} { - New password + {t('settings.tabs.change-password.new-password')} { - Confirm password + {t('settings.tabs.change-password.confirm-password')} {
diff --git a/src/pages/Settings/EditUser/index.tsx b/src/pages/Settings/EditUser/index.tsx index 83aabd1..b07b65c 100644 --- a/src/pages/Settings/EditUser/index.tsx +++ b/src/pages/Settings/EditUser/index.tsx @@ -5,8 +5,10 @@ import { IUser } from '@/types'; import { Button, Center, FormControl, FormErrorMessage, FormLabel, Input, Text, VStack } from '@chakra-ui/react'; import React, { useContext, useState } from 'react'; import { useForm } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; const EditUser = () => { + const { t } = useTranslation(); const { user, handleUpdateUser } = useContext(UserContext); const [isLoading, setIsLoading] = useState(false); @@ -31,10 +33,10 @@ const EditUser = () => { ) : ( - General + {t('settings.tabs.user.title')} - Update your information. + {t('settings.tabs.user.description')}
@@ -48,7 +50,7 @@ const EditUser = () => { style={{ width: '100%', display: 'flex', flexDirection: 'column' }} > - Name + {t('settings.tabs.user.name')} {errors.name && errors.name.type === 'required' && 'Name is required'} @@ -56,7 +58,7 @@ const EditUser = () => { - Email + {t('settings.tabs.user.email')} {errors.email && errors.email.type === 'required' && 'Email is required'} @@ -64,7 +66,7 @@ const EditUser = () => { diff --git a/src/pages/Settings/Logs/index.tsx b/src/pages/Settings/Logs/index.tsx index 5e59dee..bafe67a 100644 --- a/src/pages/Settings/Logs/index.tsx +++ b/src/pages/Settings/Logs/index.tsx @@ -25,11 +25,12 @@ const Logs: React.FC = () => { ) : ( log.user.name }, - { title: t('settings.tabs.logs.action'), renderColumn: (log: ILogs) => log.description }, + { title: t('settings.tabs.logs.table.user'), renderColumn: (log: ILogs) => log.user.name, width: '30%' }, + { title: t('settings.tabs.logs.table.action'), renderColumn: (log: ILogs) => log.description, width: '30%' }, { - title: t('settings.tabs.logs.date'), + title: t('settings.tabs.logs.table.date'), renderColumn: (log: ILogs) => new Date(log.created_at).toLocaleString(), + width: '40%', }, ]} data={logs} diff --git a/src/pages/Settings/Users/index.tsx b/src/pages/Settings/Users/index.tsx index 9d2a2d2..c16a7a6 100644 --- a/src/pages/Settings/Users/index.tsx +++ b/src/pages/Settings/Users/index.tsx @@ -10,9 +10,11 @@ import { SubmitHandler } from 'react-hook-form'; import { UserContext } from '@/contexts/UserContext'; import AuthService from '@/services/auth'; import { toast } from 'react-toastify'; +import { useTranslation } from 'react-i18next'; const Users = () => { const theme = useTheme(); + const { t } = useTranslation(); const { user } = useContext(UserContext); const [currentUser, setCurrentUser] = useState(); const [users, setUsers] = useState({ @@ -104,7 +106,7 @@ const Users = () => { setCurrentUser({} as any)}> - Criar usu├бrio + {t('settings.tabs.users.new')} )} diff --git a/src/pages/Settings/index.tsx b/src/pages/Settings/index.tsx index b15a9f8..811f8d1 100644 --- a/src/pages/Settings/index.tsx +++ b/src/pages/Settings/index.tsx @@ -8,6 +8,7 @@ import Icon from '@/components/Base/Icon'; import HeaderPage from '@/components/HeaderPage'; import Logs from './Logs'; import { UserContext } from '@/contexts/UserContext'; +import ChangeLanguage from './ChangeLanguage'; const SettingsPage: React.FC = () => { const { t } = useTranslation(); @@ -33,12 +34,17 @@ const SettingsPage: React.FC = () => { component: , }, { - label: t('settings.tabs.logs.title'), + label: t('settings.tabs.logs.table.title'), icon: 'receipt-alt', component: , }, ] : []), + { + label: t('settings.tabs.language.title'), + icon: 'globe', + component: , + }, ]; return ( diff --git a/src/routes/index.tsx b/src/routes/index.tsx index b050504..0646df2 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -24,10 +24,10 @@ export const Router = () => { {!user ? ( <> - } /> + } /> ) : ( - }> + }> } /> } /> } /> @@ -41,7 +41,7 @@ export const Router = () => { } /> )} - } /> + } /> ); diff --git a/src/styles/index.css b/src/styles/index.css index f0c6356..c21f59f 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -1,17 +1,10 @@ -@import url("https://fonts.googleapis.com/css2?family=Inter:wght@100;300;400;500;600;700;800;900&display=swap"); - body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + font-family: 'Noto Sans'; } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", - monospace; + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } .lds-ring { diff --git a/vite.config.ts b/vite.config.ts index 881bb69..f4ae669 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,19 +1,24 @@ -import { defineConfig } from "vite"; -import react from "@vitejs/plugin-react-swc"; -import path from "path"; +import { defineConfig, loadEnv } from 'vite'; +import react from '@vitejs/plugin-react-swc'; +import path from 'path'; // https://vitejs.dev/config/ -export default defineConfig({ - base: '/sl/admin/', - plugins: [react()], - resolve: { - alias: [{ find: "@", replacement: path.resolve(__dirname, "src") }], - }, - mode: "development", - build: { - minify: false, - }, - define: { - "process.env": {}, - }, -}); + +export default ({ mode }) => { + process.env = { ...process.env, ...loadEnv(mode, process.cwd()) }; + + return defineConfig({ + base: `/${process.env.VITE_COUNTRY}/admin/`, + plugins: [react()], + resolve: { + alias: [{ find: '@', replacement: path.resolve(__dirname, 'src') }], + }, + mode: 'development', + build: { + minify: false, + }, + define: { + 'process.env': {}, + }, + }); +}; diff --git a/yarn.lock b/yarn.lock index 6fe268f..b1c57ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1275,6 +1275,11 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.47.0.tgz#5478fdf443ff8158f9de171c704ae45308696c7d" integrity sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og== +"@fontsource/noto-sans@^5.0.17": + version "5.0.17" + resolved "https://registry.yarnpkg.com/@fontsource/noto-sans/-/noto-sans-5.0.17.tgz#ce2044d79516c000b6e1e2bd76356e322360a5a1" + integrity sha512-VcnKA99cE8OgRiy6O3T6xCKirsguD5+MYrGrbBWYA3m3fqDArCr66eEvR3iuTngGLbTODJq4bzc6yfaiGZu/pQ== + "@hookform/resolvers@^3.1.1": version "3.2.0" resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-3.2.0.tgz#0f48f57d464a216fa4a2d76b0f1317b91f91e99b"