added taskreport, commentTask feature
This commit is contained in:
parent
ddfbed1020
commit
10d6f96ea7
13
index.html
13
index.html
@ -49,6 +49,7 @@
|
|||||||
|
|
||||||
<!-- Timer Picker -->
|
<!-- Timer Picker -->
|
||||||
<!-- Flatpickr CSS -->
|
<!-- Flatpickr CSS -->
|
||||||
|
<link rel="stylesheet" href="/assets/vendor/libs/flatpickr/flatpickr.css" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -84,7 +85,7 @@
|
|||||||
<script src="/assets/vendor/libs/select2/select2.js"></script>
|
<script src="/assets/vendor/libs/select2/select2.js"></script>
|
||||||
<script src="/assets/vendor/libs/apex-charts/apexcharts.js"></script>
|
<script src="/assets/vendor/libs/apex-charts/apexcharts.js"></script>
|
||||||
<script src="/assets/vendor/libs/jquery-timepicker/jquery-timepicker.js" ></script>
|
<script src="/assets/vendor/libs/jquery-timepicker/jquery-timepicker.js" ></script>
|
||||||
|
<script src="/assets/vendor/libs/flatpickr/flatpickr.js" ></script>
|
||||||
<!-- Main JS -->
|
<!-- Main JS -->
|
||||||
<script src="/assets/js/main.js"></script>
|
<script src="/assets/js/main.js"></script>
|
||||||
|
|
||||||
@ -102,17 +103,7 @@
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script> -->
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script> -->
|
||||||
|
|
||||||
<!-- Flatpickr JS -->
|
<!-- Flatpickr JS -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Initialize flatpickr for 12-hour time format with AM/PM
|
|
||||||
flatpickr("#timePicker", {
|
|
||||||
enableTime: true,
|
|
||||||
noCalendar: true,
|
|
||||||
time_24hr: false, // Disable 24-hour format
|
|
||||||
dateFormat: "h:i K", // 12-hour format with AM/PM
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
906
public/assets/vendor/libs/flatpickr/flatpickr.css
vendored
Normal file
906
public/assets/vendor/libs/flatpickr/flatpickr.css
vendored
Normal file
@ -0,0 +1,906 @@
|
|||||||
|
.flatpickr-calendar {
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
max-height: 0;
|
||||||
|
border: 0;
|
||||||
|
text-align: center;
|
||||||
|
opacity: 0;
|
||||||
|
animation: none;
|
||||||
|
outline: 0;
|
||||||
|
touch-action: manipulation;
|
||||||
|
line-height: 1.375;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.open, .flatpickr-calendar.inline {
|
||||||
|
visibility: visible;
|
||||||
|
overflow: visible;
|
||||||
|
max-height: 640px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.open {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.animate.open {
|
||||||
|
animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1);
|
||||||
|
}
|
||||||
|
.flatpickr-calendar:not(.inline):not(.open) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.inline {
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.static {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 2px);
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.static.open {
|
||||||
|
z-index: 999;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.hasWeeks {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
html:not([dir=rtl]) .flatpickr-calendar.hasWeeks .flatpickr-days {
|
||||||
|
border-bottom-left-radius: 0 !important;
|
||||||
|
}
|
||||||
|
[dir=rtl] .flatpickr-calendar.hasWeeks .flatpickr-days {
|
||||||
|
border-bottom-right-radius: 0 !important;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.hasTime {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.hasTime .flatpickr-time {
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.noCalendar.hasTime .flatpickr-time {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar input[type=number] {
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar input[type=number]::-webkit-inner-spin-button,
|
||||||
|
.flatpickr-calendar input[type=number]::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-wrapper {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-month {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 3rem;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-prev-month,
|
||||||
|
.flatpickr-next-month {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.75rem;
|
||||||
|
z-index: 3;
|
||||||
|
padding: 0 0.41rem;
|
||||||
|
height: 1.875rem;
|
||||||
|
width: 1.875rem;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.flatpickr-prev-month svg,
|
||||||
|
.flatpickr-next-month svg {
|
||||||
|
stroke-width: 2;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-prev-month i,
|
||||||
|
.flatpickr-next-month i {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-prev-month.flatpickr-prev-month {
|
||||||
|
left: 1rem;
|
||||||
|
}
|
||||||
|
[dir=rtl] .flatpickr-prev-month {
|
||||||
|
right: 1rem;
|
||||||
|
left: auto;
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-next-month.flatpickr-prev-month {
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-next-month.flatpickr-next-month {
|
||||||
|
right: 1rem;
|
||||||
|
}
|
||||||
|
[dir=rtl] .flatpickr-next-month {
|
||||||
|
right: auto;
|
||||||
|
left: 1rem;
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-prev-month:hover,
|
||||||
|
.flatpickr-next-month:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-prev-month svg,
|
||||||
|
.flatpickr-next-month svg {
|
||||||
|
width: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-prev-month svg path,
|
||||||
|
.flatpickr-next-month svg path {
|
||||||
|
transition: fill 0.1s;
|
||||||
|
fill: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.numInputWrapper {
|
||||||
|
position: relative;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.numInputWrapper :hover {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.numInputWrapper input,
|
||||||
|
.numInputWrapper span {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.numInputWrapper input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.numInputWrapper span {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 14px;
|
||||||
|
height: 50%;
|
||||||
|
line-height: 1;
|
||||||
|
opacity: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
[dir=rtl] .numInputWrapper span {
|
||||||
|
right: auto;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.numInputWrapper span:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
.numInputWrapper span:active {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
.numInputWrapper span:after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
.numInputWrapper span.arrowUp {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.numInputWrapper span.arrowUp:after {
|
||||||
|
border-right: 4px solid transparent;
|
||||||
|
border-bottom: 4px solid rgba(72, 72, 72, 0.6);
|
||||||
|
border-left: 4px solid transparent;
|
||||||
|
}
|
||||||
|
.numInputWrapper span.arrowDown {
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
.numInputWrapper span.arrowDown:after {
|
||||||
|
border-top: 4px solid rgba(72, 72, 72, 0.6);
|
||||||
|
border-right: 4px solid transparent;
|
||||||
|
border-left: 4px solid transparent;
|
||||||
|
}
|
||||||
|
.numInputWrapper span svg {
|
||||||
|
width: inherit;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.numInputWrapper span svg path {
|
||||||
|
fill: rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
.numInputWrapper:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
.numInputWrapper:hover span {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-current-month {
|
||||||
|
position: absolute;
|
||||||
|
left: 12.5%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
width: 75%;
|
||||||
|
height: 2.5rem;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 300;
|
||||||
|
line-height: 1;
|
||||||
|
padding: 0.9rem 0 0 0;
|
||||||
|
transform: translate3d(0px, 0px, 0px);
|
||||||
|
}
|
||||||
|
.flatpickr-current-month .flatpickr-monthDropdown-months,
|
||||||
|
.flatpickr-current-month input.cur-year {
|
||||||
|
outline: none;
|
||||||
|
vertical-align: middle !important;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
color: inherit;
|
||||||
|
display: inline-block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month .flatpickr-monthDropdown-months:not(:first-child),
|
||||||
|
.flatpickr-current-month input.cur-year:not(:first-child) {
|
||||||
|
padding: 0 0 0 0.5ch;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month .numInputWrapper {
|
||||||
|
display: inline-block;
|
||||||
|
width: 6ch;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month .flatpickr-monthDropdown-months {
|
||||||
|
appearance: menulist;
|
||||||
|
cursor: pointer;
|
||||||
|
height: 2.25rem;
|
||||||
|
position: relative;
|
||||||
|
width: auto;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month input.cur-year {
|
||||||
|
margin: 0;
|
||||||
|
height: 1.2rem;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
[dir=rtl] .flatpickr-current-month input.cur-year {
|
||||||
|
padding-right: 0.5ch;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month input.cur-year:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month input.cur-year[disabled], .flatpickr-current-month input.cur-year[disabled]:hover {
|
||||||
|
background: transparent;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month input.cur-year[disabled] {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-weekdaycontainer {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.25rem 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-weekdays {
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
align-items: center;
|
||||||
|
max-width: 17.5rem;
|
||||||
|
width: 100%;
|
||||||
|
height: 2.25rem;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 0.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.flatpickr-weekday {
|
||||||
|
display: block;
|
||||||
|
flex: 1;
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dayContainer,
|
||||||
|
.flatpickr-weeks {
|
||||||
|
padding: 1px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-days {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
.flatpickr-days:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.hasTime .flatpickr-days {
|
||||||
|
border-bottom: 0 !important;
|
||||||
|
border-bottom-right-radius: 0 !important;
|
||||||
|
border-bottom-left-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dayContainer {
|
||||||
|
display: inline-block;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-around;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0;
|
||||||
|
min-width: 15.75rem;
|
||||||
|
max-width: 15.75rem;
|
||||||
|
width: 15.75rem;
|
||||||
|
outline: 0;
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate3d(0px, 0px, 0px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-day {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
flex-basis: 14.2857143%;
|
||||||
|
justify-content: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
max-width: 2.25rem;
|
||||||
|
width: 15.2857143%;
|
||||||
|
height: 2.25rem;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background: none;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: calc(2.25rem - 2px);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.flatpickr-day.inRange, .flatpickr-day.prevMonthDay.inRange, .flatpickr-day.nextMonthDay.inRange, .flatpickr-day.today.inRange, .flatpickr-day.prevMonthDay.today.inRange, .flatpickr-day.nextMonthDay.today.inRange, .flatpickr-day:hover, .flatpickr-day.prevMonthDay:hover, .flatpickr-day.nextMonthDay:hover, .flatpickr-day:focus, .flatpickr-day.prevMonthDay:focus, .flatpickr-day.nextMonthDay:focus {
|
||||||
|
outline: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.flatpickr-day.inRange:not(.startRange):not(.endRange) {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
.flatpickr-day.disabled, .flatpickr-day.flatpickr-disabled, .flatpickr-day.flatpickr-disabled.today, .flatpickr-day.disabled:hover, .flatpickr-day.flatpickr-disabled:hover, .flatpickr-day.flatpickr-disabled.today:hover {
|
||||||
|
border-color: transparent;
|
||||||
|
background: transparent !important;
|
||||||
|
cursor: default;
|
||||||
|
pointer-events: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.flatpickr-day.prevMonthDay, .flatpickr-day.nextMonthDay {
|
||||||
|
border-color: transparent;
|
||||||
|
background: transparent;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.flatpickr-day.notAllowed, .flatpickr-day.notAllowed.prevMonthDay, .flatpickr-day.notAllowed.nextMonthDay {
|
||||||
|
border-color: transparent;
|
||||||
|
background: transparent;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.flatpickr-day.week.selected {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
html:not([dir=rtl]) .flatpickr-day.selected.startRange, html:not([dir=rtl]) .flatpickr-day.startRange.startRange, html:not([dir=rtl]) .flatpickr-day.endRange.startRange {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
html:not([dir=rtl]) .flatpickr-day.selected.endRange, html:not([dir=rtl]) .flatpickr-day.startRange.endRange, html:not([dir=rtl]) .flatpickr-day.endRange.endRange {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
[dir=rtl] .flatpickr-day.selected.startRange, [dir=rtl] .flatpickr-day.startRange.startRange, [dir=rtl] .flatpickr-day.endRange.startRange {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
[dir=rtl] .flatpickr-day.selected.endRange, [dir=rtl] .flatpickr-day.startRange.endRange, [dir=rtl] .flatpickr-day.endRange.endRange {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-weekwrapper {
|
||||||
|
display: inline-block;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.flatpickr-weekwrapper .flatpickr-weeks {
|
||||||
|
background-clip: padding-box !important;
|
||||||
|
}
|
||||||
|
html:not([dir=rtl]) .flatpickr-weekwrapper .flatpickr-weeks .flatpickr-weeks {
|
||||||
|
border-bottom-right-radius: 0 !important;
|
||||||
|
}
|
||||||
|
[dir=rtl] .flatpickr-weekwrapper .flatpickr-weeks .flatpickr-weeks {
|
||||||
|
border-bottom-left-radius: 0 !important;
|
||||||
|
}
|
||||||
|
.flatpickr-weekwrapper .flatpickr-weeks .flatpickr-day {
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
}
|
||||||
|
.flatpickr-weekwrapper .flatpickr-calendar.hasTime .flatpickr-weeks {
|
||||||
|
border-bottom: 0 !important;
|
||||||
|
border-bottom-right-radius: 0 !important;
|
||||||
|
border-bottom-left-radius: 0 !important;
|
||||||
|
}
|
||||||
|
.flatpickr-weekwrapper .flatpickr-weekday {
|
||||||
|
float: none;
|
||||||
|
width: 100%;
|
||||||
|
line-height: 2.25rem;
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
margin-bottom: 0.4rem;
|
||||||
|
}
|
||||||
|
.flatpickr-weekwrapper span.flatpickr-day {
|
||||||
|
display: block;
|
||||||
|
max-width: none;
|
||||||
|
width: 2.25rem;
|
||||||
|
background: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-calendar.hasTime .flatpickr-weeks {
|
||||||
|
border-bottom: 0 !important;
|
||||||
|
border-bottom-left-radius: 0 !important;
|
||||||
|
border-bottom-right-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-innerContainer {
|
||||||
|
display: block;
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
html:not([dir=rtl]) .flatpickr-innerContainer:has(.flatpickr-weeks) .flatpickr-weeks {
|
||||||
|
padding-left: 0.445rem;
|
||||||
|
}
|
||||||
|
[dir=rtl] .flatpickr-innerContainer:has(.flatpickr-weeks) .flatpickr-weeks {
|
||||||
|
padding-left: 0.445rem;
|
||||||
|
}
|
||||||
|
[dir=rtl] .flatpickr-innerContainer:has(.flatpickr-weeks) .flatpickr-weekdaycontainer {
|
||||||
|
padding-left: 0.625rem;
|
||||||
|
}
|
||||||
|
.flatpickr-innerContainer:has(.flatpickr-weeks) .flatpickr-weekwrapper .flatpickr-weekday {
|
||||||
|
padding-left: 0.445rem;
|
||||||
|
}
|
||||||
|
[dir=rtl] .flatpickr-innerContainer:has(.flatpickr-weeks) .flatpickr-weekwrapper {
|
||||||
|
padding-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-rContainer {
|
||||||
|
display: inline-block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-time {
|
||||||
|
display: block;
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
max-height: 40px;
|
||||||
|
height: 0;
|
||||||
|
outline: 0;
|
||||||
|
background-clip: padding-box !important;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
.flatpickr-time:after {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
.flatpickr-time .numInputWrapper {
|
||||||
|
float: left;
|
||||||
|
flex: 1;
|
||||||
|
width: 40%;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
.flatpickr-time.hasSeconds .numInputWrapper {
|
||||||
|
width: 26%;
|
||||||
|
}
|
||||||
|
.flatpickr-time.time24hr .numInputWrapper {
|
||||||
|
width: 49%;
|
||||||
|
}
|
||||||
|
.flatpickr-time input {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: inherit;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
text-align: center;
|
||||||
|
line-height: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
}
|
||||||
|
.flatpickr-time input.flatpickr-hour, .flatpickr-time input.flatpickr-minute, .flatpickr-time input.flatpickr-second {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
.flatpickr-time input:focus {
|
||||||
|
outline: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-time .flatpickr-time-separator,
|
||||||
|
.flatpickr-time .flatpickr-am-pm {
|
||||||
|
display: inline-block;
|
||||||
|
float: left;
|
||||||
|
align-self: center;
|
||||||
|
width: 2%;
|
||||||
|
height: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.flatpickr-time .flatpickr-am-pm {
|
||||||
|
width: 18%;
|
||||||
|
outline: 0;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: normal;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.flatpickr-time .flatpickr-am-pm:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.noCalendar .flatpickr-time {
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar:not(.noCalendar) .flatpickr-time {
|
||||||
|
border-top: 0;
|
||||||
|
border-top-left-radius: 0 !important;
|
||||||
|
border-top-right-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flatpickr-input[readonly] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fpFadeInDown {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate3d(0, -20px, 0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-moz-keyframes fpFadeInDown {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate3d(0, -20px, 0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fpFadeInDown {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate3d(0, -20px, 0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-calendar {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-prev-month,
|
||||||
|
.light-style .flatpickr-next-month {
|
||||||
|
background-color: #edeef0;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-prev-month svg,
|
||||||
|
.light-style .flatpickr-next-month svg {
|
||||||
|
fill: #646e78;
|
||||||
|
stroke: #646e78;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-calendar,
|
||||||
|
.light-style .flatpickr-days {
|
||||||
|
width: calc(16.75rem + 0 * 2px) !important;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-calendar {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 0.375rem !important;
|
||||||
|
}
|
||||||
|
.light-style:not([dir=rtl]) .flatpickr-calendar.hasWeeks {
|
||||||
|
width: calc(19rem + 0 * 3px + 0.35rem) !important;
|
||||||
|
}
|
||||||
|
.light-style[dir=rtl] .flatpickr-calendar.hasWeeks {
|
||||||
|
width: calc(19rem + 0 * 3px + 1rem) !important;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-calendar.open {
|
||||||
|
z-index: 1091;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-input[readonly],
|
||||||
|
.light-style .flatpickr-input ~ .form-control[readonly] {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-days {
|
||||||
|
background: #fff;
|
||||||
|
padding: 0.25rem 0.5rem 0.5rem;
|
||||||
|
border: 0 solid #e4e6e8;
|
||||||
|
border-top: 0;
|
||||||
|
background-clip: padding-box;
|
||||||
|
border-bottom-right-radius: 0.375rem;
|
||||||
|
border-bottom-left-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
.light-style:not([dir=rtl]) .flatpickr-calendar.hasWeeks .flatpickr-days {
|
||||||
|
border-left: 0;
|
||||||
|
padding-left: calc(0.5rem + 0px);
|
||||||
|
box-shadow: 0 0 0 #e4e6e8 inset;
|
||||||
|
}
|
||||||
|
.light-style[dir=rtl] .flatpickr-calendar.hasWeeks .flatpickr-days {
|
||||||
|
border-right: 0;
|
||||||
|
padding-right: calc(0.5rem + 0px);
|
||||||
|
box-shadow: 0 0 0 #e4e6e8 inset;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-calendar {
|
||||||
|
line-height: 1.375;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
box-shadow: 0 0.25rem 0.75rem 0 rgba(34, 48, 62, 0.14);
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-calendar.hasTime:not(.noCalendar):not(.hasTime) .flatpickr-time {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-calendar.hasTime .flatpickr-time {
|
||||||
|
box-shadow: 0 1px 0 #e4e6e8 inset;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-monthDropdown-months {
|
||||||
|
color: #384551;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-current-month {
|
||||||
|
font-size: 112%;
|
||||||
|
color: #384551;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-current-month .cur-month,
|
||||||
|
.light-style .flatpickr-current-month .cur-year {
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #384551;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-month,
|
||||||
|
.light-style span.flatpickr-weekday,
|
||||||
|
.light-style .flatpickr-weekdays {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-month {
|
||||||
|
border-top-left-radius: 0.375rem;
|
||||||
|
border-top-right-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-month option.flatpickr-monthDropdown-month {
|
||||||
|
color: #384551;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.light-style span.flatpickr-weekday {
|
||||||
|
color: #384551;
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-day {
|
||||||
|
color: #384551;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-day:hover, .light-style .flatpickr-day:focus, .light-style .flatpickr-day.prevMonthDay:hover, .light-style .flatpickr-day.nextMonthDay:hover, .light-style .flatpickr-day.today:hover, .light-style .flatpickr-day.prevMonthDay:focus, .light-style .flatpickr-day.nextMonthDay:focus, .light-style .flatpickr-day.today:focus {
|
||||||
|
color: #384551;
|
||||||
|
background: #f2f3f3;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-day:hover:not(.today), .light-style .flatpickr-day:focus:not(.today), .light-style .flatpickr-day.prevMonthDay:hover:not(.today), .light-style .flatpickr-day.nextMonthDay:hover:not(.today), .light-style .flatpickr-day.today:hover:not(.today), .light-style .flatpickr-day.prevMonthDay:focus:not(.today), .light-style .flatpickr-day.nextMonthDay:focus:not(.today), .light-style .flatpickr-day.today:focus:not(.today) {
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-day.prevMonthDay, .light-style .flatpickr-day.nextMonthDay, .light-style .flatpickr-day.flatpickr-disabled {
|
||||||
|
color: #a7acb2 !important;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-day.prevMonthDay.today, .light-style .flatpickr-day.nextMonthDay.today, .light-style .flatpickr-day.flatpickr-disabled.today {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-day.disabled {
|
||||||
|
color: #a7acb2 !important;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-day.selected.startRange.endRange {
|
||||||
|
border-radius: 0.375rem !important;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-weeks {
|
||||||
|
border-bottom: 0 solid #e4e6e8;
|
||||||
|
border-left: 0 solid #e4e6e8;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom-right-radius: 0.375rem;
|
||||||
|
border-bottom-left-radius: 0.375rem;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-weeks .flatpickr-day {
|
||||||
|
color: #384551;
|
||||||
|
}
|
||||||
|
.light-style[dir=rtl] .flatpickr-weeks {
|
||||||
|
border-right: 0 solid #e4e6e8;
|
||||||
|
border-left: 0;
|
||||||
|
border-bottom-right-radius: 0.375rem;
|
||||||
|
border-bottom-left-radius: 0.375rem;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-time {
|
||||||
|
border: 0 solid #e4e6e8;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-time input {
|
||||||
|
color: #646e78;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-time .numInputWrapper span.arrowUp:after {
|
||||||
|
border-bottom-color: #a7acb2;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-time .numInputWrapper span.arrowDown:after {
|
||||||
|
border-top-color: #a7acb2;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-time .flatpickr-am-pm {
|
||||||
|
color: #646e78;
|
||||||
|
}
|
||||||
|
.light-style .flatpickr-time .flatpickr-time-separator {
|
||||||
|
color: #646e78;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark-style .flatpickr-calendar {
|
||||||
|
background: #2b2c40;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-prev-month,
|
||||||
|
.dark-style .flatpickr-next-month {
|
||||||
|
background-color: rgba(230, 230, 241, 0.08);
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-prev-month svg,
|
||||||
|
.dark-style .flatpickr-next-month svg {
|
||||||
|
fill: #b2b2c4;
|
||||||
|
stroke: #b2b2c4;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-calendar,
|
||||||
|
.dark-style .flatpickr-days {
|
||||||
|
width: calc(16.75rem + 0 * 2px) !important;
|
||||||
|
}
|
||||||
|
.dark-style:not([dir=rtl]) .flatpickr-calendar.hasWeeks {
|
||||||
|
width: calc(19rem + 0 * 3px + 0.355rem) !important;
|
||||||
|
}
|
||||||
|
.dark-style[dir=rtl] .flatpickr-calendar.hasWeeks {
|
||||||
|
width: calc(19rem + 0 * 3px + 1rem) !important;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-calendar.open {
|
||||||
|
z-index: 1091;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-input:not(.is-invalid):not(.is-valid) ~ .form-control:disabled,
|
||||||
|
.dark-style .flatpickr-input:not(.is-invalid):not(.is-valid)[readonly],
|
||||||
|
.dark-style .flatpickr-input:not(.is-invalid):not(.is-valid) ~ .form-control[readonly] {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-days {
|
||||||
|
border: 0 solid #4e4f6c;
|
||||||
|
border-top: 0;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
background: #2b2c40;
|
||||||
|
background-clip: padding-box;
|
||||||
|
border-bottom-right-radius: 0.375rem;
|
||||||
|
border-bottom-left-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
.dark-style:not([dir=rtl]) .flatpickr-calendar.hasWeeks .flatpickr-days {
|
||||||
|
border-left: 0;
|
||||||
|
padding-left: calc(0.5rem + 0px);
|
||||||
|
box-shadow: 0 0 0 #4e4f6c inset;
|
||||||
|
}
|
||||||
|
.dark-style[dir=rtl] .flatpickr-calendar.hasWeeks .flatpickr-days {
|
||||||
|
border-right: 0;
|
||||||
|
padding-right: calc(0.5rem + 0px);
|
||||||
|
box-shadow: 0 0 0 #4e4f6c inset;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-calendar {
|
||||||
|
line-height: 1.375;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
box-shadow: 0 0.25rem 0.75rem 0 rgba(20, 20, 29, 0.24);
|
||||||
|
background-color: #2b2c40;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-calendar.hasTime:not(.noCalendar):not(.hasTime) .flatpickr-time {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-calendar.hasTime .flatpickr-time {
|
||||||
|
box-shadow: 0 1px 0 #4e4f6c inset;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-month,
|
||||||
|
.dark-style span.flatpickr-weekday,
|
||||||
|
.dark-style .flatpickr-weekdays {
|
||||||
|
background: #2b2c40;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-month {
|
||||||
|
border-top-left-radius: 0.375rem;
|
||||||
|
border-top-right-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-month option.flatpickr-monthDropdown-month {
|
||||||
|
color: #b2b2c4;
|
||||||
|
background: #2b2c40;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-monthDropdown-months {
|
||||||
|
color: #d5d5e2;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-current-month {
|
||||||
|
font-size: 112%;
|
||||||
|
color: #d5d5e2;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-current-month .cur-month,
|
||||||
|
.dark-style .flatpickr-current-month .cur-year {
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #d5d5e2;
|
||||||
|
}
|
||||||
|
.dark-style span.flatpickr-weekday {
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
color: #d5d5e2;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-day {
|
||||||
|
color: #d5d5e2;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-day:hover, .dark-style .flatpickr-day:focus, .dark-style .flatpickr-day.nextMonthDay:hover, .dark-style .flatpickr-day.prevMonthDay:hover, .dark-style .flatpickr-day.today:hover, .dark-style .flatpickr-day.nextMonthDay:focus, .dark-style .flatpickr-day.prevMonthDay:focus, .dark-style .flatpickr-day.today:focus {
|
||||||
|
border-color: transparent;
|
||||||
|
color: #d5d5e2;
|
||||||
|
background: #434463;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-day.nextMonthDay, .dark-style .flatpickr-day.prevMonthDay, .dark-style .flatpickr-day.flatpickr-disabled {
|
||||||
|
color: #7e7f96 !important;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-day.nextMonthDay.today, .dark-style .flatpickr-day.prevMonthDay.today, .dark-style .flatpickr-day.flatpickr-disabled.today {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-day.selected.startRange.endRange {
|
||||||
|
border-radius: 0.375rem !important;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-day.disabled {
|
||||||
|
color: #7e7f96 !important;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-weeks {
|
||||||
|
border-bottom: 0 solid #4e4f6c;
|
||||||
|
border-left: 0 solid #4e4f6c;
|
||||||
|
background: #2b2c40;
|
||||||
|
border-bottom-right-radius: 0.375rem;
|
||||||
|
border-bottom-left-radius: 0.375rem;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-weeks .flatpickr-day {
|
||||||
|
color: #d5d5e2;
|
||||||
|
}
|
||||||
|
.dark-style[dir=rtl] .flatpickr-weeks {
|
||||||
|
border-right: 0 solid #4e4f6c;
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-time {
|
||||||
|
border: 0 solid #4e4f6c;
|
||||||
|
background: #2b2c40;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-time input {
|
||||||
|
color: #b2b2c4;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-time .numInputWrapper span.arrowUp:after {
|
||||||
|
border-bottom-color: #7e7f96;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-time .numInputWrapper span.arrowDown:after {
|
||||||
|
border-top-color: #7e7f96;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-time .flatpickr-am-pm {
|
||||||
|
color: #b2b2c4;
|
||||||
|
}
|
||||||
|
.dark-style .flatpickr-time .flatpickr-time-separator {
|
||||||
|
color: #b2b2c4;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
144
public/assets/vendor/libs/flatpickr/flatpickr.js
vendored
Normal file
144
public/assets/vendor/libs/flatpickr/flatpickr.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -9,7 +9,7 @@ import { useNavigate } from "react-router-dom";
|
|||||||
|
|
||||||
const Attendance = ( {attendance, getRole, handleModalData} ) =>
|
const Attendance = ( {attendance, getRole, handleModalData} ) =>
|
||||||
{
|
{
|
||||||
console.log(attendance)
|
|
||||||
const { currentPage, totalPages, currentItems, paginate } = usePagination(attendance, 5);
|
const { currentPage, totalPages, currentItems, paginate } = usePagination(attendance, 5);
|
||||||
const [loading,setLoading] = useState(false);
|
const [loading,setLoading] = useState(false);
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
@ -47,7 +47,6 @@ console.log(attendance)
|
|||||||
></Avatar>
|
></Avatar>
|
||||||
<div className="d-flex flex-column">
|
<div className="d-flex flex-column">
|
||||||
<a
|
<a
|
||||||
// href="#"
|
|
||||||
onClick={(e) =>navigate(`/employee/${item.employeeId}?for=attendance`)}
|
onClick={(e) =>navigate(`/employee/${item.employeeId}?for=attendance`)}
|
||||||
className="text-heading text-truncate cursor-pointer"
|
className="text-heading text-truncate cursor-pointer"
|
||||||
>
|
>
|
||||||
@ -68,7 +67,7 @@ console.log(attendance)
|
|||||||
<td>{item.checkInTime ? convertShortTime(item.checkInTime):"--"}</td>
|
<td>{item.checkInTime ? convertShortTime(item.checkInTime):"--"}</td>
|
||||||
<td>{item.checkOutTime ? convertShortTime(item.checkOutTime):"--"}</td>
|
<td>{item.checkOutTime ? convertShortTime(item.checkOutTime):"--"}</td>
|
||||||
|
|
||||||
<td className="mx-24" >
|
<td className="text-center" >
|
||||||
<RenderAttendanceStatus attendanceData={item} handleModalData={handleModalData} Tab={1} currentDate={null}/>
|
<RenderAttendanceStatus attendanceData={item} handleModalData={handleModalData} Tab={1} currentDate={null}/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -4,7 +4,7 @@ import AttendLogs from './AttendLogs'
|
|||||||
import Confirmation from './Confirmation'
|
import Confirmation from './Confirmation'
|
||||||
|
|
||||||
const AttendanceModel = ({modelConfig,closeModal,handleSubmitForm}) => {
|
const AttendanceModel = ({modelConfig,closeModal,handleSubmitForm}) => {
|
||||||
console.log(modelConfig)
|
|
||||||
return (
|
return (
|
||||||
<div className={`modal-dialog modal-md modal-simple ${modelConfig.type === "view" ? "modal-lg":"modal-md"}`} >
|
<div className={`modal-dialog modal-md modal-simple ${modelConfig.type === "view" ? "modal-lg":"modal-md"}`} >
|
||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
|
@ -21,11 +21,15 @@ const InfraPlanning = () =>
|
|||||||
{
|
{
|
||||||
const {profile: LoggedUser} = useProfile()
|
const {profile: LoggedUser} = useProfile()
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
|
const {projects,loading:project_listLoader,error:projects_error} = useProjects()
|
||||||
|
|
||||||
const selectedProject = useSelector((store)=>store.localVariables.projectId)
|
const selectedProject = useSelector((store)=>store.localVariables.projectId)
|
||||||
const ManageInfra = useHasUserPermission( MANAGE_PROJECT_INFRA )
|
const ManageInfra = useHasUserPermission( MANAGE_PROJECT_INFRA )
|
||||||
const {projects,loading:project_listLoader,error:projects_error} = useProjects()
|
|
||||||
const {projects_Details, loading: project_deatilsLoader, error: project_error} = useProjectDetails(selectedProject)
|
const {projects_Details, loading: project_deatilsLoader, error: project_error} = useProjectDetails(selectedProject)
|
||||||
|
useEffect( () =>
|
||||||
|
{
|
||||||
|
dispatch(setProjectId(projects[0]?.id))
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4">
|
<div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4">
|
||||||
@ -93,8 +97,13 @@ const InfraPlanning = () =>
|
|||||||
</button>
|
</button>
|
||||||
</div> */}
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
<div className="row ">
|
<div className="row ">
|
||||||
<InfraTable buildings={projects_Details?.buildings}/>
|
{project_deatilsLoader && ( <p>Loading...</p> )}
|
||||||
|
{( !project_deatilsLoader && projects_Details?.buildings.length === 0 ) && ( <p>No Result Found</p> )}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{(!project_deatilsLoader && projects_Details?.buildings?.length > 0) && (<InfraTable buildings={projects_Details?.buildings}/>)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -23,7 +23,7 @@ const RenderAttendanceStatus = ({ attendanceData, handleModalData,Tab,currentDat
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-auto d-flex gap-2 align-items-center justify-content-between">
|
<div className="d-flex justify-content-center">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`btn btn-xs ${color}`}
|
className={`btn btn-xs ${color}`}
|
||||||
@ -39,7 +39,7 @@ const RenderAttendanceStatus = ({ attendanceData, handleModalData,Tab,currentDat
|
|||||||
{attendanceData?.checkInTime && (
|
{attendanceData?.checkInTime && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-xs btn-success"
|
className="btn btn-xs btn-success ms-2"
|
||||||
tabIndex="0"
|
tabIndex="0"
|
||||||
aria-controls="DataTables_Table_0"
|
aria-controls="DataTables_Table_0"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
|
180
src/components/Activities/ReportTask.jsx
Normal file
180
src/components/Activities/ReportTask.jsx
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import { formatDate } from "../../utils/dateUtils";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { z } from "zod";
|
||||||
|
import showToast from "../../services/toastService";
|
||||||
|
import { TasksRepository } from "../../repositories/TaskRepository";
|
||||||
|
|
||||||
|
export const ReportTask = ({ report,closeModal,refetch }) => {
|
||||||
|
const [ loading, setloading ] = useState( false );
|
||||||
|
|
||||||
|
|
||||||
|
const schema = z.object({
|
||||||
|
completedTask: z
|
||||||
|
.number()
|
||||||
|
.min(1, "Completed Work must be at least 1")
|
||||||
|
.max(
|
||||||
|
report?.plannedTask,
|
||||||
|
`Completed Work cannot exceed ${report?.plannedTask}`
|
||||||
|
)
|
||||||
|
.int("Completed Work must be an integer")
|
||||||
|
.positive("Completed Work must be a positive number")
|
||||||
|
.optional(),
|
||||||
|
comment: z.string().min(1, "Comment cannot be empty"),
|
||||||
|
});
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm({
|
||||||
|
resolver: zodResolver(schema),
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
setloading(true)
|
||||||
|
const reportData = {
|
||||||
|
...data,
|
||||||
|
id: report?.id,
|
||||||
|
reportedDate: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let response = await TasksRepository.reportTsak( reportData )
|
||||||
|
showToast( "succesfully", "success" )
|
||||||
|
refetch()
|
||||||
|
closeModal()
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
showToast("Somthing wrog", "error");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleClose = () => {
|
||||||
|
closeModal();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
|
||||||
|
<div className="modal-dialog modal-md modal-simple report-task-modal" role="document">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-body px-1">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close"
|
||||||
|
|
||||||
|
onClick={handleClose}
|
||||||
|
aria-label="Close"
|
||||||
|
></button>
|
||||||
|
|
||||||
|
<div className="container m-0">
|
||||||
|
<div className="d-flex justify-content-between">
|
||||||
|
|
||||||
|
<figure class="text-start p-0 m-0">
|
||||||
|
<blockquote class="blockquote">
|
||||||
|
<small> Assigned Date : {formatDate(report?.assignmentDate)}</small>
|
||||||
|
</blockquote>
|
||||||
|
</figure>
|
||||||
|
<figure class="text-end p-0 m-0">
|
||||||
|
<blockquote class="blockquote">
|
||||||
|
<small>Assigned By</small>
|
||||||
|
</blockquote>
|
||||||
|
<figcaption className="blockquote-footer mb-0">
|
||||||
|
{/* <div className="d-flex avatar avatar-xs">
|
||||||
|
<span className="avatar-initial rounded-circle bg-label-primary">
|
||||||
|
{report?.assignedBy?.firstName.slice(0, 1)}
|
||||||
|
</span> */}
|
||||||
|
<cite title="Source Title m-0">{` ${report?.assignedBy.firstName} ${report?.assignedBy.lastName}`}</cite>
|
||||||
|
{/* </div> */}
|
||||||
|
</figcaption>
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="d-flex p-0 m-0">
|
||||||
|
<div className="flex-shrink-0 mt-1 mx-sm-0 px-2 mx-auto">
|
||||||
|
<i class="bx bx-buildings"></i>
|
||||||
|
</div>
|
||||||
|
<p class="lead">{report?.workItem?.workArea?.floor?.building?.name}</p>
|
||||||
|
<p class="lead ms-12">{report?.workItem?.workArea?.floor?.floorName}</p>
|
||||||
|
</div>
|
||||||
|
<dl class="row text-start ms-3">
|
||||||
|
<dt class="col-sm-6">
|
||||||
|
Work Area : {report?.workItem?.workArea?.areaName}
|
||||||
|
</dt>
|
||||||
|
<dd class="col-sm-6">
|
||||||
|
<small> {report?.workItem?.activityMaster.activityName}</small>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<dl class="row text-start ms-3">
|
||||||
|
<dt class="col-sm-4">Team</dt>
|
||||||
|
|
||||||
|
<dd class="col-sm-4 d-flex align-items-center avatar-group justify-content-start">
|
||||||
|
{report?.teamMembers.map((member) => (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
data-bs-html="true"
|
||||||
|
data-popup="tooltip-custom"
|
||||||
|
data-bs-placement="top"
|
||||||
|
title={`${member.firstName} ${member.lastName}`}
|
||||||
|
className="avatar avatar-xs"
|
||||||
|
>
|
||||||
|
{/* <img src="..." alt="Avatar" class="rounded-circle pull-up" /> */}
|
||||||
|
<span className="avatar-initial rounded-circle bg-label-primary">
|
||||||
|
{member?.firstName.slice(0, 1)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
))}
|
||||||
|
</dd>
|
||||||
|
<dt class="col-sm-4 text-start">Planned : {report?.plannedTask}</dt>
|
||||||
|
</dl>
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<div className="row p-0">
|
||||||
|
<div className="col-4">
|
||||||
|
<input
|
||||||
|
{...register("completedTask", { valueAsNumber: true })}
|
||||||
|
id="smallInput"
|
||||||
|
className="form-control form-control-sm"
|
||||||
|
type="number"
|
||||||
|
placeholder="Completed Work"
|
||||||
|
/>
|
||||||
|
{errors.completedTask && (
|
||||||
|
<div className="text-danger">{errors.completedTask.message}</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="col-8">
|
||||||
|
<textarea
|
||||||
|
{...register("comment")}
|
||||||
|
className="form-control"
|
||||||
|
id="exampleFormControlTextarea1"
|
||||||
|
rows="1"
|
||||||
|
placeholder="Enter comment"
|
||||||
|
/>
|
||||||
|
{errors.comment && (
|
||||||
|
<div className="text-danger">{errors.comment.message}</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-12 text-center my-2">
|
||||||
|
<button type="submit" className="btn btn-sm btn-primary me-3">
|
||||||
|
{loading ? "Please wait":"Submit Report"}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-sm btn-label-secondary"
|
||||||
|
onClick={handleClose}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
158
src/components/Activities/ReportTaskComments.jsx
Normal file
158
src/components/Activities/ReportTaskComments.jsx
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
import React, {useEffect, useState} from "react";
|
||||||
|
import {useProfile} from "../../hooks/useProfile";
|
||||||
|
import moment from "moment";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { z } from "zod";
|
||||||
|
import {TasksRepository} from "../../repositories/TaskRepository";
|
||||||
|
import showToast from "../../services/toastService";
|
||||||
|
|
||||||
|
|
||||||
|
const schema = z.object({
|
||||||
|
comment: z.string().min(1, "Comment cannot be empty"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const ReportTaskComments = ( {commentsData, closeModal} ) =>
|
||||||
|
{
|
||||||
|
const [loading,setloading]=useState(false)
|
||||||
|
const {profile} = useProfile()
|
||||||
|
const [comments,setComment] = useState([])
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },reset
|
||||||
|
} = useForm({
|
||||||
|
resolver: zodResolver(schema),
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect( () =>
|
||||||
|
{
|
||||||
|
setComment(commentsData?.comments
|
||||||
|
)
|
||||||
|
}, [commentsData] )
|
||||||
|
const isLoggedUser = ( usrId ) => profile?.employeeInfo.id;
|
||||||
|
|
||||||
|
const onSubmit = async(data) =>
|
||||||
|
{
|
||||||
|
let sendComment = {
|
||||||
|
...data,
|
||||||
|
taskAllocationId: commentsData?.id,
|
||||||
|
commentDate: new Date().toISOString(),
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
setloading(true)
|
||||||
|
// const resp = await TasksRepository.taskComments( sendComment );
|
||||||
|
// console.timeLog( resp )
|
||||||
|
reset()
|
||||||
|
setloading(false)
|
||||||
|
showToast( "Successfully Sent", "success" )
|
||||||
|
closeModal()
|
||||||
|
} catch ( err )
|
||||||
|
{
|
||||||
|
setloading(false)
|
||||||
|
showToast(error.response.data?.message || "Something wrong","error")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="modal-dialog modal-md modal-simple report-task-comments-modal"
|
||||||
|
role="document"
|
||||||
|
>
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-body px-1">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close"
|
||||||
|
onClick={closeModal}
|
||||||
|
aria-label="Close"
|
||||||
|
></button>
|
||||||
|
<div className="container ">
|
||||||
|
|
||||||
|
{
|
||||||
|
comments && comments.map( ( data ) =>
|
||||||
|
(
|
||||||
|
<div className="text-start" key={data.id}>
|
||||||
|
<div class={`li-wrapper d-flex justify-content-${isLoggedUser(data?.employee?.id) ? "end":"start"} align-items-start`}>
|
||||||
|
<div class="avatar avatar-xs me-1">
|
||||||
|
<span class="avatar-initial rounded-circle bg-label-success">
|
||||||
|
M
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="text-start py-0">
|
||||||
|
<p class="mb-0">
|
||||||
|
<strong>{ `${data?.employee?.firstName} ${data?.employee?.lastName}`}</strong>
|
||||||
|
</p>
|
||||||
|
<small style={{fontSize: "10px"}}>{ moment(data?.commentDate).fromNow()}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className={`ms-${ isLoggedUser( data?.employee?.id ) ? "0 text-end me-6" : "6 " } mt-1`}>{ data?.comment
|
||||||
|
}</p>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
{/* by other users */}
|
||||||
|
{/* <div className="text-start">
|
||||||
|
<div class="li-wrapper d-flex justify-content-start align-items-start">
|
||||||
|
<div class="avatar avatar-xs me-1">
|
||||||
|
<span class="avatar-initial rounded-circle bg-label-success">
|
||||||
|
M
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="text-start py-0">
|
||||||
|
<p class="mb-0">
|
||||||
|
<strong>Mahajan</strong>
|
||||||
|
</p>
|
||||||
|
<small style={{ fontSize: "10px" }}>2 hour ago</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="ms-6 mt-1">Stylized implementation of HTML’s element for abbreviations and acronyms to show the expanded version on hover. Abbreviations have a default underline and gain a help cursor to provide additional context on hov </p>
|
||||||
|
</div> */}
|
||||||
|
|
||||||
|
{/* by login usrer */}
|
||||||
|
{/* <div className="text-start">
|
||||||
|
<div class="li-wrapper d-flex justify-content-end align-items-start">
|
||||||
|
<div class="avatar avatar-xs me-1">
|
||||||
|
<span class="avatar-initial rounded-circle bg-label-success">
|
||||||
|
M
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="text-start py-0">
|
||||||
|
<p class="mb-0">
|
||||||
|
<strong>Pramod Mahajan</strong>
|
||||||
|
</p>
|
||||||
|
<small style={{ fontSize: "10px" }}>2 hour ago</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="ms-6 mt-1">Stylized implementation of HTML’s element for abbreviations and acronyms to show the expanded version on hover. Abbreviations have a default underline and gain a help cursor to provide additional context on hov </p>
|
||||||
|
</div> */}
|
||||||
|
<form onSubmit={handleSubmit( onSubmit )}>
|
||||||
|
<textarea
|
||||||
|
{...register("comment")}
|
||||||
|
className="form-control"
|
||||||
|
id="exampleFormControlTextarea1"
|
||||||
|
rows="1"
|
||||||
|
placeholder="Enter comment"
|
||||||
|
/>
|
||||||
|
{errors.comment && (
|
||||||
|
<div className="danger-text">{errors.comment.message}</div>
|
||||||
|
)}
|
||||||
|
<div class="text-end my-1">
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-secondary" onClick={closeModal} data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" class="btn btn-primary ms-2">{ loading ? "Sending...":"Comment"}</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReportTaskComments;
|
@ -16,13 +16,12 @@ import showToast from "../../services/toastService";
|
|||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
selectedEmployees: z.array( z.number() ).min( 1, {message: "At least one employee must be selected"} ),
|
selectedEmployees: z.array( z.number() ).min( 1, {message: "At least one employee must be selected"} ),
|
||||||
description: z.string().min( 1, {message: "description required"} ),
|
description: z.string().min( 1, {message: "description required"} ),
|
||||||
pannedTask: z.number()
|
|
||||||
.refine(value => value > 0, { message: "pannedTask should be greater than zero" })
|
|
||||||
.refine(value => value !== undefined, { message: "pannedTask is required" }),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const AssignRoleModel = ( {assignData,onClose}) => {
|
const AssignRoleModel = ( {assignData,onClose}) => {
|
||||||
|
const [ plannedTask, setPlannedTask ] = useState()
|
||||||
const { openModal, closeModal } = useModal()
|
const { openModal, closeModal } = useModal()
|
||||||
const selectedProject = useSelector((store)=>store.localVariables.projectId)
|
const selectedProject = useSelector((store)=>store.localVariables.projectId)
|
||||||
const {employees} = useEmployeesAllOrByProjectId( selectedProject )
|
const {employees} = useEmployeesAllOrByProjectId( selectedProject )
|
||||||
@ -78,7 +77,7 @@ const handleEmployeeSelection = (employeeId,field) => {
|
|||||||
const removeEmployee = (employeeId) => {
|
const removeEmployee = (employeeId) => {
|
||||||
setSelectedEmployees((prevSelected) => {
|
setSelectedEmployees((prevSelected) => {
|
||||||
const updatedSelection = prevSelected.filter((id) => id !== employeeId);
|
const updatedSelection = prevSelected.filter((id) => id !== employeeId);
|
||||||
setValue("selectedEmployees", updatedSelection);
|
setValue("selectedEmployees", updatedSelection); // Ensure form state is updated
|
||||||
return updatedSelection;
|
return updatedSelection;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -105,7 +104,6 @@ const onSubmit = async(data) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
console.log(assignData?.workItem?.workItem)
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
dispatch(changeMaster("Job Role"))
|
dispatch(changeMaster("Job Role"))
|
||||||
return ()=> setSelectedRole("all")
|
return ()=> setSelectedRole("all")
|
||||||
@ -212,6 +210,8 @@ useEffect(()=>{
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
{selectedEmployees.length > 0 && (
|
{selectedEmployees.length > 0 && (
|
||||||
<div className="mt-1">
|
<div className="mt-1">
|
||||||
<div className="text-start px-2">
|
<div className="text-start px-2">
|
||||||
@ -236,29 +236,23 @@ useEffect(()=>{
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{errors.selectedEmployees && (
|
|
||||||
<div className="danger-text mt-1">
|
|
||||||
<p>{errors.selectedEmployees[0]}</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div class="col-md text-start mx-0 px-0">
|
<div class="col-md text-start mx-0 px-0">
|
||||||
<div class="form-check form-check-inline mt-4 px-1">
|
<div class="form-check form-check-inline mt-4 px-1">
|
||||||
<label className="form-text fs-6" for="inlineCheckbox1">Pending Work</label>
|
<label className="form-text fs-6" for="inlineCheckbox1">Pending Work</label>
|
||||||
<label className="form-check-label ms-2" for="inlineCheckbox1">{ assignData?.workItem?.workItem?.plannedWork - assignData?.workItem?.workItem?.completedWork}</label>
|
<label className="form-check-label ms-2" for="inlineCheckbox1">{ assignData?.workItem?.workItem?.plannedWork - assignData?.workItem?.workItem?.completedWork}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-check form-check-inline col-sm-2 col">
|
<div className="form-check form-check-inline col-sm-2 col">
|
||||||
<label for="defaultFormControlInput" className="form-label">Target</label>
|
<label for="defaultFormControlInput" className="form-label">Target</label>
|
||||||
<Controller name="pannedTask" control={control} render={( {field} ) => (
|
<input type="text" className="form-control form-control-sm " value={plannedTask} onChange={(e)=>setPlannedTask(e.target.value)} id="defaultFormControlInput" aria-describedby="defaultFormControlHelp" />
|
||||||
<input type="text" className="form-control form-control-sm " {...field} />
|
|
||||||
)} />
|
|
||||||
{errors.pannedTask && (
|
|
||||||
<div className="danger-text">
|
|
||||||
<p>{errors.pannedTask.message}</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{errors.selectedEmployees && (
|
||||||
|
<div className="danger-text mt-1">
|
||||||
|
<p>{errors.selectedEmployees[0]}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<label for="exampleFormControlTextarea1" className="form-label">Description</label>
|
<label for="exampleFormControlTextarea1" className="form-label">Description</label>
|
||||||
<Controller
|
<Controller
|
||||||
name="description"
|
name="description"
|
||||||
|
@ -16,6 +16,7 @@ const buildingSchema = z.object({
|
|||||||
|
|
||||||
const BuildingModel = ({
|
const BuildingModel = ({
|
||||||
project,
|
project,
|
||||||
|
onClose,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
clearTrigger,
|
clearTrigger,
|
||||||
onClearComplete,
|
onClearComplete,
|
||||||
@ -70,6 +71,8 @@ const BuildingModel = ({
|
|||||||
className="btn-close"
|
className="btn-close"
|
||||||
data-bs-dismiss="modal"
|
data-bs-dismiss="modal"
|
||||||
aria-label="Close"
|
aria-label="Close"
|
||||||
|
onClick={onClose}
|
||||||
|
|
||||||
></button>
|
></button>
|
||||||
<h5 className="text-center mb-2">Manage Buildings - {project.name}</h5>
|
<h5 className="text-center mb-2">Manage Buildings - {project.name}</h5>
|
||||||
<form onSubmit={handleSubmit(onSubmitHandler)} className="row g-2">
|
<form onSubmit={handleSubmit(onSubmitHandler)} className="row g-2">
|
||||||
@ -115,7 +118,7 @@ const BuildingModel = ({
|
|||||||
<button type="submit" className="btn btn-primary me-3">
|
<button type="submit" className="btn btn-primary me-3">
|
||||||
{formData.id ? "Edit Building" : "Add Building"}
|
{formData.id ? "Edit Building" : "Add Building"}
|
||||||
</button>
|
</button>
|
||||||
<button type="reset" className="btn btn-label-secondary" data-bs-dismiss="modal" aria-label="Close">
|
<button type="reset" className="btn btn-label-secondary" data-bs-dismiss="modal" aria-label="Close" onClick={onClose}>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,11 +2,16 @@ import React, { useState } from "react";
|
|||||||
import { useModal } from "../../../ModalContext";
|
import { useModal } from "../../../ModalContext";
|
||||||
import AssignRoleModel from "../AssignRole";
|
import AssignRoleModel from "../AssignRole";
|
||||||
import {useParams} from "react-router-dom";
|
import {useParams} from "react-router-dom";
|
||||||
|
import GlobalModel from "../../common/GlobalModel";
|
||||||
|
|
||||||
const WorkItem = ( {workItem, forBuilding, forFloor, forWorkArea} ) =>{
|
const WorkItem = ( {workItem, forBuilding, forFloor, forWorkArea} ) =>{
|
||||||
const {projectId} = useParams()
|
const {projectId} = useParams()
|
||||||
const { openModal ,closedModal} = useModal();
|
const [ itemName, setItemName ] = useState( '' );
|
||||||
const [itemName, setItemName] = useState('');
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
|
const openModal = () => setIsModalOpen(true);
|
||||||
|
const closeModal = () => setIsModalOpen(false);
|
||||||
const getProgress = (planned, completed) => {
|
const getProgress = (planned, completed) => {
|
||||||
return (completed * 100) / planned + "%";
|
return (completed * 100) / planned + "%";
|
||||||
};
|
};
|
||||||
@ -16,12 +21,12 @@ const WorkItem = ( {workItem, forBuilding, forFloor, forWorkArea} ) =>{
|
|||||||
setItemName('');
|
setItemName('');
|
||||||
};
|
};
|
||||||
|
|
||||||
const showCreateItemModal = (modalData) => {
|
// const showCreateItemModal = (modalData) => {
|
||||||
openModal(
|
// openModal(
|
||||||
<AssignRoleModel assignData={modalData} onClose={closedModal} />,
|
// <AssignRoleModel assignData={modalData} onClose={closedModal} />,
|
||||||
handleAssignTask ,"lg"
|
// handleAssignTask ,"lg"
|
||||||
);
|
// );
|
||||||
};
|
// };
|
||||||
|
|
||||||
let assigndata = {
|
let assigndata = {
|
||||||
building: forBuilding,
|
building: forBuilding,
|
||||||
@ -30,6 +35,11 @@ const WorkItem = ( {workItem, forBuilding, forFloor, forWorkArea} ) =>{
|
|||||||
workItem
|
workItem
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<GlobalModel isOpen={isModalOpen}
|
||||||
|
closeModal={closeModal} dialogClass="modal-dialog-centered" role="document" size="lg" >
|
||||||
|
<AssignRoleModel assignData={assigndata} onClose={closeModal} />
|
||||||
|
</GlobalModel>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="text-start table-cell-small">
|
<td className="text-start table-cell-small">
|
||||||
<i className="bx bx-right-arrow-alt"></i>
|
<i className="bx bx-right-arrow-alt"></i>
|
||||||
@ -68,10 +78,7 @@ const WorkItem = ( {workItem, forBuilding, forFloor, forWorkArea} ) =>{
|
|||||||
className="btn p-0"
|
className="btn p-0"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#project-modal"
|
data-bs-target="#project-modal"
|
||||||
onClick={() =>
|
onClick={openModal}
|
||||||
{
|
|
||||||
showCreateItemModal(assigndata)
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<span className="badge bg-label-primary me-1">Assign</span>
|
<span className="badge bg-label-primary me-1">Assign</span>
|
||||||
</button>)}
|
</button>)}
|
||||||
@ -91,7 +98,8 @@ const WorkItem = ( {workItem, forBuilding, forFloor, forWorkArea} ) =>{
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,12 +5,14 @@ import ProjectRepository from "../../repositories/ProjectRepository";
|
|||||||
import { cacheData,getCachedData } from "../../slices/apiDataManager";
|
import { cacheData,getCachedData } from "../../slices/apiDataManager";
|
||||||
import {hasUserPermission} from "../../utils/authUtils";
|
import {hasUserPermission} from "../../utils/authUtils";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
import {useHasUserPermission} from "../../hooks/useHasUserPermission";
|
||||||
|
import {MANAGE_PROJECT} from "../../utils/constants";
|
||||||
|
|
||||||
|
|
||||||
const ProjectBanner = ( {project_data} ) =>
|
const ProjectBanner = ( {project_data} ) =>
|
||||||
{
|
{
|
||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
|
const manageProject = useHasUserPermission(MANAGE_PROJECT)
|
||||||
const [ CurrentProject, setCurrentProject ] = useState( project_data )
|
const [ CurrentProject, setCurrentProject ] = useState( project_data )
|
||||||
if (project_data == null) {
|
if (project_data == null) {
|
||||||
return <span>incomplete project information</span>;
|
return <span>incomplete project information</span>;
|
||||||
@ -118,7 +120,7 @@ const ProjectBanner = ( {project_data} ) =>
|
|||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`btn btn-sm btn-primary ${hasUserPermission("53176ebf-c75d-42e5-839f-4508ffac3def") ? "":"d-none"}`}
|
className={`btn btn-sm btn-primary ${!manageProject && 'd-none'}`}
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#edit-project-modal"
|
data-bs-target="#edit-project-modal"
|
||||||
onClick={handleShow}
|
onClick={handleShow}
|
||||||
|
@ -223,6 +223,7 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
|
|||||||
const closeBuildingModel = () => {
|
const closeBuildingModel = () => {
|
||||||
setIsBuildingModalOpen(false);
|
setIsBuildingModalOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBuildingModelFormSubmit = (buildingmodel) => {
|
const handleBuildingModelFormSubmit = (buildingmodel) => {
|
||||||
if (buildingmodel.id == "" || buildingmodel.id == 0)
|
if (buildingmodel.id == "" || buildingmodel.id == 0)
|
||||||
delete buildingmodel.id;
|
delete buildingmodel.id;
|
||||||
@ -337,7 +338,6 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={`modal fade ${showModal ? 'show' : ''}`}
|
className={`modal fade ${showModal ? 'show' : ''}`}
|
||||||
tabIndex="-1"
|
tabIndex="-1"
|
||||||
@ -347,14 +347,12 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
|
|||||||
>
|
>
|
||||||
<BuildingModel
|
<BuildingModel
|
||||||
project={data}
|
project={data}
|
||||||
onClose={closeBuildingModel}
|
onClose={handleClose}
|
||||||
onSubmit={handleBuildingModelFormSubmit}
|
onSubmit={handleBuildingModelFormSubmit}
|
||||||
clearTrigger={clearFormTrigger}
|
clearTrigger={clearFormTrigger}
|
||||||
onClearComplete={() => setClearFormTrigger(false)}
|
onClearComplete={() => setClearFormTrigger(false)}
|
||||||
></BuildingModel>
|
></BuildingModel>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{isFloorModalOpen && (
|
{isFloorModalOpen && (
|
||||||
<div
|
<div
|
||||||
className={`modal fade `}
|
className={`modal fade `}
|
||||||
|
77
src/components/common/GlobalModel.jsx
Normal file
77
src/components/common/GlobalModel.jsx
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import React, { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
const GlobalModel = ({
|
||||||
|
isOpen,
|
||||||
|
closeModal,
|
||||||
|
children,
|
||||||
|
modalType = '', // For custom positioning like modal-top, modal-bottom
|
||||||
|
dialogClass = '', // For additional custom classes on modal dialog
|
||||||
|
role = 'dialog', // Accessibility role for the modal
|
||||||
|
size = '', // Dynamically set the size (sm, lg, xl)
|
||||||
|
dataAttributes = {} // Additional dynamic data-bs-* attributes
|
||||||
|
}) => {
|
||||||
|
const modalRef = useRef(null); // Reference to the modal element
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const modalElement = modalRef.current;
|
||||||
|
const modalInstance = new window.bootstrap.Modal(modalElement);
|
||||||
|
|
||||||
|
// Show modal if isOpen is true
|
||||||
|
if (isOpen) {
|
||||||
|
modalInstance.show();
|
||||||
|
} else {
|
||||||
|
modalInstance.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle modal hide event to invoke the closeModal function
|
||||||
|
const handleHideModal = () => {
|
||||||
|
closeModal(); // Close the modal via React state
|
||||||
|
};
|
||||||
|
|
||||||
|
modalElement.addEventListener('hidden.bs.modal', handleHideModal);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
modalElement.removeEventListener('hidden.bs.modal', handleHideModal);
|
||||||
|
};
|
||||||
|
}, [isOpen, closeModal]);
|
||||||
|
|
||||||
|
// Dynamically set the modal size classes (modal-sm, modal-lg, modal-xl)
|
||||||
|
const modalSizeClass = size ? `modal-${size}` : ''; // Default is empty if no size is specified
|
||||||
|
|
||||||
|
// Dynamically generate data-bs attributes
|
||||||
|
const dataAttributesProps = Object.keys(dataAttributes).map(key => ({
|
||||||
|
[key]: dataAttributes[key],
|
||||||
|
}));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`modal fade ${modalType}`}
|
||||||
|
id="customModal"
|
||||||
|
tabIndex="-1"
|
||||||
|
aria-labelledby="exampleModalLabel"
|
||||||
|
aria-hidden="true"
|
||||||
|
ref={modalRef} // Assign the ref to the modal element
|
||||||
|
{...dataAttributesProps}
|
||||||
|
>
|
||||||
|
<div className={`modal-dialog ${dialogClass} ${modalSizeClass}`} role={role}>
|
||||||
|
<div className="modal-content">
|
||||||
|
<div className="modal-header">
|
||||||
|
{/* Close button inside the modal header */}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close"
|
||||||
|
data-bs-dismiss="modal"
|
||||||
|
aria-label="Close"
|
||||||
|
onClick={closeModal} // Trigger the React closeModal function
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
{children} {/* Render children here, which can be the ReportTask component */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GlobalModel;
|
40
src/hooks/useTasks.js
Normal file
40
src/hooks/useTasks.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { TasksRepository } from "../repositories/TaskRepository";
|
||||||
|
import { cacheData, getCachedData } from "../slices/apiDataManager";
|
||||||
|
|
||||||
|
export const useTaskList = (projectId, fromDate, ToDate) => {
|
||||||
|
const [TaskList, setTaskList] = useState([]);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [error, setError] = useState(null);
|
||||||
|
|
||||||
|
const fetchList = async () => {
|
||||||
|
const taskList_cached = getCachedData("taskList");
|
||||||
|
if (!taskList_cached || taskList_cached?.projectId !== projectId) {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const resp = await TasksRepository.getTaskList(
|
||||||
|
projectId,
|
||||||
|
fromDate,
|
||||||
|
ToDate
|
||||||
|
);
|
||||||
|
setTaskList(resp.data);
|
||||||
|
cacheData("taskList", { projectId: projectId, data: resp.data });
|
||||||
|
setLoading(false);
|
||||||
|
} catch (err) {
|
||||||
|
setLoading(false);
|
||||||
|
console.log(err);
|
||||||
|
setError(err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setTaskList(taskList_cached.data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(TaskList)
|
||||||
|
useEffect(() => {
|
||||||
|
if (projectId) {
|
||||||
|
fetchList();
|
||||||
|
}
|
||||||
|
}, [projectId, fromDate, ToDate]);
|
||||||
|
|
||||||
|
return { TaskList, loading, error, refetch:fetchList};
|
||||||
|
};
|
@ -1,10 +1,81 @@
|
|||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||||
|
import { dailyTask } from "../../data/masters";
|
||||||
|
import { useTaskList } from "../../hooks/useTasks";
|
||||||
|
import { useProjects } from "../../hooks/useProjects";
|
||||||
|
import { setProjectId } from "../../slices/localVariablesSlice";
|
||||||
|
import { useProfile } from "../../hooks/useProfile";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import {formatDate} from "../../utils/dateUtils";
|
||||||
|
import GlobalModel from "../../components/common/GlobalModel";
|
||||||
|
import AssignRoleModel from "../../components/Project/AssignRole";
|
||||||
|
import {ReportTask} from "../../components/Activities/ReportTask";
|
||||||
|
import ReportTaskComments from "../../components/Activities/ReportTaskComments";
|
||||||
|
|
||||||
import Breadcrumb from "../../components/common/Breadcrumb"
|
const DailyTask = () => {
|
||||||
import { dailyTask } from "../../data/masters"
|
const { profile: LoggedUser } = useProfile();
|
||||||
const DailyTask =()=>{
|
const {
|
||||||
return (
|
projects,
|
||||||
<>
|
loading: project_lodaing,
|
||||||
<div className="container-xxl flex-grow-1 container-p-y">
|
error: projects_Error,
|
||||||
|
} = useProjects();
|
||||||
|
const selectedProject = useSelector(
|
||||||
|
(store) => store.localVariables.projectId
|
||||||
|
);
|
||||||
|
const dispatch = useDispatch( selectedProject );
|
||||||
|
const {
|
||||||
|
TaskList,
|
||||||
|
loading: task_loading,
|
||||||
|
error: task_error,
|
||||||
|
refetch
|
||||||
|
} = useTaskList(selectedProject);
|
||||||
|
const [TaskLists, setTaskLists] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTaskLists(TaskList);
|
||||||
|
}, [ TaskList, selectedProject ] );
|
||||||
|
|
||||||
|
const [ selectedTask, selectTask ] = useState( null )
|
||||||
|
const [comments,setComment] = useState(null)
|
||||||
|
|
||||||
|
const [ isModalOpen, setIsModalOpen ] = useState( false );
|
||||||
|
const [ isModalOpenComment, setIsModalOpenComment ] = useState( false )
|
||||||
|
|
||||||
|
const openModal = () => setIsModalOpen(true);
|
||||||
|
const closeModal = () => setIsModalOpen( false );
|
||||||
|
|
||||||
|
const openComment = () =>setIsModalOpenComment(true)
|
||||||
|
const closeCommentModal =()=>setIsModalOpenComment(false)
|
||||||
|
const handletask = (task) =>
|
||||||
|
{
|
||||||
|
selectTask(task)
|
||||||
|
openModal()
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
className={`modal fade ${isModalOpen ? 'show' : ''}`}
|
||||||
|
tabIndex="-1"
|
||||||
|
role="dialog"
|
||||||
|
style={{ display: isModalOpen ? 'block' : 'none' }}
|
||||||
|
aria-hidden={!isModalOpen}
|
||||||
|
>
|
||||||
|
<ReportTask report={selectedTask} closeModal={ closeModal} refetch={refetch} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={`modal fade ${isModalOpenComment ? 'show' : ''}`}
|
||||||
|
tabIndex="-1"
|
||||||
|
role="dialog"
|
||||||
|
style={{ display: isModalOpenComment ? 'block' : 'none' }}
|
||||||
|
aria-hidden={!isModalOpenComment}
|
||||||
|
>
|
||||||
|
<ReportTaskComments commentsData={comments} closeModal={ closeCommentModal} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className="container-xxl flex-grow-1 container-p-y">
|
||||||
<Breadcrumb
|
<Breadcrumb
|
||||||
data={[
|
data={[
|
||||||
{ label: "Home", link: "/dashboard" },
|
{ label: "Home", link: "/dashboard" },
|
||||||
@ -14,61 +85,153 @@ const DailyTask =()=>{
|
|||||||
<div className="card card-action mb-6">
|
<div className="card card-action mb-6">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
|
<div className="col-sm-3 col-8 text-start mb-1">
|
||||||
|
<select
|
||||||
|
name="DataTables_Table_0_length"
|
||||||
|
aria-controls="DataTables_Table_0"
|
||||||
|
className="form-select form-select-sm"
|
||||||
|
value={selectedProject}
|
||||||
|
onChange={(e) => dispatch(setProjectId(e.target.value))}
|
||||||
|
aria-label=""
|
||||||
|
>
|
||||||
|
{(project_lodaing || projects.length < 0) && (
|
||||||
|
<option value="Loading..." disabled>
|
||||||
|
Loading...
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
{!project_lodaing &&
|
||||||
|
projects
|
||||||
|
?.filter((project) =>
|
||||||
|
LoggedUser?.projects?.map(Number).includes(project.id)
|
||||||
|
)
|
||||||
|
.map((project) => (
|
||||||
|
<option value={project.id} key={project.id}>
|
||||||
|
{project.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="table-responsive text-nowrap">
|
<div className="table-responsive text-nowrap">
|
||||||
{/* {employees && employees.length > 0 ? ( */}
|
<table className="table">
|
||||||
<table className="table ">
|
<thead>
|
||||||
<thead>
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th>Activity</th>
|
||||||
|
<th>Planned </th>
|
||||||
|
<th>Compeleted</th>
|
||||||
|
<th>Assign On</th>
|
||||||
|
<th>Team</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="table-border-bottom-0">
|
||||||
|
{TaskLists?.length === 0 && !task_loading && (
|
||||||
<tr>
|
<tr>
|
||||||
<th>Sr</th>
|
<td colSpan={7} className="text-center">
|
||||||
<th>Project Name</th>
|
No Data Found
|
||||||
<th>Target</th>
|
</td>
|
||||||
<th>Employees</th>
|
|
||||||
|
|
||||||
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
)}
|
||||||
<tbody className="table-border-bottom-0">
|
|
||||||
|
{task_loading && (
|
||||||
|
<tr>
|
||||||
|
<td colSpan={7} className="text-center">
|
||||||
|
<p>Loading..</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{TaskLists.map((task, index) => {
|
||||||
|
const accordionId = `accordion-${index}`;
|
||||||
|
return (
|
||||||
|
<React.Fragment key={index}>
|
||||||
|
{/* Main Row */}
|
||||||
<tr >
|
<tr >
|
||||||
<td>
|
<td>
|
||||||
<div className="d-flex justify-content-center align-items-center">
|
<div className="d-flex justify-content-center align-items-center" data-bs-toggle="collapse"
|
||||||
|
data-bs-target={`#${accordionId}`}
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-controls={accordionId}
|
||||||
|
>
|
||||||
<div className="d-flex flex-column">
|
<div className="d-flex flex-column">
|
||||||
<a href="#" className="text-heading text-truncate">
|
<a
|
||||||
<span className="fw-medium ">
|
href="#"
|
||||||
1
|
className="text-heading text-truncate"
|
||||||
</span>
|
|
||||||
|
>
|
||||||
|
<i class='bx bx-chevron-right'></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="flex-wrap">
|
<td className="flex-wrap">
|
||||||
project Name project Name project Name
|
{task.workItem.activityMaster.activityName || "No Activity Name"}
|
||||||
</td>
|
</td>
|
||||||
|
<td>{task.plannedTask || "NA"}</td>
|
||||||
<td>
|
<td>{task.completedTask}</td>
|
||||||
80
|
<td>{formatDate( task.assignmentDate )}</td>
|
||||||
|
<td className="text-center">
|
||||||
|
<div class="d-flex align-items-center avatar-group justify-content-center">
|
||||||
|
{task.teamMembers.map( ( member ) => (
|
||||||
|
|
||||||
|
<div key={member.id} data-bs-toggle="tooltip" data-bs-html="true" data-popup="tooltip-custom" data-bs-placement="top" title={`${member.firstName} ${member.lastName}`} className="avatar avatar-xs">
|
||||||
|
{/* <img src="..." alt="Avatar" class="rounded-circle pull-up" /> */}
|
||||||
|
<span className="avatar-initial rounded-circle bg-label-primary">{member?.firstName.slice(0,1) }</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
<td className="text-center">
|
||||||
<td> NA</td>
|
<div className="d-flex justify-content-center">
|
||||||
|
<button
|
||||||
<td>
|
type="button"
|
||||||
|
className="btn btn-xs btn-primary"
|
||||||
<button type="button" className="btn btn-xs btn-primary">Report</button>
|
onClick={() =>
|
||||||
|
{
|
||||||
|
selectTask( task )
|
||||||
|
openModal()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Report
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-xs btn-primary ms-2"
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
setComment( task )
|
||||||
|
openComment()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Comment
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{/* ))} */}
|
|
||||||
</tbody>
|
{/* Accordion Content */}
|
||||||
</table>
|
<tr
|
||||||
|
id={accordionId}
|
||||||
|
className="accordion-collapse collapse"
|
||||||
|
>
|
||||||
|
<td colSpan={5}>
|
||||||
|
<div className="row">
|
||||||
|
<p>{task.subdata?.name}</p>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
export default DailyTask
|
export default DailyTask;
|
||||||
|
@ -17,7 +17,8 @@ const loginScheam = z.object( {
|
|||||||
|
|
||||||
const LoginPage = () => {
|
const LoginPage = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [loading, setLoading] = useState(false);
|
const [ loading, setLoading ] = useState( false );
|
||||||
|
const[hidepass,setHidepass] = useState(true)
|
||||||
|
|
||||||
const {register,
|
const {register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@ -93,7 +94,7 @@ const LoginPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="input-group input-group-merge">
|
<div className="input-group input-group-merge">
|
||||||
<input
|
<input
|
||||||
type="password"
|
type={hidepass ? "password" :"text"}
|
||||||
autoComplete="true"
|
autoComplete="true"
|
||||||
id="password"
|
id="password"
|
||||||
{...register("password")}
|
{...register("password")}
|
||||||
@ -102,7 +103,7 @@ const LoginPage = () => {
|
|||||||
placeholder="············"
|
placeholder="············"
|
||||||
aria-describedby="password"
|
aria-describedby="password"
|
||||||
/>
|
/>
|
||||||
<span className="input-group-text cursor-pointer"></span>
|
<span class="input-group-text cursor-pointer" onClick={()=>setHidepass(!hidepass)}>{ hidepass ? <i className="bx bx-hide"></i> :<i className="bx bx-show"></i>}</span>
|
||||||
</div>
|
</div>
|
||||||
{errors.password && (
|
{errors.password && (
|
||||||
<div
|
<div
|
||||||
|
7
src/repositories/TaskRepository.jsx
Normal file
7
src/repositories/TaskRepository.jsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import {api} from "../utils/axiosClient";
|
||||||
|
|
||||||
|
export const TasksRepository = {
|
||||||
|
getTaskList: ( id, fromdate = null, todate = null ) => api.get( `api/task/list?projectId=${ id }` ),
|
||||||
|
reportTsak: ( data ) => api.post( 'api/task/report', data ),
|
||||||
|
taskComments:(data)=>api.post("api/task/comment",data)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user