Compare commits

...

11 Commits

Author SHA1 Message Date
6f8735d03e Merge pull request 'Selected organization should remain visible after navigating back' (#460) from Kartik_Bug#1381 into Issues_Oct_1W
Reviewed-on: #460
Merged
2025-10-08 13:36:43 +00:00
51374f612b Updation in SPIRD Id selection. 2025-10-08 13:36:43 +00:00
2eb96b222c Selected organization should remain visible after navigating back 2025-10-08 13:36:43 +00:00
bce58aade6 Merge pull request 'Show Meaningful Message When No Employees Exist in a Service Under Project Teams' (#458) from Kartik_Bug#1395 into Issues_Oct_1W
Reviewed-on: #458
merged
2025-10-08 13:23:58 +00:00
fae11d7b8c Show Meaningful Message When No Employees Exist in a Service Under Project Teams 2025-10-08 13:23:58 +00:00
f417194ad3 Merge pull request 'Removing border line in directory contact tab.' (#457) from Kartik_Bug#1429 into Issues_Oct_1W
Reviewed-on: #457
merged
2025-10-08 13:23:40 +00:00
5e10e5080f Removing border line in directory contact tab. 2025-10-08 13:23:40 +00:00
f6f528c394 Merge pull request 'Adding percentage in Infrastructure.' (#456) from Kartik_Bug#1350 into Issues_Oct_1W
Reviewed-on: #456
merged
2025-10-08 13:23:22 +00:00
6151fa9424 Adding percentage in Infrastructure. 2025-10-08 13:23:22 +00:00
00353b23d6 Merge pull request 'UI updation in Organization view and Search button' (#444) from Kartik_Bug#1388 into Issues_Oct_1W
Reviewed-on: #444
merged
2025-10-08 13:23:05 +00:00
9ddf530710 UI updation in Organization view and Search button 2025-10-08 13:23:05 +00:00
7 changed files with 190 additions and 141 deletions

View File

@ -179,7 +179,7 @@ const ListViewContact = ({ data, Pagination }) => {
<tr style={{ height: "200px" }}> <tr style={{ height: "200px" }}>
<td <td
colSpan={contactList.length + 1} colSpan={contactList.length + 1}
className="text-center align-middle" className="text-center align-middle border-0"
> >
No contacts found No contacts found
</td> </td>

View File

@ -92,17 +92,17 @@ const AssignOrg = ({ setStep }) => {
return ( return (
<div className="row text-black text-start mb-3"> <div className="row text-black text-start mb-3">
{/* Organization Info Display */} {/* Organization Info Display */}
<div className="col-12 mb-3"> <div className="col-12 mb-4">
<div className="d-flex justify-content-between align-items-center text-start mb-1"> <div className="d-flex justify-content-between align-items-center">
<div className="d-flex flex-row gap-2 align-items-center text-wrap"> <div className="d-flex flex-row gap-2 align-items-center text-wrap">
<img <img
src="/public/assets/img/orgLogo.png" src="/public/assets/img/orgLogo.png"
alt="logo" alt="logo"
width={40} width={40}
height={40} height={40}
/> <p className="fw-semibold fs-6 m-0">{orgData.name}</p> />
<p className="fw-semibold fs-5 mt-2 m-0">{orgData.name}</p>
</div> </div>
<div className="text-end">
<button <button
type="button" type="button"
onClick={handleEdit} onClick={handleEdit}
@ -112,75 +112,73 @@ const AssignOrg = ({ setStep }) => {
</button> </button>
</div> </div>
</div> </div>
<div className="col-12 fw-semibold mb-4 mt-2 fs-6">
<i className="bx bx-sm bx-info-circle me-1" /> Organization Info
</div> </div>
<div className="d-flex text-secondary mb-2"> <i className="bx bx-sm bx-info-circle me-1" /> Organization Info</div>
{/* Contact Info */} {/* Contact Person */}
<div className="col-md-6 mb-3"> <div className="col-12 mb-4">
<div className="d-flex"> <div className="row">
<label <div className="col-md-4 col-12 fw-semibold mb-2 mb-md-0">
className="form-label me-2 mb-0 fw-semibold"
style={{ minWidth: "130px" }}
>
<i className="bx bx-sm bx-user me-1" /> Contact Person : <i className="bx bx-sm bx-user me-1" /> Contact Person :
</label> </div>
<div className="text-muted">{orgData.contactPerson}</div> <div className="col-md-8 col-12 text-muted">{orgData.contactPerson}</div>
</div> </div>
</div> </div>
<div className="col-md-6 mb-3">
<div className="d-flex"> {/* Contact Number */}
<label <div className="col-12 mb-4">
className="form-label me-2 mb-0 fw-semibold" <div className="row">
style={{ minWidth: "130px" }} <div className="col-md-4 col-12 fw-semibold mb-2 mb-md-0">
> <i className="bx bx-sm bx-phone me-1" /> Contact Number :
<i className='bx bx-sm me-1 bx-phone'></i> Contact Number : </div>
</label> <div className="col-md-8 col-12 text-muted">{orgData.contactNumber}</div>
<div className="text-muted">{orgData.contactNumber}</div>
</div> </div>
</div> </div>
<div className="col-md-6 mb-3">
<div className="d-flex"> {/* Email */}
<label <div className="col-12 mb-4">
className="form-label me-2 mb-0 fw-semibold" <div className="row">
style={{ minWidth: "130px" }} <div className="col-md-4 col-12 fw-semibold mb-2 mb-md-0">
> <i className="bx bx-sm bx-envelope me-1" /> Email Address :
<i className='bx bx-sm me-1 bx-envelope'></i> Email Address : </div>
</label> <div className="col-md-8 col-12 text-muted">{orgData.email}</div>
<div className="text-muted">{orgData.email}</div>
</div> </div>
</div> </div>
<div className="col-12 mb-3">
<div className="d-flex"> {/* SPRID */}
<label <div className="col-12 mb-4">
className="form-label me-2 mb-0 fw-semibold" <div className="row">
style={{ maxWidth: "130px" }} <div className="col-md-4 col-12 fw-semibold mb-2 mb-md-0">
> <i className="bx bx-sm bx-barcode me-1" /> Service Provider Id :
<i className="bx bx-sm me-1 bx-barcode"></i> </div>
Service Provider Id (SPRID) : <div className="col-md-8 col-12 text-muted">{orgData.sprid}</div>
</label>
<div className="text-muted">{orgData.sprid}</div>
</div> </div>
</div> </div>
<div className="col-12 mb-3">
<div className="d-flex"> {/* Address */}
<label <div className="col-12 mb-4">
className="form-label me-1 mb-0 fw-semibold" <div className="row">
style={{ minWidth: "130px" }} <div className="col-md-4 col-12 fw-semibold mb-2 mb-md-0">
> <i className="bx bx-sm bx-map me-1" /> Address :
<i className='bx bx-sm me-1 bx-map'></i> Address : </div>
</label> <div className="col-md-8 col-12 text-muted">{orgData.address}</div>
<div className="text-muted text-start">{orgData.address}</div>
</div> </div>
</div> </div>
{/* Form */} {/* Form */}
<div className="text-black text-start"> <div className="col-12 text-black text-start">
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
{/* Show fields only if flowType is NOT default */}
{flowType !== "default" && ( {flowType !== "default" && (
<> <>
{/* Organization Type */} {/* Organization Type */}
<div className="mb-3 text-start"> <div className="mb-4">
<Label htmlFor="organizationTypeId" className="mb-3 fw-semibold" required> <Label
htmlFor="organizationTypeId"
className="mb-3 fw-semibold"
required
>
Organization Type Organization Type
</Label> </Label>
<div className="d-flex flex-wrap gap-3 mt-1"> <div className="d-flex flex-wrap gap-3 mt-1">
@ -213,12 +211,13 @@ const AssignOrg = ({ setStep }) => {
</div> </div>
{/* Services */} {/* Services */}
<div className="mb-3"> <div className="mb-4">
<Label htmlFor="serviceIds" className="mb-3 fw-semibold" required> <Label htmlFor="serviceIds" className="mb-3 fw-semibold" required>
Select Services Select Services
</Label> </Label>
<div className="d-flex flex-column gap-3">
{mergedServices?.map((service) => ( {mergedServices?.map((service) => (
<div key={service.id} className="form-check mb-3"> <div key={service.id} className="form-check">
<input <input
type="checkbox" type="checkbox"
value={service.id} value={service.id}
@ -228,6 +227,7 @@ const AssignOrg = ({ setStep }) => {
<label className="form-check-label">{service.name}</label> <label className="form-check-label">{service.name}</label>
</div> </div>
))} ))}
</div>
{errors.serviceIds && ( {errors.serviceIds && (
<div className="text-danger small"> <div className="text-danger small">
{errors.serviceIds.message} {errors.serviceIds.message}
@ -237,7 +237,7 @@ const AssignOrg = ({ setStep }) => {
</> </>
)} )}
{/* Buttons: Always visible */} {/* Buttons */}
<div className="d-flex justify-content-between mt-5"> <div className="d-flex justify-content-between mt-5">
<button <button
type="button" type="button"
@ -245,7 +245,7 @@ const AssignOrg = ({ setStep }) => {
onClick={handleBack} onClick={handleBack}
disabled={isPending} disabled={isPending}
> >
<i className="bx bx-chevron-left"></i>Back <i className="bx bx-chevron-left"></i> Back
</button> </button>
<button <button
type="submit" type="submit"
@ -262,6 +262,7 @@ const AssignOrg = ({ setStep }) => {
</form> </form>
</div> </div>
</div> </div>
); );
}; };

View File

@ -1,4 +1,4 @@
import { useState } from "react"; import { useEffect, useState } from "react";
import { import {
useAssignOrgToTenant, useAssignOrgToTenant,
useOrganizationBySPRID, useOrganizationBySPRID,
@ -14,12 +14,14 @@ import { OrgCardSkeleton } from "./OrganizationSkeleton";
// Zod schema: only allow exactly 4 digits // Zod schema: only allow exactly 4 digits
const OrgPickerFromSPId = ({ title, placeholder }) => { const OrgPickerFromSPId = ({ title, placeholder }) => {
const { onClose, startStep, flowType, onOpen, prevStep } = const { onClose, startStep, flowType, onOpen, prevStep, orgData } =
useOrganizationModal(); useOrganizationModal();
const { const {
register, register,
handleSubmit, handleSubmit,
setValue,
formState: { errors }, formState: { errors },
watch, watch,
} = useForm({ } = useForm({
@ -36,7 +38,24 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
setSPRID(formdata.spridSearchText); setSPRID(formdata.spridSearchText);
}; };
const handleOrg = (orgId) => {}; // Add this..
useEffect(() => {
if (orgData?.sprid) {
setValue("spridSearchText", orgData.sprid);
setSPRID(orgData.sprid);
}
}, [orgData, setValue]);
// Add this..
useEffect(() => {
const subscription = watch((value) => {
if (!value.spridSearchText) {
setSPRID("");
}
});
return () => subscription.unsubscribe();
}, [watch]);
const handleOrg = (orgId) => { };
const SP = watch("spridSearchText"); const SP = watch("spridSearchText");
return ( return (
<div className="d-block"> <div className="d-block">
@ -45,7 +64,7 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
onSubmit={handleSubmit(onSubmit)} onSubmit={handleSubmit(onSubmit)}
> >
<div className="d-flex flex-row align-items-center gap-2"> <div className="d-flex flex-row align-items-center gap-2">
<Label className="text-secondary">Search by SPRID</Label> <Label className="fw-semibold">Search by SPRID</Label>
<input <input
type="search" type="search"
{...register("spridSearchText")} {...register("spridSearchText")}
@ -72,10 +91,10 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
{isLoading ? ( {isLoading ? (
<OrgCardSkeleton /> <OrgCardSkeleton />
) : data && data?.data.length > 0 ? ( ) : data && data?.data.length > 0 ? (
<div className="py-2 text-tiny text-center"> <div className="py-2 text-tiny text-center mt-5">
<div className="d-flex flex-column gap-2 border-0 bg-none"> <div className="d-flex flex-column gap-2 border-0 bg-none">
{data.data.map((org) => ( {data.data.map((org) => (
<div className="d-flex flex-row gap-2 text-start text-black "> <div className="d-flex flex-row gap-4 text-start text-black ">
<div className="mt-1"> <div className="mt-1">
<img <img
src="/public/assets/img/orgLogo.png" src="/public/assets/img/orgLogo.png"
@ -85,8 +104,8 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
/> />
</div> </div>
<div className="d-flex flex-column p-0 m-0 cursor-pointer"> <div className="d-flex flex-column p-0 m-0 cursor-pointer">
<span className="fs-6 fw-semibold">{org.name}</span> <span className="fs-5 fw-semibold">{org.name}</span>
<div className="d-flex gap-2"> <div className="d-flex gap-2 mt-2">
<small <small
className=" fw-semibold text-uppercase" className=" fw-semibold text-uppercase"
style={{ letterSpacing: "1px" }} style={{ letterSpacing: "1px" }}
@ -95,11 +114,11 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
</small> </small>
<small className="fs-6">{org.sprid}</small> <small className="fs-6">{org.sprid}</small>
</div> </div>
<div className="d-flex flex-row gap-2"> <div className="d-flex flex-row gap-2 mt-2">
<small className="text-small fw-semibold">Address:</small> <small className="text-small fw-semibold">Address:</small>
<div className="d-flex text-wrap">{org.address}</div> <div className="d-flex text-wrap">{org.address}</div>
</div> </div>
<div className="m-0 p-0"> <div className="m-0 p-0 mt-4">
{" "} {" "}
<button <button
type="submit" type="submit"

View File

@ -22,8 +22,7 @@ const VieworgDataanization = ({ orgId }) => {
</div> </div>
<div className="text-end"> <div className="text-end">
<span <span
className={`badge bg-label-${ className={`badge bg-label-${data?.isActive ? "primary" : "secondary"
data?.isActive ? "primary" : "secondary"
} `} } `}
> >
{data?.isActive ? "Active" : "In-Active"}{" "} {data?.isActive ? "Active" : "In-Active"}{" "}
@ -31,27 +30,27 @@ const VieworgDataanization = ({ orgId }) => {
</div> </div>
</div> </div>
</div> </div>
<div className="d-flex text-secondary mb-2"> <div className="d-flex fw-semibold fs-6 mb-4 mt-2">
{" "} {" "}
<i className="bx bx-sm bx-info-circle me-1" /> Organization Info <i className="bx bx-sm bx-info-circle me-1" /> Organization Info
</div> </div>
{/* Contact Info */} {/* Contact Info */}
<div className="col-md-6 mb-3"> <div className="col-md-12 mb-3">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-1 fw-semibold"
style={{ minWidth: "130px" }} style={{ minWidth: "200px" }}
> >
<i className="bx bx-sm bx-user me-1" /> Contact Person : <i className="bx bx-sm bx-user me-1" /> Contact Person :
</label> </label>
<div className="text-muted">{data?.contactPerson}</div> <div className="text-muted">{data?.contactPerson}</div>
</div> </div>
</div> </div>
<div className="col-md-6 mb-3"> <div className="col-md-12 mb-3">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-1 fw-semibold"
style={{ minWidth: "130px" }} style={{ minWidth: "200px" }}
> >
<i className="bx bx-sm me-1 bx-phone"></i> Contact Number : <i className="bx bx-sm me-1 bx-phone"></i> Contact Number :
</label> </label>
@ -61,44 +60,44 @@ const VieworgDataanization = ({ orgId }) => {
<div className="col-md-12 mb-3"> <div className="col-md-12 mb-3">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-1 fw-semibold"
style={{ minWidth: "130px" }} style={{ minWidth: "200px" }}
> >
<i className="bx bx-sm me-1 bx-envelope"></i> Email Address : <i className="bx bx-sm me-1 bx-envelope"></i> Email Address :
</label> </label>
<div className="text-muted">{data?.email}</div> <div className="text-muted">{data?.email}</div>
</div> </div>
</div> </div>
<div className="col-6 mb-3"> <div className="col-md-12 mb-3">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-1 fw-semibold"
style={{ maxWidth: "130px" }} style={{ maxWidth: "250px" }}
> >
<i className="bx bx-sm me-1 bx-barcode"></i> <i className="bx bx-sm me-2 bx-barcode"></i>
Service Provider Id (SPRID) : Service Provider Id (SPRID) :
</label> </label>
<div className="text-muted">{data?.sprid}</div> <div className="text-muted ms-1">{data?.sprid}</div>
</div> </div>
</div> </div>
<div className="col-6 mb-3"> <div className="col-md-12 mb-3">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-2 mb-0 fw-semibold" className="form-label me-2 mb-1 fw-semibold"
style={{ maxWidth: "130px" }}
> >
<i className="bx bx-sm me-1 bx-group"></i> <i className="bx bx-sm me-2 bx-group"></i>
Employees : Employees :
</label> </label>
<div className="text-muted">{data?.activeEmployeeCount}</div> <div className="text-muted" style={{ marginLeft: "104px" }}>{data?.activeEmployeeCount}</div>
</div> </div>
</div> </div>
<div className="col-12 mb-3"> <div className="col-md-12 mb-3">
<div className="d-flex"> <div className="d-flex">
<label <label
className="form-label me-1 mb-0 fw-semibold" className="form-label me-1 mb-1 fw-semibold"
style={{ minWidth: "130px" }} style={{ minWidth: "207px" }}
> >
<i className="bx bx-sm me-1 bx-map"></i> Address : <i className="bx bx-sm me-1 bx-map"></i> Address :
</label> </label>

View File

@ -108,7 +108,10 @@ const WorkArea = ({ workArea, floor, forBuilding }) => {
<ProgressBar <ProgressBar
completedWork={formatNumber(workArea?.completedWork)} completedWork={formatNumber(workArea?.completedWork)}
plannedWork={formatNumber(workArea?.plannedWork)} plannedWork={formatNumber(workArea?.plannedWork)}
className="m-0 my-2 me-6 text-info" className="m-0 my-2"
height="6px"
rounded
showLabel={true}
/> />
</div> </div>
</div> </div>

View File

@ -324,8 +324,8 @@ const Teams = () => {
<div className="text-center text-muted py-3 d-flex justify-content-center align-items-center py-12"> <div className="text-center text-muted py-3 d-flex justify-content-center align-items-center py-12">
<p> <p>
{activeEmployee {activeEmployee
? "No active employees assigned to the project" ? "No active employees are currently assigned to this service in the project."
: "No inactive employees assigned to the project"} : "No In-active employees are currently assigned to this service in the project."}
</p> </p>
</div> </div>
)} )}

View File

@ -3,35 +3,62 @@ import React from "react";
const ProgressBar = ({ const ProgressBar = ({
plannedWork = 100, plannedWork = 100,
completedWork = 0, completedWork = 0,
height = "8px", height = "6px",
className = "mb-4", className = "mb-4",
rounded = true, rounded = true,
showLabel = true,
}) => { }) => {
const getProgress = (planned, completed) => { const getProgress = (planned, completed) => {
if (!planned || planned === 0) return "0%"; if (!planned || planned === 0) return 0;
return `${Math.min((completed / planned) * 100, 100).toFixed(2)}%`; return Math.min((completed / planned) * 100, 100);
}; };
const progressStyle = { const percentage = getProgress(plannedWork, completedWork);
width: getProgress(plannedWork, completedWork),
const progressBarStyle = {
width: `${percentage.toFixed(2)}%`,
transition: "width 0.4s ease",
};
const containerStyle = {
height,
display: "flex",
alignItems: "center",
gap: "8px",
}; };
return ( return (
<div className={`d-flex align-items-center ${className}`} style={containerStyle}>
<div className="flex-grow-1">
<div <div
className={`progress ${className} ${rounded ? "rounded" : ""}`} className={`progress ${rounded ? "rounded" : ""}`}
style={{ height }} style={{ height, backgroundColor: "#f0f0f0" }}
> >
<div <div
className={`progress-bar ${rounded ? "rounded" : ""}`} className={`progress-bar ${rounded ? "rounded" : ""}`}
role="progressbar" role="progressbar"
style={progressStyle} style={progressBarStyle}
aria-valuenow={completedWork} aria-valuenow={completedWork}
aria-valuemin="0" aria-valuemin="0"
aria-valuemax={plannedWork} aria-valuemax={plannedWork}
></div> />
</div>
</div>
{showLabel && (
<span
className="fw-semibold text-secondary"
style={{
minWidth: "45px",
textAlign: "right",
fontSize: "0.8rem",
}}
>
{percentage.toFixed(2)}%
</span>
)}
</div> </div>
); );
}; };
export default ProgressBar; export default ProgressBar;