Compare commits
171 Commits
Kartik_Bug
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 96bcdffdca | |||
| f8963ef476 | |||
| 9ad3b8726c | |||
| d4582c101a | |||
| c6af020c85 | |||
| 822ff1a7e4 | |||
| 92d17167b1 | |||
| 8ec62827d5 | |||
| 965fce1587 | |||
| bb37fd7044 | |||
| 03d60bf66d | |||
| 071e5956a7 | |||
| c669eb90c3 | |||
| 4d2e37f52e | |||
| 6dde240926 | |||
| 482b5a1680 | |||
| 098090cf69 | |||
| 5747d4ec71 | |||
| 48f314eac4 | |||
| 18e739f3ab | |||
| a5329f1a2a | |||
| 8b4a9d2d1c | |||
| 4506f740eb | |||
| f001dff5b0 | |||
| 33d94f6f06 | |||
| 0ac1141579 | |||
| 4d8af5da91 | |||
| fead3a37a6 | |||
| 98e9a8b625 | |||
| 2781da8906 | |||
| d13c48dd39 | |||
| ee4ef18594 | |||
| 742337a3d0 | |||
| 5abab06b0c | |||
| 17a9f4a9b1 | |||
| de088fcfc2 | |||
| 8e12eb6797 | |||
| 14c1da7888 | |||
| 753d8c4a2c | |||
| 766d19744c | |||
| caaadc4c08 | |||
| 1531fbe6f2 | |||
| 9f5a167613 | |||
| fa923d4c3a | |||
| bd43475d12 | |||
| 521d46bdee | |||
| 604bb68dc2 | |||
| 047e563505 | |||
| e4f053ee65 | |||
| 7105a3640f | |||
| d167c57ab0 | |||
| d3c006279c | |||
| 195a0c83bb | |||
| 8f86b05d35 | |||
| dd716187da | |||
| 5b86a2f64f | |||
| e99d49b83e | |||
| 0210e17170 | |||
| e7fddd41c2 | |||
| 7e4dffff34 | |||
| e7a68aeab7 | |||
| 8a5d6158c2 | |||
| 50269aead2 | |||
| 0ede07b0d5 | |||
| df24b18a27 | |||
| f5d89f2bab | |||
| 15978b2ac7 | |||
| 2dbf5dc109 | |||
| 7cc8cc99c2 | |||
| c04ee8dab5 | |||
| c52f85ee4a | |||
| c718269dfd | |||
| 268bd2875f | |||
| 7773b7a43b | |||
| 25003d912e | |||
| a3be63b74f | |||
| 54420c70d9 | |||
| 4b5f8756b3 | |||
| 10e54637d5 | |||
| 3fe533c8e3 | |||
| 5b91c13b85 | |||
| ed87e3f11b | |||
| e276836653 | |||
| 523d6baea6 | |||
| 9e47f10440 | |||
| 54d89e1429 | |||
| 018f132501 | |||
| f3eed11540 | |||
| 836b34c237 | |||
| bf92ffcb3e | |||
| dd380f6820 | |||
| f997c2f2cc | |||
| 1c5d62f5ed | |||
| 37dbbf53f3 | |||
| 2cb9b41f98 | |||
| e6e27beb6f | |||
| 9822ae91ec | |||
| 3753d01f7d | |||
| c8a599fc8f | |||
| 1c2674d435 | |||
| 31d340c645 | |||
| 61e210c305 | |||
| dd41600045 | |||
| 72052a4708 | |||
| 4dfc0fa7ca | |||
| 3cfac9a2bb | |||
| b14353dd4f | |||
| 8de1230f79 | |||
| 9b65e0a320 | |||
| 70ed617b9b | |||
| d4bb7373f2 | |||
| f4f14127b7 | |||
| c8bbf6b8a8 | |||
| 36be17daa7 | |||
| d6b2ed9f84 | |||
| 088e5e0368 | |||
| 977e5c77a7 | |||
| 2b1d3e5890 | |||
| a61e621ce2 | |||
| 0bd1cea703 | |||
| d6ef713370 | |||
| da391368a6 | |||
| 6860ba3dff | |||
| 849567f999 | |||
| 507bc68da9 | |||
| 767475c7e5 | |||
| 5f649cd917 | |||
| ea6686560d | |||
| 1358cd749a | |||
| d95ba4c800 | |||
| 78eafd2e5a | |||
| 6598ec9f73 | |||
| 679ae95b8c | |||
| 4f03cbb305 | |||
| d342550b0f | |||
| 4f7ad519cf | |||
| c311324bad | |||
| 937531afb6 | |||
| b68f8306fd | |||
| 7470a6836f | |||
| 12184091cd | |||
| 8761c128e6 | |||
| 8eb34addcd | |||
| b568188a3e | |||
| a21bec943d | |||
| 3d1d8264ad | |||
| d831d08aaf | |||
| 8553b6bee7 | |||
| e47262123d | |||
| 852ebd7dd0 | |||
| fc1235caef | |||
| 7e646ca3e8 | |||
| 92bcfb73c6 | |||
| 770123119c | |||
| 7190a3c190 | |||
| b399977946 | |||
| 64d96d46d0 | |||
| 05f45a66d8 | |||
| 0b38196847 | |||
| 598601c515 | |||
| 14ed888fe8 | |||
| b13034a995 | |||
| 32b7c53b6c | |||
| c0378e1d7d | |||
| 6019114853 | |||
| 15e67da7f6 | |||
| 8900ed6fc4 | |||
| 04a3141f65 | |||
| 1067ac02b3 | |||
| 717d215d8e | |||
| b86bf204a9 |
17
public/assets/vendor/css/core.css
vendored
@ -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.85rem;
|
||||
--bs-body-font-weight: 400;
|
||||
--bs-body-line-height: 1.375;
|
||||
--bs-body-color: #646e78;
|
||||
@ -9059,7 +9060,7 @@ img[data-app-light-img][data-app-dark-img] {
|
||||
}
|
||||
.table th {
|
||||
color: var(--bs-heading-color);
|
||||
font-size: 0.8125rem;
|
||||
font-size: 0.8025rem;
|
||||
letter-spacing: 0.2px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@ -20344,7 +20345,7 @@ li:not(:first-child) .dropdown-item,
|
||||
}
|
||||
|
||||
.fs-6 {
|
||||
font-size: 0.9375rem !important;
|
||||
font-size: 0.8375rem !important;
|
||||
}
|
||||
|
||||
.fs-tiny {
|
||||
@ -32559,9 +32560,7 @@ body:not(.modal-open) .layout-content-navbar .layout-navbar {
|
||||
.bg-blue {
|
||||
background-color:var(--bs-blue)
|
||||
}
|
||||
.text-blue{
|
||||
color:var(--bs-blue)
|
||||
}
|
||||
|
||||
.bg-indigo {
|
||||
background-color:var(--bs-indigo)
|
||||
}
|
||||
@ -32573,4 +32572,10 @@ body:not(.modal-open) .layout-content-navbar .layout-navbar {
|
||||
}
|
||||
.text-red{
|
||||
color:var(--bs-red)
|
||||
}
|
||||
.text-blue{
|
||||
color:var(--bs-blue)
|
||||
}
|
||||
.text-green{
|
||||
color:var(--bs-green)
|
||||
}
|
||||
|
Before Width: | Height: | Size: 273 KiB |
|
Before Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
BIN
public/img/brand/marco-250x250.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
public/img/brand/ofw-500x500.png
Normal file
|
After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 21 KiB |
BIN
public/img/hero/bg-01.jpg
Normal file
|
After Width: | Height: | Size: 500 KiB |
BIN
public/img/hero/bg-02.png
Normal file
|
After Width: | Height: | Size: 201 KiB |
BIN
public/img/hero/bg-03.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
public/img/hero/bg-04.png
Normal file
|
After Width: | Height: | Size: 233 KiB |
|
Before Width: | Height: | Size: 860 KiB After Width: | Height: | Size: 860 KiB |
BIN
public/img/icons/ai.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
public/img/icons/apple-icon-lite.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
public/img/icons/attendance.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
public/img/icons/cloud-service.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/img/icons/dashboard.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/img/icons/directory.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/img/icons/document.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
public/img/icons/google-play-icon-lite.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 3.5 KiB |
BIN
public/img/icons/profile.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/img/icons/report.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/img/icons/spending.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 140 KiB |
BIN
public/img/illustrations/contact-customer-service.png
Normal file
|
After Width: | Height: | Size: 860 KiB |
BIN
public/img/illustrations/contact-us.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
public/img/illustrations/fm-01.png
Normal file
|
After Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 426 KiB |
|
Before Width: | Height: | Size: 395 KiB |
|
Before Width: | Height: | Size: 267 KiB |
|
Before Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 252 KiB |
|
Before Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 62 KiB |
@ -1,42 +0,0 @@
|
||||
<svg width="25" viewBox="0 0 25 42" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<path
|
||||
d="M13.7918663,0.358365126 L3.39788168,7.44174259 C0.566865006,9.69408886 -0.379795268,12.4788597 0.557900856,15.7960551 C0.68998853,16.2305145 1.09562888,17.7872135 3.12357076,19.2293357 C3.8146334,19.7207684 5.32369333,20.3834223 7.65075054,21.2172976 L7.59773219,21.2525164 L2.63468769,24.5493413 C0.445452254,26.3002124 0.0884951797,28.5083815 1.56381646,31.1738486 C2.83770406,32.8170431 5.20850219,33.2640127 7.09180128,32.5391577 C8.347334,32.0559211 11.4559176,30.0011079 16.4175519,26.3747182 C18.0338572,24.4997857 18.6973423,22.4544883 18.4080071,20.2388261 C17.963753,17.5346866 16.1776345,15.5799961 13.0496516,14.3747546 L10.9194936,13.4715819 L18.6192054,7.984237 L13.7918663,0.358365126 Z"
|
||||
id="path-1"></path>
|
||||
<path
|
||||
d="M5.47320593,6.00457225 C4.05321814,8.216144 4.36334763,10.0722806 6.40359441,11.5729822 C8.61520715,12.571656 10.0999176,13.2171421 10.8577257,13.5094407 L15.5088241,14.433041 L18.6192054,7.984237 C15.5364148,3.11535317 13.9273018,0.573395879 13.7918663,0.358365126 C13.5790555,0.511491653 10.8061687,2.3935607 5.47320593,6.00457225 Z"
|
||||
id="path-3"></path>
|
||||
<path
|
||||
d="M7.50063644,21.2294429 L12.3234468,23.3159332 C14.1688022,24.7579751 14.397098,26.4880487 13.008334,28.506154 C11.6195701,30.5242593 10.3099883,31.790241 9.07958868,32.3040991 C5.78142938,33.4346997 4.13234973,34 4.13234973,34 C4.13234973,34 2.75489982,33.0538207 2.37032616e-14,31.1614621 C-0.55822714,27.8186216 -0.55822714,26.0572515 -4.05231404e-15,25.8773518 C0.83734071,25.6075023 2.77988457,22.8248993 3.3049379,22.52991 C3.65497346,22.3332504 5.05353963,21.8997614 7.50063644,21.2294429 Z"
|
||||
id="path-4"></path>
|
||||
<path
|
||||
d="M20.6,7.13333333 L25.6,13.8 C26.2627417,14.6836556 26.0836556,15.9372583 25.2,16.6 C24.8538077,16.8596443 24.4327404,17 24,17 L14,17 C12.8954305,17 12,16.1045695 12,15 C12,14.5672596 12.1403557,14.1461923 12.4,13.8 L17.4,7.13333333 C18.0627417,6.24967773 19.3163444,6.07059163 20.2,6.73333333 C20.3516113,6.84704183 20.4862915,6.981722 20.6,7.13333333 Z"
|
||||
id="path-5"></path>
|
||||
</defs>
|
||||
<g id="g-app-brand" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Brand-Logo" transform="translate(-27.000000, -15.000000)">
|
||||
<g id="Icon" transform="translate(27.000000, 15.000000)">
|
||||
<g id="Mask" transform="translate(0.000000, 8.000000)">
|
||||
<mask id="mask-2" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<use fill="#696cff" xlink:href="#path-1"></use>
|
||||
<g id="Path-3" mask="url(#mask-2)">
|
||||
<use fill="#696cff" xlink:href="#path-3"></use>
|
||||
<use fill-opacity="0.2" fill="#FFFFFF" xlink:href="#path-3"></use>
|
||||
</g>
|
||||
<g id="Path-4" mask="url(#mask-2)">
|
||||
<use fill="#696cff" xlink:href="#path-4"></use>
|
||||
<use fill-opacity="0.2" fill="#FFFFFF" xlink:href="#path-4"></use>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Triangle"
|
||||
transform="translate(19.000000, 11.000000) rotate(-300.000000) translate(-19.000000, -11.000000) ">
|
||||
<use fill="#696cff" xlink:href="#path-5"></use>
|
||||
<use fill-opacity="0.2" fill="#FFFFFF" xlink:href="#path-5"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 54 KiB |
@ -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 && <OrganizationModal />}
|
||||
{isAuthOpen && <SwitchTenant />}
|
||||
{isChangePass && <ChangePasswordPage /> }
|
||||
{isCollectionNew && <NewCollection/>}
|
||||
{isChangePass && <ChangePasswordPage />}
|
||||
{isCollectionNew && <NewCollection />}
|
||||
{isServiceTeamAllocation && <ServiceProjectTeamAllocation />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModalProvider;
|
||||
export default ModalProvider;
|
||||
|
||||
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 4.0 KiB |
2
src/assets/vendor/css/core.css
vendored
@ -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;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
|
||||
import React, { useEffect, useMemo } from "react";
|
||||
import { useExpenseTransactions } from "../../hooks/useExpense";
|
||||
import { useExpenseAllTransactionsList, useExpenseTransactions } from "../../hooks/useExpense";
|
||||
import Error from "../common/Error";
|
||||
import { formatUTCToLocalTime } from "../../utils/dateUtils";
|
||||
import Loader, { SpinnerLoader } from "../common/Loader";
|
||||
@ -11,11 +11,10 @@ import { employee } from "../../data/masters";
|
||||
import { useAdvancePaymentContext } from "../../pages/AdvancePayment/AdvancePaymentPage";
|
||||
import { formatFigure } from "../../utils/appUtils";
|
||||
|
||||
const AdvancePaymentList = ({ employeeId }) => {
|
||||
const { setBalance } = useAdvancePaymentContext();
|
||||
const AdvancePaymentList = ({ employeeId, searchString }) => {
|
||||
const { setBalance } = useAdvancePaymentContext();
|
||||
const { data, isError, isLoading, error, isFetching } =
|
||||
useExpenseTransactions(employeeId, { enabled: !!employeeId });
|
||||
|
||||
const records = Array.isArray(data) ? data : [];
|
||||
|
||||
let currentBalance = 0;
|
||||
@ -85,7 +84,7 @@ const AdvancePaymentList = ({ employeeId }) => {
|
||||
key: "date",
|
||||
label: (
|
||||
<>
|
||||
Date
|
||||
Date
|
||||
</>
|
||||
),
|
||||
align: "text-start",
|
||||
|
||||
100
src/components/AdvancePayment/AdvancePaymentList1.jsx
Normal file
@ -0,0 +1,100 @@
|
||||
import React from 'react'
|
||||
import Avatar from "../../components/common/Avatar"; // <-- ADD THIS
|
||||
import { useExpenseAllTransactionsList } from '../../hooks/useExpense';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { formatFigure } from '../../utils/appUtils';
|
||||
|
||||
const AdvancePaymentList1 = ({ searchString }) => {
|
||||
|
||||
const { data, isError, isLoading, error } =
|
||||
useExpenseAllTransactionsList(searchString);
|
||||
|
||||
const rows = data || [];
|
||||
const navigate = useNavigate();
|
||||
|
||||
const columns = [
|
||||
{
|
||||
key: "employee",
|
||||
label: "Employee Name",
|
||||
align: "text-start",
|
||||
customRender: (r) => (
|
||||
<div className="d-flex align-items-center gap-2" onClick={() => navigate(`/advance-payment/${r.id}`)}
|
||||
style={{ cursor: "pointer" }}>
|
||||
<Avatar firstName={r.firstName} lastName={r.lastName} />
|
||||
|
||||
<span className="fw-medium">
|
||||
{r.firstName} {r.lastName}
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "jobRoleName",
|
||||
label: "Job Role",
|
||||
align: "text-start",
|
||||
customRender: (r) => (
|
||||
<span className="fw-semibold">
|
||||
{r.jobRoleName}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "balanceAmount",
|
||||
label: "Balance (₹)",
|
||||
align: "text-end",
|
||||
customRender: (r) => (
|
||||
<span className="fw-semibold fs-6">
|
||||
{formatFigure(r.balanceAmount, {
|
||||
// type: "currency",
|
||||
currency: "INR",
|
||||
})}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
if (isLoading) return <p className="text-center py-4">Loading...</p>;
|
||||
if (isError) return <p className="text-center py-4 text-danger">{error.message}</p>;
|
||||
|
||||
return (
|
||||
<div className="card-datatable" id="payment-request-table">
|
||||
<div className="mx-2">
|
||||
<table className="table border-top dataTable text-nowrap align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
{columns.map((col) => (
|
||||
<th key={col.key} className={`sorting ${col.align}`}>
|
||||
{col.label}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{rows.length > 0 ? (
|
||||
rows.map((row) => (
|
||||
<tr key={row.id} className="align-middle" style={{ height: "40px" }}>
|
||||
{columns.map((col) => (
|
||||
<td key={col.key} className={`d-table-cell ${col.align} py-3`}>
|
||||
{col.customRender
|
||||
? col.customRender(row)
|
||||
: col.getValue(row)}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
))
|
||||
) : (
|
||||
<tr>
|
||||
<td colSpan={columns.length} className="text-center border-0 py-3">
|
||||
No Employees Found
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AdvancePaymentList1;
|
||||
@ -54,6 +54,7 @@ const TaskReportFilterPanel = ({ handleFilter }) => {
|
||||
<div className="mb-3 w-100">
|
||||
<label className="fw-semibold">Choose Date Range:</label>
|
||||
<DateRangePicker1
|
||||
className="w-100"
|
||||
placeholder="DD-MM-YYYY To DD-MM-YYYY"
|
||||
startField="dateFrom"
|
||||
endField="dateTo"
|
||||
|
||||
@ -202,6 +202,7 @@ const TaskReportList = () => {
|
||||
<span>
|
||||
Total Pending{" "}
|
||||
<HoverPopup
|
||||
id="total_pending_task"
|
||||
title="Total Pending Task"
|
||||
content={<p>This shows the total pending tasks for each activity on that date.</p>}
|
||||
>
|
||||
@ -213,6 +214,7 @@ const TaskReportList = () => {
|
||||
<span>
|
||||
Reported/Planned{" "}
|
||||
<HoverPopup
|
||||
id="reportes_and_planned_task"
|
||||
title="Reported and Planned Task"
|
||||
content={<p>This shows the reported versus planned tasks for each activity on that date.</p>}
|
||||
>
|
||||
|
||||
@ -100,9 +100,9 @@ const AttendanceOverview = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white p-4 rounded shadow d-flex flex-column h-100">
|
||||
<div className="bg-white px-4 rounded shadow d-flex flex-column h-100">
|
||||
{/* Header */}
|
||||
<div className="d-flex justify-content-between align-items-center mb-3">
|
||||
<div className="d-flex mt-2 justify-content-between align-items-center mb-3">
|
||||
<div className="card-title mb-0 text-start">
|
||||
<h5 className="mb-1 fw-bold">Attendance Overview</h5>
|
||||
<p className="card-subtitle">Role-wise present count</p>
|
||||
@ -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 = () => {
|
||||
<div className="row gy-4">
|
||||
{isAllProjectsSelected && (
|
||||
<div className="col-sm-6 col-lg-4">
|
||||
<Projects />
|
||||
<Projects />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={`${!isAllProjectsSelected ? "col-sm-6 col-lg-6" : "col-sm-6 col-lg-4"}`}>
|
||||
<Teams />
|
||||
<Teams />
|
||||
</div>
|
||||
|
||||
<div className={`${!isAllProjectsSelected ? "col-sm-6 col-lg-6" : "col-sm-6 col-lg-4"}`}>
|
||||
<TasksCard/>
|
||||
<TasksCard />
|
||||
</div>
|
||||
|
||||
{isAllProjectsSelected && (
|
||||
@ -46,32 +46,31 @@ const Dashboard = () => {
|
||||
<ProjectCompletionChart />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!isAllProjectsSelected && (
|
||||
<div className="col-xxl-6 col-lg-6">
|
||||
<ProjectOverview />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="col-xxl-6 col-lg-6">
|
||||
<ProjectProgressChart />
|
||||
</div>
|
||||
<div className="col-12 col-xl-8">
|
||||
<div className="card h-100">
|
||||
<ExpenseAnalysis />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-12 col-xl-4 col-md-6">
|
||||
<div className="card h-100">
|
||||
<ExpenseStatus />
|
||||
</div>
|
||||
</div>
|
||||
{!isAllProjectsSelected && (
|
||||
<div className="col-12 col-md-6 mb-sm-0 mb-4">
|
||||
<AttendanceOverview />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!isAllProjectsSelected && (
|
||||
<div className="col-xxl-4 col-lg-4">
|
||||
<ProjectStatistics />
|
||||
</div>
|
||||
)}
|
||||
<div className="col-12 col-xl-4 col-md-6">
|
||||
<div className="card ">
|
||||
<ExpenseStatus />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-12 col-xl-8">
|
||||
<div className="card h-100">
|
||||
<ExpenseAnalysis />
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-md-6">
|
||||
<ExpenseByProject />
|
||||
</div>
|
||||
|
||||
@ -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 (
|
||||
<>
|
||||
|
||||
<div className="card-header d-flex flex-column flex-sm-row justify-content-between align-items-start align-items-sm-center gap-2">
|
||||
<div className="text-start ">
|
||||
<div className="text-start">
|
||||
<h5 className="mb-1 card-title">Expense Breakdown</h5>
|
||||
{/* <p className="card-subtitle mb-0">Category Wise Expense Breakdown</p> */}
|
||||
<p className="card-subtitle m-0">{projectName}</p>
|
||||
</div>
|
||||
|
||||
<div className="text-end text-sm-end ">
|
||||
<div className="text-end text-sm-end">
|
||||
<FormProvider {...methods}>
|
||||
<DateRangePicker1 />
|
||||
</FormProvider>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Card body */}
|
||||
<div className="card-body position-relative">
|
||||
{isLoading && (
|
||||
<div
|
||||
@ -114,7 +112,6 @@ const ExpenseAnalysis = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
{!isLoading && report.length > 0 && (
|
||||
<>
|
||||
{isFetching && (
|
||||
@ -123,50 +120,59 @@ const ExpenseAnalysis = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="d-flex justify-content-center mb-3">
|
||||
<Chart
|
||||
options={donutOptions}
|
||||
series={series}
|
||||
type="donut"
|
||||
width="100%"
|
||||
height={320}
|
||||
/>
|
||||
</div>
|
||||
<div className="row">
|
||||
{/* Chart Column */}
|
||||
<div className="col-12 col-lg-6 d-flex justify-content-center mt-5 mb-3 mb-lg-0">
|
||||
<Chart
|
||||
options={donutOptions}
|
||||
series={series}
|
||||
type="donut"
|
||||
width="70%"
|
||||
height={320}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mb-2 w-100">
|
||||
<div className="row g-2">
|
||||
{report.map((item, idx) => (
|
||||
<div
|
||||
className="col-12 col-sm-6 d-flex align-items-start"
|
||||
key={idx}
|
||||
>
|
||||
<div className="avatar me-2">
|
||||
<span
|
||||
className="avatar-initial rounded-2"
|
||||
style={{
|
||||
backgroundColor:
|
||||
donutOptions.colors[idx % donutOptions.colors.length],
|
||||
}}
|
||||
>
|
||||
<i className="bx bx-receipt fs-4"></i>
|
||||
</span>
|
||||
{/* Data/Legend Column */}
|
||||
<div className="col-12 mt-6 col-lg-6">
|
||||
<div className="row g-4">
|
||||
{report.map((item, idx) => (
|
||||
<div
|
||||
className="col-6"
|
||||
key={idx}
|
||||
style={{
|
||||
borderLeft: `3px solid ${flatColors[idx % flatColors.length]}`,
|
||||
}}
|
||||
>
|
||||
<div className="d-flex flex-column text-start">
|
||||
<small
|
||||
className="fw-semibold text-wrap text-dark"
|
||||
style={{
|
||||
fontSize: "0.8rem",
|
||||
whiteSpace: "normal",
|
||||
wordBreak: "break-word",
|
||||
lineHeight: "1.2",
|
||||
}}
|
||||
>
|
||||
{item.projectName}
|
||||
</small>
|
||||
<span
|
||||
className="fw-semibold text-muted"
|
||||
style={{
|
||||
fontSize: "0.75rem",
|
||||
}}
|
||||
>
|
||||
{formatCurrency(item.totalApprovedAmount)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-column gap-1 text-start">
|
||||
<small className="fw-semibold">{item.projectName}</small>
|
||||
<span className="fw-semibold text-muted ms-1">
|
||||
{formatCurrency(item.totalApprovedAmount)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Header */}
|
||||
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -92,7 +92,7 @@ const ExpenseByProject = () => {
|
||||
<div className="card shadow-sm h-100 rounded ">
|
||||
{/* Header */}
|
||||
<div className="card-header">
|
||||
<div className="d-flex justify-content-start align-items-center mb-1 mt-1">
|
||||
<div className="d-flex justify-content-between align-items-center mb-1 mt-1">
|
||||
<div className="text-start">
|
||||
<h5 className="mb-1 me-6 card-title">Monthly Expense -</h5>
|
||||
<p className="card-subtitle m-0">{projectName}</p>
|
||||
|
||||
@ -103,7 +103,7 @@ const ExpenseStatus = () => {
|
||||
</div>
|
||||
<div>
|
||||
<small
|
||||
className={`text-royalblue ${countDigit(item?.count || 0) >= 3 ? "text-xl" : "text-2xl"
|
||||
className={`text-royalblue ${countDigit(item?.count || 0) >= 3 ? "text-xl" : "text-xl"
|
||||
} text-gray-500`}
|
||||
>
|
||||
{item?.count || 0}
|
||||
@ -122,7 +122,7 @@ const ExpenseStatus = () => {
|
||||
{isManageExpense && (
|
||||
<div
|
||||
className="d-flex justify-content-between align-items-center cursor-pointer"
|
||||
onClick={() => handleNavigate(EXPENSE_STATUS.process_pending)}
|
||||
onClick={() => handleNavigate(EXPENSE_STATUS.payment_processed)}
|
||||
>
|
||||
<div className="d-block">
|
||||
<span
|
||||
@ -137,7 +137,7 @@ const ExpenseStatus = () => {
|
||||
</div>
|
||||
<div className="d-flex align-items-center gap-2">
|
||||
<span
|
||||
className={`text-end text-royalblue ${countDigit(data?.totalAmount || 0) > 3 ? "text-" : "text-3xl"
|
||||
className={`text-end text-royalblue ${countDigit(data?.totalAmount || 0) > 3 ? "text-xl" : "text-3xl"
|
||||
} text-md`}
|
||||
>
|
||||
{formatCurrency(data?.totalAmount || 0)}
|
||||
|
||||
@ -1,12 +1,17 @@
|
||||
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";
|
||||
import { useProjectCompletionStatus } from "../../hooks/useDashboard_Data";
|
||||
|
||||
const ProjectCompletionChart = () => {
|
||||
const { data: projects = [], isLoading: loading, isError, error } = useProjects();
|
||||
|
||||
|
||||
// Bar chart logic
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const {
|
||||
data: projects,
|
||||
isLoading: loading,
|
||||
isError,
|
||||
error,
|
||||
} = useProjectCompletionStatus();
|
||||
const projectNames = projects?.map((p) => p.name) || [];
|
||||
const projectProgress =
|
||||
projects?.map((p) => {
|
||||
|
||||
@ -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 }) => {
|
||||
<Label htmlFor={"organization"} required>
|
||||
Organization
|
||||
</Label>
|
||||
<InputSuggestions
|
||||
organizationList={organizationList}
|
||||
value={watch("organization") || ""}
|
||||
onChange={(val) => setValue("organization", val, { shouldValidate: true })}
|
||||
error={errors.organization?.message}
|
||||
/>
|
||||
<InputSuggestions
|
||||
organizationList={organizationList}
|
||||
value={watch("organization") || ""}
|
||||
onChange={(val) => setValue("organization", val, { shouldValidate: true })}
|
||||
error={errors.organization?.message}
|
||||
/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@ -408,6 +408,7 @@ const ManageContact = ({ contactId, closeModal }) => {
|
||||
label="Tags"
|
||||
options={contactTags}
|
||||
isRequired={true}
|
||||
placeholder="Enter Tag"
|
||||
/>
|
||||
{errors.tags && (
|
||||
<small className="danger-text">{errors.tags.message}</small>
|
||||
@ -482,7 +483,7 @@ const ManageContact = ({ contactId, closeModal }) => {
|
||||
<button className="btn btn-sm btn-primary" type="submit" disabled={isPending}>
|
||||
{isPending ? "Please Wait..." : "Submit"}
|
||||
</button>
|
||||
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</FormProvider>
|
||||
|
||||
@ -3,7 +3,7 @@ import React, { useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { defaultExpense, ExpenseSchema } from "./ExpenseSchema";
|
||||
import { formatFileSize, localToUtc } from "../../utils/appUtils";
|
||||
import { useProjectName } from "../../hooks/useProjects";
|
||||
import { useProjectName } from "../../hooks/useProjects";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { changeMaster } from "../../slices/localVariablesSlice";
|
||||
import useMaster, {
|
||||
@ -32,6 +32,11 @@ import Label from "../common/Label";
|
||||
import EmployeeSearchInput from "../common/EmployeeSearchInput";
|
||||
import Filelist from "./Filelist";
|
||||
import { DEFAULT_CURRENCY } from "../../utils/constants";
|
||||
import SelectEmployeeServerSide, {
|
||||
SelectProjectField,
|
||||
} from "../common/Forms/SelectFieldServerSide";
|
||||
import { useAllocationServiceProjectTeam } from "../../hooks/useServiceProject";
|
||||
import { AppFormController } from "../../hooks/appHooks/useAppForm";
|
||||
|
||||
const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
|
||||
const {
|
||||
@ -40,6 +45,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
|
||||
error: ExpenseErrorLoad,
|
||||
} = useExpense(expenseToEdit);
|
||||
const [expenseCategory, setExpenseCategory] = useState();
|
||||
const [selectedEmployees, setSelectedEmployees] = useState([]);
|
||||
const dispatch = useDispatch();
|
||||
const {
|
||||
expenseCategories,
|
||||
@ -83,11 +89,11 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
|
||||
loading: StatusLoadding,
|
||||
error: stausError,
|
||||
} = useExpenseStatus();
|
||||
const {
|
||||
data: employees,
|
||||
isLoading: EmpLoading,
|
||||
isError: isEmployeeError,
|
||||
} = useEmployeesNameByProject(selectedproject);
|
||||
// const {
|
||||
// data: employees,
|
||||
// isLoading: EmpLoading,
|
||||
// isError: isEmployeeError,
|
||||
// } = useEmployeesNameByProject(selectedproject);
|
||||
|
||||
const files = watch("billAttachments");
|
||||
const onFileChange = async (e) => {
|
||||
@ -150,6 +156,14 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const { mutate: AllocationTeam, isPending1 } =
|
||||
useAllocationServiceProjectTeam(() => {
|
||||
setSelectedEmployees([]);
|
||||
setSeletingEmp({
|
||||
employee: null,
|
||||
isOpen: false,
|
||||
});
|
||||
});
|
||||
useEffect(() => {
|
||||
if (expenseToEdit && data) {
|
||||
reset({
|
||||
@ -180,7 +194,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
|
||||
: [],
|
||||
});
|
||||
}
|
||||
}, [data, reset, employees]);
|
||||
}, [data, reset]);
|
||||
const { mutate: ExpenseUpdate, isPending } = useUpdateExpense(() =>
|
||||
handleClose()
|
||||
);
|
||||
@ -223,7 +237,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
|
||||
</h5>
|
||||
<form id="expenseForm" onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="row my-2 text-start">
|
||||
<div className="col-md-6">
|
||||
{/* <div className="col-md-6">
|
||||
<Label className="form-label" required>
|
||||
Select Project
|
||||
</Label>
|
||||
@ -245,6 +259,23 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
|
||||
{errors.projectId && (
|
||||
<small className="danger-text">{errors.projectId.message}</small>
|
||||
)}
|
||||
</div> */}
|
||||
<div className="col-12 col-md-6 mb-2">
|
||||
<SelectProjectField
|
||||
label="Project"
|
||||
required
|
||||
placeholder="Select Project"
|
||||
value={watch("projectId")}
|
||||
onChange={(val) =>
|
||||
setValue("projectId", val, {
|
||||
shouldDirty: true,
|
||||
shouldValidate: true,
|
||||
})
|
||||
}
|
||||
/>
|
||||
{errors.projectId && (
|
||||
<small className="danger-text">{errors.projectId.message}</small>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="col-md-6">
|
||||
@ -307,14 +338,28 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
|
||||
)}
|
||||
</div>
|
||||
<div className="col-12 col-md-6 text-start">
|
||||
<Label className="form-label" required>
|
||||
{/* <Label className="form-label" required>
|
||||
Paid By{" "}
|
||||
</Label>
|
||||
<EmployeeSearchInput
|
||||
</Label> */}
|
||||
{/* <EmployeeSearchInput
|
||||
control={control}
|
||||
name="paidById"
|
||||
projectId={null}
|
||||
forAll={expenseToEdit ? true : false}
|
||||
forAll={true}
|
||||
/> */}
|
||||
|
||||
<AppFormController
|
||||
name="paidById"
|
||||
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<SelectEmployeeServerSide
|
||||
label="Paid By" required
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
isFullObject={false} // because using ID
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -423,10 +468,9 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
|
||||
<small className="danger-text">{errors.gstNumber.message}</small>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-md-6 text-start ">
|
||||
<div className="row">
|
||||
<div className="col-md-6 text-start ">
|
||||
<Label htmlFor="currencyId" className="form-label" required>
|
||||
Select Currency
|
||||
</Label>
|
||||
@ -452,24 +496,26 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
|
||||
<small className="danger-text">{errors.currencyId.message}</small>
|
||||
)}
|
||||
</div>
|
||||
{expenseCategory?.noOfPersonsRequired && (
|
||||
<div className="col-md-6 text-start">
|
||||
<Label className="form-label" required>No. of Persons</Label>
|
||||
<input
|
||||
type="number"
|
||||
id="noOfPersons"
|
||||
className="form-control form-control-sm"
|
||||
{...register("noOfPersons")}
|
||||
inputMode="numeric"
|
||||
/>
|
||||
{errors.noOfPersons && (
|
||||
<small className="danger-text">
|
||||
{errors.noOfPersons.message}
|
||||
</small>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{expenseCategory?.noOfPersonsRequired && (
|
||||
<div className="col-md-6 text-start">
|
||||
<Label className="form-label" required>
|
||||
No. of Persons
|
||||
</Label>
|
||||
<input
|
||||
type="number"
|
||||
id="noOfPersons"
|
||||
className="form-control form-control-sm"
|
||||
{...register("noOfPersons")}
|
||||
inputMode="numeric"
|
||||
/>
|
||||
{errors.noOfPersons && (
|
||||
<small className="danger-text">
|
||||
{errors.noOfPersons.message}
|
||||
</small>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="row my-2 text-start">
|
||||
<div className="col-md-12">
|
||||
|
||||
@ -1,54 +1,80 @@
|
||||
import { useState } from "react";
|
||||
|
||||
|
||||
const PreviewDocument = ({ imageUrl }) => {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [rotation, setRotation] = useState(0);
|
||||
const [scale, setScale] = useState(1);
|
||||
|
||||
const zoomIn = () => setScale((prev) => Math.min(prev + 0.2, 3));
|
||||
const zoomOut = () => setScale((prev) => Math.max(prev - 0.2, 0.4));
|
||||
const resetAll = () => {
|
||||
setRotation(0);
|
||||
setScale(1);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="d-flex justify-content-start">
|
||||
<>
|
||||
<div className="d-flex justify-content-start gap-3 mb-2">
|
||||
<i
|
||||
className="bx bx-rotate-right cursor-pointer"
|
||||
className="bx bx-rotate-right cursor-pointer fs-4"
|
||||
title="Rotate"
|
||||
onClick={() => setRotation((prev) => prev + 90)}
|
||||
></i>
|
||||
</div>
|
||||
<div
|
||||
className="position-relative d-flex flex-column justify-content-center align-items-center"
|
||||
style={{ minHeight: "80vh" }}
|
||||
>
|
||||
|
||||
{loading && (
|
||||
<div className="text-secondary text-center mb-2">Loading...</div>
|
||||
)}
|
||||
|
||||
<div className="mb-3 d-flex justify-content-center align-items-center">
|
||||
<img
|
||||
src={imageUrl}
|
||||
alt="Full View"
|
||||
className="img-fluid"
|
||||
style={{
|
||||
maxHeight: "80vh",
|
||||
objectFit: "contain",
|
||||
display: loading ? "none" : "block",
|
||||
transform: `rotate(${rotation}deg)`,
|
||||
transition: "transform 0.3s ease",
|
||||
}}
|
||||
onLoad={() => setLoading(false)}
|
||||
/>
|
||||
<i
|
||||
className="bx bx-zoom-in cursor-pointer fs-4"
|
||||
title="Zoom In"
|
||||
onClick={zoomIn}
|
||||
></i>
|
||||
|
||||
<i
|
||||
className="bx bx-zoom-out cursor-pointer fs-4"
|
||||
title="Zoom Out"
|
||||
onClick={zoomOut}
|
||||
></i>
|
||||
</div>
|
||||
|
||||
<div className="position-absolute bottom-0 start-0 justify-content-center gap-2">
|
||||
<button
|
||||
className="btn btn-outline-secondary"
|
||||
onClick={() => setRotation(0)}
|
||||
title="Reset Rotation"
|
||||
>
|
||||
<i className="bx bx-reset"></i> Reset
|
||||
</button>
|
||||
<div
|
||||
className="position-relative d-flex flex-column justify-content-center align-items-center overflow-hidden"
|
||||
style={{ minHeight: "80vh" }}
|
||||
>
|
||||
{loading && (
|
||||
<div className="text-secondary text-center mb-2">
|
||||
Loading...
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mb-3 d-flex justify-content-center align-items-center">
|
||||
<img
|
||||
src={imageUrl}
|
||||
alt="Full View"
|
||||
className="img-fluid"
|
||||
style={{
|
||||
maxHeight: "80vh",
|
||||
objectFit: "contain",
|
||||
display: loading ? "none" : "block",
|
||||
transform: `rotate(${rotation}deg) scale(${scale})`,
|
||||
transition: "transform 0.3s ease",
|
||||
cursor: "grab",
|
||||
}}
|
||||
onLoad={() => setLoading(false)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="position-absolute bottom-0 start-0 m-2">
|
||||
<button
|
||||
className="btn btn-outline-secondary"
|
||||
onClick={resetAll}
|
||||
>
|
||||
<i className="bx bx-reset"></i> Reset
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default PreviewDocument;
|
||||
|
||||
@ -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 }) => {
|
||||
<span>{data?.expenseUId}</span>
|
||||
</div>{" "}
|
||||
<span
|
||||
className={`badge bg-label-${
|
||||
getColorNameFromHex(data?.status?.color) || "secondary"
|
||||
}`}
|
||||
className={`badge bg-label-${getColorNameFromHex(data?.status?.color) || "secondary"
|
||||
}`}
|
||||
t
|
||||
>
|
||||
{data?.status?.name}
|
||||
@ -142,7 +152,7 @@ const ViewExpense = ({ ExpenseId }) => {
|
||||
</div>
|
||||
|
||||
{/* Row 1 */}
|
||||
<div className="row text-start">
|
||||
<div className="row text-start">
|
||||
<div className="col-md-6 mb-3">
|
||||
<label
|
||||
className="form-label me-2 mb-0 fw-semibold text-start"
|
||||
@ -264,28 +274,28 @@ const ViewExpense = ({ ExpenseId }) => {
|
||||
</div> */}
|
||||
|
||||
{/* Row 5 */}
|
||||
|
||||
|
||||
<div className="row text-start">
|
||||
|
||||
<div className="row text-start">
|
||||
<div className="col-md-6 mb-3">
|
||||
|
||||
|
||||
<label
|
||||
className="form-label me-2 mb-0 fw-semibold text-start"
|
||||
style={{ minWidth: "130px" }}
|
||||
>
|
||||
Created At :
|
||||
</label>
|
||||
|
||||
|
||||
</div>
|
||||
<div className="col-md-6 mb-3">
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div className="col-md-6 mb-3">
|
||||
|
||||
<small className="text-muted">
|
||||
{formatUTCToLocalTime(data?.createdAt, true)}
|
||||
</small>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Created & Paid By */}
|
||||
{data.createdBy && (
|
||||
@ -307,9 +317,8 @@ const ViewExpense = ({ ExpenseId }) => {
|
||||
lastName={data.createdBy?.lastName}
|
||||
/>
|
||||
<span className="text-muted">
|
||||
{`${data.createdBy?.firstName ?? ""} ${
|
||||
data.createdBy?.lastName ?? ""
|
||||
}`.trim() || "N/A"}
|
||||
{`${data.createdBy?.firstName ?? ""} ${data.createdBy?.lastName ?? ""
|
||||
}`.trim() || "N/A"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -337,31 +346,30 @@ const ViewExpense = ({ ExpenseId }) => {
|
||||
</span>
|
||||
</div>
|
||||
</div> */}
|
||||
<div className="row text-start">
|
||||
<div className="col-md-6 text-start mb-3">
|
||||
<label
|
||||
className="form-label me-2 mb-0 fw-semibold"
|
||||
style={{ minWidth: "130px" }}
|
||||
>
|
||||
Paid By :
|
||||
</label>
|
||||
</div>
|
||||
<div className="col-md-6 text-start mb-3">
|
||||
<div className="d-flex align-items-center">
|
||||
<Avatar
|
||||
size="xs"
|
||||
classAvatar="m-0 me-1"
|
||||
firstName={data.paidBy?.firstName}
|
||||
lastName={data.paidBy?.lastName}
|
||||
/>
|
||||
<span className="text-muted">
|
||||
{`${data.paidBy?.firstName ?? ""} ${
|
||||
data.paidBy?.lastName ?? ""
|
||||
<div className="row text-start">
|
||||
<div className="col-md-6 text-start mb-3">
|
||||
<label
|
||||
className="form-label me-2 mb-0 fw-semibold"
|
||||
style={{ minWidth: "130px" }}
|
||||
>
|
||||
Paid By :
|
||||
</label>
|
||||
</div>
|
||||
<div className="col-md-6 text-start mb-3">
|
||||
<div className="d-flex align-items-center">
|
||||
<Avatar
|
||||
size="xs"
|
||||
classAvatar="m-0 me-1"
|
||||
firstName={data.paidBy?.firstName}
|
||||
lastName={data.paidBy?.lastName}
|
||||
/>
|
||||
<span className="text-muted">
|
||||
{`${data.paidBy?.firstName ?? ""} ${data.paidBy?.lastName ?? ""
|
||||
}`.trim() || "N/A"}
|
||||
</span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
<div className="col-12 text-start mb-2">
|
||||
@ -493,19 +501,7 @@ const ViewExpense = ({ ExpenseId }) => {
|
||||
projectId={null}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-12 col-md-6 text-start">
|
||||
<Label className="form-label">TDS Percentage</Label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control form-control-sm"
|
||||
{...register("tdsPercentage")}
|
||||
/>
|
||||
{errors.tdsPercentage && (
|
||||
<small className="danger-text">
|
||||
{errors.tdsPercentage.message}
|
||||
</small>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="col-12 col-md-6 text-start">
|
||||
<Label className="form-label" required>
|
||||
Base Amount
|
||||
@ -536,28 +532,53 @@ const ViewExpense = ({ ExpenseId }) => {
|
||||
</small>
|
||||
)}
|
||||
</div>
|
||||
<div className="col-12 col-md-6 text-start">
|
||||
<Label className="form-label">TDS Percentage</Label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control form-control-sm"
|
||||
{...register("tdsPercentage")}
|
||||
/>
|
||||
{errors.tdsPercentage && (
|
||||
<small className="danger-text">
|
||||
{errors.tdsPercentage.message}
|
||||
</small>
|
||||
)}
|
||||
</div>
|
||||
<div className="col-12 d-flex align-items-center gap-4 mb-2 mt-1">
|
||||
<div>
|
||||
<span className="fw-semibold">TDS Amount: </span>
|
||||
<span className="badge bg-label-secondary">{tdsAmount.toFixed(2)}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="fw-semibold">Net Payable: </span>
|
||||
<span className="badge bg-label-secondary">{netPayable.toFixed(2)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)}
|
||||
<div className="col-12 mb-3 text-start mt-1">
|
||||
{((nextStatusWithPermission.length > 0 &&
|
||||
!IsRejectedExpense) ||
|
||||
(IsRejectedExpense && isCreatedBy)) && (
|
||||
<>
|
||||
<Label className="form-label me-2 mb-0" required>
|
||||
Comment
|
||||
</Label>
|
||||
<textarea
|
||||
className="form-control form-control-sm"
|
||||
{...register("comment")}
|
||||
rows="2"
|
||||
/>
|
||||
{errors.comment && (
|
||||
<small className="danger-text">
|
||||
{errors.comment.message}
|
||||
</small>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<>
|
||||
<Label className="form-label me-2 mb-0" required>
|
||||
Comment
|
||||
</Label>
|
||||
<textarea
|
||||
className="form-control form-control-sm"
|
||||
{...register("comment")}
|
||||
rows="2"
|
||||
/>
|
||||
{errors.comment && (
|
||||
<small className="danger-text">
|
||||
{errors.comment.message}
|
||||
</small>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{nextStatusWithPermission?.length > 0 &&
|
||||
(!IsRejectedExpense || isCreatedBy) && (
|
||||
|
||||
@ -46,8 +46,15 @@ const Header = () => {
|
||||
pathname
|
||||
);
|
||||
const isExpensePage = /^\/expenses$/.test(pathname);
|
||||
const isPaymentRequest = /^\/payment-request$/.test(pathname);
|
||||
const isRecurringExpense = /^\/recurring-payment$/.test(pathname);
|
||||
const isAdvancePayment = /^\/advance-payment$/.test(pathname);
|
||||
const isServiceProjectPage = /^\/service-projects\/[0-9a-fA-F-]{36}$/.test(pathname);
|
||||
const isAdvancePayment1 =
|
||||
/^\/advance-payment(\/[0-9a-fA-F-]{36})?$/.test(pathname);
|
||||
|
||||
return !(isDirectoryPath || isProfilePage || isExpensePage);
|
||||
|
||||
return !(isDirectoryPath || isProfilePage || isExpensePage || isPaymentRequest || isRecurringExpense || isAdvancePayment ||isServiceProjectPage || isAdvancePayment1);
|
||||
};
|
||||
const allowedProjectStatusIds = [
|
||||
"603e994b-a27f-4e5d-a251-f3d69b0498ba",
|
||||
@ -59,11 +66,7 @@ const Header = () => {
|
||||
if (!Array.isArray(roles)) return "User";
|
||||
let role = roles.find((role) => role.id === joRoleId);
|
||||
return role ? role.name : "User";
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
const handleProfilePage = () => {
|
||||
navigate(`/employee/${profile?.employeeInfo?.id}`);
|
||||
|
||||
@ -25,22 +25,19 @@ const Sidebar = () => {
|
||||
/>
|
||||
</span> */}
|
||||
|
||||
<a
|
||||
href="/"
|
||||
className="app-brand-link fw-bold navbar-brand text-green fs-6"
|
||||
>
|
||||
<small className="app-brand-link fw-bold navbar-brand text-green fs-6">
|
||||
<span className="app-brand-logo demo">
|
||||
<img src="/img/brand/marco.png" width="50" />
|
||||
</span>
|
||||
<span className="text-blue">OnField</span>
|
||||
<span>Work</span>
|
||||
<span className="text-dark">.com</span>
|
||||
</a>
|
||||
</small>
|
||||
</Link>
|
||||
|
||||
<a className="layout-menu-toggle menu-link text-large ms-auto">
|
||||
<small className="layout-menu-toggle menu-link text-large ms-auto">
|
||||
<i className="bx bx-chevron-left bx-sm d-flex align-items-center justify-content-center"></i>
|
||||
</a>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div className="menu-inner-shadow"></div>
|
||||
@ -61,7 +58,7 @@ const Sidebar = () => {
|
||||
</>
|
||||
)}
|
||||
{data &&
|
||||
data?.data.map((section) => (
|
||||
data?.data?.map((section) => (
|
||||
<React.Fragment
|
||||
key={section.id || section.header || section.items[0]?.id}
|
||||
>
|
||||
@ -99,7 +96,7 @@ const MenuItem = (item) => {
|
||||
className={`menu-link ${hasSubmenu ? "menu-toggle" : ""}`}
|
||||
target={item.link?.includes("http") ? "_blank" : undefined}
|
||||
>
|
||||
<i className={`menu-icon tf-icons ${item.icon}`}></i>
|
||||
{item.icon && <i className={`menu-icon tf-icons ${item.icon}`}></i>}
|
||||
<div>{item.name}</div>
|
||||
{item.available === false && (
|
||||
<div className="badge bg-label-primary fs-tiny rounded-pill ms-auto">
|
||||
|
||||
@ -135,6 +135,19 @@ const ManagOrg = () => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mb-1 text-start">
|
||||
<Label htmlFor="gstNumber">
|
||||
GST Number
|
||||
</Label>
|
||||
<input
|
||||
className="form-control form-control-sm"
|
||||
{...register("gstNumber")}
|
||||
/>
|
||||
{errors.gstNumber && (
|
||||
<span className="danger-text">{errors.gstNumber.message}</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mb-1 text-start">
|
||||
<Label htmlFor="email" required>
|
||||
Email Address
|
||||
@ -199,8 +212,8 @@ const ManagOrg = () => {
|
||||
{isCreating || isUpdating
|
||||
? "Please Wait..."
|
||||
: orgData
|
||||
? "Update"
|
||||
: "Submit"}
|
||||
? "Update"
|
||||
: "Submit"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -20,6 +20,7 @@ export const organizationSchema = z.object({
|
||||
serviceIds: z
|
||||
.array(z.string())
|
||||
.min(1, { message: "Service isrequired" }),
|
||||
gstNumber: z.string().optional(),
|
||||
});
|
||||
|
||||
export const defaultOrganizationValues = {
|
||||
@ -29,6 +30,7 @@ export const defaultOrganizationValues = {
|
||||
address: "",
|
||||
email: "",
|
||||
serviceIds: [],
|
||||
gstNumber : ""
|
||||
};
|
||||
|
||||
export const assignedOrgToProject = z.object({
|
||||
|
||||
@ -24,7 +24,7 @@ import { useNavigate } from "react-router-dom";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useSelector } from "react-redux";
|
||||
import { usePaymentRequestContext } from "../../pages/PaymentRequest/PaymentRequestPage";
|
||||
import { localToUtc } from "../../utils/appUtils";
|
||||
import { calculateTDSPercentage, localToUtc } from "../../utils/appUtils";
|
||||
import { usePaymentMode } from "../../hooks/masterHook/useMaster";
|
||||
import Filelist from "../Expenses/Filelist";
|
||||
|
||||
@ -40,6 +40,7 @@ const ActionPaymentRequest = ({ requestId }) => {
|
||||
error: PaymentModeError,
|
||||
} = usePaymentMode();
|
||||
|
||||
|
||||
const IsReview = useHasUserPermission(REVIEW_EXPENSE);
|
||||
const [imageLoaded, setImageLoaded] = useState({});
|
||||
|
||||
@ -69,15 +70,10 @@ const ActionPaymentRequest = ({ requestId }) => {
|
||||
const taxAmount = watch("taxAmount") || 0;
|
||||
const tdsPercentage = watch("tdsPercentage") || 0;
|
||||
|
||||
const grossAmount = baseAmount + taxAmount;
|
||||
|
||||
const tdsAmount = useMemo(() => (baseAmount * tdsPercentage) / 100, [
|
||||
baseAmount,
|
||||
tdsPercentage,
|
||||
]);
|
||||
|
||||
const netPayable = useMemo(() => grossAmount - tdsAmount, [grossAmount, tdsAmount]);
|
||||
|
||||
const { grossAmount, tdsAmount, netPayable } = useMemo(() => {
|
||||
return calculateTDSPercentage(baseAmount, taxAmount, tdsPercentage);
|
||||
}, [baseAmount, taxAmount, tdsPercentage]);
|
||||
|
||||
const userPermissions = useSelector(
|
||||
(state) => state?.globalVariables?.loginUser?.featurePermissions || []
|
||||
@ -180,6 +176,16 @@ const ActionPaymentRequest = ({ requestId }) => {
|
||||
const newFiles = files.filter((_, i) => i !== index);
|
||||
setValue("billAttachments", newFiles, { shouldValidate: true });
|
||||
};
|
||||
|
||||
const filteredPaymentModes = useMemo(() => {
|
||||
return PaymentModes?.filter((mode) => {
|
||||
if (mode.name === "Advance Payment" && data?.isAdvancePayment === false) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}) || [];
|
||||
}, [PaymentModes, data]);
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
{IsPaymentProcess && nextStatusWithPermission?.length > 0 && (
|
||||
@ -224,7 +230,7 @@ const ActionPaymentRequest = ({ requestId }) => {
|
||||
{PaymentModeLoading ? (
|
||||
<option disabled>Loading...</option>
|
||||
) : (
|
||||
PaymentModes?.map((payment) => (
|
||||
filteredPaymentModes?.map((payment) => (
|
||||
<option key={payment.id} value={payment.id}>
|
||||
{payment.name}
|
||||
</option>
|
||||
@ -428,6 +434,7 @@ const ActionPaymentRequest = ({ requestId }) => {
|
||||
<span className="badge bg-label-secondary">{netPayable.toFixed(2)}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
)}
|
||||
|
||||