Issues_Aug_2W #371

Merged
pramod.mahajan merged 29 commits from Issues_Aug_2W into main 2025-09-05 05:45:32 +00:00
34 changed files with 1141 additions and 1037 deletions
Showing only changes of commit 4369705a2d - Show all commits

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react";
import { useEmployeeAttendacesLog } from "../../hooks/useAttendance";
import { convertShortTime } from "../../utils/dateUtils";
import { convertShortTime, formatUTCToLocalTime } from "../../utils/dateUtils";
import { useNavigate } from "react-router-dom";
import { THRESH_HOLD } from "../../utils/constants";
@ -128,7 +128,7 @@ const AttendLogs = ({ Id }) => {
<p>
Attendance logs for{" "}
{logs[0]?.employee?.firstName + " " + logs[0]?.employee?.lastName}{" "}
on {logs[0]?.activityTime.slice(0, 10)}{" "}
on {formatUTCToLocalTime(logs[0]?.activityTime)}
</p>
)}
</div>
@ -156,7 +156,7 @@ const AttendLogs = ({ Id }) => {
.sort((a, b) => b.id - a.id)
.map((log, index) => (
<tr key={index}>
<td>{log.activityTime.slice(0, 10)}</td>
<td>{formatUTCToLocalTime(log.activityTime)}</td>
<td>{convertShortTime(log.activityTime)}</td>
<td>
{whichActivityPerform(log.activity, log.activityTime)}

View File

@ -1,7 +1,7 @@
import React, { useState, useEffect, useCallback, useMemo } from "react";
import moment from "moment";
import Avatar from "../common/Avatar";
import { convertShortTime } from "../../utils/dateUtils";
import { convertShortTime, formatUTCToLocalTime } from "../../utils/dateUtils";
import RenderAttendanceStatus from "./RenderAttendanceStatus";
import usePagination from "../../hooks/usePagination";
import { useNavigate } from "react-router-dom";
@ -116,7 +116,7 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
<>
<div className="table-responsive text-nowrap h-100" >
<div className="d-flex text-start align-items-center py-2">
<strong>Date : {todayDate.toLocaleDateString("en-GB")}</strong>
<strong>Date : {formatUTCToLocalTime(todayDate)}</strong>
<div className="form-check form-switch text-start m-0 ms-5">
<input
type="checkbox"

View File

@ -11,6 +11,7 @@ import eventBus from "../../services/eventBus";
import AttendanceRepository from "../../repositories/AttendanceRepository";
import { useAttendancesLogs } from "../../hooks/useAttendance";
import { queryClient } from "../../layouts/AuthLayout";
import { ITEMS_PER_PAGE } from "../../utils/constants";
const usePagination = (data, itemsPerPage) => {
const [currentPage, setCurrentPage] = useState(1);
@ -353,7 +354,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
<span className="text-secondary">No Pending Record Available !</span>
</div>
)}
{filteredSearchData.length > 10 && (
{filteredSearchData.length > ITEMS_PER_PAGE && (
<nav aria-label="Page ">
<ul className="pagination pagination-sm justify-content-end py-1">
<li className={`page-item ${currentPage === 1 ? "disabled" : ""}`}>

View File

@ -1,8 +1,16 @@
import React, { useEffect, useState, useMemo } from "react";
import { DirectoryRepository } from "../../repositories/DirectoryRepository";
import NoteCardDirectoryEditable from "./NoteCardDirectoryEditable";
import { useSelectedproject } from "../../slices/apiDataManager";
const NotesCardViewDirectory = ({
notes,
setNotesForFilter,
searchText,
filterAppliedNotes,
}) => {
const projectId = useSelectedproject(); // get projectId from Redux
const NotesCardViewDirectory = ({ notes, setNotesForFilter, searchText, filterAppliedNotes }) => {
const [allNotes, setAllNotes] = useState([]);
const [filteredNotes, setFilteredNotes] = useState([]);
const [loading, setLoading] = useState(true);
@ -13,13 +21,15 @@ const NotesCardViewDirectory = ({ notes, setNotesForFilter, searchText, filterAp
const pageSize = 20;
useEffect(() => {
fetchNotes();
}, []);
if (projectId) {
fetchNotes(projectId);
}
}, [projectId]);
const fetchNotes = async () => {
const fetchNotes = async (projId) => {
setLoading(true);
try {
const response = await DirectoryRepository.GetNotes(1000, 1);
const response = await DirectoryRepository.GetNotes(1000, 1, projId); // pass projectId
const fetchedNotes = response.data?.data || [];
setAllNotes(fetchedNotes);
setNotesForFilter(fetchedNotes)
@ -122,7 +132,7 @@ const NotesCardViewDirectory = ({ notes, setNotesForFilter, searchText, filterAp
prevNotes.map((n) => (n.id === updatedNote.id ? updatedNote : n))
);
}}
onNoteDelete={() => fetchNotes()}
onNoteDelete={() => fetchNotes(projectId)} // reload with projectId
/>
))}
</div>

View File

@ -126,7 +126,7 @@ const EmpAttendance = ({ employee }) => {
className="dataTables_length text-start py-2 d-flex justify-content-between "
id="DataTables_Table_0_length"
>
<div className="col-md-3 my-0 ">
<div className="col-md-4 my-0 ">
<DateRangePicker
DateDifference="30"
onRangeChange={setDateRange}

View File

@ -59,20 +59,20 @@ const EmpBanner = ({ profile, loggedInUser }) => {
</h4>
<ul className="list-inline mb-0 d-flex align-items-center flex-wrap justify-content-sm-start justify-content-center gap-4 mt-4">
<li className="list-inline-item">
<i className="icon-base bx bx-crown me-2 align-top"></i>
<i className="icon-base bx bx-crown me-1 align-top"></i>
<span className="fw-medium">
{profile?.jobRole || <em>NA</em>}
</span>
</li>
<li className="list-inline-item">
<i className="icon-base bx bx-phone me-2 align-top"></i>
<i className="icon-base bx bx-phone me-0 align-top"></i>
<span className="fw-medium">
{" "}
{profile?.phoneNumber || <em>NA</em>}
</span>
</li>
<li className="list-inline-item">
<i className="icon-base bx bx-calendar me-2 align-top"></i>
<i className="icon-base bx bx-calendar me-0 align-top"></i>
<span className="fw-medium">
{" "}
Joined on{" "}
@ -85,6 +85,7 @@ const EmpBanner = ({ profile, loggedInUser }) => {
</li>
</ul>
<ul className="list-inline mb-0 d-flex align-items-center flex-wrap justify-content-sm-start justify-content-center mt-4">
{profile?.isActive && ( // show only if active
<li className="list-inline-item">
<button
className="btn btn-sm btn-primary btn-block"
@ -93,8 +94,10 @@ const EmpBanner = ({ profile, loggedInUser }) => {
Edit Profile
</button>
</li>
)}
<li className="list-inline-item">
{profile?.id == loggedInUser?.employeeInfo?.id && (
{profile?.id === loggedInUser?.employeeInfo?.id && (
<button
className="btn btn-sm btn-outline-primary btn-block"
onClick={() => openChangePassword()}

View File

@ -105,6 +105,7 @@ const ExpenseFilterPanel = ({ onApply, handleGroupBy }) => {
startField="startDate"
endField="endDate"
resetSignal={resetKey}
defaultRange={false}
/>
</div>

View File

@ -96,19 +96,19 @@ const EditProfile = ({ TenantId,onClose }) => {
</div>
<div className="col-sm-6 mt-1">
<Label htmlFor="domainName" required>Domain Name</Label>
<Label htmlFor="domainName" >Domain Name</Label>
<input id="domainName" type="text" className="form-control form-control-sm" {...register("domainName")} />
{errors.domainName && <div className="danger-text">{errors.domainName.message}</div>}
</div>
<div className="col-sm-6 mt-1">
<Label htmlFor="taxId" required>Tax ID</Label>
<Label htmlFor="taxId" >Tax ID</Label>
<input id="taxId" type="text" className="form-control form-control-sm" {...register("taxId")} />
{errors.taxId && <div className="danger-text">{errors.taxId.message}</div>}
</div>
<div className="col-sm-6 mt-1">
<Label htmlFor="officeNumber" required>Office Number</Label>
<Label htmlFor="officeNumber" >Office Number</Label>
<input id="officeNumber" type="text" className="form-control form-control-sm" {...register("officeNumber")} />
{errors.officeNumber && <div className="danger-text">{errors.officeNumber.message}</div>}
</div>

View File

@ -73,7 +73,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
</div>
<div className="col-sm-6">
<Label htmlFor="officeNumber" required>
<Label htmlFor="officeNumber" >
Office Number
</Label>
<input
@ -87,7 +87,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
</div>
<div className="col-sm-6">
<Label htmlFor="domainName" required>
<Label htmlFor="domainName" >
Domain Name
</Label>
<input
@ -101,7 +101,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
</div>
<div className="col-sm-6">
<Label htmlFor="taxId" required>
<Label htmlFor="taxId" >
Tax ID
</Label>
<input
@ -138,8 +138,10 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
</Label>
<select
className="form-select form-select-sm"
{...register("organizationSize")}
id="organizationSize"
className="form-select shadow-none border py-1 px-2"
style={{ fontSize: "0.875rem" }} // Bootstrap's small text size
{...register("organizationSize", { required: "Organization size is required" })}
>
{orgSize.map((org) => (
<option key={org.val} value={org.val}>
@ -147,17 +149,20 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
</option>
))}
</select>
{errors.organizationSize && (
<div className="danger-text">{errors.organizationSize.message}</div>
)}
</div>
<div className="col-sm-6">
<Label htmlFor="industryId" required>
Industry
</Label>
<select
className="form-select form-select-sm"
id="industryId"
className="form-select shadow-none border py-1 px-2 small"
{...register("industryId")}
>
{industryLoading ? (
@ -177,9 +182,9 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
<div className="col-sm-6">
<Label htmlFor="reference">Reference</Label>
<select
className="form-select form-select-sm"
id="reference"
className="form-select shadow-none border py-1 px-2 small"
{...register("reference")}
>
{reference.map((org) => (
@ -193,6 +198,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
)}
</div>
<div className="col-sm-12">
<Label htmlFor="description">Description</Label>
<textarea

View File

@ -1,5 +1,5 @@
import { zodResolver } from "@hookform/resolvers/zod";
import React, { useState,useCallback } from "react";
import React, { useState, useCallback, useEffect } from "react";
import { FormProvider, useForm, useFormContext } from "react-hook-form";
import { defaultFilterValues, filterSchema } from "./TenantSchema";
import Label from "../common/Label";
@ -8,6 +8,7 @@ import { useIndustries } from "../../hooks/useTenant";
import { reference, TENANT_STATUS } from "../../utils/constants";
import { DateRangePicker1 } from "../common/DateRangePicker";
import moment from "moment";
import { useLocation } from "react-router-dom";
const TenantFilterPanel = ({ onApply }) => {
const [resetKey, setResetKey] = useState(0);
@ -36,6 +37,13 @@ const [resetKey, setResetKey] = useState(0);
[onApply, handleClosePanel]
);
// Close popup when navigating to another component
const location = useLocation();
useEffect(() => {
handleClosePanel();
}, [location]);
const onClear = useCallback(() => {
reset(defaultFilterValues);
setResetKey((prev) => prev + 1); // triggers DateRangePicker reset

View File

@ -11,12 +11,12 @@ export const newTenantSchema = z.object({
.regex(/^[A-Za-z]+$/, { message: "Last Name should contain only letters!" }),
email: z.string().trim().email("Invalid email address"),
description: z.string().trim().optional(),
domainName: z.string().trim().nonempty("Domain name is required"),
domainName: z.string().trim().optional(),
billingAddress: z.string().trim().nonempty("Billing address is required"),
taxId: z.string().trim().nonempty("Tax ID is required"),
taxId: z.string().trim().optional(),
logoImage: z.string().trim().optional(),
organizationName: z.string().trim().nonempty("Organization name is required"),
officeNumber: z.string().trim().nonempty("Office number is required"),
officeNumber: z.string().trim().optional(),
contactNumber: z.string().trim()
.nonempty("Contact number is required")
.regex(/^\+?[1-9]\d{7,14}$/, "Enter a valid contact number"),
@ -141,11 +141,11 @@ lastName: z
.min(1, { message: "Last Name is required!" })
.regex(/^[A-Za-z]+$/, { message: "Last Name should contain only letters!" }),
description: z.string().trim().optional(),
domainName: z.string().trim().min(1, { message: "Domain Name is required!" }),
domainName: z.string().trim().optional(),
billingAddress: z.string().trim().min(1, { message: "Billing Address is required!" }),
taxId: z.string().trim().min(1, { message: "Tax ID is required!" }),
taxId: z.string().trim().optional(),
logoImage: z.string().optional(),
officeNumber: z.string().trim().min(1, { message: "Office Number is required!" }),
officeNumber: z.string().trim().optional(),
contactNumber: z.string().trim()
.nonempty("Contact number is required")
.regex(/^\+?[1-9]\d{7,14}$/, "Enter a valid contact number"),

View File

@ -46,6 +46,12 @@ const DateRangePicker = ({
};
}, [onRangeChange, DateDifference, endDateMode]);
const handleIconClick = () => {
if (inputRef.current) {
inputRef.current._flatpickr.open(); // directly opens flatpickr
}
};
return (
<div className={`col-${sm} col-sm-${md} px-1`}>
<input
@ -57,7 +63,7 @@ const DateRangePicker = ({
/>
<i
className="bx bx-calendar calendar-icon cursor-pointer position-relative top-50 translate-middle-y "
className="bx bx-calendar calendar-icon cursor-pointer position-relative top-50 translate-middle-y " onClick={handleIconClick}
style={{ right: "22px", bottom: "-8px" }}
></i>
</div>

View File

@ -1,4 +1,5 @@
import React, { useState, useEffect } from "react";
import { useSelector } from "react-redux";
const FilterIcon = ({
taskListData,
@ -7,15 +8,26 @@ const FilterIcon = ({
currentSelectedFloors,
currentSelectedActivities,
}) => {
const selectedProject = useSelector((store) => store.localVariables.projectId);
const [selectedBuilding, setSelectedBuilding] = useState(currentSelectedBuilding || "");
const [selectedFloors, setSelectedFloors] = useState(currentSelectedFloors || []);
const [selectedActivities, setSelectedActivities] = useState(currentSelectedActivities || []);
const [appliedBuilding, setAppliedBuilding] = useState(currentSelectedBuilding || "");
const [appliedFloors, setAppliedFloors] = useState(currentSelectedFloors || []);
const [appliedActivities, setAppliedActivities] = useState(currentSelectedActivities || []);
// Reset filters whenever inputs OR projectId changes
useEffect(() => {
setSelectedBuilding(currentSelectedBuilding || "");
setSelectedFloors(currentSelectedFloors || []);
setSelectedActivities(currentSelectedActivities || []);
}, [currentSelectedBuilding, currentSelectedFloors, currentSelectedActivities]);
setAppliedBuilding(currentSelectedBuilding || "");
setAppliedFloors(currentSelectedFloors || []);
setAppliedActivities(currentSelectedActivities || []);
}, [currentSelectedBuilding, currentSelectedFloors, currentSelectedActivities, selectedProject]);
const getUniqueFilterValues = (key, overrideBuilding, overrideFloors) => {
if (!taskListData) return [];
@ -61,12 +73,11 @@ const FilterIcon = ({
} else if (filterType === "floor") {
if (updatedFloors.includes(value)) {
updatedFloors = updatedFloors.filter((floor) => floor !== value);
const validActivities = getUniqueFilterValues("activity", updatedBuilding, updatedFloors);
updatedActivities = updatedActivities.filter((act) => validActivities.includes(act));
} else {
updatedFloors.push(value);
}
const validActivities = getUniqueFilterValues("activity", updatedBuilding, updatedFloors);
updatedActivities = updatedActivities.filter((act) => validActivities.includes(act));
} else if (filterType === "activity") {
if (updatedActivities.includes(value)) {
updatedActivities = updatedActivities.filter((act) => act !== value);
@ -78,12 +89,20 @@ const FilterIcon = ({
setSelectedBuilding(updatedBuilding);
setSelectedFloors(updatedFloors);
setSelectedActivities(updatedActivities);
};
const applyFilters = () => {
setAppliedBuilding(selectedBuilding);
setAppliedFloors(selectedFloors);
setAppliedActivities(selectedActivities);
onApplyFilters({
selectedBuilding: updatedBuilding,
selectedFloors: updatedFloors,
selectedActivities: updatedActivities,
selectedBuilding,
selectedFloors,
selectedActivities,
});
document.getElementById("filterDropdown").click();
};
const clearAllFilters = () => {
@ -91,6 +110,10 @@ const FilterIcon = ({
setSelectedFloors([]);
setSelectedActivities([]);
setAppliedBuilding("");
setAppliedFloors([]);
setAppliedActivities([]);
onApplyFilters({
selectedBuilding: "",
selectedFloors: [],
@ -98,21 +121,51 @@ const FilterIcon = ({
});
};
// Count applied filters
const appliedFilterCount =
(appliedBuilding ? 1 : 0) + appliedFloors.length + appliedActivities.length;
return (
<div className="dropdown" style={{marginLeft:"-14px"}}>
<div className="dropdown" style={{ marginLeft: "-14px", position: "relative" }}>
<a
className="dropdown-toggle hide-arrow cursor-pointer"
id="filterDropdown"
data-bs-toggle="dropdown"
aria-expanded="false"
>
{/* <i className="bx bx-slider-alt ms-1" /> */}
<div style={{ position: "relative", display: "inline-block" }}>
<i
className="bx bx-slider-alt"
style={{ color: selectedBuilding || selectedFloors.length > 0 || selectedActivities.length > 0 ? "#7161EF" : "gray" }}
style={{
color: appliedFilterCount > 0 ? "#7161EF" : "gray",
fontSize: "20px",
}}
></i>
{appliedFilterCount > 0 && (
<span
style={{
position: "absolute",
top: "-11px",
right: "-6px",
backgroundColor: "#FFC107", // yellow
color: "white",
fontSize: "10px",
fontWeight: "bold",
borderRadius: "50%",
width: "18px",
height: "18px",
display: "flex",
alignItems: "center",
justifyContent: "center",
border: "1px solid white",
}}
>
{appliedFilterCount}
</span>
)}
</div>
</a>
<ul
className="dropdown-menu p-2 mt-2"
aria-labelledby="filterDropdown"
@ -205,45 +258,30 @@ const FilterIcon = ({
)}
{/* Action Buttons */}
<li><hr className="my-1" /></li>
{(selectedBuilding || selectedFloors.length > 0 || selectedActivities.length > 0) && (
<li className="d-flex justify-content-end gap-2 px-2">
<li>
<hr className="my-1" />
</li>
{(appliedFilterCount > 0 ||
selectedBuilding ||
selectedFloors.length > 0 ||
selectedActivities.length > 0) && (
<li className="d-flex justify-content-end gap-2 px-2 mt-2 mb-2">
<button
type="button"
className="btn btn-sm"
style={{
backgroundColor: "#7161EF",
color: "white",
fontSize: "13px",
padding: "4px 16px",
borderRadius: "8px",
boxShadow: "0 1px 4px rgba(0,0,0,0.1)"
}}
className="btn btn-secondary btn-sm py-0 px-2"
onClick={clearAllFilters}
>
Clear
</button>
<button
type="button"
className="btn btn-sm"
style={{
backgroundColor: "#7161EF",
color: "white",
fontSize: "13px",
padding: "4px 16px",
borderRadius: "8px",
boxShadow: "0 1px 4px rgba(0,0,0,0.1)"
}}
onClick={() => {
document.getElementById("filterDropdown").click();
}}
className="btn btn-primary btn-sm py-0 px-2"
onClick={applyFilters}
>
Apply
</button>
</li>
)}
</ul>
</div>
);

View File

@ -123,8 +123,7 @@ useEffect(() => {
<input
type="text"
{...register("activityName")}
className={`form-control form-control-sm ${
errors.activityName ? "is-invalid" : ""
className={`form-control form-control-sm ${errors.activityName ? "is-invalid" : ""
}`}
/>
{errors.activityName && (
@ -137,8 +136,7 @@ useEffect(() => {
<input
type="text"
{...register("unitOfMeasurement")}
className={`form-control form-control-sm ${
errors.unitOfMeasurement ? "is-invalid" : ""
className={`form-control form-control-sm ${errors.unitOfMeasurement ? "is-invalid" : ""
}`}
/>
{errors.unitOfMeasurement && (
@ -226,12 +224,13 @@ useEffect(() => {
{isLoading ? "Please Wait" : "Submit"}
</button>
<button
type="reset"
type="button" // change to button
className="btn btn-sm btn-label-secondary"
onClick={handleClose}
>
Cancel
</button>
</div>
</div>
</form>

View File

@ -97,13 +97,16 @@ useEffect(() => {
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="reset"
type="button" // not reset
className="btn btn-sm btn-label-secondary"
data-bs-dismiss="modal"
aria-label="Close"
onClick={() => {
resetForm(); // clear inputs
onClose?.(); // close modal from parent
}}
>
Cancel
</button>
</div>
</form>

View File

@ -97,13 +97,16 @@ useEffect(() => {
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="reset"
type="button" // not reset
className="btn btn-sm btn-label-secondary"
data-bs-dismiss="modal"
aria-label="Close"
onClick={() => {
resetForm(); // clear inputs
onClose?.(); // close modal from parent
}}
>
Cancel
</button>
</div>
</form>

View File

@ -123,13 +123,16 @@ const CreateJobRole = ({onClose}) => {
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="reset"
type="button" // change from reset button
className="btn btn-sm btn-label-secondary"
data-bs-dismiss="modal"
aria-label="Close"
onClick={() => {
resetForm(); // optional: clears form
onClose?.(); // close modal via parent
}}
>
Cancel
</button>
</div>
</form>

View File

@ -233,13 +233,13 @@ const CreateRole = ({ modalType, onClose }) => {
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="reset"
type="button"
className="btn btn-sm btn-label-secondary"
data-bs-dismiss="modal"
aria-label="Close"
onClick={onClose}
>
Cancel
</button>
</div>
)}
</form>

View File

@ -77,9 +77,9 @@ useEffect(() => {
return (<>
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12">
{/* <div className="col-12 col-md-12">
<label className="fs-5 text-dark text-center d-flex align-items-center justify-content-center flex-wrap">Create Work Category</label>
</div>
</div> */}
<div className="col-12 col-md-12">
<label className="form-label">Category Name</label>
@ -113,10 +113,12 @@ useEffect(() => {
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="reset"
type="button" // not reset
className="btn btn-sm btn-label-secondary"
data-bs-dismiss="modal"
aria-label="Close"
onClick={() => {
resetForm(); // clear inputs
onClose?.(); // close modal from parent
}}
>
Cancel
</button>

View File

@ -34,13 +34,15 @@ const DeleteMaster = ({ master, onClose }) => {
)}
</button>
<button
type="reset"
type="button" // not reset
className="btn btn-label-secondary"
data-bs-dismiss="modal"
aria-label="Close"
onClick={() => {
onClose?.(); // properly close modal
}}
>
Cancel
</button>
</div>
</div>
);

View File

@ -241,7 +241,7 @@ useEffect(() => {
{isLoading ? "Please Wait" : "Submit"}
</button>
<button
type="button"
type="button" // change to button
className="btn btn-sm btn-label-secondary"
onClick={onClose}
>

View File

@ -116,10 +116,12 @@ useEffect(() => {
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="button"
type="button" // not reset
className="btn btn-sm btn-label-secondary"
data-bs-dismiss="modal"
aria-label="Close"
onClick={() => {
resetForm(); // clear inputs
onClose?.(); // close modal from parent
}}
>
Cancel
</button>

View File

@ -116,10 +116,12 @@ useEffect(() => {
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="button"
type="button" // not reset
className="btn btn-sm btn-label-secondary"
data-bs-dismiss="modal"
aria-label="Close"
onClick={() => {
resetForm(); // clear inputs
onClose?.(); // close modal from parent
}}
>
Cancel
</button>

View File

@ -134,13 +134,13 @@ const [descriptionLength, setDescriptionLength] = useState(data?.description?.le
<button
type="button"
className="btn btn-sm btn-label-secondary"
data-bs-dismiss="modal"
aria-label="Close"
onClick={onClose} // 👈 This will now close the popup
>
Cancel
</button>
</div>
</form>
</>

View File

@ -280,11 +280,11 @@ const EditMaster = ({ master, onClose }) => {
<button
type="button"
className="btn btn-sm btn-label-secondary"
data-bs-dismiss="modal"
aria-label="Close"
onClick={onClose}
>
Cancel
</button>
</div>
</form>

View File

@ -121,13 +121,13 @@ useEffect(() => {
{isLoading ? "Please Wait..." : "Submit"}
</button>
<button
type="reset"
type="button"
className="btn btn-sm btn-label-secondary"
data-bs-dismiss="modal"
aria-label="Close"
onClick={onClose}
>
Cancel
</button>
</div>
</form>

View File

@ -79,14 +79,14 @@ const ManagePaymentMode = ({ data = null, onClose }) => {
{isPending || Updating ? "Please Wait..." : Updating ? "Update" : "Submit"}
</button>
<button
type="reset"
type="button"
className="btn btn-sm btn-label-secondary"
data-bs-dismiss="modal"
aria-label="Close"
onClick={onClose} // call onClose here
disabled={isPending || Updating}
>
Cancel
</button>
</div>
</form>
);

View File

@ -17,13 +17,13 @@ const cleanFilter = (filter) => {
});
// moment.utc() to get consistent UTC ISO strings
if (!cleaned.startDate) {
cleaned.startDate = moment.utc().subtract(7, "days").startOf("day").toISOString();
}
// if (!cleaned.startDate) {
// cleaned.startDate = moment.utc().subtract(7, "days").startOf("day").toISOString();
// }
if (!cleaned.endDate) {
cleaned.endDate = moment.utc().startOf("day").toISOString();
}
// if (!cleaned.endDate) {
// cleaned.endDate = moment.utc().startOf("day").toISOString();
// }
return cleaned;
};

View File

@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import React, { useEffect, useMemo, useState } from "react";
import { useDispatch } from "react-redux";
import { useTaskList } from "../../hooks/useTasks";
import { useProjectName } from "../../hooks/useProjects";
@ -46,6 +46,15 @@ const DailyTask = () => {
}
}, [selectedProject, projectNames, dispatch]);
// 🔹 Reset filters when project changes
useEffect(() => {
setFilters({
selectedBuilding: "",
selectedFloors: [],
selectedActivities: [],
});
}, [selectedProject]);
// Memoized filtering
const filteredTasks = useMemo(() => {
if (!TaskList) return [];
@ -164,6 +173,7 @@ const DailyTask = () => {
currentSelectedBuilding={filters.selectedBuilding}
currentSelectedFloors={filters.selectedFloors}
currentSelectedActivities={filters.selectedActivities}
selectedProject={selectedProject}
/>
</div>

View File

@ -210,7 +210,7 @@ const LoginPage = () => {
Login With Password
</a>
) : (
<Link to="/auth/reqest/demo" className="registration-link">
<Link to="/market/enquire" className="registration-link">
Request a Demo
</Link>
)}

View File

@ -122,13 +122,16 @@ const MasterPage = () => {
onChange={(e) => dispatch(changeMaster(e.target.value))}
name="DataTables_Table_0_length"
aria-controls="DataTables_Table_0"
className="form-select form-select-sm"
className="form-select py-1 px-2"
style={{ fontSize: "0.875rem", height: "32px", width: "150px" }}
value={selectedMaster}
>
{isLoading && (<option value={null}>Loading...</option>)}
{(!isLoading && data) && data?.map((item) => (
<option key={item.id} value={item.name}>{item.name}</option>
{isLoading && <option value="">Loading...</option>}
{!isLoading &&
data?.map((item) => (
<option key={item.id} value={item.name}>
{item.name}
</option>
))}
</select>
</label>

View File

@ -34,6 +34,8 @@ export const DirectoryRepository = {
DeleteNote: (id, isActive) =>
api.delete(`/api/directory/note/${id}?active=${isActive}`),
GetNotes: (pageSize, pageNumber) =>
api.get(`/api/directory/notes?pageSize=${pageSize}&pageNumber=${pageNumber}`),
GetNotes: (pageSize, pageNumber, projectId) =>
api.get(
`/api/directory/notes?pageSize=${pageSize}&pageNumber=${pageNumber}&projectId=${projectId}`
),
};

View File

@ -1,6 +1,6 @@
import { api } from "../utils/axiosClient";
export const MarketRepository = {
requestDemo: (data) => api.post("/api/market/inquiry", data),
requestDemo: (data) => api.post("/api/market/enquire", data),
getIndustries: () => api.get("api/market/industries"),
};

View File

@ -52,7 +52,7 @@ const router = createBrowserRouter(
children: [
{ path: "/auth/login", element: <LoginPage /> },
{ path: "/auth/login-otp", element: <LoginWithOtp /> },
{ path: "/auth/reqest/demo", element: <RegisterPage /> },
{ path: "/market/enquire", element: <RegisterPage /> },
{ path: "/auth/forgot-password", element: <ForgotPasswordPage /> },
{ path: "/reset-password", element: <ResetPasswordPage /> },
{ path: "/legal-info", element: <LegalInfoCard /> },