Implemented english, hindi and bangla language integration through i18next
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { Outlet } from "react-router-dom"
|
||||
import Header from "./components/Header"
|
||||
import Footer from "./components/Footer"
|
||||
|
||||
function App() {
|
||||
return <div className="flex flex-col min-h-screen">
|
||||
@@ -7,6 +8,7 @@ function App() {
|
||||
<main className="transition-color-mode px-7 flex-grow bg-surface dark:bg-surface-dark">
|
||||
<Outlet />
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
}
|
||||
|
||||
|
@@ -1,14 +1,21 @@
|
||||
import IpksLogo from '../assets/ipks_logo.svg';
|
||||
import DarkModeToggle from './DarkModeToggle';
|
||||
import LanguageSelector from './LanguageSelector';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
||||
function AppTitle() {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<div className='flex items-center justify-between pt-3 pb-5'>
|
||||
<div className='flex gap-5 items-center'>
|
||||
<img src={IpksLogo} alt="IPKS Logo" className="h-16" />
|
||||
<h1 className="text-title font-display font-bold">Integrated PACS Kisan Solution</h1>
|
||||
<h1 className="text-title font-display font-bold">{t('appName')}</h1>
|
||||
</div>
|
||||
<div className='flex items-center gap-2'>
|
||||
<DarkModeToggle />
|
||||
<LanguageSelector />
|
||||
</div>
|
||||
<DarkModeToggle />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@@ -1,12 +1,22 @@
|
||||
import PropTypes from "prop-types";
|
||||
import BannerInfoElement from "./BannerInfoElement";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
function BannerInfo({info}) {
|
||||
const date = new Date().toLocaleDateString('en-IN', {month: 'long', day: '2-digit', year: 'numeric'}).split(" ");
|
||||
const {t} = useTranslation();
|
||||
|
||||
const infoElements = Object.keys(info).map((key) => (
|
||||
<BannerInfoElement key={key} title={key} description={info[key]} />
|
||||
<BannerInfoElement key={key} title={t(key)} description={t(info[key])} />
|
||||
))
|
||||
infoElements.push(<BannerInfoElement key="date" title="Date" description={date.join(" ")} />);
|
||||
infoElements.push(
|
||||
<BannerInfoElement
|
||||
key="date"
|
||||
title={t('date')}
|
||||
description={t('currentDate',{val: new Date(), formatParams: {
|
||||
val: { month: 'long', day: '2-digit', year: 'numeric'},
|
||||
},})}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<div className="flex justify-between pb-1">
|
||||
{infoElements}
|
||||
|
9
src/components/Footer.jsx
Normal file
9
src/components/Footer.jsx
Normal file
@@ -0,0 +1,9 @@
|
||||
function Footer() {
|
||||
return (
|
||||
<footer>
|
||||
<p>© 2021</p>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
export default Footer;
|
@@ -7,48 +7,38 @@ import Separator from "./Separator";
|
||||
function Header() {
|
||||
const userInfo = getUserInfoFromSession();
|
||||
const menuItems = [
|
||||
{ name: "Home", submenu: [], path: "/" },
|
||||
{ name: "home", submenu: [], path: "/" },
|
||||
{
|
||||
name: "Module List",
|
||||
name: "moduleList",
|
||||
submenu: [
|
||||
{name: "KCC", path: "kcc"},
|
||||
{name: "Trading", path: "trading"},
|
||||
{name: "Asset", path: "asset"},
|
||||
{name: "Self Help Group", path: "shg"},
|
||||
{name: "Deposit", path: "deposit"},
|
||||
{name: "Loan", path: "loan"},
|
||||
{name: "Share", path: "share"},
|
||||
{name: "kcc", path: "kcc"},
|
||||
{name: "trading", path: "trading"},
|
||||
{name: "asset", path: "asset"},
|
||||
{name: "selfHelpGroup", path: "shg"},
|
||||
{name: "deposit", path: "deposit"},
|
||||
{name: "loan", path: "loan"},
|
||||
{name: "share", path: "share"},
|
||||
],
|
||||
},
|
||||
{ name: "Enquiry", submenu: [{name: "Locker Enquiry", path: "locker-enquiry"}, {name: "Account Enquiry", path: "account-enquiry"}] },
|
||||
{ name: "enquiry", submenu: [{name: "lockerEnquiry", path: "locker-enquiry"}, {name: "accountEnquiry", path: "account-enquiry"}] },
|
||||
{
|
||||
name: "Locker Operation",
|
||||
name: "lockerOperation",
|
||||
submenu: [
|
||||
{name: "Account Creation", path: "account-creation"},
|
||||
{name: "Cabinet Maintenance", path: "cabinet-maintenance"},
|
||||
{name: "Locker Maintenance", path: "locker-maintenance"},
|
||||
{name: "Rent/Penalty Collection", path: "rent-collection"},
|
||||
{name: "Charge Management", path: "charge-management"},
|
||||
{name: "Check in/out Management", path: "check-in-out"},
|
||||
{name: "Account Surrender", path: "account-surrender"}
|
||||
{name: "accountCreation", path: "account-creation"},
|
||||
{name: "cabinetMaintenance", path: "cabinet-maintenance"},
|
||||
{name: "lockerMaintenance", path: "locker-maintenance"},
|
||||
{name: "rentPenaltyCollection", path: "rent-collection"},
|
||||
{name: "chargeManagement", path: "charge-management"},
|
||||
{name: "checkInOutManagement", path: "check-in-out"},
|
||||
{name: "accountSurrender", path: "account-surrender"}
|
||||
],
|
||||
},
|
||||
{ name: "worklist", submenu: [{name:"myIntimation", path: "my-intimation"}] },
|
||||
{
|
||||
name: "Reports",
|
||||
submenu: [
|
||||
{name: "Deposit Report", path: "deposit-report"},
|
||||
{name: "Trial Balance Report", path: "trial-report"},
|
||||
{name: "Deposit Return Report", path: "deposit-return-report"},
|
||||
{name: "Account Statement Reports", path: "account-statement-report"},
|
||||
{name: "Audit Reports", path: "audit-reports"}
|
||||
],
|
||||
name: "userManagement",
|
||||
submenu: [{name: "resetLogin", path: "reset-login"}, {name: "changePassword", path: "change-password"}],
|
||||
},
|
||||
{ name: "Worklist", submenu: [{name:"My Intimation", path: "my-intimation"}] },
|
||||
{
|
||||
name: "User Management",
|
||||
submenu: [{name: "Reset Loggen In Status", path: "reset-login"}, {name: "Change Password", path: "change-password"}],
|
||||
},
|
||||
{ name: "Log Out", submenu: [] },
|
||||
{ name: "logout", submenu: [] },
|
||||
];
|
||||
|
||||
return (
|
||||
|
21
src/components/LanguageSelector.jsx
Normal file
21
src/components/LanguageSelector.jsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const LanguageSelector = () => {
|
||||
const { i18n } = useTranslation();
|
||||
|
||||
const changeLanguage = (event) => {
|
||||
i18n.changeLanguage(event.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<select className='rounded-md bg-secondary dark:bg-secondary-dark focus:outline-none' id="language-select" onChange={changeLanguage} value={i18n.language}>
|
||||
<option value="en">English</option>
|
||||
<option value="bn">বাংলা</option>
|
||||
<option value="hi">हिन्दी</option>
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LanguageSelector;
|
@@ -1,15 +1,17 @@
|
||||
import { Link } from "react-router-dom";
|
||||
import PropTypes from "prop-types";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const SubMenu = ({ items }) => {
|
||||
const {t} = useTranslation();
|
||||
return (
|
||||
<div className="
|
||||
hidden absolute top-full left-0 border-t-3 border-primary dark:border-primary-dark bg-secondary
|
||||
dark:bg-secondary-dark rounded-2xl shadow-sm shadow-surface-variant-dark dark:shadow-primary group-hover:block z-10"
|
||||
>
|
||||
{items.map((subItem, index) => (
|
||||
<div key={index} className="px-6 py-2 text-nowrap hover:bg-white dark:hover:bg-secondary-variant-dark cursor-pointer first:rounded-t-2xl last:rounded-b-2xl first:pt-4 last:pb-4">
|
||||
<Link to={subItem.path}>{subItem.name}</Link>
|
||||
<div key={index} className="px-6 py-2 text-nowrap hover:bg-white dark:hover:bg-secondary-variant-dark cursor-pointer first:rounded-t-2xl second-last:rounded-b-2xl first:pt-4 last:pb-4">
|
||||
<Link to={subItem.path}>{t(subItem.name)}</Link>
|
||||
</div>
|
||||
))}
|
||||
<svg className="absolute top-0 left-6 mt-[-13px] fill-primary dark:fill-primary-dark" width="16" height="13" viewBox="0 0 16 13" xmlns="http://www.w3.org/2000/svg">
|
||||
@@ -20,11 +22,12 @@ const SubMenu = ({ items }) => {
|
||||
};
|
||||
|
||||
function MenuBar({ menuItems }) {
|
||||
const {t} = useTranslation();
|
||||
return (
|
||||
<div className="flex justify-between text-base pt-5 pb-2 font-body">
|
||||
{menuItems.map((item, index) =>
|
||||
<div key={index} className="group relative pb-3 cursor-pointer">
|
||||
{item.name}
|
||||
{t(item.name)}
|
||||
{item.submenu.length > 0 && <SubMenu items={item.submenu} />}
|
||||
</div>
|
||||
)}
|
||||
|
19
src/i18n.js
Normal file
19
src/i18n.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import i18n from 'i18next';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||
import Backend from 'i18next-http-backend';
|
||||
|
||||
i18n
|
||||
.use(Backend)
|
||||
.use(LanguageDetector)
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
fallbackLng: 'en',
|
||||
interpolation: { escapeValue: false},
|
||||
debug: true,
|
||||
backend: {
|
||||
loadPath: '/locales/{{lng}}/{{ns}}.json',
|
||||
},
|
||||
});
|
||||
|
||||
export default i18n;
|
@@ -1,4 +1,5 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&family=Rubik:ital,wght@0,300..900;1,300..900&display=swap');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Bengali:wght@100..900&family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap');
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@@ -17,4 +18,10 @@
|
||||
transition-property: background-color, color, border-color;
|
||||
transition-duration: var(--transition-duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.second-last-child {
|
||||
@apply nth-last-child(2);
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import App from './App.jsx'
|
||||
import './index.css'
|
||||
import './i18n'
|
||||
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
||||
import Placeholder from './pages/Placeholder.jsx';
|
||||
|
||||
|
@@ -1,9 +1,9 @@
|
||||
const getUserInfoFromSession = () => {
|
||||
return {
|
||||
"User Name": "Rajesh Kumar",
|
||||
"PACS / Bank Name": "Demo SKUS Ltd.",
|
||||
"User Type": "PACS Teller",
|
||||
"Module Name": "Locker",
|
||||
username: "Rajesh Kumar",
|
||||
pacsName: "Demo SKUS Ltd.",
|
||||
userType: "pacsTeller",
|
||||
moduleName: "locker",
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user