added eslint and prettier and formatted the whole codebase
This commit is contained in:
7
.prettierrc
Normal file
7
.prettierrc
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"semi": true,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"printWidth": 100,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "es5"
|
||||||
|
}
|
@@ -1,8 +1,10 @@
|
|||||||
import js from '@eslint/js'
|
import js from '@eslint/js';
|
||||||
import globals from 'globals'
|
import globals from 'globals';
|
||||||
import react from 'eslint-plugin-react'
|
import react from 'eslint-plugin-react';
|
||||||
import reactHooks from 'eslint-plugin-react-hooks'
|
import reactHooks from 'eslint-plugin-react-hooks';
|
||||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
import reactRefresh from 'eslint-plugin-react-refresh';
|
||||||
|
import prettier from 'eslint-plugin-prettier';
|
||||||
|
import prettierConfig from 'eslint-config-prettier';
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{ ignores: ['dist'] },
|
{ ignores: ['dist'] },
|
||||||
@@ -22,17 +24,17 @@ export default [
|
|||||||
react,
|
react,
|
||||||
'react-hooks': reactHooks,
|
'react-hooks': reactHooks,
|
||||||
'react-refresh': reactRefresh,
|
'react-refresh': reactRefresh,
|
||||||
|
prettier,
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
...js.configs.recommended.rules,
|
...js.configs.recommended.rules,
|
||||||
...react.configs.recommended.rules,
|
...react.configs.recommended.rules,
|
||||||
...react.configs['jsx-runtime'].rules,
|
...react.configs['jsx-runtime'].rules,
|
||||||
...reactHooks.configs.recommended.rules,
|
...reactHooks.configs.recommended.rules,
|
||||||
|
...prettierConfig.rules,
|
||||||
'react/jsx-no-target-blank': 'off',
|
'react/jsx-no-target-blank': 'off',
|
||||||
'react-refresh/only-export-components': [
|
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
|
||||||
'warn',
|
'prettier/prettier': 'error',
|
||||||
{ allowConstantExport: true },
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
];
|
||||||
|
115
package-lock.json
generated
115
package-lock.json
generated
@@ -28,11 +28,14 @@
|
|||||||
"@vitejs/plugin-react": "^4.3.1",
|
"@vitejs/plugin-react": "^4.3.1",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"eslint": "^9.9.0",
|
"eslint": "^9.9.0",
|
||||||
|
"eslint-config-prettier": "^10.1.8",
|
||||||
|
"eslint-plugin-prettier": "^5.5.4",
|
||||||
"eslint-plugin-react": "^7.35.0",
|
"eslint-plugin-react": "^7.35.0",
|
||||||
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
||||||
"eslint-plugin-react-refresh": "^0.4.9",
|
"eslint-plugin-react-refresh": "^0.4.9",
|
||||||
"globals": "^15.9.0",
|
"globals": "^15.9.0",
|
||||||
"postcss": "^8.4.47",
|
"postcss": "^8.4.47",
|
||||||
|
"prettier": "^3.6.2",
|
||||||
"tailwindcss": "^3.4.13",
|
"tailwindcss": "^3.4.13",
|
||||||
"vite": "^5.4.1"
|
"vite": "^5.4.1"
|
||||||
}
|
}
|
||||||
@@ -1090,6 +1093,19 @@
|
|||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@pkgr/core": {
|
||||||
|
"version": "0.2.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz",
|
||||||
|
"integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/pkgr"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@remix-run/router": {
|
"node_modules/@remix-run/router": {
|
||||||
"version": "1.19.2",
|
"version": "1.19.2",
|
||||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz",
|
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz",
|
||||||
@@ -2492,6 +2508,53 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-config-prettier": {
|
||||||
|
"version": "10.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz",
|
||||||
|
"integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"eslint-config-prettier": "bin/cli.js"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint-config-prettier"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-plugin-prettier": {
|
||||||
|
"version": "5.5.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz",
|
||||||
|
"integrity": "sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"prettier-linter-helpers": "^1.0.0",
|
||||||
|
"synckit": "^0.11.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.18.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint-plugin-prettier"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/eslint": ">=8.0.0",
|
||||||
|
"eslint": ">=8.0.0",
|
||||||
|
"eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0",
|
||||||
|
"prettier": ">=3.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/eslint": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"eslint-config-prettier": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint-plugin-react": {
|
"node_modules/eslint-plugin-react": {
|
||||||
"version": "7.37.0",
|
"version": "7.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.0.tgz",
|
||||||
@@ -2738,6 +2801,13 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-diff": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/fast-glob": {
|
"node_modules/fast-glob": {
|
||||||
"version": "3.3.2",
|
"version": "3.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
|
||||||
@@ -4655,6 +4725,35 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prettier": {
|
||||||
|
"version": "3.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
|
||||||
|
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"prettier": "bin/prettier.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/prettier-linter-helpers": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-diff": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prop-types": {
|
"node_modules/prop-types": {
|
||||||
"version": "15.8.1",
|
"version": "15.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||||
@@ -5371,6 +5470,22 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/synckit": {
|
||||||
|
"version": "0.11.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz",
|
||||||
|
"integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@pkgr/core": "^0.2.9"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.18.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/synckit"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tailwindcss": {
|
"node_modules/tailwindcss": {
|
||||||
"version": "3.4.13",
|
"version": "3.4.13",
|
||||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz",
|
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz",
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
|
"format": "prettier --write .",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -30,11 +31,14 @@
|
|||||||
"@vitejs/plugin-react": "^4.3.1",
|
"@vitejs/plugin-react": "^4.3.1",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"eslint": "^9.9.0",
|
"eslint": "^9.9.0",
|
||||||
|
"eslint-config-prettier": "^10.1.8",
|
||||||
|
"eslint-plugin-prettier": "^5.5.4",
|
||||||
"eslint-plugin-react": "^7.35.0",
|
"eslint-plugin-react": "^7.35.0",
|
||||||
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
||||||
"eslint-plugin-react-refresh": "^0.4.9",
|
"eslint-plugin-react-refresh": "^0.4.9",
|
||||||
"globals": "^15.9.0",
|
"globals": "^15.9.0",
|
||||||
"postcss": "^8.4.47",
|
"postcss": "^8.4.47",
|
||||||
|
"prettier": "^3.6.2",
|
||||||
"tailwindcss": "^3.4.13",
|
"tailwindcss": "^3.4.13",
|
||||||
"vite": "^5.4.1"
|
"vite": "^5.4.1"
|
||||||
}
|
}
|
||||||
|
@@ -3,4 +3,4 @@ export default {
|
|||||||
tailwindcss: {},
|
tailwindcss: {},
|
||||||
autoprefixer: {},
|
autoprefixer: {},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
"myIntimation": "আমার বিজ্ঞপ্তি",
|
"myIntimation": "আমার বিজ্ঞপ্তি",
|
||||||
"changePassword": "পাসওয়ার্ড পরিবর্তন",
|
"changePassword": "পাসওয়ার্ড পরিবর্তন",
|
||||||
"resetLogin": "লগইন স্ট্যাটাস রিসেট করুন",
|
"resetLogin": "লগইন স্ট্যাটাস রিসেট করুন",
|
||||||
"currentDate" : "{{val, datetime}}",
|
"currentDate": "{{val, datetime}}",
|
||||||
"notifications": "বিজ্ঞপ্তি",
|
"notifications": "বিজ্ঞপ্তি",
|
||||||
"holidayList": "ছুটির তালিকা",
|
"holidayList": "ছুটির তালিকা",
|
||||||
"information": "তথ্য",
|
"information": "তথ্য",
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
"myIntimation": "My Intimation",
|
"myIntimation": "My Intimation",
|
||||||
"changePassword": "Change Password",
|
"changePassword": "Change Password",
|
||||||
"resetLogin": "Reset Login Status",
|
"resetLogin": "Reset Login Status",
|
||||||
"currentDate" : "{{val, datetime}}",
|
"currentDate": "{{val, datetime}}",
|
||||||
"notifications": "Notification",
|
"notifications": "Notification",
|
||||||
"holidayList": "Holiday List",
|
"holidayList": "Holiday List",
|
||||||
"information": "Information",
|
"information": "Information",
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
"myIntimation": "मेरा सूचितकरण",
|
"myIntimation": "मेरा सूचितकरण",
|
||||||
"changePassword": "पासवर्ड बदलें",
|
"changePassword": "पासवर्ड बदलें",
|
||||||
"resetLogin": "लॉगिन स्थिति रीसेट करें",
|
"resetLogin": "लॉगिन स्थिति रीसेट करें",
|
||||||
"currentDate" : "{{val, datetime}}",
|
"currentDate": "{{val, datetime}}",
|
||||||
"notifications": "सूचना",
|
"notifications": "सूचना",
|
||||||
"holidayList": "छुट्टी की सूची",
|
"holidayList": "छुट्टी की सूची",
|
||||||
"information": "जानकारी",
|
"information": "जानकारी",
|
||||||
|
20
src/App.jsx
20
src/App.jsx
@@ -1,13 +1,13 @@
|
|||||||
import { useLocation, useOutlet } from "react-router";
|
import { useLocation, useOutlet } from 'react-router';
|
||||||
import { useState } from "react";
|
import { useState } from 'react';
|
||||||
import Header from "./components/Header";
|
import Header from './components/Header';
|
||||||
import Footer from "./components/Footer";
|
import Footer from './components/Footer';
|
||||||
import { AnimatePresence } from "motion/react";
|
import { AnimatePresence } from 'motion/react';
|
||||||
import { motion } from "motion/react";
|
import { motion } from 'motion/react';
|
||||||
import { ToastProvider } from "./contexts/Toast";
|
import { ToastProvider } from './contexts/Toast';
|
||||||
import { useLoading } from "./hooks/useLoading";
|
import { useLoading } from './hooks/useLoading';
|
||||||
import LoadingBar from "./components/LoadingBar";
|
import LoadingBar from './components/LoadingBar';
|
||||||
import { LoadingProvider } from "./contexts/Loading";
|
import { LoadingProvider } from './contexts/Loading';
|
||||||
|
|
||||||
const AnimatedOutlet = () => {
|
const AnimatedOutlet = () => {
|
||||||
const o = useOutlet();
|
const o = useOutlet();
|
||||||
|
@@ -3,16 +3,15 @@ import DarkModeToggle from './DarkModeToggle';
|
|||||||
import LanguageSelector from './LanguageSelector';
|
import LanguageSelector from './LanguageSelector';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
|
||||||
function AppTitle() {
|
function AppTitle() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<div className='flex items-center justify-between pt-3 pb-5'>
|
<div className="flex items-center justify-between pt-3 pb-5">
|
||||||
<div className='flex items-center gap-5'>
|
<div className="flex items-center gap-5">
|
||||||
<img src={IpksLogo} alt="IPKS Logo" className="h-16" />
|
<img src={IpksLogo} alt="IPKS Logo" className="h-16" />
|
||||||
<h1 className="font-bold text-title font-display">{t('appName')}</h1>
|
<h1 className="font-bold text-title font-display">{t('appName')}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex items-center gap-2'>
|
<div className="flex items-center gap-2">
|
||||||
<DarkModeToggle />
|
<DarkModeToggle />
|
||||||
<LanguageSelector />
|
<LanguageSelector />
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,31 +1,30 @@
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
import BannerInfoElement from "./BannerInfoElement";
|
import BannerInfoElement from './BannerInfoElement';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
function BannerInfo({info}) {
|
function BannerInfo({ info }) {
|
||||||
const {t} = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const infoElements = Object.keys(info).map((key) => (
|
const infoElements = Object.keys(info).map((key) => (
|
||||||
<BannerInfoElement key={key} title={t(key)} description={t(info[key])} />
|
<BannerInfoElement key={key} title={t(key)} description={t(info[key])} />
|
||||||
))
|
));
|
||||||
infoElements.push(
|
infoElements.push(
|
||||||
<BannerInfoElement
|
<BannerInfoElement
|
||||||
key="date"
|
key="date"
|
||||||
title={t('date')}
|
title={t('date')}
|
||||||
description={t('currentDate',{val: new Date(), formatParams: {
|
description={t('currentDate', {
|
||||||
val: { month: 'long', day: '2-digit', year: 'numeric'},
|
val: new Date(),
|
||||||
},})}
|
formatParams: {
|
||||||
|
val: { month: 'long', day: '2-digit', year: 'numeric' },
|
||||||
|
},
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
return (
|
return <div className="flex justify-between pb-1">{infoElements}</div>;
|
||||||
<div className="flex justify-between pb-1">
|
|
||||||
{infoElements}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BannerInfo.propTypes = {
|
BannerInfo.propTypes = {
|
||||||
info: PropTypes.object.isRequired
|
info: PropTypes.object.isRequired,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default BannerInfo;
|
export default BannerInfo;
|
@@ -2,16 +2,16 @@ import PropTypes from 'prop-types';
|
|||||||
|
|
||||||
function BannerInfoElement({ title, description }) {
|
function BannerInfoElement({ title, description }) {
|
||||||
return (
|
return (
|
||||||
<div className='font-body'>
|
<div className="font-body">
|
||||||
<div className='text-base '>{title}</div>
|
<div className="text-base ">{title}</div>
|
||||||
<div className='text-[18px] font-medium'>{description}</div>
|
<div className="text-[18px] font-medium">{description}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
BannerInfoElement.propTypes = {
|
BannerInfoElement.propTypes = {
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
description: PropTypes.string.isRequired
|
description: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default BannerInfoElement;
|
export default BannerInfoElement;
|
@@ -2,18 +2,21 @@ import PropTypes from 'prop-types';
|
|||||||
import { motion } from 'motion/react';
|
import { motion } from 'motion/react';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
function Button({text, onClick, disabled}) {
|
function Button({ text, onClick, disabled }) {
|
||||||
return (
|
return (
|
||||||
<motion.button
|
<motion.button
|
||||||
whileHover={!disabled && { scale: 1.05 }}
|
whileHover={!disabled && { scale: 1.05 }}
|
||||||
whileTap={!disabled && { scale: 0.95 }}
|
whileTap={!disabled && { scale: 0.95 }}
|
||||||
className={clsx("px-12 py-2 text-lg text-white dark:text-primary-dark rounded-full bg-primary dark:bg-secondary-dark", disabled && "bg-[#cccccc] dark:bg-[#cccccc]")}
|
className={clsx(
|
||||||
|
'px-12 py-2 text-lg text-white dark:text-primary-dark rounded-full bg-primary dark:bg-secondary-dark',
|
||||||
|
disabled && 'bg-[#cccccc] dark:bg-[#cccccc]'
|
||||||
|
)}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
{text}
|
{text}
|
||||||
</motion.button>
|
</motion.button>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Button.propTypes = {
|
Button.propTypes = {
|
||||||
|
@@ -17,7 +17,7 @@ const DarkModeToggle = () => {
|
|||||||
}, [darkMode]);
|
}, [darkMode]);
|
||||||
|
|
||||||
const toggleDarkMode = () => {
|
const toggleDarkMode = () => {
|
||||||
setDarkMode(prevMode => !prevMode);
|
setDarkMode((prevMode) => !prevMode);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
import { motion } from "motion/react";
|
import { motion } from 'motion/react';
|
||||||
|
|
||||||
function FieldError({ text }) {
|
function FieldError({ text }) {
|
||||||
return (
|
return (
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
function FieldsWrapper({ children, className = "" }) {
|
function FieldsWrapper({ children, className = '' }) {
|
||||||
return <div className={`flex flex-col gap-4 m-2 my-7 ${className}`}>{children}</div>;
|
return <div className={`flex flex-col gap-4 m-2 my-7 ${className}`}>{children}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { PropTypes } from "prop-types";
|
import { PropTypes } from 'prop-types';
|
||||||
import clsx from "clsx";
|
import clsx from 'clsx';
|
||||||
|
|
||||||
function FormBox({ title, children, alt = false }) {
|
function FormBox({ title, children, alt = false }) {
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={clsx(
|
className={clsx(
|
||||||
alt
|
alt
|
||||||
? "bg-secondary-variant dark:bg-secondary-variant-dark border-secondary-variant dark:border-secondary-variant-dark"
|
? 'bg-secondary-variant dark:bg-secondary-variant-dark border-secondary-variant dark:border-secondary-variant-dark'
|
||||||
: "bg-surface-variant dark:bg-surface-variant-dark",
|
: 'bg-surface-variant dark:bg-surface-variant-dark',
|
||||||
"transition-color-mode font-body border-secondary dark:border-secondary-dark border-2 p-4 rounded-3xl relative h-full"
|
'transition-color-mode font-body border-secondary dark:border-secondary-dark border-2 p-4 rounded-3xl relative h-full'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
className={clsx(
|
className={clsx(
|
||||||
alt &&
|
alt &&
|
||||||
"bg-surface dark:bg-surface-dark border-3 border-secondary-variant dark:border-secondary-variant-dark",
|
'bg-surface dark:bg-surface-dark border-3 border-secondary-variant dark:border-secondary-variant-dark',
|
||||||
"font-body absolute left-11 -top-4 bg-secondary dark:bg-secondary-dark text-primary dark:text-primary-dark font-medium py-1 px-4 rounded-full z-20"
|
'font-body absolute left-11 -top-4 bg-secondary dark:bg-secondary-dark text-primary dark:text-primary-dark font-medium py-1 px-4 rounded-full z-20'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
|
@@ -1,30 +1,35 @@
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
import { motion } from "motion/react";
|
import { motion } from 'motion/react';
|
||||||
import clsx from "clsx";
|
import clsx from 'clsx';
|
||||||
|
|
||||||
function FormField({ label, children, icon, variant }) {
|
function FormField({ label, children, icon, variant }) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<label className={clsx(
|
<label
|
||||||
"mr-20 text-lg text-black dark:text-primary-dark whitespace-nowrap",
|
className={clsx(
|
||||||
variant === 'long' && "sm:w-[5%]"
|
'mr-20 text-lg text-black dark:text-primary-dark whitespace-nowrap',
|
||||||
)}>
|
variant === 'long' && 'sm:w-[5%]'
|
||||||
|
)}
|
||||||
|
>
|
||||||
{label}
|
{label}
|
||||||
</label>
|
</label>
|
||||||
<div className={clsx("flex w-full gap-4 items-center", variant === 'long' && 'gap-10')}>
|
<div className={clsx('flex w-full gap-4 items-center', variant === 'long' && 'gap-10')}>
|
||||||
{children}
|
{children}
|
||||||
{icon && (
|
{icon && (
|
||||||
<motion.div
|
<motion.div
|
||||||
whileHover={{ scale: 1.1 }}
|
whileHover={{ scale: 1.1 }}
|
||||||
whileTap={{ scale: 0.9 }}
|
whileTap={{ scale: 0.9 }}
|
||||||
className={clsx(icon.mode === "plain" ? "text-[#444]" : "bg-primary rounded-full p-2 text-white cursor-pointer")}
|
className={clsx(
|
||||||
|
icon.mode === 'plain'
|
||||||
|
? 'text-[#444]'
|
||||||
|
: 'bg-primary rounded-full p-2 text-white cursor-pointer'
|
||||||
|
)}
|
||||||
onClick={icon.onClick}
|
onClick={icon.onClick}
|
||||||
>
|
>
|
||||||
{icon.icon}
|
{icon.icon}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -33,7 +38,7 @@ FormField.propTypes = {
|
|||||||
label: PropTypes.string.isRequired,
|
label: PropTypes.string.isRequired,
|
||||||
children: PropTypes.node.isRequired,
|
children: PropTypes.node.isRequired,
|
||||||
icon: PropTypes.object,
|
icon: PropTypes.object,
|
||||||
variant: PropTypes.string
|
variant: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FormField;
|
export default FormField;
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
function FormHeader({ text }) {
|
function FormHeader({ text }) {
|
||||||
return <h1 className="text-2xl font-medium text-primary mt-5">{text}</h1>;
|
return <h1 className="text-2xl font-medium text-primary mt-5">{text}</h1>;
|
||||||
}
|
}
|
||||||
|
|
||||||
FormHeader.propTypes = {
|
FormHeader.propTypes = {
|
||||||
text: PropTypes.string.isRequired
|
text: PropTypes.string.isRequired,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default FormHeader;
|
export default FormHeader;
|
||||||
|
@@ -1,15 +1,15 @@
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
import { motion, AnimatePresence } from "motion/react";
|
import { motion, AnimatePresence } from 'motion/react';
|
||||||
import clsx from "clsx";
|
import clsx from 'clsx';
|
||||||
|
|
||||||
function FormInput({ props, valid = true, className = "" }) {
|
function FormInput({ props, valid = true, className = '' }) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
{...props}
|
{...props}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
`w-72 h-10 px-2 rounded-full dark:bg-white dark:text-grey border-2 text-grey focus:outline-grey ${className}`,
|
`w-72 h-10 px-2 rounded-full dark:bg-white dark:text-grey border-2 text-grey focus:outline-grey ${className}`,
|
||||||
!valid && "border-error"
|
!valid && 'border-error'
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
import { AnimatePresence } from "motion/react";
|
import { AnimatePresence } from 'motion/react';
|
||||||
import clsx from "clsx";
|
import clsx from 'clsx';
|
||||||
import FieldError from "./FieldError";
|
import FieldError from './FieldError';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
function FormSelect({ props, valid = true, className = "", options }) {
|
function FormSelect({ props, valid = true, className = '', options }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -12,11 +12,11 @@ function FormSelect({ props, valid = true, className = "", options }) {
|
|||||||
{...props}
|
{...props}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
`w-72 h-10 px-2 rounded-full dark:bg-white dark:text-grey border-2 text-grey focus:outline-grey ${className}`,
|
`w-72 h-10 px-2 rounded-full dark:bg-white dark:text-grey border-2 text-grey focus:outline-grey ${className}`,
|
||||||
!valid && "border-error"
|
!valid && 'border-error'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<option disabled value="">
|
<option disabled value="">
|
||||||
{t("select")}
|
{t('select')}
|
||||||
</option>
|
</option>
|
||||||
{options?.map(({ value, label }) => (
|
{options?.map(({ value, label }) => (
|
||||||
<option key={value} value={value}>
|
<option key={value} value={value}>
|
||||||
@@ -24,9 +24,7 @@ function FormSelect({ props, valid = true, className = "", options }) {
|
|||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
<AnimatePresence>
|
<AnimatePresence>{!valid && <FieldError text={'Invalid value'} />}</AnimatePresence>
|
||||||
{!valid && <FieldError text={"Invalid value"} />}
|
|
||||||
</AnimatePresence>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -1,43 +1,52 @@
|
|||||||
import { getUserInfoFromSession } from "../util/util";
|
import { getUserInfoFromSession } from '../util/util';
|
||||||
import AppTitle from "./AppTitle";
|
import AppTitle from './AppTitle';
|
||||||
import BannerInfo from "./BannerInfo";
|
import BannerInfo from './BannerInfo';
|
||||||
import MenuBar from "./MenuBar";
|
import MenuBar from './MenuBar';
|
||||||
import Separator from "./Separator";
|
import Separator from './Separator';
|
||||||
|
|
||||||
function Header() {
|
function Header() {
|
||||||
const userInfo = getUserInfoFromSession();
|
const userInfo = getUserInfoFromSession();
|
||||||
const menuItems = [
|
const menuItems = [
|
||||||
{ name: "home", submenu: [], path: "/" },
|
{ name: 'home', submenu: [], path: '/' },
|
||||||
{
|
{
|
||||||
name: "moduleList",
|
name: 'moduleList',
|
||||||
submenu: [
|
submenu: [
|
||||||
{ name: "kcc", path: "kcc" },
|
{ name: 'kcc', path: 'kcc' },
|
||||||
{ name: "trading", path: "trading" },
|
{ name: 'trading', path: 'trading' },
|
||||||
{ name: "asset", path: "asset" },
|
{ name: 'asset', path: 'asset' },
|
||||||
{ name: "selfHelpGroup", path: "shg" },
|
{ name: 'selfHelpGroup', path: 'shg' },
|
||||||
{ name: "deposit", path: "deposit" },
|
{ name: 'deposit', path: 'deposit' },
|
||||||
{ name: "loan", path: "loan" },
|
{ name: 'loan', path: 'loan' },
|
||||||
{ name: "share", path: "share" },
|
{ name: 'share', path: 'share' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ name: "enquiry", submenu: [{ name: "lockerEnquiry", path: "locker-enquiry" }, { name: "accountEnquiry", path: "account-enquiry" }] },
|
|
||||||
{
|
{
|
||||||
name: "lockerOperation",
|
name: 'enquiry',
|
||||||
submenu: [
|
submenu: [
|
||||||
{ name: "accountCreation", path: "operation/account" },
|
{ name: 'lockerEnquiry', path: 'locker-enquiry' },
|
||||||
{ name: "cabinetMaintenance", path: "operation/cabinet" },
|
{ name: 'accountEnquiry', path: 'account-enquiry' },
|
||||||
{ name: "lockerMaintenance", path: "operation/locker" },
|
|
||||||
{ name: "chargeManagement", path: "operation/charge-management" },
|
|
||||||
{ name: "checkInOutManagement", path: "operation/check-in-out" },
|
|
||||||
{ name: "accountSurrender", path: "operation/account-surrender" }
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ name: "worklist", submenu: [{ name: "myIntimation", path: "my-intimation" }] },
|
|
||||||
{
|
{
|
||||||
name: "userManagement",
|
name: 'lockerOperation',
|
||||||
submenu: [{ name: "resetLogin", path: "reset-login" }, { name: "changePassword", path: "change-password" }],
|
submenu: [
|
||||||
|
{ name: 'accountCreation', path: 'operation/account' },
|
||||||
|
{ name: 'cabinetMaintenance', path: 'operation/cabinet' },
|
||||||
|
{ name: 'lockerMaintenance', path: 'operation/locker' },
|
||||||
|
{ name: 'chargeManagement', path: 'operation/charge-management' },
|
||||||
|
{ name: 'checkInOutManagement', path: 'operation/check-in-out' },
|
||||||
|
{ name: 'accountSurrender', path: 'operation/account-surrender' },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{ name: "logout", submenu: [] },
|
{ name: 'worklist', submenu: [{ name: 'myIntimation', path: 'my-intimation' }] },
|
||||||
|
{
|
||||||
|
name: 'userManagement',
|
||||||
|
submenu: [
|
||||||
|
{ name: 'resetLogin', path: 'reset-login' },
|
||||||
|
{ name: 'changePassword', path: 'change-password' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ name: 'logout', submenu: [] },
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -47,7 +56,7 @@ function Header() {
|
|||||||
<Separator />
|
<Separator />
|
||||||
<MenuBar menuItems={menuItems} />
|
<MenuBar menuItems={menuItems} />
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Header;
|
export default Header;
|
||||||
|
@@ -9,7 +9,12 @@ const LanguageSelector = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<select className='rounded-md font-body bg-secondary dark:bg-secondary-dark focus:outline-none' id="language-select" onChange={changeLanguage} value={i18n.language}>
|
<select
|
||||||
|
className="rounded-md font-body bg-secondary dark:bg-secondary-dark focus:outline-none"
|
||||||
|
id="language-select"
|
||||||
|
onChange={changeLanguage}
|
||||||
|
value={i18n.language}
|
||||||
|
>
|
||||||
<option value="en">English</option>
|
<option value="en">English</option>
|
||||||
<option value="bn">বাংলা</option>
|
<option value="bn">বাংলা</option>
|
||||||
<option value="hi">हिन्दी</option>
|
<option value="hi">हिन्दी</option>
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
import { motion } from "framer-motion";
|
import { motion } from 'framer-motion';
|
||||||
|
|
||||||
function LoadingBar() {
|
function LoadingBar() {
|
||||||
return (
|
return (
|
||||||
<div className="h-1 bg-grey relative overflow-hidden">
|
<div className="h-1 bg-grey relative overflow-hidden">
|
||||||
<motion.div
|
<motion.div
|
||||||
className="bg-primary dark:bg-primary-dark w-full h-full rounded-sm absolute"
|
className="bg-primary dark:bg-primary-dark w-full h-full rounded-sm absolute"
|
||||||
animate={{ x: ["-100%", "100%"] }}
|
animate={{ x: ['-100%', '100%'] }}
|
||||||
transition={{ repeat: Infinity, duration: 2, ease: "anticipate" }}
|
transition={{ repeat: Infinity, duration: 2, ease: 'anticipate' }}
|
||||||
></motion.div>
|
></motion.div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
import { Link } from "react-router-dom";
|
import { Link } from 'react-router-dom';
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import clsx from "clsx";
|
import clsx from 'clsx';
|
||||||
import { useState } from "react";
|
import { useState } from 'react';
|
||||||
import { AnimatePresence, motion } from "motion/react";
|
import { AnimatePresence, motion } from 'motion/react';
|
||||||
|
|
||||||
function SubMenu({ items, isVisible, onLinkClick }) {
|
function SubMenu({ items, isVisible, onLinkClick }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -13,12 +13,12 @@ function SubMenu({ items, isVisible, onLinkClick }) {
|
|||||||
<div>
|
<div>
|
||||||
<motion.div
|
<motion.div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"absolute left-0 z-50 shadow-sm top-full border-t-3 border-primary dark:border-primary-dark bg-secondary dark:bg-secondary-dark rounded-2xl shadow-surface-variant-dark dark:shadow-primary"
|
'absolute left-0 z-50 shadow-sm top-full border-t-3 border-primary dark:border-primary-dark bg-secondary dark:bg-secondary-dark rounded-2xl shadow-surface-variant-dark dark:shadow-primary'
|
||||||
)}
|
)}
|
||||||
initial={{ y: 15, opacity: 0 }}
|
initial={{ y: 15, opacity: 0 }}
|
||||||
animate={{ y: 0, opacity: 1 }}
|
animate={{ y: 0, opacity: 1 }}
|
||||||
exit={{ y: 15, opacity: 0 }}
|
exit={{ y: 15, opacity: 0 }}
|
||||||
transition={{ duration: 0.3, type: "spring" }}
|
transition={{ duration: 0.3, type: 'spring' }}
|
||||||
>
|
>
|
||||||
{items.map((subItem, index) => (
|
{items.map((subItem, index) => (
|
||||||
<div
|
<div
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import clsx from "clsx";
|
import clsx from 'clsx';
|
||||||
import { Copy } from "lucide-react";
|
import { Copy } from 'lucide-react';
|
||||||
import { motion } from "motion/react";
|
import { motion } from 'motion/react';
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
function Notification({ message, type }) {
|
function Notification({ message, type }) {
|
||||||
return (
|
return (
|
||||||
@@ -10,17 +10,17 @@ function Notification({ message, type }) {
|
|||||||
animate={{ y: 0, opacity: 1 }}
|
animate={{ y: 0, opacity: 1 }}
|
||||||
exit={{ y: 15, opacity: 0 }}
|
exit={{ y: 15, opacity: 0 }}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"p-2 pl-8 mb-8 font-body text-lg border-2 rounded-3xl flex items-center gap-2",
|
'p-2 pl-8 mb-8 font-body text-lg border-2 rounded-3xl flex items-center gap-2',
|
||||||
type === "error"
|
type === 'error'
|
||||||
? "bg-error-surface text-white border-error"
|
? 'bg-error-surface text-white border-error'
|
||||||
: type === "success"
|
: type === 'success'
|
||||||
? "bg-success text-white border-green-700"
|
? 'bg-success text-white border-green-700'
|
||||||
: type === "warning"
|
: type === 'warning'
|
||||||
? "bg-warning-surface text-white border-warning"
|
? 'bg-warning-surface text-white border-warning'
|
||||||
: ""
|
: ''
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{message.split(":").map((msg, index) => {
|
{message.split(':').map((msg, index) => {
|
||||||
return index === 1 ? (
|
return index === 1 ? (
|
||||||
<span key={index} className="border-b border-dashed">
|
<span key={index} className="border-b border-dashed">
|
||||||
{msg}
|
{msg}
|
||||||
@@ -29,11 +29,11 @@ function Notification({ message, type }) {
|
|||||||
<span key={index}>{msg}</span>
|
<span key={index}>{msg}</span>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{message.split(":")[1] && (
|
{message.split(':')[1] && (
|
||||||
<Copy
|
<Copy
|
||||||
cursor={"pointer"}
|
cursor={'pointer'}
|
||||||
size={15}
|
size={15}
|
||||||
onClick={navigator.clipboard.writeText(message.split(":")[1].trim())}
|
onClick={navigator.clipboard.writeText(message.split(':')[1].trim())}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import clsx from "clsx";
|
import clsx from 'clsx';
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
function ProductListTable({ productInfo, onSelectProduct }) {
|
function ProductListTable({ productInfo, onSelectProduct }) {
|
||||||
return (
|
return (
|
||||||
@@ -29,32 +29,32 @@ function ProductListTable({ productInfo, onSelectProduct }) {
|
|||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"border border-l-2 border-primary p-2",
|
'border border-l-2 border-primary p-2',
|
||||||
idx === productInfo.length - 1 && "rounded-bl-2xl border-b-2"
|
idx === productInfo.length - 1 && 'rounded-bl-2xl border-b-2'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{prod.productCode}
|
{prod.productCode}
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"border border-primary p-2",
|
'border border-primary p-2',
|
||||||
idx === productInfo.length - 1 && "border-b-2"
|
idx === productInfo.length - 1 && 'border-b-2'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{prod.productCodeDescription}
|
{prod.productCodeDescription}
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"border border-primary p-2",
|
'border border-primary p-2',
|
||||||
idx === productInfo.length - 1 && "border-b-2"
|
idx === productInfo.length - 1 && 'border-b-2'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{prod.interestCategory}
|
{prod.interestCategory}
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"border border-r-2 border-primary p-2",
|
'border border-r-2 border-primary p-2',
|
||||||
idx === productInfo.length - 1 && "rounded-br-2xl border-b-2"
|
idx === productInfo.length - 1 && 'rounded-br-2xl border-b-2'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{prod.interestCategoryDescription}
|
{prod.interestCategoryDescription}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { motion } from "motion/react";
|
import { motion } from 'motion/react';
|
||||||
import ProductListTable from "./ProductListTable";
|
import ProductListTable from './ProductListTable';
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
function ProductModal({ productInfo, handleProductSelect }) {
|
function ProductModal({ productInfo, handleProductSelect }) {
|
||||||
return (
|
return (
|
||||||
@@ -18,10 +18,7 @@ function ProductModal({ productInfo, handleProductSelect }) {
|
|||||||
className="flex flex-col items-center bg-white p-4 py-8 rounded-3xl w-[60%] max-h-[80%] overflow-auto font-body"
|
className="flex flex-col items-center bg-white p-4 py-8 rounded-3xl w-[60%] max-h-[80%] overflow-auto font-body"
|
||||||
>
|
>
|
||||||
<h2 className="text-xl mb-4">Select Product</h2>
|
<h2 className="text-xl mb-4">Select Product</h2>
|
||||||
<ProductListTable
|
<ProductListTable productInfo={productInfo} onSelectProduct={handleProductSelect} />
|
||||||
productInfo={productInfo}
|
|
||||||
onSelectProduct={handleProductSelect}
|
|
||||||
/>
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
);
|
);
|
||||||
|
@@ -3,7 +3,7 @@ function Separator() {
|
|||||||
<div className="h-[2px]">
|
<div className="h-[2px]">
|
||||||
<div className="w-full h-full bg-white rounded-md dark:bg-primary-dark"></div>
|
<div className="w-full h-full bg-white rounded-md dark:bg-primary-dark"></div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Separator;
|
export default Separator;
|
@@ -16,4 +16,3 @@ export function LoadingProvider({ children }) {
|
|||||||
LoadingProvider.propTypes = {
|
LoadingProvider.propTypes = {
|
||||||
children: PropTypes.node.isRequired,
|
children: PropTypes.node.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,22 +1,22 @@
|
|||||||
import { createContext, useState } from "react";
|
import { createContext, useState } from 'react';
|
||||||
import { CircleAlert, X, CircleX, Check } from "lucide-react";
|
import { CircleAlert, X, CircleX, Check } from 'lucide-react';
|
||||||
import { toTitleCase } from "../util/util";
|
import { toTitleCase } from '../util/util';
|
||||||
|
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
export const ToastContext = createContext();
|
export const ToastContext = createContext();
|
||||||
|
|
||||||
export const ToastProvider = ({ children }) => {
|
export const ToastProvider = ({ children }) => {
|
||||||
const [toast, setToast] = useState({ show: false, message: "", type: "" });
|
const [toast, setToast] = useState({ show: false, message: '', type: '' });
|
||||||
|
|
||||||
const playAudio = (type) => {
|
const playAudio = (type) => {
|
||||||
let audioSrc;
|
let audioSrc;
|
||||||
if(type === "warning") audioSrc = "/audio/warning.mp3";
|
if (type === 'warning') audioSrc = '/audio/warning.mp3';
|
||||||
else if (type === "error") audioSrc = "/audio/error.mp3";
|
else if (type === 'error') audioSrc = '/audio/error.mp3';
|
||||||
|
|
||||||
if (audioSrc) {
|
if (audioSrc) {
|
||||||
const audio = new Audio(audioSrc);
|
const audio = new Audio(audioSrc);
|
||||||
audio.play().catch((error) => console.error("Error playing audio:", error));
|
audio.play().catch((error) => console.error('Error playing audio:', error));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -24,28 +24,28 @@ export const ToastProvider = ({ children }) => {
|
|||||||
playAudio(type);
|
playAudio(type);
|
||||||
setToast({ show: true, message, type });
|
setToast({ show: true, message, type });
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setToast({ show: false, message: "", type: "" });
|
setToast({ show: false, message: '', type: '' });
|
||||||
}, 7000);
|
}, 7000);
|
||||||
};
|
};
|
||||||
let toastIcon;
|
let toastIcon;
|
||||||
let surfaceColor;
|
let surfaceColor;
|
||||||
let borderColor;
|
let borderColor;
|
||||||
if(toast.type === "warning") {
|
if (toast.type === 'warning') {
|
||||||
toastIcon = <CircleAlert size={30} fill="#EA7000" stroke="#FDF1E5" />;
|
toastIcon = <CircleAlert size={30} fill="#EA7000" stroke="#FDF1E5" />;
|
||||||
surfaceColor = "bg-warning-surface";
|
surfaceColor = 'bg-warning-surface';
|
||||||
borderColor = "border-warning";
|
borderColor = 'border-warning';
|
||||||
} else if(toast.type === "success") {
|
} else if (toast.type === 'success') {
|
||||||
toastIcon = <Check size={30} color="green"/>;
|
toastIcon = <Check size={30} color="green" />;
|
||||||
surfaceColor = "bg-success-surface";
|
surfaceColor = 'bg-success-surface';
|
||||||
borderColor = "border-success";
|
borderColor = 'border-success';
|
||||||
} else if (toast.type === "error") {
|
} else if (toast.type === 'error') {
|
||||||
toastIcon = <CircleX size={30} fill="#E5254B" stroke="#FCE9ED" />;
|
toastIcon = <CircleX size={30} fill="#E5254B" stroke="#FCE9ED" />;
|
||||||
surfaceColor = "bg-error-surface";
|
surfaceColor = 'bg-error-surface';
|
||||||
borderColor = "border-error";
|
borderColor = 'border-error';
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ToastContext.Provider value={ showToast }>
|
<ToastContext.Provider value={showToast}>
|
||||||
{children}
|
{children}
|
||||||
{toast.show && (
|
{toast.show && (
|
||||||
<div
|
<div
|
||||||
@@ -57,7 +57,7 @@ export const ToastProvider = ({ children }) => {
|
|||||||
<div className="text-lg text-onToast">{toTitleCase(toast.type)}</div>
|
<div className="text-lg text-onToast">{toTitleCase(toast.type)}</div>
|
||||||
<div className="text-sm font-body">{toast.message}</div>
|
<div className="text-sm font-body">{toast.message}</div>
|
||||||
</div>
|
</div>
|
||||||
<X onClick={() => setToast({ show: false, message: "", type: "" })}/>
|
<X onClick={() => setToast({ show: false, message: '', type: '' })} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</ToastContext.Provider>
|
</ToastContext.Provider>
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { useContext } from "react";
|
import { useContext } from 'react';
|
||||||
import { LoadingContext } from "../contexts/Loading";
|
import { LoadingContext } from '../contexts/Loading';
|
||||||
|
|
||||||
export const useLoading = () => useContext(LoadingContext);
|
export const useLoading = () => useContext(LoadingContext);
|
@@ -1,4 +1,4 @@
|
|||||||
import { useContext } from "react";
|
import { useContext } from 'react';
|
||||||
import { ToastContext } from "../contexts/Toast";
|
import { ToastContext } from '../contexts/Toast';
|
||||||
|
|
||||||
export const useToast = () => useContext(ToastContext);
|
export const useToast = () => useContext(ToastContext);
|
||||||
|
68
src/main.jsx
68
src/main.jsx
@@ -1,25 +1,25 @@
|
|||||||
import { StrictMode } from "react";
|
import { StrictMode } from 'react';
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from 'react-dom/client';
|
||||||
import App from "./App.jsx";
|
import App from './App.jsx';
|
||||||
import "./index.css";
|
import './index.css';
|
||||||
import "./i18n";
|
import './i18n';
|
||||||
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
||||||
import Home from "./pages/Home.jsx";
|
import Home from './pages/Home.jsx';
|
||||||
import CabinetMaintenace from "./pages/CabinetMaintenance.jsx";
|
import CabinetMaintenace from './pages/CabinetMaintenance.jsx';
|
||||||
import CabinetCreation from "./pages/CabinetCreation.jsx";
|
import CabinetCreation from './pages/CabinetCreation.jsx';
|
||||||
import LockersRegistration from "./pages/LockersRegistration.jsx";
|
import LockersRegistration from './pages/LockersRegistration.jsx';
|
||||||
import AccountCreation from "./pages/AccountCreation.jsx";
|
import AccountCreation from './pages/AccountCreation.jsx';
|
||||||
import LockerMaintenance from "./pages/LockerMaintenance.jsx";
|
import LockerMaintenance from './pages/LockerMaintenance.jsx';
|
||||||
import LockerStatus from "./pages/LockerStatus.jsx";
|
import LockerStatus from './pages/LockerStatus.jsx';
|
||||||
import KeySwap from "./pages/KeySwap.jsx";
|
import KeySwap from './pages/KeySwap.jsx';
|
||||||
import ChargeManagement from "./pages/ChargeManagement.jsx";
|
import ChargeManagement from './pages/ChargeManagement.jsx';
|
||||||
import ChargeEdit from "./pages/ChargeEdit.jsx";
|
import ChargeEdit from './pages/ChargeEdit.jsx';
|
||||||
import CheckInOutManagement from "./pages/CheckInOutManagement.jsx";
|
import CheckInOutManagement from './pages/CheckInOutManagement.jsx';
|
||||||
import CheckInOutLog from "./pages/CheckInOutLog.jsx";
|
import CheckInOutLog from './pages/CheckInOutLog.jsx';
|
||||||
|
|
||||||
const router = createBrowserRouter([
|
const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
path: "/",
|
path: '/',
|
||||||
element: <App />,
|
element: <App />,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@@ -27,54 +27,54 @@ const router = createBrowserRouter([
|
|||||||
element: <Home />,
|
element: <Home />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "operation/cabinet",
|
path: 'operation/cabinet',
|
||||||
element: <CabinetMaintenace />,
|
element: <CabinetMaintenace />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "operation/cabinet/create",
|
path: 'operation/cabinet/create',
|
||||||
element: <CabinetCreation />,
|
element: <CabinetCreation />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "operation/cabinet/create/register-lockers",
|
path: 'operation/cabinet/create/register-lockers',
|
||||||
element: <LockersRegistration />,
|
element: <LockersRegistration />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "operation/account",
|
path: 'operation/account',
|
||||||
element: <AccountCreation />,
|
element: <AccountCreation />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "operation/locker",
|
path: 'operation/locker',
|
||||||
element: <LockerMaintenance />,
|
element: <LockerMaintenance />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "operation/locker/status",
|
path: 'operation/locker/status',
|
||||||
element: <LockerStatus />,
|
element: <LockerStatus />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "operation/locker/key-swap",
|
path: 'operation/locker/key-swap',
|
||||||
element: <KeySwap />,
|
element: <KeySwap />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "operation/charge-management",
|
path: 'operation/charge-management',
|
||||||
element: <ChargeManagement />,
|
element: <ChargeManagement />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "operation/charge-management/change",
|
path: 'operation/charge-management/change',
|
||||||
element: <ChargeEdit />,
|
element: <ChargeEdit />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "operation/check-in-out",
|
path: 'operation/check-in-out',
|
||||||
element: <CheckInOutManagement />
|
element: <CheckInOutManagement />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "operation/check-in-out/log",
|
path: 'operation/check-in-out/log',
|
||||||
element: <CheckInOutLog />
|
element: <CheckInOutLog />,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
createRoot(document.getElementById("root")).render(
|
createRoot(document.getElementById('root')).render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<RouterProvider router={router} />
|
<RouterProvider router={router} />
|
||||||
</StrictMode>
|
</StrictMode>
|
||||||
|
@@ -1,33 +1,33 @@
|
|||||||
import { AnimatePresence } from "motion/react";
|
import { AnimatePresence } from 'motion/react';
|
||||||
import { PackageSearch, UserSearch } from "lucide-react";
|
import { PackageSearch, UserSearch } from 'lucide-react';
|
||||||
import { useState } from "react";
|
import { useState } from 'react';
|
||||||
import FormBox from "../components/FormBox";
|
import FormBox from '../components/FormBox';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import FormField from "../components/FormField";
|
import FormField from '../components/FormField';
|
||||||
import FormInput from "../components/FormInput";
|
import FormInput from '../components/FormInput';
|
||||||
import FormSelect from "../components/FormSelect";
|
import FormSelect from '../components/FormSelect';
|
||||||
import Button from "../components/Button";
|
import Button from '../components/Button';
|
||||||
import productInfo from "../util/productList";
|
import productInfo from '../util/productList';
|
||||||
import Notification from "../components/Notification";
|
import Notification from '../components/Notification';
|
||||||
import ProductModal from "../components/ProductModal";
|
import ProductModal from '../components/ProductModal';
|
||||||
import FormHeader from "../components/FormHeader";
|
import FormHeader from '../components/FormHeader';
|
||||||
import FieldsWrapper from "../components/FieldsWrapper";
|
import FieldsWrapper from '../components/FieldsWrapper';
|
||||||
|
|
||||||
function AccountCreation() {
|
function AccountCreation() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [notification] = useState({ message: "", type: "" });
|
const [notification] = useState({ message: '', type: '' });
|
||||||
const [showProductModal, setShowProductModal] = useState(false);
|
const [showProductModal, setShowProductModal] = useState(false);
|
||||||
const [accountDetails, setAccountDetails] = useState({
|
const [accountDetails, setAccountDetails] = useState({
|
||||||
productCode: "",
|
productCode: '',
|
||||||
interestCategory: "",
|
interestCategory: '',
|
||||||
segmentCode: "",
|
segmentCode: '',
|
||||||
accountHolderType: "",
|
accountHolderType: '',
|
||||||
primaryCifNumber: "",
|
primaryCifNumber: '',
|
||||||
nomineeCifNumber: "",
|
nomineeCifNumber: '',
|
||||||
activityCode: "",
|
activityCode: '',
|
||||||
customerType: "",
|
customerType: '',
|
||||||
collateralFDAccount: "",
|
collateralFDAccount: '',
|
||||||
rentPayAccount: "",
|
rentPayAccount: '',
|
||||||
productCodeValid: true,
|
productCodeValid: true,
|
||||||
interestCategoryValid: true,
|
interestCategoryValid: true,
|
||||||
segmentCodeValid: true,
|
segmentCodeValid: true,
|
||||||
@@ -52,107 +52,107 @@ function AccountCreation() {
|
|||||||
|
|
||||||
const accountDetailsFields = [
|
const accountDetailsFields = [
|
||||||
{
|
{
|
||||||
label: t("productCode"),
|
label: t('productCode'),
|
||||||
name: "productCode",
|
name: 'productCode',
|
||||||
type: "input",
|
type: 'input',
|
||||||
subType: "number",
|
subType: 'number',
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
validate: (value) => value !== "",
|
validate: (value) => value !== '',
|
||||||
icon: {
|
icon: {
|
||||||
icon: <PackageSearch size={18} />,
|
icon: <PackageSearch size={18} />,
|
||||||
onClick: () => setShowProductModal(true),
|
onClick: () => setShowProductModal(true),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t("interestCategory"),
|
label: t('interestCategory'),
|
||||||
name: "interestCategory",
|
name: 'interestCategory',
|
||||||
type: "input",
|
type: 'input',
|
||||||
subType: "number",
|
subType: 'number',
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
validate: (value) => value !== "",
|
validate: (value) => value !== '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t("segmentCode"),
|
label: t('segmentCode'),
|
||||||
name: "segmentCode",
|
name: 'segmentCode',
|
||||||
type: "select",
|
type: 'select',
|
||||||
options: [
|
options: [
|
||||||
{ value: "0706", label: "0706: Individual" },
|
{ value: '0706', label: '0706: Individual' },
|
||||||
{ value: "0306", label: "0306: Staff" },
|
{ value: '0306', label: '0306: Staff' },
|
||||||
{ value: "5003", label: "5003: Senior Citizen" },
|
{ value: '5003', label: '5003: Senior Citizen' },
|
||||||
{ value: "5010", label: "5010: SHG" },
|
{ value: '5010', label: '5010: SHG' },
|
||||||
{ value: "5000", label: "5000: Bank" },
|
{ value: '5000', label: '5000: Bank' },
|
||||||
{ value: "5009", label: "5009: Institutions" },
|
{ value: '5009', label: '5009: Institutions' },
|
||||||
{ value: "5050", label: "5050: Others" },
|
{ value: '5050', label: '5050: Others' },
|
||||||
{ value: "5007", label: "5007: Society" },
|
{ value: '5007', label: '5007: Society' },
|
||||||
],
|
],
|
||||||
validate: (value) => value !== "",
|
validate: (value) => value !== '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t("accountHolderType"),
|
label: t('accountHolderType'),
|
||||||
name: "accountHolderType",
|
name: 'accountHolderType',
|
||||||
type: "select",
|
type: 'select',
|
||||||
options: [
|
options: [
|
||||||
{ value: "1", label: "Single" },
|
{ value: '1', label: 'Single' },
|
||||||
{ value: "2", label: "Joint" },
|
{ value: '2', label: 'Joint' },
|
||||||
],
|
],
|
||||||
validate: (value) => value === "1" || value === "2",
|
validate: (value) => value === '1' || value === '2',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t("primaryCifNumber"),
|
label: t('primaryCifNumber'),
|
||||||
name: "primaryCifNumber",
|
name: 'primaryCifNumber',
|
||||||
type: "input",
|
type: 'input',
|
||||||
subType: "number",
|
subType: 'number',
|
||||||
maxLength: 17,
|
maxLength: 17,
|
||||||
validate: (value) => /^[0-9]{17}$/.test(value),
|
validate: (value) => /^[0-9]{17}$/.test(value),
|
||||||
icon: { icon: <UserSearch size={18} /> },
|
icon: { icon: <UserSearch size={18} /> },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t("nomineeCifNumber"),
|
label: t('nomineeCifNumber'),
|
||||||
name: "nomineeCifNumber",
|
name: 'nomineeCifNumber',
|
||||||
type: "input",
|
type: 'input',
|
||||||
subType: "number",
|
subType: 'number',
|
||||||
maxLength: 17,
|
maxLength: 17,
|
||||||
validate: (value) => /^[0-9]{17}$/.test(value),
|
validate: (value) => /^[0-9]{17}$/.test(value),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const additionalDetailsFields = [
|
const additionalDetailsFields = [
|
||||||
{
|
{
|
||||||
label: t("activityCode"),
|
label: t('activityCode'),
|
||||||
name: "activityCode",
|
name: 'activityCode',
|
||||||
type: "select",
|
type: 'select',
|
||||||
options: [
|
options: [
|
||||||
{ value: "0701", label: "Direct Agriculture" },
|
{ value: '0701', label: 'Direct Agriculture' },
|
||||||
{ value: "0702", label: "Indirect Agriculture" },
|
{ value: '0702', label: 'Indirect Agriculture' },
|
||||||
{ value: "0703", label: "Agricultural Services Unit" },
|
{ value: '0703', label: 'Agricultural Services Unit' },
|
||||||
{ value: "0704", label: "Farm Irrigation" },
|
{ value: '0704', label: 'Farm Irrigation' },
|
||||||
{ value: "0705", label: "Fruits & Vegetables" },
|
{ value: '0705', label: 'Fruits & Vegetables' },
|
||||||
{ value: "0706", label: "Non-Agriculture" },
|
{ value: '0706', label: 'Non-Agriculture' },
|
||||||
],
|
],
|
||||||
validate: (value) => value !== "",
|
validate: (value) => value !== '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t("customerType"),
|
label: t('customerType'),
|
||||||
name: "customerType",
|
name: 'customerType',
|
||||||
type: "select",
|
type: 'select',
|
||||||
options: [
|
options: [
|
||||||
{ value: "0709", label: "Individual" },
|
{ value: '0709', label: 'Individual' },
|
||||||
{ value: "0701", label: "Corporate" },
|
{ value: '0701', label: 'Corporate' },
|
||||||
],
|
],
|
||||||
validate: (value) => value === "0709" || value === "0701",
|
validate: (value) => value === '0709' || value === '0701',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t("collateralFDAccount"),
|
label: t('collateralFDAccount'),
|
||||||
name: "collateralFDAccount",
|
name: 'collateralFDAccount',
|
||||||
type: "input",
|
type: 'input',
|
||||||
subType: "number",
|
subType: 'number',
|
||||||
maxLength: 17,
|
maxLength: 17,
|
||||||
validate: (value) => /^[0-9]{17}$/.test(value),
|
validate: (value) => /^[0-9]{17}$/.test(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t("rentPayAccount"),
|
label: t('rentPayAccount'),
|
||||||
name: "rentPayAccount",
|
name: 'rentPayAccount',
|
||||||
type: "input",
|
type: 'input',
|
||||||
subType: "number",
|
subType: 'number',
|
||||||
maxLength: 17,
|
maxLength: 17,
|
||||||
validate: (value) => /^[0-9]{17}$/.test(value),
|
validate: (value) => /^[0-9]{17}$/.test(value),
|
||||||
},
|
},
|
||||||
@@ -177,7 +177,7 @@ function AccountCreation() {
|
|||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("Form is valid", accountDetails);
|
console.log('Form is valid', accountDetails);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderField = (field) => {
|
const renderField = (field) => {
|
||||||
@@ -197,14 +197,10 @@ function AccountCreation() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<FormField key={field.name} label={field.label} icon={field.icon}>
|
<FormField key={field.name} label={field.label} icon={field.icon}>
|
||||||
{field.type === "input" ? (
|
{field.type === 'input' ? (
|
||||||
<FormInput props={commonProps} valid={valid} />
|
<FormInput props={commonProps} valid={valid} />
|
||||||
) : (
|
) : (
|
||||||
<FormSelect
|
<FormSelect props={commonProps} valid={valid} options={field.options} />
|
||||||
props={commonProps}
|
|
||||||
valid={valid}
|
|
||||||
options={field.options}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</FormField>
|
</FormField>
|
||||||
);
|
);
|
||||||
@@ -213,26 +209,23 @@ function AccountCreation() {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{notification.message !== "" && <Notification {...notification} />}
|
{notification.message !== '' && <Notification {...notification} />}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
|
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{showProductModal && (
|
{showProductModal && (
|
||||||
<ProductModal
|
<ProductModal productInfo={productInfo} handleProductSelect={handleProductSelect} />
|
||||||
productInfo={productInfo}
|
|
||||||
handleProductSelect={handleProductSelect}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
|
|
||||||
<FormBox title="Account Creation">
|
<FormBox title="Account Creation">
|
||||||
<FieldsWrapper>
|
<FieldsWrapper>
|
||||||
<FormHeader text={"Account Details"} />
|
<FormHeader text={'Account Details'} />
|
||||||
{accountDetailsFields.map(renderField)}
|
{accountDetailsFields.map(renderField)}
|
||||||
<FormHeader text={"Additional Details"} />
|
<FormHeader text={'Additional Details'} />
|
||||||
{additionalDetailsFields.map(renderField)}
|
{additionalDetailsFields.map(renderField)}
|
||||||
</FieldsWrapper>
|
</FieldsWrapper>
|
||||||
<Button text={t("submit")} onClick={handleSubmit} />
|
<Button text={t('submit')} onClick={handleSubmit} />
|
||||||
</FormBox>
|
</FormBox>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { useState } from "react";
|
import { useState } from 'react';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import FormBox from "../components/FormBox";
|
import FormBox from '../components/FormBox';
|
||||||
import Button from "../components/Button";
|
import Button from '../components/Button';
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from 'react-router-dom';
|
||||||
import FieldsWrapper from "../components/FieldsWrapper";
|
import FieldsWrapper from '../components/FieldsWrapper';
|
||||||
import FormField from "../components/FormField";
|
import FormField from '../components/FormField';
|
||||||
import FormInput from "../components/FormInput";
|
import FormInput from '../components/FormInput';
|
||||||
import FormSelect from "../components/FormSelect";
|
import FormSelect from '../components/FormSelect';
|
||||||
|
|
||||||
function CabinetCreation() {
|
function CabinetCreation() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [cabinetDetails, setCabinetDetails] = useState({
|
const [cabinetDetails, setCabinetDetails] = useState({
|
||||||
cabinetId: "",
|
cabinetId: '',
|
||||||
cabinetIdValid: true,
|
cabinetIdValid: true,
|
||||||
cabinetKeyId: "",
|
cabinetKeyId: '',
|
||||||
cabinetKeyIdValid: true,
|
cabinetKeyIdValid: true,
|
||||||
noOfLockers: 0,
|
noOfLockers: 0,
|
||||||
noOfLockersValid: true,
|
noOfLockersValid: true,
|
||||||
@@ -24,21 +24,21 @@ function CabinetCreation() {
|
|||||||
const handleNext = (e) => {
|
const handleNext = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let isFormValid = true;
|
let isFormValid = true;
|
||||||
const newValues = {...cabinetDetails};
|
const newValues = { ...cabinetDetails };
|
||||||
formFields.forEach(field => {
|
formFields.forEach((field) => {
|
||||||
if(field.validate) {
|
if (field.validate) {
|
||||||
const isFieldValid = field.validate(cabinetDetails[field.name])
|
const isFieldValid = field.validate(cabinetDetails[field.name]);
|
||||||
newValues[`${field.name}Valid`] = isFieldValid;
|
newValues[`${field.name}Valid`] = isFieldValid;
|
||||||
if(!isFieldValid) isFormValid = false;
|
if (!isFieldValid) isFormValid = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(!isFormValid) {
|
if (!isFormValid) {
|
||||||
setCabinetDetails(newValues);
|
setCabinetDetails(newValues);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
navigate("register-lockers", {
|
navigate('register-lockers', {
|
||||||
state: {
|
state: {
|
||||||
cabinetId: cabinetDetails.cabinetId,
|
cabinetId: cabinetDetails.cabinetId,
|
||||||
cabinetKeyId: cabinetDetails.cabinetKeyId,
|
cabinetKeyId: cabinetDetails.cabinetKeyId,
|
||||||
@@ -49,25 +49,25 @@ function CabinetCreation() {
|
|||||||
|
|
||||||
const formFields = [
|
const formFields = [
|
||||||
{
|
{
|
||||||
name: "cabinetId",
|
name: 'cabinetId',
|
||||||
label: t("cabinetId"),
|
label: t('cabinetId'),
|
||||||
type: "input",
|
type: 'input',
|
||||||
maxLength: 6,
|
maxLength: 6,
|
||||||
validate: v => /^\w{2}\d{4}$/.test(v)
|
validate: (v) => /^\w{2}\d{4}$/.test(v),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "cabinetKeyId",
|
name: 'cabinetKeyId',
|
||||||
label: t("cabinetKeyId"),
|
label: t('cabinetKeyId'),
|
||||||
type: "input",
|
type: 'input',
|
||||||
maxLength: 6,
|
maxLength: 6,
|
||||||
validate: v => /^\w{2}\d{4}$/.test(v)
|
validate: (v) => /^\w{2}\d{4}$/.test(v),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "noOfLockers",
|
name: 'noOfLockers',
|
||||||
label: t("noOfLockers"),
|
label: t('noOfLockers'),
|
||||||
type: "input",
|
type: 'input',
|
||||||
subType: "number",
|
subType: 'number',
|
||||||
validate: v => parseInt(v) > 0
|
validate: (v) => parseInt(v) > 0,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -87,24 +87,18 @@ function CabinetCreation() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<FormField key={field.name} label={field.label}>
|
<FormField key={field.name} label={field.label}>
|
||||||
{field.type === "input" ? (
|
{field.type === 'input' ? (
|
||||||
<FormInput props={commonProps} valid={valid} />
|
<FormInput props={commonProps} valid={valid} />
|
||||||
) : (
|
) : (
|
||||||
<FormSelect
|
<FormSelect props={commonProps} valid={valid} options={field.options} />
|
||||||
props={commonProps}
|
|
||||||
valid={valid}
|
|
||||||
options={field.options}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</FormField>
|
</FormField>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormBox title={t("cabinetCreation")}>
|
<FormBox title={t('cabinetCreation')}>
|
||||||
<FieldsWrapper>
|
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
||||||
{formFields.map(renderField)}
|
|
||||||
</FieldsWrapper>
|
|
||||||
<Button text={t('next')} onClick={handleNext} />
|
<Button text={t('next')} onClick={handleNext} />
|
||||||
</FormBox>
|
</FormBox>
|
||||||
);
|
);
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { useState } from "react";
|
import { useState } from 'react';
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import FormBox from "../components/FormBox";
|
import FormBox from '../components/FormBox';
|
||||||
import Button from "../components/Button";
|
import Button from '../components/Button';
|
||||||
import FormInput from "../components/FormInput";
|
import FormInput from '../components/FormInput';
|
||||||
import FormSelect from "../components/FormSelect";
|
import FormSelect from '../components/FormSelect';
|
||||||
import FieldsWrapper from "../components/FieldsWrapper";
|
import FieldsWrapper from '../components/FieldsWrapper';
|
||||||
import FormField from "../components/FormField";
|
import FormField from '../components/FormField';
|
||||||
|
|
||||||
function CabinetMaintenace() {
|
function CabinetMaintenace() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [operation, setOperation] = useState({ value: "", valid: true });
|
const [operation, setOperation] = useState({ value: '', valid: true });
|
||||||
|
|
||||||
const handleNext = (e) => {
|
const handleNext = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (operation.value === "") {
|
if (operation.value === '') {
|
||||||
setOperation({ value: operation.value, valid: false });
|
setOperation({ value: operation.value, valid: false });
|
||||||
}
|
}
|
||||||
navigate(operation.value);
|
navigate(operation.value);
|
||||||
@@ -23,10 +23,10 @@ function CabinetMaintenace() {
|
|||||||
|
|
||||||
const formFields = [
|
const formFields = [
|
||||||
{
|
{
|
||||||
name: "value",
|
name: 'value',
|
||||||
label: t("operation"),
|
label: t('operation'),
|
||||||
options: [{ label: t("create"), value: "create" }],
|
options: [{ label: t('create'), value: 'create' }],
|
||||||
type: "select",
|
type: 'select',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ function CabinetMaintenace() {
|
|||||||
const options = field.options;
|
const options = field.options;
|
||||||
return (
|
return (
|
||||||
<FormField label={field.label}>
|
<FormField label={field.label}>
|
||||||
{field.type === "input" ? (
|
{field.type === 'input' ? (
|
||||||
<FormInput props={commonProps} />
|
<FormInput props={commonProps} />
|
||||||
) : (
|
) : (
|
||||||
<FormSelect props={commonProps} options={options} />
|
<FormSelect props={commonProps} options={options} />
|
||||||
@@ -54,9 +54,9 @@ function CabinetMaintenace() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<FormBox title={t("cabinetMaintenance")}>
|
<FormBox title={t('cabinetMaintenance')}>
|
||||||
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
||||||
<Button text={t("next")} onClick={(e) => handleNext(e)} />
|
<Button text={t('next')} onClick={(e) => handleNext(e)} />
|
||||||
</FormBox>
|
</FormBox>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -1,27 +1,27 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from 'react';
|
||||||
import { useLoading } from "../hooks/useLoading";
|
import { useLoading } from '../hooks/useLoading';
|
||||||
import FormField from "../components/FormField";
|
import FormField from '../components/FormField';
|
||||||
import FormInput from "../components/FormInput";
|
import FormInput from '../components/FormInput';
|
||||||
import FormSelect from "../components/FormSelect";
|
import FormSelect from '../components/FormSelect';
|
||||||
import Button from "../components/Button";
|
import Button from '../components/Button';
|
||||||
import FormBox from "../components/FormBox";
|
import FormBox from '../components/FormBox';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from 'react-router-dom';
|
||||||
import { lockerService } from "../services/locker.service";
|
import { lockerService } from '../services/locker.service';
|
||||||
import { AnimatePresence } from "motion/react";
|
import { AnimatePresence } from 'motion/react';
|
||||||
import { Pencil } from "lucide-react";
|
import { Pencil } from 'lucide-react';
|
||||||
import Notification from "../components/Notification";
|
import Notification from '../components/Notification';
|
||||||
import FieldsWrapper from "../components/FieldsWrapper";
|
import FieldsWrapper from '../components/FieldsWrapper';
|
||||||
|
|
||||||
function ChargeEdit() {
|
function ChargeEdit() {
|
||||||
const [chargeDetails, setChargeDetails] = useState({
|
const [chargeDetails, setChargeDetails] = useState({
|
||||||
rentAmount: "",
|
rentAmount: '',
|
||||||
rentAmountEdit: false,
|
rentAmountEdit: false,
|
||||||
penaltyAmount: "",
|
penaltyAmount: '',
|
||||||
penaltyAmountEdit: false,
|
penaltyAmountEdit: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const [notification, setNotification] = useState({ message: "", type: "" });
|
const [notification, setNotification] = useState({ message: '', type: '' });
|
||||||
|
|
||||||
const { setIsLoading } = useLoading();
|
const { setIsLoading } = useLoading();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -33,10 +33,7 @@ function ChargeEdit() {
|
|||||||
const fetchCharges = async () => {
|
const fetchCharges = async () => {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const response = await lockerService.getCharges(
|
const response = await lockerService.getCharges(productCode, interestCategory);
|
||||||
productCode,
|
|
||||||
interestCategory
|
|
||||||
);
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
const { rent, penalty } = response.data;
|
const { rent, penalty } = response.data;
|
||||||
setChargeDetails({
|
setChargeDetails({
|
||||||
@@ -48,14 +45,14 @@ function ChargeEdit() {
|
|||||||
} else {
|
} else {
|
||||||
setNotification({
|
setNotification({
|
||||||
message: response.data.message,
|
message: response.data.message,
|
||||||
type: "error",
|
type: 'error',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
setNotification({
|
setNotification({
|
||||||
message: error.message,
|
message: error.message,
|
||||||
type: "error",
|
type: 'error',
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -70,28 +67,28 @@ function ChargeEdit() {
|
|||||||
|
|
||||||
const formFields = [
|
const formFields = [
|
||||||
{
|
{
|
||||||
name: "rentAmount",
|
name: 'rentAmount',
|
||||||
label: "Rent Amount",
|
label: 'Rent Amount',
|
||||||
type: "input",
|
type: 'input',
|
||||||
subType: "number",
|
subType: 'number',
|
||||||
readOnly: !chargeDetails.rentAmountEdit,
|
readOnly: !chargeDetails.rentAmountEdit,
|
||||||
icon: {
|
icon: {
|
||||||
icon: <Pencil size={22} />,
|
icon: <Pencil size={22} />,
|
||||||
mode: "plain",
|
mode: 'plain',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
setChargeDetails({ ...chargeDetails, rentAmountEdit: true });
|
setChargeDetails({ ...chargeDetails, rentAmountEdit: true });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "penaltyAmount",
|
name: 'penaltyAmount',
|
||||||
label: "Penalty Amount",
|
label: 'Penalty Amount',
|
||||||
type: "input",
|
type: 'input',
|
||||||
subType: "number",
|
subType: 'number',
|
||||||
readOnly: !chargeDetails.penaltyAmountEdit,
|
readOnly: !chargeDetails.penaltyAmountEdit,
|
||||||
icon: {
|
icon: {
|
||||||
icon: <Pencil size={22} />,
|
icon: <Pencil size={22} />,
|
||||||
mode: "plain",
|
mode: 'plain',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
setChargeDetails({ ...chargeDetails, penaltyAmountEdit: true });
|
setChargeDetails({ ...chargeDetails, penaltyAmountEdit: true });
|
||||||
},
|
},
|
||||||
@@ -113,19 +110,19 @@ function ChargeEdit() {
|
|||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
setNotification({
|
setNotification({
|
||||||
message: response.data.message,
|
message: response.data.message,
|
||||||
type: "success",
|
type: 'success',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setNotification({
|
setNotification({
|
||||||
message: response.data.message,
|
message: response.data.message,
|
||||||
type: "error",
|
type: 'error',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
setNotification({
|
setNotification({
|
||||||
message: error.message,
|
message: error.message,
|
||||||
type: "error",
|
type: 'error',
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -145,17 +142,13 @@ function ChargeEdit() {
|
|||||||
|
|
||||||
type: field.subType,
|
type: field.subType,
|
||||||
};
|
};
|
||||||
const className = field.readOnly ? "bg-grey/[0.3]" : "";
|
const className = field.readOnly ? 'bg-grey/[0.3]' : '';
|
||||||
return (
|
return (
|
||||||
<FormField key={field.name} label={field.label} icon={field.icon}>
|
<FormField key={field.name} label={field.label} icon={field.icon}>
|
||||||
{field.type === "input" ? (
|
{field.type === 'input' ? (
|
||||||
<FormInput props={commonProps} className={className} />
|
<FormInput props={commonProps} className={className} />
|
||||||
) : (
|
) : (
|
||||||
<FormSelect
|
<FormSelect props={commonProps} options={field.options} className={className} />
|
||||||
props={commonProps}
|
|
||||||
options={field.options}
|
|
||||||
className={className}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</FormField>
|
</FormField>
|
||||||
);
|
);
|
||||||
@@ -164,17 +157,15 @@ function ChargeEdit() {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{notification.message !== "" && <Notification {...notification} />}
|
{notification.message !== '' && <Notification {...notification} />}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
|
|
||||||
<FormBox title={t("chargeEdit")}>
|
<FormBox title={t('chargeEdit')}>
|
||||||
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
||||||
<Button
|
<Button
|
||||||
text={t("submit")}
|
text={t('submit')}
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
disabled={
|
disabled={!chargeDetails.rentAmountEdit && !chargeDetails.penaltyAmountEdit}
|
||||||
!chargeDetails.rentAmountEdit && !chargeDetails.penaltyAmountEdit
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</FormBox>
|
</FormBox>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import FormField from "../components/FormField";
|
import FormField from '../components/FormField';
|
||||||
import FormInput from "../components/FormInput";
|
import FormInput from '../components/FormInput';
|
||||||
import FormSelect from "../components/FormSelect";
|
import FormSelect from '../components/FormSelect';
|
||||||
import Button from "../components/Button";
|
import Button from '../components/Button';
|
||||||
import FormBox from "../components/FormBox";
|
import FormBox from '../components/FormBox';
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useState } from "react";
|
import { useState } from 'react';
|
||||||
import { useToast } from "../hooks/useToast";
|
import { useToast } from '../hooks/useToast';
|
||||||
import FieldsWrapper from "../components/FieldsWrapper";
|
import FieldsWrapper from '../components/FieldsWrapper';
|
||||||
|
|
||||||
function ChargeManagement() {
|
function ChargeManagement() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -15,26 +15,26 @@ function ChargeManagement() {
|
|||||||
const showToast = useToast();
|
const showToast = useToast();
|
||||||
|
|
||||||
const [productDetails, setProductDetails] = useState({
|
const [productDetails, setProductDetails] = useState({
|
||||||
productCode: "",
|
productCode: '',
|
||||||
interestCategory: "",
|
interestCategory: '',
|
||||||
productCodeValid: true,
|
productCodeValid: true,
|
||||||
interestCategoryValid: true,
|
interestCategoryValid: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const formFields = [
|
const formFields = [
|
||||||
{
|
{
|
||||||
name: "productCode",
|
name: 'productCode',
|
||||||
label: t("productCode"),
|
label: t('productCode'),
|
||||||
type: "input",
|
type: 'input',
|
||||||
subType: "number",
|
subType: 'number',
|
||||||
maxLength: 4,
|
maxLength: 4,
|
||||||
validate: (value) => /^[0-9]{4}/.test(value),
|
validate: (value) => /^[0-9]{4}/.test(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "interestCategory",
|
name: 'interestCategory',
|
||||||
label: t("interestCategory"),
|
label: t('interestCategory'),
|
||||||
type: "input",
|
type: 'input',
|
||||||
subType: "number",
|
subType: 'number',
|
||||||
maxLength: 4,
|
maxLength: 4,
|
||||||
validate: (value) => /^[0-9]{4}/.test(value),
|
validate: (value) => /^[0-9]{4}/.test(value),
|
||||||
},
|
},
|
||||||
@@ -54,11 +54,11 @@ function ChargeManagement() {
|
|||||||
|
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
setProductDetails(newProductDetails);
|
setProductDetails(newProductDetails);
|
||||||
showToast(t("highlightedFieldsInvalid"), "error");
|
showToast(t('highlightedFieldsInvalid'), 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
navigate("change", {
|
navigate('change', {
|
||||||
state: {
|
state: {
|
||||||
productCode: productDetails.productCode,
|
productCode: productDetails.productCode,
|
||||||
interestCategory: productDetails.interestCategory,
|
interestCategory: productDetails.interestCategory,
|
||||||
@@ -71,8 +71,8 @@ function ChargeManagement() {
|
|||||||
value: productDetails[field.name],
|
value: productDetails[field.name],
|
||||||
onChange: (e) => {
|
onChange: (e) => {
|
||||||
const newLockerDetails = { ...productDetails };
|
const newLockerDetails = { ...productDetails };
|
||||||
if (field.subType === "number") {
|
if (field.subType === 'number') {
|
||||||
e.target.value = e.target.value.replace(/\D/g, "");
|
e.target.value = e.target.value.replace(/\D/g, '');
|
||||||
if (e.target.value.length > field.maxLength) {
|
if (e.target.value.length > field.maxLength) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -89,11 +89,8 @@ function ChargeManagement() {
|
|||||||
const valid = productDetails[`${field.name}Valid`];
|
const valid = productDetails[`${field.name}Valid`];
|
||||||
return (
|
return (
|
||||||
<FormField key={field.name} label={field.label} icon={field.icon}>
|
<FormField key={field.name} label={field.label} icon={field.icon}>
|
||||||
{field.type === "input" ? (
|
{field.type === 'input' ? (
|
||||||
<FormInput
|
<FormInput props={commonProps} valid={valid} />
|
||||||
props={commonProps}
|
|
||||||
valid={valid}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<FormSelect props={commonProps} valid={valid} options={field.options} />
|
<FormSelect props={commonProps} valid={valid} options={field.options} />
|
||||||
)}
|
)}
|
||||||
@@ -102,11 +99,9 @@ function ChargeManagement() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormBox title={t("chargeManagement")}>
|
<FormBox title={t('chargeManagement')}>
|
||||||
<FieldsWrapper>
|
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
||||||
{formFields.map(renderField)}
|
<Button text={t('submit')} onClick={handleSubmit} />
|
||||||
</FieldsWrapper>
|
|
||||||
<Button text={t("submit")} onClick={handleSubmit} />
|
|
||||||
</FormBox>
|
</FormBox>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -1,16 +1,16 @@
|
|||||||
import { useState } from "react";
|
import { useState } from 'react';
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from 'react-router-dom';
|
||||||
import FormBox from "../components/FormBox";
|
import FormBox from '../components/FormBox';
|
||||||
import Button from "../components/Button";
|
import Button from '../components/Button';
|
||||||
import Notification from "../components/Notification";
|
import Notification from '../components/Notification';
|
||||||
import { lockerService } from "../services/locker.service";
|
import { lockerService } from '../services/locker.service';
|
||||||
import { useToast } from "../hooks/useToast";
|
import { useToast } from '../hooks/useToast';
|
||||||
import { useLoading } from "../hooks/useLoading";
|
import { useLoading } from '../hooks/useLoading';
|
||||||
|
|
||||||
function CheckInOutLog() {
|
function CheckInOutLog() {
|
||||||
const [time, setTime] = useState(null);
|
const [time, setTime] = useState(null);
|
||||||
const [checkType, setCheckType] = useState("");
|
const [checkType, setCheckType] = useState('');
|
||||||
const [notification, setNotification] = useState({ message: "", type: "" });
|
const [notification, setNotification] = useState({ message: '', type: '' });
|
||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const showToast = useToast();
|
const showToast = useToast();
|
||||||
@@ -19,27 +19,23 @@ function CheckInOutLog() {
|
|||||||
|
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (time === null || checkType === "") {
|
if (time === null || checkType === '') {
|
||||||
showToast("Please fill in all fields", "error");
|
showToast('Please fill in all fields', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Add your logic here
|
// Add your logic here
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const response = await lockerService.checkInOut(
|
const response = await lockerService.checkInOut(accountNumber, time, checkType);
|
||||||
accountNumber,
|
|
||||||
time,
|
|
||||||
checkType
|
|
||||||
);
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
setNotification({ message: response.data.message, type: "success" });
|
setNotification({ message: response.data.message, type: 'success' });
|
||||||
} else {
|
} else {
|
||||||
console.log(response);
|
console.log(response);
|
||||||
setNotification({ message: response.data.message, type: "error" });
|
setNotification({ message: response.data.message, type: 'error' });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
setNotification({ message: error.message, type: "error" });
|
setNotification({ message: error.message, type: 'error' });
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
@@ -47,16 +43,14 @@ function CheckInOutLog() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{notification.message !== "" && <Notification {...notification} />}
|
{notification.message !== '' && <Notification {...notification} />}
|
||||||
<FormBox title="Check In/Out Log">
|
<FormBox title="Check In/Out Log">
|
||||||
<div className="px-4 pt-7 text-2xl font-display font-bold text-primary dark:text-primary-dark">
|
<div className="px-4 pt-7 text-2xl font-display font-bold text-primary dark:text-primary-dark">
|
||||||
{accountNumber}
|
{accountNumber}
|
||||||
</div>
|
</div>
|
||||||
<div className="p-2 pt-7 flex flex-col gap-4">
|
<div className="p-2 pt-7 flex flex-col gap-4">
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<label className="mr-4 text-lg text-black dark:text-primary-dark w-[10%]">
|
<label className="mr-4 text-lg text-black dark:text-primary-dark w-[10%]">Time</label>
|
||||||
Time
|
|
||||||
</label>
|
|
||||||
<input
|
<input
|
||||||
type="time"
|
type="time"
|
||||||
className="w-1/5 h-10 px-2 rounded-full dark:bg-grey dark:text-primary-dark border-2 focus:outline-grey border-grey text-black"
|
className="w-1/5 h-10 px-2 rounded-full dark:bg-grey dark:text-primary-dark border-2 focus:outline-grey border-grey text-black"
|
||||||
|
@@ -1,20 +1,20 @@
|
|||||||
import FormBox from "../components/FormBox";
|
import FormBox from '../components/FormBox';
|
||||||
import { useState } from "react";
|
import { useState } from 'react';
|
||||||
import FormField from "../components/FormField";
|
import FormField from '../components/FormField';
|
||||||
import FormInput from "../components/FormInput";
|
import FormInput from '../components/FormInput';
|
||||||
import { Search } from "lucide-react";
|
import { Search } from 'lucide-react';
|
||||||
import Button from "../components/Button";
|
import Button from '../components/Button';
|
||||||
import { AnimatePresence } from "motion/react";
|
import { AnimatePresence } from 'motion/react';
|
||||||
import Notification from "../components/Notification";
|
import Notification from '../components/Notification';
|
||||||
import { useToast } from "../hooks/useToast";
|
import { useToast } from '../hooks/useToast';
|
||||||
import { lockerService } from "../services/locker.service";
|
import { lockerService } from '../services/locker.service';
|
||||||
import { useLoading } from "../hooks/useLoading";
|
import { useLoading } from '../hooks/useLoading';
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from 'react-router-dom';
|
||||||
import FieldsWrapper from "../components/FieldsWrapper";
|
import FieldsWrapper from '../components/FieldsWrapper';
|
||||||
|
|
||||||
function CheckInOutManagement() {
|
function CheckInOutManagement() {
|
||||||
const [accountNumber, setAccountNumber] = useState("");
|
const [accountNumber, setAccountNumber] = useState('');
|
||||||
const [notification, setNotification] = useState({ message: "", type: "" });
|
const [notification, setNotification] = useState({ message: '', type: '' });
|
||||||
|
|
||||||
const showToast = useToast();
|
const showToast = useToast();
|
||||||
const { setIsLoading } = useLoading();
|
const { setIsLoading } = useLoading();
|
||||||
@@ -22,8 +22,8 @@ function CheckInOutManagement() {
|
|||||||
|
|
||||||
const handleNext = async (e) => {
|
const handleNext = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (accountNumber === "") {
|
if (accountNumber === '') {
|
||||||
showToast("Account Number is required", "error");
|
showToast('Account Number is required', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -33,26 +33,26 @@ function CheckInOutManagement() {
|
|||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
const data = response.data;
|
const data = response.data;
|
||||||
if (data.code === 1) {
|
if (data.code === 1) {
|
||||||
navigate("log", { state: { accountNumber } });
|
navigate('log', { state: { accountNumber } });
|
||||||
} else if (data.code === 2) {
|
} else if (data.code === 2) {
|
||||||
setNotification({
|
setNotification({
|
||||||
visible: true,
|
visible: true,
|
||||||
message:
|
message:
|
||||||
"Monthly access limit exceeded. A fine will be charged for each additional access.",
|
'Monthly access limit exceeded. A fine will be charged for each additional access.',
|
||||||
type: "warning",
|
type: 'warning',
|
||||||
});
|
});
|
||||||
} else if (data.code === 3) {
|
} else if (data.code === 3) {
|
||||||
setNotification({
|
setNotification({
|
||||||
visible: true,
|
visible: true,
|
||||||
message:
|
message:
|
||||||
"Rent for this account is due. Please pay the rent amount in full to access the locker.",
|
'Rent for this account is due. Please pay the rent amount in full to access the locker.',
|
||||||
type: "error",
|
type: 'error',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
setNotification(error.message, "error");
|
setNotification(error.message, 'error');
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ function CheckInOutManagement() {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{ notification.message !== "" && <Notification {...notification} /> }
|
{notification.message !== '' && <Notification {...notification} />}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
<FormBox title="Check In/Out">
|
<FormBox title="Check In/Out">
|
||||||
<FieldsWrapper>
|
<FieldsWrapper>
|
||||||
@@ -70,7 +70,7 @@ function CheckInOutManagement() {
|
|||||||
>
|
>
|
||||||
<FormInput
|
<FormInput
|
||||||
props={{
|
props={{
|
||||||
type: "text",
|
type: 'text',
|
||||||
value: accountNumber,
|
value: accountNumber,
|
||||||
onChange: (e) => setAccountNumber(e.target.value),
|
onChange: (e) => setAccountNumber(e.target.value),
|
||||||
}}
|
}}
|
||||||
|
@@ -1,11 +1,20 @@
|
|||||||
import FormBox from "../components/FormBox";
|
import FormBox from '../components/FormBox';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import { getUserInfoFromSession } from "../util/util";
|
import { getUserInfoFromSession } from '../util/util';
|
||||||
|
|
||||||
function Home() {
|
function Home() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const holidayList = [{ date: '23 May, 2024', name: 'Buddha Purnima' }, { date: '15 June, 2024', name: 'Raja Sankranti' }];
|
const holidayList = [
|
||||||
const homePageNotifications = ['hpn_complete_before_31', 'hpn_npa', 'hpn_helpdesk_contact', 'hpn_rupay_kcc_time', 'hpn_rupay_kcc_atm'];
|
{ date: '23 May, 2024', name: 'Buddha Purnima' },
|
||||||
|
{ date: '15 June, 2024', name: 'Raja Sankranti' },
|
||||||
|
];
|
||||||
|
const homePageNotifications = [
|
||||||
|
'hpn_complete_before_31',
|
||||||
|
'hpn_npa',
|
||||||
|
'hpn_helpdesk_contact',
|
||||||
|
'hpn_rupay_kcc_time',
|
||||||
|
'hpn_rupay_kcc_atm',
|
||||||
|
];
|
||||||
const userInformation = getUserInfoFromSession();
|
const userInformation = getUserInfoFromSession();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -15,7 +24,12 @@ function Home() {
|
|||||||
<FormBox title={t('holidayList')} alt={true}>
|
<FormBox title={t('holidayList')} alt={true}>
|
||||||
<ul className="px-4 list-disc list-inside">
|
<ul className="px-4 list-disc list-inside">
|
||||||
{holidayList.map((holiday, index) => (
|
{holidayList.map((holiday, index) => (
|
||||||
<li key={index} className="py-2 font-body text-surface dark:text-surface-dark text-lg/loose">{t(holiday.date)} - {t(holiday.name)}</li>
|
<li
|
||||||
|
key={index}
|
||||||
|
className="py-2 font-body text-surface dark:text-surface-dark text-lg/loose"
|
||||||
|
>
|
||||||
|
{t(holiday.date)} - {t(holiday.name)}
|
||||||
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</FormBox>
|
</FormBox>
|
||||||
@@ -23,11 +37,14 @@ function Home() {
|
|||||||
<div className="flex-grow">
|
<div className="flex-grow">
|
||||||
<FormBox title={t('information')}>
|
<FormBox title={t('information')}>
|
||||||
<ul className="px-4 list-disc list-inside">
|
<ul className="px-4 list-disc list-inside">
|
||||||
{
|
{Object.keys(userInformation).map((key, index) => (
|
||||||
Object.keys(userInformation).map((key, index) => (
|
<li
|
||||||
<li key={index} className="py-2 font-body text-surface-dark dark:text-surface text-lg/loose">{t(key)}: {t(userInformation[key])}</li>
|
key={index}
|
||||||
))
|
className="py-2 font-body text-surface-dark dark:text-surface text-lg/loose"
|
||||||
}
|
>
|
||||||
|
{t(key)}: {t(userInformation[key])}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</FormBox>
|
</FormBox>
|
||||||
</div>
|
</div>
|
||||||
@@ -37,7 +54,12 @@ function Home() {
|
|||||||
<FormBox title={t('notifications')}>
|
<FormBox title={t('notifications')}>
|
||||||
<ul className="px-4 list-disc list-inside">
|
<ul className="px-4 list-disc list-inside">
|
||||||
{homePageNotifications.map((notification, index) => (
|
{homePageNotifications.map((notification, index) => (
|
||||||
<li key={index} className="py-2 font-body text-surface-dark dark:text-surface text-lg/relaxed">{t(notification)}</li>
|
<li
|
||||||
|
key={index}
|
||||||
|
className="py-2 font-body text-surface-dark dark:text-surface text-lg/relaxed"
|
||||||
|
>
|
||||||
|
{t(notification)}
|
||||||
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</FormBox>
|
</FormBox>
|
||||||
|
@@ -1,29 +1,29 @@
|
|||||||
import { useState } from "react";
|
import { useState } from 'react';
|
||||||
import { AnimatePresence } from "motion/react";
|
import { AnimatePresence } from 'motion/react';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useToast } from "../hooks/useToast";
|
import { useToast } from '../hooks/useToast';
|
||||||
import { useLoading } from "../hooks/useLoading";
|
import { useLoading } from '../hooks/useLoading';
|
||||||
import FormField from "../components/FormField";
|
import FormField from '../components/FormField';
|
||||||
import FormInput from "../components/FormInput";
|
import FormInput from '../components/FormInput';
|
||||||
import FormSelect from "../components/FormSelect";
|
import FormSelect from '../components/FormSelect';
|
||||||
import Button from "../components/Button";
|
import Button from '../components/Button';
|
||||||
import { lockerService } from "../services/locker.service";
|
import { lockerService } from '../services/locker.service';
|
||||||
import FormBox from "../components/FormBox";
|
import FormBox from '../components/FormBox';
|
||||||
import Notification from "../components/Notification";
|
import Notification from '../components/Notification';
|
||||||
import FieldsWrapper from "../components/FieldsWrapper";
|
import FieldsWrapper from '../components/FieldsWrapper';
|
||||||
|
|
||||||
function KeySwap() {
|
function KeySwap() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const showToast = useToast();
|
const showToast = useToast();
|
||||||
const { isLoading, setIsLoading } = useLoading();
|
const { isLoading, setIsLoading } = useLoading();
|
||||||
const [notification, setNotification] = useState({ message: "", type: "" });
|
const [notification, setNotification] = useState({ message: '', type: '' });
|
||||||
const [keySwapDetails, setKeySwapDetails] = useState({
|
const [keySwapDetails, setKeySwapDetails] = useState({
|
||||||
cabinetId: "",
|
cabinetId: '',
|
||||||
lockerId: "",
|
lockerId: '',
|
||||||
reason: "",
|
reason: '',
|
||||||
oldKey: "",
|
oldKey: '',
|
||||||
newKey: "",
|
newKey: '',
|
||||||
newKeyConfirm: "",
|
newKeyConfirm: '',
|
||||||
cabinetIdValid: true,
|
cabinetIdValid: true,
|
||||||
lockerIdValid: true,
|
lockerIdValid: true,
|
||||||
reasonValid: true,
|
reasonValid: true,
|
||||||
@@ -34,52 +34,52 @@ function KeySwap() {
|
|||||||
|
|
||||||
const formFields = [
|
const formFields = [
|
||||||
{
|
{
|
||||||
name: "cabinetId",
|
name: 'cabinetId',
|
||||||
label: t("cabinetId"),
|
label: t('cabinetId'),
|
||||||
type: "input",
|
type: 'input',
|
||||||
maxLength: 6,
|
maxLength: 6,
|
||||||
readOnly: isLoading,
|
readOnly: isLoading,
|
||||||
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "lockerId",
|
name: 'lockerId',
|
||||||
label: t("lockerId"),
|
label: t('lockerId'),
|
||||||
type: "input",
|
type: 'input',
|
||||||
maxLength: 6,
|
maxLength: 6,
|
||||||
readOnly: isLoading,
|
readOnly: isLoading,
|
||||||
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "reason",
|
name: 'reason',
|
||||||
label: t("reasonForChange"),
|
label: t('reasonForChange'),
|
||||||
type: "input",
|
type: 'input',
|
||||||
maxLength: 50,
|
maxLength: 50,
|
||||||
readOnly: isLoading,
|
readOnly: isLoading,
|
||||||
validate: (value) => value !== "",
|
validate: (value) => value !== '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "oldKey",
|
name: 'oldKey',
|
||||||
label: t("oldKeyId"),
|
label: t('oldKeyId'),
|
||||||
type: "input",
|
type: 'input',
|
||||||
maxLength: 6,
|
maxLength: 6,
|
||||||
readOnly: isLoading,
|
readOnly: isLoading,
|
||||||
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "newKey",
|
name: 'newKey',
|
||||||
label: t("newKeyId"),
|
label: t('newKeyId'),
|
||||||
type: "input",
|
type: 'input',
|
||||||
maxLength: 6,
|
maxLength: 6,
|
||||||
readOnly: isLoading,
|
readOnly: isLoading,
|
||||||
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "newKeyConfirm",
|
name: 'newKeyConfirm',
|
||||||
label: t("confirmNewKeyId"),
|
label: t('confirmNewKeyId'),
|
||||||
type: "input",
|
type: 'input',
|
||||||
maxLength: 6,
|
maxLength: 6,
|
||||||
readOnly: isLoading,
|
readOnly: isLoading,
|
||||||
validate: (value) => value !== "" && value === keySwapDetails.newKey,
|
validate: (value) => value !== '' && value === keySwapDetails.newKey,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ function KeySwap() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
showToast(t("highlightedFieldsInvalid"), "error");
|
showToast(t('highlightedFieldsInvalid'), 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,18 +114,18 @@ function KeySwap() {
|
|||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
setNotification({
|
setNotification({
|
||||||
message: response.data.message,
|
message: response.data.message,
|
||||||
type: "success",
|
type: 'success',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setNotification({
|
setNotification({
|
||||||
message: response.data.message,
|
message: response.data.message,
|
||||||
type: "error",
|
type: 'error',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setNotification({
|
setNotification({
|
||||||
message: error.message,
|
message: error.message,
|
||||||
type: "error",
|
type: 'error',
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -148,14 +148,10 @@ function KeySwap() {
|
|||||||
const valid = keySwapDetails[`${field.name}Valid`];
|
const valid = keySwapDetails[`${field.name}Valid`];
|
||||||
return (
|
return (
|
||||||
<FormField key={field.name} label={field.label} icon={field.icon}>
|
<FormField key={field.name} label={field.label} icon={field.icon}>
|
||||||
{field.type === "input" ? (
|
{field.type === 'input' ? (
|
||||||
<FormInput props={commonProps} valid={valid} />
|
<FormInput props={commonProps} valid={valid} />
|
||||||
) : (
|
) : (
|
||||||
<FormSelect
|
<FormSelect props={commonProps} valid={valid} options={field.options} />
|
||||||
props={commonProps}
|
|
||||||
valid={valid}
|
|
||||||
options={field.options}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</FormField>
|
</FormField>
|
||||||
);
|
);
|
||||||
@@ -164,11 +160,11 @@ function KeySwap() {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{notification.message !== "" && <Notification {...notification} />}
|
{notification.message !== '' && <Notification {...notification} />}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
<FormBox title={t("lockerStatus")}>
|
<FormBox title={t('lockerStatus')}>
|
||||||
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
||||||
<Button text={t("submit")} onClick={handleKeySwap} />
|
<Button text={t('submit')} onClick={handleKeySwap} />
|
||||||
</FormBox>
|
</FormBox>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { useState } from "react";
|
import { useState } from 'react';
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import FormBox from "../components/FormBox";
|
import FormBox from '../components/FormBox';
|
||||||
import Button from "../components/Button";
|
import Button from '../components/Button';
|
||||||
import FormField from "../components/FormField";
|
import FormField from '../components/FormField';
|
||||||
import FormInput from "../components/FormInput";
|
import FormInput from '../components/FormInput';
|
||||||
import FormSelect from "../components/FormSelect";
|
import FormSelect from '../components/FormSelect';
|
||||||
import FieldsWrapper from "../components/FieldsWrapper";
|
import FieldsWrapper from '../components/FieldsWrapper';
|
||||||
|
|
||||||
function LockerMaintenance() {
|
function LockerMaintenance() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [operation, setOperation] = useState({ value: "", valid: true });
|
const [operation, setOperation] = useState({ value: '', valid: true });
|
||||||
|
|
||||||
const handleNext = (e) => {
|
const handleNext = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (operation.value === "") {
|
if (operation.value === '') {
|
||||||
setOperation({ value: operation.value, valid: false });
|
setOperation({ value: operation.value, valid: false });
|
||||||
}
|
}
|
||||||
navigate(operation.value);
|
navigate(operation.value);
|
||||||
@@ -23,13 +23,13 @@ function LockerMaintenance() {
|
|||||||
|
|
||||||
const formFields = [
|
const formFields = [
|
||||||
{
|
{
|
||||||
name: "value",
|
name: 'value',
|
||||||
label: t("operation"),
|
label: t('operation'),
|
||||||
options: [
|
options: [
|
||||||
{ label: t("status"), value: "status" },
|
{ label: t('status'), value: 'status' },
|
||||||
{ label: t("keySwap"), value: "key-swap" },
|
{ label: t('keySwap'), value: 'key-swap' },
|
||||||
],
|
],
|
||||||
type: "select",
|
type: 'select',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ function LockerMaintenance() {
|
|||||||
const options = field.options;
|
const options = field.options;
|
||||||
return (
|
return (
|
||||||
<FormField label={field.label}>
|
<FormField label={field.label}>
|
||||||
{field.type === "input" ? (
|
{field.type === 'input' ? (
|
||||||
<FormInput props={commonProps} />
|
<FormInput props={commonProps} />
|
||||||
) : (
|
) : (
|
||||||
<FormSelect props={commonProps} options={options} />
|
<FormSelect props={commonProps} options={options} />
|
||||||
@@ -57,9 +57,9 @@ function LockerMaintenance() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<FormBox title={t("lockerMaintenance")}>
|
<FormBox title={t('lockerMaintenance')}>
|
||||||
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
||||||
<Button text={t("next")} onClick={(e) => handleNext(e)} />
|
<Button text={t('next')} onClick={(e) => handleNext(e)} />
|
||||||
</FormBox>
|
</FormBox>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -1,56 +1,56 @@
|
|||||||
import FormBox from "../components/FormBox";
|
import FormBox from '../components/FormBox';
|
||||||
import FormField from "../components/FormField";
|
import FormField from '../components/FormField';
|
||||||
import FormInput from "../components/FormInput";
|
import FormInput from '../components/FormInput';
|
||||||
import FormSelect from "../components/FormSelect";
|
import FormSelect from '../components/FormSelect';
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useState } from "react";
|
import { useState } from 'react';
|
||||||
import Button from "../components/Button";
|
import Button from '../components/Button';
|
||||||
import { lockerService } from "../services/locker.service";
|
import { lockerService } from '../services/locker.service';
|
||||||
import { useLoading } from "../hooks/useLoading";
|
import { useLoading } from '../hooks/useLoading';
|
||||||
import { AnimatePresence } from "motion/react";
|
import { AnimatePresence } from 'motion/react';
|
||||||
import Notification from "../components/Notification";
|
import Notification from '../components/Notification';
|
||||||
import FieldsWrapper from "../components/FieldsWrapper";
|
import FieldsWrapper from '../components/FieldsWrapper';
|
||||||
|
|
||||||
function LockerStatus() {
|
function LockerStatus() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [lockerDetails, setLockerDetails] = useState({
|
const [lockerDetails, setLockerDetails] = useState({
|
||||||
cabinetId: "",
|
cabinetId: '',
|
||||||
lockerId: "",
|
lockerId: '',
|
||||||
status: "",
|
status: '',
|
||||||
cabinetIdValid: true,
|
cabinetIdValid: true,
|
||||||
lockerIdValid: true,
|
lockerIdValid: true,
|
||||||
statusValid: true,
|
statusValid: true,
|
||||||
});
|
});
|
||||||
const { isLoading, setIsLoading } = useLoading();
|
const { isLoading, setIsLoading } = useLoading();
|
||||||
const [notification, setNotification] = useState({ message: "", type: "" });
|
const [notification, setNotification] = useState({ message: '', type: '' });
|
||||||
|
|
||||||
const formFields = [
|
const formFields = [
|
||||||
{
|
{
|
||||||
name: "cabinetId",
|
name: 'cabinetId',
|
||||||
label: t("cabinetId"),
|
label: t('cabinetId'),
|
||||||
type: "input",
|
type: 'input',
|
||||||
maxLength: 6,
|
maxLength: 6,
|
||||||
readOnly: isLoading,
|
readOnly: isLoading,
|
||||||
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "lockerId",
|
name: 'lockerId',
|
||||||
label: t("lockerId"),
|
label: t('lockerId'),
|
||||||
type: "input",
|
type: 'input',
|
||||||
maxLength: 6,
|
maxLength: 6,
|
||||||
readOnly: isLoading,
|
readOnly: isLoading,
|
||||||
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
validate: (value) => /^[A-Z]{2}[0-9]{4}/.test(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "status",
|
name: 'status',
|
||||||
label: t("status"),
|
label: t('status'),
|
||||||
type: "select",
|
type: 'select',
|
||||||
readOnly: isLoading,
|
readOnly: isLoading,
|
||||||
options: [
|
options: [
|
||||||
{ value: "open", label: t("open") },
|
{ value: 'open', label: t('open') },
|
||||||
{ value: "close", label: t("close") },
|
{ value: 'close', label: t('close') },
|
||||||
],
|
],
|
||||||
validate: (value) => value !== "",
|
validate: (value) => value !== '',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -83,12 +83,12 @@ function LockerStatus() {
|
|||||||
);
|
);
|
||||||
setNotification({
|
setNotification({
|
||||||
message: response.data.message,
|
message: response.data.message,
|
||||||
type: "success",
|
type: 'success',
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setNotification({
|
setNotification({
|
||||||
message: error.message,
|
message: error.message,
|
||||||
type: "error",
|
type: 'error',
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -111,7 +111,7 @@ function LockerStatus() {
|
|||||||
const valid = lockerDetails[`${field.name}Valid`];
|
const valid = lockerDetails[`${field.name}Valid`];
|
||||||
return (
|
return (
|
||||||
<FormField key={field.name} label={field.label} icon={field.icon}>
|
<FormField key={field.name} label={field.label} icon={field.icon}>
|
||||||
{field.type === "input" ? (
|
{field.type === 'input' ? (
|
||||||
<FormInput props={commonProps} valid={valid} />
|
<FormInput props={commonProps} valid={valid} />
|
||||||
) : (
|
) : (
|
||||||
<FormSelect props={commonProps} options={field.options} />
|
<FormSelect props={commonProps} options={field.options} />
|
||||||
@@ -123,12 +123,12 @@ function LockerStatus() {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{notification.message !== "" && <Notification {...notification} />}
|
{notification.message !== '' && <Notification {...notification} />}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
|
|
||||||
<FormBox title={t("lockerStatus")}>
|
<FormBox title={t('lockerStatus')}>
|
||||||
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
<FieldsWrapper>{formFields.map(renderField)}</FieldsWrapper>
|
||||||
<Button text={t("submit")} onClick={handleSubmit} />
|
<Button text={t('submit')} onClick={handleSubmit} />
|
||||||
</FormBox>
|
</FormBox>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from 'react-router-dom';
|
||||||
import { useState } from "react";
|
import { useState } from 'react';
|
||||||
import { useLoading } from "../hooks/useLoading";
|
import { useLoading } from '../hooks/useLoading';
|
||||||
import FormBox from "../components/FormBox";
|
import FormBox from '../components/FormBox';
|
||||||
import Button from "../components/Button";
|
import Button from '../components/Button';
|
||||||
import { lockerService } from "../services/locker.service";
|
import { lockerService } from '../services/locker.service';
|
||||||
import { AnimatePresence } from "motion/react";
|
import { AnimatePresence } from 'motion/react';
|
||||||
import Notification from "../components/Notification";
|
import Notification from '../components/Notification';
|
||||||
import FormField from "../components/FormField";
|
import FormField from '../components/FormField';
|
||||||
import FormInput from "../components/FormInput";
|
import FormInput from '../components/FormInput';
|
||||||
import FormSelect from "../components/FormSelect";
|
import FormSelect from '../components/FormSelect';
|
||||||
import FormHeader from "../components/FormHeader";
|
import FormHeader from '../components/FormHeader';
|
||||||
import FieldsWrapper from "../components/FieldsWrapper";
|
import FieldsWrapper from '../components/FieldsWrapper';
|
||||||
|
|
||||||
function LockersRegistration() {
|
function LockersRegistration() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const { setIsLoading } = useLoading();
|
const { setIsLoading } = useLoading();
|
||||||
const [notification, setNotification] = useState({ message: "", type: "" });
|
const [notification, setNotification] = useState({ message: '', type: '' });
|
||||||
|
|
||||||
const noOfLockers = location.state?.noOfLockers;
|
const noOfLockers = location.state?.noOfLockers;
|
||||||
const cabinetId = location.state?.cabinetId;
|
const cabinetId = location.state?.cabinetId;
|
||||||
@@ -23,9 +23,9 @@ function LockersRegistration() {
|
|||||||
const initLockers = Array(noOfLockers)
|
const initLockers = Array(noOfLockers)
|
||||||
.fill()
|
.fill()
|
||||||
.map(() => ({
|
.map(() => ({
|
||||||
id: "",
|
id: '',
|
||||||
size: "",
|
size: '',
|
||||||
keyId: "",
|
keyId: '',
|
||||||
idValid: true,
|
idValid: true,
|
||||||
sizeValid: true,
|
sizeValid: true,
|
||||||
keyIdValid: true,
|
keyIdValid: true,
|
||||||
@@ -49,18 +49,14 @@ function LockersRegistration() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Find duplicates
|
// Find duplicates
|
||||||
const duplicateLockerIds = findDuplicates(lockerValues, "id");
|
const duplicateLockerIds = findDuplicates(lockerValues, 'id');
|
||||||
const duplicateKeyIds = findDuplicates(lockerValues, "keyId");
|
const duplicateKeyIds = findDuplicates(lockerValues, 'keyId');
|
||||||
|
|
||||||
const newValues = lockerValues.map((locker) => {
|
const newValues = lockerValues.map((locker) => {
|
||||||
const newLocker = { ...locker };
|
const newLocker = { ...locker };
|
||||||
|
|
||||||
// Check ID
|
// Check ID
|
||||||
if (
|
if (locker.id === '' || !idRegex.test(locker.id) || duplicateLockerIds.includes(locker.id)) {
|
||||||
locker.id === "" ||
|
|
||||||
!idRegex.test(locker.id) ||
|
|
||||||
duplicateLockerIds.includes(locker.id)
|
|
||||||
) {
|
|
||||||
newLocker.idValid = false;
|
newLocker.idValid = false;
|
||||||
valid = false;
|
valid = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -68,7 +64,7 @@ function LockersRegistration() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check size
|
// Check size
|
||||||
if (locker.size === "") {
|
if (locker.size === '') {
|
||||||
newLocker.sizeValid = false;
|
newLocker.sizeValid = false;
|
||||||
valid = false;
|
valid = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -77,7 +73,7 @@ function LockersRegistration() {
|
|||||||
|
|
||||||
// Check keyId
|
// Check keyId
|
||||||
if (
|
if (
|
||||||
locker.keyId === "" ||
|
locker.keyId === '' ||
|
||||||
!idRegex.test(locker.keyId) ||
|
!idRegex.test(locker.keyId) ||
|
||||||
duplicateKeyIds.includes(locker.keyId)
|
duplicateKeyIds.includes(locker.keyId)
|
||||||
) {
|
) {
|
||||||
@@ -98,19 +94,16 @@ function LockersRegistration() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const response = await lockerService.registerLockers(
|
const response = await lockerService.registerLockers(cabinetId, lockerValues);
|
||||||
cabinetId,
|
|
||||||
lockerValues
|
|
||||||
);
|
|
||||||
setNotification({
|
setNotification({
|
||||||
message: `Cabinet creation successful. Cabinet ID: ${response.data.cabinetId}`,
|
message: `Cabinet creation successful. Cabinet ID: ${response.data.cabinetId}`,
|
||||||
type: "success",
|
type: 'success',
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
setNotification({
|
setNotification({
|
||||||
message: `Error registering lockers. ${error.message}`,
|
message: `Error registering lockers. ${error.message}`,
|
||||||
type: "error",
|
type: 'error',
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -120,29 +113,29 @@ function LockersRegistration() {
|
|||||||
|
|
||||||
const formRow = [
|
const formRow = [
|
||||||
{
|
{
|
||||||
label: "Locker ID",
|
label: 'Locker ID',
|
||||||
type: "input",
|
type: 'input',
|
||||||
subType: "text",
|
subType: 'text',
|
||||||
name: "id",
|
name: 'id',
|
||||||
maxLength: 6,
|
maxLength: 6,
|
||||||
validate: (value) => /^[A-Z]{2}[0-9]{4}$/.test(value),
|
validate: (value) => /^[A-Z]{2}[0-9]{4}$/.test(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Size",
|
label: 'Size',
|
||||||
type: "select",
|
type: 'select',
|
||||||
subType: "text",
|
subType: 'text',
|
||||||
name: "size",
|
name: 'size',
|
||||||
options: [
|
options: [
|
||||||
{ label: "Small", value: "1" },
|
{ label: 'Small', value: '1' },
|
||||||
{ label: "Medium", value: "2" },
|
{ label: 'Medium', value: '2' },
|
||||||
{ label: "Large", value: "3" },
|
{ label: 'Large', value: '3' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Key ID",
|
label: 'Key ID',
|
||||||
type: "input",
|
type: 'input',
|
||||||
subType: "text",
|
subType: 'text',
|
||||||
name: "keyId",
|
name: 'keyId',
|
||||||
maxLength: 6,
|
maxLength: 6,
|
||||||
validate: (value) => /^[A-Z]{2}[0-9]{4}$/.test(value),
|
validate: (value) => /^[A-Z]{2}[0-9]{4}$/.test(value),
|
||||||
},
|
},
|
||||||
@@ -162,7 +155,7 @@ function LockersRegistration() {
|
|||||||
|
|
||||||
const valid = lockerValues[`${field.name}Valid`];
|
const valid = lockerValues[`${field.name}Valid`];
|
||||||
|
|
||||||
return field.type === "input" ? (
|
return field.type === 'input' ? (
|
||||||
<FormInput key={field.name} props={commonProps} valid={valid} />
|
<FormInput key={field.name} props={commonProps} valid={valid} />
|
||||||
) : (
|
) : (
|
||||||
<FormSelect key={field.name} props={commonProps} valid={valid} options={field.options} />
|
<FormSelect key={field.name} props={commonProps} valid={valid} options={field.options} />
|
||||||
@@ -181,17 +174,15 @@ function LockersRegistration() {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{notification.message !== "" && <Notification {...notification} />}
|
{notification.message !== '' && <Notification {...notification} />}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
{notification.type === "success" && (
|
{notification.type === 'success' && (
|
||||||
<div className="absolute inset-0 bg-[#fff]/50 z-10 rounded-3xl" />
|
<div className="absolute inset-0 bg-[#fff]/50 z-10 rounded-3xl" />
|
||||||
)}
|
)}
|
||||||
<FormBox title="Locker Registration">
|
<FormBox title="Locker Registration">
|
||||||
<FormHeader text={cabinetId} />
|
<FormHeader text={cabinetId} />
|
||||||
<FieldsWrapper className="">
|
<FieldsWrapper className="">{formFields.map(renderFormFields)}</FieldsWrapper>
|
||||||
{formFields.map(renderFormFields)}
|
|
||||||
</FieldsWrapper>
|
|
||||||
<Button text="Register" onClick={handleSubmit} />
|
<Button text="Register" onClick={handleSubmit} />
|
||||||
</FormBox>
|
</FormBox>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
const api = axios.create({
|
const api = axios.create({
|
||||||
baseURL: "http://localhost:8081/api/v1",
|
baseURL: 'http://localhost:8081/api/v1',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json',
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default api;
|
export default api;
|
@@ -1,8 +1,8 @@
|
|||||||
import api from "./api";
|
import api from './api';
|
||||||
|
|
||||||
export const lockerService = {
|
export const lockerService = {
|
||||||
registerLockers: async (cabinetId, lockers) => {
|
registerLockers: async (cabinetId, lockers) => {
|
||||||
return api.post("/cabinet", {
|
return api.post('/cabinet', {
|
||||||
cabinetId,
|
cabinetId,
|
||||||
lockers: lockers.map(({ id, size, keyId }) => ({
|
lockers: lockers.map(({ id, size, keyId }) => ({
|
||||||
id,
|
id,
|
||||||
|
@@ -1,8 +1,43 @@
|
|||||||
const productInfo = [
|
const productInfo = [
|
||||||
{ productCode: '3001', productCodeDescription: 'RECURRING DEPOSIT', interestCategory: '1004', interestCategoryDescription: 'NON MEMBER - SENIOR CITIZEN', payableGl: '16010', paidGl: '62110' },
|
{
|
||||||
{ productCode: '1101', productCodeDescription: 'CURRENT ACCOUNT', interestCategory: '1009', interestCategoryDescription: 'GENERAL', payableGl: '16018', paidGl: '62115' },
|
productCode: '3001',
|
||||||
{ productCode: '1101', productCodeDescription: 'SAVINGS DEPOSIT', interestCategory: '1007', interestCategoryDescription: 'NON MEMBER', payableGl: '16301', paidGl: '62117' },
|
productCodeDescription: 'RECURRING DEPOSIT',
|
||||||
{ productCode: '2002', productCodeDescription: 'CASH CERTIFICATE -GENERAL', interestCategory: '1047', interestCategoryDescription: 'COMPOUNDING', payableGl: '16011', paidGl: '62111' },
|
interestCategory: '1004',
|
||||||
{ productCode: '2002', productCodeDescription: 'CASH CERTIFICATE', interestCategory: '1005', interestCategoryDescription: 'NON MEMBER - SENIOR CITIZEN', payableGl: '16011', paidGl: '62111' },
|
interestCategoryDescription: 'NON MEMBER - SENIOR CITIZEN',
|
||||||
]
|
payableGl: '16010',
|
||||||
export default productInfo;
|
paidGl: '62110',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
productCode: '1101',
|
||||||
|
productCodeDescription: 'CURRENT ACCOUNT',
|
||||||
|
interestCategory: '1009',
|
||||||
|
interestCategoryDescription: 'GENERAL',
|
||||||
|
payableGl: '16018',
|
||||||
|
paidGl: '62115',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
productCode: '1101',
|
||||||
|
productCodeDescription: 'SAVINGS DEPOSIT',
|
||||||
|
interestCategory: '1007',
|
||||||
|
interestCategoryDescription: 'NON MEMBER',
|
||||||
|
payableGl: '16301',
|
||||||
|
paidGl: '62117',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
productCode: '2002',
|
||||||
|
productCodeDescription: 'CASH CERTIFICATE -GENERAL',
|
||||||
|
interestCategory: '1047',
|
||||||
|
interestCategoryDescription: 'COMPOUNDING',
|
||||||
|
payableGl: '16011',
|
||||||
|
paidGl: '62111',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
productCode: '2002',
|
||||||
|
productCodeDescription: 'CASH CERTIFICATE',
|
||||||
|
interestCategory: '1005',
|
||||||
|
interestCategoryDescription: 'NON MEMBER - SENIOR CITIZEN',
|
||||||
|
payableGl: '16011',
|
||||||
|
paidGl: '62111',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
export default productInfo;
|
||||||
|
@@ -1,14 +1,16 @@
|
|||||||
const getUserInfoFromSession = () => {
|
const getUserInfoFromSession = () => {
|
||||||
return {
|
return {
|
||||||
username: "Rajesh Kumar",
|
username: 'Rajesh Kumar',
|
||||||
pacsName: "Demo SKUS Ltd.",
|
pacsName: 'Demo SKUS Ltd.',
|
||||||
userType: "pacsTeller",
|
userType: 'pacsTeller',
|
||||||
moduleName: "locker",
|
moduleName: 'locker',
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
const toTitleCase = (str) => {
|
const toTitleCase = (str) => {
|
||||||
return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
|
return str.replace(/\w\S*/g, function (txt) {
|
||||||
}
|
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export { getUserInfoFromSession, toTitleCase };
|
export { getUserInfoFromSession, toTitleCase };
|
@@ -1,9 +1,6 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
export default {
|
export default {
|
||||||
content: [
|
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
|
||||||
"./index.html",
|
|
||||||
"./src/**/*.{js,ts,jsx,tsx}",
|
|
||||||
],
|
|
||||||
darkMode: 'selector',
|
darkMode: 'selector',
|
||||||
theme: {
|
theme: {
|
||||||
colors: {
|
colors: {
|
||||||
@@ -13,7 +10,7 @@ export default {
|
|||||||
error: {
|
error: {
|
||||||
DEFAULT: '#A14444',
|
DEFAULT: '#A14444',
|
||||||
dark: '#E5254B',
|
dark: '#E5254B',
|
||||||
surface: {DEFAULT: '#D26464', dark: '#FCE9ED'}
|
surface: { DEFAULT: '#D26464', dark: '#FCE9ED' },
|
||||||
},
|
},
|
||||||
onToast: {
|
onToast: {
|
||||||
DEFAULT: '#646564',
|
DEFAULT: '#646564',
|
||||||
@@ -22,22 +19,22 @@ export default {
|
|||||||
warning: {
|
warning: {
|
||||||
DEFAULT: '#A5A513',
|
DEFAULT: '#A5A513',
|
||||||
dark: '#EA7000',
|
dark: '#EA7000',
|
||||||
surface: {DEFAULT: '#C8C820', dark: '#FDF1E5'}
|
surface: { DEFAULT: '#C8C820', dark: '#FDF1E5' },
|
||||||
},
|
},
|
||||||
success: {
|
success: {
|
||||||
DEFAULT: '#038100',
|
DEFAULT: '#038100',
|
||||||
dark: '#038100',
|
dark: '#038100',
|
||||||
surface: {DEFAULT: '#E6F2E5', dark: '#E6F2E5'}
|
surface: { DEFAULT: '#E6F2E5', dark: '#E6F2E5' },
|
||||||
},
|
},
|
||||||
transparent: 'transparent',
|
transparent: 'transparent',
|
||||||
primary: {
|
primary: {
|
||||||
DEFAULT: '#008C46',
|
DEFAULT: '#008C46',
|
||||||
dark: '#E6F4E1'
|
dark: '#E6F4E1',
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
DEFAULT: '#B1E1B3',
|
DEFAULT: '#B1E1B3',
|
||||||
dark: '#7DBD80',
|
dark: '#7DBD80',
|
||||||
variant: {DEFAULT: '#80AE82', dark: '#5B875D'}
|
variant: { DEFAULT: '#80AE82', dark: '#5B875D' },
|
||||||
},
|
},
|
||||||
tertiary: {
|
tertiary: {
|
||||||
DEFAULT: '#f2f2df',
|
DEFAULT: '#f2f2df',
|
||||||
@@ -46,17 +43,16 @@ export default {
|
|||||||
surface: {
|
surface: {
|
||||||
DEFAULT: '#F6F6F6',
|
DEFAULT: '#F6F6F6',
|
||||||
dark: '#2d332d',
|
dark: '#2d332d',
|
||||||
variant: {DEFAULT: '#F4FFF4', dark: '#2b372c'}
|
variant: { DEFAULT: '#F4FFF4', dark: '#2b372c' },
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
display: ['Montserrat', 'sans-serif'],
|
display: ['Montserrat', 'sans-serif'],
|
||||||
body: ['Rubik', 'Noto Sans','Noto Sans Bengali', 'sans-serif'],
|
body: ['Rubik', 'Noto Sans', 'Noto Sans Bengali', 'sans-serif'],
|
||||||
},
|
},
|
||||||
extend: {
|
extend: {
|
||||||
borderWidth: {
|
borderWidth: {
|
||||||
'3': '3px',
|
3: '3px',
|
||||||
},
|
},
|
||||||
fontSize: {
|
fontSize: {
|
||||||
title: '40px',
|
title: '40px',
|
||||||
@@ -75,7 +71,7 @@ export default {
|
|||||||
'30%': { width: '30%' },
|
'30%': { width: '30%' },
|
||||||
'80%': { width: '10%' },
|
'80%': { width: '10%' },
|
||||||
'100%': { left: '100%' },
|
'100%': { left: '100%' },
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -84,5 +80,4 @@ export default {
|
|||||||
addVariant('second-last', '&:nth-last-child(2)');
|
addVariant('second-last', '&:nth-last-child(2)');
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
};
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite';
|
||||||
import react from '@vitejs/plugin-react'
|
import react from '@vitejs/plugin-react';
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
})
|
});
|
||||||
|
Reference in New Issue
Block a user