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" }}>
<td
colSpan={contactList.length + 1}
className="text-center align-middle"
className="text-center align-middle border-0"
>
No contacts found
</td>

View File

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

View File

@ -1,4 +1,4 @@
import { useState } from "react";
import { useEffect, useState } from "react";
import {
useAssignOrgToTenant,
useOrganizationBySPRID,
@ -14,12 +14,14 @@ import { OrgCardSkeleton } from "./OrganizationSkeleton";
// Zod schema: only allow exactly 4 digits
const OrgPickerFromSPId = ({ title, placeholder }) => {
const { onClose, startStep, flowType, onOpen, prevStep } =
const { onClose, startStep, flowType, onOpen, prevStep, orgData } =
useOrganizationModal();
const {
register,
handleSubmit,
setValue,
formState: { errors },
watch,
} = useForm({
@ -36,7 +38,24 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
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");
return (
<div className="d-block">
@ -44,8 +63,8 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
className="d-flex flex-row gap-6 text-start align-items-center"
onSubmit={handleSubmit(onSubmit)}
>
<div className="d-flex flex-row align-items-center gap-2">
<Label className="text-secondary">Search by SPRID</Label>
<div className="d-flex flex-row align-items-center gap-2">
<Label className="fw-semibold">Search by SPRID</Label>
<input
type="search"
{...register("spridSearchText")}
@ -72,10 +91,10 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
{isLoading ? (
<OrgCardSkeleton />
) : 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">
{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">
<img
src="/public/assets/img/orgLogo.png"
@ -85,8 +104,8 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
/>
</div>
<div className="d-flex flex-column p-0 m-0 cursor-pointer">
<span className="fs-6 fw-semibold">{org.name}</span>
<div className="d-flex gap-2">
<span className="fs-5 fw-semibold">{org.name}</span>
<div className="d-flex gap-2 mt-2">
<small
className=" fw-semibold text-uppercase"
style={{ letterSpacing: "1px" }}
@ -95,11 +114,11 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
</small>
<small className="fs-6">{org.sprid}</small>
</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>
<div className="d-flex text-wrap">{org.address}</div>
</div>
<div className="m-0 p-0">
<div className="m-0 p-0 mt-4">
{" "}
<button
type="submit"

View File

@ -22,36 +22,35 @@ const VieworgDataanization = ({ orgId }) => {
</div>
<div className="text-end">
<span
className={`badge bg-label-${
data?.isActive ? "primary" : "secondary"
} `}
className={`badge bg-label-${data?.isActive ? "primary" : "secondary"
} `}
>
{data?.isActive ? "Active" : "In-Active"}{" "}
</span>
</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
</div>
{/* Contact Info */}
<div className="col-md-6 mb-3">
<div className="col-md-12 mb-3">
<div className="d-flex">
<label
className="form-label me-2 mb-0 fw-semibold"
style={{ minWidth: "130px" }}
className="form-label me-2 mb-1 fw-semibold"
style={{ minWidth: "200px" }}
>
<i className="bx bx-sm bx-user me-1" /> Contact Person :
</label>
<div className="text-muted">{data?.contactPerson}</div>
</div>
</div>
<div className="col-md-6 mb-3">
<div className="col-md-12 mb-3">
<div className="d-flex">
<label
className="form-label me-2 mb-0 fw-semibold"
style={{ minWidth: "130px" }}
className="form-label me-2 mb-1 fw-semibold"
style={{ minWidth: "200px" }}
>
<i className="bx bx-sm me-1 bx-phone"></i> Contact Number :
</label>
@ -61,44 +60,44 @@ const VieworgDataanization = ({ orgId }) => {
<div className="col-md-12 mb-3">
<div className="d-flex">
<label
className="form-label me-2 mb-0 fw-semibold"
style={{ minWidth: "130px" }}
className="form-label me-2 mb-1 fw-semibold"
style={{ minWidth: "200px" }}
>
<i className="bx bx-sm me-1 bx-envelope"></i> Email Address :
</label>
<div className="text-muted">{data?.email}</div>
</div>
</div>
<div className="col-6 mb-3">
<div className="col-md-12 mb-3">
<div className="d-flex">
<label
className="form-label me-2 mb-0 fw-semibold"
style={{ maxWidth: "130px" }}
className="form-label me-2 mb-1 fw-semibold"
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) :
</label>
<div className="text-muted">{data?.sprid}</div>
<div className="text-muted ms-1">{data?.sprid}</div>
</div>
</div>
<div className="col-6 mb-3">
<div className="col-md-12 mb-3">
<div className="d-flex">
<label
className="form-label me-2 mb-0 fw-semibold"
style={{ maxWidth: "130px" }}
className="form-label me-2 mb-1 fw-semibold"
>
<i className="bx bx-sm me-1 bx-group"></i>
<i className="bx bx-sm me-2 bx-group"></i>
Employees :
</label>
<div className="text-muted">{data?.activeEmployeeCount}</div>
<div className="text-muted" style={{ marginLeft: "104px" }}>{data?.activeEmployeeCount}</div>
</div>
</div>
<div className="col-12 mb-3">
<div className="col-md-12 mb-3">
<div className="d-flex">
<label
className="form-label me-1 mb-0 fw-semibold"
style={{ minWidth: "130px" }}
className="form-label me-1 mb-1 fw-semibold"
style={{ minWidth: "207px" }}
>
<i className="bx bx-sm me-1 bx-map"></i> Address :
</label>

View File

@ -108,7 +108,10 @@ const WorkArea = ({ workArea, floor, forBuilding }) => {
<ProgressBar
completedWork={formatNumber(workArea?.completedWork)}
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>

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">
<p>
{activeEmployee
? "No active employees assigned to the project"
: "No inactive employees assigned to the project"}
? "No active employees are currently assigned to this service in the project."
: "No In-active employees are currently assigned to this service in the project."}
</p>
</div>
)}

View File

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