diff --git a/public/assets/css/core-extend.css b/public/assets/css/core-extend.css index ae7c4205..3b5619a2 100644 --- a/public/assets/css/core-extend.css +++ b/public/assets/css/core-extend.css @@ -5,8 +5,13 @@ } .offcanvas.offcanvas-wide { width: 700px !important; /* adjust as needed */ - max-width: 90vw; /* responsive fallback */ } +.sticky-section { + position: sticky; + top: var(--sticky-top, 0px) !important; + z-index: 1025; +} + /* ===========================% Background_Colors %========================================================== */ .bg-light-primary { @@ -451,3 +456,8 @@ font-weight: normal; .fs-md-xlarge { font-size: 170% !important; } .fs-md-xxlarge { font-size: calc(1.725rem + 5.7vw) !important; } } + +.me-16 { + /* margin-inline-end: -7.0625rem !important; */ + margin-left: -7.0625rem !important; +} diff --git a/public/assets/vendor/css/core.css b/public/assets/vendor/css/core.css index 48163eb5..f440443e 100644 --- a/public/assets/vendor/css/core.css +++ b/public/assets/vendor/css/core.css @@ -76,6 +76,7 @@ --bs-dark-border-subtle: #bfc0c6; --bs-white-rgb: 255, 255, 255; --bs-black-rgb: 34, 48, 62; + --bs-font-roboto:"Segoe UI", Roboto, "sans-serif", --bs-font-sans-serif: "Public Sans", -apple-system, blinkmacsystemfont, "Segoe UI", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; @@ -88,7 +89,7 @@ ); --bs-root-font-size: 16px; --bs-body-font-family: var(--bs-font-sans-serif); - --bs-body-font-size: 0.8375rem; + --bs-body-font-size: 0.875rem; --bs-body-font-weight: 400; --bs-body-line-height: 1.375; --bs-body-color: #646e78; diff --git a/public/img/app/error in filter of expenses .png b/public/img/app/error in filter of expenses .png deleted file mode 100644 index ee2034bb..00000000 Binary files a/public/img/app/error in filter of expenses .png and /dev/null differ diff --git a/public/img/app/should be expense category .png b/public/img/app/should be expense category .png deleted file mode 100644 index 5e7e36e0..00000000 Binary files a/public/img/app/should be expense category .png and /dev/null differ diff --git a/public/img/avatars/1.png b/public/img/avatars/1.png deleted file mode 100644 index 02ffed82..00000000 Binary files a/public/img/avatars/1.png and /dev/null differ diff --git a/public/img/avatars/5.png b/public/img/avatars/5.png deleted file mode 100644 index 649f9ec0..00000000 Binary files a/public/img/avatars/5.png and /dev/null differ diff --git a/public/img/avatars/6.png b/public/img/avatars/6.png deleted file mode 100644 index 99ad3a60..00000000 Binary files a/public/img/avatars/6.png and /dev/null differ diff --git a/public/img/avatars/7.png b/public/img/avatars/7.png deleted file mode 100644 index 335a7417..00000000 Binary files a/public/img/avatars/7.png and /dev/null differ diff --git a/public/img/brand/logo-1.png b/public/img/brand/logo-1.png deleted file mode 100644 index 7f551d70..00000000 Binary files a/public/img/brand/logo-1.png and /dev/null differ diff --git a/public/img/brand/logo-2.png b/public/img/brand/logo-2.png deleted file mode 100644 index 5e3f2698..00000000 Binary files a/public/img/brand/logo-2.png and /dev/null differ diff --git a/public/img/brand/logo-3.png b/public/img/brand/logo-3.png deleted file mode 100644 index e854e939..00000000 Binary files a/public/img/brand/logo-3.png and /dev/null differ diff --git a/public/img/brand/logo-4.png b/public/img/brand/logo-4.png deleted file mode 100644 index 6c5d3f3c..00000000 Binary files a/public/img/brand/logo-4.png and /dev/null differ diff --git a/public/img/brand/logo-5.png b/public/img/brand/logo-5.png deleted file mode 100644 index bf3cc14e..00000000 Binary files a/public/img/brand/logo-5.png and /dev/null differ diff --git a/public/img/brand/logo-6.png b/public/img/brand/logo-6.png deleted file mode 100644 index 99980b2a..00000000 Binary files a/public/img/brand/logo-6.png and /dev/null differ diff --git a/public/img/brand/logo_1-dark.png b/public/img/brand/logo_1-dark.png deleted file mode 100644 index cb1a58d2..00000000 Binary files a/public/img/brand/logo_1-dark.png and /dev/null differ diff --git a/public/img/brand/logo_1-light.png b/public/img/brand/logo_1-light.png deleted file mode 100644 index e0308e90..00000000 Binary files a/public/img/brand/logo_1-light.png and /dev/null differ diff --git a/public/img/brand/logo_2-dark.png b/public/img/brand/logo_2-dark.png deleted file mode 100644 index f5e92478..00000000 Binary files a/public/img/brand/logo_2-dark.png and /dev/null differ diff --git a/public/img/brand/logo_2-light.png b/public/img/brand/logo_2-light.png deleted file mode 100644 index 719e6103..00000000 Binary files a/public/img/brand/logo_2-light.png and /dev/null differ diff --git a/public/img/brand/logo_3-dark.png b/public/img/brand/logo_3-dark.png deleted file mode 100644 index 27c68e49..00000000 Binary files a/public/img/brand/logo_3-dark.png and /dev/null differ diff --git a/public/img/brand/logo_3-light.png b/public/img/brand/logo_3-light.png deleted file mode 100644 index 5ec4f174..00000000 Binary files a/public/img/brand/logo_3-light.png and /dev/null differ diff --git a/public/img/brand/logo_4-dark.png b/public/img/brand/logo_4-dark.png deleted file mode 100644 index 3e5bfc3d..00000000 Binary files a/public/img/brand/logo_4-dark.png and /dev/null differ diff --git a/public/img/brand/logo_4-light.png b/public/img/brand/logo_4-light.png deleted file mode 100644 index 0929f535..00000000 Binary files a/public/img/brand/logo_4-light.png and /dev/null differ diff --git a/public/img/brand/logo_5-dark.png b/public/img/brand/logo_5-dark.png deleted file mode 100644 index 34342001..00000000 Binary files a/public/img/brand/logo_5-dark.png and /dev/null differ diff --git a/public/img/brand/logo_5-light.png b/public/img/brand/logo_5-light.png deleted file mode 100644 index deb1071f..00000000 Binary files a/public/img/brand/logo_5-light.png and /dev/null differ diff --git a/public/img/brand/ofw-500x500.png b/public/img/brand/ofw-500x500.png new file mode 100644 index 00000000..4e8c3112 Binary files /dev/null and b/public/img/brand/ofw-500x500.png differ diff --git a/public/img/elements/1.jpg b/public/img/elements/1.jpg deleted file mode 100644 index 779350ea..00000000 Binary files a/public/img/elements/1.jpg and /dev/null differ diff --git a/public/img/elements/11.jpg b/public/img/elements/11.jpg deleted file mode 100644 index 30f1d630..00000000 Binary files a/public/img/elements/11.jpg and /dev/null differ diff --git a/public/img/elements/12.jpg b/public/img/elements/12.jpg deleted file mode 100644 index e7347643..00000000 Binary files a/public/img/elements/12.jpg and /dev/null differ diff --git a/public/img/elements/13.jpg b/public/img/elements/13.jpg deleted file mode 100644 index 5b19ce51..00000000 Binary files a/public/img/elements/13.jpg and /dev/null differ diff --git a/public/img/elements/17.jpg b/public/img/elements/17.jpg deleted file mode 100644 index 2004cda1..00000000 Binary files a/public/img/elements/17.jpg and /dev/null differ diff --git a/public/img/elements/18.jpg b/public/img/elements/18.jpg deleted file mode 100644 index 46af1552..00000000 Binary files a/public/img/elements/18.jpg and /dev/null differ diff --git a/public/img/elements/19.jpg b/public/img/elements/19.jpg deleted file mode 100644 index cae34490..00000000 Binary files a/public/img/elements/19.jpg and /dev/null differ diff --git a/public/img/elements/2.jpg b/public/img/elements/2.jpg deleted file mode 100644 index 78bc4d8e..00000000 Binary files a/public/img/elements/2.jpg and /dev/null differ diff --git a/public/img/elements/20.jpg b/public/img/elements/20.jpg deleted file mode 100644 index 1d7fb7c2..00000000 Binary files a/public/img/elements/20.jpg and /dev/null differ diff --git a/public/img/elements/3.jpg b/public/img/elements/3.jpg deleted file mode 100644 index f34f3de6..00000000 Binary files a/public/img/elements/3.jpg and /dev/null differ diff --git a/public/img/elements/4.jpg b/public/img/elements/4.jpg deleted file mode 100644 index 48432005..00000000 Binary files a/public/img/elements/4.jpg and /dev/null differ diff --git a/public/img/elements/5.jpg b/public/img/elements/5.jpg deleted file mode 100644 index 29714f59..00000000 Binary files a/public/img/elements/5.jpg and /dev/null differ diff --git a/public/img/elements/7.jpg b/public/img/elements/7.jpg deleted file mode 100644 index 01a42a51..00000000 Binary files a/public/img/elements/7.jpg and /dev/null differ diff --git a/public/img/hero/bg-01.jpg b/public/img/hero/bg-01.jpg new file mode 100644 index 00000000..0ea8eebf Binary files /dev/null and b/public/img/hero/bg-01.jpg differ diff --git a/public/img/hero/bg-02.png b/public/img/hero/bg-02.png new file mode 100644 index 00000000..e6acaea7 Binary files /dev/null and b/public/img/hero/bg-02.png differ diff --git a/public/img/hero/bg-03.png b/public/img/hero/bg-03.png new file mode 100644 index 00000000..622a1104 Binary files /dev/null and b/public/img/hero/bg-03.png differ diff --git a/public/img/hero/bg-04.png b/public/img/hero/bg-04.png new file mode 100644 index 00000000..988f506f Binary files /dev/null and b/public/img/hero/bg-04.png differ diff --git a/public/img/images/contact-customer-service.png b/public/img/hero/contact-customer-service.png similarity index 100% rename from public/img/images/contact-customer-service.png rename to public/img/hero/contact-customer-service.png diff --git a/public/img/icons/ai.png b/public/img/icons/ai.png new file mode 100644 index 00000000..bf9b1f11 Binary files /dev/null and b/public/img/icons/ai.png differ diff --git a/public/img/icons/apple-icon-lite.png b/public/img/icons/apple-icon-lite.png new file mode 100644 index 00000000..2654c2d3 Binary files /dev/null and b/public/img/icons/apple-icon-lite.png differ diff --git a/public/img/icons/attendance.png b/public/img/icons/attendance.png new file mode 100644 index 00000000..ea2460b6 Binary files /dev/null and b/public/img/icons/attendance.png differ diff --git a/public/img/icons/cloud-service.png b/public/img/icons/cloud-service.png new file mode 100644 index 00000000..de9dd0ac Binary files /dev/null and b/public/img/icons/cloud-service.png differ diff --git a/public/img/icons/dashboard.png b/public/img/icons/dashboard.png new file mode 100644 index 00000000..5d62aef8 Binary files /dev/null and b/public/img/icons/dashboard.png differ diff --git a/public/img/icons/directory.png b/public/img/icons/directory.png new file mode 100644 index 00000000..038852cd Binary files /dev/null and b/public/img/icons/directory.png differ diff --git a/public/img/icons/document.png b/public/img/icons/document.png new file mode 100644 index 00000000..aec11224 Binary files /dev/null and b/public/img/icons/document.png differ diff --git a/public/img/icons/google-play-icon-lite.png b/public/img/icons/google-play-icon-lite.png new file mode 100644 index 00000000..6952cb9f Binary files /dev/null and b/public/img/icons/google-play-icon-lite.png differ diff --git a/public/img/icons/google-play-icon.png b/public/img/icons/google-play-icon.png index 1365ff35..117bcb16 100644 Binary files a/public/img/icons/google-play-icon.png and b/public/img/icons/google-play-icon.png differ diff --git a/public/img/icons/profile.png b/public/img/icons/profile.png new file mode 100644 index 00000000..8333da3a Binary files /dev/null and b/public/img/icons/profile.png differ diff --git a/public/img/icons/report.png b/public/img/icons/report.png new file mode 100644 index 00000000..62b6682c Binary files /dev/null and b/public/img/icons/report.png differ diff --git a/public/img/icons/spending.png b/public/img/icons/spending.png new file mode 100644 index 00000000..aaf8d53c Binary files /dev/null and b/public/img/icons/spending.png differ diff --git a/public/img/illustrations/02.png b/public/img/illustrations/02.png deleted file mode 100644 index dba19e98..00000000 Binary files a/public/img/illustrations/02.png and /dev/null differ diff --git a/public/img/illustrations/03.png b/public/img/illustrations/03.png index 45d19881..8d517756 100644 Binary files a/public/img/illustrations/03.png and b/public/img/illustrations/03.png differ diff --git a/public/img/illustrations/contact-customer-service.png b/public/img/illustrations/contact-customer-service.png new file mode 100644 index 00000000..4e5aaaad Binary files /dev/null and b/public/img/illustrations/contact-customer-service.png differ diff --git a/public/img/illustrations/contact-us.png b/public/img/illustrations/contact-us.png new file mode 100644 index 00000000..4886aca8 Binary files /dev/null and b/public/img/illustrations/contact-us.png differ diff --git a/public/img/illustrations/fm-01.png b/public/img/illustrations/fm-01.png new file mode 100644 index 00000000..885bde1a Binary files /dev/null and b/public/img/illustrations/fm-01.png differ diff --git a/public/img/illustrations/gap between grid header and message.png b/public/img/illustrations/gap between grid header and message.png deleted file mode 100644 index 9461a532..00000000 Binary files a/public/img/illustrations/gap between grid header and message.png and /dev/null differ diff --git a/public/img/illustrations/man-with-laptop-light.png b/public/img/illustrations/man-with-laptop-light.png deleted file mode 100644 index 42661207..00000000 Binary files a/public/img/illustrations/man-with-laptop-light.png and /dev/null differ diff --git a/public/img/illustrations/payment request.png b/public/img/illustrations/payment request.png deleted file mode 100644 index 8d8a289b..00000000 Binary files a/public/img/illustrations/payment request.png and /dev/null differ diff --git a/public/img/illustrations/prom-min.webp b/public/img/illustrations/prom-min.webp deleted file mode 100644 index 0cccb84b..00000000 Binary files a/public/img/illustrations/prom-min.webp and /dev/null differ diff --git a/public/img/illustrations/worker_01.svg b/public/img/illustrations/worker_01.svg deleted file mode 100644 index 2170c2f4..00000000 --- a/public/img/illustrations/worker_01.svg +++ /dev/null @@ -1,4955 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/img/illustrations/worker_02.jpg b/public/img/illustrations/worker_02.jpg deleted file mode 100644 index 274c55c3..00000000 Binary files a/public/img/illustrations/worker_02.jpg and /dev/null differ diff --git a/public/img/illustrations/worker_02.svg b/public/img/illustrations/worker_02.svg deleted file mode 100644 index c673e01c..00000000 --- a/public/img/illustrations/worker_02.svg +++ /dev/null @@ -1,1117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/img/illustrations/worker_03.jpg b/public/img/illustrations/worker_03.jpg deleted file mode 100644 index 99c9be24..00000000 Binary files a/public/img/illustrations/worker_03.jpg and /dev/null differ diff --git a/public/img/illustrations/worker_03.png b/public/img/illustrations/worker_03.png deleted file mode 100644 index d5fdab98..00000000 Binary files a/public/img/illustrations/worker_03.png and /dev/null differ diff --git a/public/img/layouts/layout-container-light.png b/public/img/layouts/layout-container-light.png deleted file mode 100644 index 513338f0..00000000 Binary files a/public/img/layouts/layout-container-light.png and /dev/null differ diff --git a/public/img/layouts/layout-fluid-light.png b/public/img/layouts/layout-fluid-light.png deleted file mode 100644 index ca093f4c..00000000 Binary files a/public/img/layouts/layout-fluid-light.png and /dev/null differ diff --git a/public/img/layouts/layout-without-menu-light.png b/public/img/layouts/layout-without-menu-light.png deleted file mode 100644 index fe7d9198..00000000 Binary files a/public/img/layouts/layout-without-menu-light.png and /dev/null differ diff --git a/public/img/layouts/layout-without-navbar-light.png b/public/img/layouts/layout-without-navbar-light.png deleted file mode 100644 index 68e69ba9..00000000 Binary files a/public/img/layouts/layout-without-navbar-light.png and /dev/null differ diff --git a/public/img/sneat.svg b/public/img/sneat.svg deleted file mode 100644 index 347e4f0d..00000000 --- a/public/img/sneat.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/public/img/teams/team-member-1.png b/public/img/teams/team-member-1.png deleted file mode 100644 index 2a007f12..00000000 Binary files a/public/img/teams/team-member-1.png and /dev/null differ diff --git a/public/img/teams/team-member-2.png b/public/img/teams/team-member-2.png deleted file mode 100644 index b1b7e7c0..00000000 Binary files a/public/img/teams/team-member-2.png and /dev/null differ diff --git a/public/img/teams/team-member-3.png b/public/img/teams/team-member-3.png deleted file mode 100644 index 805b2825..00000000 Binary files a/public/img/teams/team-member-3.png and /dev/null differ diff --git a/public/img/teams/team-member-4.png b/public/img/teams/team-member-4.png deleted file mode 100644 index 8718f3c1..00000000 Binary files a/public/img/teams/team-member-4.png and /dev/null differ diff --git a/src/ModalProvider.jsx b/src/ModalProvider.jsx index bb217139..8ef00bcd 100644 --- a/src/ModalProvider.jsx +++ b/src/ModalProvider.jsx @@ -5,21 +5,24 @@ import { useAuthModal, useModal } from "./hooks/useAuth"; import SwitchTenant from "./pages/authentication/SwitchTenant"; import ChangePasswordPage from "./pages/authentication/ChangePassword"; import NewCollection from "./components/collections/ManageCollection"; +import ServiceProjectTeamAllocation from "./components/ServiceProject/ServiceProjectTeam/ServiceProjectTeamAllocation"; const ModalProvider = () => { const { isOpen, onClose } = useOrganizationModal(); const { isOpen: isAuthOpen } = useAuthModal(); - const {isOpen:isChangePass} = useModal("ChangePassword") - const {isOpen:isCollectionNew} = useModal("newCollection"); + const { isOpen: isChangePass } = useModal("ChangePassword"); + const { isOpen: isCollectionNew } = useModal("newCollection"); + const { isOpen: isServiceTeamAllocation } = useModal("ServiceTeamAllocation"); return ( <> {isOpen && } {isAuthOpen && } - {isChangePass && } - {isCollectionNew && } + {isChangePass && } + {isCollectionNew && } + {isServiceTeamAllocation && } ); }; -export default ModalProvider; \ No newline at end of file +export default ModalProvider; diff --git a/src/assets/react.svg b/src/assets/react.svg deleted file mode 100644 index 6c87de9b..00000000 --- a/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/vendor/css/core.css b/src/assets/vendor/css/core.css index 70f4fb09..bf74ae48 100644 --- a/src/assets/vendor/css/core.css +++ b/src/assets/vendor/css/core.css @@ -72,7 +72,7 @@ --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); --bs-root-font-size: 16px; --bs-body-font-family: var(--bs-font-sans-serif); - --bs-body-font-size: 0.9375rem; + --bs-body-font-size: 0.875rem; --bs-body-font-weight: 400; --bs-body-line-height: 1.375; --bs-body-color: #646e78; diff --git a/src/components/Dashboard/AttendanceChart.jsx b/src/components/Dashboard/AttendanceOverview.jsx similarity index 97% rename from src/components/Dashboard/AttendanceChart.jsx rename to src/components/Dashboard/AttendanceOverview.jsx index 71d14e48..77fbee51 100644 --- a/src/components/Dashboard/AttendanceChart.jsx +++ b/src/components/Dashboard/AttendanceOverview.jsx @@ -100,9 +100,9 @@ const AttendanceOverview = () => { }; return ( -
+
{/* Header */} -
+
Attendance Overview

