addded imported field added

This commit is contained in:
pramod.mahajan 2025-10-01 18:45:26 +05:30
parent 2531d91209
commit 9884943907
13 changed files with 111 additions and 112 deletions

View File

@ -138,7 +138,7 @@ const Attendance = ({ getRole, handleModalData, searchTerm, projectId, organizat
<tr className="border-top-1">
<th colSpan={2}>Name</th>
<th>Role</th>
<th>Organization</th>
{/* <th>Organization</th> */}
<th>
<i className="bx bxs-down-arrow-alt text-success"></i>
Check-In
@ -187,7 +187,7 @@ const Attendance = ({ getRole, handleModalData, searchTerm, projectId, organizat
</td>
<td>{item.jobRoleName}</td>
<td>{item.organizationName || "--"}</td>
{/* <td>{item.organizationName || "--"}</td> */}
<td>
{item.checkInTime

View File

@ -84,56 +84,50 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
dateRange.endDate,
organizationId
);
const filtering = (data) => {
const filteredData = showPending
? data.filter((item) => item.checkOutTime === null)
: data;
const filtering = useCallback((dataToFilter) => {
const filteredData = showPending
? dataToFilter.filter((item) => item.checkOutTime === null)
: dataToFilter;
const group1 = filteredData
.filter((d) => d.activity === 1 && isSameDay(d.checkInTime))
.sort(sortByName);
const group2 = filteredData
.filter((d) => d.activity === 4 && isSameDay(d.checkOutTime))
.sort(sortByName);
const group3 = filteredData
.filter((d) => d.activity === 1 && isBeforeToday(d.checkInTime))
.sort(sortByName);
const group4 = filteredData.filter(
(d) => d.activity === 4 && isBeforeToday(d.checkOutTime)
);
const group5 = filteredData
.filter((d) => d.activity === 2 && isBeforeToday(d.checkOutTime))
.sort(sortByName);
const group6 = filteredData
.filter((d) => d.activity === 5)
.sort(sortByName);
const group1 = filteredData
.filter((d) => d.activity === 1 && isSameDay(d.checkInTime))
.sort(sortByName);
const group2 = filteredData
.filter((d) => d.activity === 4 && isSameDay(d.checkOutTime))
.sort(sortByName);
const group3 = filteredData
.filter((d) => d.activity === 1 && isBeforeToday(d.checkInTime))
.sort(sortByName);
const group4 = filteredData.filter(
(d) => d.activity === 4 && isBeforeToday(d.checkOutTime)
);
const group5 = filteredData
.filter((d) => d.activity === 2 && isBeforeToday(d.checkOutTime))
.sort(sortByName);
const group6 = filteredData
.filter((d) => d.activity === 5)
.sort(sortByName);
const sortedList = [
...group1,
...group2,
...group3,
...group4,
...group5,
...group6,
];
const sortedList = [...group1, ...group2, ...group3, ...group4, ...group5, ...group6];
// Group by date
const groupedByDate = sortedList.reduce((acc, item) => {
const date = (item.checkInTime || item.checkOutTime)?.split("T")[0];
if (date) {
acc[date] = acc[date] || [];
acc[date].push(item);
}
return acc;
}, {});
// Group by date
const groupedByDate = sortedList.reduce((acc, item) => {
const date = (item.checkInTime || item.checkOutTime)?.split("T")[0];
if (date) {
acc[date] = acc[date] || [];
acc[date].push(item);
}
return acc;
}, {});
const sortedDates = Object.keys(groupedByDate).sort(
(a, b) => new Date(b) - new Date(a)
);
const sortedDates = Object.keys(groupedByDate).sort(
(a, b) => new Date(b) - new Date(a)
);
const finalData = sortedDates.flatMap((date) => groupedByDate[date]);
setProcessedData(finalData);
}, [showPending]);
const finalData = sortedDates.flatMap((date) => groupedByDate[date]);
setProcessedData(finalData);
};
useEffect(() => {
filtering(data);
@ -285,7 +279,7 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
Name
</th>
<th className="border-top-1">Date</th>
<th>Organization</th>
{/* <th>Organization</th> */}
<th>
<i className="bx bxs-down-arrow-alt text-success"></i> Check-In
</th>
@ -344,7 +338,7 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
attendance.checkInTime || attendance.checkOutTime
).format("DD-MMM-YYYY")}
</td>
<td>{attendance.organizationName || "--"}</td>
{/* <td>{attendance.organizationName || "--"}</td> */}
<td>{convertShortTime(attendance.checkInTime)}</td>
<td>
{attendance.checkOutTime

View File

@ -89,7 +89,7 @@ const CheckInCheckOut = ({ modeldata, closeModal, handleSubmitForm }) => {
Id: modeldata?.id || null,
comment: data.description,
employeeID: modeldata.employeeId,
// projectId: projectId,
projectId: projectId,
date: new Date().toISOString(),
markTime: data.markTime,
latitude: coords.latitude.toString(),

View File

@ -128,7 +128,7 @@ const Regularization = ({ handleRequest, searchTerm,projectId, organizationId, I
<tr>
<th colSpan={2}>Name</th>
<th>Date</th>
<th>Organization</th>
{/* <th>Organization</th> */}
<th>
<i className="bx bxs-down-arrow-alt text-success"></i>Check-In
</th>
@ -158,7 +158,7 @@ const Regularization = ({ handleRequest, searchTerm,projectId, organizationId, I
</td>
<td>{moment(att.checkOutTime).format("DD-MMM-YYYY")}</td>
<td>{att.organizationName || "--"}</td>
{/* <td>{att.organizationName || "--"}</td> */}
<td>{convertShortTime(att.checkInTime)}</td>
<td>

View File

@ -86,6 +86,8 @@ const ListViewContact = ({ data, Pagination, isLoading }) => {
ActiveInActive({ contactId: contactId, contactStatus: !showActive });
};
if(isLoading) return <Loader/>
if(!data|| data.length === 0)return <div className="text-center py-12">No Contact Found</div>
return (
<>
<ConfirmModal
@ -103,11 +105,7 @@ const ListViewContact = ({ data, Pagination, isLoading }) => {
className="card-datatable table-responsive"
id="horizontal-example"
>
{isLoading && (
<div>
<Loader />
</div>
)}
{data && (
<div className="dataTables_wrapper no-footer mx-5 pb-2">
<table className="table dataTable text-nowrap">
@ -124,7 +122,7 @@ const ListViewContact = ({ data, Pagination, isLoading }) => {
</tr>
</thead>
<tbody>
{Array.isArray(data) && data.length > 0 ? (
{Array.isArray(data) && data.length > 0 && (
data.map((row, i) => (
<tr
key={i}
@ -184,16 +182,7 @@ const ListViewContact = ({ data, Pagination, isLoading }) => {
</td>
</tr>
))
) : (
<tr style={{ height: "200px" }}>
<td
colSpan={contactList.length + 1}
className="text-center align-middle border-0"
>
No contacts found
</td>
</tr>
)}
) }
</tbody>
</table>
{Pagination && (

View File

@ -23,7 +23,7 @@ import Label from "../common/Label";
const ManageContact = ({ contactId, closeModal }) => {
// fetch master data
const { buckets, loading: bucketsLoaging } = useBuckets();
const { data:projects, loading: projectLoading } = useProjects();
const { data: projects, loading: projectLoading } = useProjects();
const { contactCategory, loading: contactCategoryLoading } =
useContactCategory();
const { organizationList } = useOrganization();
@ -205,13 +205,14 @@ const ManageContact = ({ contactId, closeModal }) => {
<Label htmlFor={"organization"} required>
Organization
</Label>
<InputSuggestions
organizationList={organizationList}
value={watch("organization") || ""}
onChange={(val) => setValue("organization", val, { shouldValidate: true })}
error={errors.organization?.message}
/>
<InputSuggestions
organizationList={organizationList}
value={watch("organization") || ""}
onChange={(val) =>
setValue("organization", val, { shouldValidate: true })
}
error={errors.organization?.message}
/>
</div>
</div>
@ -394,6 +395,7 @@ const ManageContact = ({ contactId, closeModal }) => {
labelKey="name"
valueKey="id"
IsLoading={projectLoading}
/>
{errors.projectIds && (
<small className="danger-text">{errors.projectIds.message}</small>
@ -408,6 +410,7 @@ const ManageContact = ({ contactId, closeModal }) => {
label="Tags"
options={contactTags}
isRequired={true}
require
/>
{errors.tags && (
<small className="danger-text">{errors.tags.message}</small>
@ -417,7 +420,7 @@ const ManageContact = ({ contactId, closeModal }) => {
{/* Buckets */}
<div className="row">
<div className="col-md-12 mt-1 text-start">
<label className="form-label ">Select Bucket</label>
<Label required>Select Bucket</Label>
<ul className="d-flex flex-wrap px-1 list-unstyled mb-0">
{bucketsLoaging && <p>Loading...</p>}
{buckets?.map((item) => (
@ -450,7 +453,7 @@ const ManageContact = ({ contactId, closeModal }) => {
</div>
{/* Address + Description */}
<div className="col-12 text-start">
<div className="col-12 text-start mb-2">
<label className="form-label">Address</label>
<textarea
className="form-control form-control-sm"
@ -459,7 +462,7 @@ const ManageContact = ({ contactId, closeModal }) => {
/>
</div>
<div className="col-12 text-start">
<label className="form-label">Description</label>
<Label required>Description</Label>
<textarea
className="form-control form-control-sm"
rows="2"
@ -479,10 +482,13 @@ const ManageContact = ({ contactId, closeModal }) => {
>
Cancel
</button>
<button className="btn btn-sm btn-primary" type="submit" disabled={isPending}>
<button
className="btn btn-sm btn-primary"
type="submit"
disabled={isPending}
>
{isPending ? "Please Wait..." : "Submit"}
</button>
</div>
</form>
</FormProvider>

View File

@ -8,12 +8,14 @@ import { orgSize, reference } from "../../utils/constants";
import moment from "moment";
import { useGlobalServices } from "../../hooks/masterHook/useMaster";
import SelectMultiple from "../common/SelectMultiple";
import { useNavigate } from "react-router-dom";
const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
const { data, isError, isLoading: industryLoading } = useIndustries();
const [logoPreview, setLogoPreview] = useState(null);
const [logoName, setLogoName] = useState("");
const { data: services, isLoading: serviceLoading } = useGlobalServices();
const navigate = useNavigate()
const {
register,
control,
@ -29,7 +31,8 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
error,
isPending,
} = useCreateTenant(() => {
onNext()
// onNext()
navigate("/tenants");
});
const handleNext = async () => {

View File

@ -4,21 +4,26 @@ import { createPortal } from "react-dom";
import "./MultiSelectDropdown.css";
import Label from "./Label";
const SelectMultiple = ({
name,
options = [],
label = "Select options",
labelKey = "name",
labelKey = "name",
valueKey = "id",
placeholder = "Please select...",
IsLoading = false,required = false
IsLoading = false,
required = false,
}) => {
const { setValue, watch,register } = useFormContext();
useEffect(() => {
register(name, { value: [] });
}, [register, name]);
const { setValue, watch, register } = useFormContext();
const selectedValues = watch(name) || [];
useEffect(() => {
register(name, { value: [] });
}, [register, name]);
const selectedValues = watch(name) || [];
const [isOpen, setIsOpen] = useState(false);
const [searchText, setSearchText] = useState("");
@ -60,18 +65,20 @@ const selectedValues = watch(name) || [];
const updated = selectedValues.includes(value)
? selectedValues.filter((v) => v !== value)
: [...selectedValues, value];
setValue(name, updated, { shouldValidate: true });
};
const filteredOptions = (options || []).filter((item) => {
const label = getLabel(item);
return (
typeof label === "string" &&
label.toLowerCase().includes(searchText.toLowerCase())
);
});
const label = getLabel(item);
return typeof label === "string" && label.toLowerCase().includes(searchText.toLowerCase());
});
// Sort filtered options in ascending order
const sortedOptions = filteredOptions.sort((a, b) => {
const labelA = getLabel(a).toString().toLowerCase();
const labelB = getLabel(b).toString().toLowerCase();
return labelA.localeCompare(labelB);
});
const dropdownElement = (
<div
@ -101,7 +108,7 @@ const selectedValues = watch(name) || [];
/>
</div>
{filteredOptions.map((item) => {
{sortedOptions.map((item) => {
const labelVal = getLabel(item);
const valueVal = item[valueKey];
const isChecked = selectedValues.includes(valueVal);
@ -124,12 +131,12 @@ const selectedValues = watch(name) || [];
);
})}
{!IsLoading && filteredOptions.length === 0 && (
{!IsLoading && sortedOptions.length === 0 && (
<div className="multi-select-dropdown-Not-found" style={{ padding: 8 }}>
<label className="text-muted">Not Found {`'${searchText}'`}</label>
</div>
)}
{IsLoading && filteredOptions.length === 0 && (
{IsLoading && sortedOptions.length === 0 && (
<div className="multi-select-dropdown-Not-found" style={{ padding: 8 }}>
<label className="text-muted">Loading...</label>
</div>
@ -140,19 +147,14 @@ const selectedValues = watch(name) || [];
return (
<>
<div ref={containerRef} className="multi-select-dropdown-container" style={{ position: "relative" }}>
<label className="form-label mb-1">{label}</label>
<Label className={name} required={required}></Label>
<Label required={required}>{label}</Label>
<div
className="multi-select-dropdown-header"
onClick={() => setIsOpen((prev) => !prev)}
style={{ cursor: "pointer" }}
>
<span
className={
selectedValues.length > 0 ? "placeholder-style-selected" : "placeholder-style"
}
>
<span className={selectedValues.length > 0 ? "placeholder-style-selected" : "placeholder-style"}>
<div className="selected-badges-container">
{selectedValues.length > 0 ? (
selectedValues.map((val) => {

View File

@ -2,7 +2,7 @@ import { useFormContext, useWatch } from "react-hook-form";
import React, { useEffect, useState } from "react";
import Label from "./Label";
const TagInput = ({ label, name, placeholder, color = "#e9ecef", options = [] }) => {
const TagInput = ({ label, name, placeholder, color = "#e9ecef", options = [],require = false }) => {
const { setValue, watch } = useFormContext();
const tags = watch(name) || [];
const [input, setInput] = useState("");
@ -65,9 +65,9 @@ const handleChange = (e) => {
return (
<>
<label htmlFor={name} className="form-label">
<Label required={require}>
{label}
</label>
</Label>
<div
className="form-control form-control-sm p-1"

View File

@ -399,7 +399,6 @@ export const useUpdateBucket = (onSuccessCallBack) => {
mutationFn: async ({ bucketId, BucketPayload }) =>
await DirectoryRepository.UpdateBuckets(bucketId, BucketPayload),
onSuccess: (_, variables) => {
debugger;
queryClient.invalidateQueries({ queryKey: ["bucketList"] });
showToast("Bucket updated successfully", "success");
if (onSuccessCallBack) onSuccessCallBack();
@ -464,6 +463,7 @@ export const useCreateContact = (onSuccessCallBack) => {
await DirectoryRepository.CreateContact(contactPayload),
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: ["contacts"] });
queryClient.invalidateQueries({ queryKey: ["bucketList"] });
showToast("Contact created Successfully", "success");
if (onSuccessCallBack) onSuccessCallBack();
},

View File

@ -6,6 +6,7 @@ import { useDispatch } from "react-redux";
import { setCurrentTenant } from "../slices/globalVariablesSlice";
import { ITEMS_PER_PAGE } from "../utils/constants";
import moment from "moment";
import { queryClient } from "../layouts/AuthLayout";
const cleanFilter = (filter) => {
const cleaned = { ...filter };
@ -71,6 +72,7 @@ export const useSubscriptionPlan = (freq) => {
// ------------Mutation---------------------
export const useCreateTenant = (onSuccessCallback) => {
const clinet = queryClient()
const dispatch = useDispatch();
return useMutation({
mutationFn: async (tenantPayload) => {
@ -87,6 +89,9 @@ export const useCreateTenant = (onSuccessCallback) => {
operationMode = 2; // tenant exists but subscription not added yet
}
clinet.invalidateQueries({queryKey:["Tenants"]})
dispatch(setCurrentTenant({ operationMode, data }));
if (onSuccessCallback) onSuccessCallback();

View File

@ -88,7 +88,7 @@ const ContactsPage = ({ projectId, searchText, onExport }) => {
)}
{data?.data?.length === 0 && (<div className="py-12 text-secondary">
{data?.data?.length === 0 && (<div className="py-12 ">
{searchText ? `No contact found for "${searchText}"`:"No contacts found" }
</div>)}
{data?.data?.map((contact) => (

View File

@ -22,7 +22,7 @@ export function startSignalR(loggedUser) {
accessTokenFactory: () => jwtToken,
transport: signalR.HttpTransportType.LongPolling,
withCredentials: false,
})
})
.withAutomaticReconnect()
.build();
const todayDate = new Date();