diff --git a/.scannerwork/.sonar_lock b/.scannerwork/.sonar_lock new file mode 100644 index 00000000..e69de29b diff --git a/.scannerwork/report-task.txt b/.scannerwork/report-task.txt new file mode 100644 index 00000000..df1f2fb1 --- /dev/null +++ b/.scannerwork/report-task.txt @@ -0,0 +1,6 @@ +projectKey=pms-react +serverUrl=https://sonar.marcoaiot.com +serverVersion=25.5.0.107428 +dashboardUrl=https://sonar.marcoaiot.com/dashboard?id=pms-react +ceTaskId=ad6ba36a-08cb-400b-903e-94f173cac03f +ceTaskUrl=https://sonar.marcoaiot.com/api/ce/task?id=ad6ba36a-08cb-400b-903e-94f173cac03f diff --git a/package-lock.json b/package-lock.json index 75c151b9..dfe50b1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,7 @@ "react-router-dom": "^6.20.1", "react-toastify": "^11.0.2", "sort-by": "^1.2.0", + "swiper": "^11.2.10", "xlsx": "^0.18.5", "zod": "^3.24.1" }, @@ -5547,6 +5548,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swiper": { + "version": "11.2.10", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.10.tgz", + "integrity": "sha512-RMeVUUjTQH+6N3ckimK93oxz6Sn5la4aDlgPzB+rBrG/smPdCTicXyhxa+woIpopz+jewEloiEE3lKo1h9w2YQ==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "engines": { + "node": ">= 4.7.0" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", diff --git a/package.json b/package.json index 33e1f019..02c59115 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "react-router-dom": "^6.20.1", "react-toastify": "^11.0.2", "sort-by": "^1.2.0", + "swiper": "^11.2.10", "xlsx": "^0.18.5", "zod": "^3.24.1" }, diff --git a/public/assets/css/default.css b/public/assets/css/default.css index 2abd37ee..db070129 100644 --- a/public/assets/css/default.css +++ b/public/assets/css/default.css @@ -30,9 +30,7 @@ width: 45px; } -.app-brand-logo-login { - width: 100px; -} + .app-brand-logo-border { border: 1px solid #d5d5d5; @@ -164,3 +162,24 @@ thead tr { border-top: 1px solid white; } + +.app-brand-logo-login { + max-width: 50px; /* default for mobile */ + height: auto; /* keep aspect ratio */ +} + + +/* Tablet and up (≥768px) */ +@media (min-width: 768px) { + .app-brand-logo-login { + max-width: 60px; + } +} + +/* Desktop and up (≥1200px) */ +@media (min-width: 1200px) { + .app-brand-logo-login { + max-width: 80px; + } +} + diff --git a/public/assets/vendor/css/core.css b/public/assets/vendor/css/core.css index 6e3d5d14..9be75669 100644 --- a/public/assets/vendor/css/core.css +++ b/public/assets/vendor/css/core.css @@ -32544,3 +32544,29 @@ body:not(.modal-open) .layout-content-navbar .layout-navbar { var(--bs-dark-contrast) ); } + +/* App colors classes */ +.bg-gray-60{ + background-color:var(--bs-gray-60) +} +.text-gray-60{ + color:var(--bs-gray-60) +} +.bg-blue { + background-color:var(--bs-blue) +} +.text-blue{ + color:var(--bs-blue) +} +.bg-indigo { + background-color:var(--bs-indigo) +} +.text-indigo{ + color:var(--bs-indigo) +} +.bg-red { + background-color:var(--bs-red) +} +.text-red{ + color:var(--bs-red) +} \ No newline at end of file diff --git a/public/img/front-pages/backgrounds/cta-bg-dark.png b/public/img/front-pages/backgrounds/cta-bg-dark.png new file mode 100644 index 00000000..7c4e84ae Binary files /dev/null and b/public/img/front-pages/backgrounds/cta-bg-dark.png differ diff --git a/public/img/front-pages/backgrounds/cta-bg-light.png b/public/img/front-pages/backgrounds/cta-bg-light.png new file mode 100644 index 00000000..f2cdb6fb Binary files /dev/null and b/public/img/front-pages/backgrounds/cta-bg-light.png differ diff --git a/public/img/front-pages/backgrounds/footer-bg-dark.png b/public/img/front-pages/backgrounds/footer-bg-dark.png new file mode 100644 index 00000000..150c6ee6 Binary files /dev/null and b/public/img/front-pages/backgrounds/footer-bg-dark.png differ diff --git a/public/img/front-pages/backgrounds/footer-bg-light.png b/public/img/front-pages/backgrounds/footer-bg-light.png new file mode 100644 index 00000000..ff217349 Binary files /dev/null and b/public/img/front-pages/backgrounds/footer-bg-light.png differ diff --git a/public/img/front-pages/backgrounds/footer-bg.png b/public/img/front-pages/backgrounds/footer-bg.png new file mode 100644 index 00000000..5890f0d6 Binary files /dev/null and b/public/img/front-pages/backgrounds/footer-bg.png differ diff --git a/public/img/front-pages/backgrounds/hero-bg.png b/public/img/front-pages/backgrounds/hero-bg.png new file mode 100644 index 00000000..7d175c58 Binary files /dev/null and b/public/img/front-pages/backgrounds/hero-bg.png differ diff --git a/public/img/front-pages/branding/logo-1.png b/public/img/front-pages/branding/logo-1.png new file mode 100644 index 00000000..7f551d70 Binary files /dev/null and b/public/img/front-pages/branding/logo-1.png differ diff --git a/public/img/front-pages/branding/logo-2.png b/public/img/front-pages/branding/logo-2.png new file mode 100644 index 00000000..5e3f2698 Binary files /dev/null and b/public/img/front-pages/branding/logo-2.png differ diff --git a/public/img/front-pages/branding/logo-3.png b/public/img/front-pages/branding/logo-3.png new file mode 100644 index 00000000..e854e939 Binary files /dev/null and b/public/img/front-pages/branding/logo-3.png differ diff --git a/public/img/front-pages/branding/logo-4.png b/public/img/front-pages/branding/logo-4.png new file mode 100644 index 00000000..6c5d3f3c Binary files /dev/null and b/public/img/front-pages/branding/logo-4.png differ diff --git a/public/img/front-pages/branding/logo-5.png b/public/img/front-pages/branding/logo-5.png new file mode 100644 index 00000000..bf3cc14e Binary files /dev/null and b/public/img/front-pages/branding/logo-5.png differ diff --git a/public/img/front-pages/branding/logo-6.png b/public/img/front-pages/branding/logo-6.png new file mode 100644 index 00000000..99980b2a Binary files /dev/null and b/public/img/front-pages/branding/logo-6.png differ diff --git a/public/img/front-pages/branding/logo_1-dark.png b/public/img/front-pages/branding/logo_1-dark.png new file mode 100644 index 00000000..cb1a58d2 Binary files /dev/null and b/public/img/front-pages/branding/logo_1-dark.png differ diff --git a/public/img/front-pages/branding/logo_1-light.png b/public/img/front-pages/branding/logo_1-light.png new file mode 100644 index 00000000..e0308e90 Binary files /dev/null and b/public/img/front-pages/branding/logo_1-light.png differ diff --git a/public/img/front-pages/branding/logo_2-dark.png b/public/img/front-pages/branding/logo_2-dark.png new file mode 100644 index 00000000..f5e92478 Binary files /dev/null and b/public/img/front-pages/branding/logo_2-dark.png differ diff --git a/public/img/front-pages/branding/logo_2-light.png b/public/img/front-pages/branding/logo_2-light.png new file mode 100644 index 00000000..719e6103 Binary files /dev/null and b/public/img/front-pages/branding/logo_2-light.png differ diff --git a/public/img/front-pages/branding/logo_3-dark.png b/public/img/front-pages/branding/logo_3-dark.png new file mode 100644 index 00000000..27c68e49 Binary files /dev/null and b/public/img/front-pages/branding/logo_3-dark.png differ diff --git a/public/img/front-pages/branding/logo_3-light.png b/public/img/front-pages/branding/logo_3-light.png new file mode 100644 index 00000000..5ec4f174 Binary files /dev/null and b/public/img/front-pages/branding/logo_3-light.png differ diff --git a/public/img/front-pages/branding/logo_4-dark.png b/public/img/front-pages/branding/logo_4-dark.png new file mode 100644 index 00000000..3e5bfc3d Binary files /dev/null and b/public/img/front-pages/branding/logo_4-dark.png differ diff --git a/public/img/front-pages/branding/logo_4-light.png b/public/img/front-pages/branding/logo_4-light.png new file mode 100644 index 00000000..0929f535 Binary files /dev/null and b/public/img/front-pages/branding/logo_4-light.png differ diff --git a/public/img/front-pages/branding/logo_5-dark.png b/public/img/front-pages/branding/logo_5-dark.png new file mode 100644 index 00000000..34342001 Binary files /dev/null and b/public/img/front-pages/branding/logo_5-dark.png differ diff --git a/public/img/front-pages/branding/logo_5-light.png b/public/img/front-pages/branding/logo_5-light.png new file mode 100644 index 00000000..deb1071f Binary files /dev/null and b/public/img/front-pages/branding/logo_5-light.png differ diff --git a/public/img/front-pages/icons/Join-community-arrow.png b/public/img/front-pages/icons/Join-community-arrow.png new file mode 100644 index 00000000..9bde454a Binary files /dev/null and b/public/img/front-pages/icons/Join-community-arrow.png differ diff --git a/public/img/front-pages/icons/check-warning.svg b/public/img/front-pages/icons/check-warning.svg new file mode 100644 index 00000000..4c16161c --- /dev/null +++ b/public/img/front-pages/icons/check-warning.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/img/front-pages/icons/check.svg b/public/img/front-pages/icons/check.svg new file mode 100644 index 00000000..59b5961e --- /dev/null +++ b/public/img/front-pages/icons/check.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/img/front-pages/icons/contact-border.png b/public/img/front-pages/icons/contact-border.png new file mode 100644 index 00000000..1eb721d6 Binary files /dev/null and b/public/img/front-pages/icons/contact-border.png differ diff --git a/public/img/front-pages/icons/diamond-info.svg b/public/img/front-pages/icons/diamond-info.svg new file mode 100644 index 00000000..5f24f9ef --- /dev/null +++ b/public/img/front-pages/icons/diamond-info.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/img/front-pages/icons/facebook.svg b/public/img/front-pages/icons/facebook.svg new file mode 100644 index 00000000..42672a2d --- /dev/null +++ b/public/img/front-pages/icons/facebook.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/img/front-pages/icons/github.svg b/public/img/front-pages/icons/github.svg new file mode 100644 index 00000000..75bdf8d1 --- /dev/null +++ b/public/img/front-pages/icons/github.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/img/front-pages/icons/instagram.svg b/public/img/front-pages/icons/instagram.svg new file mode 100644 index 00000000..9a6830c8 --- /dev/null +++ b/public/img/front-pages/icons/instagram.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/img/front-pages/icons/keyboard.svg b/public/img/front-pages/icons/keyboard.svg new file mode 100644 index 00000000..dd6b8775 --- /dev/null +++ b/public/img/front-pages/icons/keyboard.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/img/front-pages/icons/laptop.svg b/public/img/front-pages/icons/laptop.svg new file mode 100644 index 00000000..befca175 --- /dev/null +++ b/public/img/front-pages/icons/laptop.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/img/front-pages/icons/paper-airplane.png b/public/img/front-pages/icons/paper-airplane.png new file mode 100644 index 00000000..a4911dc4 Binary files /dev/null and b/public/img/front-pages/icons/paper-airplane.png differ diff --git a/public/img/front-pages/icons/paper.svg b/public/img/front-pages/icons/paper.svg new file mode 100644 index 00000000..6d933f2a --- /dev/null +++ b/public/img/front-pages/icons/paper.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/img/front-pages/icons/plane.png b/public/img/front-pages/icons/plane.png new file mode 100644 index 00000000..497cc1e4 Binary files /dev/null and b/public/img/front-pages/icons/plane.png differ diff --git a/public/img/front-pages/icons/pricing-plans-arrow.png b/public/img/front-pages/icons/pricing-plans-arrow.png new file mode 100644 index 00000000..ed8f60bb Binary files /dev/null and b/public/img/front-pages/icons/pricing-plans-arrow.png differ diff --git a/public/img/front-pages/icons/rocket.svg b/public/img/front-pages/icons/rocket.svg new file mode 100644 index 00000000..700323aa --- /dev/null +++ b/public/img/front-pages/icons/rocket.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/img/front-pages/icons/section-title-icon.png b/public/img/front-pages/icons/section-title-icon.png new file mode 100644 index 00000000..6e8d1730 Binary files /dev/null and b/public/img/front-pages/icons/section-title-icon.png differ diff --git a/public/img/front-pages/icons/shuttle-rocket.png b/public/img/front-pages/icons/shuttle-rocket.png new file mode 100644 index 00000000..154b17e7 Binary files /dev/null and b/public/img/front-pages/icons/shuttle-rocket.png differ diff --git a/public/img/front-pages/icons/twitter.svg b/public/img/front-pages/icons/twitter.svg new file mode 100644 index 00000000..78fa4dc2 --- /dev/null +++ b/public/img/front-pages/icons/twitter.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/img/front-pages/icons/user-success.svg b/public/img/front-pages/icons/user-success.svg new file mode 100644 index 00000000..32d4b3bb --- /dev/null +++ b/public/img/front-pages/icons/user-success.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/img/front-pages/icons/user.svg b/public/img/front-pages/icons/user.svg new file mode 100644 index 00000000..af4eac79 --- /dev/null +++ b/public/img/front-pages/icons/user.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/img/front-pages/landing-page/apple-icon.png b/public/img/front-pages/landing-page/apple-icon.png new file mode 100644 index 00000000..82527801 Binary files /dev/null and b/public/img/front-pages/landing-page/apple-icon.png differ diff --git a/public/img/front-pages/landing-page/contact-customer-service.png b/public/img/front-pages/landing-page/contact-customer-service.png new file mode 100644 index 00000000..4e5aaaad Binary files /dev/null and b/public/img/front-pages/landing-page/contact-customer-service.png differ diff --git a/public/img/front-pages/landing-page/cta-dashboard.png b/public/img/front-pages/landing-page/cta-dashboard.png new file mode 100644 index 00000000..9dcb642f Binary files /dev/null and b/public/img/front-pages/landing-page/cta-dashboard.png differ diff --git a/public/img/front-pages/landing-page/dashboard-light-01.png b/public/img/front-pages/landing-page/dashboard-light-01.png new file mode 100644 index 00000000..8e1d4956 Binary files /dev/null and b/public/img/front-pages/landing-page/dashboard-light-01.png differ diff --git a/public/img/front-pages/landing-page/dashboard-light-02.png b/public/img/front-pages/landing-page/dashboard-light-02.png new file mode 100644 index 00000000..ede59aed Binary files /dev/null and b/public/img/front-pages/landing-page/dashboard-light-02.png differ diff --git a/public/img/front-pages/landing-page/dashboard-light-03.png b/public/img/front-pages/landing-page/dashboard-light-03.png new file mode 100644 index 00000000..1e45e519 Binary files /dev/null and b/public/img/front-pages/landing-page/dashboard-light-03.png differ diff --git a/public/img/front-pages/landing-page/dashboard-light-04.png b/public/img/front-pages/landing-page/dashboard-light-04.png new file mode 100644 index 00000000..998d30ea Binary files /dev/null and b/public/img/front-pages/landing-page/dashboard-light-04.png differ diff --git a/public/img/front-pages/landing-page/dashboard-light-05.png b/public/img/front-pages/landing-page/dashboard-light-05.png new file mode 100644 index 00000000..c7e6f5ac Binary files /dev/null and b/public/img/front-pages/landing-page/dashboard-light-05.png differ diff --git a/public/img/front-pages/landing-page/dashboard-light-06.png b/public/img/front-pages/landing-page/dashboard-light-06.png new file mode 100644 index 00000000..386d7289 Binary files /dev/null and b/public/img/front-pages/landing-page/dashboard-light-06.png differ diff --git a/public/img/front-pages/landing-page/dashboard-light-07.png b/public/img/front-pages/landing-page/dashboard-light-07.png new file mode 100644 index 00000000..b358f986 Binary files /dev/null and b/public/img/front-pages/landing-page/dashboard-light-07.png differ diff --git a/public/img/front-pages/landing-page/dashboard-light-08.png b/public/img/front-pages/landing-page/dashboard-light-08.png new file mode 100644 index 00000000..2ae124a9 Binary files /dev/null and b/public/img/front-pages/landing-page/dashboard-light-08.png differ diff --git a/public/img/front-pages/landing-page/faq-boy-with-logos.png b/public/img/front-pages/landing-page/faq-boy-with-logos.png new file mode 100644 index 00000000..b64dbfcc Binary files /dev/null and b/public/img/front-pages/landing-page/faq-boy-with-logos.png differ diff --git a/public/img/front-pages/landing-page/google-play-icon.png b/public/img/front-pages/landing-page/google-play-icon.png new file mode 100644 index 00000000..117bcb16 Binary files /dev/null and b/public/img/front-pages/landing-page/google-play-icon.png differ diff --git a/public/img/front-pages/landing-page/hero-dashboard-dark.png b/public/img/front-pages/landing-page/hero-dashboard-dark.png new file mode 100644 index 00000000..e035ae98 Binary files /dev/null and b/public/img/front-pages/landing-page/hero-dashboard-dark.png differ diff --git a/public/img/front-pages/landing-page/hero-dashboard-light1.png b/public/img/front-pages/landing-page/hero-dashboard-light1.png new file mode 100644 index 00000000..b4f5fe55 Binary files /dev/null and b/public/img/front-pages/landing-page/hero-dashboard-light1.png differ diff --git a/public/img/front-pages/landing-page/hero-elements-dark.png b/public/img/front-pages/landing-page/hero-elements-dark.png new file mode 100644 index 00000000..af1f5506 Binary files /dev/null and b/public/img/front-pages/landing-page/hero-elements-dark.png differ diff --git a/public/img/front-pages/landing-page/hero-elements-light.png b/public/img/front-pages/landing-page/hero-elements-light.png new file mode 100644 index 00000000..99f88901 Binary files /dev/null and b/public/img/front-pages/landing-page/hero-elements-light.png differ diff --git a/public/img/front-pages/landing-page/team-member-1.png b/public/img/front-pages/landing-page/team-member-1.png new file mode 100644 index 00000000..2a007f12 Binary files /dev/null and b/public/img/front-pages/landing-page/team-member-1.png differ diff --git a/public/img/front-pages/landing-page/team-member-2.png b/public/img/front-pages/landing-page/team-member-2.png new file mode 100644 index 00000000..b1b7e7c0 Binary files /dev/null and b/public/img/front-pages/landing-page/team-member-2.png differ diff --git a/public/img/front-pages/landing-page/team-member-3.png b/public/img/front-pages/landing-page/team-member-3.png new file mode 100644 index 00000000..805b2825 Binary files /dev/null and b/public/img/front-pages/landing-page/team-member-3.png differ diff --git a/public/img/front-pages/landing-page/team-member-4.png b/public/img/front-pages/landing-page/team-member-4.png new file mode 100644 index 00000000..8718f3c1 Binary files /dev/null and b/public/img/front-pages/landing-page/team-member-4.png differ diff --git a/public/img/front-pages/misc/checkout-image.png b/public/img/front-pages/misc/checkout-image.png new file mode 100644 index 00000000..720bfc48 Binary files /dev/null and b/public/img/front-pages/misc/checkout-image.png differ diff --git a/public/img/front-pages/misc/nav-item-col-img.png b/public/img/front-pages/misc/nav-item-col-img.png new file mode 100644 index 00000000..5e51e3be Binary files /dev/null and b/public/img/front-pages/misc/nav-item-col-img.png differ diff --git a/public/img/front-pages/misc/product-image.png b/public/img/front-pages/misc/product-image.png new file mode 100644 index 00000000..25f511b9 Binary files /dev/null and b/public/img/front-pages/misc/product-image.png differ diff --git a/public/img/illustrations/girl-unlock-password-light.png b/public/img/illustrations/girl-unlock-password-light.png new file mode 100644 index 00000000..18f4b274 Binary files /dev/null and b/public/img/illustrations/girl-unlock-password-light.png differ diff --git a/public/img/illustrations/registration.jpg b/public/img/illustrations/registration.jpg new file mode 100644 index 00000000..69cf7b8e Binary files /dev/null and b/public/img/illustrations/registration.jpg differ diff --git a/public/img/illustrations/worker_01.svg b/public/img/illustrations/worker_01.svg new file mode 100644 index 00000000..2170c2f4 --- /dev/null +++ b/public/img/illustrations/worker_01.svg @@ -0,0 +1,4955 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/img/illustrations/worker_02.jpg b/public/img/illustrations/worker_02.jpg new file mode 100644 index 00000000..274c55c3 Binary files /dev/null and b/public/img/illustrations/worker_02.jpg differ diff --git a/public/img/illustrations/worker_02.svg b/public/img/illustrations/worker_02.svg new file mode 100644 index 00000000..c673e01c --- /dev/null +++ b/public/img/illustrations/worker_02.svg @@ -0,0 +1,1117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/img/illustrations/worker_03.jpg b/public/img/illustrations/worker_03.jpg new file mode 100644 index 00000000..99c9be24 Binary files /dev/null and b/public/img/illustrations/worker_03.jpg differ diff --git a/public/img/illustrations/worker_03.png b/public/img/illustrations/worker_03.png new file mode 100644 index 00000000..d5fdab98 Binary files /dev/null and b/public/img/illustrations/worker_03.png differ diff --git a/public/img/illustrations/worker_03.svg b/public/img/illustrations/worker_03.svg new file mode 100644 index 00000000..ee552ecf --- /dev/null +++ b/public/img/illustrations/worker_03.svg @@ -0,0 +1,383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/Activities/Attendance.jsx b/src/components/Activities/Attendance.jsx index eb7dc500..6d751b12 100644 --- a/src/components/Activities/Attendance.jsx +++ b/src/components/Activities/Attendance.jsx @@ -114,7 +114,10 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => { return ( <> -
+
Date : {formatUTCToLocalTime(todayDate)}
@@ -209,7 +212,11 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => { ))} {!attendance && ( - No employees assigned to the project! + + + No employees assigned to the project! + + )} @@ -258,7 +265,10 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => { )} ) : ( -
+
{searchTerm ? "No results found for your search." : attendanceList.length === 0 diff --git a/src/components/Activities/AttendcesLogs.jsx b/src/components/Activities/AttendcesLogs.jsx index 681783be..faf4bdc5 100644 --- a/src/components/Activities/AttendcesLogs.jsx +++ b/src/components/Activities/AttendcesLogs.jsx @@ -42,7 +42,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => { const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" }); const dispatch = useDispatch(); const [loading, setLoading] = useState(false); - const [showPending,setShowPending] = useState(false) + const [showPending, setShowPending] = useState(false) const [isRefreshing, setIsRefreshing] = useState(false); const [processedData, setProcessedData] = useState([]); @@ -245,17 +245,16 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
refetch()} />
-
+
{isLoading ? ( -
+

Loading...

) : filteredSearchData?.length > 0 ? ( @@ -284,9 +283,9 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => { const previousAttendance = arr[index - 1]; const previousDate = previousAttendance ? moment( - previousAttendance.checkInTime || - previousAttendance.checkOutTime - ).format("YYYY-MM-DD") + previousAttendance.checkInTime || + previousAttendance.checkOutTime + ).format("YYYY-MM-DD") : null; if (!previousDate || currentDate !== previousDate) { @@ -346,12 +345,15 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => { ) : ( -
No Record Available !
+
No Record Available !
)}
{paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && ( -
- No Pending Record Available ! +
+ No Record Available !
)} {filteredSearchData.length > ITEMS_PER_PAGE && ( @@ -369,9 +371,8 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => { (pageNumber) => (
  • +
    +
    ); diff --git a/src/components/Activities/Regularization.jsx b/src/components/Activities/Regularization.jsx index cdcd3972..82c906b5 100644 --- a/src/components/Activities/Regularization.jsx +++ b/src/components/Activities/Regularization.jsx @@ -87,9 +87,9 @@ const Regularization = ({ handleRequest, searchTerm }) => { }, [employeeHandler]); return ( -
    +
    {loading ? ( -
    +

    Loading...

    ) : currentItems?.length > 0 ? ( @@ -143,9 +143,14 @@ const Regularization = ({ handleRequest, searchTerm }) => { ) : ( -
    +
    - {searchTerm ? "No results found for your search." : "No Requests Found !"} + {searchTerm + ? "No results found for your search." + : "No Requests Found !"}
    )} @@ -163,9 +168,8 @@ const Regularization = ({ handleRequest, searchTerm }) => { {[...Array(totalPages)].map((_, index) => (
  • ))}
  • -
    - +
    + +
    ); }; - export default ReportTask; \ No newline at end of file +export default ReportTask; \ No newline at end of file diff --git a/src/components/Activities/ReportTaskComments.jsx b/src/components/Activities/ReportTaskComments.jsx index c48f9796..60a81ff3 100644 --- a/src/components/Activities/ReportTaskComments.jsx +++ b/src/components/Activities/ReportTaskComments.jsx @@ -10,6 +10,7 @@ import { getBgClassFromHash } from "../../utils/projectStatus"; import { cacheData, getCachedData } from "../../slices/apiDataManager"; import ImagePreview from "../common/ImagePreview"; import { useAuditStatus, useSubmitTaskComment } from "../../hooks/useTasks"; +import Label from "../common/Label"; const ReportTaskComments = ({ commentsData, @@ -291,10 +292,10 @@ const ReportTaskComments = ({

    )}
    -
    -
    + return ( +
    + {/* Header */} +
    +
    +
    Attendance Overview
    +

    Role-wise present count

    +
    +
    + + + +
    +
    {/* Content */}
    diff --git a/src/components/Dashboard/ProjectCompletionChart.jsx b/src/components/Dashboard/ProjectCompletionChart.jsx index f0c85179..8ce4b13a 100644 --- a/src/components/Dashboard/ProjectCompletionChart.jsx +++ b/src/components/Dashboard/ProjectCompletionChart.jsx @@ -19,7 +19,7 @@ const ProjectCompletionChart = () => {
    -
    Projects
    +
    Projects

    Projects Completion Status

    diff --git a/src/components/Dashboard/ProjectProgressChart.jsx b/src/components/Dashboard/ProjectProgressChart.jsx index f80bb0d5..61747f6c 100644 --- a/src/components/Dashboard/ProjectProgressChart.jsx +++ b/src/components/Dashboard/ProjectProgressChart.jsx @@ -90,7 +90,7 @@ const ProjectProgressChart = ({
    {/* Left: Title */}
    -
    Project Progress
    +
    Project Progress

    Progress Overview by Project

    diff --git a/src/components/Directory/ManageBucket.jsx b/src/components/Directory/ManageBucket.jsx index 7b8f2832..63125a14 100644 --- a/src/components/Directory/ManageBucket.jsx +++ b/src/components/Directory/ManageBucket.jsx @@ -208,23 +208,14 @@ const ManageBucket = () => { return ( <> {deleteBucket && ( -
    - setDeleteBucket(null)} - /> -
    + setDeleteBucket(null)} + /> )}
    diff --git a/src/components/Directory/ManageDirectory.jsx b/src/components/Directory/ManageDirectory.jsx index 1615c263..fa5e7a30 100644 --- a/src/components/Directory/ManageDirectory.jsx +++ b/src/components/Directory/ManageDirectory.jsx @@ -23,6 +23,7 @@ import { useProjects } from "../../hooks/useProjects"; import SelectMultiple from "../common/SelectMultiple"; import { ContactSchema } from "./DirectorySchema"; import InputSuggestions from "../common/InputSuggestion"; +import Label from "../common/Label"; const ManageDirectory = ({ submitContact, onCLosed }) => { const selectedMaster = useSelector( @@ -170,11 +171,11 @@ const ManageDirectory = ({ submitContact, onCLosed }) => {
    -
    Create New Contact
    +
    Create New Contact
    - + {
    - + {
    - + {
    {index === phoneFields.length - 1 ? ( {
    - +
      {bucketsLoaging &&

      Loading...

      } @@ -450,8 +453,8 @@ const ManageDirectory = ({ submitContact, onCLosed }) => { />
    -
    - +
    + + {errors.description && ( +
    {errors.description.message}
    + )} +
    + + {/* Buttons */} +
    + + +
    + + +
    + ); +}; + +export default ManageDocument; diff --git a/src/components/Documents/VersionListSkeleton.jsx b/src/components/Documents/VersionListSkeleton.jsx new file mode 100644 index 00000000..d239315c --- /dev/null +++ b/src/components/Documents/VersionListSkeleton.jsx @@ -0,0 +1,47 @@ +import React from "react"; + +const SkeletonLine = ({ height = 16, width = "100%", className = "" }) => ( +
    +); + +const VersionListSkeleton = ({ items = 5 }) => { + return ( +
    + {[...Array(items)].map((_, idx) => ( +
    + {/* Top row: document name + version/status */} +
    + +
    + + +
    +
    + + {/* Upload by row */} +
    + + +
    + + {/* Updated at row */} +
    + +
    +
    + ))} +
    + ); +}; + +export default VersionListSkeleton; diff --git a/src/components/Documents/ViewDocument.jsx b/src/components/Documents/ViewDocument.jsx new file mode 100644 index 00000000..6405a3ed --- /dev/null +++ b/src/components/Documents/ViewDocument.jsx @@ -0,0 +1,175 @@ +import React, { useState } from "react"; +import { + useDocumentDetails, + useDocumentVersionList, + useVerifyDocument, +} from "../../hooks/useDocument"; +import { getDocuementsStatus, useDocumentContext } from "./Documents"; +import { formatUTCToLocalTime } from "../../utils/dateUtils"; +import Avatar from "../common/Avatar"; +import { + DOWNLOAD_DOCUMENT, + ITEMS_PER_PAGE, + VERIFY_DOCUMENT, +} from "../../utils/constants"; +import DocumentDetailsSkeleton from "./DocumentDetailsSkeleton "; +import { useHasUserPermission } from "../../hooks/useHasUserPermission"; +import DocumentVersionList from "./DocumentVersionList"; + +const ViewDocument = () => { + const { viewDoc, setOpenDocument } = useDocumentContext(); + const [currentPage, setCurrentPage] = useState(1); + const [showVersions, setShowVersions] = useState(false); + const canVerifyDocument = useHasUserPermission(VERIFY_DOCUMENT); + + // Document Details + const { data, isLoading, isError, error } = useDocumentDetails( + viewDoc?.document + ); + + // Document Versions (fetch only if toggle is ON) + const { + data: versionList, + isLoading: versionLoading, + } = useDocumentVersionList( + showVersions ? data?.parentAttachmentId : null, + ITEMS_PER_PAGE - 10, + currentPage + ); + + const paginate = (page) => { + if (page >= 1 && page <= (versionList?.totalPages ?? 1)) { + setCurrentPage(page); + } + }; + + // Verify / Reject + const { mutate: VerifyDoc, isPending } = useVerifyDocument(); + const VerifyDocument = () => { + VerifyDoc({ documentId: viewDoc?.document, isVerify: true }); + }; + const RejectDocument = () => { + VerifyDoc({ documentId: viewDoc?.document, isVerify: false }); + }; + + if (isLoading) return ; + if (isError) + return ( +
    +

    {error?.response?.data?.message || error?.message}

    +

    {error?.response?.status}

    +
    + ); + + return ( +
    +

    Document Details

    + + {/* Document Info Rows */} +
    +
    + + Category: + + + {data.documentType?.documentCategory?.name || "-"} + +
    +
    + + Type: + + {data.documentType?.name || "-"} +
    +
    + +
    +
    + + Document Name: + + {data.name || "-"} +
    +
    + + Document ID: + + {data.documentId || "-"} +
    +
    + +
    +
    + + Uploaded At: + + + {formatUTCToLocalTime(data.uploadedAt)} + +
    + +
    + +
    +
    + + Tags: + +
    + {data.tags?.length > 0 ? ( + data.tags.map((t, i) => ( + + {t.name} + + )) + ) : ( + - + )} +
    +
    +
    + +
    +
    + + Description: + + {data.description || "-"} +
    +
    + + {/* Toggle for Versions */} +
    +

    Documents:

    +
    + + setShowVersions(e.target.checked)} + /> +
    +
    + + +
    + ); +}; + +export default ViewDocument; \ No newline at end of file diff --git a/src/components/Employee/EmpActivities.jsx b/src/components/Employee/EmpActivities.jsx index f5d9e8c2..e79b181d 100644 --- a/src/components/Employee/EmpActivities.jsx +++ b/src/components/Employee/EmpActivities.jsx @@ -25,7 +25,7 @@ error,
    diff --git a/src/components/Employee/EmpAttendance.jsx b/src/components/Employee/EmpAttendance.jsx index 26ae9531..dfa12e98 100644 --- a/src/components/Employee/EmpAttendance.jsx +++ b/src/components/Employee/EmpAttendance.jsx @@ -128,7 +128,7 @@ const EmpAttendance = ({ employee }) => { >
    diff --git a/src/components/Employee/EmpBanner.jsx b/src/components/Employee/EmpBanner.jsx index 6cb12073..bb019bc6 100644 --- a/src/components/Employee/EmpBanner.jsx +++ b/src/components/Employee/EmpBanner.jsx @@ -3,6 +3,7 @@ import React, { useState, useEffect } from "react"; import { useChangePassword } from "../../components/Context/ChangePasswordContext"; import GlobalModel from "../common/GlobalModel"; import ManageEmployee from "./ManageEmployee"; +import { formatUTCToLocalTime } from "../../utils/dateUtils"; const EmpBanner = ({ profile, loggedInUser }) => { const { openChangePassword } = useChangePassword(); @@ -77,7 +78,7 @@ const EmpBanner = ({ profile, loggedInUser }) => { {" "} Joined on{" "} {profile?.joiningDate ? ( - new Date(profile.joiningDate).toLocaleDateString() + formatUTCToLocalTime(profile.joiningDate) ) : ( NA )} diff --git a/src/components/Employee/EmpDashboard.jsx b/src/components/Employee/EmpDashboard.jsx index b25f6803..85c97836 100644 --- a/src/components/Employee/EmpDashboard.jsx +++ b/src/components/Employee/EmpDashboard.jsx @@ -9,7 +9,6 @@ const EmpDashboard = ({ profile }) => { refetch, } = useProjectsAllocationByEmployee(profile?.id); - console.log(projectList); return ( <>
    diff --git a/src/components/Employee/EmpDocuments.jsx b/src/components/Employee/EmpDocuments.jsx index 46aa33d0..b4c8046b 100644 --- a/src/components/Employee/EmpDocuments.jsx +++ b/src/components/Employee/EmpDocuments.jsx @@ -1,10 +1,15 @@ import React, { useState, useEffect } from "react"; import { ComingSoonPage } from "../../pages/Misc/ComingSoonPage"; +import DocumentPage from "../../pages/Documents/DocumentPage"; +import Documents from "../Documents/Documents"; +import { useParams } from "react-router-dom"; +import { DOCUMENTS_ENTITIES } from "../../utils/constants"; const EmpDocuments = ({ profile, loggedInUser }) => { + const {employeeId} = useParams() return ( <> - + ); }; diff --git a/src/components/Employee/EmpOverview.jsx b/src/components/Employee/EmpOverview.jsx index 6b396745..cf4ce4af 100644 --- a/src/components/Employee/EmpOverview.jsx +++ b/src/components/Employee/EmpOverview.jsx @@ -142,13 +142,14 @@ const EmpOverview = ({ profile }) => {
    {/* Address */} -
    - +
    + - Address + Address + : - + {profile?.currentAddress || NA}
    diff --git a/src/components/Employee/EmployeeList.jsx b/src/components/Employee/EmployeeList.jsx index 2ae93d5e..5a79c6ce 100644 --- a/src/components/Employee/EmployeeList.jsx +++ b/src/components/Employee/EmployeeList.jsx @@ -4,4 +4,4 @@ const EmployeeList = () => { return
    EmployeeList
    ; }; -export default EmployeeList; +export default EmployeeList; \ No newline at end of file diff --git a/src/components/Employee/EmployeeNav.jsx b/src/components/Employee/EmployeeNav.jsx index d9a6b3e0..8c25aa22 100644 --- a/src/components/Employee/EmployeeNav.jsx +++ b/src/components/Employee/EmployeeNav.jsx @@ -1,12 +1,31 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; +import { useHasUserPermission } from "../../hooks/useHasUserPermission"; +import { VIEW_DOCUMENT } from "../../utils/constants"; +import { useProfile } from "../../hooks/useProfile"; +import { useParams } from "react-router-dom"; const EmployeeNav = ({ onPillClick, activePill }) => { + const { employeeId } = useParams(); + const [isAbleToViewDocuments, setIsAbleToViewDocuments] = useState(false); + + const canViewDocuments = useHasUserPermission(VIEW_DOCUMENT); + const { profile } = useProfile(); + + useEffect(() => { + if (profile?.employeeInfo?.id) { + setIsAbleToViewDocuments(profile.employeeInfo.id === employeeId); + } + }, [profile?.employeeInfo?.id, employeeId]); + const tabs = [ { key: "profile", icon: "bx bx-user", label: "Profile" }, { key: "attendance", icon: "bx bx-group", label: "Attendances" }, - { key: "documents", icon: "bx bx-user", label: "Documents" }, + (isAbleToViewDocuments || canViewDocuments) && { + key: "documents", + icon: "bx bx-file", + label: "Documents", + }, { key: "activities", icon: "bx bx-grid-alt", label: "Activities" }, - ]; - + ].filter(Boolean); return (
    diff --git a/src/components/Employee/ManageEmployee.jsx b/src/components/Employee/ManageEmployee.jsx index 1805220b..81a4c4d2 100644 --- a/src/components/Employee/ManageEmployee.jsx +++ b/src/components/Employee/ManageEmployee.jsx @@ -17,6 +17,8 @@ import { } from "../../slices/apiDataManager"; import { clearApiCacheKey } from "../../slices/apiCacheSlice"; import { useMutation } from "@tanstack/react-query"; +import Label from "../common/Label"; +import DatePicker from "../common/DatePicker"; const mobileNumberRegex = /^[0-9]\d{9}$/; @@ -220,10 +222,10 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => { return ( <>
    -

    {employee ? "Update Employee" : "Create Employee"}

    +

    {employee ? "Update Employee" : "Create Employee"}

    -
    First Name
    + {
    -
    Last Name
    + { )}
    -
    Phone Number
    + {
    -
    Gender
    +
    + {errors.birthDate && ( -
    +
    {errors.birthDate.message}
    )}
    -
    Joining Date
    +
    -
    + {errors.joiningDate && ( -
    +
    {errors.joiningDate.message}
    )} @@ -412,7 +416,7 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
    -
    Current Address
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + + {/* Contact Us: End */} +
    + + {/* / Sections:End */} + + {/* Footer: Start */} + + {/* Footer: End */} +
    + ); +}; +export default LandingPage; diff --git a/src/pages/TermsAndConditions/LegalInfoCard.jsx b/src/pages/TermsAndConditions/LegalInfoCard.jsx index baa5d3da..cd7c9e05 100644 --- a/src/pages/TermsAndConditions/LegalInfoCard.jsx +++ b/src/pages/TermsAndConditions/LegalInfoCard.jsx @@ -4,25 +4,10 @@ const LegalInfoPage = () => { return ( <>
    MARCO SECURE SOLUTIONS @@ -41,7 +26,7 @@ const LegalInfoPage = () => { overflowY: 'auto', flexGrow: 1, - marginBottom: '2rem', // Adds space below the card + marginBottom: '2rem', }} >

    Terms & Conditions

    diff --git a/src/pages/authentication/AuthWrapper.jsx b/src/pages/authentication/AuthWrapper.jsx index c065bac2..5c8f0eb9 100644 --- a/src/pages/authentication/AuthWrapper.jsx +++ b/src/pages/authentication/AuthWrapper.jsx @@ -4,17 +4,17 @@ import "./page-auth.css"; export const AuthWrapper = ({ children }) => { return (
    -
    + {/*
    -
    +
    */}
    -
    +
    - + marco-logo { /> -
    + {/*
    */} {children}
    -
    -
    + //
    + //
    ); -}; +}; \ No newline at end of file diff --git a/src/pages/authentication/ForgotPasswordPage.jsx b/src/pages/authentication/ForgotPasswordPage.jsx index 508b7a56..8a6fc608 100644 --- a/src/pages/authentication/ForgotPasswordPage.jsx +++ b/src/pages/authentication/ForgotPasswordPage.jsx @@ -1,89 +1,88 @@ import { useState } from "react"; -import {Link} from "react-router-dom"; +import { Link } from "react-router-dom"; import { AuthWrapper } from "./AuthWrapper" import "./page-auth.css"; import AuthRepository from "../../repositories/AuthRepository"; import showToast from "../../services/toastService"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; -import {z} from "zod"; +import { z } from "zod"; -const forgotPassSceham = z.object( { +const forgotPassSceham = z.object({ email: z.string().email(), -} ) +}) const ForgotPasswordPage = () => { - const[loding,setLoading] = useState(false) + const [loding, setLoading] = useState(false) - const {register, + const { register, handleSubmit, formState: { errors }, reset, - getValues } = useForm( { - resolver: zodResolver( forgotPassSceham ), - defaultValues: { - email:"" - } - }) + getValues } = useForm({ + resolver: zodResolver(forgotPassSceham), + defaultValues: { + email: "" + } + }) - const onSubmit = async (data) => - { - try - { + const onSubmit = async (data) => { + try { setLoading(true) - const response = await AuthRepository.forgotPassword(data) - if ( response.data && response.success ) - showToast( "verification email has been sent to your registered email address", "success" ) + const response = await AuthRepository.forgotPassword(data) + if (response.data && response.success) + showToast("verification email has been sent to your registered email address", "success") reset() - setLoading( false ) - } catch ( err ) - { + setLoading(false) + } catch (err) { reset() - if(err.response.status === 404){ - showToast( "verification email has been sent to your registered email address", "success" ) - }else{ - showToast("Something wrong","error") - } - + if (err.response.status === 404) { + showToast("verification email has been sent to your registered email address", "success") + } else { + showToast("Something wrong", "error") + } + setLoading(false) } } return ( - -

    Forgot Password? 🔒

    -

    - Enter your email and we'll send you instructions to reset your password -

    -
    -
    - - - {errors.email && ( -
    - {errors.email.message} -
    - )} -
    - -
    -
    +
    +
    +

    Forgot Password? 🔒

    +

    + Enter your email and we'll send you instructions to reset your password +

    + +
    +
    + + + {errors.email && ( +
    + {errors.email.message} +
    + )} +
    + +
    +
    { Back to login
    - + + {/* Footer Text */} + +
    +
    ); }; -export default ForgotPasswordPage; +export default ForgotPasswordPage; \ No newline at end of file diff --git a/src/pages/authentication/LoginPage.jsx b/src/pages/authentication/LoginPage.jsx index 3f91e29a..9240e33d 100644 --- a/src/pages/authentication/LoginPage.jsx +++ b/src/pages/authentication/LoginPage.jsx @@ -1,70 +1,54 @@ import { useEffect, useState } from "react"; -import { Link } from "react-router-dom"; -import { AuthWrapper } from "./AuthWrapper"; -import { useNavigate } from "react-router-dom"; -import "./page-auth.css"; +import { Link, useNavigate } from "react-router-dom"; import AuthRepository from "../../repositories/AuthRepository"; import showToast from "../../services/toastService"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; +import { AuthWrapper } from "./AuthWrapper"; const LoginPage = () => { const navigate = useNavigate(); const [loading, setLoading] = useState(false); const [hidepass, setHidepass] = useState(true); const [IsLoginWithOTP, setLoginWithOtp] = useState(false); - const [IsTriedOTPThrough, setIsTriedOTPThrough] = useState(false); const now = Date.now(); const loginSchema = IsLoginWithOTP ? z.object({ - username: z.string() - .trim() - .email({ message: "Valid email required" }), - }) + username: z.string().email({ message: "Valid email required" }), + }) : z.object({ - username: z.string() - .trim() - .email({ message: "Valid email required" }), - password: z.string() - .trim() - .min(1, { message: "Password required" }), - rememberMe: z.boolean(), - }); + username: z.string().email({ message: "Valid email required" }), + password: z.string().min(1, { message: "Password required" }), + rememberMe: z.boolean(), + }); const { register, handleSubmit, formState: { errors }, - reset, - getValues, } = useForm({ resolver: zodResolver(loginSchema), }); const onSubmit = async (data) => { setLoading(true); - try { - const username = data.username.trim(); - const password = data.password?.trim(); - if (!IsLoginWithOTP) { const userCredential = { - username, - password, + username: data.username, + password: data.password, }; - const response = await AuthRepository.login(userCredential); localStorage.setItem("jwtToken", response.data.token); localStorage.setItem("refreshToken", response.data.refreshToken); setLoading(false); navigate("/dashboard"); } else { - await AuthRepository.sendOTP({ email: username }); + await AuthRepository.sendOTP({ email: data.username }); showToast("OTP has been sent to your email.", "success"); - localStorage.setItem("otpUsername", username); + localStorage.setItem("otpUsername", data.username); localStorage.setItem("otpSentTime", now.toString()); navigate("/auth/login-otp"); } @@ -74,7 +58,6 @@ const LoginPage = () => { } }; - useEffect(() => { const otpSentTime = localStorage.getItem("otpSentTime"); if ( @@ -85,138 +68,150 @@ const LoginPage = () => { navigate("/auth/login-otp"); } }, [IsLoginWithOTP]); + return ( - -

    Welcome to PMS!

    -

    - {IsLoginWithOTP - ? "Enter your email to receive a one-time password (OTP)." - : "Please sign-in to your account and start the adventure."} -

    -
    -
    - - - {errors.username && ( -
    - {errors.username.message} -
    - )} -
    +
    +
    +

    Welcome to PMS!

    +

    + {IsLoginWithOTP + ? "Enter your email to receive a one-time password (OTP)." + : "Please sign in to your account and start the adventure"} +

    - {!IsLoginWithOTP && ( - <> -
    - -
    - - + + {/* Email */} +
    + + + {errors.username && ( +
    + {errors.username.message}
    - {errors.password && ( -
    - {errors.password.message} -
    - )} -
    + )} +
    - -
    -
    - - -
    - Forgot Password? -
    - - )} - -
    - - {!IsLoginWithOTP &&
    OR
    } + {/* Password */} {!IsLoginWithOTP && ( - - )} -
    - + <> +
    + +
    + + setHidepass(!hidepass)} + > + + +
    + {errors.password && ( +
    + {errors.password.message} +
    + )} +
    -

    - New on our platform? - {IsLoginWithOTP ? ( - setLoginWithOtp(false)} + {/* Remember Me + Forgot Password */} +

    + + )} + + {/* Submit */} + + + {/* Login With OTP Button */} + {!IsLoginWithOTP && ( + <> +
    +
    or
    +
    + + + )} + + + {/* Footer Text */} + {!IsLoginWithOTP ? ( +

    + New on our platform? + + Request a Demo + +

    ) : ( - - Request a Demo - +
    + +
    )} -

    - +
    +
    ); }; -export default LoginPage; +export default LoginPage; \ No newline at end of file diff --git a/src/pages/authentication/LoginWithOtp.jsx b/src/pages/authentication/LoginWithOtp.jsx index 2157b4e1..8b07f8fb 100644 --- a/src/pages/authentication/LoginWithOtp.jsx +++ b/src/pages/authentication/LoginWithOtp.jsx @@ -52,7 +52,7 @@ const LoginWithOtp = () => { setLoading(false); localStorage.removeItem("otpUsername"); localStorage.removeItem("otpSentTime"); - navigate("/dashboard"); + navigate("/dashboard"); } catch (err) { showToast("Invalid or expired OTP.", "error"); @@ -123,8 +123,9 @@ const LoginWithOtp = () => { return ( - -
    + // +
    +

    Verify Your OTP

    Please enter the 4-digit code sent to your email.

    @@ -209,8 +210,9 @@ const LoginWithOtp = () => { )} +
    -
    + // ); }; diff --git a/src/pages/authentication/MainForgetPage.jsx b/src/pages/authentication/MainForgetPage.jsx new file mode 100644 index 00000000..caae1016 --- /dev/null +++ b/src/pages/authentication/MainForgetPage.jsx @@ -0,0 +1,26 @@ +import React from "react"; +// import LoginPage from "./LoginPage"; +import ForgotPasswordPage from "./ForgotPasswordPage"; + +const MainForgetPage = () => { + return ( + <> +
    +
    +
    + Login image +
    +
    + +
    + + ); +}; +export default MainForgetPage; diff --git a/src/pages/authentication/MainLogin.jsx b/src/pages/authentication/MainLogin.jsx new file mode 100644 index 00000000..03575f40 --- /dev/null +++ b/src/pages/authentication/MainLogin.jsx @@ -0,0 +1,24 @@ +import React from "react"; +import LoginPage from "./LoginPage"; +const MainLogin = () => { + return ( + <> +
    +
    +
    + Login image +
    +
    + +
    + + ); +}; +export default MainLogin; diff --git a/src/pages/authentication/MainLoginWithOTPPage.jsx b/src/pages/authentication/MainLoginWithOTPPage.jsx new file mode 100644 index 00000000..53b9fec7 --- /dev/null +++ b/src/pages/authentication/MainLoginWithOTPPage.jsx @@ -0,0 +1,26 @@ +import React from 'react' +import LoginWithOtp from './LoginWithOtp' + +const MainLoginWithOTPPage = () => { + return ( + <> +
    +
    +
    + Login image +
    +
    + +
    + + ) +} + +export default MainLoginWithOTPPage \ No newline at end of file diff --git a/src/pages/authentication/MainRegisterPage.jsx b/src/pages/authentication/MainRegisterPage.jsx new file mode 100644 index 00000000..a2a1a5ca --- /dev/null +++ b/src/pages/authentication/MainRegisterPage.jsx @@ -0,0 +1,25 @@ +import React from "react"; +import RegisterPage from "./RegisterPage"; + +const MainRegisterPage = () => { + return ( + <> +
    +
    +
    + Login image +
    +
    + +
    + + ); +}; +export default MainRegisterPage; diff --git a/src/pages/authentication/MainResetPasswordPage.jsx b/src/pages/authentication/MainResetPasswordPage.jsx new file mode 100644 index 00000000..36fd71e6 --- /dev/null +++ b/src/pages/authentication/MainResetPasswordPage.jsx @@ -0,0 +1,26 @@ +import React from 'react' +import ResetPasswordPage from './ResetPassword' + +const MainResetPasswordPage = () => { + return ( + <> +
    +
    +
    + Login image +
    +
    + +
    + + ) +} + +export default MainResetPasswordPage \ No newline at end of file diff --git a/src/pages/authentication/RegisterPage.jsx b/src/pages/authentication/RegisterPage.jsx index 16517816..65b7d619 100644 --- a/src/pages/authentication/RegisterPage.jsx +++ b/src/pages/authentication/RegisterPage.jsx @@ -37,28 +37,33 @@ const registerSchema = z.object({ const RegisterPage = () => { const [registered, setRegristered] = useState(false); const [industries, setIndustries] = useState([]); + const [Loading,setLoading] = useState(false) const { register, handleSubmit, - formState: { errors }, + formState: { errors },reset } = useForm({ resolver: zodResolver(registerSchema), }); const onSubmit = async (data) => { try { + setLoading(true) const response = await MarketRepository.requestDemo(data); - showToast("Your Registration SuccessFully !"); + showToast("Your request has been sent successfully. Please stay in touch!"); setRegristered(true); + setLoading(false) + reset() } catch (error) { showToast(error.message, "error"); + setLoading(false) } }; useEffect(() => { fetchIndustries(); }, []); - useEffect(() => {}, [industries]); + useEffect(() => { }, [industries]); const fetchIndustries = async () => { try { @@ -71,23 +76,27 @@ const RegisterPage = () => { }; return ( <> - {!registered && ( - -

    Adventure starts here 🚀

    + +
    +
    + +

    Adventure starts here

    Make your app management easy and fun!

    -
    + +
    +
    {
    )}
    -
    +
    {
    )}
    -
    +
    +
    -
    -
    {errors.contactPerson && (
    {
    )}
    -
    +
    -
    -
    {errors.contactNumber && (
    {
    )}
    -
    +
    -
    -
    {errors.about && (
    {
    )}
    -
    +
    -
    -
    {errors.oragnizationSize && (
    {
    )}
    -
    +
    -
    -
    {errors.industryId && (
    {
    )}
    -
    +
    { {...register("terms")} /> +
    {errors.terms && (
    { )}

    - Already have an account? + Already have an account? - + Back to login

    - - )} - {registered && ( - -
    Thank you for contacting us
    -

    We will get back to you soon

    - - - Back to login - -
    - )} +
    +
    ); }; -export default RegisterPage; +export default RegisterPage; \ No newline at end of file diff --git a/src/pages/authentication/ResetPasswordPage.jsx b/src/pages/authentication/ResetPassword.jsx similarity index 94% rename from src/pages/authentication/ResetPasswordPage.jsx rename to src/pages/authentication/ResetPassword.jsx index 21b03df0..9c7ab0d2 100644 --- a/src/pages/authentication/ResetPasswordPage.jsx +++ b/src/pages/authentication/ResetPassword.jsx @@ -33,7 +33,7 @@ const resetPasswordSchema = z path: ["confirmPassword"], }); -const ResetPasswordPage = () => { +const ResetPassword = () => { const [searchParams] = useSearchParams(); const [loading, setLoading] = useState(false); const [hidepass, setHidepass] = useState(true); @@ -67,7 +67,6 @@ const ResetPasswordPage = () => { navigate("/auth/login", { replace: true }); // setLoading(false); } catch (error) { - debugger; setLoading(false); if (error?.response?.status === 400) { showToast("Please check valid Credentials", "error"); @@ -94,7 +93,8 @@ const ResetPasswordPage = () => { ); } return ( - +
    +

    Reset Password? 🔒

    Enter your email and new password to update.

    { className="mb-3" onSubmit={handleSubmit(onSubmitResetPassword)} > -
    +
    @@ -124,9 +124,9 @@ const ResetPasswordPage = () => { )}
    -
    +
    -
    @@ -238,8 +238,9 @@ const ResetPasswordPage = () => { Back to login
    - +
    +
    ); }; -export default ResetPasswordPage; +export default ResetPassword; diff --git a/src/pages/authentication/page-auth.css b/src/pages/authentication/page-auth.css index 86ceb214..8492495b 100644 --- a/src/pages/authentication/page-auth.css +++ b/src/pages/authentication/page-auth.css @@ -18,6 +18,7 @@ } .authentication-wrapper.authentication-cover .authentication-inner { height: 100vh; + background-color: #fff; } .authentication-wrapper.authentication-basic .authentication-inner { max-width: 400px; diff --git a/src/pages/employee/EmployeeList.jsx b/src/pages/employee/EmployeeList.jsx index 5cd7ab2d..ca58f018 100644 --- a/src/pages/employee/EmployeeList.jsx +++ b/src/pages/employee/EmployeeList.jsx @@ -79,11 +79,11 @@ const EmployeeList = () => { } ); - useEffect(() => { - if (selectedProjectId === null) { - dispatch(setProjectId(projectNames[0]?.id)); - } - }, [selectedProjectId]); +useEffect(() => { + if (!selectedProjectId && projectNames?.length > 0) { + dispatch(setProjectId(projectNames[0].id)); + } +}, [selectedProjectId, projectNames, dispatch]); const navigate = useNavigate(); const applySearchFilter = (data, text) => { @@ -177,10 +177,12 @@ const EmployeeList = () => { useEffect(() => { if (!loading && Array.isArray(employees)) { const sorted = [...employees].sort((a, b) => { - const nameA = `${a.firstName || ""}${a.middleName || ""}${a.lastName || "" - }`.toLowerCase(); - const nameB = `${b.firstName || ""}${b.middleName || ""}${b.lastName || "" - }`.toLowerCase(); + const nameA = `${a.firstName || ""}${a.middleName || ""}${ + a.lastName || "" + }`.toLowerCase(); + const nameB = `${b.firstName || ""}${b.middleName || ""}${ + b.lastName || "" + }`.toLowerCase(); return nameA?.localeCompare(nameB); }); @@ -278,8 +280,9 @@ const EmployeeList = () => { ? "Suspend Employee" : "Reactivate Employee" } - message={`Are you sure you want to ${selectedEmpFordelete?.isActive ? "suspend" : "reactivate" - } this employee?`} + message={`Are you sure you want to ${ + selectedEmpFordelete?.isActive ? "suspend" : "reactivate" + } this employee?`} onSubmit={() => suspendEmployee({ employeeId: selectedEmpFordelete.id, @@ -511,8 +514,9 @@ const EmployeeList = () => { Status { )} {/* Conditional messages for no data or no search results */} {!loading && - displayData?.length === 0 && - searchText && - !showAllEmployees ? ( + displayData?.length === 0 && + searchText && + !showAllEmployees ? ( @@ -544,14 +548,14 @@ const EmployeeList = () => { ) : null} {!loading && - displayData?.length === 0 && - (!searchText || showAllEmployees) ? ( + displayData?.length === 0 && + (!searchText || showAllEmployees) ? ( - No Data Found + No team members assigned yet ) : null} @@ -570,7 +574,9 @@ const EmployeeList = () => {
    - navigate(`/employee/${item.id}`) + navigate( + `/employee/${item.id}?for=attendance` + ) } className="text-heading text-truncate cursor-pointer" > @@ -606,9 +612,10 @@ const EmployeeList = () => { {item.jobRole || "Not Assign Yet"} - - {moment(item.joiningDate)?.format("DD-MMM-YYYY")} + {item.joiningDate + ? moment(item.joiningDate).format("DD-MMM-YYYY") + : "NA"} {showInactive ? ( @@ -637,56 +644,47 @@ const EmployeeList = () => {
    - {/* View always visible */} - - {/* If ACTIVE employee */} - {item.isActive && ( + + {!item.isSystem && ( <> - - {/* Suspend only when active */} - {item.isActive && ( - - )} - - )} - - {/* If INACTIVE employee AND inactive toggle is ON */} - {!item.isActive && showInactive && ( - - )}
    @@ -703,8 +701,9 @@ const EmployeeList = () => {