Role-wise present count

diff --git a/src/components/Dashboard/Dashboard.jsx b/src/components/Dashboard/Dashboard.jsx index 3d0f0a66..ad5ead8c 100644 --- a/src/components/Dashboard/Dashboard.jsx +++ b/src/components/Dashboard/Dashboard.jsx @@ -12,11 +12,11 @@ import Teams from "./Teams"; import TasksCard from "./Tasks"; import ProjectCompletionChart from "./ProjectCompletionChart"; import ProjectProgressChart from "./ProjectProgressChart"; -import ProjectOverview from "../Project/ProjectOverview"; -import AttendanceOverview from "./AttendanceChart"; +import AttendanceOverview from "./AttendanceOverview"; import ExpenseAnalysis from "./ExpenseAnalysis"; import ExpenseStatus from "./ExpenseStatus"; import ExpenseByProject from "./ExpenseByProject"; +import ProjectStatistics from "../Project/ProjectStatistics"; const Dashboard = () => { @@ -29,16 +29,16 @@ const Dashboard = () => {
{isAllProjectsSelected && (
- +
)}
- +
- +
{isAllProjectsSelected && ( @@ -46,32 +46,31 @@ const Dashboard = () => {
)} - - {!isAllProjectsSelected && ( -
- -
- )} -
-
-
- -
-
- -
-
- -
-
{!isAllProjectsSelected && (
)} + + {!isAllProjectsSelected && ( +
+ +
+ )} +
+
+ +
+
+ +
+
+ +
+
diff --git a/src/components/Dashboard/ExpenseAnalysis.jsx b/src/components/Dashboard/ExpenseAnalysis.jsx index 1fe27fae..3c6b0d08 100644 --- a/src/components/Dashboard/ExpenseAnalysis.jsx +++ b/src/components/Dashboard/ExpenseAnalysis.jsx @@ -7,11 +7,12 @@ import { FormProvider, useForm } from "react-hook-form"; import { formatCurrency, localToUtc } from "../../utils/appUtils"; import { useProjectName } from "../../hooks/useProjects"; import { SpinnerLoader } from "../common/Loader"; +import flatColors from "../Charts/flatColor"; const ExpenseAnalysis = () => { const projectId = useSelectedProject(); const [projectName, setProjectName] = useState("All Project"); - const { projectNames, loading } = useProjectName(); + const { projectNames } = useProjectName(); const methods = useForm({ defaultValues: { startDate: "", endDate: "" }, @@ -50,7 +51,7 @@ const ExpenseAnalysis = () => { labels, legend: { show: false }, dataLabels: { enabled: true, formatter: (val) => `${val.toFixed(0)}%` }, - colors: ["#7367F0", "#28C76F", "#FF9F43", "#EA5455", "#00CFE8", "#FF78B8"], + colors: flatColors, plotOptions: { pie: { donut: { @@ -79,22 +80,19 @@ const ExpenseAnalysis = () => { return ( <> -
-
+
Expense Breakdown
- {/*

Category Wise Expense Breakdown

*/}

{projectName}

-
+
- {/* Card body */}
{isLoading && (
{
)} - {!isLoading && report.length > 0 && ( <> {isFetching && ( @@ -123,50 +120,59 @@ const ExpenseAnalysis = () => {
)} -
- -
+
+ {/* Chart Column */} +
+ +
-
-
- {report.map((item, idx) => ( -
-
- - - + {/* Data/Legend Column */} +
+
+ {report.map((item, idx) => ( +
+
+ + {item.projectName} + + + {formatCurrency(item.totalApprovedAmount)} + +
-
- {item.projectName} - - {formatCurrency(item.totalApprovedAmount)} - -
-
- ))} + + ))} +
)}
- - {/* Header */} - ); }; diff --git a/src/components/Dashboard/ExpenseByProject.jsx b/src/components/Dashboard/ExpenseByProject.jsx index 9a0e5a95..c589bc45 100644 --- a/src/components/Dashboard/ExpenseByProject.jsx +++ b/src/components/Dashboard/ExpenseByProject.jsx @@ -92,7 +92,7 @@ const ExpenseByProject = () => {
{/* Header */}
-
+
Monthly Expense -

{projectName}

diff --git a/src/components/Dashboard/ExpenseStatus.jsx b/src/components/Dashboard/ExpenseStatus.jsx index d6fefe7d..86a4fd8d 100644 --- a/src/components/Dashboard/ExpenseStatus.jsx +++ b/src/components/Dashboard/ExpenseStatus.jsx @@ -103,7 +103,7 @@ const ExpenseStatus = () => {
= 3 ? "text-xl" : "text-2xl" + className={`text-royalblue ${countDigit(item?.count || 0) >= 3 ? "text-xl" : "text-xl" } text-gray-500`} > {item?.count || 0} @@ -137,7 +137,7 @@ const ExpenseStatus = () => {
3 ? "text-" : "text-3xl" + className={`text-end text-royalblue ${countDigit(data?.totalAmount || 0) > 3 ? "text-xl" : "text-3xl" } text-md`} > {formatCurrency(data?.totalAmount || 0)} diff --git a/src/components/Dashboard/ProjectCompletionChart.jsx b/src/components/Dashboard/ProjectCompletionChart.jsx index 98ee1d3b..7cc4a092 100644 --- a/src/components/Dashboard/ProjectCompletionChart.jsx +++ b/src/components/Dashboard/ProjectCompletionChart.jsx @@ -1,11 +1,14 @@ -import React from "react"; +import React, { useState } from "react"; import HorizontalBarChart from "../Charts/HorizontalBarChart"; import { useProjects } from "../../hooks/useProjects"; +import { ITEMS_PER_PAGE } from "../../utils/constants"; const ProjectCompletionChart = () => { - const { data: projects = [], isLoading: loading, isError, error } = useProjects(); + const [currentPage, setCurrentPage] = useState(1); + const { data: projects, isLoading: loading, isError, error } = useProjects(currentPage, ITEMS_PER_PAGE); + console.log("Kartik", projects) // Bar chart logic const projectNames = projects?.map((p) => p.name) || []; const projectProgress = diff --git a/src/components/Directory/ManageContact.jsx b/src/components/Directory/ManageContact.jsx index 56d45e32..f55ed858 100644 --- a/src/components/Directory/ManageContact.jsx +++ b/src/components/Directory/ManageContact.jsx @@ -23,7 +23,7 @@ import Label from "../common/Label"; const ManageContact = ({ contactId, closeModal }) => { // fetch master data const { buckets, loading: bucketsLoaging } = useBuckets(); - const { data:projects, loading: projectLoading } = useProjects(); + const { data: projects, loading: projectLoading } = useProjects(); const { contactCategory, loading: contactCategoryLoading } = useContactCategory(); const { organizationList } = useOrganization(); @@ -205,12 +205,12 @@ const ManageContact = ({ contactId, closeModal }) => { - setValue("organization", val, { shouldValidate: true })} - error={errors.organization?.message} -/> + setValue("organization", val, { shouldValidate: true })} + error={errors.organization?.message} + />
@@ -408,6 +408,7 @@ const ManageContact = ({ contactId, closeModal }) => { label="Tags" options={contactTags} isRequired={true} + placeholder="Enter Tag" /> {errors.tags && ( {errors.tags.message} @@ -482,7 +483,7 @@ const ManageContact = ({ contactId, closeModal }) => { - +
diff --git a/src/components/Expenses/Filelist.jsx b/src/components/Expenses/Filelist.jsx index bd9f7108..35a4a986 100644 --- a/src/components/Expenses/Filelist.jsx +++ b/src/components/Expenses/Filelist.jsx @@ -20,7 +20,7 @@ const Filelist = ({ files, removeFile, expenseToEdit,sm=6,md=4 }) => { diff --git a/src/components/Expenses/ViewExpense.jsx b/src/components/Expenses/ViewExpense.jsx index a4b1089b..8c032fc0 100644 --- a/src/components/Expenses/ViewExpense.jsx +++ b/src/components/Expenses/ViewExpense.jsx @@ -10,6 +10,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { defaultActionValues, ExpenseActionScheam } from "./ExpenseSchema"; import { useExpenseContext } from "../../pages/Expense/ExpensePage"; import { + calculateTDSPercentage, formatCurrency, formatFigure, getColorNameFromHex, @@ -54,12 +55,22 @@ const ViewExpense = ({ ExpenseId }) => { setValue, reset, control, + watch, formState: { errors }, } = useForm({ resolver: zodResolver(ActionSchema), defaultValues: defaultActionValues, }); +const baseAmount = Number(watch("baseAmount")) || 0; +const taxAmount = Number(watch("taxAmount")) || 0; +const tdsPercentage = Number(watch("tdsPercentage")) || 0; + + + const { grossAmount, tdsAmount, netPayable } = useMemo(() => { + return calculateTDSPercentage(baseAmount, taxAmount, tdsPercentage); + }, [baseAmount, taxAmount, tdsPercentage]); + const userPermissions = useSelector( (state) => state?.globalVariables?.loginUser?.featurePermissions || [] ); @@ -132,9 +143,8 @@ const ViewExpense = ({ ExpenseId }) => { {data?.expenseUId}
{" "} {data?.status?.name} @@ -142,7 +152,7 @@ const ViewExpense = ({ ExpenseId }) => {
{/* Row 1 */} -
+
*/} {/* Row 5 */} - -
+ +
- + - - -
-
- + + +
+
+ {formatUTCToLocalTime(data?.createdAt, true)} - + +
-
{/* Created & Paid By */} {data.createdBy && ( @@ -307,9 +317,8 @@ const ViewExpense = ({ ExpenseId }) => { lastName={data.createdBy?.lastName} /> - {`${data.createdBy?.firstName ?? ""} ${ - data.createdBy?.lastName ?? "" - }`.trim() || "N/A"} + {`${data.createdBy?.firstName ?? ""} ${data.createdBy?.lastName ?? "" + }`.trim() || "N/A"}
@@ -337,31 +346,30 @@ const ViewExpense = ({ ExpenseId }) => {
*/} -
-
- -
-
-
- - - {`${data.paidBy?.firstName ?? ""} ${ - data.paidBy?.lastName ?? "" +
+
+ +
+
+
+ + + {`${data.paidBy?.firstName ?? ""} ${data.paidBy?.lastName ?? "" }`.trim() || "N/A"} - -
+
+
{/* Description */}
@@ -493,19 +501,7 @@ const ViewExpense = ({ ExpenseId }) => { projectId={null} />
-
- - - {errors.tdsPercentage && ( - - {errors.tdsPercentage.message} - - )} -
+
)}
+
+ + + {errors.tdsPercentage && ( + + {errors.tdsPercentage.message} + + )} +
+
+
+ TDS Amount: + {tdsAmount.toFixed(2)} +
+ +
+ Net Payable: + {netPayable.toFixed(2)} +
+
+ )}
{((nextStatusWithPermission.length > 0 && !IsRejectedExpense) || (IsRejectedExpense && isCreatedBy)) && ( - <> - - + + {errors?.comment && ( + + {errors?.comment?.message} + + )} +
+
+ +
+ {/* LEFT SIDE → Uploaded Files */} +
+ {files?.length > 0 && ( + + )} +
+ + {/* RIGHT SIDE → Add Attachment + Submit */} +
+
document.getElementById("attachments").click()} + className="cursor-pointer" + style={{ whiteSpace: 'nowrap' }} + > + { + onFileChange(e); + e.target.value = ""; + }} + /> + + Add Attachment +
+ + + +
+
+ + +
+
+
+ {jobComments?.map((item) => { + const user = item?.createdBy; + + return ( +
+
+ +
+
+ + {user?.firstName} {user?.lastName} + + + {formatUTCToLocalTime(item?.createdAt, true)} + +
+
+ {user?.jobRoleName} +
+
+

{item.comment}

+
+ {item.attachments?.map((file) => ( +
+ +
+

{file.fileName}

+ + {formatFileSize(file.fileSize)} + +
+
+ ))} +
+
+
+
+
+ ); + })} +
+
+
+ ); +}; + +export default JobComments; diff --git a/src/components/ServiceProject/JobList.jsx b/src/components/ServiceProject/JobList.jsx index 425ffca4..5665511e 100644 --- a/src/components/ServiceProject/JobList.jsx +++ b/src/components/ServiceProject/JobList.jsx @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import { getNextBadgeColor } from "../../utils/appUtils"; +import { daysLeft, getNextBadgeColor } from "../../utils/appUtils"; import { useServiceProjectJobs } from "../../hooks/useServiceProject"; import { ITEMS_PER_PAGE } from "../../utils/constants"; import EmployeeAvatarGroup from "../common/EmployeeAvatarGroup"; @@ -9,28 +9,36 @@ import { useParams } from "react-router-dom"; import ProjectPage from "../../pages/project/ProjectPage"; import { useServiceProjectJobContext } from "./Jobs"; - -const JobList = ({ filterByProject }) => { - const {setSelectedJob} = useServiceProjectJobContext() - const { id } = useParams(); +const JobList = () => { + const { setSelectedJob, setManageJob } = useServiceProjectJobContext(); + const { projectId } = useParams(); const { data, isLoading, isError, error } = useServiceProjectJobs( ITEMS_PER_PAGE, 1, true, - filterByProject ?? id + projectId ); const jobGrid = [ + { + key: "jobTicketUId", + label: "Job Id", + getValue: (e) => e?.jobTicketUId || "N/A", + align: "text-start", + }, { key: "title", label: "Title", getValue: (e) => ( + setSelectedJob({ showCanvas: true, job: e?.id }) + } > {e?.title} @@ -38,36 +46,52 @@ const JobList = ({ filterByProject }) => { isAlwaysVisible: true, className: "text-start", }, - { - key: "project", - label: "Project", - getValue: (e) =>
{e?.project?.name}
, - isAlwaysVisible: true, - className: "text-start d-none d-sm-table-cell", - }, - { - key: "employee", - label: "Team", - getValue: (e) => , - isAlwaysVisible: true, - className: "text-start d-none d-sm-table-cell", - }, - - { - key: "startDate", - label: "Start Date", - getValue: (e) => formatUTCToLocalTime(e.startDate), - isAlwaysVisible: true, - className: "text-center d-none d-sm-table-cell ", - }, { key: "dueDate", - label: "Due To", + label: "Due On", getValue: (e) => formatUTCToLocalTime(e.startDate), isAlwaysVisible: true, - className: "text-center d-none d-sm-table-cell", + className: "text-start d-none d-sm-table-cell", }, + { + key: "status", + label: "Status", + getValue: (e) => { + const statusName = e?.status?.displayName || "N/A"; + const statusColorMap = { + Assigned: "label-primary", + Pending: "label-warning", + Completed: "label-success", + Cancelled: "label-danger", + }; + + const badgeColor = statusColorMap[statusName] || "label-secondary"; + + return ( + + {statusName} + + ); + }, + isAlwaysVisible: true, + className: "text-start d-none d-sm-table-cell", + }, + { + key: "daysLeft", + label: "Days Left", + getValue: (e) => { + const { days, color } = daysLeft(e.startDate, e.dueDate); + + return ( + + {days !== null ? `${days} days` : "N/A"} + + ); + }, + isAlwaysVisible: true, + className: "text-start d-none d-sm-table-cell" + } ]; return ( @@ -81,7 +105,7 @@ const JobList = ({ filterByProject }) => { {jobGrid.map((col) => (
{col.label}
@@ -96,14 +120,14 @@ const JobList = ({ filterByProject }) => { {Array.isArray(data?.data) && data.data.length > 0 ? ( data.data.map((row, i) => ( - + {jobGrid.map((col) => ( {col.getValue(row)} ))} -
+
{/* View always visible */} - <> - diff --git a/src/components/ServiceProject/JobStatusLog.jsx b/src/components/ServiceProject/JobStatusLog.jsx new file mode 100644 index 00000000..6e97f9e9 --- /dev/null +++ b/src/components/ServiceProject/JobStatusLog.jsx @@ -0,0 +1,57 @@ +import React from "react"; +import Avatar from "../common/Avatar"; + +const JobStatusLog = ({ data }) => { + return ( +
+
+
+ {data?.map((item) => ( +
+
+
+ + {item.nextStatus?.displayName ?? + item.status?.displayName ?? + "Status"} + +
+ + {/* + Level {item.nextStatus?.level ?? item.status?.level} + */} +
+
+ +
+
+ + {item.updatedBy?.firstName} {item.updatedBy?.lastName} + + + {/* {formatUTCToLocalTime(item?.createdAt, true)} */} + +
+
+ {item?.updatedBy?.jobRoleName} +
+
+

{item.comment}

+
+
+
+
+ ))} +
+
+
+ ); +}; + +export default JobStatusLog; diff --git a/src/components/ServiceProject/Jobs.jsx b/src/components/ServiceProject/Jobs.jsx index 69e20b61..47f0995c 100644 --- a/src/components/ServiceProject/Jobs.jsx +++ b/src/components/ServiceProject/Jobs.jsx @@ -7,6 +7,8 @@ import OffcanvasComponent from "../common/OffcanvasComponent"; import showToast from "../../services/toastService"; import ManageJob from "./ManageJob"; import ManageJobTicket from "./ManageJobTicket"; +import GlobalModel from "../common/GlobalModel"; +import PreviewDocument from "../Expenses/PreviewDocument"; export const JonContext = createContext(); export const useServiceProjectJobContext = () => { @@ -18,15 +20,22 @@ export const useServiceProjectJobContext = () => { return context; }; const Jobs = () => { + const [manageJob, setManageJob] = useState({ isOpen: false, jobId: null }); const [showCanvas, setShowCanvas] = useState(false); const [selectedProject, setSelectedProject] = useState(null); - const [selectJob,setSelectedJob] = useState({showCanvas:false,job:null}) + const [selectJob, setSelectedJob] = useState({ + showCanvas: false, + job: null, + }); const navigate = useNavigate(); const { data } = useServiceProjects(ITEMS_PER_PAGE, 1); const contextProvider = { - setSelectedJob - } + setSelectedJob, + setSelectedProject, + setManageJob, + manageJob, + }; return ( <> @@ -35,34 +44,26 @@ const Jobs = () => { title="Job" placement="end" show={selectJob.showCanvas} - onClose={() => setSelectedJob({showCanvas:false,job:null})} + onClose={() => setSelectedJob({ showCanvas: false, job: null })} > -
+ setManageJob({ isOpen: false, jobId: null })} + > + + +
-
-
- {" "} - -
+
diff --git a/src/components/ServiceProject/ManageJob.jsx b/src/components/ServiceProject/ManageJob.jsx index 5232e3ca..53c51578 100644 --- a/src/components/ServiceProject/ManageJob.jsx +++ b/src/components/ServiceProject/ManageJob.jsx @@ -1,10 +1,12 @@ -import React from "react"; +import React, { useEffect } from "react"; import Breadcrumb from "../common/Breadcrumb"; import Label from "../common/Label"; import { zodResolver } from "@hookform/resolvers/zod"; import { defaultJobValue, jobSchema } from "./ServiceProjectSchema"; import { useCreateServiceProjectJob, + useJobTags, + useServiceProjectJobDetails, useServiceProjects, } from "../../hooks/useServiceProject"; import { ITEMS_PER_PAGE } from "../../utils/constants"; @@ -18,13 +20,14 @@ import { AppFormProvider, useAppForm, } from "../../hooks/appHooks/useAppForm"; +import { useParams } from "react-router-dom"; -const ManageJob = () => { +const ManageJob = ({ Job }) => { + const { projectId } = useParams(); const methods = useAppForm({ resolver: zodResolver(jobSchema), defaultValues: defaultJobValue, }); - const { register, control, @@ -35,15 +38,21 @@ const ManageJob = () => { } = methods; const { - data, - isLoading: isProjectLoading, - isError: isProjectError, - error, - } = useServiceProjects(ITEMS_PER_PAGE, 1); - + data: JobTags, + isLoading: isTagLoading, + isError: isTagError, + error: tagError, + } = useJobTags(); + const { + data: JobData, + isLoading: isJobLoading, + isError: isJobError, + error: jobError, + } = useServiceProjectJobDetails(Job); const { mutate: CreateJob, isPending } = useCreateServiceProjectJob(() => { reset(); }); + const onSubmit = (formData) => { formData.assignees = formData.assignees.map((emp) => ({ employeeId: emp, @@ -52,104 +61,104 @@ const ManageJob = () => { formData.startDate = localToUtc(formData.startDate); formData.dueDate = localToUtc(formData.dueDate); - // CreateJob(formData); - console.log(formData); + formData.projectId = projectId; + CreateJob(formData); }; - console.log(errors); + + useEffect(() => { + if (!JobData && !Job) { + reset({ + ...defaultJobValue, + projectId: projectId, + }); + return; + } + + if (!JobData || !Job) return; + + const assignedEmployees = (JobData.assignees || []).map((e) => e.id); + + reset({ + title: JobData.title ?? "", + description: JobData.description ?? "", + projectId: JobData.project?.id ?? projectId, + assignees: assignedEmployees, + startDate: JobData.startDate ?? null, + dueDate: JobData.dueDate ?? null, + tags: JobData.tags ?? [], + }); + }, [JobData, Job, projectId]); + return ( -
- -
-
-
- -
-
-

Create Job

-
-
- - -
-
- ( - - )} - /> -
-
- - -
-
- - -
-
- - -
-
- -
-
- - -
-
- -
-
- -
-
-
-
-
- - {/* Contact Us: End */} + +
- - {/* / Sections:End */} - - {/* Footer: Start */} - - {/* Footer: End */} -
+ ); }; + export default LandingPage; diff --git a/src/pages/Home/LandingPageOld.css b/src/pages/Home/LandingPageOld.css new file mode 100644 index 00000000..16c8dbbc --- /dev/null +++ b/src/pages/Home/LandingPageOld.css @@ -0,0 +1,668 @@ +.section-py { + padding: 6.25rem 0; +} + +.section-py .heading { + font-size: 1.625rem; +} +@media (max-width: 1199.98px) { + .section-py { + padding: 4rem 0; + } +} +@media (max-width: 767.98px) { + .section-py { + padding: 3rem 0; + } +} + +.first-section-pt { + padding-top: 11.28rem; +} +@media (max-width: 1199.98px) { + .first-section-pt { + padding-top: 7.5rem; + } +} + +.card[class*="card-hover-border-"] { + transition: all 0.2s ease-in-out; +} + +.banner-bg-img { + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + object-fit: cover; + object-position: left; +} + +.section-title-img { + height: 100%; + width: 120%; + inset-inline-start: -12%; + top: 10px; +} + +/* .light-style body { + background-color: #fff; +} */ + +.dark-style body { + background-color: #2b2c40; +} + +nav.layout-navbar { + /* backdrop-filter: unset; */ + /* background-color: transparent !important; */ + /* background-color: rgba(214, 36, 33, 0.88) !important; */ +} + +nav.layout-navbar::before { + position: absolute; + display: block; + block-size: 100%; + content: ""; + inline-size: 100%; + inset-block-start: 0; + inset-inline-start: 0; +} + +nav.layout-navbar .navbar.landing-navbar { + --bs-front-navbar-bg: rgba(var(--bs-paper-bg-rgb), 0.38); + --bs-front-navbar-border-color: rgba(var(--bs-paper-bg-rgb), 0.68); + border: 2px solid var(--bs-front-navbar-border-color); + background-color: var(--bs-front-navbar-bg); + margin-block-start: 0rem; + padding-block: 0.614rem; + transform: unset; + transition: all 0.2s ease-in-out; + border-radius: 0.375rem; +} + +nav.layout-navbar.navbar-active::after { + backdrop-filter: saturate(100%) blur(6px); + -webkit-backdrop-filter: saturate(100%) blur(6px); +} + +.navbar.landing-navbar { + box-shadow: none; + transition: all 0.2s ease-in-out; + transform: unset !important; + padding-top: 0.614rem; + padding-bottom: 0.614rem; + margin-top: 1rem; + border-width: 2px; + border-style: solid; + border-radius: 0.375rem; +} +.navbar.landing-navbar .navbar-nav .nav-link { + padding: 0.5rem 0.625rem; + margin-inline-end: 0.625rem; +} +@media (max-width: 1199.98px) { + .navbar.landing-navbar .navbar-nav .nav-link { + padding-left: 0.5rem; + padding-right: 0.5rem; + margin-inline-end: 0; + } +} +.navbar.landing-navbar .navbar-nav .nav-item:last-child .nav-link { + margin-inline-end: 0; +} +@media (min-width: 992px) { + .navbar.landing-navbar .navbar-nav .nav-item.mega-dropdown > .dropdown-menu { + max-width: 1300px; + inset-inline-start: 50% !important; + transform: translateX(-50%); + top: 100%; + } +} +@media (max-width: 991.98px) { + .navbar.landing-navbar .navbar-nav .nav-item.mega-dropdown > .dropdown-menu { + background: transparent; + box-shadow: none; + border: none; + } +} +.navbar.landing-navbar + .navbar-nav + .nav-item.mega-dropdown + > .dropdown-menu + .mega-dropdown-link { + padding-left: 0; + padding-right: 0; + margin: 0; + font-weight: 400; +} +.navbar.landing-navbar + .navbar-nav + .nav-item.mega-dropdown + > .dropdown-menu + .mega-dropdown-link + i { + font-size: 1rem; + font-weight: 700; + margin-top: -0.125rem; +} +.navbar.landing-navbar .navbar-nav .nav-item .nav-img-col, +.navbar.landing-navbar .navbar-nav .nav-item .nav-img-col img { + border-radius: 0.625rem; +} +@media (max-width: 991.98px) { + .navbar.landing-navbar .landing-menu-overlay { + position: fixed; + display: none; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(34, 48, 62, 0.78); + transition: all 0.2s ease-in-out; + z-index: 9998; + } + .navbar.landing-navbar .landing-nav-menu { + position: fixed; + display: block !important; + height: 100%; + max-width: 300px; + width: 80%; + padding: 1rem; + inset-inline-start: -100%; + top: 0; + overflow-y: auto; + transition: all 0.3s ease-in-out; + z-index: 9999; + } + .navbar.landing-navbar .landing-nav-menu.show { + inset-inline-start: 0; + } + .navbar.landing-navbar .landing-nav-menu.show ~ .landing-menu-overlay { + display: block; + } +} + +.light-style .layout-navbar .navbar.landing-navbar { + border-color: rgba(255, 255, 255, 100); + background: rgba(255, 255, 255, 50); +} +.light-style .layout-navbar .navbar.landing-navbar .navbar-nav .nav-link { + color: #384551; +} +.light-style + .layout-navbar + .navbar.landing-navbar + .navbar-nav + .show + > .nav-link, +.light-style + .layout-navbar + .navbar.landing-navbar + .navbar-nav + .active + > .nav-link, +.light-style .layout-navbar .navbar.landing-navbar .navbar-nav .nav-link.show, +.light-style + .layout-navbar + .navbar.landing-navbar + .navbar-nav + .nav-link.active { + color: #696cff !important; +} +.light-style + .layout-navbar + .navbar.landing-navbar + .navbar-nav + .nav-item.mega-dropdown + > .dropdown-menu + .mega-dropdown-link + i { + color: #646e78; +} +@media (max-width: 991.98px) { + .light-style .layout-navbar .navbar.landing-navbar .landing-nav-menu { + background-color: #fff; + } +} +.light-style .layout-navbar.navbar-active .navbar.landing-navbar { + background: #fff; + box-shadow: 0 0.125rem 0.375rem 0 rgba(34, 48, 62, 0.08); +} +.light-style .layout-navbar .menu-text { + color: #384551; +} + +.dark-style .layout-navbar .navbar.landing-navbar { + border-color: rgba(65, 65, 95, 0.68); + background-color: rgba(65, 65, 95, 0.38); +} +.dark-style .layout-navbar .navbar.landing-navbar .navbar-nav .nav-link { + color: #d5d5e2; +} +.dark-style .layout-navbar .navbar.landing-navbar .navbar-nav .show > .nav-link, +.dark-style + .layout-navbar + .navbar.landing-navbar + .navbar-nav + .active + > .nav-link, +.dark-style .layout-navbar .navbar.landing-navbar .navbar-nav .nav-link.show, +.dark-style .layout-navbar .navbar.landing-navbar .navbar-nav .nav-link.active { + color: #696cff !important; +} +.dark-style + .layout-navbar + .navbar.landing-navbar + .navbar-nav + .nav-item.mega-dropdown + > .dropdown-menu + .mega-dropdown-link + i { + color: #b2b2c4; +} +@media (max-width: 991.98px) { + .dark-style .layout-navbar .navbar.landing-navbar .landing-nav-menu { + background-color: #2b2c40; + } +} +.dark-style .layout-navbar .navbar .menu-text { + color: #d5d5e2; +} +.dark-style .layout-navbar.navbar-active .navbar.landing-navbar { + background: #2b2c40; + border-color: #2b2c40; + box-shadow: 0 0.125rem 0.375rem 0 rgba(20, 20, 29, 0.2); +} + +@media (min-width: 992px) { + [dir="rtl"] + .navbar.landing-navbar + .navbar-nav + .nav-item.mega-dropdown + > .dropdown-menu { + transform: translateX(50%); + } +} + +.landing-footer .footer-link, +.landing-footer .footer-text { + color: #fff; + opacity: 0.78; +} +.landing-footer .footer-title { + color: #fff; + opacity: 0.92; +} +.landing-footer .footer-bottom-text { + color: #d3d4dc; +} +.landing-footer .footer-bottom { + background-color: #f44336; +} +.landing-footer .footer-link { + transition: all 0.2s ease-in-out; +} +.landing-footer .footer-link:hover { + opacity: 1; +} +.landing-footer .footer-top { + padding-top: 1.3rem; + padding-bottom: 1.3rem; + border-top-left-radius: 1.75rem; + border-top-right-radius: 1.75rem; + background-color: #f44336; +} +@media (max-width: 767.98px) { + .landing-footer .footer-top { + padding: 3rem 0; + } +} +.landing-footer .footer-top .footer-bg { + object-position: center; +} +@media (min-width: 992px) { + .landing-footer .footer-logo-description { + max-width: 385px; + } +} +.landing-footer .footer-form { + max-width: 22.25rem; +} +.landing-footer .footer-form input { + background-color: transparent; + border-color: #4e4f6c; + color: #fff; +} +.landing-footer .footer-form input:hover:not([disabled]):not([focus]) { + border-color: #4e4f6c; +} +.landing-footer .footer-form input::placeholder { + color: rgba(255, 255, 255, 0.5); +} +.landing-footer .footer-form label { + color: #d5d5e2; +} + +.section-py { + padding: 6.25rem 0; +} +@media (max-width: 1199.98px) { + .section-py { + padding: 5rem 0; + } +} +@media (max-width: 767.98px) { + .section-py { + padding: 3rem 0; + } +} + +.landing-hero { + border-radius: 0 0 3.5rem 3.5rem; + padding-top: 8.2rem; +} +.landing-hero::after { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; +} +@media (min-width: 992px) { + .landing-hero .hero-text-box { + /* max-width: 34.375rem; */ + max-width: 70%; + margin: 0 auto; + } +} +.landing-hero .hero-title { + background: linear-gradient( + to right, + #28c76f 0%, + #5a4aff 47.92%, + #ff3739 100% + ); + background-size: 200% auto; + color: #384551; + font-size: calc(1.3875rem + 1.65vw); + background-clip: text; + line-height: 1.2; + text-fill-color: transparent; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + animation: shine 2s ease-in-out infinite alternate; +} +@media (min-width: 1200px) { + .landing-hero .hero-title { + font-size: 2.625rem; + } +} +.landing-hero .landing-hero-btn .hero-btn-item { + inset-inline-start: -94%; + top: 65%; +} +.landing-hero .hero-animation-img { + margin-bottom: -32rem; +} +.animation-img { + border: 1px soid red; +} +@media (max-width: 1199.98px) { + .landing-hero .hero-animation-img { + margin-bottom: -20rem; + } +} +@media (max-width: 575.98px) { + .landing-hero .hero-animation-img { + margin-bottom: -10rem; + } +} +.landing-hero .hero-animation-img .hero-dashboard-img { + width: 80%; + margin: 0 auto; + will-change: transform; + transform-style: preserve-3d; + transition: all 0.1s; +} +.landing-hero .hero-animation-img .hero-dashboard-img img { + width: 100%; +} + +.landing-hero-blank { + padding-top: 26rem; +} +@media (max-width: 1199.98px) { + .landing-hero-blank { + padding-top: 15rem; + } +} +@media (max-width: 575.98px) { + .landing-hero-blank { + padding-top: 7rem; + } +} + +@keyframes shine { + 0% { + background-position: 0% 50%; + } + 80% { + background-position: 50% 90%; + } + 100% { + background-position: 91% 100%; + } +} +.landing-features + .features-icon-wrapper + .features-icon-box + .features-icon-description { + max-width: 19.25rem; + margin: 0 auto; +} + +.landing-reviews { + border-top-left-radius: 3.75rem; + border-top-right-radius: 3.75rem; +} +.landing-reviews .swiper-reviews-carousel .swiper-button-prev, +.landing-reviews .swiper-reviews-carousel .swiper-button-next { + display: none; +} +.landing-reviews .swiper-reviews-carousel .swiper-slide { + height: auto; + padding: 0.8125rem; +} +.landing-reviews .swiper-reviews-carousel .client-logo { + height: 1.375rem; + object-fit: contain; +} +.landing-reviews .swiper-logo-carousel { + padding-bottom: 6.25rem; +} +.landing-reviews .swiper-logo-carousel .swiper { + max-width: 45rem; +} +.landing-reviews .swiper-logo-carousel .swiper .swiper-slide { + display: flex; + justify-content: center; +} +.landing-reviews .swiper-logo-carousel .swiper .client-logo { + max-height: 2.5rem; + max-width: 95%; + object-fit: contain; +} + +.landing-team .card, +.landing-team .card .team-image-box { + border-top-left-radius: 5.625rem; + border-top-right-radius: 1.25rem; +} +.landing-team .card .card-body { + border-bottom-left-radius: 0.375rem; + border-bottom-right-radius: 0.375rem; +} +.landing-team .team-image-box { + height: 11.5625rem; +} +.landing-team .team-image-box .card-img-position { + height: 15rem; + transform: translateX(-50%); + max-width: 100%; + object-fit: cover; +} +@media (max-width: 991.98px) { + .landing-team .team-image-box .card-img-position { + height: 13rem; + } +} +@media (max-width: 575.98px) { + .landing-team .team-image-box { + height: 11rem; + } +} +.landing-team .card .team-media-icons i { + transition: all 0.2s ease-in-out; +} + +.landing-pricing { + border-radius: 3.75rem; +} +.landing-pricing .pricing-plans-item { + inset-inline-end: -56%; + bottom: -0.5rem; +} +@media (max-width: 767.98px) { + .landing-pricing .pricing-plans-item { + inset-inline-end: 0; + bottom: 1rem; + } +} +.landing-pricing .pricing-list .badge.badge-center { + width: 1rem; + height: 1rem; +} +.landing-pricing .pricing-list .badge.badge-center i { + margin-top: -5px; +} +.landing-pricing .price-yearly-toggle { + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); +} +.landing-pricing .card .card-header, +.landing-pricing .card .card-body { + padding: 2rem; + padding-top: 3rem; +} + +.landing-faq { + border-top-left-radius: 3.75rem; + border-top-right-radius: 3.75rem; +} +.landing-faq .faq-image { + max-width: 20rem; + width: 80%; +} + +.landing-cta .cta-title { + font-size: 2.125rem; +} +@media (max-width: 767.98px) { + .landing-cta .cta-title { + font-size: 1.8rem; + } +} + +.landing-contact .text-heading { + overflow-wrap: anywhere; +} +.landing-contact .contact-img-box, +.landing-contact .contact-img-box .contact-img { + border-radius: 3.75rem 0.375rem 0.375rem 0.375rem; +} +.landing-contact .contact-img-box .contact-border-img { + inset-block-start: -2.5rem; + inset-inline-start: -2.8125rem; +} + +.light-style .landing-hero { + background: linear-gradient(138.18deg, #eae8fd 0%, #fce5e6 94.44%); +} +.light-style .landing-hero::after { + background-color: #fff; +} + +.dark-style .landing-hero { + background: #1e2130; +} +.dark-style .landing-hero::after { + background-color: #2b2c40; +} + +[dir="rtl"] .landing-reviews-btns { + display: flex; + justify-content: flex-end; + flex-direction: row-reverse; + gap: 1rem; +} +[dir="rtl"] .landing-team .team-image-box .card-img-position { + transform: translateX(50%) !important; +} +[dir="rtl"] .landing-pricing .switch .switch-label { + padding-right: 0; +} +[dir="rtl"] .landing-pricing .switch .switch-label:first-child { + padding-left: 0.5rem; +} +[dir="rtl"] .landing-pricing .switch .switch-input ~ .switch-label { + padding-right: 3rem; +} +[dir="rtl"] .landing-contact .contact-img-box { + border-radius: 0.375rem 3.75rem 0.375rem 0.375rem; +} +[dir="rtl"] .landing-contact .contact-img-box::before { + inset-block-start: -1.875rem; + inset-inline-start: -3.125rem; + transform: rotate(90deg); +} + +.swiper { + width: 100%; + height: 100%; + border-radius: 10px; +} + +.swiper-slide { + text-align: center; + font-size: 18px; + + /* Center slide text vertically */ + display: flex; + justify-content: center; + align-items: center; +} + +.swiper-slide img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; +} + +.light-style .landing-hero { + background: linear-gradient(138.18deg, #eae8fd, #ede7e7 94.44%); +} + +.text-green { + color: #49bf3c !important; +} + +.text-blue { + color: var(--bs-blue); +} diff --git a/src/pages/Home/LandingPageOld.jsx b/src/pages/Home/LandingPageOld.jsx new file mode 100644 index 00000000..df546e60 --- /dev/null +++ b/src/pages/Home/LandingPageOld.jsx @@ -0,0 +1,1288 @@ +import { noop } from "@tanstack/react-query"; +import React, { useEffect, useMemo, useState } from "react"; + +import "./LandingPageOld.css"; +import { Link } from "react-router-dom"; + +import { Swiper, SwiperSlide } from "swiper/react"; +// import required modules +import { EffectFlip, Autoplay, Pagination, Navigation } from "swiper/modules"; +// Import Swiper styles +import "swiper/css"; +import "swiper/css/navigation"; +import SwaperSlideContent from "./SwaperSlideContent"; +import SwaperBlogContent from "./SwaperBlogContent"; +import SubscriptionPlans from "./SubscriptionPlans"; + +const swiperConfig = { + spaceBetween: 30, + centeredSlides: true, + rewind: true, + autoplay: { + delay: 3500, + disableOnInteraction: false, + }, + pagination: { + clickable: true, + }, + keyboard: { + enabled: true, + }, + navigation: false, + modules: [EffectFlip, Autoplay, Pagination, Navigation], + className: "mySwiper", +}; + +const LandingPageOld = () => { + const [swiperRef, setSwiperRef] = useState(null); + return ( +
+ + {/* Navbar: End */} + + {/* Sections:Start */} + +
+ {/* Hero: Start */} +
+
+
+
+

+ All-in-one platform to manage projects, people, and resources + seamlessly. +

+ {/*

+ Production-ready & easy to use Admin Template +
+ for Reliability and Customizability. +

*/} +
+ {/* + Join community + Join community arrow + */} + + Get Early Access + + + Request a Demo + +
+
+ +
+
+ {}} + onSwiper={(swiper) => {}} + > + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ {/* Hero: End */} + + {/* Useful features: Start */} +
+
+
+ + Useful Features + +
+

+ + From tasks to teams, documents to inventory — + {/* laptop charging */} + + everything your business needs in one place. +

+

+ All-in-one platform to manage projects, people, and resources + seamlessly. +

+
+
+
+ laptop charging +
+
Project & Task Management
+

+ Plan, assign, and track projects and tasks seamlessly for + better team collaboration. +

+
+
+
+ transition up +
+
Attendance & Leave Tracking
+

+ Monitor employee attendance and manage leave requests with + ease. +

+
+
+
+ edit +
+
Role-based Permissions
+

+ Securely control access with customizable roles and + permissions. +

+
+
+
+ 3d select solid +
+
Expense & Budget Tracking
+

+ Keep projects on budget with real-time expense and cost + management. +

+
+
+
+ user +
+
Reporting & Analytics
+

+ Gain actionable insights through powerful reports and + analytics dashboards. +

+
+
+
+ keyboard +
+
Document Management
+

+ Organize, share, and access all your project and employee + documents in one place. +

+
+
+
+ keyboard +
+
+ Service Provider & Subcontractor Tracking +
+

+ Manage multiple service providers and subcontractors + efficiently within projects. +

+
{" "} +
+
+ keyboard +
+
Inventory Management
+

+ Track materials, supplies, and assets — never run short again. +

+
{" "} +
+
+
+ keyboard +
+
Directory
+

+ Your team, suppliers, vendors organized and connected in one + unified directory. +

+
{" "} +
+
+ {/* Useful features: End */} + + {/* */} + + {/* */} + + {/* Pricing plans: Start */} +
+
+
+ + Pricing Plans + +
+

+ + Tailored pricing plans + {/* laptop charging */} + + designed for you +

+

+ No matter which plan you choose, you’ll get access to powerful + features. Choose the best plan to fit your needs. +

+ {/* */} + +
+
+ {/* Pricing plans: End */} + + {/* Fun facts: Start */} +
+
+
+
+
+
+ laptop +

7.1k+

+

+ Support Tickets +
+ Resolved +

+
+
+
+
+
+
+ laptop +

50k+

+

+ Join creatives +
+ community +

+
+
+
+
+
+
+ laptop +

4.8/5

+

+ Highly Rated +
+ Products +

+
+
+
+
+
+
+ laptop +

100%

+

+ Money Back +
+ Guarantee +

+
+
+
+
+
+
+ {/* Fun facts: End */} + + {/* FAQ: Start */} +
+
+
+ FAQ +
+

+ Frequently Asked + + Questions + {/* laptop charging */} + +

+

+ Browse through these FAQs to find answers to commonly asked + questions. +

+
+
+
+ faq boy with logos +
+
+
+
+
+

+ +

+ +
+
+ A smart Project Management System designed to bring + teams, tasks, and timelines together in one place. With + AI-driven insights, role-based access, and seamless + reporting, it empowers organizations to deliver projects + faster and smarter. +
+
+
+
+

+ +

+
+
+ Yes, you have full flexibility to manage your + subscription. You can upgrade to a higher plan to unlock + more features, downgrade to a smaller plan if your needs + change, or cancel your subscription anytime. Plan + changes take effect instantly, and billing adjustments + are applied on a pro-rated basis. +
+
+
+
+

+ +

+
+
+ Security is at the core of OnFieldWork.com. We use + industry-standard encryption (SSL/TLS) to protect data + in transit and advanced encryption to safeguard data at + rest. Role-based access controls ensure that only + authorized users can access sensitive information. Our + system is hosted on secure, cloud-ready infrastructure + with regular backups, monitoring, and compliance with + best practices to keep your data safe and available at + all times. +
+
+
+
+

+ +

+
+
+ You can reach our support team anytime through the + in-app help center, email, or live chat. We also provide + a detailed knowledge base and FAQs to guide you through + common queries. For personalized assistance, our support + specialists are always ready to help you. +
+
+
+
+

+ +

+
+
+ OnFieldWork.com operate under a proprietary license + combined with a subscription model. This means customers + don’t own the software but are granted the right to + access and use it through the cloud under our Terms of + Service. Depending on the plan, licensing may be based + on users, features, or usage, and you can upgrade, + downgrade, or cancel at any time. non! +
+
+
+
+

+ +

+
+
+ Yes, OnFieldWork.com is designed to be flexible and + adaptable. You can customize workflows, user roles, + permissions, and reporting to match your organization’s + unique processes. Depending on your plan, we also + support advanced customization such as integrating with + third-party tools, adding custom fields, and tailoring + modules to fit your business requirements. +
+
+
{" "} +
+
+
+
+
+ {/* FAQ: End */} + + {/* CTA: Start */} +
+ cta image +
+
+ Contact US +
+ +
+
+ hero elements +
+
+
+ {" "} +

+ + Let's Work + {/* laptop charging */} + + Together +

+

+ Any question or remark? just write us a message +

+
+
+
+
+ +
+ +
+
+
+
+
+ +
+
+

Phone

+
+ + +91 70288 83755 + +
+
+
+
+
+
+
+
+ Ready to Get Started? +
+
+ Start your project with a free trial +
+ {/* + Get Started + {" "} */} + + Request a Demo + +
+
+
+
+
+ {/* CTA: End */} + + {/* Contact Us: Start */} +
+
+
+ Contact US +
+

+ + Let's work + laptop charging + + together +

+

+ Any question or remark? just write us a message +

+
+
+
+ contact border + contact customer service +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+
+

Phone

+
+ + +1234 568 963 + +
+
+
+
+
+
+
+
+
+
+
+

Send a message

+

+ If you would like to discuss anything related to payment, + account, licensing, +
+ partnerships, or have pre-sales questions, you’re at the + right place. +

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+
+
+
+
+ {/* Contact Us: End */} +
+ + {/* / Sections:End */} + + {/* Footer: Start */} + + {/* Footer: End */} +
+ ); +}; +export default LandingPageOld; diff --git a/src/pages/Home/SubscriptionPlans.jsx b/src/pages/Home/SubscriptionPlans.jsx index 8e7a736a..59ef4a7e 100644 --- a/src/pages/Home/SubscriptionPlans.jsx +++ b/src/pages/Home/SubscriptionPlans.jsx @@ -10,8 +10,6 @@ const SubscriptionPlans = () => { const { data, isLoading, isError, error } = useSubscription(frequency); const [loading, setLoading] = useState(false); - - const frequencyLabel = (freq) => { switch (freq) { case 0: @@ -104,13 +102,13 @@ const SubscriptionPlans = () => {
Features
-
    +
      {plan.features?.modules && Object.values(plan.features.modules).map((mod) => mod && mod.name ? (
    • {mod.enabled ? ( @@ -124,20 +122,20 @@ const SubscriptionPlans = () => {
    {/* Button */} -
    - - Subscribe - - - Request a Demo - -
    +
    + + Subscribe + + + Request a Demo + +
)) diff --git a/src/pages/Home/SwaperSlideImages.jsx b/src/pages/Home/SwaperSlideImages.jsx new file mode 100644 index 00000000..9300b12c --- /dev/null +++ b/src/pages/Home/SwaperSlideImages.jsx @@ -0,0 +1,26 @@ +import { SwiperSlide } from "swiper/react"; + +const SwaperSlideImages = ({ + ImageUrl = "../../../public/assets/img/backgrounds/18.jpg", + Title = "", + Body = "", + ContentAlign = "right", +}) => { + return ( +
+ Card image cap + {/*
+
Card title
+

+ Some quick example text to build on the card title and make up the + bulk of the card's content. +

+ + Go somewhere + +
*/} +
+ ); +}; + +export default SwaperSlideImages; diff --git a/src/pages/Organization/OrganizationPage.jsx b/src/pages/Organization/OrganizationPage.jsx index 95629d87..017245e9 100644 --- a/src/pages/Organization/OrganizationPage.jsx +++ b/src/pages/Organization/OrganizationPage.jsx @@ -6,12 +6,15 @@ import OrganizationsList from "../../components/Organization/OrganizationsList"; const OrganizationPage = () => { const { isOpen, orgData, startStep, onOpen, flowType } = useOrganizationModal(); - const [searchText, setSearchText] = useState("") + const [searchText, setSearchText] = useState(""); return (
@@ -29,27 +32,24 @@ const OrganizationPage = () => {
-
+
- -
- +
-
); }; diff --git a/src/pages/PaymentRequest/PaymentRequestPage.jsx b/src/pages/PaymentRequest/PaymentRequestPage.jsx index e176cfb9..7b7d2ff1 100644 --- a/src/pages/PaymentRequest/PaymentRequestPage.jsx +++ b/src/pages/PaymentRequest/PaymentRequestPage.jsx @@ -82,7 +82,7 @@ const PaymentRequestPage = () => { {/* Breadcrumb */} { className="form-control form-control-sm w-auto" placeholder="Search Payment Request" value={search} - style={{minWidth:"200px"}} + style={{ minWidth: "200px" }} onChange={(e) => setSearch(e.target.value)} />
@@ -156,7 +156,6 @@ const PaymentRequestPage = () => { )} - {isExpenseGenerate.IsOpen && ( { + const { projectId } = useParams(); + const { + data: projectdata, + isLoading: isProjectLoading, + isProjectError, + } = useServiceProject(projectId); + const [activePill, setActivePill] = useState( sessionStorage.getItem("servicePrjectTab") || "profile" ); @@ -17,19 +28,22 @@ const ServiceProjectDetail = () => { switch (activePill) { case "profile": return ; - case "jobs": + case "teams": + return ; + case "jobs": return ; default: return ; } }; + return (
diff --git a/src/pages/authentication/MainLogin.css b/src/pages/authentication/MainLogin.css index 5ac6d208..dd6a759e 100644 --- a/src/pages/authentication/MainLogin.css +++ b/src/pages/authentication/MainLogin.css @@ -29,15 +29,6 @@ font-size: 16px; font-weight: 300; } -ul { - font-size: 16px; - font-weight: 300; - list-style-type: disc; - margin-block-start: 1em; - margin-block-end: 1em; - padding-inline-start: 40px; - unicode-bidi: isolate; -} ul li { /* padding: 10px 10px 10px 0; */ @@ -48,16 +39,21 @@ li { margin: 0px; display: list-item; } -.ul.more-features-list { - max-width: 430px; - padding: 10px 0 0 0; - display: block; -} + ul.more-features-list { + font-size: 16px; + font-weight: 300; + list-style-type: none; + margin-block-start: 1em; + margin-block-end: 1em; + padding-inline-start: 40px; + unicode-bidi: isolate; display: block; position: relative; margin-left: 10px; + padding: 10px 0 0 0; + display: block; } .list-item { @@ -93,3 +89,16 @@ ul.more-features-list { stroke-dasharray: 125.6; transform: rotate(-90deg); } + +.login-pg-swiper { + width: 80vw; /* 80% of viewport width */ + height: 70vh; /* 70% of viewport height */ + margin: auto; /* Center the swiper container */ +} + +.swiper-slide img.login-pg-img-swiper { + display: block; + width: 100%; /* Image takes full width of the slide (which is 80vw) */ + height: 100%; /* Image takes full height of the slide (which is 70vh) */ + object-fit: contain; /* Ensures the entire image is visible without stretching, maintaining aspect ratio */ +} diff --git a/src/pages/authentication/MainLogin.jsx b/src/pages/authentication/MainLogin.jsx index 271770dc..1de9f1f2 100644 --- a/src/pages/authentication/MainLogin.jsx +++ b/src/pages/authentication/MainLogin.jsx @@ -1,249 +1,293 @@ import { React, useRef } from "react"; import LoginPage from "./LoginPage"; import "./MainLogin.css"; -import { Swiper, SwiperSlide } from "swiper/react"; -import { EffectFlip, Autoplay, Pagination, Navigation } from "swiper/modules"; const MainLogin = () => { - const progressCircle = useRef(null); - const progressContent = useRef(null); - const onAutoplayTimeLeft = (s, time, progress) => { - progressCircle.current.style.setProperty("--progress", 1 - progress); - progressContent.current.textContent = `${Math.ceil(time / 1000)}s`; - }; return ( <>
-
- {}} - onSwiper={(swiper) => {}} - onAutoplayTimeLeft={onAutoplayTimeLeft} + {/*
*/} + diff --git a/src/pages/collections/CollectionPage.jsx b/src/pages/collections/CollectionPage.jsx index fbac9564..0dbe446c 100644 --- a/src/pages/collections/CollectionPage.jsx +++ b/src/pages/collections/CollectionPage.jsx @@ -101,7 +101,7 @@ const CollectionPage = () => { ) { return ( ); } @@ -109,7 +109,10 @@ const CollectionPage = () => {
@@ -117,7 +120,8 @@ const CollectionPage = () => { {/* Left side: Date Picker + Show Pending (stacked on mobile) */}
- +
@@ -152,16 +156,18 @@ const CollectionPage = () => { )}
-
-
{ const [projectList, setProjectList] = useState([]); const [listView, setListView] = useState(false); const [searchTerm, setSearchTerm] = useState(""); - const [coreProjects, setCoreProjects] = useState(() => { - const storedValue = sessionStorage.getItem('whichProjectDisplay'); - return storedValue === 'true'; -}); + const [coreProjects, setCoreProjects] = useState(() => { + const storedValue = sessionStorage.getItem('whichProjectDisplay'); + return storedValue === 'true'; + }); const HasManageProject = useHasUserPermission(MANAGE_PROJECT); const [selectedStatuses, setSelectedStatuses] = useState( @@ -58,11 +58,11 @@ const ProjectPage = () => { }; -const handleToggleProject = (e) => { - const checked = e.target.checked; - setCoreProjects(checked); - sessionStorage.setItem('whichProjectDisplay', String(checked)); -}; + const handleToggleProject = (value) => { + setCoreProjects(value); + sessionStorage.setItem("whichProjectDisplay", String(value)); + }; + return ( @@ -75,10 +75,39 @@ const handleToggleProject = (e) => { />
-
+
-
-
+ {/* LEFT SIDE — DATE TOGGLE BUTTONS */} +
+
+ {/* Service Project Button */} + + {/* Organization Project Button */} + + +
+
+ + + {/* RIGHT SIDE — SEARCH + CARD/LIST + DROPDOWN */} +
+ + {/* Search */} +
{ />
-
+ {/* Card/List Buttons */} +
+
-
+ {/* Dropdown Filter */} +
+
    {PROJECT_STATUS.map(({ id, label }) => (
  • handleStatusChange(id)} @@ -144,56 +168,27 @@ const handleToggleProject = (e) => { ))}
-
- - -
-
- {HasManageProject && ( -
- + {HasManageProject && ( - -
- )} + )} + + +
+ +
diff --git a/src/repositories/ColllectionRepository.jsx b/src/repositories/ColllectionRepository.jsx index 8eb512da..04db4369 100644 --- a/src/repositories/ColllectionRepository.jsx +++ b/src/repositories/ColllectionRepository.jsx @@ -4,26 +4,46 @@ import { DirectoryRepository } from "./DirectoryRepository"; export const CollectionRepository = { createNewCollection: (data) => api.post(`/api/Collection/invoice/create`, data), - updateCollection:(id,data)=>{ - api.put(`/api/Collection/invoice/edit/${id}`,data) + updateCollection: (id, data) => { + api.put(`/api/Collection/invoice/edit/${id}`, data) }, - getCollections: (pageSize, pageNumber,fromDate,toDate, isPending,isActive,projectId, searchString) => { - let url = `/api/Collection/invoice/list?pageSize=${pageSize}&pageNumber=${pageNumber}&isPending=${isPending}&isActive=${isActive}&searchString=${searchString}`; + // getCollections: (pageSize, pageNumber,fromDate,toDate, isPending,isActive,projectId, searchString) => { + // let url = `/api/Collection/invoice/list?pageSize=${pageSize}&pageNumber=${pageNumber}&isPending=${isPending}&isActive=${isActive}&searchString=${searchString}`; + // const params = []; + // if (fromDate) params.push(`fromDate=${fromDate}`); + // if (toDate) params.push(`toDate=${toDate}`); + // if(projectId) params.push(`projectId=${projectId}`) + + // if (params.length > 0) { + // url += `&${params.join("&")}`; + // } + // return api.get(url); + // }, + + getCollections: (projectId, searchString, fromDate, toDate, pageSize, pageNumber, isActive, isPending) => { + let url = `/api/Collection/invoice/list`; const params = []; - if (fromDate) params.push(`fromDate=${fromDate}`); - if (toDate) params.push(`toDate=${toDate}`); - if(projectId) params.push(`projectId=${projectId}`) + + if (projectId) params.push(`projectId=${projectId}`); + if (searchString) params.push(`search=${searchString}`); + if (fromDate) params.push(`dateFrom=${fromDate}`); + if (toDate) params.push(`dateTo=${toDate}`); + if (pageSize) params.push(`pageSize=${pageSize}`); + if (pageNumber) params.push(`pageNumber=${pageNumber}`); + if (isActive) params.push(`isActive=${isActive}`); + if (isPending) params.push(`isPending=${isPending}`); if (params.length > 0) { - url += `&${params.join("&")}`; + url += "?" + params.join("&"); } - return api.get(url); + + return api.get(url); }, - makeReceivePayment:(data)=> api.post(`/api/Collection/invoice/payment/received`,data), - markPaymentReceived:(invoiceId)=>api.put(`/api/Collection/invoice/marked/completed/${invoiceId}`), - getCollection:(id)=>api.get(`/api/Collection/invoice/details/${id}`), - addComment:(data)=>api.post(`/api/Collection/invoice/add/comment`,data) + makeReceivePayment: (data) => api.post(`/api/Collection/invoice/payment/received`, data), + markPaymentReceived: (invoiceId) => api.put(`/api/Collection/invoice/marked/completed/${invoiceId}`), + getCollection: (id) => api.get(`/api/Collection/invoice/details/${id}`), + addComment: (data) => api.post(`/api/Collection/invoice/add/comment`, data) }; diff --git a/src/repositories/MastersRepository.jsx b/src/repositories/MastersRepository.jsx index 9542300d..72b3e2a0 100644 --- a/src/repositories/MastersRepository.jsx +++ b/src/repositories/MastersRepository.jsx @@ -149,5 +149,12 @@ export const MasterRespository = { getCurrencies: () => api.get(`/api/Master/currencies/list`), - getRecurringStatus:()=>api.get(`/api/Master/recurring-status/list`) + getRecurringStatus: () => api.get(`/api/Master/recurring-status/list`), + // Service Job JobTickets Status + getJobStatus: (statusId,projectId) => + api.get( + `/api/Master/job-status/list?statusId=${statusId}&projectId=${projectId}` + ), + + getTeamRole: () => api.get(`/api/Master/team-roles/list`), }; diff --git a/src/repositories/ProjectRepository.jsx b/src/repositories/ProjectRepository.jsx index 1220d085..1de7d87e 100644 --- a/src/repositories/ProjectRepository.jsx +++ b/src/repositories/ProjectRepository.jsx @@ -1,7 +1,7 @@ import { api } from "../utils/axiosClient"; const ProjectRepository = { - getProjectList: (pageSize,pageNumber) => api.get(`/api/project/list?pageSize=${pageSize}&pageNumber=${pageNumber}`), + getProjectList: (pageNumber,pageSize) => api.get(`/api/project/list?&pageNumber=${pageNumber}&pageSize=${pageSize}`), getProjectByprojectId: (projetid) => api.get(`/api/project/details/${projetid}`), diff --git a/src/repositories/ServiceProjectRepository.jsx b/src/repositories/ServiceProjectRepository.jsx index 541d63de..94ef3c8e 100644 --- a/src/repositories/ServiceProjectRepository.jsx +++ b/src/repositories/ServiceProjectRepository.jsx @@ -11,13 +11,28 @@ export const ServiceProjectRepository = { api.put(`/api/ServiceProject/edit/${id}`, data), DeleteServiceProject: (id, isActive = false) => api.delete(`/api/ServiceProject/delete/${id}?isActive=${isActive}`), - + AllocateEmployee: (data) => + api.post(`/api/ServiceProject/manage/allocation`, data), + GetAllocatedEmployees: (projectId, isActive) => + api.get( + `/api/ServiceProject/get/allocation/list?projectId=${projectId}&isActive=${isActive} ` + ), //#region Job CreateJob: (data) => api.post(`/api/ServiceProject/job/create`, data), - GetJobList: (pageSize, pageNumber, isActive,projectId,) => + GetJobList: (pageSize, pageNumber, isActive, projectId) => api.get( `/api/ServiceProject/job/list?pageSize=${pageSize}&pageNumber=${pageNumber}&isActive=${isActive}&projectId=${projectId}` ), - GetJobDetails:(id)=>api.get(`/api/ServiceProject/job/details/${id}`) + GetJobDetails: (id) => api.get(`/api/ServiceProject/job/details/${id}`), + AddComment: (data) => api.post("/api/ServiceProject/job/add/comment", data), + GetJobComment: (jobTicketId, pageSize, pageNumber) => + api.get( + `/api/ServiceProject/job/comment/list?jobTicketId=${jobTicketId}&pageSize=${pageSize}&pageNumber=${pageNumber}` + ), + GetJobTags: () => api.get(`/api/ServiceProject/job/tag/list`), + UpdateJob: (id, patchData) => + api.patch(`/api/ServiceProject/job/edit/${id}`, patchData, { + "Content-Type": "application/json-patch+json", + }), }; diff --git a/src/router/AppRoutes.jsx b/src/router/AppRoutes.jsx index 86feec5f..1c95ec64 100644 --- a/src/router/AppRoutes.jsx +++ b/src/router/AppRoutes.jsx @@ -95,7 +95,7 @@ const router = createBrowserRouter( { path: "/projects", element: }, { path: "/projects/details", element: }, { path: "/project/manage/:projectId", element: }, - { path: "service-projects/:id", element: }, + { path: "/service-projects/:projectId", element: }, {path:"/service/job",element:}, { path: "/employees", element: }, diff --git a/src/router/ProtectedRoute.jsx b/src/router/ProtectedRoute.jsx index 9179d43d..2a741df6 100644 --- a/src/router/ProtectedRoute.jsx +++ b/src/router/ProtectedRoute.jsx @@ -24,7 +24,6 @@ const validateToken = async () => { sessionStorage.getItem("refreshToken"); if (!refreshTokenStored){ - console.log("no refrh tokem"); removeSession() return false }; diff --git a/src/services/signalRService.js b/src/services/signalRService.js index 49607c80..9b96b95a 100644 --- a/src/services/signalRService.js +++ b/src/services/signalRService.js @@ -23,8 +23,11 @@ export function startSignalR(loggedUser) { transport: signalR.HttpTransportType.LongPolling, withCredentials: false, }) + // .withKeepAliveInterval(30000) + // .withServerTimeout(30000) .withAutomaticReconnect() .build(); + connection.serverTimeoutInMilliseconds = 30000; // 60 seconds const todayDate = new Date(); const today = new Date( Date.UTC(todayDate.getFullYear(), todayDate.getMonth(), todayDate.getDate()) @@ -140,6 +143,24 @@ export function startSignalR(loggedUser) { ) { emitters.image_gallery(); } + + // --- Service Project ---------------- + + if (keyword === "Service_Project") { + queryClient.invalidateQueries(["serviceProjects"]); + queryClient.invalidateQueries(["serviceProject"]); + } + + if (keyword === "Service_Project_Allocation") { + queryClient.invalidateQueries(["serviceProjectTeam"]); + } + if (keyword === "Job_Ticket") { + queryClient.invalidateQueries(["serviceProjectJobs"]); + queryClient.invalidateQueries(["service-job"]); + } + if (keyword === "Job_Ticket_Comment") { + queryClient.invalidateQueries(["jobComments"]); + } }); connection.start(); diff --git a/src/slices/localVariablesSlice.jsx b/src/slices/localVariablesSlice.jsx index fba4390c..2e2951ba 100644 --- a/src/slices/localVariablesSlice.jsx +++ b/src/slices/localVariablesSlice.jsx @@ -11,6 +11,9 @@ const localVariablesSlice = createSlice({ SelectedOrg: "", }, + // PopUp + popups: {}, + // Modal for all simple pass Name modals: { @@ -35,9 +38,9 @@ const localVariablesSlice = createSlice({ selfTenant: { tenantEnquireId: null, planId: null, - details:null, - frequency:null, - paymentDetailId:null + details: null, + frequency: null, + paymentDetailId: null, }, }, reducers: { @@ -94,26 +97,52 @@ const localVariablesSlice = createSlice({ openModal: (state, action) => { const { modalType, data } = action.payload; - state.modals[modalType] = { isOpen: true, ...data }; + + state.modals[modalType] = { + isOpen: true, + data: data ?? {}, + }; }, + closeModal: (state, action) => { const { modalType } = action.payload; - state.modals[modalType] = { ...state.modals[modalType], isOpen: false }; + state.modals[modalType] = { + isOpen: false, + data: null, + }; }, + toggleModal: (state, action) => { const { modalType } = action.payload; - state.modals[modalType].isOpen = !state.modals[modalType].isOpen; + const modal = state.modals[modalType] || {}; + modal.isOpen = !modal.isOpen; }, + setSelfTenant: (state, action) => { state.selfTenant.tenantEnquireId = action.payload.tenantEnquireId ?? state.selfTenant.tenantEnquireId; state.selfTenant.planId = action.payload.planId ?? state.selfTenant.planId; - state.selfTenant.details = + state.selfTenant.details = action.payload.details ?? state.selfTenant.details; - state.selfTenant.frequency = action.payload.frequency ?? state.selfTenant.frequency; - state.selfTenant.paymentDetailId = action.payload.paymentDetailId ?? state.selfTenant.paymentDetailId; + state.selfTenant.frequency = + action.payload.frequency ?? state.selfTenant.frequency; + state.selfTenant.paymentDetailId = + action.payload.paymentDetailId ?? state.selfTenant.paymentDetailId; }, + + openPopup: (state, action) => { + const id = action.payload; + state.popups[id] = true; + }, + closePopup: (state, action) => { + const id = action.payload; + state.popups[id] = false; + }, + togglePopup: (state, action) => { + const id = action.payload; + state.popups[id] = !state.popups[id]; + } }, }); @@ -132,6 +161,6 @@ export const { openModal, closeModal, toggleModal, - setSelfTenant, + setSelfTenant,openPopup, closePopup, togglePopup } = localVariablesSlice.actions; export default localVariablesSlice.reducer; diff --git a/src/utils/appUtils.js b/src/utils/appUtils.js index 5cb6068c..563520be 100644 --- a/src/utils/appUtils.js +++ b/src/utils/appUtils.js @@ -51,13 +51,15 @@ export const useDebounce = (value, delay = 500) => { export const getIconByFileType = (type = "") => { const lower = type.toLowerCase(); - if (lower === "application/pdf") return "bxs-file-pdf"; - if (lower.includes("word")) return "bxs-file-doc"; + if (lower === "application/pdf") return "bxs-file-pdf text-danger"; + if (lower.includes("word")) return "bxs-file-doc text-primary text-primry"; if (lower.includes("excel") || lower.includes("spreadsheet")) - return "bxs-file-xls"; + return "bxs-file-xls text-primry"; if (lower === "image/png") return "bxs-file-png"; - if (lower === "image/jpeg" || lower === "image/jpg") return "bxs-file-jpg"; - if (lower.includes("zip") || lower.includes("rar")) return "bxs-file-archive"; + if (lower === "image/jpeg" || lower === "image/jpg") + return "bxs-file-jpg text-primry"; + if (lower.includes("zip") || lower.includes("rar")) + return "bxs-file-archive text-secondary"; return "bx bx-file"; }; @@ -192,19 +194,55 @@ export const frequencyLabel = ( } }; -const badgeColors = [ - "primary", - "secondary", - "success", - "warning", - "info", -]; +const badgeColors = ["primary", "secondary", "success", "warning", "info"]; let colorIndex = 0; -export function getNextBadgeColor(type="label") { +export function getNextBadgeColor(type = "label") { const color = badgeColors[colorIndex]; - colorIndex = (colorIndex + 1) % badgeColors.length; + colorIndex = (colorIndex + 1) % badgeColors.length; return `rounded-pill text-bg-${color}`; } +export function daysLeft(startDate, dueDate) { + if (!startDate || !dueDate) { + return { days: null, color: "label-secondary" }; + } + + const start = new Date(startDate); + const due = new Date(dueDate); + + const today = new Date(); + const diffTime = due.getTime() - today.getTime(); + const days = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); + + let color = "label-primary"; // default + + if (days < 0) { + color = "label-danger"; // overdue → red + } else if (days <= 15) { + color = "label-warning"; // near due → yellow + } else { + color = "label-primary"; // safe range + } + + return { days, color }; +} + +export function calculateTDSPercentage(baseAmount = 0, taxAmount = 0, tdsPercentage = 0) { + baseAmount = Number(baseAmount) || 0; + taxAmount = Number(taxAmount) || 0; + tdsPercentage = Number(tdsPercentage) || 0; + + const grossAmount = baseAmount + taxAmount; + const tdsAmount = (baseAmount * tdsPercentage) / 100; + const netPayable = grossAmount - tdsAmount; + + return { + grossAmount, + tdsAmount, + netPayable, + }; +} + + diff --git a/src/utils/axiosClient.jsx b/src/utils/axiosClient.jsx index 0f2f14a2..40981633 100644 --- a/src/utils/axiosClient.jsx +++ b/src/utils/axiosClient.jsx @@ -178,6 +178,12 @@ export const api = { headers: { ...customHeaders }, authRequired: true, }), + patch: (url, data = {}, customHeaders = {}) => + apiRequest("patch", url, data, { + headers: { ...customHeaders }, + authRequired: true, + }), + }; // Redirect helper